(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/third_party/cryptoppwin/include/cryptopp/base32.h b/third_party/cryptoppwin/include/cryptopp/base32.h
new file mode 100644
index 00000000..80a64ed8
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/base64.h b/third_party/cryptoppwin/include/cryptopp/base64.h
new file mode 100644
index 00000000..be5c6b77
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/basecode.h b/third_party/cryptoppwin/include/cryptopp/basecode.h
new file mode 100644
index 00000000..7158de6a
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/basecode.h
@@ -0,0 +1,146 @@
+// basecode.h - originally written and placed in the public domain by Wei Dai
+
+/// \file
+/// \brief Base classes for working with encoders and decoders.
+
+#ifndef CRYPTOPP_BASECODE_H
+#define CRYPTOPP_BASECODE_H
+
+#include "cryptlib.h"
+#include "filters.h"
+#include "algparam.h"
+#include "argnames.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+/// \brief Encoder for bases that are a power of 2
+class CRYPTOPP_DLL BaseN_Encoder : public Unflushable
+{
+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/third_party/cryptoppwin/include/cryptopp/bench.h b/third_party/cryptoppwin/include/cryptopp/bench.h
new file mode 100644
index 00000000..561b6578
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/blake2.h b/third_party/cryptoppwin/include/cryptopp/blake2.h
new file mode 100644
index 00000000..bbbe134b
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/blowfish.h b/third_party/cryptoppwin/include/cryptopp/blowfish.h
new file mode 100644
index 00000000..8032491e
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/blowfish.h
@@ -0,0 +1,54 @@
+// blowfish.h - originally written and placed in the public domain by Wei Dai
+
+/// \file blowfish.h
+/// \brief Classes for the Blowfish block cipher
+
+#ifndef CRYPTOPP_BLOWFISH_H
+#define CRYPTOPP_BLOWFISH_H
+
+#include "seckey.h"
+#include "secblock.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+/// \brief Blowfish block cipher information
+struct Blowfish_Info : public FixedBlockSize<8>, 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/third_party/cryptoppwin/include/cryptopp/blumshub.h b/third_party/cryptoppwin/include/cryptopp/blumshub.h
new file mode 100644
index 00000000..997a5152
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/camellia.h b/third_party/cryptoppwin/include/cryptopp/camellia.h
new file mode 100644
index 00000000..2d551dcd
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/cast.h b/third_party/cryptoppwin/include/cryptopp/cast.h
new file mode 100644
index 00000000..424cf62b
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/cast.h
@@ -0,0 +1,109 @@
+// cast.h - originally written and placed in the public domain by Wei Dai
+
+/// \file cast.h
+/// \brief Classes for the CAST-128 and CAST-256 block ciphers
+/// \since Crypto++ 2.2
+
+#ifndef CRYPTOPP_CAST_H
+#define CRYPTOPP_CAST_H
+
+#include "seckey.h"
+#include "secblock.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+/// \brief CAST block cipher base
+/// \since Crypto++ 2.2
+class CAST
+{
+protected:
+ static const word32 S[8][256];
+};
+
+/// \brief CAST128 block cipher information
+/// \since Crypto++ 2.2
+struct CAST128_Info : public FixedBlockSize<8>, 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/third_party/cryptoppwin/include/cryptopp/cbcmac.h b/third_party/cryptoppwin/include/cryptopp/cbcmac.h
new file mode 100644
index 00000000..5a0c1201
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/ccm.h b/third_party/cryptoppwin/include/cryptopp/ccm.h
new file mode 100644
index 00000000..f4f8ab05
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/chacha.h b/third_party/cryptoppwin/include/cryptopp/chacha.h
new file mode 100644
index 00000000..8b21ebb2
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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 classes 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/third_party/cryptoppwin/include/cryptopp/chachapoly.h b/third_party/cryptoppwin/include/cryptopp/chachapoly.h
new file mode 100644
index 00000000..27d4d593
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/cham.h b/third_party/cryptoppwin/include/cryptopp/cham.h
new file mode 100644
index 00000000..2ce7b8e6
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/channels.h b/third_party/cryptoppwin/include/cryptopp/channels.h
new file mode 100644
index 00000000..d7aecd2a
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/cmac.h b/third_party/cryptoppwin/include/cryptopp/cmac.h
new file mode 100644
index 00000000..91d9f7f9
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/config.h b/third_party/cryptoppwin/include/cryptopp/config.h
new file mode 100644
index 00000000..e96b1127
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/config.h
@@ -0,0 +1,33 @@
+// 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/third_party/cryptoppwin/include/cryptopp/config_align.h b/third_party/cryptoppwin/include/cryptopp/config_align.h
new file mode 100644
index 00000000..d6d85e75
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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(CRYPTOPP_MSC_VERSION)
+ #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(CRYPTOPP_MSC_VERSION)
+ #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/third_party/cryptoppwin/include/cryptopp/config_asm.h b/third_party/cryptoppwin/include/cryptopp/config_asm.h
new file mode 100644
index 00000000..edfbdefb
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/config_asm.h
@@ -0,0 +1,492 @@
+// 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 code will
+// not explicitly 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_asm.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(CRYPTOPP_MSC_VERSION) || CRYPTOPP_GCC_VERSION >= 30300 || defined(__SSE2__) || (__SUNPRO_CC >= 0x5100))
+ #define CRYPTOPP_SSE2_INTRIN_AVAILABLE 1
+#endif
+
+#if !defined(CRYPTOPP_DISABLE_SSSE3)
+# if defined(__SSSE3__) || (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_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 platforms 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
+
+// Buggy Microsoft compiler, https://github.com/weidai11/cryptopp/issues/1096
+#if defined(CRYPTOPP_MSC_VERSION)
+# undef CRYPTOPP_ARM_SHA1_AVAILABLE
+# undef CRYPTOPP_ARM_SHA2_AVAILABLE
+#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(CRYPTOPP_DISABLE_ARM_NEON)
+# 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
+#endif
+
+// We are still having trouble with integrating Cryptogams AES. Ugh...
+// https://github.com/weidai11/cryptopp/issues/1236
+#undef CRYPTOGAMS_ARM_AES
+
+// 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/third_party/cryptoppwin/include/cryptopp/config_cpu.h b/third_party/cryptoppwin/include/cryptopp/config_cpu.h
new file mode 100644
index 00000000..15f694e7
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/config_cpu.h
@@ -0,0 +1,212 @@
+// 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(CRYPTOPP_MSC_VERSION) || defined(__BORLANDC__) || \
+ defined(CRYPTOPP_MSVC_CLANG_VERSION)
+ #define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 1
+#else
+ #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY 1
+#endif
+
+#endif // CRYPTOPP_CONFIG_CPU_H
diff --git a/third_party/cryptoppwin/include/cryptopp/config_cxx.h b/third_party/cryptoppwin/include/cryptopp/config_cxx.h
new file mode 100644
index 00000000..ffd57add
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/config_cxx.h
@@ -0,0 +1,250 @@
+// 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(CRYPTOPP_MSC_VERSION) && CRYPTOPP_MSC_VERSION <= 1300) || \
+ defined(__MWERKS__) || \
+ (defined(_STLPORT_VERSION) && ((_STLPORT_VERSION < 0x450) || defined(_STLP_NO_UNCAUGHT_EXCEPT_SUPPORT)) || \
+ (__cplusplus >= 202002L))
+#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 ((CRYPTOPP_MSC_VERSION >= 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 ((CRYPTOPP_MSC_VERSION >= 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 ((CRYPTOPP_MSC_VERSION >= 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/third_party/cryptoppwin/include/cryptopp/config_dll.h b/third_party/cryptoppwin/include/cryptopp/config_dll.h
new file mode 100644
index 00000000..73d16d9d
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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 declaration 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/third_party/cryptoppwin/include/cryptopp/config_int.h b/third_party/cryptoppwin/include/cryptopp/config_int.h
new file mode 100644
index 00000000..2eeda0e9
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/config_int.h
@@ -0,0 +1,268 @@
+// 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"
+#include "config_misc.h"
+
+// C5264 new for VS2022/v17.4, MSC v17.3.4
+// https://github.com/weidai11/cryptopp/issues/1185
+#if (CRYPTOPP_MSC_VERSION)
+# pragma warning(push)
+# if (CRYPTOPP_MSC_VERSION >= 1933)
+# pragma warning(disable: 5264)
+# endif
+#endif
+
+/// \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(CRYPTOPP_MSC_VERSION) || 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.
+CRYPTOPP_CONST_OR_CONSTEXPR 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(CRYPTOPP_MSC_VERSION) && (!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
+CRYPTOPP_CONST_OR_CONSTEXPR unsigned int WORD_SIZE = sizeof(word);
+
+/// \brief Size of a platform word in bits
+/// \details The size of a platform word, in bits
+/// \sa https://github.com/weidai11/cryptopp/issues/1185
+CRYPTOPP_CONST_OR_CONSTEXPR unsigned int WORD_BITS = WORD_SIZE * 8;
+
+NAMESPACE_END
+
+#if (CRYPTOPP_MSC_VERSION)
+# pragma warning(pop)
+#endif
+
+#endif // CRYPTOPP_CONFIG_INT_H
diff --git a/third_party/cryptoppwin/include/cryptopp/config_misc.h b/third_party/cryptoppwin/include/cryptopp/config_misc.h
new file mode 100644
index 00000000..68e196cb
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/config_misc.h
@@ -0,0 +1,199 @@
+// 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(CRYPTOPP_MSC_VERSION)
+# 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
+// CRYPTOPP_CONST_OR_CONSTEXPR due to https://github.com/weidai11/cryptopp/issues/1185
+#if defined(CRYPTOPP_CXX11_CONSTEXPR)
+# define CRYPTOPP_STATIC_CONSTEXPR static constexpr
+# define CRYPTOPP_STATIC_CONST_OR_CONSTEXPR static constexpr
+# define CRYPTOPP_CONST_OR_CONSTEXPR constexpr
+# define CRYPTOPP_CONSTEXPR constexpr
+#else
+# define CRYPTOPP_STATIC_CONSTEXPR static
+# define CRYPTOPP_STATIC_CONST_OR_CONSTEXPR static const
+# define CRYPTOPP_CONST_OR_CONSTEXPR const
+# 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 CRYPTOPP_MSC_VERSION
+ // 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)
+ // CRYPTOPP_MSC_VERSION 1920 is VS2019
+# if CRYPTOPP_MSC_VERSION >= 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/third_party/cryptoppwin/include/cryptopp/config_ns.h b/third_party/cryptoppwin/include/cryptopp/config_ns.h
new file mode 100644
index 00000000..256b7916
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/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/third_party/cryptoppwin/include/cryptopp/config_os.h b/third_party/cryptoppwin/include/cryptopp/config_os.h
new file mode 100644
index 00000000..1a636c34
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/config_os.h
@@ -0,0 +1,168 @@
+// 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__))
+//# 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(CRYPTOPP_MSC_VERSION) || defined(__fastcall)
+ #define CRYPTOPP_FASTCALL __fastcall
+#else
+ #define CRYPTOPP_FASTCALL
+#endif
+
+// Microsoft compilers
+#if defined(CRYPTOPP_MSC_VERSION)
+ #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/third_party/cryptoppwin/include/cryptopp/config_ver.h b/third_party/cryptoppwin/include/cryptopp/config_ver.h
new file mode 100644
index 00000000..c7e457c2
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/config_ver.h
@@ -0,0 +1,98 @@
+// 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 9
+/// \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 890
+
+// Compiler version macros
+
+// 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__)
+# define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
+#elif defined(__clang__) && defined(_MSC_VER)
+# define CRYPTOPP_MSVC_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
+#elif defined(__clang__)
+# 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(__GNUC__) && !defined(__clang__)
+# undef CRYPTOPP_APPLE_CLANG_VERSION
+# undef CRYPTOPP_LLVM_CLANG_VERSION
+# define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
+
+#if defined(__xlc__) || defined(__xlC__) && !defined(__clang__)
+# undef CRYPTOPP_LLVM_CLANG_VERSION
+# define CRYPTOPP_XLC_VERSION ((__xlC__ / 256) * 10000 + (__xlC__ % 256) * 100)
+#endif
+
+#if defined(__INTEL_COMPILER) && !defined(__clang__)
+# undef CRYPTOPP_LLVM_CLANG_VERSION
+# define CRYPTOPP_INTEL_VERSION (__INTEL_COMPILER)
+#endif
+
+#if defined(_MSC_VER) && !defined(__clang__)
+# undef CRYPTOPP_LLVM_CLANG_VERSION
+# define CRYPTOPP_MSC_VERSION (_MSC_VER)
+#endif
+
+// To control include. May need a guard, like GCC 4.5 and above
+// Also see https://stackoverflow.com/a/42493893 and https://github.com/weidai11/cryptopp/issues/1198
+#if defined(CRYPTOPP_GCC_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) || defined(CRYPTOPP_LLVM_CLANG_VERSION)
+# define CRYPTOPP_GCC_COMPATIBLE 1
+#endif
+
+#endif // CRYPTOPP_CONFIG_VERSION_H
diff --git a/third_party/cryptoppwin/include/cryptopp/cpu.h b/third_party/cryptoppwin/include/cryptopp/cpu.h
new file mode 100644
index 00000000..29ab6d42
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/cpu.h
@@ -0,0 +1,1089 @@
+// 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(CRYPTOPP_GCC_VERSION)
+ #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
+
+// Thanks to v1ne at https://github.com/weidai11/cryptopp/pull/1133
+#define PERCENT_PASTE(x) "%" #x
+#define PERCENT_REG(x) PERCENT_PASTE(x)
+
+#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(CRYPTOPP_MSC_VERSION) || 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/third_party/cryptoppwin/include/cryptopp/crc.h b/third_party/cryptoppwin/include/cryptopp/crc.h
new file mode 100644
index 00000000..17e5977b
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/crc.h
@@ -0,0 +1,90 @@
+// crc.h - originally written and placed in the public domain by Wei Dai
+
+/// \file crc.h
+/// \brief Classes for CRC-32 and CRC-32C checksum algorithm
+
+#ifndef CRYPTOPP_CRC32_H
+#define CRYPTOPP_CRC32_H
+
+#include "cryptlib.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+const word32 CRC32_NEGL = 0xffffffffL;
+
+#if (CRYPTOPP_LITTLE_ENDIAN)
+#define CRC32_INDEX(c) (c & 0xff)
+#define CRC32_SHIFTED(c) (c >> 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();}
+
+ /// \brief Updates a CRC with additional input
+ /// \param b the additional input as a byte
+ void UpdateByte(byte b) {m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc);}
+
+ /// \brief Retrieves the i-th byte of the CRC
+ /// \param i the additional input as a byte
+ /// \return the byte at the i-th position
+ 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();}
+
+ /// \brief Updates a CRC with additional input
+ /// \param b the additional input as a byte
+ void UpdateByte(byte b) {m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc);}
+
+ /// \brief Retrieves the i-th byte of the CRC
+ /// \param i the additional input as a byte
+ /// \return the byte at the i-th position
+ 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/third_party/cryptoppwin/include/cryptopp/cryptlib.h b/third_party/cryptoppwin/include/cryptopp/cryptlib.h
new file mode 100644
index 00000000..4a5c83bf
--- /dev/null
+++ b/third_party/cryptoppwin/include/cryptopp/cryptlib.h
@@ -0,0 +1,3384 @@
+// 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.9 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, LSH (256/512), Tiger, RIPEMD160, 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"
+
+// C5264 new for VS2022/v17.4, MSC v17.3.4
+// https://github.com/weidai11/cryptopp/issues/1185
+#if CRYPTOPP_MSC_VERSION
+# pragma warning(push)
+# pragma warning(disable: 4127 4189 4505 4702)
+# if (CRYPTOPP_MSC_VERSION >= 1933)
+# pragma warning(disable: 5264)
+# endif
+#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
+CRYPTOPP_CONST_OR_CONSTEXPR 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