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) NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ThreeWay_TestInstantiations() void ThreeWay_TestInstantiations()
{ {
ThreeWay::Encryption x1; ThreeWay::Encryption x1;
ThreeWay::Decryption x2; ThreeWay::Decryption x2;
} }
#endif
static const word32 START_E = 0x0b0b; // round constant of first encryption round static const word32 START_E = 0x0b0b; // round constant of first encryption round
static const word32 START_D = 0xb1b1; // round constant of first decryption round static const word32 START_D = 0xb1b1; // round constant of first decryption round

2
3way.h
View File

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

View File

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

View File

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

View File

@ -206,7 +206,8 @@ template <class Element, class Iterator> Element GeneralCascadeMultiplication(co
struct WindowSlider struct WindowSlider
{ {
WindowSlider(const Integer &expIn, bool fastNegate, unsigned int windowSizeIn=0) 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) if (windowSize == 0)
{ {

View File

@ -1,14 +1,15 @@
// algebra.h - written and placed in the public domain by Wei Dai // algebra.h - written and placed in the public domain by Wei Dai
//! \file //! \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 #ifndef CRYPTOPP_ALGEBRA_H
#define CRYPTOPP_ALGEBRA_H #define CRYPTOPP_ALGEBRA_H
#include "config.h" #include "config.h"
#include "integer.h"
#include "misc.h" #include "misc.h"
#include "integer.h"
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)

View File

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

View File

@ -13,10 +13,12 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 { namespace Weak1 {
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ARC4_TestInstantiations() void ARC4_TestInstantiations()
{ {
ARC4 x; ARC4 x;
} }
#endif
ARC4_Base::~ARC4_Base() 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 // arc4.h - written and placed in the public domain by Wei Dai
//! \file //! \file
//! \brief Implementation of ARC4 //! \headerfile arc4.h
//! \brief Classes for ARC4 cipher
#ifndef CRYPTOPP_ARC4_H #ifndef CRYPTOPP_ARC4_H
#define CRYPTOPP_ARC4_H #define CRYPTOPP_ARC4_H
@ -16,7 +17,8 @@ NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 { namespace Weak1 {
//! \class ARC4_Base //! \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 class CRYPTOPP_NO_VTABLE ARC4_Base : public VariableKeyLength<16, 1, 256>, public RandomNumberGenerator, public SymmetricCipher, public SymmetricCipherDocumentation
{ {
public: public:
@ -47,7 +49,10 @@ protected:
//! <a href="http://www.weidai.com/scan-mirror/cs.html#RC4">Alleged RC4</a> //! <a href="http://www.weidai.com/scan-mirror/cs.html#RC4">Alleged RC4</a>
DOCUMENTED_TYPEDEF(SymmetricCipherFinal<ARC4_Base>, ARC4) 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 class CRYPTOPP_NO_VTABLE MARC4_Base : public ARC4_Base
{ {
public: public:
@ -60,7 +65,6 @@ protected:
unsigned int GetDefaultDiscardBytes() const {return 256;} 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) DOCUMENTED_TYPEDEF(SymmetricCipherFinal<MARC4_Base>, MARC4)
} }

View File

@ -1,7 +1,7 @@
// argnames.h - written and placed in the public domain by Wei Dai // argnames.h - written and placed in the public domain by Wei Dai
//! \file //! \file argnames.h
//! \brief Standard names for retrieving values when working with \p NameValuePairs //! \brief Standard names for retrieving values by name when working with \p NameValuePairs
#ifndef CRYPTOPP_ARGNAMES_H #ifndef CRYPTOPP_ARGNAMES_H
#define 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(DigestSize) //!< int, in bytes
CRYPTOPP_DEFINE_NAME_STRING(L1KeyLength) //!< int, in bytes CRYPTOPP_DEFINE_NAME_STRING(L1KeyLength) //!< int, in bytes
CRYPTOPP_DEFINE_NAME_STRING(TableSize) //!< 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(Blinding) //!< bool
CRYPTOPP_DEFINE_NAME_STRING(DerivedLength) //< int, key derivation, derived key length 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
DOCUMENTED_NAMESPACE_END DOCUMENTED_NAMESPACE_END
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 // asn.h - written and placed in the public domain by Wei Dai
//! \file //! \file
//! \headerfile asn.h
//! \brief Classes and functions for working with ANS.1 objects //! \brief Classes and functions for working with ANS.1 objects
#ifndef CRYPTOPP_ASN_H #ifndef CRYPTOPP_ASN_H
@ -348,7 +349,9 @@ void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
BERDecodeError(); BERDecodeError();
size_t bc; size_t bc;
BERLengthDecode(in, bc); bool definite = BERLengthDecode(in, bc);
if (!definite)
BERDecodeError();
SecByteBlock buf(bc); SecByteBlock buf(bc);

View File

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

View File

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

View File

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

View File

@ -17,6 +17,7 @@
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
#include <iostream> #include <iostream>
#include <sstream>
#include <iomanip> #include <iomanip>
// These are noisy enoguh due to test.cpp. Turn them off here. // 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; const double CLOCK_TICKS_PER_SECOND = 1000000.0;
#endif #endif
double logtotal = 0, g_allocatedTime, g_hertz; double logtotal = 0.0, g_allocatedTime = 0, g_hertz = 0;
unsigned int logcount = 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) 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); double mbs = length / timeTaken / (1024*1024);
cout << "\n<TR><TH>" << name; out << "\n<TR><TH>" << name;
// cout << "<TD>" << setprecision(3) << length / (1024*1024); // out << "<TD>" << setprecision(3) << length / (1024*1024);
cout << setiosflags(ios::fixed); out << setiosflags(ios::fixed);
// cout << "<TD>" << setprecision(3) << timeTaken; // out << "<TD>" << setprecision(3) << timeTaken;
cout << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << mbs; out << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << mbs;
if (g_hertz) if (g_hertz)
cout << "<TD>" << setprecision(1) << setiosflags(ios::fixed) << timeTaken * g_hertz / length; out << "<TD>" << setprecision(1) << setiosflags(ios::fixed) << timeTaken * g_hertz / length;
cout << resetiosflags(ios::fixed);
logtotal += log(mbs); logtotal += log(mbs);
logcount++; logcount++;
cout << out.str();
} }
void OutputResultKeying(double iterations, double timeTaken) 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) 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) void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken)
{ {
cout << "\n<TR><TH>" << name << " " << operation << (pc ? " with precomputation" : ""); // Coverity finding (http://stackoverflow.com/a/30968371 does not squash the finding)
// cout << "<TD>" << iterations; std::ostringstream out;
// cout << setiosflags(ios::fixed); out.copyfmt(cout);
// cout << "<TD>" << setprecision(3) << timeTaken;
cout << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << (1000*timeTaken/iterations); // 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) if (g_hertz)
cout << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations / 1000000; out << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations / 1000000;
cout << resetiosflags(ios::fixed);
logtotal += log(iterations/timeTaken); logtotal += log(iterations/timeTaken);
logcount++; 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); CRYPTOPP_UNUSED(x), CRYPTOPP_UNUSED(y), CRYPTOPP_UNUSED(params);
std::string name(factoryName ? factoryName : ""); 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) if (displayName)
name = displayName; name = displayName;
else if (keyLength) else if (keyLength)
name += " (" + IntToString(keyLength * 8) + "-bit key)"; 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))); 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); 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))); 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; cout << "</TABLE>" << endl;
BenchmarkAll2(t, hertz); BenchmarkAll2(t, hertz);
cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/(logcount ? logcount : 1)) << endl;
cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/logcount) << endl;
// Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55 // Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
#if defined(CRYPTOPP_MSC_VERSION) #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 #ifndef CRYPTOPP_BENCH_H
#define 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)); SecByteBlock plaintext(len), ciphertext(key.CiphertextLength(len));
GlobalRNG().GenerateBlock(plaintext, len); GlobalRNG().GenerateBlock(plaintext, len);
clock_t start = clock(); const clock_t start = clock();
unsigned int i; unsigned int i;
double timeTaken; double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) 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); GlobalRNG().GenerateBlock(plaintext, len);
pub.Encrypt(GlobalRNG(), plaintext, len, ciphertext); pub.Encrypt(GlobalRNG(), plaintext, len, ciphertext);
clock_t start = clock(); const clock_t start = clock();
unsigned int i; unsigned int i;
double timeTaken; double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) 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()); AlignedSecByteBlock message(len), signature(key.SignatureLength());
GlobalRNG().GenerateBlock(message, len); GlobalRNG().GenerateBlock(message, len);
clock_t start = clock(); const clock_t start = clock();
unsigned int i; unsigned int i;
double timeTaken; double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) 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); GlobalRNG().GenerateBlock(message, len);
priv.SignMessage(GlobalRNG(), message, len, signature); priv.SignMessage(GlobalRNG(), message, len, signature);
clock_t start = clock(); const clock_t start = clock();
unsigned int i; unsigned int i;
double timeTaken; double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) 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); 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()); SecByteBlock priv(d.PrivateKeyLength()), pub(d.PublicKeyLength());
clock_t start = clock(); const clock_t start = clock();
unsigned int i; unsigned int i;
double timeTaken; double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) 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()); SecByteBlock priv(d.EphemeralPrivateKeyLength()), pub(d.EphemeralPublicKeyLength());
clock_t start = clock(); const clock_t start = clock();
unsigned int i; unsigned int i;
double timeTaken; double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) 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); d.GenerateKeyPair(GlobalRNG(), priv2, pub2);
SecByteBlock val(d.AgreedValueLength()); SecByteBlock val(d.AgreedValueLength());
clock_t start = clock(); const clock_t start = clock();
unsigned int i; unsigned int i;
double timeTaken; double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2) 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); d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2);
SecByteBlock val(d.AgreedValueLength()); SecByteBlock val(d.AgreedValueLength());
clock_t start = clock(); const clock_t start = clock();
unsigned int i; unsigned int i;
double timeTaken; double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2) 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 // blowfish.h - written and placed in the public domain by Wei Dai
//! \file //! \file
//! \brief Class files for the Blowfish algorithm //! \brief Classes for the Blowfish algorithm
#ifndef CRYPTOPP_BLOWFISH_H #ifndef CRYPTOPP_BLOWFISH_H
#define CRYPTOPP_BLOWFISH_H #define CRYPTOPP_BLOWFISH_H

View File

@ -8,10 +8,10 @@ NAMESPACE_BEGIN(CryptoPP)
PublicBlumBlumShub::PublicBlumBlumShub(const Integer &n, const Integer &seed) PublicBlumBlumShub::PublicBlumBlumShub(const Integer &n, const Integer &seed)
: modn(n), : 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() 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 #ifndef CRYPTOPP_BLUMSHUB_H
#define CRYPTOPP_BLUMSHUB_H #define CRYPTOPP_BLUMSHUB_H
@ -22,13 +28,14 @@ public:
bool IsSelfInverting() const {return true;} bool IsSelfInverting() const {return true;}
bool IsForwardTransformation() const {return true;} bool IsForwardTransformation() const {return true;}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~PublicBlumBlumShub() {}
#endif
protected: protected:
ModularArithmetic modn; ModularArithmetic modn;
word maxBits, bitsLeft;
Integer current; Integer current;
word maxBits, bitsLeft;
friend class BlumGoldwasserPublicKey;
friend class BlumGoldwasserPrivateKey;
}; };
//! BlumBlumShub with factorization of the modulus //! BlumBlumShub with factorization of the modulus
@ -42,6 +49,10 @@ public:
bool IsRandomAccess() const {return true;} bool IsRandomAccess() const {return true;}
void Seek(lword index); void Seek(lword index);
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~BlumBlumShub() {}
#endif
protected: protected:
const Integer p, q; const Integer p, q;
const Integer x0; 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 #ifndef CRYPTOPP_CAMELLIA_H
#define 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 #ifndef CRYPTOPP_CAST_H
#define 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 #ifndef CRYPTOPP_CBCMAC_H
#define 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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_MAC_Base : public MessageAuthenticationCode
{ {
public: public:
CBC_MAC_Base() {} CBC_MAC_Base() : m_counter(0) {}
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params); void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Update(const byte *input, size_t length); 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 #ifndef CRYPTOPP_CCM_H
#define CRYPTOPP_CCM_H #define CRYPTOPP_CCM_H
@ -10,7 +16,7 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CCM_Base : public AuthenticatedSymmetricCi
{ {
public: public:
CCM_Base() CCM_Base()
: m_digestSize(0), m_L(0) {} : m_digestSize(0), m_L(0), m_messageLength(0), m_aadLength(0) {}
// AuthenticatedSymmetricCipher // AuthenticatedSymmetricCipher
std::string AlgorithmName() const 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 #ifndef CRYPTOPP_CHANNELS_H
#define CRYPTOPP_CHANNELS_H #define CRYPTOPP_CHANNELS_H
#include "cryptlib.h" #include "cryptlib.h"
#include "simple.h" #include "simple.h"
#include "smartptr.h" #include "smartptr.h"
#include <map> #include "stdcpp.h"
#include <list>
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
@ -64,18 +69,23 @@ class ChannelSwitch;
class ChannelRouteIterator : public ChannelSwitchTypedefs class ChannelRouteIterator : public ChannelSwitchTypedefs
{ {
public: 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; ChannelSwitch& m_cs;
std::string m_channel; std::string m_channel;
bool m_useDefault; bool m_useDefault;
MapIterator m_itMapCurrent, m_itMapEnd; MapIterator m_itMapCurrent, m_itMapEnd;
ListIterator m_itListCurrent, m_itListEnd; ListIterator m_itListCurrent, m_itListEnd;
ChannelRouteIterator(ChannelSwitch &cs) : m_cs(cs) {} protected:
void Reset(const std::string &channel); // Hide this to see if we break something...
bool End() const; ChannelRouteIterator();
void Next();
BufferedTransformation & Destination();
const std::string & Channel();
}; };
//! Route input to different and/or multiple channels based on channel ID //! 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) void CMAC_Base::Update(const byte *input, size_t length)
{ {
assert((input && length) || !(input || length));
if (!length) if (!length)
return; return;
@ -65,11 +66,14 @@ void CMAC_Base::Update(const byte *input, size_t length)
if (m_counter > 0) 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); xorbuf(m_reg+m_counter, input, len);
length -= len; length -= len;
input += len; input += len;
m_counter += len; m_counter += len;
}
if (m_counter == blockSize && length > 0) 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 #ifndef CRYPTOPP_CMAC_H
#define CRYPTOPP_CMAC_H #define CRYPTOPP_CMAC_H
@ -10,7 +16,7 @@ NAMESPACE_BEGIN(CryptoPP)
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CMAC_Base : public MessageAuthenticationCode class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CMAC_Base : public MessageAuthenticationCode
{ {
public: public:
CMAC_Base() {} CMAC_Base() : m_counter(0) {}
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params); void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Update(const byte *input, size_t length); void Update(const byte *input, size_t length);

107
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 #ifndef CRYPTOPP_CONFIG_H
#define CRYPTOPP_CONFIG_H #define CRYPTOPP_CONFIG_H
@ -54,8 +60,16 @@
# endif # endif
#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. // File system code to write to GZIP archive.
#if !defined(GZIP_OS_CODE)
# define GZIP_OS_CODE 0 # define GZIP_OS_CODE 0
#endif
// Try this if your CPU has 256K internal cache or a slow multiply instruction // 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 // and you want a (possibly) faster IDEA implementation using log tables
@ -90,7 +104,7 @@
#if defined(CRYPTOPP_INIT_PRIORITY) && (CRYPTOPP_INIT_PRIORITY > 0) #if defined(CRYPTOPP_INIT_PRIORITY) && (CRYPTOPP_INIT_PRIORITY > 0)
# define CRYPTOPP_USER_PRIORITY (CRYPTOPP_INIT_PRIORITY + 101) # define CRYPTOPP_USER_PRIORITY (CRYPTOPP_INIT_PRIORITY + 101)
#else #else
# define CRYPTOPP_USER_PRIORITY 500 # define CRYPTOPP_USER_PRIORITY 250
#endif #endif
// ***************** Important Settings Again ******************** // ***************** Important Settings Again ********************
@ -113,8 +127,8 @@
//! \details Nearly all classes are located in the CryptoPP namespace. Within //! \details Nearly all classes are located in the CryptoPP namespace. Within
//! the namespace, there are two additional namespaces. //! the namespace, there are two additional namespaces.
//! <ul> //! <ul>
//! <li>Name - the namespace for names used with \p NameValuePairs and documented in argnames.h //! <li>Name - 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>Weak - namespace for weak and wounded algorithms, like ARC4, MD5 and Pananma
//! </ul> //! </ul>
namespace CryptoPP { } namespace CryptoPP { }
// Bring in the symbols fund in the weak namespace; and fold Weak1 into Weak // Bring in the symbols fund in the weak namespace; and fold Weak1 into Weak
@ -126,12 +140,15 @@ namespace CryptoPP { }
# define NAMESPACE_END # define NAMESPACE_END
// Get Doxygen to generate better documentation for these typedefs // Get Doxygen to generate better documentation for these typedefs
# define DOCUMENTED_TYPEDEF(x, y) class y : public x {}; # define DOCUMENTED_TYPEDEF(x, y) class y : public x {};
// Make "protected" "private" so the functions and members are not documented
# define protected private
#else #else
# define NAMESPACE_BEGIN(x) namespace x { # define NAMESPACE_BEGIN(x) namespace x {
# define NAMESPACE_END } # define NAMESPACE_END }
# define DOCUMENTED_TYPEDEF(x, y) typedef x y; # define DOCUMENTED_TYPEDEF(x, y) typedef x y;
#endif #endif
#define ANONYMOUS_NAMESPACE_BEGIN namespace { #define ANONYMOUS_NAMESPACE_BEGIN namespace {
#define ANONYMOUS_NAMESPACE_END }
#define USING_NAMESPACE(x) using namespace x; #define USING_NAMESPACE(x) using namespace x;
#define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x { #define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x {
#define DOCUMENTED_NAMESPACE_END } #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__) #define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif #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__) #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 #endif
#ifdef _MSC_VER #ifdef _MSC_VER
#define CRYPTOPP_MSC_VERSION (_MSC_VER) #define CRYPTOPP_MSC_VERSION (_MSC_VER)
#endif #endif
// Need GCC 4.6/Clang 1.7 or above due to "GCC diagnostic {push|pop}" // 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) #if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000)
#define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1 #define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1
#endif #endif
// Detect availabliltiy of int128_t and uint128_t in preprocessor, http://gcc.gnu.org/ml/gcc-help/2015-08/msg00185.html. // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232
// Both GCC and Clang respond to it. // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes.
#if ((defined(__GNUC__) || defined(__clang__) || defined(_INTEL_COMPILER)) && (__SIZEOF_INT128__ >= 16)) #if (defined(CRYPTOPP_CLANG_VERSION) && CRYPTOPP_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000)
#define CRYPTOPP_NATIVE_DWORD_AVAILABLE #define CRYPTOPP_DISABLE_INTEL_ASM 1
#define CRYPTOPP_WORD128_AVAILABLE #endif
typedef word32 hword;
typedef word64 word;
typedef __uint128_t dword;
typedef __uint128_t word128;
// define hword, word, and dword. these are used for multiprecision integer arithmetic // 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 // 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 word32 hword;
typedef word64 word; typedef word64 word;
#else #else
@ -214,12 +230,26 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
typedef word64 word; typedef word64 word;
typedef __uint128_t dword; typedef __uint128_t dword;
typedef __uint128_t word128; 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 #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 // 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 word16 hword;
typedef word32 word; typedef word32 word;
typedef word64 dword; typedef word64 dword;
#endif #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 #else
// being here means the native register size is probably 32 bits or less // being here means the native register size is probably 32 bits or less
#define CRYPTOPP_BOOL_SLOW_WORD64 1 #define CRYPTOPP_BOOL_SLOW_WORD64 1
@ -233,7 +263,7 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
#endif #endif
// Produce a compiler error. It can be commented out, but you may not get the benefit of the fastest integers. // 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" # error "An int128_t and uint128_t are available, but CRYPTOPP_WORD128_AVAILABLE is not defined"
#endif #endif
@ -352,6 +382,11 @@ NAMESPACE_END
#define CRYPTOPP_DISABLE_SSE2 #define CRYPTOPP_DISABLE_SSE2
#endif #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__)))) #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 // C++Builder 2010 does not allow "call label" where label is defined within inline assembly
#define CRYPTOPP_X86_ASM_AVAILABLE #define CRYPTOPP_X86_ASM_AVAILABLE
@ -380,7 +415,7 @@ NAMESPACE_END
#define CRYPTOPP_X64_ASM_AVAILABLE #define CRYPTOPP_X64_ASM_AVAILABLE
#endif #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 #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 1
#else #else
#define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 0 #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 0
@ -401,6 +436,8 @@ NAMESPACE_END
// how to allocate 16-byte aligned memory (for SSE2) // how to allocate 16-byte aligned memory (for SSE2)
#if defined(CRYPTOPP_MSVC6PP_OR_LATER) #if defined(CRYPTOPP_MSVC6PP_OR_LATER)
#define CRYPTOPP_MM_MALLOC_AVAILABLE #define CRYPTOPP_MM_MALLOC_AVAILABLE
#elif defined(__APPLE__)
#define CRYPTOPP_APPLE_MALLOC_AVAILABLE
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define CRYPTOPP_MALLOC_ALIGNMENT_IS_16 #define CRYPTOPP_MALLOC_ALIGNMENT_IS_16
#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__) #elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
@ -409,6 +446,9 @@ NAMESPACE_END
#define CRYPTOPP_NO_ALIGNED_ALLOC #define CRYPTOPP_NO_ALIGNED_ALLOC
#endif #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 // how to disable inlining
#if defined(_MSC_VER) && _MSC_VER >= 1300 #if defined(_MSC_VER) && _MSC_VER >= 1300
# define CRYPTOPP_NOINLINE_DOTDOTDOT # define CRYPTOPP_NOINLINE_DOTDOTDOT
@ -462,13 +502,6 @@ NAMESPACE_END
#endif #endif
#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 ******************** // ***************** determine availability of OS features ********************
#ifndef NO_OS_DEPENDENCE #ifndef NO_OS_DEPENDENCE
@ -547,7 +580,7 @@ NAMESPACE_END
#define CRYPTOPP_API __cdecl #define CRYPTOPP_API __cdecl
#else // CRYPTOPP_WIN32_AVAILABLE #else // not CRYPTOPP_WIN32_AVAILABLE
#define CRYPTOPP_DLL #define CRYPTOPP_DLL
#define CRYPTOPP_API #define CRYPTOPP_API
@ -583,12 +616,14 @@ NAMESPACE_END
#endif #endif
// ************** Unused variable *************** // ************** 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) #define CRYPTOPP_UNUSED(x) ((void)x)
// ***************** C++11 related ******************** // ***************** 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 // 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 // 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 // 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. // 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. // Thanks to Jonathan Wakely for devising the clever test for modern/ancient versions.
// TODO: test under Xcode 3, where g++ is really g++. // TODO: test under Xcode 3, where g++ is really g++.
#if defined(__clang__) #if defined(__APPLE__) && defined(__clang__)
# if !(__has_include(<forward_list>)) # if !(defined(__has_include) && __has_include(<forward_list>))
# undef CRYPTOPP_CXX11 # undef CRYPTOPP_CXX11
# endif # endif
#endif #endif
@ -610,18 +645,22 @@ NAMESPACE_END
// C++11 or C++14 is available // C++11 or C++14 is available
#if defined(CRYPTOPP_CXX11) #if defined(CRYPTOPP_CXX11)
// alignof/alignas: MS at VS2013 (18.00); GCC at 4.8; Clang at 3.3; and Intel 15.0. // alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
#if (CRYPTOPP_MSC_VERSION >= 1800) #if (CRYPTOPP_MSC_VERSION >= 1900)
# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1 # define CRYPTOPP_CXX11_ALIGNOF 1
#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) #elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1 # define CRYPTOPP_CXX11_ALIGNOF 1
#elif defined(__clang__) #elif defined(__clang__)
# if __has_feature(cxx_alignof) # if __has_feature(cxx_alignof)
# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1 # define CRYPTOPP_CXX11_ALIGNOF 1
# endif # endif
#elif (CRYPTOPP_GCC_VERSION >= 40800) #elif (CRYPTOPP_GCC_VERSION >= 40800)
# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 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. // noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; and Intel 14.0.
#if (CRYPTOPP_MSC_VERSION >= 1900) #if (CRYPTOPP_MSC_VERSION >= 1900)
@ -647,7 +686,7 @@ NAMESPACE_END
# endif # endif
#elif (CRYPTOPP_GCC_VERSION >= 40300) #elif (CRYPTOPP_GCC_VERSION >= 40300)
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1 # define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
#endif // noexcept compilers #endif // variadic templates
// TODO: Emplacement, R-values and Move semantics // TODO: Emplacement, R-values and Move semantics
// Needed because we are catching warnings with GCC and MSC // 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; return true;
#else #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); SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
if (oldHandler == SIG_ERR) if (oldHandler == SIG_ERR)
return false; result = false;
bool result = true;
if (setjmp(s_jmpNoCPUID)) if (setjmp(s_jmpNoCPUID))
result = false; result = false;
else else
@ -134,13 +138,17 @@ static bool TrySSE2()
} }
return true; return true;
#else #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); SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
if (oldHandler == SIG_ERR) if (oldHandler == SIG_ERR)
return false; return false;
bool result = true;
if (setjmp(s_jmpNoSSE2)) if (setjmp(s_jmpNoSSE2))
result = false; result = true;
else else
{ {
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
@ -156,20 +164,30 @@ static bool TrySSE2()
#endif #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_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; word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
#endif
// MacPorts/GCC does not provide constructor(priority). Apple/GCC and Fink/GCC do provide it. // 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)) #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 #if HAVE_GCC_CONSTRUCTOR1
void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 50))) DetectX86Features() void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 50))) DetectX86Features()
#elif HAVE_GCC_CONSTRUCTOR0 #elif HAVE_GCC_CONSTRUCTOR0
@ -204,22 +222,32 @@ void DetectX86Features()
} }
} }
std::swap(cpuid[2], cpuid[3]); static const unsigned int RDRAND_FLAG = (1 << 30);
if (memcmp(cpuid+1, "GenuineIntel", 12) == 0) static const unsigned int RDSEED_FLAG = (1 << 18);
if (IsIntel(cpuid))
{ {
g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf; g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1); 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); CpuId(0x80000005, cpuid);
g_cacheLineSize = GETBYTE(cpuid[2], 0); g_cacheLineSize = GETBYTE(cpuid[2], 0);
g_hasRDRAND = !!(cpuid[2] /*ECX*/ & RDRAND_FLAG);
} }
if (!g_cacheLineSize) if (!g_cacheLineSize)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
g_x86DetectionDone = true; *((volatile bool*)&g_x86DetectionDone) = true;
} }
#endif #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 #ifndef CRYPTOPP_CPU_H
#define CRYPTOPP_CPU_H #define CRYPTOPP_CPU_H
@ -20,16 +26,19 @@
#if !defined(__GNUC__) || defined(__SSSE3__) || defined(__INTEL_COMPILER) #if !defined(__GNUC__) || defined(__SSSE3__) || defined(__INTEL_COMPILER)
#include <tmmintrin.h> #include <tmmintrin.h>
#else #else
NAMESPACE_BEGIN(CryptoPP)
__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_shuffle_epi8 (__m128i a, __m128i b) _mm_shuffle_epi8 (__m128i a, __m128i b)
{ {
asm ("pshufb %1, %0" : "+x"(a) : "xm"(b)); asm ("pshufb %1, %0" : "+x"(a) : "xm"(b));
return a; return a;
} }
#endif NAMESPACE_END
#endif // tmmintrin.h
#if !defined(__GNUC__) || defined(__SSE4_1__) || defined(__INTEL_COMPILER) #if !defined(__GNUC__) || defined(__SSE4_1__) || defined(__INTEL_COMPILER)
#include <smmintrin.h> #include <smmintrin.h>
#else #else
NAMESPACE_BEGIN(CryptoPP)
__inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_extract_epi32 (__m128i a, const int i) _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)); asm ("pinsrd %2, %1, %0" : "+x"(a) : "rm"(b), "i"(i));
return a; return a;
} }
#endif NAMESPACE_END
#endif // smmintrin.h
#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) #if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER)
#include <wmmintrin.h> #include <wmmintrin.h>
#else #else
NAMESPACE_BEGIN(CryptoPP)
__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_clmulepi64_si128 (__m128i a, __m128i b, const int i) _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)); asm ("aesdeclast %1, %0" : "+x"(a) : "xm"(b));
return a; return a;
} }
#endif NAMESPACE_END
#endif #endif // wmmintrin.h
#endif // CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
@ -109,6 +121,8 @@ extern CRYPTOPP_DLL bool g_hasSSSE3;
extern CRYPTOPP_DLL bool g_hasAESNI; extern CRYPTOPP_DLL bool g_hasAESNI;
extern CRYPTOPP_DLL bool g_hasCLMUL; extern CRYPTOPP_DLL bool g_hasCLMUL;
extern CRYPTOPP_DLL bool g_isP4; extern CRYPTOPP_DLL bool g_isP4;
extern CRYPTOPP_DLL bool g_hasRDRAND;
extern CRYPTOPP_DLL bool g_hasRDSEED;
extern CRYPTOPP_DLL word32 g_cacheLineSize; extern CRYPTOPP_DLL word32 g_cacheLineSize;
CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features(); CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features();
@ -175,6 +189,20 @@ inline bool IsP4()
return g_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() inline int GetCacheLineSize()
{ {
if (!g_x86DetectionDone) if (!g_x86DetectionDone)
@ -215,12 +243,27 @@ inline int GetCacheLineSize()
#define AS_HEX(y) 0x##y #define AS_HEX(y) 0x##y
#else #else
#define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY #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 these in two steps to allow arguments to be expanded
#define GNU_AS1(x) #x ";" #define GNU_AS1(x) #x ";" NEW_LINE
#define GNU_AS2(x, y) #x ", " #y ";" #define GNU_AS2(x, y) #x ", " #y ";" NEW_LINE
#define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" NEW_LINE
#define GNU_ASL(x) "\n" #x ":" #define GNU_ASL(x) "\n" #x ":" NEW_LINE
#define GNU_ASJ(x, y, z) #x " " #y #z ";" #define GNU_ASJ(x, y, z) #x " " #y #z ";" NEW_LINE
#define AS1(x) GNU_AS1(x) #define AS1(x) GNU_AS1(x)
#define AS2(x, y) GNU_AS2(x, y) #define AS2(x, y) GNU_AS2(x, y)
#define AS3(x, y, z) GNU_AS3(x, y, z) #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 #ifndef CRYPTOPP_CRC32_H
#define 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 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 blockSize = BlockSize();
size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize; size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize;
size_t xorIncrement = xorBlocks ? blockSize : 0; size_t xorIncrement = xorBlocks ? blockSize : 0;
@ -200,11 +204,20 @@ size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const by
{ {
if (flags & BT_XorInput) 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); xorbuf(outBlocks, xorBlocks, inBlocks, blockSize);
ProcessBlock(outBlocks); ProcessBlock(outBlocks);
} }
else else
{
// xorBlocks can be NULL. See, for example, ECB_OneWay::ProcessData.
ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks); ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
}
if (flags & BT_InBlockIsCounter) if (flags & BT_InBlockIsCounter)
const_cast<byte *>(inBlocks)[blockSize-1]++; const_cast<byte *>(inBlocks)[blockSize-1]++;
inBlocks += inIncrement; 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 class ClassNullRNG : public RandomNumberGenerator
{ {
public: public:
//! \brief The name of the generator
//! \returns the string \a NullRNGs
std::string AlgorithmName() const {return "NullRNG";} 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) void GenerateBlock(byte *output, size_t size)
{ {
CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(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"); 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() 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) # pragma strict_gs_check (on)
#endif #endif
#if defined(__COVERITY__)
extern "C" void __coverity_tainted_data_sanitize__(void *);
#endif
USING_NAMESPACE(CryptoPP) USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std) USING_NAMESPACE(std)
@ -579,7 +583,7 @@ void TestDigestOrMAC(TestData &v, bool testDigest)
{ {
int digestSize = -1; int digestSize = -1;
if (test == "VerifyTruncated") if (test == "VerifyTruncated")
pairs.GetIntValue(Name::DigestSize(), digestSize); digestSize = pairs.GetIntValueWithDefault(Name::DigestSize(), digestSize);
HashVerificationFilter verifierFilter(*pHash, NULL, HashVerificationFilter::HASH_AT_BEGIN, digestSize); HashVerificationFilter verifierFilter(*pHash, NULL, HashVerificationFilter::HASH_AT_BEGIN, digestSize);
PutDecodedDatumInto(v, digestName, verifierFilter); PutDecodedDatumInto(v, digestName, verifierFilter);
PutDecodedDatumInto(v, "Message", 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() name.resize(0); // GCC workaround: 2.95.3 doesn't have clear()
is >> name; 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()) if (name.empty())
return false; 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 #ifndef CRYPTOPP_DEFAULT_H
#define 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 #ifndef CRYPTOPP_DES_H
#define CRYPTOPP_DES_H #define CRYPTOPP_DES_H
/** \file
*/
#include "seckey.h" #include "seckey.h"
#include "secblock.h" #include "secblock.h"

2
dh.cpp
View File

@ -8,11 +8,13 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void DH_TestInstantiations() void DH_TestInstantiations()
{ {
DH dh1; DH dh1;
DH dh2(NullRNG(), 10); DH dh2(NullRNG(), 10);
} }
#endif
NAMESPACE_END 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 #ifndef CRYPTOPP_DH_H
#define CRYPTOPP_DH_H #define CRYPTOPP_DH_H
/** \file
*/
#include "cryptlib.h" #include "cryptlib.h"
#include "gfpcrypt.h" #include "gfpcrypt.h"

View File

@ -5,10 +5,12 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void DH2_TestInstantiations() void DH2_TestInstantiations()
{ {
DH2 dh(*(SimpleKeyAgreementDomain*)NULL); DH2 dh(*(SimpleKeyAgreementDomain*)NULL);
} }
#endif
bool DH2::Agree(byte *agreedValue, bool DH2::Agree(byte *agreedValue,
const byte *staticSecretKey, const byte *ephemeralSecretKey, 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 #ifndef CRYPTOPP_DH2_H
#define CRYPTOPP_DH2_H #define CRYPTOPP_DH2_H
/** \file
*/
#include "cryptlib.h" #include "cryptlib.h"
NAMESPACE_BEGIN(CryptoPP) 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 #ifndef CRYPTOPP_DLL_H
#define 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 #ifndef CRYPTOPP_DMAC_H
#define CRYPTOPP_DMAC_H #define CRYPTOPP_DMAC_H
@ -14,7 +20,7 @@ public:
CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE) 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 UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Update(const byte *input, size_t length); 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 #ifndef CRYPTOPP_DSA_H
#define CRYPTOPP_DSA_H #define CRYPTOPP_DSA_H
/** \file
*/
#include "cryptlib.h" #include "cryptlib.h"
NAMESPACE_BEGIN(CryptoPP) 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 #ifndef CRYPTOPP_EAX_H
#define CRYPTOPP_EAX_H #define CRYPTOPP_EAX_H
@ -7,7 +13,9 @@
NAMESPACE_BEGIN(CryptoPP) 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 class CRYPTOPP_NO_VTABLE EAX_Base : public AuthenticatedSymmetricCipherBase
{ {
public: public:
@ -59,7 +67,13 @@ protected:
CTR_Mode_ExternalCipher::Encryption m_ctr; 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> template <class T_BlockCipher, bool T_IsEncryption>
class EAX_Final : public EAX_Base class EAX_Final : public EAX_Base
{ {
@ -78,7 +92,14 @@ private:
#undef EAX #undef EAX
#endif #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> template <class T_BlockCipher>
struct EAX : public AuthenticatedSymmetricCipherDocumentation 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 #ifndef CRYPTOPP_EC2N_H
#define CRYPTOPP_EC2N_H #define CRYPTOPP_EC2N_H

View File

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

View File

@ -299,7 +299,7 @@ struct ECIES
virtual ~ECIES() {} virtual ~ECIES() {}
#endif #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."))); } __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 ) #elif (CRYPTOPP_GCC_VERSION )
} __attribute__((deprecated)); } __attribute__((deprecated));

View File

@ -8,6 +8,7 @@
#include "asn.h" #include "asn.h"
#include "integer.h" #include "integer.h"
#include "nbtheory.h" #include "nbtheory.h"
#include "modarith.h"
#include "filters.h" #include "filters.h"
#include "algebra.cpp" #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 #ifndef CRYPTOPP_ECP_H
#define CRYPTOPP_ECP_H #define CRYPTOPP_ECP_H

View File

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

View File

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

View File

@ -45,7 +45,8 @@ public:
void SetPublicExponent(const Integer &e) {m_e = e;} void SetPublicExponent(const Integer &e) {m_e = e;}
protected: 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; Integer m_n, m_e;
}; };

View File

@ -10,7 +10,7 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
#ifndef NDEBUG #if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Files_TestInstantiations() void Files_TestInstantiations()
{ {
FileStore f0; 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 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") {}}; class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}};
FileStore() : m_stream(NULL) {} FileStore() : m_stream(NULL), m_space(NULL), m_len(0), m_waiting(0) {}
FileStore(std::istream &in) FileStore(std::istream &in) : m_stream(NULL), m_space(NULL), m_len(0), m_waiting(0)
{StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));} {StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));}
FileStore(const char *filename) FileStore(const char *filename) : m_stream(NULL), m_space(NULL), m_len(0), m_waiting(0)
{StoreInitialize(MakeParameters(Name::InputFileName(), filename));} {StoreInitialize(MakeParameters(Name::InputFileName(), filename ? filename : ""));}
#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 #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. //! specify file with Unicode name. On non-Windows OS, this function assumes that setlocale() has been called.
FileStore(const wchar_t *filename) FileStore(const wchar_t *filename)

View File

@ -18,10 +18,9 @@
#include "fltrimpl.h" #include "fltrimpl.h"
#include "argnames.h" #include "argnames.h"
#include "smartptr.h" #include "smartptr.h"
#include "stdcpp.h"
#include "misc.h" #include "misc.h"
#include <functional>
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
Filter::Filter(BufferedTransformation *attachment) Filter::Filter(BufferedTransformation *attachment)
@ -83,9 +82,12 @@ bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
case 0: case 0:
if (IsolatedFlush(hardFlush, blocking)) if (IsolatedFlush(hardFlush, blocking))
return true; return true;
// fall through
case 1: case 1:
if (OutputFlush(1, hardFlush, propagation, blocking)) if (OutputFlush(1, hardFlush, propagation, blocking))
return true; return true;
// fall through
default: ;;
} }
return false; return false;
} }
@ -97,9 +99,12 @@ bool Filter::MessageSeriesEnd(int propagation, bool blocking)
case 0: case 0:
if (IsolatedMessageSeriesEnd(blocking)) if (IsolatedMessageSeriesEnd(blocking))
return true; return true;
// fall through
case 1: case 1:
if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking)) if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
return true; return true;
// fall through
default: ;;
} }
return false; return false;
} }
@ -434,7 +439,8 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
m_firstInputDone = false; m_firstInputDone = false;
m_queue.ResetQueue(1, m_firstSize); 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; 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) StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool allowAuthenticatedSymmetricCipher)
: FilterWithBufferedInput(attachment) : FilterWithBufferedInput(attachment)
, m_cipher(c) , m_cipher(c), m_padding(DEFAULT_PADDING), m_optimalBufferSize(0)
{ {
assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize()); 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) 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; m_digestSize = truncatedDigestSize < 0 ? m_hashModule.DigestSize() : truncatedDigestSize;
Detach(attachment); 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) HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize)
: FilterWithBufferedInput(attachment) : 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)); 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) SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment, word32 flags)
: FilterWithBufferedInput(attachment) : FilterWithBufferedInput(attachment)
, m_verifier(verifier) , m_verifier(verifier), m_flags(0), m_verified(0)
{ {
IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags)); 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 #ifndef CRYPTOPP_FILTERS_H
#define CRYPTOPP_FILTERS_H #define CRYPTOPP_FILTERS_H
@ -21,24 +27,55 @@
NAMESPACE_BEGIN(CryptoPP) 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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Filter : public BufferedTransformation, public NotCopyable
{ {
public: public:
//! \brief Construct a Filter
//! \param attachment the filter's attached transformation
//! \details attachment can be \p NULL.
Filter(BufferedTransformation *attachment = 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;} bool Attachable() {return true;}
//! \brief Retrieve attached transformation
//! \returns pointer to a BufferedTransformation if there is an attached transformation, \p NULL otherwise.
BufferedTransformation *AttachedTransformation(); BufferedTransformation *AttachedTransformation();
//! \brief Retrieve attached transformation
//! \returns pointer to a BufferedTransformation if there is an attached transformation, \p NULL otherwise.
const BufferedTransformation *AttachedTransformation() const; 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); 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 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; 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); void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
bool MessageSeriesEnd(int propagation=-1, bool blocking=true); bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~Filter() {}
#endif
protected: protected:
virtual BufferedTransformation * NewDefaultAttachment() const; virtual BufferedTransformation * NewDefaultAttachment() const;
void Insert(Filter *nextFilter); // insert filter after this one void Insert(Filter *nextFilter); // insert filter after this one
@ -48,10 +85,65 @@ protected:
void PropagateInitialize(const NameValuePairs &parameters, int propagation); 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); 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); 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); 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); 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); bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
private: private:
@ -62,6 +154,8 @@ protected:
int m_continueAt; int m_continueAt;
}; };
//! \struct FilterPutSpaceHelper
struct CRYPTOPP_DLL FilterPutSpaceHelper struct CRYPTOPP_DLL FilterPutSpaceHelper
{ {
// desiredSize is how much to ask target, bufferSize is how much to allocate in m_tempSpace // 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) byte * CreatePutSpace(size_t &size)
{return AttachedTransformation()->CreatePutSpace(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); size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking);
bool IsolatedMessageSeriesEnd(bool blocking); bool IsolatedMessageSeriesEnd(bool blocking);
@ -275,18 +369,35 @@ protected:
ByteQueue m_inQueue; ByteQueue m_inQueue;
}; };
//! \struct BlockPaddingSchemeDef
//! \detils Padding schemes used for block ciphers.
struct BlockPaddingSchemeDef 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 //! Filter Wrapper for StreamTransformation, optionally handling padding/unpadding when needed
class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper
{ {
public: 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); StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING, bool allowAuthenticatedSymmetricCipher = false);
std::string AlgorithmName() const {return m_cipher.AlgorithmName();} std::string AlgorithmName() const {return m_cipher.AlgorithmName();}
@ -317,7 +428,7 @@ public:
std::string AlgorithmName() const {return m_hashModule.AlgorithmName();} std::string AlgorithmName() const {return m_hashModule.AlgorithmName();}
void IsolatedInitialize(const NameValuePairs &parameters); 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);} byte * CreatePutSpace(size_t &size) {return m_hashModule.CreateUpdateSpace(size);}
private: private:
@ -415,7 +526,7 @@ public:
std::string AlgorithmName() const {return m_signer.AlgorithmName();} std::string AlgorithmName() const {return m_signer.AlgorithmName();}
void IsolatedInitialize(const NameValuePairs &parameters); 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: private:
RandomNumberGenerator &m_rng; RandomNumberGenerator &m_rng;
@ -463,11 +574,17 @@ typedef SignatureVerificationFilter VerifierFilter; // for backwards compatibili
class CRYPTOPP_DLL Redirector : public CustomSignalPropagation<Sink> class CRYPTOPP_DLL Redirector : public CustomSignalPropagation<Sink>
{ {
public: public:
//! \brief Controls signal propagation behavior
enum Behavior enum Behavior
{ {
//! \brief Pass data only
DATA_ONLY = 0x00, DATA_ONLY = 0x00,
//! \brief Pass signals
PASS_SIGNALS = 0x01, PASS_SIGNALS = 0x01,
//! \brief Pass wait events
PASS_WAIT_OBJECTS = 0x02, PASS_WAIT_OBJECTS = 0x02,
//! \brief Pass everything
//! \details PASS_EVERYTHING is default
PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS
}; };
@ -491,8 +608,8 @@ public:
void Initialize(const NameValuePairs &parameters, int propagation); void Initialize(const NameValuePairs &parameters, int propagation);
byte * CreatePutSpace(size_t &size) byte * CreatePutSpace(size_t &size)
{return m_target ? m_target->CreatePutSpace(size) : (byte *)(size=0, NULL);} {return m_target ? m_target->CreatePutSpace(size) : (byte *)(size=0, NULL);}
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)
{return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} {return m_target ? m_target->Put2(inString, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
{return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;} {return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;}
bool MessageSeriesEnd(int propagation=-1, bool blocking=true) bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
@ -530,8 +647,8 @@ public:
byte * CreatePutSpace(size_t &size) byte * CreatePutSpace(size_t &size)
{return m_owner.AttachedTransformation()->CreatePutSpace(size);} {return m_owner.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)
{return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, 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) size_t PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);} {return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1) void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
@ -616,7 +733,7 @@ public:
void IsolatedInitialize(const NameValuePairs &parameters) void IsolatedInitialize(const NameValuePairs &parameters)
{if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");} {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); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking);
if (length > 0) if (length > 0)
@ -624,7 +741,7 @@ public:
typename T::size_type size = m_output->size(); typename T::size_type size = m_output->size();
if (length < size && size + length > m_output->capacity()) if (length < size && size + length > m_output->capacity())
m_output->reserve(2*size); 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; return 0;
} }
@ -648,7 +765,7 @@ public:
: m_rng(&rng) {} : m_rng(&rng) {}
void IsolatedInitialize(const NameValuePairs &parameters); 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: private:
RandomNumberGenerator *m_rng; RandomNumberGenerator *m_rng;
@ -668,7 +785,7 @@ public:
void IsolatedInitialize(const NameValuePairs &parameters); void IsolatedInitialize(const NameValuePairs &parameters);
byte * CreatePutSpace(size_t &size); 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: protected:
byte *m_buf; byte *m_buf;
@ -683,7 +800,7 @@ public:
ArrayXorSink(byte *buf, size_t size) ArrayXorSink(byte *buf, size_t size)
: ArraySink(buf, 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);} byte * CreatePutSpace(size_t &size) {return BufferedTransformation::CreatePutSpace(size);}
}; };
@ -750,13 +867,25 @@ private:
lword m_size; 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> class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting<Filter>
{ {
public: public:
Source(BufferedTransformation *attachment = NULL) Source(BufferedTransformation *attachment = NULL)
{Source::Detach(attachment);} {Source::Detach(attachment);}
//! \name PIPELINE
//@{
lword Pump(lword pumpMax=size_t(SIZE_MAX)) lword Pump(lword pumpMax=size_t(SIZE_MAX))
{Pump2(pumpMax); return pumpMax;} {Pump2(pumpMax); return pumpMax;}
unsigned int PumpMessages(unsigned int count=UINT_MAX) unsigned int PumpMessages(unsigned int count=UINT_MAX)
@ -768,6 +897,12 @@ public:
virtual size_t PumpAll2(bool blocking=true); virtual size_t PumpAll2(bool blocking=true);
virtual bool SourceExhausted() const =0; virtual bool SourceExhausted() const =0;
//@}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~Source() {}
#endif
protected: protected:
void SourceInitialize(bool pumpAll, const NameValuePairs &parameters) 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> template <class T>
class SourceTemplate : public Source class SourceTemplate : public Source
{ {
@ -803,7 +940,8 @@ protected:
T m_store; 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> class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore>
{ {
public: 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 CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
if (HasCLMUL()) 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; tableSize = s_clmulTableSizeInBlocks * REQUIRED_BLOCKSIZE;
} }
else else
@ -579,7 +580,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
#ifdef __GNUC__ #ifdef __GNUC__
__asm__ __volatile__ __asm__ __volatile__
( (
".intel_syntax noprefix;" INTEL_NOPREFIX
#elif defined(CRYPTOPP_GENERATE_X64_MASM) #elif defined(CRYPTOPP_GENERATE_X64_MASM)
ALIGN 8 ALIGN 8
GCM_AuthenticateBlocks_2K PROC FRAME 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( pxor xmm5, xmm2 )
AS2( psrldq xmm0, 15 ) 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 ) AS2( movd WORD_REG(di), xmm0 )
#endif
AS2( movzx eax, WORD PTR [RED_TABLE + WORD_REG(di)*2] ) AS2( movzx eax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
AS2( shl eax, 8 ) AS2( shl eax, 8 )
@ -692,12 +699,24 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
AS2( pxor xmm4, xmm5 ) AS2( pxor xmm4, xmm5 )
AS2( psrldq xmm1, 15 ) 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 ) AS2( movd WORD_REG(di), xmm1 )
#endif
AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] ) AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
AS2( shl eax, 8 ) AS2( shl eax, 8 )
AS2( psrldq xmm0, 15 ) 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 ) AS2( movd WORD_REG(di), xmm0 )
#endif
AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] ) AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
AS2( movd xmm0, eax ) AS2( movd xmm0, eax )
@ -717,7 +736,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__
".att_syntax prefix;" ATT_PREFIX
: :
: "c" (data), "d" (len/16), "S" (hashBuffer), "D" (s_reductionTable) : "c" (data), "d" (len/16), "S" (hashBuffer), "D" (s_reductionTable)
: "memory", "cc", "%eax" : "memory", "cc", "%eax"
@ -740,7 +759,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
#ifdef __GNUC__ #ifdef __GNUC__
__asm__ __volatile__ __asm__ __volatile__
( (
".intel_syntax noprefix;" INTEL_NOPREFIX
#elif defined(CRYPTOPP_GENERATE_X64_MASM) #elif defined(CRYPTOPP_GENERATE_X64_MASM)
ALIGN 8 ALIGN 8
GCM_AuthenticateBlocks_64K PROC FRAME 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 ) AS2( movdqa [WORD_REG(si)], xmm0 )
#ifdef __GNUC__ #ifdef __GNUC__
".att_syntax prefix;" ATT_PREFIX
: :
: "c" (data), "d" (len/16), "S" (hashBuffer) : "c" (data), "d" (len/16), "S" (hashBuffer)
: "memory", "cc", "%edi", "%eax" : "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 #ifndef CRYPTOPP_GCM_H
#define CRYPTOPP_GCM_H #define CRYPTOPP_GCM_H
@ -6,10 +12,13 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
//! . //! \enum GCM_TablesOption
//! \brief Use either 2K or 64K size tables.
enum GCM_TablesOption {GCM_2K_Tables, GCM_64K_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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase
{ {
public: public:
@ -77,7 +86,14 @@ protected:
enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16}; 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> template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption>
class GCM_Final : public GCM_Base class GCM_Final : public GCM_Base
{ {
@ -93,7 +109,12 @@ private:
typename T_BlockCipher::Encryption m_cipher; 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> template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables>
struct GCM : public AuthenticatedSymmetricCipherDocumentation struct GCM : public AuthenticatedSymmetricCipherDocumentation
{ {

View File

@ -7,10 +7,11 @@
#include "cryptlib.h" #include "cryptlib.h"
#include "algebra.h" #include "algebra.h"
#include "words.h"
#include "randpool.h" #include "randpool.h"
#include "filters.h" #include "filters.h"
#include "smartptr.h" #include "smartptr.h"
#include "words.h"
#include "misc.h"
#include "gf2n.h" #include "gf2n.h"
#include "asn.h" #include "asn.h"
#include "oids.h" #include "oids.h"
@ -324,6 +325,11 @@ PolynomialMod2 PolynomialMod2::Modulo(const PolynomialMod2 &b) const
PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n) PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n)
{ {
#if !defined(NDEBUG)
int x; CRYPTOPP_UNUSED(x);
assert(SafeConvert(n,x));
#endif
if (!reg.size()) if (!reg.size())
return *this; return *this;
@ -352,8 +358,8 @@ PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n)
return *this; return *this;
} }
int shiftWords = n / WORD_BITS; const int shiftWords = n / WORD_BITS;
int shiftBits = n % WORD_BITS; const int shiftBits = n % WORD_BITS;
if (shiftBits) if (shiftBits)
{ {
@ -369,8 +375,10 @@ PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n)
if (carry) if (carry)
{ {
reg.Grow(reg.size()+shiftWords+1); // Thanks to Apatryda, http://github.com/weidai11/cryptopp/issues/64
reg[reg.size()-1] = carry; const size_t carryIndex = reg.size();
reg.Grow(reg.size()+shiftWords+!!shiftBits);
reg[carryIndex] = carry;
} }
else else
reg.Grow(reg.size()+shiftWords); reg.Grow(reg.size()+shiftWords);
@ -677,6 +685,8 @@ const GF2NT::Element& GF2NT::MultiplicativeInverse(const Element &a) const
b[i] = b[i+1]; b[i] = b[i+1];
b[BitsToWords(m)-1] = 0; 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) if (t1 < WORD_BITS)
for (unsigned int j=0; j<WORD_BITS-t1; j++) for (unsigned int j=0; j<WORD_BITS-t1; j++)
temp ^= ((temp >> j) & 1) << (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); ShiftWordsRightByBits(b, BitsToWords(m), k);
if (t1 < WORD_BITS) if (t1 < WORD_BITS)
{
for (unsigned int j=0; j<WORD_BITS-t1; j++) 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); temp ^= ((temp >> j) & 1) << (t1 + j);
}
}
else else
{
b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS; b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS;
}
if (t1 % WORD_BITS) if (t1 % WORD_BITS)
b[t1/WORD_BITS] ^= temp >> (WORD_BITS - 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; byte GetByte(size_t n) const;
//! the zero polynomial will return a degree of -1 //! 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 //! degree + 1
unsigned int CoefficientCount() const {return BitCount();} unsigned int CoefficientCount() const {return BitCount();}
//! return coefficient for x^i //! return coefficient for x^i

View File

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

View File

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

View File

@ -37,7 +37,7 @@ void Gzip::WritePoststreamTail()
// ************************************************************* // *************************************************************
Gunzip::Gunzip(BufferedTransformation *attachment, bool repeat, int propagation) 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: public:
Gzip(BufferedTransformation *attachment=NULL, unsigned int deflateLevel=DEFAULT_DEFLATE_LEVEL, unsigned int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true) 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) Gzip(const NameValuePairs &parameters, BufferedTransformation *attachment=NULL)
: Deflator(parameters, attachment) {} : Deflator(parameters, attachment), m_totalLen(0) {}
protected: protected:
enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header

View File

@ -19,7 +19,9 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TimerBase
{ {
public: public:
enum Unit {SECONDS = 0, MILLISECONDS, MICROSECONDS, NANOSECONDS}; 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 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 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: public:
RawIDA(BufferedTransformation *attachment=NULL) RawIDA(BufferedTransformation *attachment=NULL)
: m_threshold (0), m_channelsReady(0), m_channelsFinished(0)
{Detach(attachment);} {Detach(attachment);}
unsigned int GetThreshold() const {return m_threshold;} unsigned int GetThreshold() const {return m_threshold;}
@ -100,7 +101,7 @@ class InformationDispersal : public CustomFlushPropagation<Filter>
{ {
public: public:
InformationDispersal(int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true) 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); Detach(attachment);
IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding)); IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding));
@ -121,7 +122,7 @@ class InformationRecovery : public RawIDA
{ {
public: public:
InformationRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true) InformationRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true)
: RawIDA(attachment) : RawIDA(attachment), m_pad(false)
{IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));} {IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));}
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs); void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
@ -138,7 +139,7 @@ class PaddingRemover : public Unflushable<Filter>
{ {
public: public:
PaddingRemover(BufferedTransformation *attachment=NULL) PaddingRemover(BufferedTransformation *attachment=NULL)
: m_possiblePadding(false) {Detach(attachment);} : m_possiblePadding(false), m_zeroCount(0) {Detach(attachment);}
void IsolatedInitialize(const NameValuePairs &parameters) void IsolatedInitialize(const NameValuePairs &parameters)
{CRYPTOPP_UNUSED(parameters); m_possiblePadding = false;} {CRYPTOPP_UNUSED(parameters); m_possiblePadding = false;}

View File

@ -19,12 +19,12 @@
#include "secblock.h" #include "secblock.h"
#include "modarith.h" #include "modarith.h"
#include "nbtheory.h" #include "nbtheory.h"
#include "filters.h"
#include "smartptr.h" #include "smartptr.h"
#include "algparam.h"
#include "filters.h"
#include "asn.h" #include "asn.h"
#include "oids.h" #include "oids.h"
#include "words.h" #include "words.h"
#include "algparam.h"
#include "pubkey.h" // for P1363_KDF2 #include "pubkey.h" // for P1363_KDF2
#include "sha.h" #include "sha.h"
#include "cpu.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.") #pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 instructions will be disabled.")
#endif #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) NAMESPACE_BEGIN(CryptoPP)
// Debian QEMU/ARMEL issue in MultiplyTop; see https://github.com/weidai11/cryptopp/issues/31. // Debian QEMU/ARMEL issue in MultiplyTop; see http://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
#if __ARMEL__ && (CRYPTOPP_GCC_VERSION >= 50200) && (CRYPTOPP_GCC_VERSION < 50300) && __OPTIMIZE__ #if __ARMEL__ && (CRYPTOPP_GCC_VERSION >= 50200) && (CRYPTOPP_GCC_VERSION < 50300) && __OPTIMIZE__
# define WORKAROUND_ARMEL_BUG 1 # define WORKAROUND_ARMEL_BUG 1
#endif #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 #if WORKAROUND_ARMEL_BUG
# pragma GCC push_options # pragma GCC push_options
# pragma GCC optimize("O1") # pragma GCC optimize("O1")
#endif #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) bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt)
{ {
if (valueType != typeid(Integer)) if (valueType != typeid(Integer))
@ -197,13 +215,20 @@ static word AtomicInverseModPower2(word A)
class DWord class DWord
{ {
public: 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() {} DWord() {}
#endif
#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
explicit DWord(word low) explicit DWord(word low) : m_whole(low) {}
{
m_whole = low;
}
#else #else
explicit DWord(word low) explicit DWord(word low)
{ {
@ -225,6 +250,8 @@ public:
r.m_whole = (dword)a * b; r.m_whole = (dword)a * b;
#elif defined(MultiplyWordsLoHi) #elif defined(MultiplyWordsLoHi)
MultiplyWordsLoHi(r.m_halfs.low, r.m_halfs.high, a, b); MultiplyWordsLoHi(r.m_halfs.low, r.m_halfs.high, a, b);
#else
assert(0);
#endif #endif
return r; return r;
} }
@ -322,17 +349,19 @@ private:
class Word class Word
{ {
public: 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() {} Word() {}
#endif
Word(word value) Word(word value) : m_whole(value) {}
{ Word(hword low, hword high) : m_whole(low | (word(high) << (WORD_BITS/2))) {}
m_whole = value;
}
Word(hword low, hword high)
{
m_whole = low | (word(high) << (WORD_BITS/2));
}
static Word Multiply(hword a, hword b) 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__) #if defined(__GNUC__)
#define AddPrologue \ #define AddPrologue \
int result; \ int result; \
__asm__ __volatile__ \ __asm__ __volatile__ \
( \ ( \
".intel_syntax noprefix;" INTEL_NOPREFIX
#define AddEpilogue \ #define AddEpilogue \
".att_syntax prefix;" \ ".att_syntax prefix;" \
: "=a" (result)\ : "=a" (result)\
@ -563,7 +592,7 @@ int Baseline_Add(size_t N, word *C, const word *A, const word *B)
word result; word result;
__asm__ __volatile__ __asm__ __volatile__
( (
".intel_syntax;" INTEL_NOPREFIX
AS1( neg %1) AS1( neg %1)
ASJ( jz, 1, f) ASJ( jz, 1, f)
AS2( mov %0,[%3+8*%1]) 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) ASL(1)
AS2( mov %0, 0) AS2( mov %0, 0)
AS2( adc %0, %0) AS2( adc %0, %0)
".att_syntax;" ATT_NOPREFIX
: "=&r" (result), "+c" (N) : "=&r" (result), "+c" (N)
: "r" (C+N), "r" (A+N), "r" (B+N) : "r" (C+N), "r" (A+N), "r" (B+N)
: "memory", "cc" : "memory", "cc"
@ -595,7 +624,7 @@ int Baseline_Sub(size_t N, word *C, const word *A, const word *B)
word result; word result;
__asm__ __volatile__ __asm__ __volatile__
( (
".intel_syntax;" INTEL_NOPREFIX
AS1( neg %1) AS1( neg %1)
ASJ( jz, 1, f) ASJ( jz, 1, f)
AS2( mov %0,[%3+8*%1]) 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) ASL(1)
AS2( mov %0, 0) AS2( mov %0, 0)
AS2( adc %0, %0) AS2( adc %0, %0)
".att_syntax;" ATT_NOPREFIX
: "=&r" (result), "+c" (N) : "=&r" (result), "+c" (N)
: "r" (C+N), "r" (A+N), "r" (B+N) : "r" (C+N), "r" (A+N), "r" (B+N)
: "memory", "cc" : "memory", "cc"
@ -3446,8 +3475,8 @@ std::ostream& operator<<(std::ostream& out, const Integer &a)
static const char lower[]="0123456789abcdef"; static const char lower[]="0123456789abcdef";
const char* vec = (out.flags() & std::ios::uppercase) ? upper : lower; const char* vec = (out.flags() & std::ios::uppercase) ? upper : lower;
unsigned i=0; unsigned int i=0;
SecBlock<char> s(a.BitCount() / (BitPrecision(base)-1) + 1); SecBlock<char> s(a.BitCount() / (SaturatingSubtract1(BitPrecision(base),1U)) + 1);
while (!!temp1) while (!!temp1)
{ {
@ -3463,6 +3492,7 @@ std::ostream& operator<<(std::ostream& out, const Integer &a)
// if (i && !(i%block)) // if (i && !(i%block))
// out << ","; // out << ",";
} }
return out << suffix; return out << suffix;
} }
@ -4271,10 +4301,104 @@ const Integer& MontgomeryRepresentation::MultiplicativeInverse(const Integer &a)
return m_result; 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 NAMESPACE_END
#if WORKAROUND_ARMEL_BUG #if WORKAROUND_ARMEL_BUG
# pragma GCC pop_options # pragma GCC pop_options
#endif #endif
#if WORKAROUND_ARM64_BUG
# pragma GCC pop_options
#endif
#endif #endif

358
integer.h
View File

@ -5,174 +5,262 @@
#include "cryptlib.h" #include "cryptlib.h"
#include "secblock.h" #include "secblock.h"
#include "stdcpp.h"
#include <iosfwd> #include <iosfwd>
#include <algorithm>
#if CRYPTOPP_BOOL_X32
# define CRYPTOPP_DISABLE_INTEGER_ASM
#endif
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
struct InitializeInteger // used to initialize static variables //! \struct InitializeInteger
//! Performs static intialization of the Integer class
struct InitializeInteger
{ {
InitializeInteger(); InitializeInteger();
}; };
typedef SecBlock<word, AllocatorWithCleanup<word, CRYPTOPP_BOOL_X86> > IntegerSecBlock; typedef SecBlock<word, AllocatorWithCleanup<word, CRYPTOPP_BOOL_X86> > IntegerSecBlock;
//! multiple precision integer and basic arithmetics //! \brief Multiple precision integer with arithmetic operations
/*! This class can represent positive and negative integers //! \details The Integer class can represent positive and negative integers
with absolute value less than (256**sizeof(word)) ** (256**sizeof(int)). //! with absolute value less than (256**sizeof(word))<sup>(256**sizeof(int))</sup>.
\nosubgrouping //! \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 class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object
{ {
public: public:
//! \name ENUMS, EXCEPTIONS, and TYPEDEFS //! \name ENUMS, EXCEPTIONS, and TYPEDEFS
//@{ //@{
//! division by zero exception //! \brief Exception thrown when division by 0 is encountered
class DivideByZero : public Exception class DivideByZero : public Exception
{ {
public: public:
DivideByZero() : Exception(OTHER_ERROR, "Integer: division by zero") {} 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 class RandomNumberNotFound : public Exception
{ {
public: public:
RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {} RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {}
}; };
//! //! \enum Sign
enum Sign {POSITIVE=0, NEGATIVE=1}; //! \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 { enum Signedness {
//! //! \brief an unsigned value
UNSIGNED, UNSIGNED,
//! //! \brief a signed value
SIGNED}; SIGNED};
//! //! \enum RandomNumberType
//! \brief Properties of a random integer
enum RandomNumberType { enum RandomNumberType {
//! //! \brief a number with no special properties
ANY, ANY,
//! //! \brief a number which is probabilistically prime
PRIME}; PRIME};
//@} //@}
//! \name CREATORS //! \name CREATORS
//@{ //@{
//! creates the zero integer //! \brief Creates the zero integer
Integer(); Integer();
//! copy constructor //! copy constructor
Integer(const Integer& t); Integer(const Integer& t);
//! convert from signed long //! \brief Convert from signed long
Integer(signed long value); Integer(signed long value);
//! convert from lword //! \brief Convert from lword
Integer(Sign s, lword value); //! \param sign enumeration indicating Sign
//! \param value the long word
Integer(Sign sign, lword value);
//! convert from two words //! \brief Convert from two words
Integer(Sign s, word highWord, word lowWord); //! \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 //! \brief Convert from a C-string
/*! str can be in base 2, 8, 10, or 16. Base is determined by a //! \param str C-string value
case insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10. //! \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); 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); explicit Integer(const wchar_t *str);
//! convert from big-endian byte array //! \brief Convert from a big-endian byte array
Integer(const byte *encodedInteger, size_t byteCount, Signedness s=UNSIGNED); //! \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 //! \brief Convert from a big-endian array
Integer(BufferedTransformation &bt, size_t byteCount, Signedness s=UNSIGNED); //! \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); explicit Integer(BufferedTransformation &bt);
//! create a random integer //! \brief Create a random integer
/*! The random integer created is uniformly distributed over [0, 2**bitcount). */ //! \param rng RandomNumberGenerator used to generate material
Integer(RandomNumberGenerator &rng, size_t bitcount); //! \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(); 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(); 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(); static const Integer & CRYPTOPP_API Two();
//! create a random integer of special type //! \brief Create a random integer of special form
/*! Ideally, the random integer created should be uniformly distributed //! \param rng RandomNumberGenerator used to generate material
over {x | min <= x <= max and x is of rnType and x % mod == equiv}. //! \param min the minimum value
However the actual distribution may not be uniform because sequential //! \param max the maximum value
search is used to find an appropriate number from a random starting //! \param rnType RandomNumberType to specify the type
point. //! \param equiv the equivalence class based on the parameter \p mod
May return (with very small probability) a pseudoprime when a prime //! \param mod the modulus used to reduce the equivalence class
is requested and max > lastSmallPrime*lastSmallPrime (lastSmallPrime //! \throw RandomNumberNotFound if the set is empty.
is declared in nbtheory.h). //! \details Ideally, the random integer created should be uniformly distributed
\throw RandomNumberNotFound if the set is empty. //! 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()); 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); static Integer CRYPTOPP_API Power2(size_t e);
//@} //@}
//! \name ENCODE/DECODE //! \name ENCODE/DECODE
//@{ //@{
//! minimum number of bytes to encode this integer //! \brief The minimum number of bytes to encode this integer
/*! MinEncodedSize of 0 is 1 */ //! \param sign enumeration indicating Signedness
size_t MinEncodedSize(Signedness=UNSIGNED) const; //! \note The MinEncodedSize() of 0 is 1.
//! encode in big-endian format size_t MinEncodedSize(Signedness sign=UNSIGNED) const;
/*! 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;
//! 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; void DEREncode(BufferedTransformation &bt) const;
//! encode absolute value as big-endian octet string //! 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; 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; 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; size_t OpenPGPEncode(BufferedTransformation &bt) const;
//! //! \brief Decode from big-endian byte array
void Decode(const byte *input, size_t inputLen, Signedness=UNSIGNED); //! \param input big-endian byte array
//! //! \param inputLen length of the byte array
//* Precondition: bt.MaxRetrievable() >= inputLen //! \param sign enumeration indicating Signedness
void Decode(BufferedTransformation &bt, size_t inputLen, Signedness=UNSIGNED); 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); void BERDecode(const byte *input, size_t inputLen);
//!
//! \brief Decode from BER format
//! \param bt BufferedTransformation object
void BERDecode(BufferedTransformation &bt); 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); void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length);
//! \brief Exception thrown when an error is encountered decoding an OpenPGP integer
class OpenPGPDecodeErr : public Exception class OpenPGPDecodeErr : public Exception
{ {
public: public:
OpenPGPDecodeErr() : Exception(INVALID_DATA_FORMAT, "OpenPGP decode error") {} 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); void OpenPGPDecode(const byte *input, size_t inputLen);
//! //! \brief Decode from OpenPGP format
//! \param bt BufferedTransformation object
void OpenPGPDecode(BufferedTransformation &bt); void OpenPGPDecode(BufferedTransformation &bt);
//@} //@}
@ -225,14 +313,17 @@ public:
//! //!
Integer& operator-=(const Integer& t); 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 = Times(t);}
//! //!
Integer& operator/=(const Integer& t) {return *this = DividedBy(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%=(const Integer& t) {return *this = Modulo(t);}
//! //!
Integer& operator/=(word t) {return *this = DividedBy(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));} Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));}
//! //!
@ -240,12 +331,35 @@ public:
//! //!
Integer& operator>>=(size_t); Integer& operator>>=(size_t);
//! //! \brief Set this Integer to random integer
void Randomize(RandomNumberGenerator &rng, size_t bitcount); //! \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); 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 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); bool GenerateRandomNoThrow(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs);
@ -255,19 +369,24 @@ public:
throw RandomNumberNotFound(); 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); 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); void SetByte(size_t n, byte value);
//! //! \brief Reverse the Sign of the Integer
void Negate(); void Negate();
//!
//! \brief Sets the Integer to positive
void SetPositive() {sign = POSITIVE;} void SetPositive() {sign = POSITIVE;}
//!
//! \brief Sets the Integer to negative
void SetNegative() {if (!!(*this)) sign = NEGATIVE;} void SetNegative() {if (!!(*this)) sign = NEGATIVE;}
//! //! \brief Swaps this Integer with another Integer
void swap(Integer &a); void swap(Integer &a);
//@} //@}
@ -291,11 +410,11 @@ public:
//! \name BINARY OPERATORS //! \name BINARY OPERATORS
//@{ //@{
//! signed comparison //! \brief Perform signed comparison
/*! \retval -1 if *this < a //! \param a the Integer to comapre
\retval 0 if *this = a //! \retval -1 if <tt>*this < a</tt>
\retval 1 if *this > a //! \retval 0 if <tt>*this = a</tt>
*/ //! \retval 1 if <tt>*this > a</tt>
int Compare(const Integer& a) const; int Compare(const Integer& a) const;
//! //!
@ -303,14 +422,17 @@ public:
//! //!
Integer Minus(const Integer &b) const; 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 Times(const Integer &b) const;
//! //!
Integer DividedBy(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 Modulo(const Integer &b) const;
//! //!
Integer DividedBy(word b) const; Integer DividedBy(word b) const;
//! //!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
word Modulo(word b) const; word Modulo(word b) const;
//! //!
@ -326,6 +448,7 @@ public:
//! //!
Integer Doubled() const {return Plus(*this);} Integer Doubled() const {return Plus(*this);}
//! //!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Squared() const {return Times(*this);} Integer Squared() const {return Times(*this);}
//! extract square root, if negative return 0, else return floor of square root //! extract square root, if negative return 0, else return floor of square root
Integer SquareRoot() const; Integer SquareRoot() const;
@ -337,11 +460,6 @@ public:
//! return inverse if 1 or -1, otherwise return 0 //! return inverse if 1 or -1, otherwise return 0
Integer MultiplicativeInverse() const; 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)) //! 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); static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
//! use a faster division algorithm when divisor is short //! use a faster division algorithm when divisor is short
@ -353,34 +471,59 @@ public:
//! greatest common divisor //! greatest common divisor
static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n); static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n);
//! calculate multiplicative inverse of *this mod 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; Integer InverseMod(const Integer &n) const;
//! //!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
word InverseMod(word n) const; word InverseMod(word n) const;
//@} //@}
//! \name INPUT/OUTPUT //! \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); 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); 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: 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 ModularArithmetic;
friend class MontgomeryRepresentation; friend class MontgomeryRepresentation;
friend class HalfMontgomeryRepresentation; 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 PositiveAdd(Integer &sum, const Integer &a, const Integer &b);
friend void PositiveSubtract(Integer &diff, 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 PositiveMultiply(Integer &product, const Integer &a, const Integer &b);
friend void PositiveDivide(Integer &remainder, Integer &quotient, const Integer &dividend, const Integer &divisor); friend void PositiveDivide(Integer &remainder, Integer &quotient, const Integer &dividend, const Integer &divisor);
#endif
IntegerSecBlock reg;
Sign sign;
}; };
//! //!
@ -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);} 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.Times(b);}
//! //!
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(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, const CryptoPP::Integer &b) {return a.Modulo(b);}
//! //!
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(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);} inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);}
NAMESPACE_END 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) if (m_countHi < oldCountHi || SafeRightShift<2*8*sizeof(HashWordType)>(len) != 0)
throw HashInputTooLong(this->AlgorithmName()); throw HashInputTooLong(this->AlgorithmName());
unsigned int blockSize = this->BlockSize(); const unsigned int blockSize = this->BlockSize();
unsigned int num = ModPowerOf2(oldCountLo, blockSize); unsigned int num = ModPowerOf2(oldCountLo, blockSize);
T* dataBuf = this->DataBuf(); T* dataBuf = this->DataBuf();

View File

@ -10,12 +10,14 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void LUC_TestInstantiations() void LUC_TestInstantiations()
{ {
LUC_HMP<SHA>::Signer t1; LUC_HMP<SHA>::Signer t1;
LUCFunction t2; LUCFunction t2;
InvertibleLUCFunction t3; 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 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_BEGIN(CryptoPP)
namespace Weak1 { namespace Weak1 {
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void MD5_TestInstantiations() void MD5_TestInstantiations()
{ {
MD5 x; MD5 x;
} }
#endif
void MD5::InitState(HashWordType *state) void MD5::InitState(HashWordType *state)
{ {

View File

@ -11,8 +11,11 @@
#include "misc.h" #include "misc.h"
#include "words.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) #if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX)
# include <malloc.h> # include <malloc.h>
#endif #endif
@ -21,8 +24,11 @@ NAMESPACE_BEGIN(CryptoPP)
void xorbuf(byte *buf, const byte *mask, size_t count) 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 (IsAligned<word32>(buf) && IsAligned<word32>(mask))
{ {
if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(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) 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 (IsAligned<word32>(output) && IsAligned<word32>(input) && IsAligned<word32>(mask))
{ {
if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(output) && IsAligned<word64>(input) && IsAligned<word64>(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) 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; byte acc8 = 0;
if (IsAligned<word32>(buf) && IsAligned<word32>(mask)) if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
@ -139,7 +152,9 @@ void CallNewHandler()
void * AlignedAllocate(size_t size) void * AlignedAllocate(size_t size)
{ {
byte *p; 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) while ((p = (byte *)_mm_malloc(size, 16)) == NULL)
#elif defined(CRYPTOPP_MEMALIGN_AVAILABLE) #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
while ((p = (byte *)memalign(16, size)) == NULL) 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 #ifndef CRYPTOPP_MODARITH_H
#define 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 AbstractRing<Integer>;
CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain<Integer>; CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain<Integer>;
//! ring of congruence classes modulo n //! \class ModularArithmetic
/*! \note this implementation represents each congruence class as the smallest non-negative integer in that class */ //! \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> class CRYPTOPP_DLL ModularArithmetic : public AbstractRing<Integer>
{ {
public: public:
@ -25,10 +32,9 @@ public:
typedef Integer Element; typedef Integer Element;
ModularArithmetic(const Integer &modulus = Integer::One()) 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) 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 ModularArithmetic(BufferedTransformation &bt); // construct from BER encoded parameters
@ -40,7 +46,8 @@ public:
void BERDecodeElement(BufferedTransformation &in, Element &a) const; void BERDecodeElement(BufferedTransformation &in, Element &a) const;
const Integer& GetModulus() const {return m_modulus;} 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;} virtual bool IsMontgomeryRepresentation() const {return false;}
@ -111,6 +118,10 @@ public:
static const RandomizationParameter DefaultRandomizationParameter ; static const RandomizationParameter DefaultRandomizationParameter ;
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~ModularArithmetic() {}
#endif
protected: protected:
Integer m_modulus; Integer m_modulus;
mutable Integer m_result, m_result1; mutable Integer m_result, m_result1;
@ -119,8 +130,10 @@ protected:
// const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ; // const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ;
//! do modular arithmetics in Montgomery representation for increased speed //! \class MontgomeryRepresentation
/*! \note the Montgomery representation represents each congruence class [a] as a*r%n, where r is a convenient power of 2 */ //! \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 class CRYPTOPP_DLL MontgomeryRepresentation : public ModularArithmetic
{ {
public: public:
@ -150,6 +163,10 @@ public:
void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
{AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);} {AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~MontgomeryRepresentation() {}
#endif
private: private:
Integer m_u; Integer m_u;
mutable IntegerSecBlock m_workspace; mutable IntegerSecBlock m_workspace;

View File

@ -13,7 +13,7 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
#ifndef NDEBUG #if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Modes_TestInstantiations() void Modes_TestInstantiations()
{ {
CFB_Mode<DES>::Encryption m0; 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) 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_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
assert(m_feedbackSize == BlockSize()); assert(m_feedbackSize == BlockSize());
unsigned int s = BlockSize(); const unsigned int s = BlockSize();
if (dir == ENCRYPTION) if (dir == ENCRYPTION)
{ {
m_cipher->ProcessAndXorBlock(m_register, input, output); m_cipher->ProcessAndXorBlock(m_register, input, output);
if (iterationCount > 1)
m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0); m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0);
memcpy(m_register, output+(iterationCount-1)*s, s); memcpy(m_register, output+(iterationCount-1)*s, s);
} }
else else
{ {
memcpy(m_temp, input+(iterationCount-1)*s, s); // make copy first in case of in-place decryption 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->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection);
m_cipher->ProcessAndXorBlock(m_register, input, output); m_cipher->ProcessAndXorBlock(m_register, input, output);
memcpy(m_register, m_temp, s); 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 #ifndef CRYPTOPP_MODES_H
#define CRYPTOPP_MODES_H #define CRYPTOPP_MODES_H
/*! \file
*/
#include "cryptlib.h" #include "cryptlib.h"
#include "secblock.h" #include "secblock.h"
#include "misc.h" #include "misc.h"
@ -13,17 +15,18 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
//! Cipher modes documentation. See NIST SP 800-38A for definitions of these modes. See AuthenticatedSymmetricCipherDocumentation for authenticated encryption modes. //! \class CipherModeDocumentation
//! \brief Classes for operating block cipher modes of operation
/*! Each class derived from this one defines two types, Encryption and Decryption, //! \details Each class derived from this one defines two types, Encryption and Decryption,
both of which implement the SymmetricCipher interface. //! both of which implement the SymmetricCipher interface.
For each mode there are two classes, one of which is a template class, //! 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". //! and the other one has a name that ends in "_ExternalCipher".
The "external cipher" mode objects hold a reference to the underlying block cipher, //! 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. //! 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 //! For the "cipher holder" classes, the CIPHER template parameter should be a class
derived from BlockCipherDocumentation, for example DES or AES. //! 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 struct CipherModeDocumentation : public SymmetricCipherDocumentation
{ {
}; };
@ -292,7 +295,9 @@ public:
{return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();} {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();}
}; };
//! _ //! \class CipherModeFinalTemplate_ExternalCipher
//! \tparam BASE CipherModeFinalTemplate_CipherHolder class
//! \brief OFB block cipher mode of operation.
template <class BASE> template <class BASE>
class CipherModeFinalTemplate_ExternalCipher : public 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_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<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> template <class CIPHER>
struct CFB_Mode : public CipherModeDocumentation 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; 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 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_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption; 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> template <class CIPHER>
struct CFB_FIPS_Mode : public CipherModeDocumentation 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; 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 struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation
{ {
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption; 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> >; CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> >;
//! OFB mode //! \class OFB_Mode
//! \brief OFB block cipher mode of operation.
template <class CIPHER> template <class CIPHER>
struct OFB_Mode : public CipherModeDocumentation struct OFB_Mode : public CipherModeDocumentation
{ {
@ -351,7 +363,8 @@ struct OFB_Mode : public CipherModeDocumentation
typedef Encryption Decryption; typedef Encryption Decryption;
}; };
//! OFB mode, external cipher //! \class OFB_Mode_ExternalCipher
//! \brief OFB mode, external cipher.
struct OFB_Mode_ExternalCipher : public CipherModeDocumentation struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
{ {
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption; 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 AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> >;
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, 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> template <class CIPHER>
struct CTR_Mode : public CipherModeDocumentation struct CTR_Mode : public CipherModeDocumentation
{ {
@ -369,14 +383,16 @@ struct CTR_Mode : public CipherModeDocumentation
typedef Encryption Decryption; typedef Encryption Decryption;
}; };
//! CTR mode, external cipher //! \class CTR_Mode_ExternalCipher
//! \brief CTR mode, external cipher.
struct CTR_Mode_ExternalCipher : public CipherModeDocumentation struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
{ {
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption; typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
typedef Encryption Decryption; typedef Encryption Decryption;
}; };
//! ECB mode //! \class ECB_Mode
//! \brief ECB block cipher mode of operation.
template <class CIPHER> template <class CIPHER>
struct ECB_Mode : public CipherModeDocumentation struct ECB_Mode : public CipherModeDocumentation
{ {
@ -386,7 +402,8 @@ struct ECB_Mode : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ECB_OneWay>; 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 struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
{ {
typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption; 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_Encryption>;
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption>; 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 struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
{ {
typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption; typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;

View File

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

1
mqv.h
View File

@ -6,6 +6,7 @@
#include "cryptlib.h" #include "cryptlib.h"
#include "gfpcrypt.h" #include "gfpcrypt.h"
#include "modarith.h"
#include "integer.h" #include "integer.h"
#include "misc.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 #ifndef CRYPTOPP_OIDS_H
#define 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) #if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
asm __volatile__ asm __volatile__
( (
".intel_syntax noprefix;" INTEL_NOPREFIX
AS_PUSH_IF86( bx) AS_PUSH_IF86( bx)
#else #else
AS2( mov AS_REG_1, count) 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) #if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
AS_POP_IF86( bx) AS_POP_IF86( bx)
".att_syntax prefix;" ATT_PREFIX
: :
#if CRYPTOPP_BOOL_X64 #if CRYPTOPP_BOOL_X64
: "D" (count), "S" (state), "d" (z), "c" (y) : "D" (count), "S" (state), "d" (z), "c" (y)

13
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 #ifndef CRYPTOPP_PCH_H
#define CRYPTOPP_PCH_H #define CRYPTOPP_PCH_H
# ifdef CRYPTOPP_GENERATE_X64_MASM # ifdef CRYPTOPP_GENERATE_X64_MASM
#include "cpu.h" #include "cpu.h"
# else # else
#include "config.h" #include "config.h"
#ifdef USE_PRECOMPILED_HEADERS #ifdef USE_PRECOMPILED_HEADERS
@ -14,8 +17,8 @@
#include "secblock.h" #include "secblock.h"
#include "misc.h" #include "misc.h"
#include "smartptr.h" #include "smartptr.h"
#include "stdcpp.h"
#endif
# endif # endif
#endif #endif // CRYPTOPP_PCH_H
#endif

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 #ifndef CRYPTOPP_PKCSPAD_H
#define 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 #ifndef CRYPTOPP_POLYNOMI_H
#define 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); GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize, false);
byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1; byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1;
xorStart[0] ^= 1; xorStart[0] ^= 1;
if (recoverableMessage && recoverableMessageLength)
xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength); xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength);
xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size()); xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size());
if (hashIdentifier.first && hashIdentifier.second) if (hashIdentifier.first && hashIdentifier.second)
@ -114,6 +115,8 @@ DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative(
size_t &recoverableMessageLength = result.messageLength; size_t &recoverableMessageLength = result.messageLength;
valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid; valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid;
if (hashIdentifier.first && hashIdentifier.second)
valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid; valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid;
GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize); 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 #ifndef CRYPTOPP_PSSR_H
#define CRYPTOPP_PSSR_H #define CRYPTOPP_PSSR_H

157
pubkey.h
View File

@ -56,23 +56,61 @@
NAMESPACE_BEGIN(CryptoPP) 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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
{ {
public: public:
virtual ~TrapdoorFunctionBounds() {} 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; 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; 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();} 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();} 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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
{ {
public: 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; 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;} virtual bool IsRandomized() const {return true;}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
@ -80,40 +118,87 @@ public:
#endif #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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
{ {
public: public:
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~TrapdoorFunction() { } virtual ~TrapdoorFunction() { }
#endif #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 Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
{CRYPTOPP_UNUSED(rng); return ApplyFunction(x);} {CRYPTOPP_UNUSED(rng); return ApplyFunction(x);}
bool IsRandomized() const {return false;} 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; 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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
{ {
public: public:
virtual ~RandomizedTrapdoorFunctionInverse() {} 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; 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;} 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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
{ {
public: public:
virtual ~TrapdoorFunctionInverse() {} 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 Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
{return CalculateInverse(rng, x);} {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;} bool IsRandomized() const {return false;}
virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0; 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 class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
{ {
public: 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> template <class TFI, class MEI>
class CRYPTOPP_NO_VTABLE TF_Base 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> template <class BASE>
class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
{ {
@ -178,7 +269,10 @@ public:
#endif #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> template <class INTERFACE, class BASE>
class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
{ {
@ -189,14 +283,16 @@ public:
protected: protected:
size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());} 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 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~TF_CryptoSystemBase() { } virtual ~TF_CryptoSystemBase() { }
#endif #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> > class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
{ {
public: public:
@ -207,7 +303,8 @@ public:
#endif #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> > class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
{ {
public: public:
@ -222,7 +319,12 @@ public:
typedef std::pair<const byte *, size_t> HashIdentifier; 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 class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
{ {
public: 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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
{ {
public: public:
@ -303,6 +409,10 @@ public:
byte *representative, size_t representativeBitLength) const; 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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
{ {
public: public:
@ -311,6 +421,10 @@ public:
byte *representative, size_t representativeBitLength) const; 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 class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
{ {
public: public:
@ -320,6 +434,10 @@ public:
byte *representative, size_t representativeBitLength) const; 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 class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
{ {
public: public:
@ -329,6 +447,10 @@ public:
byte *representative, size_t representativeBitLength) const; 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 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
{ {
public: public:
@ -347,6 +469,10 @@ public:
bool m_empty; 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> template <class HASH_ALGORITHM>
class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM> class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
{ {
@ -379,7 +505,8 @@ public:
protected: protected:
size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());} 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 HashIdentifier GetHashIdentifier() const =0;
virtual size_t GetDigestSize() const =0; virtual size_t GetDigestSize() const =0;
}; };

View File

@ -132,7 +132,7 @@ public:
ByteQueue::ByteQueue(size_t nodeSize) ByteQueue::ByteQueue(size_t nodeSize)
: Bufferless<BufferedTransformation>(), m_autoNodeSize(!nodeSize), m_nodeSize(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); SetNodeSize(nodeSize);
m_head = m_tail = new ByteQueueNode(m_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 #ifndef CRYPTOPP_QUEUE_H
#define CRYPTOPP_QUEUE_H #define CRYPTOPP_QUEUE_H
@ -66,7 +70,8 @@ public:
{ {
public: public:
Walker(const ByteQueue &queue) 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;} 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 #ifndef CRYPTOPP_RABIN_H
#define CRYPTOPP_RABIN_H #define CRYPTOPP_RABIN_H
/** \file
*/
#include "cryptlib.h" #include "cryptlib.h"
#include "oaep.h" #include "oaep.h"
#include "pssr.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 #ifndef CRYPTOPP_RC2_H
#define CRYPTOPP_RC2_H #define CRYPTOPP_RC2_H
/** \file
*/
#include "seckey.h" #include "seckey.h"
#include "secblock.h" #include "secblock.h"
#include "algparam.h" #include "algparam.h"
NAMESPACE_BEGIN(CryptoPP) 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> struct RC2_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 128>
{ {
CRYPTOPP_CONSTANT(DEFAULT_EFFECTIVE_KEYLENGTH = 1024) 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";} 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 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> class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<RC2_Info>
{ {
public: public:
@ -31,12 +38,18 @@ class RC2 : public RC2_Info, public BlockCipherDocumentation
FixedSizeSecBlock<word16, 64> K; // expanded key table 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 class CRYPTOPP_NO_VTABLE Enc : public Base
{ {
public: public:
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; 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 class CRYPTOPP_NO_VTABLE Dec : public Base
{ {
public: public:
@ -44,6 +57,10 @@ class RC2 : public RC2_Info, public BlockCipherDocumentation
}; };
public: 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> class Encryption : public BlockCipherFinal<ENCRYPTION, Enc>
{ {
public: public:
@ -54,6 +71,9 @@ public:
{SetKey(key, keyLen, MakeParameters("EffectiveKeyLength", effectiveKeyLen));} {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> class Decryption : public BlockCipherFinal<DECRYPTION, Dec>
{ {
public: public:

View File

@ -617,7 +617,7 @@ CRYPTOPP_NAKED void CRYPTOPP_FASTCALL Rijndael_Enc_AdvancedProcessBlocks(void *l
#elif defined(__GNUC__) #elif defined(__GNUC__)
__asm__ __volatile__ __asm__ __volatile__
( (
".intel_syntax noprefix;" INTEL_NOPREFIX
#if CRYPTOPP_BOOL_X64 #if CRYPTOPP_BOOL_X64
AS2( mov L_REG, rcx) AS2( mov L_REG, rcx)
#endif #endif
@ -972,7 +972,7 @@ CRYPTOPP_NAKED void CRYPTOPP_FASTCALL Rijndael_Enc_AdvancedProcessBlocks(void *l
Rijndael_Enc_AdvancedProcessBlocks ENDP Rijndael_Enc_AdvancedProcessBlocks ENDP
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__
".att_syntax prefix;" ATT_PREFIX
: :
: "c" (locals), "d" (k), "S" (Te), "D" (g_cacheLineSize) : "c" (locals), "d" (k), "S" (Te), "D" (g_cacheLineSize)
: "memory", "cc", "%eax" : "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 #ifndef CRYPTOPP_RIJNDAEL_H
#define CRYPTOPP_RIJNDAEL_H #define CRYPTOPP_RIJNDAEL_H
/** \file
*/
#include "seckey.h" #include "seckey.h"
#include "secblock.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 #ifndef CRYPTOPP_RNG_H
#define CRYPTOPP_RNG_H #define CRYPTOPP_RNG_H
@ -47,10 +53,12 @@ private:
SecByteBlock randseed, m_lastBlock, m_deterministicTimeVector; SecByteBlock randseed, m_lastBlock, m_deterministicTimeVector;
}; };
/** This class implements Maurer's Universal Statistical Test for Random Bit Generators //! \class MaurerRandomnessTest
it is intended for measuring the randomness of *PHYSICAL* RNGs. //! \brief Maurer's Universal Statistical Test for Random Bit Generators
For more details see his paper in Journal of Cryptology, 1992. */ //! \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> class MaurerRandomnessTest : public Bufferless<Sink>
{ {
public: public:

View File

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

3
rw.cpp
View File

@ -4,8 +4,9 @@
#include "rw.h" #include "rw.h"
#include "asn.h" #include "asn.h"
#include "nbtheory.h"
#include "integer.h" #include "integer.h"
#include "nbtheory.h"
#include "modarith.h"
#ifndef CRYPTOPP_IMPORTS #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 #ifndef CRYPTOPP_RW_H
#define 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 "cryptlib.h"
#include "pubkey.h" #include "pubkey.h"

View File

@ -16,19 +16,28 @@
# pragma warning(disable: 4702 4740) # pragma warning(disable: 4702 4740)
#endif #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" // 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_SSE2_ASM_AVAILABLE
# undef CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
# define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0 # define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0
# define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0
#endif #endif
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Salsa20_TestInstantiations() void Salsa20_TestInstantiations()
{ {
Salsa20::Encryption x; Salsa20::Encryption x;
} }
#endif
void Salsa20_Policy::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length) 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); 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 unsigned int Salsa20_Policy::GetAlignment() const
{ {
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
@ -164,7 +173,7 @@ void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output
#ifdef __GNUC__ #ifdef __GNUC__
__asm__ __volatile__ __asm__ __volatile__
( (
".intel_syntax noprefix;" INTEL_NOPREFIX
AS_PUSH_IF86( bx) AS_PUSH_IF86( bx)
#else #else
void *s = m_state.data(); void *s = m_state.data();
@ -472,7 +481,7 @@ void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output
AS_POP_IF86( bp) AS_POP_IF86( bp)
#ifdef __GNUC__ #ifdef __GNUC__
AS_POP_IF86( bx) AS_POP_IF86( bx)
".att_syntax prefix;" ATT_PREFIX
#if CRYPTOPP_BOOL_X64 #if CRYPTOPP_BOOL_X64
: "+r" (input), "+r" (output), "+r" (iterationCount) : "+r" (input), "+r" (output), "+r" (iterationCount)
: "r" (m_rounds), "r" (m_state.m_ptr), "r" (workspace) : "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 // 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 #ifndef CRYPTOPP_SALSA_H
#define CRYPTOPP_SALSA_H #define CRYPTOPP_SALSA_H
#include "strciphr.h" #include "strciphr.h"
#include "secblock.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) NAMESPACE_BEGIN(CryptoPP)
//! _ //! \class Salsa20_Info
//! \brief Salsa block cipher information
struct Salsa20_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8> struct Salsa20_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8>
{ {
static const char *StaticAlgorithmName() {return "Salsa20";} static const char *StaticAlgorithmName() {return "Salsa20";}
@ -22,7 +34,7 @@ protected:
void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
bool CipherIsRandomAccess() const {return true;} bool CipherIsRandomAccess() const {return true;}
void SeekToIteration(lword iterationCount); 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 GetAlignment() const;
unsigned int GetOptimalBlockSize() const; unsigned int GetOptimalBlockSize() const;
#endif #endif
@ -31,14 +43,18 @@ protected:
int m_rounds; 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 struct Salsa20 : public Salsa20_Info, public SymmetricCipherDocumentation
{ {
typedef SymmetricCipherFinal<ConcretePolicyHolder<Salsa20_Policy, AdditiveCipherTemplate<> >, Salsa20_Info> Encryption; typedef SymmetricCipherFinal<ConcretePolicyHolder<Salsa20_Policy, AdditiveCipherTemplate<> >, Salsa20_Info> Encryption;
typedef Encryption Decryption; typedef Encryption Decryption;
}; };
//! _ //! \class XSalsa20_Info
//! \brief XSalsa20 block cipher information
struct XSalsa20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24> struct XSalsa20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24>
{ {
static const char *StaticAlgorithmName() {return "XSalsa20";} static const char *StaticAlgorithmName() {return "XSalsa20";}
@ -54,7 +70,10 @@ protected:
FixedSizeSecBlock<word32, 8> m_key; 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 struct XSalsa20 : public XSalsa20_Info, public SymmetricCipherDocumentation
{ {
typedef SymmetricCipherFinal<ConcretePolicyHolder<XSalsa20_Policy, AdditiveCipherTemplate<> >, XSalsa20_Info> Encryption; 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