Cleared issues 11,12,13 (Clang integrated assembler), 58 (RC rollup), 66 (Coverity rollup)

pull/75/head
Jeffrey Walton 2015-11-18 15:32:28 -05:00
parent d2fda9bd42
commit 6ac1e46a1f
136 changed files with 3456 additions and 1541 deletions

View File

@ -7,11 +7,13 @@
NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ThreeWay_TestInstantiations()
{
ThreeWay::Encryption x1;
ThreeWay::Decryption x2;
}
#endif
static const word32 START_E = 0x0b0b; // round constant of first encryption round
static const word32 START_D = 0xb1b1; // round constant of first decryption round

2
3way.h
View File

@ -2,7 +2,7 @@
//! \file
//! \headerfile 3way.h
//! \brief Class files for the 3way cipher
//! \brief Class file for the 3way cipher
#ifndef CRYPTOPP_THREEWAY_H
#define CRYPTOPP_THREEWAY_H

View File

@ -61,14 +61,19 @@ void Adler32::TruncatedFinal(byte *hash, size_t size)
{
default:
hash[3] = byte(m_s1);
// fall through
case 3:
hash[2] = byte(m_s1 >> 8);
// fall through
case 2:
hash[1] = byte(m_s2);
// fall through
case 1:
hash[0] = byte(m_s2 >> 8);
// fall through
case 0:
;
;;
// fall through
}
Reset();

View File

@ -1,7 +1,8 @@
// adler32.h - written and placed in the public domain by Wei Dai
//! \file
//! \brief Class files for ADLER-32 checksum calculations
//! \headerfile adler32.h
//! \brief Class file for ADLER-32 checksum calculations
#ifndef CRYPTOPP_ADLER32_H
#define CRYPTOPP_ADLER32_H

View File

@ -206,7 +206,8 @@ template <class Element, class Iterator> Element GeneralCascadeMultiplication(co
struct WindowSlider
{
WindowSlider(const Integer &expIn, bool fastNegate, unsigned int windowSizeIn=0)
: exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), windowBegin(0), fastNegate(fastNegate), negateNext(false), firstTime(true), finished(false)
: exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), windowBegin(0), expWindow(0)
, fastNegate(fastNegate), negateNext(false), firstTime(true), finished(false)
{
if (windowSize == 0)
{

View File

@ -1,14 +1,15 @@
// algebra.h - written and placed in the public domain by Wei Dai
//! \file
//! \brief Classes and functions for performing mathematics over different fields
//! \headerfile algebra.h
//! \brief Classes for performing mathematics over different fields
#ifndef CRYPTOPP_ALGEBRA_H
#define CRYPTOPP_ALGEBRA_H
#include "config.h"
#include "integer.h"
#include "misc.h"
#include "integer.h"
NAMESPACE_BEGIN(CryptoPP)

View File

@ -1,7 +1,8 @@
// algparam.h - written and placed in the public domain by Wei Dai
//! \file
//! \brief Classes and functions for working with NameValuePairs
//! \headerfile algparam.h
//! \brief Classes for working with NameValuePairs
#ifndef CRYPTOPP_ALGPARAM_H
@ -30,14 +31,17 @@ class ConstByteArrayParameter
{
public:
ConstByteArrayParameter(const char *data = NULL, bool deepCopy = false)
: m_deepCopy(false), m_data(NULL), m_size(0)
{
Assign((const byte *)data, data ? strlen(data) : 0, deepCopy);
}
ConstByteArrayParameter(const byte *data, size_t size, bool deepCopy = false)
: m_deepCopy(false), m_data(NULL), m_size(0)
{
Assign(data, size, deepCopy);
}
template <class T> ConstByteArrayParameter(const T &string, bool deepCopy = false)
: m_deepCopy(false), m_data(NULL), m_size(0)
{
CRYPTOPP_COMPILE_ASSERT(sizeof(CPP_TYPENAME T::value_type) == 1);
Assign((const byte *)string.data(), string.size(), deepCopy);
@ -45,6 +49,8 @@ public:
void Assign(const byte *data, size_t size, bool deepCopy)
{
// This fires, which means: no data with a size, or data with no size.
// assert((data && size) || !(data || size));
if (deepCopy)
m_block.Assign(data, size);
else
@ -400,6 +406,19 @@ CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<bool>;
CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<int>;
CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<ConstByteArrayParameter>;
//! \class AlgorithmParameters
//! \brief An object that implements NameValuePairs
//! \tparam T the class or type
//! \param name the name of the object or value to retrieve
//! \param value reference to a variable that receives the value
//! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
//! \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(),
//! such as MSVC 7.0 and earlier.
//! \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by
//! repeatedly using operator() on the object returned by MakeParameters, for example:
//! <pre>
//! AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
//! </pre>
class CRYPTOPP_DLL AlgorithmParameters : public NameValuePairs
{
public:
@ -418,6 +437,10 @@ public:
AlgorithmParameters & operator=(const AlgorithmParameters &x);
//! \tparam T the class or type
//! \param name the name of the object or value to retrieve
//! \param value reference to a variable that receives the value
//! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
template <class T>
AlgorithmParameters & operator()(const char *name, const T &value, bool throwIfNotUsed)
{
@ -428,6 +451,10 @@ public:
return *this;
}
//! \brief Appends a NameValuePair to a collection of NameValuePairs
//! \tparam T the class or type
//! \param name the name of the object or value to retrieve
//! \param value reference to a variable that receives the value
template <class T>
AlgorithmParameters & operator()(const char *name, const T &value)
{
@ -441,23 +468,23 @@ protected:
bool m_defaultThrowIfNotUsed;
};
//! Create an object that implements NameValuePairs for passing parameters
/*! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
\note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(),
such as MSVC 7.0 and earlier.
\note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by
repeatedly using operator() on the object returned by MakeParameters, for example:
AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
*/
//! \brief Create an object that implements NameValuePairs
//! \tparam T the class or type
//! \param name the name of the object or value to retrieve
//! \param value reference to a variable that receives the value
//! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
//! \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(),
//! such as MSVC 7.0 and earlier.
//! \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by
//! repeatedly using \p operator() on the object returned by \p MakeParameters, for example:
//! <pre>
//! AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
//! </pre>
#ifdef __BORLANDC__
typedef AlgorithmParameters MakeParameters;
#else
template <class T>
#if __APPLE__
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = false)
#else
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true)
#endif
{
return AlgorithmParameters()(name, value, throwIfNotUsed);
}

View File

@ -13,10 +13,12 @@
NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 {
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ARC4_TestInstantiations()
{
ARC4 x;
}
#endif
ARC4_Base::~ARC4_Base()
{

12
arc4.h
View File

@ -1,7 +1,8 @@
// arc4.h - written and placed in the public domain by Wei Dai
//! \file
//! \brief Implementation of ARC4
//! \headerfile arc4.h
//! \brief Classes for ARC4 cipher
#ifndef CRYPTOPP_ARC4_H
#define CRYPTOPP_ARC4_H
@ -16,7 +17,8 @@ NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 {
//! \class ARC4_Base
//! \brief Allegedly RC4
//! \brief Class specific methods used to operate the cipher.
//! \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions
class CRYPTOPP_NO_VTABLE ARC4_Base : public VariableKeyLength<16, 1, 256>, public RandomNumberGenerator, public SymmetricCipher, public SymmetricCipherDocumentation
{
public:
@ -47,7 +49,10 @@ protected:
//! <a href="http://www.weidai.com/scan-mirror/cs.html#RC4">Alleged RC4</a>
DOCUMENTED_TYPEDEF(SymmetricCipherFinal<ARC4_Base>, ARC4)
//! _
//! \class MARC4_Base
//! \brief Class specific methods used to operate the cipher.
//! \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions
//! \details MARC4 discards the first 256 bytes of keystream, which may be weaker than the rest
class CRYPTOPP_NO_VTABLE MARC4_Base : public ARC4_Base
{
public:
@ -60,7 +65,6 @@ protected:
unsigned int GetDefaultDiscardBytes() const {return 256;}
};
//! Modified ARC4: it discards the first 256 bytes of keystream which may be weaker than the rest
DOCUMENTED_TYPEDEF(SymmetricCipherFinal<MARC4_Base>, MARC4)
}

View File

@ -1,7 +1,7 @@
// argnames.h - written and placed in the public domain by Wei Dai
//! \file
//! \brief Standard names for retrieving values when working with \p NameValuePairs
//! \file argnames.h
//! \brief Standard names for retrieving values by name when working with \p NameValuePairs
#ifndef CRYPTOPP_ARGNAMES_H
#define CRYPTOPP_ARGNAMES_H
@ -78,9 +78,9 @@ CRYPTOPP_DEFINE_NAME_STRING(MaxLineLength) //< int
CRYPTOPP_DEFINE_NAME_STRING(DigestSize) //!< int, in bytes
CRYPTOPP_DEFINE_NAME_STRING(L1KeyLength) //!< int, in bytes
CRYPTOPP_DEFINE_NAME_STRING(TableSize) //!< int, in bytes
CRYPTOPP_DEFINE_NAME_STRING(DerivedKey) //< ByteArrayParameter, key derivation, derived key
CRYPTOPP_DEFINE_NAME_STRING(DerivedLength) //< int, key derivation, derived key length in bytes
CRYPTOPP_DEFINE_NAME_STRING(Blinding) //!< bool
CRYPTOPP_DEFINE_NAME_STRING(DerivedKey) //!< ByteArrayParameter, key derivation, derived key
CRYPTOPP_DEFINE_NAME_STRING(DerivedLength) //!< int, key derivation, derived key length in bytes
DOCUMENTED_NAMESPACE_END
NAMESPACE_END

5
asn.h
View File

@ -1,6 +1,7 @@
// asn.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile asn.h
//! \brief Classes and functions for working with ANS.1 objects
#ifndef CRYPTOPP_ASN_H
@ -348,7 +349,9 @@ void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
BERDecodeError();
size_t bc;
BERLengthDecode(in, bc);
bool definite = BERLengthDecode(in, bc);
if (!definite)
BERDecodeError();
SecByteBlock buf(bc);

View File

@ -1,6 +1,7 @@
// authenc.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile authenc.h
//! \brief Base classes for working with authenticated encryption modes of encryption
#ifndef CRYPTOPP_AUTHENC_H
@ -16,7 +17,8 @@ NAMESPACE_BEGIN(CryptoPP)
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipherBase : public AuthenticatedSymmetricCipher
{
public:
AuthenticatedSymmetricCipherBase() : m_state(State_Start) {}
AuthenticatedSymmetricCipherBase() : m_state(State_Start), m_bufferedDataLength(0),
m_totalHeaderLength(0), m_totalMessageLength(0), m_totalFooterLength(0) {}
bool IsRandomAccess() const {return false;}
bool IsSelfInverting() const {return true;}

View File

@ -1,7 +1,7 @@
// base32.h - written and placed in the public domain by Wei Dai
//! \file
//! \brief Class files for the Base32 encoder and decoder
//! \brief Classes for Base32 encoder and decoder
#ifndef CRYPTOPP_BASE32_H
#define CRYPTOPP_BASE32_H

View File

@ -1,7 +1,7 @@
// .h - written and placed in the public domain by Wei Dai
//! \file
//! \brief Class files for the Base64Encoder, Base64Decoder, Base64URLEncoder and Base64URLDecoder
//! \brief Classes for the Base64Encoder, Base64Decoder, Base64URLEncoder and Base64URLDecoder
#ifndef CRYPTOPP_BASE64_H
#define CRYPTOPP_BASE64_H

View File

@ -1,7 +1,7 @@
// basecode.h - written and placed in the public domain by Wei Dai
//! \file
//! \brief Base class files for working with encoders and decoders.
//! \brief Base classes for working with encoders and decoders.
#ifndef CRYPTOPP_BASECODE_H
#define CRYPTOPP_BASECODE_H
@ -19,9 +19,13 @@ class CRYPTOPP_DLL BaseN_Encoder : public Unflushable<Filter>
{
public:
BaseN_Encoder(BufferedTransformation *attachment=NULL)
: m_alphabet(NULL), m_padding(0), m_bitsPerChar(0)
, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{Detach(attachment);}
BaseN_Encoder(const byte *alphabet, int log2base, BufferedTransformation *attachment=NULL, int padding=-1)
: m_alphabet(NULL), m_padding(0), m_bitsPerChar(0)
, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters(Name::EncodingLookupArray(), alphabet)
@ -46,9 +50,13 @@ class CRYPTOPP_DLL BaseN_Decoder : public Unflushable<Filter>
{
public:
BaseN_Decoder(BufferedTransformation *attachment=NULL)
: m_lookup(0), m_padding(0), m_bitsPerChar(0)
, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{Detach(attachment);}
BaseN_Decoder(const int *lookup, int log2base, BufferedTransformation *attachment=NULL)
: m_lookup(0), m_padding(0), m_bitsPerChar(0)
, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters(Name::DecodingLookupArray(), lookup)(Name::Log2Base(), log2base));
@ -71,9 +79,10 @@ class CRYPTOPP_DLL Grouper : public Bufferless<Filter>
{
public:
Grouper(BufferedTransformation *attachment=NULL)
{Detach(attachment);}
: m_groupSize(0), m_counter(0) {Detach(attachment);}
Grouper(int groupSize, const std::string &separator, const std::string &terminator, BufferedTransformation *attachment=NULL)
: m_groupSize(0), m_counter(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters(Name::GroupSize(), groupSize)

View File

@ -17,6 +17,7 @@
#include <time.h>
#include <math.h>
#include <iostream>
#include <sstream>
#include <iomanip>
// These are noisy enoguh due to test.cpp. Turn them off here.
@ -35,46 +36,72 @@ const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK;
const double CLOCK_TICKS_PER_SECOND = 1000000.0;
#endif
double logtotal = 0, g_allocatedTime, g_hertz;
double logtotal = 0.0, g_allocatedTime = 0, g_hertz = 0;
unsigned int logcount = 0;
static const byte defaultKey[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
static const byte defaultKey[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
void OutputResultBytes(const char *name, double length, double timeTaken)
{
// Coverity finding (http://stackoverflow.com/a/30968371 does not squash the finding)
std::ostringstream out;
out.copyfmt(cout);
// Coverity finding
if (length < 0.0000000001f) length = 0.000001f;
if (timeTaken < 0.0000000001f) timeTaken = 0.000001f;
double mbs = length / timeTaken / (1024*1024);
cout << "\n<TR><TH>" << name;
// cout << "<TD>" << setprecision(3) << length / (1024*1024);
cout << setiosflags(ios::fixed);
// cout << "<TD>" << setprecision(3) << timeTaken;
cout << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << mbs;
out << "\n<TR><TH>" << name;
// out << "<TD>" << setprecision(3) << length / (1024*1024);
out << setiosflags(ios::fixed);
// out << "<TD>" << setprecision(3) << timeTaken;
out << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << mbs;
if (g_hertz)
cout << "<TD>" << setprecision(1) << setiosflags(ios::fixed) << timeTaken * g_hertz / length;
cout << resetiosflags(ios::fixed);
out << "<TD>" << setprecision(1) << setiosflags(ios::fixed) << timeTaken * g_hertz / length;
logtotal += log(mbs);
logcount++;
cout << out.str();
}
void OutputResultKeying(double iterations, double timeTaken)
{
cout << "<TD>" << setprecision(3) << setiosflags(ios::fixed) << (1000*1000*timeTaken/iterations);
// Coverity finding (http://stackoverflow.com/a/30968371 does not squash the finding)
std::ostringstream out;
out.copyfmt(cout);
// Coverity finding
if (iterations < 0.0000000001f) iterations = 0.000001f;
if (timeTaken < 0.0000000001f) timeTaken = 0.000001f;
out << "<TD>" << setprecision(3) << setiosflags(ios::fixed) << (1000*1000*timeTaken/iterations);
if (g_hertz)
cout << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations;
out << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations;
cout << out.str();
}
void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken)
{
cout << "\n<TR><TH>" << name << " " << operation << (pc ? " with precomputation" : "");
// cout << "<TD>" << iterations;
// cout << setiosflags(ios::fixed);
// cout << "<TD>" << setprecision(3) << timeTaken;
cout << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << (1000*timeTaken/iterations);
// Coverity finding (http://stackoverflow.com/a/30968371 does not squash the finding)
std::ostringstream out;
out.copyfmt(cout);
// Coverity finding
if (!iterations) iterations++;
if (timeTaken < 0.0000000001f) timeTaken = 0.000001f;
out << "\n<TR><TH>" << name << " " << operation << (pc ? " with precomputation" : "");
out << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << (1000*timeTaken/iterations);
if (g_hertz)
cout << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations / 1000000;
cout << resetiosflags(ios::fixed);
out << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations / 1000000;
logtotal += log(iterations/timeTaken);
logcount++;
cout << out.str();
}
/*
@ -196,14 +223,16 @@ void BenchMarkByName2(const char *factoryName, size_t keyLength = 0, const char
CRYPTOPP_UNUSED(x), CRYPTOPP_UNUSED(y), CRYPTOPP_UNUSED(params);
std::string name(factoryName ? factoryName : "");
member_ptr<T_FactoryOutput> obj(ObjectFactoryRegistry<T_FactoryOutput>::Registry().CreateObject(name.c_str()));
if (!keyLength)
keyLength = obj->DefaultKeyLength();
if (displayName)
name = displayName;
else if (keyLength)
name += " (" + IntToString(keyLength * 8) + "-bit key)";
member_ptr<T_FactoryOutput> obj(ObjectFactoryRegistry<T_FactoryOutput>::Registry().CreateObject(factoryName));
if (!keyLength)
keyLength = obj->DefaultKeyLength();
obj->SetKey(defaultKey, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(defaultKey, obj->IVSize()), false)));
BenchMark(name.c_str(), *static_cast<T_Interface *>(obj.get()), g_allocatedTime);
BenchMarkKeying(*obj, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(defaultKey, obj->IVSize()), false)));
@ -347,8 +376,7 @@ void BenchmarkAll(double t, double hertz)
cout << "</TABLE>" << endl;
BenchmarkAll2(t, hertz);
cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/logcount) << endl;
cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/(logcount ? logcount : 1)) << endl;
// Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
#if defined(CRYPTOPP_MSC_VERSION)

View File

@ -1,3 +1,5 @@
// bench.h - written and placed in the public domain by Wei Dai
#ifndef CRYPTOPP_BENCH_H
#define CRYPTOPP_BENCH_H

View File

@ -48,7 +48,7 @@ void BenchMarkEncryption(const char *name, PK_Encryptor &key, double timeTotal,
SecByteBlock plaintext(len), ciphertext(key.CiphertextLength(len));
GlobalRNG().GenerateBlock(plaintext, len);
clock_t start = clock();
const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@ -71,7 +71,7 @@ void BenchMarkDecryption(const char *name, PK_Decryptor &priv, PK_Encryptor &pub
GlobalRNG().GenerateBlock(plaintext, len);
pub.Encrypt(GlobalRNG(), plaintext, len, ciphertext);
clock_t start = clock();
const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@ -86,7 +86,7 @@ void BenchMarkSigning(const char *name, PK_Signer &key, double timeTotal, bool p
AlignedSecByteBlock message(len), signature(key.SignatureLength());
GlobalRNG().GenerateBlock(message, len);
clock_t start = clock();
const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@ -108,11 +108,15 @@ void BenchMarkVerification(const char *name, const PK_Signer &priv, PK_Verifier
GlobalRNG().GenerateBlock(message, len);
priv.SignMessage(GlobalRNG(), message, len, signature);
clock_t start = clock();
const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
pub.VerifyMessage(message, len, signature, signature.size());
{
// The return value is ignored because we are interested in throughput
bool unused = pub.VerifyMessage(message, len, signature, signature.size());
CRYPTOPP_UNUSED(unused);
}
OutputResultOperations(name, "Verification", pc, i, timeTaken);
@ -127,7 +131,7 @@ void BenchMarkKeyGen(const char *name, SimpleKeyAgreementDomain &d, double timeT
{
SecByteBlock priv(d.PrivateKeyLength()), pub(d.PublicKeyLength());
clock_t start = clock();
const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@ -146,7 +150,7 @@ void BenchMarkKeyGen(const char *name, AuthenticatedKeyAgreementDomain &d, doubl
{
SecByteBlock priv(d.EphemeralPrivateKeyLength()), pub(d.EphemeralPublicKeyLength());
clock_t start = clock();
const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@ -169,7 +173,7 @@ void BenchMarkAgreement(const char *name, SimpleKeyAgreementDomain &d, double ti
d.GenerateKeyPair(GlobalRNG(), priv2, pub2);
SecByteBlock val(d.AgreedValueLength());
clock_t start = clock();
const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2)
@ -193,7 +197,7 @@ void BenchMarkAgreement(const char *name, AuthenticatedKeyAgreementDomain &d, do
d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2);
SecByteBlock val(d.AgreedValueLength());
clock_t start = clock();
const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2)

View File

@ -1,7 +1,7 @@
// blowfish.h - written and placed in the public domain by Wei Dai
//! \file
//! \brief Class files for the Blowfish algorithm
//! \brief Classes for the Blowfish algorithm
#ifndef CRYPTOPP_BLOWFISH_H
#define CRYPTOPP_BLOWFISH_H

View File

@ -8,10 +8,10 @@ NAMESPACE_BEGIN(CryptoPP)
PublicBlumBlumShub::PublicBlumBlumShub(const Integer &n, const Integer &seed)
: modn(n),
maxBits(BitPrecision(n.BitCount())-1)
current(modn.Square(modn.Square(seed))),
maxBits(BitPrecision(n.BitCount())-1),
bitsLeft(maxBits)
{
current = modn.Square(modn.Square(seed));
bitsLeft = maxBits;
}
unsigned int PublicBlumBlumShub::GenerateBit()

View File

@ -1,3 +1,9 @@
// blumshub.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile blumshub.h
//! \brief Classes for Blum Blum Shub generator
#ifndef CRYPTOPP_BLUMSHUB_H
#define CRYPTOPP_BLUMSHUB_H
@ -22,13 +28,14 @@ public:
bool IsSelfInverting() const {return true;}
bool IsForwardTransformation() const {return true;}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~PublicBlumBlumShub() {}
#endif
protected:
ModularArithmetic modn;
word maxBits, bitsLeft;
Integer current;
friend class BlumGoldwasserPublicKey;
friend class BlumGoldwasserPrivateKey;
word maxBits, bitsLeft;
};
//! BlumBlumShub with factorization of the modulus
@ -42,6 +49,10 @@ public:
bool IsRandomAccess() const {return true;}
void Seek(lword index);
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~BlumBlumShub() {}
#endif
protected:
const Integer p, q;
const Integer x0;

View File

@ -1,3 +1,9 @@
// camellia.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile camellia.h
//! \brief Classes for Cameliia cipher
#ifndef CRYPTOPP_CAMELLIA_H
#define CRYPTOPP_CAMELLIA_H

6
cast.h
View File

@ -1,3 +1,9 @@
// cast.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile cast.h
//! \brief Classes for CAST cipher
#ifndef CRYPTOPP_CAST_H
#define CRYPTOPP_CAST_H

View File

@ -1,3 +1,9 @@
// cbcmac.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile cbcmac.h
//! \brief Classes for CBC MAC
#ifndef CRYPTOPP_CBCMAC_H
#define CRYPTOPP_CBCMAC_H
@ -10,7 +16,7 @@ NAMESPACE_BEGIN(CryptoPP)
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_MAC_Base : public MessageAuthenticationCode
{
public:
CBC_MAC_Base() {}
CBC_MAC_Base() : m_counter(0) {}
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Update(const byte *input, size_t length);

8
ccm.h
View File

@ -1,3 +1,9 @@
// ccm.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile ccm.h
//! \brief CCM block cipher mode of operation
#ifndef CRYPTOPP_CCM_H
#define CRYPTOPP_CCM_H
@ -10,7 +16,7 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CCM_Base : public AuthenticatedSymmetricCi
{
public:
CCM_Base()
: m_digestSize(0), m_L(0) {}
: m_digestSize(0), m_L(0), m_messageLength(0), m_aadLength(0) {}
// AuthenticatedSymmetricCipher
std::string AlgorithmName() const

View File

@ -1,11 +1,16 @@
// channels.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile 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 <map>
#include <list>
#include "stdcpp.h"
NAMESPACE_BEGIN(CryptoPP)
@ -64,18 +69,23 @@ 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;
ChannelRouteIterator(ChannelSwitch &cs) : m_cs(cs) {}
void Reset(const std::string &channel);
bool End() const;
void Next();
BufferedTransformation & Destination();
const std::string & Channel();
protected:
// Hide this to see if we break something...
ChannelRouteIterator();
};
//! Route input to different and/or multiple channels based on channel ID

View File

@ -57,6 +57,7 @@ void CMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const Name
void CMAC_Base::Update(const byte *input, size_t length)
{
assert((input && length) || !(input || length));
if (!length)
return;
@ -65,11 +66,14 @@ void CMAC_Base::Update(const byte *input, size_t length)
if (m_counter > 0)
{
unsigned int len = UnsignedMin(blockSize - m_counter, length);
const unsigned int len = UnsignedMin(blockSize - m_counter, length);
if (len)
{
xorbuf(m_reg+m_counter, input, len);
length -= len;
input += len;
m_counter += len;
}
if (m_counter == blockSize && length > 0)
{

8
cmac.h
View File

@ -1,3 +1,9 @@
// cmac.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile cmac.h
//! \brief Classes for CMAC message authentication code
#ifndef CRYPTOPP_CMAC_H
#define CRYPTOPP_CMAC_H
@ -10,7 +16,7 @@ NAMESPACE_BEGIN(CryptoPP)
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CMAC_Base : public MessageAuthenticationCode
{
public:
CMAC_Base() {}
CMAC_Base() : m_counter(0) {}
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Update(const byte *input, size_t length);

109
config.h
View File

@ -1,3 +1,9 @@
// config.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile config.h
//! \brief Library configuration file
#ifndef CRYPTOPP_CONFIG_H
#define CRYPTOPP_CONFIG_H
@ -54,8 +60,16 @@
# endif
#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
// File system code to write to GZIP archive.
#define GZIP_OS_CODE 0
#if !defined(GZIP_OS_CODE)
# define GZIP_OS_CODE 0
#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
@ -90,7 +104,7 @@
#if defined(CRYPTOPP_INIT_PRIORITY) && (CRYPTOPP_INIT_PRIORITY > 0)
# define CRYPTOPP_USER_PRIORITY (CRYPTOPP_INIT_PRIORITY + 101)
#else
# define CRYPTOPP_USER_PRIORITY 500
# define CRYPTOPP_USER_PRIORITY 250
#endif
// ***************** Important Settings Again ********************
@ -113,8 +127,8 @@
//! \details Nearly all classes are located in the CryptoPP namespace. Within
//! the namespace, there are two additional namespaces.
//! <ul>
//! <li>Name - the namespace for names used with \p NameValuePairs and documented in argnames.h
//! <li>Weak - the namespace for weak and wounded algorithms, like ARC4, MD5 and Pananma
//! <li>Name - namespace for names used with \p NameValuePairs and documented in argnames.h
//! <li>Weak - namespace for weak and wounded algorithms, like ARC4, MD5 and Pananma
//! </ul>
namespace CryptoPP { }
// Bring in the symbols fund in the weak namespace; and fold Weak1 into Weak
@ -126,12 +140,15 @@ namespace CryptoPP { }
# 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
# define NAMESPACE_BEGIN(x) namespace x {
# define NAMESPACE_END }
# define DOCUMENTED_TYPEDEF(x, y) typedef x y;
#endif
#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 }
@ -175,32 +192,31 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
#define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#ifdef __clang__
// Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7
#if defined(__clang__ ) && !defined(__apple_build_version__)
#define CRYPTOPP_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#elif defined(__clang__ ) && defined(__apple_build_version__)
#define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#endif
#ifdef _MSC_VER
#define CRYPTOPP_MSC_VERSION (_MSC_VER)
#endif
// Need GCC 4.6/Clang 1.7 or above due to "GCC diagnostic {push|pop}"
#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700)
// 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_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000)
#define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1
#endif
// Detect availabliltiy of int128_t and uint128_t in preprocessor, http://gcc.gnu.org/ml/gcc-help/2015-08/msg00185.html.
// Both GCC and Clang respond to it.
#if ((defined(__GNUC__) || defined(__clang__) || defined(_INTEL_COMPILER)) && (__SIZEOF_INT128__ >= 16))
#define CRYPTOPP_NATIVE_DWORD_AVAILABLE
#define CRYPTOPP_WORD128_AVAILABLE
typedef word32 hword;
typedef word64 word;
typedef __uint128_t dword;
typedef __uint128_t word128;
// Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232
// TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes.
#if (defined(CRYPTOPP_CLANG_VERSION) && CRYPTOPP_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000)
#define CRYPTOPP_DISABLE_INTEL_ASM 1
#endif
// 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
#elif (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__))
#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER < 1000) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__))
typedef word32 hword;
typedef word64 word;
#else
@ -214,12 +230,26 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
typedef word64 word;
typedef __uint128_t dword;
typedef __uint128_t word128;
#elif defined(__GNUC__) && (__SIZEOF_INT128__ >= 16)
// Detect availabliltiy of int128_t and uint128_t in preprocessor, http://gcc.gnu.org/ml/gcc-help/2015-08/msg00185.html.
#define CRYPTOPP_WORD128_AVAILABLE
typedef word32 hword;
typedef word64 word;
typedef __uint128_t dword;
typedef __uint128_t word128;
#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
#elif defined(__GNUC__) && (__SIZEOF_INT128__ >= 16)
// Detect availabliltiy of int128_t and uint128_t in preprocessor, http://gcc.gnu.org/ml/gcc-help/2015-08/msg00185.html.
#define CRYPTOPP_WORD128_AVAILABLE
typedef word32 hword;
typedef word64 word;
typedef __uint128_t dword;
typedef __uint128_t word128;
#else
// being here means the native register size is probably 32 bits or less
#define CRYPTOPP_BOOL_SLOW_WORD64 1
@ -233,7 +263,7 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
#endif
// Produce a compiler error. It can be commented out, but you may not get the benefit of the fastest integers.
#if (__SIZEOF_INT128__ >= 16) && !defined(CRYPTOPP_WORD128_AVAILABLE)
#if (__SIZEOF_INT128__ >= 16) && !defined(CRYPTOPP_WORD128_AVAILABLE) && !defined(__aarch64__)
# error "An int128_t and uint128_t are available, but CRYPTOPP_WORD128_AVAILABLE is not defined"
#endif
@ -352,6 +382,11 @@ NAMESPACE_END
#define CRYPTOPP_DISABLE_SSE2
#endif
// Apple's Clang prior to 5.0 cannot handle SSE2 (and Apple does not use LLVM Clang numbering...)
#if defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION < 50000)
# define CRYPTOPP_DISABLE_ASM
#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && ((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
@ -380,7 +415,7 @@ NAMESPACE_END
#define CRYPTOPP_X64_ASM_AVAILABLE
#endif
#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__) || defined(__AES__))
#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__))
#define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 1
#else
#define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 0
@ -401,6 +436,8 @@ NAMESPACE_END
// how to allocate 16-byte aligned memory (for SSE2)
#if defined(CRYPTOPP_MSVC6PP_OR_LATER)
#define CRYPTOPP_MM_MALLOC_AVAILABLE
#elif defined(__APPLE__)
#define CRYPTOPP_APPLE_MALLOC_AVAILABLE
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define CRYPTOPP_MALLOC_ALIGNMENT_IS_16
#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
@ -409,6 +446,9 @@ NAMESPACE_END
#define CRYPTOPP_NO_ALIGNED_ALLOC
#endif
// Apple always provides 16-byte aligned, and tells us to use calloc
// http://developer.apple.com/library/mac/documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html
// how to disable inlining
#if defined(_MSC_VER) && _MSC_VER >= 1300
# define CRYPTOPP_NOINLINE_DOTDOTDOT
@ -462,13 +502,6 @@ NAMESPACE_END
#endif
#endif
// For use in template parameters; also see CRYPTOPP_BOOL_ALIGN16 for MMX and above.
#if defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS)
#define CRYPTOPP_BOOL_ALIGN 0
#else
#define CRYPTOPP_BOOL_ALIGN 1
#endif
// ***************** determine availability of OS features ********************
#ifndef NO_OS_DEPENDENCE
@ -547,7 +580,7 @@ NAMESPACE_END
#define CRYPTOPP_API __cdecl
#else // CRYPTOPP_WIN32_AVAILABLE
#else // not CRYPTOPP_WIN32_AVAILABLE
#define CRYPTOPP_DLL
#define CRYPTOPP_API
@ -583,12 +616,14 @@ NAMESPACE_END
#endif
// ************** Unused variable ***************
// Portable way to suppress warning
// Portable way to suppress warnings.
// Moved from misc.h due to circular depenedencies.
#define CRYPTOPP_UNUSED(x) ((void)x)
// ***************** C++11 related ********************
// Visual Studio and C++11 language features began at Visual Studio 2010, http://msdn.microsoft.com/en-us/library/hh567368%28v=vs.110%29.aspx.
// Visual Studio began at VS2010, http://msdn.microsoft.com/en-us/library/hh567368%28v=vs.110%29.aspx.
// Intel and C++11 language features, http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler
// GCC and C++11 language features, http://gcc.gnu.org/projects/cxx0x.html
// Clang and C++11 language features, http://clang.llvm.org/cxx_status.html
@ -601,8 +636,8 @@ NAMESPACE_END
// way. However, modern standard libraries have <forward_list>, 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(__clang__)
# if !(__has_include(<forward_list>))
#if defined(__APPLE__) && defined(__clang__)
# if !(defined(__has_include) && __has_include(<forward_list>))
# undef CRYPTOPP_CXX11
# endif
#endif
@ -610,18 +645,22 @@ NAMESPACE_END
// C++11 or C++14 is available
#if defined(CRYPTOPP_CXX11)
// alignof/alignas: MS at VS2013 (18.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
#if (CRYPTOPP_MSC_VERSION >= 1800)
// alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
#if (CRYPTOPP_MSC_VERSION >= 1900)
# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1
#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1
#elif defined(__clang__)
# if __has_feature(cxx_alignof)
# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1
# endif
#elif (CRYPTOPP_GCC_VERSION >= 40800)
# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1
#endif
#endif // alignof/alignas
// noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; and Intel 14.0.
#if (CRYPTOPP_MSC_VERSION >= 1900)
@ -647,7 +686,7 @@ NAMESPACE_END
# endif
#elif (CRYPTOPP_GCC_VERSION >= 40300)
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
#endif // noexcept compilers
#endif // variadic templates
// TODO: Emplacement, R-values and Move semantics
// Needed because we are catching warnings with GCC and MSC

60
cpu.cpp
View File

@ -83,11 +83,15 @@ bool CpuId(word32 input, word32 output[4])
return true;
#else
// longjmp and clobber warnings. Volatile is required.
// http://github.com/weidai11/cryptopp/issues/24
// http://stackoverflow.com/q/7721854
volatile bool result = true;
SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
if (oldHandler == SIG_ERR)
return false;
result = false;
bool result = true;
if (setjmp(s_jmpNoCPUID))
result = false;
else
@ -134,13 +138,17 @@ static bool TrySSE2()
}
return true;
#else
// longjmp and clobber warnings. Volatile is required.
// http://github.com/weidai11/cryptopp/issues/24
// http://stackoverflow.com/q/7721854
volatile bool result = true;
SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
if (oldHandler == SIG_ERR)
return false;
bool result = true;
if (setjmp(s_jmpNoSSE2))
result = false;
result = true;
else
{
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
@ -156,20 +164,30 @@ static bool TrySSE2()
#endif
}
#if 0
static bool g_x86DetectionDone = false;
static bool g_hasMMX = false, g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasAESNI = false, g_hasCLMUL = false, g_isP4 = false;
static word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
#else
bool g_x86DetectionDone = false;
bool g_hasMMX = false, g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasAESNI = false, g_hasCLMUL = false, g_isP4 = false;
bool g_hasMMX = false, g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasAESNI = false, g_hasCLMUL = false, g_isP4 = false, g_hasRDRAND = false, g_hasRDSEED = false;
word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
#endif
// MacPorts/GCC does not provide constructor(priority). Apple/GCC and Fink/GCC do provide it.
#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 1000)) && !(MACPORTS_GCC_COMPILER > 0))
#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0))
#define HAVE_GCC_CONSTRUCTOR0 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0))
static inline bool IsIntel(const word32 output[4])
{
// This is the "GenuineIntel" string
return (output[1] /*EBX*/ == 0x756e6547) &&
(output[2] /*ECX*/ == 0x6c65746e) &&
(output[3] /*EDX*/ == 0x49656e69);
}
static inline bool IsAMD(const word32 output[4])
{
// This is the "AuthenticAMD" string
return (output[1] /*EBX*/ == 0x68747541) &&
(output[2] /*ECX*/ == 0x69746E65) &&
(output[3] /*EDX*/ == 0x444D4163);
}
#if HAVE_GCC_CONSTRUCTOR1
void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 50))) DetectX86Features()
#elif HAVE_GCC_CONSTRUCTOR0
@ -204,22 +222,32 @@ void DetectX86Features()
}
}
std::swap(cpuid[2], cpuid[3]);
if (memcmp(cpuid+1, "GenuineIntel", 12) == 0)
static const unsigned int RDRAND_FLAG = (1 << 30);
static const unsigned int RDSEED_FLAG = (1 << 18);
if (IsIntel(cpuid))
{
g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
g_hasRDRAND = !!(cpuid1[2] /*ECX*/ & RDRAND_FLAG);
if (cpuid[0] /*EAX*/ >= 7)
{
word32 cpuid3[4];
if (CpuId(7, cpuid3))
g_hasRDSEED = !!(cpuid3[1] /*EBX*/ & RDSEED_FLAG);
}
else if (memcmp(cpuid+1, "AuthenticAMD", 12) == 0)
}
else if (IsAMD(cpuid))
{
CpuId(0x80000005, cpuid);
g_cacheLineSize = GETBYTE(cpuid[2], 0);
g_hasRDRAND = !!(cpuid[2] /*ECX*/ & RDRAND_FLAG);
}
if (!g_cacheLineSize)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
g_x86DetectionDone = true;
*((volatile bool*)&g_x86DetectionDone) = true;
}
#endif

61
cpu.h
View File

@ -1,3 +1,9 @@
// cpu.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile cpu.h
//! \brief Classes, functions, intrinsics and features for X86, X32 nd X64 assembly
#ifndef CRYPTOPP_CPU_H
#define CRYPTOPP_CPU_H
@ -20,16 +26,19 @@
#if !defined(__GNUC__) || defined(__SSSE3__) || defined(__INTEL_COMPILER)
#include <tmmintrin.h>
#else
NAMESPACE_BEGIN(CryptoPP)
__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_shuffle_epi8 (__m128i a, __m128i b)
{
asm ("pshufb %1, %0" : "+x"(a) : "xm"(b));
return a;
}
#endif
NAMESPACE_END
#endif // tmmintrin.h
#if !defined(__GNUC__) || defined(__SSE4_1__) || defined(__INTEL_COMPILER)
#include <smmintrin.h>
#else
NAMESPACE_BEGIN(CryptoPP)
__inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_extract_epi32 (__m128i a, const int i)
{
@ -43,10 +52,12 @@ _mm_insert_epi32 (__m128i a, int b, const int i)
asm ("pinsrd %2, %1, %0" : "+x"(a) : "rm"(b), "i"(i));
return a;
}
#endif
NAMESPACE_END
#endif // smmintrin.h
#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER)
#include <wmmintrin.h>
#else
NAMESPACE_BEGIN(CryptoPP)
__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_clmulepi64_si128 (__m128i a, __m128i b, const int i)
{
@ -91,8 +102,9 @@ _mm_aesdeclast_si128 (__m128i a, __m128i b)
asm ("aesdeclast %1, %0" : "+x"(a) : "xm"(b));
return a;
}
#endif
#endif
NAMESPACE_END
#endif // wmmintrin.h
#endif // CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
NAMESPACE_BEGIN(CryptoPP)
@ -109,6 +121,8 @@ extern CRYPTOPP_DLL bool g_hasSSSE3;
extern CRYPTOPP_DLL bool g_hasAESNI;
extern CRYPTOPP_DLL bool g_hasCLMUL;
extern CRYPTOPP_DLL bool g_isP4;
extern CRYPTOPP_DLL bool g_hasRDRAND;
extern CRYPTOPP_DLL bool g_hasRDSEED;
extern CRYPTOPP_DLL word32 g_cacheLineSize;
CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features();
@ -175,6 +189,20 @@ inline bool IsP4()
return g_isP4;
}
inline bool HasRDRAND()
{
if (!g_x86DetectionDone)
DetectX86Features();
return g_hasRDRAND;
}
inline bool HasRDSEED()
{
if (!g_x86DetectionDone)
DetectX86Features();
return g_hasRDSEED;
}
inline int GetCacheLineSize()
{
if (!g_x86DetectionDone)
@ -215,12 +243,27 @@ inline int GetCacheLineSize()
#define AS_HEX(y) 0x##y
#else
#define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
#if defined(CRYPTOPP_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;"
#else
#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;"
#endif
// define these in two steps to allow arguments to be expanded
#define GNU_AS1(x) #x ";"
#define GNU_AS2(x, y) #x ", " #y ";"
#define GNU_AS3(x, y, z) #x ", " #y ", " #z ";"
#define GNU_ASL(x) "\n" #x ":"
#define GNU_ASJ(x, y, z) #x " " #y #z ";"
#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
#define GNU_ASJ(x, y, z) #x " " #y #z ";" NEW_LINE
#define AS1(x) GNU_AS1(x)
#define AS2(x, y) GNU_AS2(x, y)
#define AS3(x, y, z) GNU_AS3(x, y, z)

6
crc.h
View File

@ -1,3 +1,9 @@
// crc.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile crc.h
//! \brief Classes for CRC-32 checksum algorithm
#ifndef CRYPTOPP_CRC32_H
#define CRYPTOPP_CRC32_H

View File

@ -180,6 +180,10 @@ void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV)
size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
{
assert(inBlocks);
assert(outBlocks);
assert(length);
size_t blockSize = BlockSize();
size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize;
size_t xorIncrement = xorBlocks ? blockSize : 0;
@ -200,11 +204,20 @@ size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const by
{
if (flags & BT_XorInput)
{
// Coverity finding. However, xorBlocks is never NULL if BT_XorInput.
assert(xorBlocks);
#if defined(__COVERITY__)
if (xorBlocks)
#endif
xorbuf(outBlocks, xorBlocks, inBlocks, blockSize);
ProcessBlock(outBlocks);
}
else
{
// xorBlocks can be NULL. See, for example, ECB_OneWay::ProcessData.
ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
}
if (flags & BT_InBlockIsCounter)
const_cast<byte *>(inBlocks)[blockSize-1]++;
inBlocks += inIncrement;
@ -344,16 +357,49 @@ void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransform
}
}
//! see NullRNG()
//! \class ClassNullRNG
//! \brief Random Number Generator that does not produce random numbers
//! \details ClassNullRNG can be used for functions that require a RandomNumberGenerator
//! but don't actually use it. The class throws NotImplemented when a generation function is called.
//! \sa NullRNG()
class ClassNullRNG : public RandomNumberGenerator
{
public:
//! \brief The name of the generator
//! \returns the string \a NullRNGs
std::string AlgorithmName() const {return "NullRNG";}
#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
//! \brief An implementation that throws NotImplemented
byte GenerateByte () {}
//! \brief An implementation that throws NotImplemented
unsigned int GenerateBit () {}
//! \brief An implementation that throws NotImplemented
word32 GenerateWord32 (word32 min, word32 max) {}
#endif
//! \brief An implementation that throws NotImplemented
void GenerateBlock(byte *output, size_t size)
{
CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size);
throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");
}
#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
//! \brief An implementation that throws NotImplemented
void GenerateIntoBufferedTransformation (BufferedTransformation &target, const std::string &channel, lword length) {}
//! \brief An implementation that throws NotImplemented
void IncorporateEntropy (const byte *input, size_t length) {}
//! \brief An implementation that returns \p false
bool CanIncorporateEntropy () const {}
//! \brief An implementation that does nothing
void DiscardBytes (size_t n) {}
//! \brief An implementation that does nothing
void Shuffle (IT begin, IT end) {}
private:
Clonable* Clone () const { return NULL; }
#endif
};
RandomNumberGenerator & NullRNG()

1093
cryptlib.h

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,10 @@
# pragma strict_gs_check (on)
#endif
#if defined(__COVERITY__)
extern "C" void __coverity_tainted_data_sanitize__(void *);
#endif
USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)
@ -579,7 +583,7 @@ void TestDigestOrMAC(TestData &v, bool testDigest)
{
int digestSize = -1;
if (test == "VerifyTruncated")
pairs.GetIntValue(Name::DigestSize(), digestSize);
digestSize = pairs.GetIntValueWithDefault(Name::DigestSize(), digestSize);
HashVerificationFilter verifierFilter(*pHash, NULL, HashVerificationFilter::HASH_AT_BEGIN, digestSize);
PutDecodedDatumInto(v, digestName, verifierFilter);
PutDecodedDatumInto(v, "Message", verifierFilter);
@ -628,6 +632,12 @@ bool GetField(std::istream &is, std::string &name, std::string &value)
{
name.resize(0); // GCC workaround: 2.95.3 doesn't have clear()
is >> name;
#if defined(__COVERITY__)
// The datafile being read is in /usr/share, and it protected by filesystem ACLs
// __coverity_tainted_data_sanitize__(reinterpret_cast<void*>(&name));
#endif
if (name.empty())
return false;

View File

@ -1,3 +1,9 @@
// default.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile default.h
//! \brief Classes for DefaultEncryptor, DefaultEncryptorWithMAC and decryptors
#ifndef CRYPTOPP_DEFAULT_H
#define CRYPTOPP_DEFAULT_H

9
des.h
View File

@ -1,9 +1,12 @@
// des.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile des.h
//! \brief Classes for DES, 2-key and 3-key Triple-DES
#ifndef CRYPTOPP_DES_H
#define CRYPTOPP_DES_H
/** \file
*/
#include "seckey.h"
#include "secblock.h"

2
dh.cpp
View File

@ -8,11 +8,13 @@
NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void DH_TestInstantiations()
{
DH dh1;
DH dh2(NullRNG(), 10);
}
#endif
NAMESPACE_END

9
dh.h
View File

@ -1,9 +1,12 @@
// dh.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile dh.h
//! \brief Classes for Diffie-Hellman key exchange
#ifndef CRYPTOPP_DH_H
#define CRYPTOPP_DH_H
/** \file
*/
#include "cryptlib.h"
#include "gfpcrypt.h"

View File

@ -5,10 +5,12 @@
NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void DH2_TestInstantiations()
{
DH2 dh(*(SimpleKeyAgreementDomain*)NULL);
}
#endif
bool DH2::Agree(byte *agreedValue,
const byte *staticSecretKey, const byte *ephemeralSecretKey,

9
dh2.h
View File

@ -1,9 +1,12 @@
// dh2.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile dh2.h
//! \brief Classes for Diffie-Hellman authenticated key exchange
#ifndef CRYPTOPP_DH2_H
#define CRYPTOPP_DH2_H
/** \file
*/
#include "cryptlib.h"
NAMESPACE_BEGIN(CryptoPP)

6
dll.h
View File

@ -1,3 +1,9 @@
// dll.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile dll.h
//! \brief Functions and definitions required for building the FIPS-140 DLL on Windows
#ifndef CRYPTOPP_DLL_H
#define CRYPTOPP_DLL_H

8
dmac.h
View File

@ -1,3 +1,9 @@
// dmac.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile dmac.h
//! \brief Classes for DMAC message authentication code
#ifndef CRYPTOPP_DMAC_H
#define CRYPTOPP_DMAC_H
@ -14,7 +20,7 @@ public:
CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE)
DMAC_Base() {}
DMAC_Base() : m_subkeylength(0), m_counter(0) {}
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Update(const byte *input, size_t length);

9
dsa.h
View File

@ -1,9 +1,12 @@
// dsa.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile dsa.h
//! \brief Classes for DSA signature algorithm
#ifndef CRYPTOPP_DSA_H
#define CRYPTOPP_DSA_H
/** \file
*/
#include "cryptlib.h"
NAMESPACE_BEGIN(CryptoPP)

27
eax.h
View File

@ -1,3 +1,9 @@
// eax.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile eax.h
//! \brief EAX block cipher mode of operation
#ifndef CRYPTOPP_EAX_H
#define CRYPTOPP_EAX_H
@ -7,7 +13,9 @@
NAMESPACE_BEGIN(CryptoPP)
//! .
//! \class EAX_Base
//! \brief EAX block cipher mode of operation
//! \details Implementations and overrides in \p EAX_Base apply to both \p ENCRYPTION and \p DECRYPTION directions
class CRYPTOPP_NO_VTABLE EAX_Base : public AuthenticatedSymmetricCipherBase
{
public:
@ -59,7 +67,13 @@ protected:
CTR_Mode_ExternalCipher::Encryption m_ctr;
};
//! .
//! \class EAX_Final
//! \brief Class specific methods used to operate the cipher.
//! \tparam T_BlockCipher block cipher
//! \tparam T_IsEncryption direction in which to operate the cipher
//! \details Implementations and overrides in \p GCM_Final apply to either
//! \p ENCRYPTION or \p DECRYPTION, depending on the template parameter \p T_IsEncryption.
//! \details \p EAX_Final does not use inner classes \p Enc and \p Dec.
template <class T_BlockCipher, bool T_IsEncryption>
class EAX_Final : public EAX_Base
{
@ -78,7 +92,14 @@ private:
#undef EAX
#endif
/// <a href="http://www.cryptolounge.org/wiki/EAX">EAX</a>
//! \class EAX
//! \brief The EAX block cipher mode of operation
//! \details EAX is an Authenticated Encryption with Associated Data (AEAD) block
//! cipher mode of operation designed to simultaneously provide both authentication
//! and privacy of the message.
//! \tparam T_BlockCipher block cipher
//! \details \p EAX provides the \p Encryption and \p Decryption typedef.
//! \sa <a href="http://www.cryptolounge.org/wiki/EAX">EAX</a> at the Crypto Lounge
template <class T_BlockCipher>
struct EAX : public AuthenticatedSymmetricCipherDocumentation
{

7
ec2n.h
View File

@ -1,3 +1,10 @@
// ec2n.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile ec2n.h
//! \brief Classes for Elliptic Curves over binary fields
#ifndef CRYPTOPP_EC2N_H
#define CRYPTOPP_EC2N_H

View File

@ -31,6 +31,7 @@
NAMESPACE_BEGIN(CryptoPP)
#if 0
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
static void ECDSA_TestInstantiations()
{
ECDSA<EC2N>::Signer t1;
@ -43,6 +44,7 @@ static void ECDSA_TestInstantiations()
ECMQV<ECP>::Domain t8;
}
#endif
#endif
// VC60 workaround: complains when these functions are put into an anonymous namespace
static Integer ConvertToInteger(const PolynomialMod2 &x)

View File

@ -299,7 +299,7 @@ struct ECIES
virtual ~ECIES() {}
#endif
#if (CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20800)
#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 30000)
} __attribute__((deprecated ("ECIES will be changing in the near future due to (1) an implementation bug and (2) an interop issue.")));
#elif (CRYPTOPP_GCC_VERSION )
} __attribute__((deprecated));

View File

@ -8,6 +8,7 @@
#include "asn.h"
#include "integer.h"
#include "nbtheory.h"
#include "modarith.h"
#include "filters.h"
#include "algebra.cpp"

6
ecp.h
View File

@ -1,3 +1,9 @@
// ecp.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile ecp.h
//! \brief Classes for Elliptic Curves over prime fields
#ifndef CRYPTOPP_ECP_H
#define CRYPTOPP_ECP_H

View File

@ -7,11 +7,13 @@
NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ElGamal_TestInstantiations()
{
ElGamalEncryptor test1(1, 1, 1);
ElGamalDecryptor test2(NullRNG(), 123);
ElGamalEncryptor test3(test2);
}
#endif
NAMESPACE_END

View File

@ -18,6 +18,7 @@
NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ESIGN_TestInstantiations()
{
ESIGN<SHA>::Verifier x1(1, 1);
@ -31,6 +32,7 @@ void ESIGN_TestInstantiations()
x3 = ESIGN<SHA>::Verifier(x2);
x4 = x2.GetKey();
}
#endif
void ESIGNFunction::BERDecode(BufferedTransformation &bt)
{

View File

@ -45,7 +45,8 @@ public:
void SetPublicExponent(const Integer &e) {m_e = e;}
protected:
unsigned int GetK() const {return m_n.BitCount()/3-1;}
// Covertiy finding on overflow. The library allows small values for research purposes.
unsigned int GetK() const {return SaturatingSubtract(m_n.BitCount()/3, 1U);}
Integer m_n, m_e;
};

View File

@ -10,7 +10,7 @@
NAMESPACE_BEGIN(CryptoPP)
#ifndef NDEBUG
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Files_TestInstantiations()
{
FileStore f0;

View File

@ -23,11 +23,11 @@ public:
class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileStore: error opening file for reading: " + filename) {}};
class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}};
FileStore() : m_stream(NULL) {}
FileStore(std::istream &in)
FileStore() : m_stream(NULL), m_space(NULL), m_len(0), m_waiting(0) {}
FileStore(std::istream &in) : m_stream(NULL), m_space(NULL), m_len(0), m_waiting(0)
{StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));}
FileStore(const char *filename)
{StoreInitialize(MakeParameters(Name::InputFileName(), filename));}
FileStore(const char *filename) : m_stream(NULL), m_space(NULL), m_len(0), m_waiting(0)
{StoreInitialize(MakeParameters(Name::InputFileName(), filename ? filename : ""));}
#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400
//! specify file with Unicode name. On non-Windows OS, this function assumes that setlocale() has been called.
FileStore(const wchar_t *filename)

View File

@ -18,10 +18,9 @@
#include "fltrimpl.h"
#include "argnames.h"
#include "smartptr.h"
#include "stdcpp.h"
#include "misc.h"
#include <functional>
NAMESPACE_BEGIN(CryptoPP)
Filter::Filter(BufferedTransformation *attachment)
@ -83,9 +82,12 @@ bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
case 0:
if (IsolatedFlush(hardFlush, blocking))
return true;
// fall through
case 1:
if (OutputFlush(1, hardFlush, propagation, blocking))
return true;
// fall through
default: ;;
}
return false;
}
@ -97,9 +99,12 @@ bool Filter::MessageSeriesEnd(int propagation, bool blocking)
case 0:
if (IsolatedMessageSeriesEnd(blocking))
return true;
// fall through
case 1:
if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
return true;
// fall through
default: ;;
}
return false;
}
@ -434,7 +439,8 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
m_firstInputDone = false;
m_queue.ResetQueue(1, m_firstSize);
Output(1, NULL, 0, messageEnd, blocking);
// Cast to void to supress Coverity finding
(void)Output(1, NULL, 0, messageEnd, blocking);
}
return 0;
}
@ -582,7 +588,7 @@ size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool
StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool allowAuthenticatedSymmetricCipher)
: FilterWithBufferedInput(attachment)
, m_cipher(c)
, m_cipher(c), m_padding(DEFAULT_PADDING), m_optimalBufferSize(0)
{
assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize());
@ -755,7 +761,8 @@ void StreamTransformationFilter::LastPut(const byte *inString, size_t length)
// *************************************************************
HashFilter::HashFilter(HashTransformation &hm, BufferedTransformation *attachment, bool putMessage, int truncatedDigestSize, const std::string &messagePutChannel, const std::string &hashPutChannel)
: m_hashModule(hm), m_putMessage(putMessage), m_messagePutChannel(messagePutChannel), m_hashPutChannel(hashPutChannel)
: m_hashModule(hm), m_putMessage(putMessage), m_digestSize(0), m_space(NULL)
, m_messagePutChannel(messagePutChannel), m_hashPutChannel(hashPutChannel)
{
m_digestSize = truncatedDigestSize < 0 ? m_hashModule.DigestSize() : truncatedDigestSize;
Detach(attachment);
@ -790,7 +797,7 @@ size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, boo
HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize)
: FilterWithBufferedInput(attachment)
, m_hashModule(hm)
, m_hashModule(hm), m_flags(0), m_digestSize(0), m_verified(false)
{
IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize));
}
@ -980,7 +987,7 @@ size_t SignerFilter::Put2(const byte *inString, size_t length, int messageEnd, b
SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment, word32 flags)
: FilterWithBufferedInput(attachment)
, m_verifier(verifier)
, m_verifier(verifier), m_flags(0), m_verified(0)
{
IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags));
}

178
filters.h
View File

@ -1,3 +1,9 @@
// filters.h - written and placed in the public domain by Wei Dai
//! \file filters.h
//! \brief Implementation of BufferedTransformation's attachment interface in cryptlib.h.
//! \nosubgrouping
#ifndef CRYPTOPP_FILTERS_H
#define CRYPTOPP_FILTERS_H
@ -21,24 +27,55 @@
NAMESPACE_BEGIN(CryptoPP)
/// provides an implementation of BufferedTransformation's attachment interface
//! \class Filter
//! \brief Implementation of BufferedTransformation's attachment interface
//! \details Filter is a cornerstone of the Pipeline trinitiy. Data flows from
//! Sources, through Filters, and then terminates in Sinks. The difference
//! between a Source and Filter is a Source \a pumps data, while a Filter does
//! not. The difference between a Filter and a Sink is a Filter allows an
//! attached transformation, while a Sink does not.
//! \details See the discussion of BufferedTransformation in cryptlib.h for
//! more details.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Filter : public BufferedTransformation, public NotCopyable
{
public:
//! \brief Construct a Filter
//! \param attachment the filter's attached transformation
//! \details attachment can be \p NULL.
Filter(BufferedTransformation *attachment = NULL);
//! \brief Determine if attachable
//! \returns \p true if the object allows attached transformations, \p false otherwise.
//! \note Source and Filter offer attached transformations; while Sink does not.
bool Attachable() {return true;}
//! \brief Retrieve attached transformation
//! \returns pointer to a BufferedTransformation if there is an attached transformation, \p NULL otherwise.
BufferedTransformation *AttachedTransformation();
//! \brief Retrieve attached transformation
//! \returns pointer to a BufferedTransformation if there is an attached transformation, \p NULL otherwise.
const BufferedTransformation *AttachedTransformation() const;
//! \brief Replace an attached transformation
//! \param newAttachment pointer to a new BufferedTransformation
//! \details newAttachment cab ne a single filter, a chain of filters or \p NULL.
//! Pass \p NULL to remove an existing BufferedTransformation or chain of filters
void Detach(BufferedTransformation *newAttachment = NULL);
// See the documentation for BufferedTransformation in cryptlib.h
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
// See the documentation for BufferedTransformation in cryptlib.h
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~Filter() {}
#endif
protected:
virtual BufferedTransformation * NewDefaultAttachment() const;
void Insert(Filter *nextFilter); // insert filter after this one
@ -48,10 +85,65 @@ protected:
void PropagateInitialize(const NameValuePairs &parameters, int propagation);
//! \brief Forward processed data on to attached transformation
//! \param outputSite unknown, system crash between keyboard and chair...
//! \param inString the byte buffer to process
//! \param length the size of the string, in bytes
//! \param messageEnd means how many filters to signal MessageEnd() to, including this one
//! \param blocking specifies whether the object should block when processing input
//! \param channel the channel to process the data
//! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
//! number of bytes that were \a not processed.
size_t Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
//! \brief Output multiple bytes that may be modified by callee.
//! \param outputSite unknown, system crash between keyboard and chair...
//! \param inString the byte buffer to process
//! \param length the size of the string, in bytes
//! \param messageEnd means how many filters to signal MessageEnd() to, including this one
//! \param blocking specifies whether the object should block when processing input
//! \param channel the channel to process the data
//! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
//! number of bytes that were \a not processed
size_t OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
//! \brief Signals the end of messages to the object
//! \param outputSite unknown, system crash between keyboard and chair...
//! \param propagation the number of attached transformations the MessageEnd() signal should be passed
//! \param blocking specifies whether the object should block when processing input
//! \param channel the channel to process the data
//! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
//! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
//! \brief Flush buffered input and/or output, with signal propagation
//! \param outputSite unknown, system crash between keyboard and chair...
//! \param hardFlush is used to indicate whether all data should be flushed
//! \param propagation the number of attached transformations the Flush() signal should be passed
//! \param blocking specifies whether the object should block when processing input
//! \param channel the channel to process the data
//! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
//! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
//! \note Hard flushes must be used with care. It means try to process and output everything, even if
//! there may not be enough data to complete the action. For example, hard flushing a HexDecoder
//! would cause an error if you do it after inputing an odd number of hex encoded characters.
//! \note For some types of filters, like ZlibDecompressor, hard flushes can only
//! be done at "synchronization points". These synchronization points are positions in the data
//! stream that are created by hard flushes on the corresponding reverse filters, in this
//! example ZlibCompressor. This is useful when zlib compressed data is moved across a
//! network in packets and compression state is preserved across packets, as in the SSH2 protocol.
bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
//! \brief Marks the end of a series of messages, with signal propagation
//! \param outputSite unknown, system crash between keyboard and chair...
//! \param propagation the number of attached transformations the MessageSeriesEnd() signal should be passed
//! \param blocking specifies whether the object should block when processing input
//! \param channel the channel to process the data
//! \details Each object that receives the signal will perform its processing, decrement
//! propagation, and then pass the signal on to attached transformations if the value is not 0.
//! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
//! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
//! \note There should be a MessageEnd() immediately before MessageSeriesEnd().
bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
private:
@ -62,6 +154,8 @@ protected:
int m_continueAt;
};
//! \struct FilterPutSpaceHelper
struct CRYPTOPP_DLL FilterPutSpaceHelper
{
// desiredSize is how much to ask target, bufferSize is how much to allocate in m_tempSpace
@ -112,7 +206,7 @@ public:
byte * CreatePutSpace(size_t &size)
{return AttachedTransformation()->CreatePutSpace(size);}
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking);
bool IsolatedMessageSeriesEnd(bool blocking);
@ -275,18 +369,35 @@ protected:
ByteQueue m_inQueue;
};
//! \struct BlockPaddingSchemeDef
//! \detils Padding schemes used for block ciphers.
struct BlockPaddingSchemeDef
{
enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING};
//! \enum BlockPaddingScheme
//! \detils Padding schemes used for block ciphers.
//! \details DEFAULT_PADDING means PKCS_PADDING if <tt>cipher.MandatoryBlockSize() > 1 &&
//! cipher.MinLastBlockSize() == 0</tt>, which holds for ECB or CBC mode. Otherwise,
//! NO_PADDING for modes like OFB, CFB, CTR, CBC-CTS.
//! \sa <A HREF="http://www.weidai.com/scan-mirror/csp.html">Block Cipher Padding</A> for
//! additional details.
enum BlockPaddingScheme {
//! \brief No padding added to a block
NO_PADDING,
//! \brief 0's padding added to a block
ZEROS_PADDING,
//! \brief PKCS #5 padding added to a block
PKCS_PADDING,
//! \brief 1 and 0's padding added to a block
ONE_AND_ZEROS_PADDING,
//! \brief Default padding acheme
DEFAULT_PADDING
};
};
//! Filter Wrapper for StreamTransformation, optionally handling padding/unpadding when needed
class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper
{
public:
/*! DEFAULT_PADDING means PKCS_PADDING if c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0 (e.g. ECB or CBC mode),
otherwise NO_PADDING (OFB, CFB, CTR, CBC-CTS modes).
See http://www.weidai.com/scan-mirror/csp.html for details of the padding schemes. */
StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING, bool allowAuthenticatedSymmetricCipher = false);
std::string AlgorithmName() const {return m_cipher.AlgorithmName();}
@ -317,7 +428,7 @@ public:
std::string AlgorithmName() const {return m_hashModule.AlgorithmName();}
void IsolatedInitialize(const NameValuePairs &parameters);
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
byte * CreatePutSpace(size_t &size) {return m_hashModule.CreateUpdateSpace(size);}
private:
@ -415,7 +526,7 @@ public:
std::string AlgorithmName() const {return m_signer.AlgorithmName();}
void IsolatedInitialize(const NameValuePairs &parameters);
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
private:
RandomNumberGenerator &m_rng;
@ -463,11 +574,17 @@ typedef SignatureVerificationFilter VerifierFilter; // for backwards compatibili
class CRYPTOPP_DLL Redirector : public CustomSignalPropagation<Sink>
{
public:
//! \brief Controls signal propagation behavior
enum Behavior
{
//! \brief Pass data only
DATA_ONLY = 0x00,
//! \brief Pass signals
PASS_SIGNALS = 0x01,
//! \brief Pass wait events
PASS_WAIT_OBJECTS = 0x02,
//! \brief Pass everything
//! \details PASS_EVERYTHING is default
PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS
};
@ -491,8 +608,8 @@ public:
void Initialize(const NameValuePairs &parameters, int propagation);
byte * CreatePutSpace(size_t &size)
{return m_target ? m_target->CreatePutSpace(size) : (byte *)(size=0, NULL);}
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
{return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
{return m_target ? m_target->Put2(inString, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
{return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;}
bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
@ -530,8 +647,8 @@ public:
byte * CreatePutSpace(size_t &size)
{return m_owner.AttachedTransformation()->CreatePutSpace(size);}
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->Put2(inString, length, m_passSignal ? messageEnd : 0, blocking);}
size_t PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
@ -616,7 +733,7 @@ public:
void IsolatedInitialize(const NameValuePairs &parameters)
{if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
{
CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking);
if (length > 0)
@ -624,7 +741,7 @@ public:
typename T::size_type size = m_output->size();
if (length < size && size + length > m_output->capacity())
m_output->reserve(2*size);
m_output->append((const char_type *)begin, (const char_type *)begin+length);
m_output->append((const char_type *)inString, (const char_type *)inString+length);
}
return 0;
}
@ -648,7 +765,7 @@ public:
: m_rng(&rng) {}
void IsolatedInitialize(const NameValuePairs &parameters);
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
private:
RandomNumberGenerator *m_rng;
@ -668,7 +785,7 @@ public:
void IsolatedInitialize(const NameValuePairs &parameters);
byte * CreatePutSpace(size_t &size);
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
protected:
byte *m_buf;
@ -683,7 +800,7 @@ public:
ArrayXorSink(byte *buf, size_t size)
: ArraySink(buf, size) {}
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
byte * CreatePutSpace(size_t &size) {return BufferedTransformation::CreatePutSpace(size);}
};
@ -750,13 +867,25 @@ private:
lword m_size;
};
//! A Filter that pumps data into its attachment as input
//! \class Source
//! \brief Implementation of BufferedTransformation's attachment interface
//! \details Source is a cornerstone of the Pipeline trinitiy. Data flows from
//! Sources, through Filters, and then terminates in Sinks. The difference
//! between a Source and Filter is a Source \a pumps data, while a Filter does
//! not. The difference between a Filter and a Sink is a Filter allows an
//! attached transformation, while a Sink does not.
//! \details See the discussion of BufferedTransformation in cryptlib.h for
//! more details.
//! \sa Store and SourceTemplate
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting<Filter>
{
public:
Source(BufferedTransformation *attachment = NULL)
{Source::Detach(attachment);}
//! \name PIPELINE
//@{
lword Pump(lword pumpMax=size_t(SIZE_MAX))
{Pump2(pumpMax); return pumpMax;}
unsigned int PumpMessages(unsigned int count=UINT_MAX)
@ -768,6 +897,12 @@ public:
virtual size_t PumpAll2(bool blocking=true);
virtual bool SourceExhausted() const =0;
//@}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~Source() {}
#endif
protected:
void SourceInitialize(bool pumpAll, const NameValuePairs &parameters)
{
@ -777,7 +912,9 @@ protected:
}
};
//! Turn a Store into a Source
//! \class SourceTemplate
//! \brief Transform a Store into a Source
//! \tparam T the class or type
template <class T>
class SourceTemplate : public Source
{
@ -803,7 +940,8 @@ protected:
T m_store;
};
//! string-based implementation of Source interface
//! \class SourceTemplate
//! \brief String-based implementation of the Source interface
class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore>
{
public:

29
gcm.cpp
View File

@ -145,7 +145,8 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
if (HasCLMUL())
{
params.GetIntValue(Name::TableSize(), tableSize); // avoid "parameter not used" error
// Avoid "parameter not used" error and suppress Coverity finding
(void)params.GetIntValue(Name::TableSize(), tableSize);
tableSize = s_clmulTableSizeInBlocks * REQUIRED_BLOCKSIZE;
}
else
@ -579,7 +580,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
#ifdef __GNUC__
__asm__ __volatile__
(
".intel_syntax noprefix;"
INTEL_NOPREFIX
#elif defined(CRYPTOPP_GENERATE_X64_MASM)
ALIGN 8
GCM_AuthenticateBlocks_2K PROC FRAME
@ -683,7 +684,13 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
AS2( pxor xmm5, xmm2 )
AS2( psrldq xmm0, 15 )
#if defined(CRYPTOPP_APPLE_CLANG_VERSION)
AS2( mov WORD_REG(di), xmm0 )
#elif defined(CRYPTOPP_CLANG_VERSION)
AS2( movd edi, xmm0 )
#else
AS2( movd WORD_REG(di), xmm0 )
#endif
AS2( movzx eax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
AS2( shl eax, 8 )
@ -692,12 +699,24 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
AS2( pxor xmm4, xmm5 )
AS2( psrldq xmm1, 15 )
#if defined(CRYPTOPP_APPLE_CLANG_VERSION)
AS2( mov WORD_REG(di), xmm1 )
#elif defined(CRYPTOPP_CLANG_VERSION)
AS2( movd edi, xmm1 )
#else
AS2( movd WORD_REG(di), xmm1 )
#endif
AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
AS2( shl eax, 8 )
AS2( psrldq xmm0, 15 )
#if defined(CRYPTOPP_APPLE_CLANG_VERSION)
AS2( mov WORD_REG(di), xmm0 )
#elif defined(CRYPTOPP_CLANG_VERSION)
AS2( movd edi, xmm0 )
#else
AS2( movd WORD_REG(di), xmm0 )
#endif
AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
AS2( movd xmm0, eax )
@ -717,7 +736,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
#endif
#ifdef __GNUC__
".att_syntax prefix;"
ATT_PREFIX
:
: "c" (data), "d" (len/16), "S" (hashBuffer), "D" (s_reductionTable)
: "memory", "cc", "%eax"
@ -740,7 +759,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
#ifdef __GNUC__
__asm__ __volatile__
(
".intel_syntax noprefix;"
INTEL_NOPREFIX
#elif defined(CRYPTOPP_GENERATE_X64_MASM)
ALIGN 8
GCM_AuthenticateBlocks_64K PROC FRAME
@ -794,7 +813,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
AS2( movdqa [WORD_REG(si)], xmm0 )
#ifdef __GNUC__
".att_syntax prefix;"
ATT_PREFIX
:
: "c" (data), "d" (len/16), "S" (hashBuffer)
: "memory", "cc", "%edi", "%eax"

29
gcm.h
View File

@ -1,3 +1,9 @@
// gcm.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile gcm.h
//! \brief GCM block cipher mode of operation
#ifndef CRYPTOPP_GCM_H
#define CRYPTOPP_GCM_H
@ -6,10 +12,13 @@
NAMESPACE_BEGIN(CryptoPP)
//! .
//! \enum GCM_TablesOption
//! \brief Use either 2K or 64K size tables.
enum GCM_TablesOption {GCM_2K_Tables, GCM_64K_Tables};
//! .
//! \class GCM_Base
//! \brief CCM block cipher mode of operation.
//! \details Implementations and overrides in \p GCM_Base apply to both \p ENCRYPTION and \p DECRYPTION directions
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase
{
public:
@ -77,7 +86,14 @@ protected:
enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16};
};
//! .
//! \class GCM_Final
//! \brief Class specific methods used to operate the cipher.
//! \tparam T_BlockCipher block cipher
//! \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables
//! \tparam T_IsEncryption direction in which to operate the cipher
//! \details Implementations and overrides in \p GCM_Final apply to either
//! \p ENCRYPTION or \p DECRYPTION, depending on the template parameter \p T_IsEncryption.
//! \details \p GCM_Final does not use inner classes \p Enc and \p Dec.
template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption>
class GCM_Final : public GCM_Base
{
@ -93,7 +109,12 @@ private:
typename T_BlockCipher::Encryption m_cipher;
};
//! <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a>
//! \class GCM
//! \brief The GCM mode of operation
//! \tparam T_BlockCipher block cipher
//! \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables
//! \details \p GCM provides the \p Encryption and \p Decryption typedef.
//! \sa <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a> at the Crypto Lounge
template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables>
struct GCM : public AuthenticatedSymmetricCipherDocumentation
{

View File

@ -7,10 +7,11 @@
#include "cryptlib.h"
#include "algebra.h"
#include "words.h"
#include "randpool.h"
#include "filters.h"
#include "smartptr.h"
#include "words.h"
#include "misc.h"
#include "gf2n.h"
#include "asn.h"
#include "oids.h"
@ -324,6 +325,11 @@ PolynomialMod2 PolynomialMod2::Modulo(const PolynomialMod2 &b) const
PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n)
{
#if !defined(NDEBUG)
int x; CRYPTOPP_UNUSED(x);
assert(SafeConvert(n,x));
#endif
if (!reg.size())
return *this;
@ -352,8 +358,8 @@ PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n)
return *this;
}
int shiftWords = n / WORD_BITS;
int shiftBits = n % WORD_BITS;
const int shiftWords = n / WORD_BITS;
const int shiftBits = n % WORD_BITS;
if (shiftBits)
{
@ -369,8 +375,10 @@ PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n)
if (carry)
{
reg.Grow(reg.size()+shiftWords+1);
reg[reg.size()-1] = carry;
// Thanks to Apatryda, http://github.com/weidai11/cryptopp/issues/64
const size_t carryIndex = reg.size();
reg.Grow(reg.size()+shiftWords+!!shiftBits);
reg[carryIndex] = carry;
}
else
reg.Grow(reg.size()+shiftWords);
@ -677,6 +685,8 @@ const GF2NT::Element& GF2NT::MultiplicativeInverse(const Element &a) const
b[i] = b[i+1];
b[BitsToWords(m)-1] = 0;
// TODO: the shift by "t1+j" (64-bits) is being flagged as potential UB
// temp ^= ((temp >> j) & 1) << ((t1 + j) & (sizeof(temp)*8-1));
if (t1 < WORD_BITS)
for (unsigned int j=0; j<WORD_BITS-t1; j++)
temp ^= ((temp >> j) & 1) << (t1 + j);
@ -703,10 +713,18 @@ const GF2NT::Element& GF2NT::MultiplicativeInverse(const Element &a) const
ShiftWordsRightByBits(b, BitsToWords(m), k);
if (t1 < WORD_BITS)
{
for (unsigned int j=0; j<WORD_BITS-t1; j++)
{
// Coverity finding on shift amount of 'word x << (t1+j)'.
assert(t1+j < WORD_BITS);
temp ^= ((temp >> j) & 1) << (t1 + j);
}
}
else
{
b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS;
}
if (t1 % WORD_BITS)
b[t1/WORD_BITS] ^= temp >> (WORD_BITS - t1%WORD_BITS);

2
gf2n.h
View File

@ -112,7 +112,7 @@ public:
byte GetByte(size_t n) const;
//! the zero polynomial will return a degree of -1
signed int Degree() const {return BitCount()-1;}
signed int Degree() const {return (signed int)(BitCount()-1U);}
//! degree + 1
unsigned int CoefficientCount() const {return BitCount();}
//! return coefficient for x^i

View File

@ -11,14 +11,16 @@
#ifndef CRYPTOPP_IMPORTS
#include "gfpcrypt.h"
#include "integer.h"
#include "nbtheory.h"
#include "modarith.h"
#include "integer.h"
#include "asn.h"
#include "oids.h"
#include "misc.h"
NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void TestInstantiations_gfpcrypt()
{
GDSA<SHA>::Signer test;
@ -30,6 +32,7 @@ void TestInstantiations_gfpcrypt()
DLIES<>::Encryptor test6;
DLIES<>::Decryptor test7;
}
#endif
void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
{

View File

@ -524,7 +524,9 @@ public:
ConstByteArrayParameter encodingParameters;
parameters.GetValue(Name::EncodingParameters(), encodingParameters);
if (plaintextLength) // Coverity finding
xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
MAC mac(macKey);
mac.Update(ciphertext, plaintextLength);
mac.Update(encodingParameters.begin(), encodingParameters.size());
@ -566,7 +568,9 @@ public:
if (!mac.Verify(ciphertext + plaintextLength))
return DecodingResult();
if (plaintextLength) // Coverity finding
xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
return DecodingResult(plaintextLength);
}

View File

@ -37,7 +37,7 @@ void Gzip::WritePoststreamTail()
// *************************************************************
Gunzip::Gunzip(BufferedTransformation *attachment, bool repeat, int propagation)
: Inflator(attachment, repeat, propagation)
: Inflator(attachment, repeat, propagation), m_length(0)
{
}

4
gzip.h
View File

@ -13,9 +13,9 @@ class Gzip : public Deflator
{
public:
Gzip(BufferedTransformation *attachment=NULL, unsigned int deflateLevel=DEFAULT_DEFLATE_LEVEL, unsigned int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true)
: Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible) {}
: Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible), m_totalLen(0) {}
Gzip(const NameValuePairs &parameters, BufferedTransformation *attachment=NULL)
: Deflator(parameters, attachment) {}
: Deflator(parameters, attachment), m_totalLen(0) {}
protected:
enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header

View File

@ -19,7 +19,9 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TimerBase
{
public:
enum Unit {SECONDS = 0, MILLISECONDS, MICROSECONDS, NANOSECONDS};
TimerBase(Unit unit, bool stuckAtZero) : m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false) {}
TimerBase(Unit unit, bool stuckAtZero)
: m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false)
, m_start(0), m_last(0) {}
virtual TimerWord GetCurrentTimerValue() =0; // GetCurrentTime is a macro in MSVC 6.0
virtual TimerWord TicksPerSecond() =0; // this is not the resolution, just a conversion factor into seconds

7
ida.h
View File

@ -18,6 +18,7 @@ class RawIDA : public AutoSignaling<Unflushable<Multichannel<Filter> > >
{
public:
RawIDA(BufferedTransformation *attachment=NULL)
: m_threshold (0), m_channelsReady(0), m_channelsFinished(0)
{Detach(attachment);}
unsigned int GetThreshold() const {return m_threshold;}
@ -100,7 +101,7 @@ class InformationDispersal : public CustomFlushPropagation<Filter>
{
public:
InformationDispersal(int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true)
: m_ida(new OutputProxy(*this, true))
: m_ida(new OutputProxy(*this, true)), m_pad(false), m_nextChannel(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding));
@ -121,7 +122,7 @@ class InformationRecovery : public RawIDA
{
public:
InformationRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true)
: RawIDA(attachment)
: RawIDA(attachment), m_pad(false)
{IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));}
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
@ -138,7 +139,7 @@ class PaddingRemover : public Unflushable<Filter>
{
public:
PaddingRemover(BufferedTransformation *attachment=NULL)
: m_possiblePadding(false) {Detach(attachment);}
: m_possiblePadding(false), m_zeroCount(0) {Detach(attachment);}
void IsolatedInitialize(const NameValuePairs &parameters)
{CRYPTOPP_UNUSED(parameters); m_possiblePadding = false;}

View File

@ -19,12 +19,12 @@
#include "secblock.h"
#include "modarith.h"
#include "nbtheory.h"
#include "filters.h"
#include "smartptr.h"
#include "algparam.h"
#include "filters.h"
#include "asn.h"
#include "oids.h"
#include "words.h"
#include "algparam.h"
#include "pubkey.h" // for P1363_KDF2
#include "sha.h"
#include "cpu.h"
@ -44,24 +44,42 @@
#pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 instructions will be disabled.")
#endif
#define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || (CRYPTOPP_BOOL_X32 && !defined(CRYPTOPP_DISABLE_INTEGER_ASM))))
// "Inline assembly operands don't work with .intel_syntax",
// http://llvm.org/bugs/show_bug.cgi?id=24232
#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_INTEL_ASM)
# undef CRYPTOPP_X86_ASM_AVAILABLE
# undef CRYPTOPP_X32_ASM_AVAILABLE
# undef CRYPTOPP_X64_ASM_AVAILABLE
# undef CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
# undef CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
# define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0
# define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0
#else
# define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86)
#endif
NAMESPACE_BEGIN(CryptoPP)
// Debian QEMU/ARMEL issue in MultiplyTop; see https://github.com/weidai11/cryptopp/issues/31.
// The symptoms speak to undefined behavior, but we have not been able to locate it. It could
// also be a compiler or linker issue (very possible because it only surfaces for ARMEL and
// GCC 5.2, and not other Debian cross-compilers, like ARM64 and ARMHF).
// TODO: revisit this in the future
// Debian QEMU/ARMEL issue in MultiplyTop; see http://github.com/weidai11/cryptopp/issues/31.
#if __ARMEL__ && (CRYPTOPP_GCC_VERSION >= 50200) && (CRYPTOPP_GCC_VERSION < 50300) && __OPTIMIZE__
# define WORKAROUND_ARMEL_BUG 1
#endif
// Debian QEMU/ARM64 issue in Integer or ModularArithmetic; see http://github.com/weidai11/cryptopp/issues/61.
#if (__aarch64__ || __AARCH64EL__) && (CRYPTOPP_GCC_VERSION >= 50200) && (CRYPTOPP_GCC_VERSION < 50300)
# define WORKAROUND_ARM64_BUG 1
#endif
#if WORKAROUND_ARMEL_BUG
# pragma GCC push_options
# pragma GCC optimize("O1")
#endif
#if WORKAROUND_ARM64_BUG
# pragma GCC push_options
# pragma GCC optimize("no-devirtualize")
#endif
bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt)
{
if (valueType != typeid(Integer))
@ -197,13 +215,20 @@ static word AtomicInverseModPower2(word A)
class DWord
{
public:
// Converity finding on default ctor. We've isntrumented the code,
// and cannot uncover a case where it affects a result.
#if (defined(__COVERITY__) || !defined(NDEBUG)) && defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE)
// Repeating pattern of 1010 for debug builds to break things...
DWord() : m_whole(0) {memset(&m_whole, 0xa, sizeof(m_whole));}
#elif (defined(__COVERITY__) || !defined(NDEBUG)) && !defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE)
// Repeating pattern of 1010 for debug builds to break things...
DWord() : m_halfs() {memset(&m_halfs, 0xa, sizeof(m_halfs));}
#else
DWord() {}
#endif
#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
explicit DWord(word low)
{
m_whole = low;
}
explicit DWord(word low) : m_whole(low) {}
#else
explicit DWord(word low)
{
@ -225,6 +250,8 @@ public:
r.m_whole = (dword)a * b;
#elif defined(MultiplyWordsLoHi)
MultiplyWordsLoHi(r.m_halfs.low, r.m_halfs.high, a, b);
#else
assert(0);
#endif
return r;
}
@ -322,17 +349,19 @@ private:
class Word
{
public:
// Converity finding on default ctor. We've isntrumented the code,
// and cannot uncover a case where it affects a result.
#if defined(__COVERITY__)
Word() : m_whole(0) {}
#elif !defined(NDEBUG)
// Repeating pattern of 1010 for debug builds to break things...
Word() : m_whole(0) {memset(&m_whole, 0xa, sizeof(m_whole));}
#else
Word() {}
#endif
Word(word value)
{
m_whole = value;
}
Word(hword low, hword high)
{
m_whole = low | (word(high) << (WORD_BITS/2));
}
Word(word value) : m_whole(value) {}
Word(hword low, hword high) : m_whole(low | (word(high) << (WORD_BITS/2))) {}
static Word Multiply(hword a, hword b)
{
@ -469,13 +498,13 @@ inline word DWord::operator%(word a)
// ********************************************************
// use some tricks to share assembly code between MSVC and GCC
// Use some tricks to share assembly code between MSVC and GCC
#if defined(__GNUC__)
#define AddPrologue \
int result; \
__asm__ __volatile__ \
( \
".intel_syntax noprefix;"
INTEL_NOPREFIX
#define AddEpilogue \
".att_syntax prefix;" \
: "=a" (result)\
@ -563,7 +592,7 @@ int Baseline_Add(size_t N, word *C, const word *A, const word *B)
word result;
__asm__ __volatile__
(
".intel_syntax;"
INTEL_NOPREFIX
AS1( neg %1)
ASJ( jz, 1, f)
AS2( mov %0,[%3+8*%1])
@ -582,7 +611,7 @@ int Baseline_Add(size_t N, word *C, const word *A, const word *B)
ASL(1)
AS2( mov %0, 0)
AS2( adc %0, %0)
".att_syntax;"
ATT_NOPREFIX
: "=&r" (result), "+c" (N)
: "r" (C+N), "r" (A+N), "r" (B+N)
: "memory", "cc"
@ -595,7 +624,7 @@ int Baseline_Sub(size_t N, word *C, const word *A, const word *B)
word result;
__asm__ __volatile__
(
".intel_syntax;"
INTEL_NOPREFIX
AS1( neg %1)
ASJ( jz, 1, f)
AS2( mov %0,[%3+8*%1])
@ -614,7 +643,7 @@ int Baseline_Sub(size_t N, word *C, const word *A, const word *B)
ASL(1)
AS2( mov %0, 0)
AS2( adc %0, %0)
".att_syntax;"
ATT_NOPREFIX
: "=&r" (result), "+c" (N)
: "r" (C+N), "r" (A+N), "r" (B+N)
: "memory", "cc"
@ -3446,8 +3475,8 @@ std::ostream& operator<<(std::ostream& out, const Integer &a)
static const char lower[]="0123456789abcdef";
const char* vec = (out.flags() & std::ios::uppercase) ? upper : lower;
unsigned i=0;
SecBlock<char> s(a.BitCount() / (BitPrecision(base)-1) + 1);
unsigned int i=0;
SecBlock<char> s(a.BitCount() / (SaturatingSubtract1(BitPrecision(base),1U)) + 1);
while (!!temp1)
{
@ -3463,6 +3492,7 @@ std::ostream& operator<<(std::ostream& out, const Integer &a)
// if (i && !(i%block))
// out << ",";
}
return out << suffix;
}
@ -4271,10 +4301,104 @@ const Integer& MontgomeryRepresentation::MultiplicativeInverse(const Integer &a)
return m_result;
}
// Specialization declared in misc.h to allow us to print integers
// with additional control options, like arbirary bases and uppercase.
template <> CRYPTOPP_DLL
std::string IntToString<Integer>(Integer value, unsigned int base)
{
// Hack... set the high bit for uppercase. Set the next bit fo a suffix.
static const unsigned int BIT_32 = (1U << 31);
const bool UPPER = !!(base & BIT_32);
static const unsigned int BIT_31 = (1U << 30);
const bool BASE = !!(base & BIT_31);
const char CH = UPPER ? 'A' : 'a';
base &= ~(BIT_32|BIT_31);
assert(base >= 2 && base <= 32);
if (value == 0)
return "0";
bool negative = false, zero = false;
if (value.IsNegative())
{
negative = true;
value.Negate();
}
if (!value)
zero = true;
SecBlock<char> s(value.BitCount() / (SaturatingSubtract1(BitPrecision(base),1U)) + 1);
Integer temp;
unsigned int i=0;
while (!!value)
{
word digit;
Integer::Divide(digit, temp, value, word(base));
s[i++]=char((digit < 10 ? '0' : (CH - 10)) + digit);
value.swap(temp);
}
std::string result;
result.reserve(i+2);
if (negative)
result += '-';
if (zero)
result += '0';
while (i--)
result += s[i];
if (BASE)
{
if (base == 10)
result += '.';
else if (base == 16)
result += 'h';
else if (base == 8)
result += 'o';
else if (base == 2)
result += 'b';
}
return result;
}
// Specialization declared in misc.h to avoid Coverity findings.
template <> CRYPTOPP_DLL
std::string IntToString<unsigned long long>(unsigned long long value, unsigned int base)
{
// Hack... set the high bit for uppercase.
static const unsigned int HIGH_BIT = (1U << 31);
const char CH = !!(base & HIGH_BIT) ? 'A' : 'a';
base &= ~HIGH_BIT;
assert(base >= 2);
if (value == 0)
return "0";
std::string result;
while (value > 0)
{
unsigned long long digit = value % base;
result = char((digit < 10 ? '0' : (CH - 10)) + digit) + result;
value /= base;
}
return result;
}
NAMESPACE_END
#if WORKAROUND_ARMEL_BUG
# pragma GCC pop_options
#endif
#if WORKAROUND_ARM64_BUG
# pragma GCC pop_options
#endif
#endif

358
integer.h
View File

@ -5,174 +5,262 @@
#include "cryptlib.h"
#include "secblock.h"
#include "stdcpp.h"
#include <iosfwd>
#include <algorithm>
#if CRYPTOPP_BOOL_X32
# define CRYPTOPP_DISABLE_INTEGER_ASM
#endif
NAMESPACE_BEGIN(CryptoPP)
struct InitializeInteger // used to initialize static variables
//! \struct InitializeInteger
//! Performs static intialization of the Integer class
struct InitializeInteger
{
InitializeInteger();
};
typedef SecBlock<word, AllocatorWithCleanup<word, CRYPTOPP_BOOL_X86> > IntegerSecBlock;
//! multiple precision integer and basic arithmetics
/*! This class can represent positive and negative integers
with absolute value less than (256**sizeof(word)) ** (256**sizeof(int)).
\nosubgrouping
*/
//! \brief Multiple precision integer with arithmetic operations
//! \details The Integer class can represent positive and negative integers
//! with absolute value less than (256**sizeof(word))<sup>(256**sizeof(int))</sup>.
//! \details Internally, the library uses a sign magnitude representation, and the class
//! has two data members. The first is a IntegerSecBlock (a SecBlock<word>) and it i
//! used to hold the representation. The second is a Sign, and its is used to track
//! the sign of the Integer.
//! \nosubgrouping
class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object
{
public:
//! \name ENUMS, EXCEPTIONS, and TYPEDEFS
//@{
//! division by zero exception
//! \brief Exception thrown when division by 0 is encountered
class DivideByZero : public Exception
{
public:
DivideByZero() : Exception(OTHER_ERROR, "Integer: division by zero") {}
};
//!
//! \brief Exception thrown when a random number cannot be found that
//! satisfies the condition
class RandomNumberNotFound : public Exception
{
public:
RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {}
};
//!
enum Sign {POSITIVE=0, NEGATIVE=1};
//! \enum Sign
//! \brief Used internally to represent the integer
//! \details Sign is used internally to represent the integer. It is also used in a few API functions.
//! \sa Signedness
enum Sign {
//! \brief the value is positive or 0
POSITIVE=0,
//! \brief the value is negative
NEGATIVE=1};
//!
//! \enum Signedness
//! \brief Used when importing and exporting integers
//! \details Signedness is usually used in API functions.
//! \sa Sign
enum Signedness {
//!
//! \brief an unsigned value
UNSIGNED,
//!
//! \brief a signed value
SIGNED};
//!
//! \enum RandomNumberType
//! \brief Properties of a random integer
enum RandomNumberType {
//!
//! \brief a number with no special properties
ANY,
//!
//! \brief a number which is probabilistically prime
PRIME};
//@}
//! \name CREATORS
//@{
//! creates the zero integer
//! \brief Creates the zero integer
Integer();
//! copy constructor
Integer(const Integer& t);
//! convert from signed long
//! \brief Convert from signed long
Integer(signed long value);
//! convert from lword
Integer(Sign s, lword value);
//! \brief Convert from lword
//! \param sign enumeration indicating Sign
//! \param value the long word
Integer(Sign sign, lword value);
//! convert from two words
Integer(Sign s, word highWord, word lowWord);
//! \brief Convert from two words
//! \param sign enumeration indicating Sign
//! \param highWord the high word
//! \param lowWord the low word
Integer(Sign sign, word highWord, word lowWord);
//! convert from string
/*! str can be in base 2, 8, 10, or 16. Base is determined by a
case insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10.
*/
//! \brief Convert from a C-string
//! \param str C-string value
//! \details \p str can be in base 2, 8, 10, or 16. Base is determined by a case
//! insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10.
explicit Integer(const char *str);
//! \brief Convert from a wide C-string
//! \param str wide C-string value
//! \details \p str can be in base 2, 8, 10, or 16. Base is determined by a case
//! insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10.
explicit Integer(const wchar_t *str);
//! convert from big-endian byte array
Integer(const byte *encodedInteger, size_t byteCount, Signedness s=UNSIGNED);
//! \brief Convert from a big-endian byte array
//! \param encodedInteger big-endian byte array
//! \param byteCount length of the byte array
//! \param sign enumeration indicating Signedness
Integer(const byte *encodedInteger, size_t byteCount, Signedness sign=UNSIGNED);
//! convert from big-endian form stored in a BufferedTransformation
Integer(BufferedTransformation &bt, size_t byteCount, Signedness s=UNSIGNED);
//! \brief Convert from a big-endian array
//! \param bt BufferedTransformation object with big-endian byte array
//! \param byteCount length of the byte array
//! \param sign enumeration indicating Signedness
Integer(BufferedTransformation &bt, size_t byteCount, Signedness sign=UNSIGNED);
//! convert from BER encoded byte array stored in a BufferedTransformation object
//! \brief Convert from a BER encoded byte array
//! \param bt BufferedTransformation object with BER encoded byte array
explicit Integer(BufferedTransformation &bt);
//! create a random integer
/*! The random integer created is uniformly distributed over [0, 2**bitcount). */
Integer(RandomNumberGenerator &rng, size_t bitcount);
//! \brief Create a random integer
//! \param rng RandomNumberGenerator used to generate material
//! \param bitCount the number of bits in the resulting integer
//! \details The random integer created is uniformly distributed over <tt>[0, 2<sup>bitCount</sup>]</tt>.
Integer(RandomNumberGenerator &rng, size_t bitCount);
//! avoid calling constructors for these frequently used integers
//! \brief Integer representing 0
//! \returns an Integer representing 0
//! \details Zero() avoids calling constructors for frequently used integers
static const Integer & CRYPTOPP_API Zero();
//! avoid calling constructors for these frequently used integers
//! \brief Integer representing 1
//! \returns an Integer representing 1
//! \details One() avoids calling constructors for frequently used integers
static const Integer & CRYPTOPP_API One();
//! avoid calling constructors for these frequently used integers
//! \brief Integer representing 2
//! \returns an Integer representing 2
//! \details Two() avoids calling constructors for frequently used integers
static const Integer & CRYPTOPP_API Two();
//! create a random integer of special type
/*! Ideally, the random integer created should be uniformly distributed
over {x | min <= x <= max and x is of rnType and x % mod == equiv}.
However the actual distribution may not be uniform because sequential
search is used to find an appropriate number from a random starting
point.
May return (with very small probability) a pseudoprime when a prime
is requested and max > lastSmallPrime*lastSmallPrime (lastSmallPrime
is declared in nbtheory.h).
\throw RandomNumberNotFound if the set is empty.
*/
//! \brief Create a random integer of special form
//! \param rng RandomNumberGenerator used to generate material
//! \param min the minimum value
//! \param max the maximum value
//! \param rnType RandomNumberType to specify the type
//! \param equiv the equivalence class based on the parameter \p mod
//! \param mod the modulus used to reduce the equivalence class
//! \throw RandomNumberNotFound if the set is empty.
//! \details Ideally, the random integer created should be uniformly distributed
//! over <tt>{x | min \<= x \<= max</tt> and \p x is of rnType and <tt>x \% mod == equiv}</tt>.
//! However the actual distribution may not be uniform because sequential
//! search is used to find an appropriate number from a random starting
//! point.
//! \details May return (with very small probability) a pseudoprime when a prime
//! is requested and <tt>max \> lastSmallPrime*lastSmallPrime</tt>. \p lastSmallPrime
//! is declared in nbtheory.h.
Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One());
//! return the integer 2**e
//! \brief Exponentiates to a power of 2
//! \returns the Integer 2<sup>e</sup>
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
static Integer CRYPTOPP_API Power2(size_t e);
//@}
//! \name ENCODE/DECODE
//@{
//! minimum number of bytes to encode this integer
/*! MinEncodedSize of 0 is 1 */
size_t MinEncodedSize(Signedness=UNSIGNED) const;
//! encode in big-endian format
/*! unsigned means encode absolute value, signed means encode two's complement if negative.
if outputLen < MinEncodedSize, the most significant bytes will be dropped
if outputLen > MinEncodedSize, the most significant bytes will be padded
*/
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const;
//!
void Encode(BufferedTransformation &bt, size_t outputLen, Signedness=UNSIGNED) const;
//! \brief The minimum number of bytes to encode this integer
//! \param sign enumeration indicating Signedness
//! \note The MinEncodedSize() of 0 is 1.
size_t MinEncodedSize(Signedness sign=UNSIGNED) const;
//! encode using Distinguished Encoding Rules, put result into a BufferedTransformation object
//! \brief Encode in big-endian format
//! \param output big-endian byte array
//! \param outputLen length of the byte array
//! \param sign enumeration indicating Signedness
//! \details Unsigned means encode absolute value, signed means encode two's complement if negative.
//! \details outputLen can be used to ensure an Integer is encoded to an exact size (rather than a
//! minimum size). An exact size is useful, for example, when encoding to a field element size.
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const;
//! \brief Encode in big-endian format
//! \param bt BufferedTransformation object
//! \param outputLen length of the encoding
//! \param sign enumeration indicating Signedness
//! \details Unsigned means encode absolute value, signed means encode two's complement if negative.
//! \details outputLen can be used to ensure an Integer is encoded to an exact size (rather than a
//! minimum size). An exact size is useful, for example, when encoding to a field element size.
void Encode(BufferedTransformation &bt, size_t outputLen, Signedness sign=UNSIGNED) const;
//! \brief Encode in DER format
//! \param bt BufferedTransformation object
//! \details Encodes the Integer using Distinguished Encoding Rules
//! The result is placed into a BufferedTransformation object
void DEREncode(BufferedTransformation &bt) const;
//! encode absolute value as big-endian octet string
//! \param bt BufferedTransformation object
//! \param length the number of mytes to decode
void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const;
//! encode absolute value in OpenPGP format, return length of output
//! \brief Encode absolute value in OpenPGP format
//! \param output big-endian byte array
//! \param bufferSize length of the byte array
//! \returns length of the output
//! \details OpenPGPEncode places result into a BufferedTransformation object and returns the
//! number of bytes used for the encoding
size_t OpenPGPEncode(byte *output, size_t bufferSize) const;
//! encode absolute value in OpenPGP format, put result into a BufferedTransformation object
//! \brief Encode absolute value in OpenPGP format
//! \param bt BufferedTransformation object
//! \returns length of the output
//! \details OpenPGPEncode places result into a BufferedTransformation object and returns the
//! number of bytes used for the encoding
size_t OpenPGPEncode(BufferedTransformation &bt) const;
//!
void Decode(const byte *input, size_t inputLen, Signedness=UNSIGNED);
//!
//* Precondition: bt.MaxRetrievable() >= inputLen
void Decode(BufferedTransformation &bt, size_t inputLen, Signedness=UNSIGNED);
//! \brief Decode from big-endian byte array
//! \param input big-endian byte array
//! \param inputLen length of the byte array
//! \param sign enumeration indicating Signedness
void Decode(const byte *input, size_t inputLen, Signedness sign=UNSIGNED);
//!
//! \brief Decode nonnegative value from big-endian byte array
//! \param bt BufferedTransformation object
//! \param inputLen length of the byte array
//! \param sign enumeration indicating Signedness
//! \note <tt>bt.MaxRetrievable() \>= inputLen</tt>.
void Decode(BufferedTransformation &bt, size_t inputLen, Signedness sign=UNSIGNED);
//! \brief Decode from BER format
//! \param input big-endian byte array
//! \param inputLen length of the byte array
void BERDecode(const byte *input, size_t inputLen);
//!
//! \brief Decode from BER format
//! \param bt BufferedTransformation object
void BERDecode(BufferedTransformation &bt);
//! decode nonnegative value as big-endian octet string
//! \brief Decode nonnegative value from big-endian octet string
//! \param bt BufferedTransformation object
//! \param length length of the byte array
void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length);
//! \brief Exception thrown when an error is encountered decoding an OpenPGP integer
class OpenPGPDecodeErr : public Exception
{
public:
OpenPGPDecodeErr() : Exception(INVALID_DATA_FORMAT, "OpenPGP decode error") {}
};
//!
//! \brief Decode from OpenPGP format
//! \param input big-endian byte array
//! \param inputLen length of the byte array
void OpenPGPDecode(const byte *input, size_t inputLen);
//!
//! \brief Decode from OpenPGP format
//! \param bt BufferedTransformation object
void OpenPGPDecode(BufferedTransformation &bt);
//@}
@ -225,14 +313,17 @@ public:
//!
Integer& operator-=(const Integer& t);
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator*=(const Integer& t) {return *this = Times(t);}
//!
Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
//!
Integer& operator/=(word t) {return *this = DividedBy(t);}
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));}
//!
@ -240,12 +331,35 @@ public:
//!
Integer& operator>>=(size_t);
//!
void Randomize(RandomNumberGenerator &rng, size_t bitcount);
//!
//! \brief Set this Integer to random integer
//! \param rng RandomNumberGenerator used to generate material
//! \param bitCount the number of bits in the resulting integer
//! \details The random integer created is uniformly distributed over <tt>[0, 2<sup>bitCount</sup>]</tt>.
void Randomize(RandomNumberGenerator &rng, size_t bitCount);
//! \brief Set this Integer to random integer
//! \param rng RandomNumberGenerator used to generate material
//! \param min the minimum value
//! \param max the maximum value
//! \details The random integer created is uniformly distributed over <tt>[min, max]</tt>.
void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max);
//! set this Integer to a random element of {x | min <= x <= max and x is of rnType and x % mod == equiv}
/*! returns false if the set is empty */
//! \brief Set this Integer to random integer of special form
//! \param rng RandomNumberGenerator used to generate material
//! \param min the minimum value
//! \param max the maximum value
//! \param rnType RandomNumberType to specify the type
//! \param equiv the equivalence class based on the parameter \p mod
//! \param mod the modulus used to reduce the equivalence class
//! \throw RandomNumberNotFound if the set is empty.
//! \details Ideally, the random integer created should be uniformly distributed
//! over <tt>{x | min \<= x \<= max</tt> and \p x is of rnType and <tt>x \% mod == equiv}</tt>.
//! However the actual distribution may not be uniform because sequential
//! search is used to find an appropriate number from a random starting
//! point.
//! \details May return (with very small probability) a pseudoprime when a prime
//! is requested and <tt>max \> lastSmallPrime*lastSmallPrime</tt>. \p lastSmallPrime
//! is declared in nbtheory.h.
bool Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv=Zero(), const Integer &mod=One());
bool GenerateRandomNoThrow(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs);
@ -255,19 +369,24 @@ public:
throw RandomNumberNotFound();
}
//! set the n-th bit to value
//! \brief Set the n-th bit to value
//! \details 0-based numbering.
void SetBit(size_t n, bool value=1);
//! set the n-th byte to value
//! \brief Set the n-th byte to value
//! \details 0-based numbering.
void SetByte(size_t n, byte value);
//!
//! \brief Reverse the Sign of the Integer
void Negate();
//!
//! \brief Sets the Integer to positive
void SetPositive() {sign = POSITIVE;}
//!
//! \brief Sets the Integer to negative
void SetNegative() {if (!!(*this)) sign = NEGATIVE;}
//!
//! \brief Swaps this Integer with another Integer
void swap(Integer &a);
//@}
@ -291,11 +410,11 @@ public:
//! \name BINARY OPERATORS
//@{
//! signed comparison
/*! \retval -1 if *this < a
\retval 0 if *this = a
\retval 1 if *this > a
*/
//! \brief Perform signed comparison
//! \param a the Integer to comapre
//! \retval -1 if <tt>*this < a</tt>
//! \retval 0 if <tt>*this = a</tt>
//! \retval 1 if <tt>*this > a</tt>
int Compare(const Integer& a) const;
//!
@ -303,14 +422,17 @@ public:
//!
Integer Minus(const Integer &b) const;
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Times(const Integer &b) const;
//!
Integer DividedBy(const Integer &b) const;
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Modulo(const Integer &b) const;
//!
Integer DividedBy(word b) const;
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
word Modulo(word b) const;
//!
@ -326,6 +448,7 @@ public:
//!
Integer Doubled() const {return Plus(*this);}
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Squared() const {return Times(*this);}
//! extract square root, if negative return 0, else return floor of square root
Integer SquareRoot() const;
@ -337,11 +460,6 @@ public:
//! return inverse if 1 or -1, otherwise return 0
Integer MultiplicativeInverse() const;
//! modular multiplication
CRYPTOPP_DLL friend Integer CRYPTOPP_API a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
//! modular exponentiation
CRYPTOPP_DLL friend Integer CRYPTOPP_API a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
//! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
//! use a faster division algorithm when divisor is short
@ -353,34 +471,59 @@ public:
//! greatest common divisor
static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n);
//! calculate multiplicative inverse of *this mod n
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer InverseMod(const Integer &n) const;
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
word InverseMod(word n) const;
//@}
//! \name INPUT/OUTPUT
//@{
//!
//! \brief Extraction operator
//! \param in a reference to a std::istream
//! \param a a reference to an Integer
//! \returns a reference to a std::istream reference
friend CRYPTOPP_DLL std::istream& CRYPTOPP_API operator>>(std::istream& in, Integer &a);
//!
//! \brief Insertion operator
//! \param out a reference to a std::ostream
//! \param a a constant reference to an Integer
//! \returns a reference to a std::ostream reference
//! \details The output integer responds to std::hex, std::oct, std::hex, std::upper and
//! std::lower. The output includes the suffix \a \b h (for hex), \a \b . (\a \b dot, for dec)
//! and \a \b o (for octal). There is currently no way to supress the suffix.
//! \details If you want to print an Integer without the suffix or using an arbitrary base, then
//! use IntToString<Integer>().
//! \sa IntToString<Integer>
friend CRYPTOPP_DLL std::ostream& CRYPTOPP_API operator<<(std::ostream& out, const Integer &a);
//@}
#ifndef CRYPTOPP_DOXYGEN_PROCESSING
//! modular multiplication
CRYPTOPP_DLL friend Integer CRYPTOPP_API a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
//! modular exponentiation
CRYPTOPP_DLL friend Integer CRYPTOPP_API a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
#endif
private:
Integer(word value, size_t length);
int PositiveCompare(const Integer &t) const;
IntegerSecBlock reg;
Sign sign;
#ifndef CRYPTOPP_DOXYGEN_PROCESSING
friend class ModularArithmetic;
friend class MontgomeryRepresentation;
friend class HalfMontgomeryRepresentation;
Integer(word value, size_t length);
int PositiveCompare(const Integer &t) const;
friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b);
friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b);
friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b);
friend void PositiveDivide(Integer &remainder, Integer &quotient, const Integer &dividend, const Integer &divisor);
IntegerSecBlock reg;
Sign sign;
#endif
};
//!
@ -400,14 +543,17 @@ inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::I
//!
inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);}
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);}
//!
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);}
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);}
//!
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);}
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);}
NAMESPACE_END

View File

@ -18,7 +18,7 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte
if (m_countHi < oldCountHi || SafeRightShift<2*8*sizeof(HashWordType)>(len) != 0)
throw HashInputTooLong(this->AlgorithmName());
unsigned int blockSize = this->BlockSize();
const unsigned int blockSize = this->BlockSize();
unsigned int num = ModPowerOf2(oldCountLo, blockSize);
T* dataBuf = this->DataBuf();

View File

@ -10,12 +10,14 @@
NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void LUC_TestInstantiations()
{
LUC_HMP<SHA>::Signer t1;
LUCFunction t2;
InvertibleLUCFunction t3;
}
#endif
void DL_Algorithm_LUC_HMP::Sign(const DL_GroupParameters<Integer> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
{

View File

@ -9,10 +9,12 @@
NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 {
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void MD5_TestInstantiations()
{
MD5 x;
}
#endif
void MD5::InitState(HashWordType *state)
{

View File

@ -11,18 +11,24 @@
#include "misc.h"
#include "words.h"
#include <new>
#include "words.h"
#include "stdcpp.h"
#include "integer.h"
// for memalign
#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX)
#include <malloc.h>
# include <malloc.h>
#endif
NAMESPACE_BEGIN(CryptoPP)
void xorbuf(byte *buf, const byte *mask, size_t count)
{
size_t i;
assert(buf != NULL);
assert(mask != NULL);
assert(count > 0);
size_t i=0;
if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
{
if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))
@ -51,8 +57,11 @@ void xorbuf(byte *buf, const byte *mask, size_t count)
void xorbuf(byte *output, const byte *input, const byte *mask, size_t count)
{
size_t i;
assert(output != NULL);
assert(input != NULL);
assert(count > 0);
size_t i=0;
if (IsAligned<word32>(output) && IsAligned<word32>(input) && IsAligned<word32>(mask))
{
if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(output) && IsAligned<word64>(input) && IsAligned<word64>(mask))
@ -83,7 +92,11 @@ void xorbuf(byte *output, const byte *input, const byte *mask, size_t count)
bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
{
size_t i;
assert(buf != NULL);
assert(mask != NULL);
assert(count > 0);
size_t i=0;
byte acc8 = 0;
if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
@ -139,7 +152,9 @@ void CallNewHandler()
void * AlignedAllocate(size_t size)
{
byte *p;
#ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
#if defined(CRYPTOPP_APPLE_ALLOC_AVAILABLE)
while ((p = (byte *)calloc(1, size)) == NULL)
#elif defined(CRYPTOPP_MM_MALLOC_AVAILABLE)
while ((p = (byte *)_mm_malloc(size, 16)) == NULL)
#elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
while ((p = (byte *)memalign(16, size)) == NULL)

533
misc.h

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,8 @@
// modarith.h - written and placed in the public domain by Wei Dai
//! \file modarith.h
//! \brief Class file for performing modular arithmetic.
#ifndef CRYPTOPP_MODARITH_H
#define CRYPTOPP_MODARITH_H
@ -15,8 +20,10 @@ CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup<Integer>;
CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing<Integer>;
CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain<Integer>;
//! ring of congruence classes modulo n
/*! \note this implementation represents each congruence class as the smallest non-negative integer in that class */
//! \class ModularArithmetic
//! \brief Ring of congruence classes modulo n
//! \note this implementation represents each congruence class as the smallest
//! non-negative integer in that class
class CRYPTOPP_DLL ModularArithmetic : public AbstractRing<Integer>
{
public:
@ -25,10 +32,9 @@ public:
typedef Integer Element;
ModularArithmetic(const Integer &modulus = Integer::One())
: m_modulus(modulus), m_result((word)0, modulus.reg.size()) {}
: AbstractRing<Integer>(), m_modulus(modulus), m_result((word)0, modulus.reg.size()) {}
ModularArithmetic(const ModularArithmetic &ma)
: AbstractRing<Integer>(ma), m_modulus(ma.m_modulus), m_result((word)0, m_modulus.reg.size()) {}
: AbstractRing<Integer>(), m_modulus(ma.m_modulus), m_result((word)0, ma.m_modulus.reg.size()) {}
ModularArithmetic(BufferedTransformation &bt); // construct from BER encoded parameters
@ -40,7 +46,8 @@ public:
void BERDecodeElement(BufferedTransformation &in, Element &a) const;
const Integer& GetModulus() const {return m_modulus;}
void SetModulus(const Integer &newModulus) {m_modulus = newModulus; m_result.reg.resize(m_modulus.reg.size());}
void SetModulus(const Integer &newModulus)
{m_modulus = newModulus; m_result.reg.resize(m_modulus.reg.size());}
virtual bool IsMontgomeryRepresentation() const {return false;}
@ -111,6 +118,10 @@ public:
static const RandomizationParameter DefaultRandomizationParameter ;
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~ModularArithmetic() {}
#endif
protected:
Integer m_modulus;
mutable Integer m_result, m_result1;
@ -119,8 +130,10 @@ protected:
// const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ;
//! do modular arithmetics in Montgomery representation for increased speed
/*! \note the Montgomery representation represents each congruence class [a] as a*r%n, where r is a convenient power of 2 */
//! \class MontgomeryRepresentation
//! \brief Performs modular arithmetic in Montgomery representation for increased speed
//! \details The Montgomery representation represents each congruence class <tt>[a]</tt> as
//! <tt>a*r%n</tt>, where r is a convenient power of 2.
class CRYPTOPP_DLL MontgomeryRepresentation : public ModularArithmetic
{
public:
@ -150,6 +163,10 @@ public:
void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
{AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~MontgomeryRepresentation() {}
#endif
private:
Integer m_u;
mutable IntegerSecBlock m_workspace;

View File

@ -13,7 +13,7 @@
NAMESPACE_BEGIN(CryptoPP)
#ifndef NDEBUG
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Modes_TestInstantiations()
{
CFB_Mode<DES>::Encryption m0;
@ -35,19 +35,23 @@ void CipherModeBase::ResizeBuffers()
void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount)
{
assert(input);
assert(output);
assert(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
assert(m_feedbackSize == BlockSize());
unsigned int s = BlockSize();
const unsigned int s = BlockSize();
if (dir == ENCRYPTION)
{
m_cipher->ProcessAndXorBlock(m_register, input, output);
if (iterationCount > 1)
m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0);
memcpy(m_register, output+(iterationCount-1)*s, s);
}
else
{
memcpy(m_temp, input+(iterationCount-1)*s, s); // make copy first in case of in-place decryption
if (iterationCount > 1)
m_cipher->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection);
m_cipher->ProcessAndXorBlock(m_register, input, output);
memcpy(m_register, m_temp, s);

70
modes.h
View File

@ -1,9 +1,11 @@
// modes.h - written and placed in the public domain by Wei Dai
//! \file modes.h
//! \brief Class file for modes of operation.
#ifndef CRYPTOPP_MODES_H
#define CRYPTOPP_MODES_H
/*! \file
*/
#include "cryptlib.h"
#include "secblock.h"
#include "misc.h"
@ -13,17 +15,18 @@
NAMESPACE_BEGIN(CryptoPP)
//! Cipher modes documentation. See NIST SP 800-38A for definitions of these modes. See AuthenticatedSymmetricCipherDocumentation for authenticated encryption modes.
/*! Each class derived from this one defines two types, Encryption and Decryption,
both of which implement the SymmetricCipher interface.
For each mode there are two classes, one of which is a template class,
and the other one has a name that ends in "_ExternalCipher".
The "external cipher" mode objects hold a reference to the underlying block cipher,
instead of holding an instance of it. The reference must be passed in to the constructor.
For the "cipher holder" classes, the CIPHER template parameter should be a class
derived from BlockCipherDocumentation, for example DES or AES.
*/
//! \class CipherModeDocumentation
//! \brief Classes for operating block cipher modes of operation
//! \details Each class derived from this one defines two types, Encryption and Decryption,
//! both of which implement the SymmetricCipher interface.
//! For each mode there are two classes, one of which is a template class,
//! and the other one has a name that ends in "_ExternalCipher".
//! The "external cipher" mode objects hold a reference to the underlying block cipher,
//! instead of holding an instance of it. The reference must be passed in to the constructor.
//! For the "cipher holder" classes, the CIPHER template parameter should be a class
//! derived from BlockCipherDocumentation, for example DES or AES.
//! \details See NIST SP 800-38A for definitions of these modes. See
//! AuthenticatedSymmetricCipherDocumentation for authenticated encryption modes.
struct CipherModeDocumentation : public SymmetricCipherDocumentation
{
};
@ -292,7 +295,9 @@ public:
{return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();}
};
//! _
//! \class CipherModeFinalTemplate_ExternalCipher
//! \tparam BASE CipherModeFinalTemplate_CipherHolder class
//! \brief OFB block cipher mode of operation.
template <class BASE>
class CipherModeFinalTemplate_ExternalCipher : public BASE
{
@ -311,7 +316,8 @@ CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAb
CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
//! CFB mode
//! \class CFB_Mode
//! \brief CFB block cipher mode of operation.
template <class CIPHER>
struct CFB_Mode : public CipherModeDocumentation
{
@ -319,14 +325,17 @@ struct CFB_Mode : public CipherModeDocumentation
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
};
//! CFB mode, external cipher
//! \class CFB_Mode_ExternalCipher
//! \brief CFB mode, external cipher.
struct CFB_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
};
//! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A
//! \class CFB_FIPS_Mode
//! \brief CFB block cipher mode of operation providing FIPS validated cryptography.
//! \details Requires full block plaintext according to FIPS 800-38A
template <class CIPHER>
struct CFB_FIPS_Mode : public CipherModeDocumentation
{
@ -334,7 +343,9 @@ struct CFB_FIPS_Mode : public CipherModeDocumentation
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption;
};
//! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A, external cipher
//! \class CFB_FIPS_Mode_ExternalCipher
//! \brief CFB mode, external cipher, providing FIPS validated cryptography.
//! \details Requires full block plaintext according to FIPS 800-38A
struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption;
@ -343,7 +354,8 @@ struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> >;
//! OFB mode
//! \class OFB_Mode
//! \brief OFB block cipher mode of operation.
template <class CIPHER>
struct OFB_Mode : public CipherModeDocumentation
{
@ -351,7 +363,8 @@ struct OFB_Mode : public CipherModeDocumentation
typedef Encryption Decryption;
};
//! OFB mode, external cipher
//! \class OFB_Mode_ExternalCipher
//! \brief OFB mode, external cipher.
struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
@ -361,7 +374,8 @@ struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> >;
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > >;
//! CTR mode
//! \class CTR_Mode
//! \brief CTR block cipher mode of operation.
template <class CIPHER>
struct CTR_Mode : public CipherModeDocumentation
{
@ -369,14 +383,16 @@ struct CTR_Mode : public CipherModeDocumentation
typedef Encryption Decryption;
};
//! CTR mode, external cipher
//! \class CTR_Mode_ExternalCipher
//! \brief CTR mode, external cipher.
struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
};
//! ECB mode
//! \class ECB_Mode
//! \brief ECB block cipher mode of operation.
template <class CIPHER>
struct ECB_Mode : public CipherModeDocumentation
{
@ -386,7 +402,8 @@ struct ECB_Mode : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ECB_OneWay>;
//! ECB mode, external cipher
//! \class ECB_Mode_ExternalCipher
//! \brief ECB mode, external cipher.
struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
@ -422,7 +439,8 @@ struct CBC_CTS_Mode : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption>;
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption>;
//! CBC mode with ciphertext stealing, external cipher
//! \class CBC_CTS_Mode_ExternalCipher
//! \brief CBC mode with ciphertext stealing, external cipher
struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;

View File

@ -5,9 +5,11 @@
NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void TestInstantiations_MQV()
{
MQV mqv;
}
#endif
NAMESPACE_END

1
mqv.h
View File

@ -6,6 +6,7 @@
#include "cryptlib.h"
#include "gfpcrypt.h"
#include "modarith.h"
#include "integer.h"
#include "misc.h"

6
oids.h
View File

@ -1,3 +1,9 @@
// oids.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile oids.h
//! \brief Object identifiers for algorthms and schemes
#ifndef CRYPTOPP_OIDS_H
#define CRYPTOPP_OIDS_H

View File

@ -47,7 +47,7 @@ void CRYPTOPP_NOINLINE Panama_SSE2_Pull(size_t count, word32 *state, word32 *z,
#if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
asm __volatile__
(
".intel_syntax noprefix;"
INTEL_NOPREFIX
AS_PUSH_IF86( bx)
#else
AS2( mov AS_REG_1, count)
@ -297,7 +297,7 @@ void CRYPTOPP_NOINLINE Panama_SSE2_Pull(size_t count, word32 *state, word32 *z,
#if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
AS_POP_IF86( bx)
".att_syntax prefix;"
ATT_PREFIX
:
#if CRYPTOPP_BOOL_X64
: "D" (count), "S" (state), "d" (z), "c" (y)

17
pch.h
View File

@ -1,12 +1,15 @@
// pch.h - written and placed in the public domain by Wei Dai
//! \headerfile pch.h
//! \brief Precompiled header file
#ifndef CRYPTOPP_PCH_H
#define CRYPTOPP_PCH_H
#ifdef CRYPTOPP_GENERATE_X64_MASM
# ifdef CRYPTOPP_GENERATE_X64_MASM
#include "cpu.h"
#else
# else
#include "config.h"
#ifdef USE_PRECOMPILED_HEADERS
@ -14,8 +17,8 @@
#include "secblock.h"
#include "misc.h"
#include "smartptr.h"
#include "stdcpp.h"
#endif
# endif
#endif
#endif
#endif // CRYPTOPP_PCH_H

View File

@ -1,3 +1,8 @@
// pkcspad.h - written and placed in the public domain by Wei Dai
//! \headerfile pkcspad.h
//! \brief Classes for PKCS padding schemes
#ifndef CRYPTOPP_PKCSPAD_H
#define CRYPTOPP_PKCSPAD_H

View File

@ -1,3 +1,10 @@
// polynomi.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile polynomi.h
//! \brief Classes for polynomial basis and operations
#ifndef CRYPTOPP_POLYNOMI_H
#define CRYPTOPP_POLYNOMI_H

View File

@ -77,6 +77,7 @@ void PSSR_MEM_Base::ComputeMessageRepresentative(RandomNumberGenerator &rng,
GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize, false);
byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1;
xorStart[0] ^= 1;
if (recoverableMessage && recoverableMessageLength)
xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength);
xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size());
if (hashIdentifier.first && hashIdentifier.second)
@ -114,6 +115,8 @@ DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative(
size_t &recoverableMessageLength = result.messageLength;
valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid;
if (hashIdentifier.first && hashIdentifier.second)
valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid;
GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize);

6
pssr.h
View File

@ -1,3 +1,9 @@
// pssr.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile pssr.h
//! \brief Classes for probablistic signature schemes
#ifndef CRYPTOPP_PSSR_H
#define CRYPTOPP_PSSR_H

157
pubkey.h
View File

@ -56,23 +56,61 @@
NAMESPACE_BEGIN(CryptoPP)
//! _
//! \class TrapdoorFunctionBounds
//! \brief Provides range for plaintext and ciphertext lengths
//! \details A trapdoor function is a function that is easy to compute in one direction,
//! but difficult to compute in the opposite direction without special knowledge.
//! The special knowledge is usually the private key.
//! \details Trapdoor functions only handle messages of a limited length or size.
//! \p MaxPreimage is the plaintext's maximum length, and \p MaxImage is the
//! ciphertext's maximum length.
//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
{
public:
virtual ~TrapdoorFunctionBounds() {}
//! \brief Returns the maximum size of a message before the trapdoor function is applied
//! \returns the maximum size of a message before the trapdoor function is applied
//! \details Derived classes must implement \p PreimageBound().
virtual Integer PreimageBound() const =0;
//! \brief Returns the maximum size of a message after the trapdoor function is applied
//! \returns the maximum size of a message after the trapdoor function is applied
//! \details Derived classes must implement \p ImageBound().
virtual Integer ImageBound() const =0;
//! \brief Returns the maximum size of a message before the trapdoor function is applied bound to a public key
//! \returns the maximum size of a message before the trapdoor function is applied bound to a public key
//! \details The default implementation returns <tt>PreimageBound() - 1</tt>.
virtual Integer MaxPreimage() const {return --PreimageBound();}
//! \brief Returns the maximum size of a message after the trapdoor function is applied bound to a public key
//! \returns the the maximum size of a message after the trapdoor function is applied bound to a public key
//! \details The default implementation returns <tt>ImageBound() - 1</tt>.
virtual Integer MaxImage() const {return --ImageBound();}
};
//! _
//! \class RandomizedTrapdoorFunction
//! \brief Applies the trapdoor function, using random data if required
//! \details \p ApplyFunction() is the foundation for encrypting a message under a public key.
//! Derived classes will override it at some point.
//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
{
public:
//! \brief Applies the trapdoor function, using random data if required
//! \param rng a \p RandomNumberGenerator derived class
//! \param x the message on which the encryption function is applied
//! \returns the message \p x encrypted under the public key
//! \details \p ApplyRandomizedFunction is a generalization of encryption under a public key
//! cryptosystem. The \p RandomNumberGenerator may (or may not) be required.
//! Derived classes must implement it.
virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
//! \brief Determines if the encryption algorithm is randomized
//! \returns \p true if the encryption algorithm is randominzed, \p false otherwise
//! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
virtual bool IsRandomized() const {return true;}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
@ -80,40 +118,87 @@ public:
#endif
};
//! _
//! \class TrapdoorFunction
//! \brief Applies the trapdoor function
//! \details \p ApplyFunction() is the foundation for encrypting a message under a public key.
//! Derived classes will override it at some point.
//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
{
public:
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~TrapdoorFunction() { }
#endif
//! \brief Applies the trapdoor function
//! \param rng a \p RandomNumberGenerator derived class
//! \param x the message on which the encryption function is applied
//! \details \p ApplyRandomizedFunction is a generalization of encryption under a public key
//! cryptosystem. The \p RandomNumberGenerator may (or may not) be required.
//! \details Internally, \p ApplyRandomizedFunction() calls \p ApplyFunction() \a
//! without the \p RandomNumberGenerator.
Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
{CRYPTOPP_UNUSED(rng); return ApplyFunction(x);}
bool IsRandomized() const {return false;}
//! \brief Applies the trapdoor
//! \param x the message on which the encryption function is applied
//! \returns the message \p x encrypted under the public key
//! \details \p ApplyFunction is a generalization of encryption under a public key
//! cryptosystem. Derived classes must implement it.
virtual Integer ApplyFunction(const Integer &x) const =0;
};
//! _
//! \class RandomizedTrapdoorFunctionInverse
//! \brief Applies the inverse of the trapdoor function, using random data if required
//! \details \p CalculateInverse() is the foundation for decrypting a message under a private key
//! in a public key cryptosystem. Derived classes will override it at some point.
//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
{
public:
virtual ~RandomizedTrapdoorFunctionInverse() {}
//! \brief Applies the inverse of the trapdoor function, using random data if required
//! \param rng a \p RandomNumberGenerator derived class
//! \param x the message on which the decryption function is applied
//! \returns the message \p x decrypted under the private key
//! \details \p CalculateRandomizedInverse is a generalization of decryption using the private key
//! The \p RandomNumberGenerator may (or may not) be required. Derived classes must implement it.
virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
//! \brief Determines if the decryption algorithm is randomized
//! \returns \p true if the decryption algorithm is randominzed, \p false otherwise
//! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
virtual bool IsRandomized() const {return true;}
};
//! _
//! \class TrapdoorFunctionInverse
//! \brief Applies the inverse of the trapdoor function
//! \details \p CalculateInverse() is the foundation for decrypting a message under a private key
//! in a public key cryptosystem. Derived classes will override it at some point.
//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
{
public:
virtual ~TrapdoorFunctionInverse() {}
//! \brief Applies the inverse of the trapdoor function
//! \param rng a \p RandomNumberGenerator derived class
//! \param x the message on which the decryption function is applied
//! \returns the message \p x decrypted under the private key
//! \details \p CalculateRandomizedInverse is a generalization of decryption using the private key
//! \details Internally, \p CalculateRandomizedInverse() calls \p CalculateInverse() \a
//! without the \p RandomNumberGenerator.
Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
{return CalculateInverse(rng, x);}
//! \brief Determines if the decryption algorithm is randomized
//! \returns \p true if the decryption algorithm is randominzed, \p false otherwise
//! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
bool IsRandomized() const {return false;}
virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
@ -121,7 +206,8 @@ public:
// ********************************************************
//! message encoding method for public key encryption
//! \class PK_EncryptionMessageEncodingMethod
//! \brief Message encoding method for public key encryption
class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
{
public:
@ -140,7 +226,10 @@ public:
// ********************************************************
//! _
//! \class TF_Base
//! \brief The base for trapdoor based cryptosystems
//! \tparam TFI trapdoor function interface derived class
//! \tparam MEI message encoding interface derived class
template <class TFI, class MEI>
class CRYPTOPP_NO_VTABLE TF_Base
{
@ -160,7 +249,9 @@ protected:
// ********************************************************
//! _
//! \class PK_FixedLengthCryptoSystemImpl
//! \brief Public key trapdoor function base class
//! \tparam BASE public key cryptosystem with a fixed length
template <class BASE>
class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
{
@ -178,7 +269,10 @@ public:
#endif
};
//! _
//! \class TF_CryptoSystemBase
//! \brief Trapdoor function cryptosystem base class
//! \tparam INTERFACE public key cryptosystem base interface
//! \tparam BASE public key cryptosystem implementation base
template <class INTERFACE, class BASE>
class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
{
@ -189,14 +283,16 @@ public:
protected:
size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
size_t PaddedBlockBitLength() const {return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
// Coverity finding on potential overflow/underflow.
size_t PaddedBlockBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().PreimageBound().BitCount(),1U);}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~TF_CryptoSystemBase() { }
#endif
};
//! _
//! \class TF_DecryptorBase
//! \brief Trapdoor function cryptosystems decryption base class
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
{
public:
@ -207,7 +303,8 @@ public:
#endif
};
//! _
//! \class TF_DecryptorBase
//! \brief Trapdoor function cryptosystems encryption base class
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
{
public:
@ -222,7 +319,12 @@ public:
typedef std::pair<const byte *, size_t> HashIdentifier;
//! interface for message encoding method for public key signature schemes
//! \class PK_SignatureMessageEncodingMethod
//! \brief Interface for message encoding method for public key signature schemes.
//! \details \p PK_SignatureMessageEncodingMethod provides interfaces for message
//! encoding method for public key signature schemes. The methods support both
//! trapdoor functions (<tt>TF_*</tt>) and discrete logarithm (<tt>DL_*</tt>)
//! based schemes.
class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
{
public:
@ -295,6 +397,10 @@ public:
};
};
//! \class PK_DeterministicSignatureMessageEncodingMethod
//! \brief Interface for message encoding method for public key signature schemes.
//! \details \p PK_DeterministicSignatureMessageEncodingMethod provides interfaces
//! for message encoding method for public key signature schemes.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
{
public:
@ -303,6 +409,10 @@ public:
byte *representative, size_t representativeBitLength) const;
};
//! \class PK_RecoverableSignatureMessageEncodingMethod
//! \brief Interface for message encoding method for public key signature schemes.
//! \details \p PK_RecoverableSignatureMessageEncodingMethod provides interfaces
//! for message encoding method for public key signature schemes.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
{
public:
@ -311,6 +421,10 @@ public:
byte *representative, size_t representativeBitLength) const;
};
//! \class DL_SignatureMessageEncodingMethod_DSA
//! \brief Interface for message encoding method for public key signature schemes.
//! \details \p DL_SignatureMessageEncodingMethod_DSA provides interfaces
//! for message encoding method for DSA.
class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
{
public:
@ -320,6 +434,10 @@ public:
byte *representative, size_t representativeBitLength) const;
};
//! \class DL_SignatureMessageEncodingMethod_NR
//! \brief Interface for message encoding method for public key signature schemes.
//! \details \p DL_SignatureMessageEncodingMethod_NR provides interfaces
//! for message encoding method for Nyberg-Rueppel.
class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
{
public:
@ -329,6 +447,10 @@ public:
byte *representative, size_t representativeBitLength) const;
};
//! \class PK_MessageAccumulatorBase
//! \brief Interface for message encoding method for public key signature schemes.
//! \details \p PK_MessageAccumulatorBase provides interfaces
//! for message encoding method.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
{
public:
@ -347,6 +469,10 @@ public:
bool m_empty;
};
//! \class PK_MessageAccumulatorImpl
//! \brief Interface for message encoding method for public key signature schemes.
//! \details \p PK_MessageAccumulatorBase provides interfaces
//! for message encoding method.
template <class HASH_ALGORITHM>
class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
{
@ -379,7 +505,8 @@ public:
protected:
size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
size_t MessageRepresentativeBitLength() const {return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
// Coverity finding on potential overflow/underflow.
size_t MessageRepresentativeBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().ImageBound().BitCount(),1U);}
virtual HashIdentifier GetHashIdentifier() const =0;
virtual size_t GetDigestSize() const =0;
};

View File

@ -132,7 +132,7 @@ public:
ByteQueue::ByteQueue(size_t nodeSize)
: Bufferless<BufferedTransformation>(), m_autoNodeSize(!nodeSize), m_nodeSize(nodeSize)
, m_head(NULL), m_tail(NULL), m_lazyString(NULL), m_lazyLength(0)
, m_head(NULL), m_tail(NULL), m_lazyString(NULL), m_lazyLength(0), m_lazyStringModifiable(false)
{
SetNodeSize(nodeSize);
m_head = m_tail = new ByteQueueNode(m_nodeSize);

View File

@ -1,4 +1,8 @@
// specification file for an unlimited queue for storing bytes
// queue.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile queue.h
//! \brief Classes for an unlimited queue to store bytes
#ifndef CRYPTOPP_QUEUE_H
#define CRYPTOPP_QUEUE_H
@ -66,7 +70,8 @@ public:
{
public:
Walker(const ByteQueue &queue)
: m_queue(queue) {Initialize();}
: m_queue(queue), m_node(NULL), m_position(0), m_offset(0), m_lazyString(NULL), m_lazyLength(0)
{Initialize();}
lword GetCurrentPosition() {return m_position;}

View File

@ -1,9 +1,12 @@
// rabin.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile rabin.h
//! \brief Classes Rabin encryption and signature schemes
#ifndef CRYPTOPP_RABIN_H
#define CRYPTOPP_RABIN_H
/** \file
*/
#include "cryptlib.h"
#include "oaep.h"
#include "pssr.h"

30
rc2.h
View File

@ -1,16 +1,18 @@
// rc2.h - written and placed in the public domain by Wei Dai
//! \file rc2.h
//! \brief Class file for the RC2 stream cipher
#ifndef CRYPTOPP_RC2_H
#define CRYPTOPP_RC2_H
/** \file
*/
#include "seckey.h"
#include "secblock.h"
#include "algparam.h"
NAMESPACE_BEGIN(CryptoPP)
//! _
//! \class RC2_Info
//! \brief The RC2 cipher's key, iv, block size and name information.
struct RC2_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 128>
{
CRYPTOPP_CONSTANT(DEFAULT_EFFECTIVE_KEYLENGTH = 1024)
@ -18,9 +20,14 @@ struct RC2_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 128>
static const char *StaticAlgorithmName() {return "RC2";}
};
/// <a href="http://www.weidai.com/scan-mirror/cs.html#RC2">RC2</a>
//! \class RC2
//! \brief The RC2 stream cipher
//! \sa <a href="http://www.weidai.com/scan-mirror/cs.html#RC2">RC2</a> on the Crypto Lounge.
class RC2 : public RC2_Info, public BlockCipherDocumentation
{
//! \class Base
//! \brief Class specific methods used to operate the cipher.
//! \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions
class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<RC2_Info>
{
public:
@ -31,12 +38,18 @@ class RC2 : public RC2_Info, public BlockCipherDocumentation
FixedSizeSecBlock<word16, 64> K; // expanded key table
};
//! \class Enc
//! \brief Class specific methods used to operate the cipher in the forward direction.
//! \details Implementations and overrides in \p Enc apply to \p ENCRYPTION.
class CRYPTOPP_NO_VTABLE Enc : public Base
{
public:
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
};
//! \class Dec
//! \brief Class specific methods used to operate the cipher in the reverse direction.
//! \details Implementations and overrides in \p Dec apply to \p DECRYPTION.
class CRYPTOPP_NO_VTABLE Dec : public Base
{
public:
@ -44,6 +57,10 @@ class RC2 : public RC2_Info, public BlockCipherDocumentation
};
public:
//! \class Encryption
//! \brief Class specific methods used to operate the cipher in the forward direction.
//! \details Implementations and overrides in \p Encryption apply to \p ENCRYPTION.
class Encryption : public BlockCipherFinal<ENCRYPTION, Enc>
{
public:
@ -54,6 +71,9 @@ public:
{SetKey(key, keyLen, MakeParameters("EffectiveKeyLength", effectiveKeyLen));}
};
//! \class Decryption
//! \brief Class specific methods used to operate the cipher in the reverse direction.
//! \details Implementations and overrides in \p Decryption apply to \p DECRYPTION.
class Decryption : public BlockCipherFinal<DECRYPTION, Dec>
{
public:

View File

@ -617,7 +617,7 @@ CRYPTOPP_NAKED void CRYPTOPP_FASTCALL Rijndael_Enc_AdvancedProcessBlocks(void *l
#elif defined(__GNUC__)
__asm__ __volatile__
(
".intel_syntax noprefix;"
INTEL_NOPREFIX
#if CRYPTOPP_BOOL_X64
AS2( mov L_REG, rcx)
#endif
@ -972,7 +972,7 @@ CRYPTOPP_NAKED void CRYPTOPP_FASTCALL Rijndael_Enc_AdvancedProcessBlocks(void *l
Rijndael_Enc_AdvancedProcessBlocks ENDP
#endif
#ifdef __GNUC__
".att_syntax prefix;"
ATT_PREFIX
:
: "c" (locals), "d" (k), "S" (Te), "D" (g_cacheLineSize)
: "memory", "cc", "%eax"

View File

@ -1,9 +1,12 @@
// rijndael.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile rijndael.h
//! \brief Classes for Rijndael encryption algorithm
#ifndef CRYPTOPP_RIJNDAEL_H
#define CRYPTOPP_RIJNDAEL_H
/** \file
*/
#include "seckey.h"
#include "secblock.h"

18
rng.h
View File

@ -1,4 +1,10 @@
// rng.h - misc RNG related classes, see also osrng.h, randpool.h
//! rng.h - written and placed in the public domain by Wei Dai
//! \file rng.h
//! \brief Miscellaneous classes for RNGs
//! \details This file contains miscellaneous classes for RNGs, including LC_RNG(),
//! X917RNG() and MaurerRandomnessTest()
//! \sa osrng.h, randpool.h
#ifndef CRYPTOPP_RNG_H
#define CRYPTOPP_RNG_H
@ -47,10 +53,12 @@ private:
SecByteBlock randseed, m_lastBlock, m_deterministicTimeVector;
};
/** This class implements Maurer's Universal Statistical Test for Random Bit Generators
it is intended for measuring the randomness of *PHYSICAL* RNGs.
For more details see his paper in Journal of Cryptology, 1992. */
//! \class MaurerRandomnessTest
//! \brief Maurer's Universal Statistical Test for Random Bit Generators
//! \details This class implements Maurer's Universal Statistical Test for
//! Random Bit Generators. It is intended for measuring the randomness of
//! *PHYSICAL* RNGs.
//! \details For more details see Maurer's paper in Journal of Cryptology, 1992.
class MaurerRandomnessTest : public Bufferless<Sink>
{
public:

View File

@ -3,14 +3,14 @@
#include "pch.h"
#include "rsa.h"
#include "asn.h"
#include "sha.h"
#include "oids.h"
#include "modarith.h"
#include "nbtheory.h"
#include "sha.h"
#include "algparam.h"
#include "fips140.h"
#if !defined(NDEBUG) && !defined(CRYPTOPP_IS_DLL)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) && !defined(CRYPTOPP_IS_DLL)
#include "pssr.h"
NAMESPACE_BEGIN(CryptoPP)
void RSA_TestInstantiations()
@ -108,11 +108,13 @@ void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const Nam
int modulusSize = 2048;
alg.GetIntValue(Name::ModulusSize(), modulusSize) || alg.GetIntValue(Name::KeySize(), modulusSize);
assert(modulusSize >= 16);
if (modulusSize < 16)
throw InvalidArgument("InvertibleRSAFunction: specified modulus size is too small");
m_e = alg.GetValueWithDefault(Name::PublicExponent(), Integer(17));
assert(m_e >= 3); assert(!m_e.IsEven());
if (m_e < 3 || m_e.IsEven())
throw InvalidArgument("InvertibleRSAFunction: invalid public exponent");

12
rsa.h
View File

@ -1,11 +1,13 @@
// rsa.h - written and placed in the public domain by Wei Dai
//! \file rsa.h
//! \brief Classes for the RSA cryptosystem
//! \details This file contains classes that implement the RSA
//! ciphers and signature schemes as defined in PKCS #1 v2.0.
#ifndef CRYPTOPP_RSA_H
#define CRYPTOPP_RSA_H
/** \file
This file contains classes that implement the RSA
ciphers and signature schemes as defined in PKCS #1 v2.0.
*/
#include "cryptlib.h"
#include "pubkey.h"
#include "integer.h"

3
rw.cpp
View File

@ -4,8 +4,9 @@
#include "rw.h"
#include "asn.h"
#include "nbtheory.h"
#include "integer.h"
#include "nbtheory.h"
#include "modarith.h"
#ifndef CRYPTOPP_IMPORTS

10
rw.h
View File

@ -1,10 +1,12 @@
// rw.h - written and placed in the public domain by Wei Dai
//! \file rw.h
//! \brief Classes for Rabin-Williams signature schemes
//! \details Rabin-Williams signature schemes as defined in IEEE P1363.
#ifndef CRYPTOPP_RW_H
#define CRYPTOPP_RW_H
/** \file
This file contains classes that implement the
Rabin-Williams signature schemes as defined in IEEE P1363.
*/
#include "cryptlib.h"
#include "pubkey.h"

View File

@ -16,19 +16,28 @@
# pragma warning(disable: 4702 4740)
#endif
// TODO: work around GCC 4.9+ issue with SSE2 ASM until the exact details are known
// TODO: work around GCC 4.8+ issue with SSE2 ASM until the exact details are known
// and fix is released. Duplicate with "valgrind ./cryptest.exe tv salsa"
#if (CRYPTOPP_GCC_VERSION >= 40900)
// Clang due to "Inline assembly operands don't work with .intel_syntax"
// https://llvm.org/bugs/show_bug.cgi?id=24232
#if defined(CRYPTOPP_DISABLE_SALSA_ASM)
# undef CRYPTOPP_X86_ASM_AVAILABLE
# undef CRYPTOPP_X32_ASM_AVAILABLE
# undef CRYPTOPP_X64_ASM_AVAILABLE
# undef CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
# undef CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
# define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0
# define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0
#endif
NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Salsa20_TestInstantiations()
{
Salsa20::Encryption x;
}
#endif
void Salsa20_Policy::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
{
@ -66,7 +75,7 @@ void Salsa20_Policy::SeekToIteration(lword iterationCount)
m_state[5] = (word32)SafeRightShift<32>(iterationCount);
}
#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SALSA_ASM)
unsigned int Salsa20_Policy::GetAlignment() const
{
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
@ -164,7 +173,7 @@ void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output
#ifdef __GNUC__
__asm__ __volatile__
(
".intel_syntax noprefix;"
INTEL_NOPREFIX
AS_PUSH_IF86( bx)
#else
void *s = m_state.data();
@ -472,7 +481,7 @@ void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output
AS_POP_IF86( bp)
#ifdef __GNUC__
AS_POP_IF86( bx)
".att_syntax prefix;"
ATT_PREFIX
#if CRYPTOPP_BOOL_X64
: "+r" (input), "+r" (output), "+r" (iterationCount)
: "r" (m_rounds), "r" (m_state.m_ptr), "r" (workspace)

29
salsa.h
View File

@ -1,14 +1,26 @@
// salsa.h - written and placed in the public domain by Wei Dai
//! \file
//! \headerfile salsa.h
//! \brief Classes for Salsa encryption scheme
#ifndef CRYPTOPP_SALSA_H
#define CRYPTOPP_SALSA_H
#include "strciphr.h"
#include "secblock.h"
// TODO: work around GCC 4.8+ issue with SSE2 ASM until the exact details are known
// and fix is released. Duplicate with "valgrind ./cryptest.exe tv salsa"
// "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232
#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_INTEL_ASM) || (CRYPTOPP_GCC_VERSION >= 40800)
# define CRYPTOPP_DISABLE_SALSA_ASM
#endif
NAMESPACE_BEGIN(CryptoPP)
//! _
//! \class Salsa20_Info
//! \brief Salsa block cipher information
struct Salsa20_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8>
{
static const char *StaticAlgorithmName() {return "Salsa20";}
@ -22,7 +34,7 @@ protected:
void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
bool CipherIsRandomAccess() const {return true;}
void SeekToIteration(lword iterationCount);
#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SALSA_ASM)
unsigned int GetAlignment() const;
unsigned int GetOptimalBlockSize() const;
#endif
@ -31,14 +43,18 @@ protected:
int m_rounds;
};
/// <a href="http://www.cryptolounge.org/wiki/Salsa20">Salsa20</a>, variable rounds: 8, 12 or 20 (default 20)
// <a href="http://www.cryptolounge.org/wiki/Salsa20">Salsa20</a>, variable rounds: 8, 12 or 20 (default 20)
//! \class Salsa20
//! \brief Salsa20 block cipher information
//! \details Salsa20 provides a variable number of rounds: 8, 12 or 20. The default number of rounds is 20.
struct Salsa20 : public Salsa20_Info, public SymmetricCipherDocumentation
{
typedef SymmetricCipherFinal<ConcretePolicyHolder<Salsa20_Policy, AdditiveCipherTemplate<> >, Salsa20_Info> Encryption;
typedef Encryption Decryption;
};
//! _
//! \class XSalsa20_Info
//! \brief XSalsa20 block cipher information
struct XSalsa20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24>
{
static const char *StaticAlgorithmName() {return "XSalsa20";}
@ -54,7 +70,10 @@ protected:
FixedSizeSecBlock<word32, 8> m_key;
};
/// <a href="http://www.cryptolounge.org/wiki/XSalsa20">XSalsa20</a>, variable rounds: 8, 12 or 20 (default 20)
// <a href="http://www.cryptolounge.org/wiki/XSalsa20">XSalsa20</a>, variable rounds: 8, 12 or 20 (default 20)
//! \class XSalsa20
//! \brief XSalsa20 block cipher information
//! \details XSalsa20 provides a variable number of rounds: 8, 12 or 20. The default number of rounds is 20.
struct XSalsa20 : public XSalsa20_Info, public SymmetricCipherDocumentation
{
typedef SymmetricCipherFinal<ConcretePolicyHolder<XSalsa20_Policy, AdditiveCipherTemplate<> >, XSalsa20_Info> Encryption;

Some files were not shown because too many files have changed in this diff Show More