cryptopp.h

Go to the documentation of this file.
00001 /**
00002  * \file cryptopp.h Subset of Crypto++ library, interface
00003  *
00004  * This file contains a subset of the Crypto++ library (version 5.2.1), with
00005  * kind permission from Wei Dai. Please note that this file should not reflect
00006  * on the real Crypto++ library in any way, as this file been greatly mangled to
00007  * reduce the code-size, since HydraNode only makes use of RSA classes (for
00008  * Secure Identification)
00009  *
00010  * For the full Crypto++ library, please refer to the official Crypto++ website,
00011  * which can be found at http://www.cryptopp.com
00012  */
00013 
00014 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00015 
00016 //
00017 // Compilation Copyright (c) 1995-2004 by Wei Dai.  All rights reserved.
00018 // This copyright applies only to this software distribution package
00019 // as a compilation, and does not imply a copyright on any particular
00020 // file in the package.
00021 //
00022 // The following files are copyrighted by their respective original authors,
00023 // and their use is subject to additional licenses included in these files.
00024 //
00025 // mars.cpp - Copyright 1998 Brian Gladman.
00026 
00027 // All other files in this compilation are placed in the public domain by
00028 // Wei Dai and other contributors.
00029 //
00030 // I would like to thank the following authors for placing their works into
00031 // the public domain:
00032 //
00033 // Joan Daemen - 3way.cpp
00034 // Leonard Janke - cast.cpp, seal.cpp
00035 // Steve Reid - cast.cpp
00036 // Phil Karn - des.cpp
00037 // Michael Paul Johnson - diamond.cpp
00038 // Andrew M. Kuchling - md2.cpp, md4.cpp
00039 // Colin Plumb - md5.cpp, md5mac.cpp
00040 // Seal Woods - rc6.cpp
00041 // Chris Morgan - rijndael.cpp
00042 // Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp
00043 // Richard De Moliner - safer.cpp
00044 // Matthew Skala - twofish.cpp
00045 // Kevin Springle - camellia.cpp, shacal2.cpp, ttmac.cpp, whrlpool.cpp, ripemd.cpp
00046 //
00047 // Permission to use, copy, modify, and distribute this compilation for
00048 // any purpose, including commercial applications, is hereby granted
00049 // without fee, subject to the following restrictions:
00050 //
00051 // 1. Any copy or modification of this compilation in any form, except
00052 // in object code form as part of an application software, must include
00053 // the above copyright notice and this license.
00054 //
00055 // 2. Users of this software agree that any modification or extension
00056 // they provide to Wei Dai will be considered public domain and not
00057 // copyrighted unless it includes an explicit copyright notice.
00058 //
00059 // 3. Wei Dai makes no warranty or representation that the operation of the
00060 // software in this compilation will be error-free, and Wei Dai is under no
00061 // obligation to provide any services, by way of maintenance, update, or
00062 // otherwise.  THE SOFTWARE AND ANY DOCUMENTATION ARE PROVIDED "AS IS"
00063 // WITHOUT EXPRESS OR IMPLIED WARRANTY INCLUDING, BUT NOT LIMITED TO,
00064 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00065 // PURPOSE. IN NO EVENT WILL WEI DAI OR ANY OTHER CONTRIBUTOR BE LIABLE FOR
00066 // DIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF
00067 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
00068 //
00069 // 4. Users will not use Wei Dai or any other contributor's name in any
00070 // publicity or advertising, without prior written consent in each case.
00071 //
00072 // 5. Export of this software from the United States may require a
00073 // specific license from the United States Government.  It is the
00074 // responsibility of any person or organization contemplating export
00075 // to obtain such a license before exporting.
00076 //
00077 // 6. Certain parts of this software may be protected by patents.  It
00078 // is the users' responsibility to obtain the appropriate
00079 // licenses before using those parts.
00080 //
00081 // If this compilation is used in object code form in an application
00082 // software, acknowledgement of the author is not required but would be
00083 // appreciated. The contribution of any useful modifications or extensions
00084 // to Wei Dai is not required but would also be appreciated.
00085 //
00086 ////////////////////////////////////////////////////////////////////////////////
00087 
00088 #ifndef CRYPTOPP_H
00089 #define CRYPTOPP_H
00090 
00091 #include <hn/osdep.h>
00092 
00093 ////////////////////////////////////////////////////////////////////////////////
00094 #ifndef CRYPTOPP_CONFIG_H5392
00095 #define CRYPTOPP_CONFIG_H
00096 
00097 // ***************** Important Settings ********************
00098 
00099 // define this if running on a big-endian CPU
00100 #if !defined(IS_LITTLE_ENDIAN) && (defined(__BIG_ENDIAN__) || defined(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__mips__) || (defined(__MWERKS__) && !defined(__INTEL__)))
00101 #       define IS_BIG_ENDIAN
00102 #endif
00103 
00104 // define this if running on a little-endian CPU
00105 // big endian will be assumed if IS_LITTLE_ENDIAN is not defined
00106 #ifndef IS_BIG_ENDIAN
00107 #       define IS_LITTLE_ENDIAN
00108 #endif
00109 
00110 // define this if you want to disable all OS-dependent features,
00111 // such as sockets and OS-provided random number generators
00112 // #define NO_OS_DEPENDENCE
00113 
00114 // Define this to use features provided by Microsoft's CryptoAPI.
00115 // Currently the only feature used is random number generation.
00116 // This macro will be ignored if NO_OS_DEPENDENCE is defined.
00117 #define USE_MS_CRYPTOAPI
00118 
00119 // Define this to 1 to enforce the requirement in FIPS 186-2 Change Notice 1 that only 1024 bit moduli be used
00120 #ifndef DSA_1024_BIT_MODULUS_ONLY
00121 #       define DSA_1024_BIT_MODULUS_ONLY 1
00122 #endif
00123 
00124 // ***************** Less Important Settings ***************
00125 
00126 #define GZIP_OS_CODE 0
00127 
00128 // Try this if your CPU has 256K internal cache or a slow multiply instruction
00129 // and you want a (possibly) faster IDEA implementation using log tables
00130 // #define IDEA_LARGECACHE
00131 
00132 // Define this if, for the linear congruential RNG, you want to use
00133 // the original constants as specified in S.K. Park and K.W. Miller's
00134 // CACM paper.
00135 // #define LCRNG_ORIGINAL_NUMBERS
00136 
00137 // choose which style of sockets to wrap (mostly useful for cygwin which has both)
00138 #define PREFER_BERKELEY_STYLE_SOCKETS
00139 // #define PREFER_WINDOWS_STYLE_SOCKETS
00140 
00141 // ***************** Important Settings Again ********************
00142 // But the defaults should be ok.
00143 
00144 // namespace support is now required
00145 #ifdef NO_NAMESPACE
00146 #       error namespace support is now required
00147 #endif
00148 
00149 // Define this to workaround a Microsoft CryptoAPI bug where
00150 // each call to CryptAcquireContext causes a 100 KB memory leak.
00151 // Defining this will cause Crypto++ to make only one call to CryptAcquireContext.
00152 #define WORKAROUND_MS_BUG_Q258000
00153 
00154 #ifdef CRYPTOPP_DOXYGEN_PROCESSING
00155 // Avoid putting "CryptoPP::" in front of everything in Doxygen output
00156 #       define CryptoPP
00157 #       define NAMESPACE_BEGIN(x)
00158 #       define NAMESPACE_END
00159 // Get Doxygen to generate better documentation for these typedefs
00160 #       define DOCUMENTED_TYPEDEF(x, y) class y : public x {};
00161 #else
00162 #       define NAMESPACE_BEGIN(x) namespace x {
00163 #       define NAMESPACE_END }
00164 #       define DOCUMENTED_TYPEDEF(x, y) typedef x y;
00165 #endif
00166 #define ANONYMOUS_NAMESPACE_BEGIN namespace {
00167 #define USING_NAMESPACE(x) using namespace x;
00168 #define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x {
00169 #define DOCUMENTED_NAMESPACE_END }
00170 
00171 // What is the type of the third parameter to bind?
00172 // For Unix, the new standard is ::socklen_t (typically unsigned int), and the old standard is int.
00173 // Unfortunately there is no way to tell whether or not socklen_t is defined.
00174 // To work around this, TYPE_OF_SOCKLEN_T is a macro so that you can change it from the makefile.
00175 #ifndef TYPE_OF_SOCKLEN_T
00176 #       if defined(_WIN32) || defined(__CYGWIN__) || defined(__MACH__)
00177 #               define TYPE_OF_SOCKLEN_T int
00178 #       else
00179 #               define TYPE_OF_SOCKLEN_T ::socklen_t
00180 #       endif
00181 #endif
00182 
00183 #if defined(__CYGWIN__) && defined(PREFER_WINDOWS_STYLE_SOCKETS)
00184 #       define __USE_W32_SOCKETS
00185 #endif
00186 
00187 typedef unsigned char byte;             // put in global namespace to avoid ambiguity with other byte typedefs
00188 
00189 NAMESPACE_BEGIN(CryptoPP)
00190 
00191 typedef unsigned short word16;
00192 typedef unsigned int word32;
00193 
00194 #if defined(__GNUC__) || defined(__MWERKS__)
00195         #define WORD64_AVAILABLE
00196         typedef uint64_t word64;
00197         #define W64LIT(x) x##LL
00198 #elif defined(_MSC_VER) || defined(__BCPLUSPLUS__)
00199         #define WORD64_AVAILABLE
00200         typedef unsigned __int64 word64;
00201         #define W64LIT(x) x##ui64
00202 #endif
00203 
00204 // define largest word type
00205 #ifdef WORD64_AVAILABLE
00206         typedef word64 lword;
00207 #else
00208         typedef word32 lword;
00209 #endif
00210 
00211 #if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || defined(__x86_64__) || defined(__mips64)
00212         // These platforms have 64-bit CPU registers. Unfortunately most C++ compilers doesn't
00213         // allow any way to access the 64-bit by 64-bit multiply instruction without using
00214         // assembly, so in order to use word64 as word, the assembly instruction must be defined
00215         // in Dword::Multiply().
00216         typedef word32 hword;
00217         typedef word64 word;
00218 #else
00219         #define CRYPTOPP_NATIVE_DWORD_AVAILABLE
00220         #ifdef WORD64_AVAILABLE
00221                 #define CRYPTOPP_SLOW_WORD64 // defined this if your CPU is not 64-bit to use alternative code that avoids word64
00222                 typedef word16 hword;
00223                 typedef word32 word;
00224                 typedef word64 dword;
00225         #else
00226                 typedef word8 hword;
00227                 typedef word16 word;
00228                 typedef word32 dword;
00229         #endif
00230 #endif
00231 
00232 const unsigned int WORD_SIZE = sizeof(word);
00233 const unsigned int WORD_BITS = WORD_SIZE * 8;
00234 
00235 #if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
00236         #define INTEL_INTRINSICS
00237         #define FAST_ROTATE
00238 #elif defined(__MWERKS__) && TARGET_CPU_PPC
00239         #define PPC_INTRINSICS
00240         #define FAST_ROTATE
00241 #elif defined(__GNUC__) && defined(__i386__)
00242         // GCC does peephole optimizations which should result in using rotate instructions
00243         #define FAST_ROTATE
00244 #endif
00245 
00246 NAMESPACE_END
00247 
00248 // VC60 workaround: it doesn't allow typename in some places
00249 #if defined(_MSC_VER) && (_MSC_VER < 1300)
00250 #define CPP_TYPENAME
00251 #else
00252 #define CPP_TYPENAME typename
00253 #endif
00254 
00255 #define CRYPTOPP_NO_VTABLE
00256 
00257 #ifdef _MSC_VER
00258         // 4231: nonstandard extension used : 'extern' before template explicit instantiation
00259         // 4250: dominance
00260         // 4251: member needs to have dll-interface
00261         // 4275: base needs to have dll-interface
00262         // 4660: explicitly instantiating a class that's already implicitly instantiated
00263         // 4661: no suitable definition provided for explicit template instantiation request
00264         // 4786: identifer was truncated in debug information
00265         // 4355: 'this' : used in base member initializer list
00266 #       pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355)
00267 #endif
00268 
00269 #if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__MWERKS__) || defined(_STLPORT_VERSION)
00270 #define CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION
00271 #endif
00272 
00273 #ifndef CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION
00274 #define CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
00275 #endif
00276 
00277 // CodeWarrior defines _MSC_VER
00278 #if !defined(CRYPTOPP_DISABLE_X86ASM) && ((defined(_MSC_VER) && !defined(__MWERKS__) && defined(_M_IX86)) || (defined(__GNUC__) && defined(__i386__)))
00279 #define CRYPTOPP_X86ASM_AVAILABLE
00280 #endif
00281 
00282 // ***************** determine availability of OS features ********************
00283 
00284 #ifndef NO_OS_DEPENDENCE
00285 
00286 #if defined(_WIN32) || defined(__CYGWIN__)
00287 #define CRYPTOPP_WIN32_AVAILABLE
00288 #endif
00289 
00290 #if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__)
00291 #define CRYPTOPP_UNIX_AVAILABLE
00292 #endif
00293 
00294 #if defined(WORD64_AVAILABLE) && (defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE))
00295 #       define HIGHRES_TIMER_AVAILABLE
00296 #endif
00297 
00298 #ifdef CRYPTOPP_UNIX_AVAILABLE
00299 #       define HAS_BERKELEY_STYLE_SOCKETS
00300 #endif
00301 
00302 #ifdef CRYPTOPP_WIN32_AVAILABLE
00303 #       define HAS_WINDOWS_STYLE_SOCKETS
00304 #endif
00305 
00306 #if defined(HIGHRES_TIMER_AVAILABLE) && (defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(HAS_WINDOWS_STYLE_SOCKETS))
00307 #       define SOCKETS_AVAILABLE
00308 #endif
00309 
00310 #if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS))
00311 #       define USE_WINDOWS_STYLE_SOCKETS
00312 #else
00313 #       define USE_BERKELEY_STYLE_SOCKETS
00314 #endif
00315 
00316 #if defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS)
00317 #       define WINDOWS_PIPES_AVAILABLE
00318 #endif
00319 
00320 #if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(USE_MS_CRYPTOAPI)
00321 #       define NONBLOCKING_RNG_AVAILABLE
00322 #       define OS_RNG_AVAILABLE
00323 #endif
00324 
00325 #if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
00326 #       define NONBLOCKING_RNG_AVAILABLE
00327 #       define BLOCKING_RNG_AVAILABLE
00328 #       define OS_RNG_AVAILABLE
00329 #       define HAS_PTHREADS
00330 #       define THREADS_AVAILABLE
00331 #endif
00332 
00333 #ifdef CRYPTOPP_WIN32_AVAILABLE
00334 #       define HAS_WINTHREADS
00335 #       define THREADS_AVAILABLE
00336 #endif
00337 
00338 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
00339 #       define CRYPTOPP_MALLOC_ALIGNMENT_IS_16
00340 #endif
00341 
00342 #if defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
00343 #       define CRYPTOPP_MEMALIGN_AVAILABLE
00344 #endif
00345 
00346 #endif  // NO_OS_DEPENDENCE
00347 
00348 // ***************** DLL related ********************
00349 
00350 #define CRYPTOPP_DLL
00351 #define CRYPTOPP_API
00352 #define CRYPTOPP_CDECL
00353 
00354 #if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_EXPORTS)
00355 #define CRYPTOPP_STATIC_TEMPLATE_CLASS template class
00356 #elif defined(__MWERKS__)
00357 #define CRYPTOPP_STATIC_TEMPLATE_CLASS extern class
00358 #else
00359 #define CRYPTOPP_STATIC_TEMPLATE_CLASS extern template class
00360 #endif
00361 
00362 #endif
00363 ////////////////////////////////////////////////////////////////////////////////
00364 
00365 
00366 
00367 ////////////////////////////////////////////////////////////////////////////////
00368 #ifndef CRYPTOPP_STDCPP_H
00369 #define CRYPTOPP_STDCPP_H
00370 
00371 #include <stddef.h>
00372 #include <assert.h>
00373 #include <limits.h>
00374 #include <memory>
00375 #include <string>
00376 #include <exception>
00377 #include <typeinfo>
00378 
00379 
00380 #ifdef _MSC_VER
00381 #include <string.h>     // CodeWarrior doesn't have memory.h
00382 #include <algorithm>
00383 #include <map>
00384 #include <vector>
00385 #include <locale>
00386 
00387 // re-disable this
00388 #pragma warning(disable: 4231)
00389 #endif
00390 
00391 #if defined(_MSC_VER) && defined(_CRTAPI1)
00392 #define CRYPTOPP_MSVCRT6
00393 #endif
00394 
00395 #endif
00396 ////////////////////////////////////////////////////////////////////////////////
00397 
00398 
00399 
00400 ////////////////////////////////////////////////////////////////////////////////
00401 // cryptlib.h - written and placed in the public domain by Wei Dai
00402 /*! \file
00403         This file contains the declarations for the abstract base
00404         classes that provide a uniform interface to this library.
00405 */
00406 
00407 /*!  <a href="http://www.cryptopp.com">Crypto++</a><sup><small>TM</small></sup> Library 5.2.1 Reference Manual
00408 <dl>
00409 <dt>Abstract Base Classes<dd>
00410         cryptlib.h
00411 <dt>Symmetric Ciphers<dd>
00412         SymmetricCipherDocumentation
00413 <dt>Hash Functions<dd>
00414         HAVAL, MD2, MD4, MD5, PanamaHash, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, SHA, SHA256, SHA384, SHA512, Tiger, Whirlpool
00415 <dt>Non-Cryptographic Checksums<dd>
00416         CRC32, Adler32
00417 <dt>Message Authentication Codes<dd>
00418         #MD5MAC, XMACC, HMAC, CBC_MAC, DMAC, PanamaMAC, TTMAC
00419 <dt>Random Number Generators<dd>
00420         NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG
00421 <dt>Password-based Cryptography<dd>
00422         PasswordBasedKeyDerivationFunction
00423 <dt>Public Key Cryptosystems<dd>
00424         DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES
00425 <dt>Public Key Signature Schemes<dd>
00426         DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RabinSS, RWSS, ESIGN
00427 <dt>Key Agreement<dd>
00428         #DH, DH2, #MQV, ECDH, ECMQV, XTR_DH
00429 <dt>Algebraic Structures<dd>
00430         Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver,
00431         ModularArithmetic, MontgomeryRepresentation, GFP2_ONB,
00432         GF2NP, GF256, GF2_32, EC2N, ECP
00433 <dt>Secret Sharing and Information Dispersal<dd>
00434         SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery
00435 <dt>Compression<dd>
00436         Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor
00437 <dt>Input Source Classes<dd>
00438         StringSource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource
00439 <dt>Output Sink Classes<dd>
00440         StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink
00441 <dt>Filter Wrappers<dd>
00442         StreamTransformationFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter
00443 <dt>Binary to Text Encoders and Decoders<dd>
00444         HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base32Encoder, Base32Decoder
00445 <dt>Wrappers for OS features<dd>
00446         Timer, Socket, WindowsHandle, ThreadLocalStorage, ThreadUserTimer
00447 <dt>FIPS 140 related<dd>
00448         fips140.h
00449 </dl>
00450 
00451 In the FIPS 140-2 validated DLL version of Crypto++, only the following implementation class are available.
00452 <dl>
00453 <dt>Block Ciphers<dd>
00454         AES, DES_EDE2, DES_EDE3, SKIPJACK
00455 <dt>Cipher Modes (replace template parameter BC with one of the block ciphers above)<dd>
00456         ECB_Mode<BC>, CTR_Mode<BC>, CBC_Mode<BC>, CFB_Mode<BC>, OFB_Mode<BC>
00457 <dt>Hash Functions<dd>
00458         SHA
00459 <dt>Public Key Signature Schemes<dd>
00460         RSASS<PKCS1v15, SHA>, DSA, ECDSA<ECP, SHA>, ECDSA<EC2N, SHA>
00461 <dt>Message Authentication Codes<dd>
00462         HMAC<SHA>, CBC_MAC<DES_EDE2>, CBC_MAC<DES_EDE3>
00463 <dt>Random Number Generators<dd>
00464         AutoSeededX917RNG<DES_EDE3>
00465 <dt>Key Agreement<dd>
00466         #DH
00467 <dt>Public Key Cryptosystems<dd>
00468         RSAES<OAEP<SHA> >
00469 </dl>
00470 
00471 <p>This reference manual is a work in progress. Some classes are still lacking detailed descriptions.
00472 <p>Click <a href="CryptoPPRef.zip">here</a> to download a zip archive containing this manual.
00473 <p>Thanks to Ryan Phillips for providing the Doxygen configuration file
00474 and getting me started with this manual.
00475 */
00476 
00477 #ifndef CRYPTOPP_CRYPTLIB_H
00478 #define CRYPTOPP_CRYPTLIB_H
00479 
00480 //- #include "config.h"
00481 //- #include "stdcpp.h"
00482 
00483 namespace CryptoPP {
00484 
00485 // forward declarations
00486 class Integer;
00487 
00488 //! used to specify a direction for a cipher to operate in (encrypt or decrypt)
00489 enum CipherDir {ENCRYPTION,     DECRYPTION};
00490 
00491 // VC60 workaround: using enums as template parameters causes problems
00492 template <typename ENUM_TYPE, int VALUE>
00493 struct EnumToType
00494 {
00495         static ENUM_TYPE ToEnum() {return (ENUM_TYPE)VALUE;}
00496 };
00497 
00498 enum ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1};
00499 typedef EnumToType<ByteOrder, LITTLE_ENDIAN_ORDER> LittleEndian;
00500 typedef EnumToType<ByteOrder, BIG_ENDIAN_ORDER> BigEndian;
00501 
00502 //! base class for all exceptions thrown by Crypto++
00503 class CRYPTOPP_DLL Exception : public std::exception
00504 {
00505 public:
00506         //! error types
00507         enum ErrorType {
00508                 //! a method is not implemented
00509                 NOT_IMPLEMENTED,
00510                 //! invalid function argument
00511                 INVALID_ARGUMENT,
00512                 //! BufferedTransformation received a Flush(true) signal but can't flush buffers
00513                 CANNOT_FLUSH,
00514                 //! data integerity check (such as CRC or MAC) failed
00515                 DATA_INTEGRITY_CHECK_FAILED,
00516                 //! received input data that doesn't conform to expected format
00517                 INVALID_DATA_FORMAT,
00518                 //! error reading from input device or writing to output device
00519                 IO_ERROR,
00520                 //! some error not belong to any of the above categories
00521                 OTHER_ERROR
00522         };
00523 
00524         explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {}
00525         virtual ~Exception() throw() {}
00526         const char *what() const throw() {return (m_what.c_str());}
00527         const std::string &GetWhat() const {return m_what;}
00528         void SetWhat(const std::string &s) {m_what = s;}
00529         ErrorType GetErrorType() const {return m_errorType;}
00530         void SetErrorType(ErrorType errorType) {m_errorType = errorType;}
00531 
00532 private:
00533         ErrorType m_errorType;
00534         std::string m_what;
00535 };
00536 
00537 //! exception thrown when an invalid argument is detected
00538 class CRYPTOPP_DLL InvalidArgument : public Exception
00539 {
00540 public:
00541         explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {}
00542 };
00543 
00544 //! exception thrown by decryption filters when trying to decrypt an invalid ciphertext
00545 class CRYPTOPP_DLL InvalidDataFormat : public Exception
00546 {
00547 public:
00548         explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {}
00549 };
00550 
00551 //! exception thrown by a class if a non-implemented method is called
00552 class CRYPTOPP_DLL NotImplemented : public Exception
00553 {
00554 public:
00555         explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {}
00556 };
00557 
00558 //! exception thrown by a class when Flush(true) is called but it can't completely flush its buffers
00559 class CRYPTOPP_DLL CannotFlush : public Exception
00560 {
00561 public:
00562         explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {}
00563 };
00564 
00565 //! error reported by the operating system
00566 class CRYPTOPP_DLL OS_Error : public Exception
00567 {
00568 public:
00569         OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode)
00570                 : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {}
00571         ~OS_Error() throw() {}
00572 
00573         // the operating system API that reported the error
00574         const std::string & GetOperation() const {return m_operation;}
00575         // the error code return by the operating system
00576         int GetErrorCode() const {return m_errorCode;}
00577 
00578 protected:
00579         std::string m_operation;
00580         int m_errorCode;
00581 };
00582 
00583 //! used to return decoding results
00584 struct CRYPTOPP_DLL DecodingResult
00585 {
00586         explicit DecodingResult() : isValidCoding(false), messageLength(0) {}
00587         explicit DecodingResult(unsigned int len) : isValidCoding(true), messageLength(len) {}
00588 
00589         bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;}
00590         bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);}
00591 
00592         bool isValidCoding;
00593         unsigned int messageLength;
00594 
00595 };
00596 
00597 //! interface for retrieving values given their names
00598 /*! \note This class is used to safely pass a variable number of arbitrarily typed arguments to functions
00599         and to read values from keys and crypto parameters.
00600         \note To obtain an object that implements NameValuePairs for the purpose of parameter
00601         passing, use the MakeParameters() function.
00602         \note To get a value from NameValuePairs, you need to know the name and the type of the value.
00603         Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports.
00604         Then look at the Name namespace documentation to see what the type of each value is, or
00605         alternatively, call GetIntValue() with the value name, and if the type is not int, a
00606         ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object.
00607 */
00608 class CRYPTOPP_NO_VTABLE NameValuePairs
00609 {
00610 public:
00611         virtual ~NameValuePairs() {}
00612 
00613         //! exception thrown when trying to retrieve a value using a different type than expected
00614         class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument
00615         {
00616         public:
00617                 ValueTypeMismatch(const std::string &name, const std::type_info &stored, const std::type_info &retrieving)
00618                         : InvalidArgument("NameValuePairs: type mismatch for '" + name + "', stored '" + stored.name() + "', trying to retrieve '" + retrieving.name() + "'")
00619                         , m_stored(stored), m_retrieving(retrieving) {}
00620 
00621                 const std::type_info & GetStoredTypeInfo() const {return m_stored;}
00622                 const std::type_info & GetRetrievingTypeInfo() const {return m_retrieving;}
00623 
00624         private:
00625                 const std::type_info &m_stored;
00626                 const std::type_info &m_retrieving;
00627         };
00628 
00629         //! get a copy of this object or a subobject of it
00630         template <class T>
00631         bool GetThisObject(T &object) const
00632         {
00633                 return GetValue((std::string("ThisObject:")+typeid(T).name()).c_str(), object);
00634         }
00635 
00636         //! get a pointer to this object, as a pointer to T
00637         template <class T>
00638         bool GetThisPointer(T *&p) const
00639         {
00640                 return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), p);
00641         }
00642 
00643         //! get a named value, returns true if the name exists
00644         template <class T>
00645         bool GetValue(const char *name, T &value) const
00646         {
00647                 return GetVoidValue(name, typeid(T), &value);
00648         }
00649 
00650         //! get a named value, returns the default if the name doesn't exist
00651         template <class T>
00652         T GetValueWithDefault(const char *name, T defaultValue) const
00653         {
00654                 GetValue(name, defaultValue);
00655                 return defaultValue;
00656         }
00657 
00658         //! get a list of value names that can be retrieved
00659         CRYPTOPP_DLL std::string GetValueNames() const
00660                 {std::string result; GetValue("ValueNames", result); return result;}
00661 
00662         //! get a named value with type int
00663         /*! used to ensure we don't accidentally try to get an unsigned int
00664                 or some other type when we mean int (which is the most common case) */
00665         CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const
00666                 {return GetValue(name, value);}
00667 
00668         //! get a named value with type int, with default
00669         CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
00670                 {return GetValueWithDefault(name, defaultValue);}
00671 
00672         //! used by derived classes to check for type mismatch
00673         CRYPTOPP_DLL static void ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving)
00674                 {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);}
00675 
00676         template <class T>
00677         void GetRequiredParameter(const char *className, const char *name, T &value) const
00678         {
00679                 if (!GetValue(name, value))
00680                         throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'");
00681         }
00682 
00683         CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const
00684         {
00685                 if (!GetIntValue(name, value))
00686                         throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'");
00687         }
00688 
00689         //! to be implemented by derived classes, users should use one of the above functions instead
00690         CRYPTOPP_DLL virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0;
00691 };
00692 
00693 //! empty set of name-value pairs
00694 class CRYPTOPP_DLL NullNameValuePairs : public NameValuePairs
00695 {
00696 public:
00697         bool GetVoidValue(const char* /* name */, const std::type_info& /* valueType */, void* /* pValue */) const {return false;}
00698 };
00699 
00700 //! _
00701 extern CRYPTOPP_DLL const NullNameValuePairs g_nullNameValuePairs;
00702 
00703 // ********************************************************
00704 
00705 //! interface for cloning objects, this is not implemented by most classes yet
00706 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable
00707 {
00708 public:
00709         virtual ~Clonable() {}
00710         //! this is not implemented by most classes yet
00711         virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");}      // TODO: make this =0
00712 };
00713 
00714 //! interface for all crypto algorithms
00715 
00716 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Algorithm : public Clonable
00717 {
00718 public:
00719         /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true,
00720                 this constructor throws SelfTestFailure if the self test hasn't been run or fails. */
00721         Algorithm(bool checkSelfTestStatus = true);
00722         //! returns name of this algorithm, not universally implemented yet
00723         virtual std::string AlgorithmName() const {return "unknown";}
00724 };
00725 
00726 //! keying interface for crypto algorithms that take byte strings as keys
00727 
00728 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyingInterface
00729 {
00730 public:
00731         virtual ~SimpleKeyingInterface() {}
00732 
00733         //! returns smallest valid key length in bytes */
00734         virtual unsigned int MinKeyLength() const =0;
00735         //! returns largest valid key length in bytes */
00736         virtual unsigned int MaxKeyLength() const =0;
00737         //! returns default (recommended) key length in bytes */
00738         virtual unsigned int DefaultKeyLength() const =0;
00739 
00740         //! returns the smallest valid key length in bytes that is >= min(n, GetMaxKeyLength())
00741         virtual unsigned int GetValidKeyLength(unsigned int n) const =0;
00742 
00743         //! returns whether n is a valid key length
00744         virtual bool IsValidKeyLength(unsigned int n) const
00745                 {return n == GetValidKeyLength(n);}
00746 
00747         //! set or reset the key of this object
00748         /*! \param params is used to specify Rounds, BlockSize, etc */
00749         virtual void SetKey(const byte *key, unsigned int length, const NameValuePairs &params = g_nullNameValuePairs) =0;
00750 
00751         //! calls SetKey() with an NameValuePairs object that just specifies "Rounds"
00752         void SetKeyWithRounds(const byte *key, unsigned int length, int rounds);
00753 
00754         //! calls SetKey() with an NameValuePairs object that just specifies "IV"
00755         void SetKeyWithIV(const byte *key, unsigned int length, const byte *iv);
00756 
00757         enum IV_Requirement {STRUCTURED_IV = 0, RANDOM_IV, UNPREDICTABLE_RANDOM_IV, INTERNALLY_GENERATED_IV, NOT_RESYNCHRONIZABLE};
00758         //! returns the minimal requirement for secure IVs
00759         virtual IV_Requirement IVRequirement() const =0;
00760 
00761         //! returns whether this object can be resynchronized (i.e. supports initialization vectors)
00762         /*! If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, an IV of all 0's will be assumed. */
00763         bool IsResynchronizable() const {return IVRequirement() < NOT_RESYNCHRONIZABLE;}
00764         //! returns whether this object can use random IVs (in addition to ones returned by GetNextIV)
00765         bool CanUseRandomIVs() const {return IVRequirement() <= UNPREDICTABLE_RANDOM_IV;}
00766         //! returns whether this object can use random but possibly predictable IVs (in addition to ones returned by GetNextIV)
00767         bool CanUsePredictableIVs() const {return IVRequirement() <= RANDOM_IV;}
00768         //! returns whether this object can use structured IVs, for example a counter (in addition to ones returned by GetNextIV)
00769         bool CanUseStructuredIVs() const {return IVRequirement() <= STRUCTURED_IV;}
00770 
00771         //! returns size of IVs used by this object
00772         virtual unsigned int IVSize() const {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00773         //! resynchronize with an IV
00774         virtual void Resynchronize(const byte* /* IV */) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00775         //! get a secure IV for the next message
00776         /*! This method should be called after you finish encrypting one message and are ready to start the next one.
00777                 After calling it, you must call SetKey() or Resynchronize() before using this object again.
00778                 This method is not implemented on decryption objects. */
00779         virtual void GetNextIV(byte* /* IV */) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support GetNextIV()");}
00780 
00781 protected:
00782         void ThrowIfInvalidKeyLength(const Algorithm &algorithm, unsigned int length);
00783         void ThrowIfResynchronizable();                 // to be called when no IV is passed
00784         void ThrowIfInvalidIV(const byte *iv);  // check for NULL IV if it can't be used
00785         const byte * GetIVAndThrowIfInvalid(const NameValuePairs &params);
00786 
00787         inline void AssertValidKeyLength(unsigned int length) const
00788         {
00789                 assert(IsValidKeyLength(length));
00790         }
00791 };
00792 
00793 //! interface for the data processing part of block ciphers
00794 
00795 /*! Classes derived from BlockTransformation are block ciphers
00796         in ECB mode (for example the DES::Encryption class), which are stateless,
00797         and they can make assumptions about the memory alignment of their inputs and outputs.
00798         These classes should not be used directly, but only in combination with
00799         a mode class (see CipherModeDocumentation in modes.h).
00800 */
00801 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm
00802 {
00803 public:
00804         //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock
00805         virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0;
00806 
00807         //! encrypt or decrypt one block
00808         /*! \pre size of inBlock and outBlock == BlockSize() */
00809         void ProcessBlock(const byte *inBlock, byte *outBlock) const
00810                 {ProcessAndXorBlock(inBlock, NULL, outBlock);}
00811 
00812         //! encrypt or decrypt one block in place
00813         void ProcessBlock(byte *inoutBlock) const
00814                 {ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);}
00815 
00816         //! block size of the cipher in bytes
00817         virtual unsigned int BlockSize() const =0;
00818 
00819         //! block pointers must be divisible by this
00820         virtual unsigned int BlockAlignment() const {return 4;}
00821 
00822         //! returns true if this is a permutation (i.e. there is an inverse transformation)
00823         virtual bool IsPermutation() const {return true;}
00824 
00825         //! returns true if this is an encryption object
00826         virtual bool IsForwardTransformation() const =0;
00827 
00828         //! return number of blocks that can be processed in parallel, for bit-slicing implementations
00829         virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;}
00830 
00831         //! encrypt or decrypt multiple blocks, for bit-slicing implementations
00832         virtual void ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, unsigned int numberOfBlocks) const;
00833 };
00834 
00835 //! interface for the data processing part of stream ciphers
00836 
00837 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm
00838 {
00839 public:
00840         //! return a reference to this object,
00841         /*! This function is useful for passing a temporary StreamTransformation object to a
00842                 function that takes a non-const reference. */
00843         StreamTransformation& Ref() {return *this;}
00844 
00845         //! returns block size, if input must be processed in blocks, otherwise 1
00846         virtual unsigned int MandatoryBlockSize() const {return 1;}
00847 
00848         //! returns the input block size that is most efficient for this cipher
00849         /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */
00850         virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();}
00851         //! returns how much of the current block is used up
00852         virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;}
00853 
00854         //! returns how input should be aligned for optimal performance
00855         virtual unsigned int OptimalDataAlignment() const {return 1;}
00856 
00857         //! encrypt or decrypt an array of bytes of specified length
00858         /*! \note either inString == outString, or they don't overlap */
00859         virtual void ProcessData(byte *outString, const byte *inString, unsigned int length) =0;
00860 
00861         //! for ciphers where the last block of data is special, encrypt or decrypt the last block of data
00862         /*! For now the only use of this function is for CBC-CTS mode. */
00863         virtual void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length);
00864         //! returns the minimum size of the last block, 0 indicating the last block is not special
00865         virtual unsigned int MinLastBlockSize() const {return 0;}
00866 
00867         //! same as ProcessData(inoutString, inoutString, length)
00868         inline void ProcessString(byte *inoutString, unsigned int length)
00869                 {ProcessData(inoutString, inoutString, length);}
00870         //! same as ProcessData(outString, inString, length)
00871         inline void ProcessString(byte *outString, const byte *inString, unsigned int length)
00872                 {ProcessData(outString, inString, length);}
00873         //! implemented as {ProcessData(&input, &input, 1); return input;}
00874         inline byte ProcessByte(byte input)
00875                 {ProcessData(&input, &input, 1); return input;}
00876 
00877         //! returns whether this cipher supports random access
00878         virtual bool IsRandomAccess() const =0;
00879         //! for random access ciphers, seek to an absolute position
00880         virtual void Seek(lword /* n */)
00881         {
00882                 assert(!IsRandomAccess());
00883                 throw NotImplemented("StreamTransformation: this object doesn't support random access");
00884         }
00885 
00886         //! returns whether this transformation is self-inverting (e.g. xor with a keystream)
00887         virtual bool IsSelfInverting() const =0;
00888         //! returns whether this is an encryption object
00889         virtual bool IsForwardTransformation() const =0;
00890 };
00891 
00892 //! interface for hash functions and data processing part of MACs
00893 
00894 /*! HashTransformation objects are stateful.  They are created in an initial state,
00895         change state as Update() is called, and return to the initial
00896         state when Final() is called.  This interface allows a large message to
00897         be hashed in pieces by calling Update() on each piece followed by
00898         calling Final().
00899 */
00900 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm
00901 {
00902 public:
00903         //! process more input
00904         virtual void Update(const byte *input, unsigned int length) =0;
00905 
00906         //! request space to write input into
00907         virtual byte * CreateUpdateSpace(unsigned int &size) {size=0; return NULL;}
00908 
00909         //! compute hash for current message, then restart for a new message
00910         /*!     \pre size of digest == DigestSize(). */
00911         virtual void Final(byte *digest)
00912                 {TruncatedFinal(digest, DigestSize());}
00913 
00914         //! discard the current state, and restart with a new message
00915         virtual void Restart()
00916                 {TruncatedFinal(NULL, 0);}
00917 
00918         //! size of the hash returned by Final()
00919         virtual unsigned int DigestSize() const =0;
00920 
00921         //! block size of underlying compression function, or 0 if not block based
00922         virtual unsigned int BlockSize() const {return 0;}
00923 
00924         //! input to Update() should have length a multiple of this for optimal speed
00925         virtual unsigned int OptimalBlockSize() const {return 1;}
00926 
00927         //! returns how input should be aligned for optimal performance
00928         virtual unsigned int OptimalDataAlignment() const {return 1;}
00929 
00930         //! use this if your input is in one piece and you don't want to call Update() and Final() separately
00931         virtual void CalculateDigest(byte *digest, const byte *input, unsigned int length)
00932                 {Update(input, length); Final(digest);}
00933 
00934         //! verify that digest is a valid digest for the current message, then reinitialize the object
00935         /*! Default implementation is to call Final() and do a bitwise comparison
00936                 between its output and digest. */
00937         virtual bool Verify(const byte *digest)
00938                 {return TruncatedVerify(digest, DigestSize());}
00939 
00940         //! use this if your input is in one piece and you don't want to call Update() and Verify() separately
00941         virtual bool VerifyDigest(const byte *digest, const byte *input, unsigned int length)
00942                 {Update(input, length); return Verify(digest);}
00943 
00944         //! truncated version of Final()
00945         virtual void TruncatedFinal(byte *digest, unsigned int digestSize) =0;
00946 
00947         //! truncated version of CalculateDigest()
00948         virtual void CalculateTruncatedDigest(byte *digest, unsigned int digestSize, const byte *input, unsigned int length)
00949                 {Update(input, length); TruncatedFinal(digest, digestSize);}
00950 
00951         //! truncated version of Verify()
00952         virtual bool TruncatedVerify(const byte *digest, unsigned int digestLength);
00953 
00954         //! truncated version of VerifyDigest()
00955         virtual bool VerifyTruncatedDigest(const byte *digest, unsigned int digestLength, const byte *input, unsigned int length)
00956                 {Update(input, length); return TruncatedVerify(digest, digestLength);}
00957 
00958 protected:
00959         void ThrowIfInvalidTruncatedSize(unsigned int size) const;
00960 };
00961 
00962 typedef HashTransformation HashFunction;
00963 
00964 template <class T>
00965 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyedTransformation : public T, public SimpleKeyingInterface
00966 {
00967 public:
00968         void ThrowIfInvalidKeyLength(unsigned int length)
00969                 {SimpleKeyingInterface::ThrowIfInvalidKeyLength(*this, length);}
00970 };
00971 
00972 typedef SimpleKeyedTransformation<BlockTransformation> BlockCipher;
00973 typedef SimpleKeyedTransformation<StreamTransformation> SymmetricCipher;
00974 typedef SimpleKeyedTransformation<HashTransformation> MessageAuthenticationCode;
00975 
00976 //! interface for random number generators
00977 /*! All return values are uniformly distributed over the range specified.
00978 */
00979 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm
00980 {
00981 public:
00982         //! generate new random byte and return it
00983         virtual byte GenerateByte() =0;
00984 
00985         //! generate new random bit and return it
00986         /*! Default implementation is to call GenerateByte() and return its parity. */
00987         virtual unsigned int GenerateBit();
00988 
00989         //! generate a random 32 bit word in the range min to max, inclusive
00990         virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL);
00991 
00992         //! generate random array of bytes
00993         /*! Default implementation is to call GenerateByte() size times. */
00994         virtual void GenerateBlock(byte *output, unsigned int size);
00995 
00996         //! generate and discard n bytes
00997         /*! Default implementation is to call GenerateByte() n times. */
00998         virtual void DiscardBytes(unsigned int n);
00999 
01000         //! randomly shuffle the specified array, resulting permutation is uniformly distributed
01001         template <class IT> void Shuffle(IT begin, IT end)
01002         {
01003                 for (; begin != end; ++begin)
01004                         std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1));
01005         }
01006 
01007 };
01008 
01009 //! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it
01010 CRYPTOPP_DLL RandomNumberGenerator & NullRNG();
01011 
01012 class WaitObjectContainer;
01013 
01014 //! interface for objects that you can wait for
01015 
01016 class CRYPTOPP_NO_VTABLE Waitable
01017 {
01018 public:
01019         virtual ~Waitable() {}
01020 
01021         //! maximum number of wait objects that this object can return
01022         virtual unsigned int GetMaxWaitObjectCount() const =0;
01023         //! put wait objects into container
01024         virtual void GetWaitObjects(WaitObjectContainer &container) =0;
01025         //! wait on this object
01026         /*! same as creating an empty container, calling GetWaitObjects(), and calling Wait() on the container */
01027         bool Wait(unsigned long milliseconds);
01028 };
01029 
01030 //! interface for buffered transformations
01031 
01032 /*! BufferedTransformation is a generalization of BlockTransformation,
01033         StreamTransformation, and HashTransformation.
01034 
01035         A buffered transformation is an object that takes a stream of bytes
01036         as input (this may be done in stages), does some computation on them, and
01037         then places the result into an internal buffer for later retrieval.  Any
01038         partial result already in the output buffer is not modified by further
01039         input.
01040 
01041         If a method takes a "blocking" parameter, and you
01042         pass "false" for it, the method will return before all input has been processed if
01043         the input cannot be processed without waiting (for network buffers to become available, for example).
01044         In this case the method will return true
01045         or a non-zero integer value. When this happens you must continue to call the method with the same
01046         parameters until it returns false or zero, before calling any other method on it or
01047         attached BufferedTransformation. The integer return value in this case is approximately
01048         the number of bytes left to be processed, and can be used to implement a progress bar.
01049 
01050         For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached
01051         BufferedTransformation objects, with propagation decremented at each step until it reaches 0.
01052         -1 means unlimited propagation.
01053 
01054         \nosubgrouping
01055 */
01056 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable
01057 {
01058 public:
01059         // placed up here for CW8
01060         static const std::string NULL_CHANNEL;  // the empty string ""
01061 
01062         BufferedTransformation() : Algorithm(false) {}
01063 
01064         //! return a reference to this object
01065         /*! This function is useful for passing a temporary BufferedTransformation object to a
01066                 function that takes a non-const reference. */
01067         BufferedTransformation& Ref() {return *this;}
01068 
01069         //!     \name INPUT
01070         //@{
01071                 //! input a byte for processing
01072                 unsigned int Put(byte inByte, bool blocking=true)
01073                         {return Put(&inByte, 1, blocking);}
01074                 //! input multiple bytes
01075                 unsigned int Put(const byte *inString, unsigned int length, bool blocking=true)
01076                         {return Put2(inString, length, 0, blocking);}
01077 
01078                 //! input a 16-bit word
01079                 unsigned int PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
01080                 //! input a 32-bit word
01081                 unsigned int PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
01082 
01083                 //! request space which can be written into by the caller, and then used as input to Put()
01084                 /*! \param size is requested size (as a hint) for input, and size of the returned space for output */
01085                 /*! \note The purpose of this method is to help avoid doing extra memory allocations. */
01086                 virtual byte * CreatePutSpace(unsigned int &size) {size=0; return NULL;}
01087 
01088                 virtual bool CanModifyInput() const {return false;}
01089 
01090                 //! input multiple bytes that may be modified by callee
01091                 unsigned int PutModifiable(byte *inString, unsigned int length, bool blocking=true)
01092                         {return PutModifiable2(inString, length, 0, blocking);}
01093 
01094                 bool MessageEnd(int propagation=-1, bool blocking=true)
01095                         {return !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
01096                 unsigned int PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1, bool blocking=true)
01097                         {return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
01098 
01099                 //! input multiple bytes for blocking or non-blocking processing
01100                 /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */
01101                 virtual unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking) =0;
01102                 //! input multiple bytes that may be modified by callee for blocking or non-blocking processing
01103                 /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */
01104                 virtual unsigned int PutModifiable2(byte *inString, unsigned int length, int messageEnd, bool blocking)
01105                         {return Put2(inString, length, messageEnd, blocking);}
01106 
01107                 //! thrown by objects that have not implemented nonblocking input processing
01108                 struct BlockingInputOnly : public NotImplemented
01109                         {BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}};
01110         //@}
01111 
01112         //!     \name WAITING
01113         //@{
01114                 unsigned int GetMaxWaitObjectCount() const;
01115                 void GetWaitObjects(WaitObjectContainer &container);
01116         //@}
01117 
01118         //!     \name SIGNALS
01119         //@{
01120                 virtual void IsolatedInitialize(const NameValuePairs& /* parameters */) {throw NotImplemented("BufferedTransformation: this object can't be reinitialized");}
01121                 virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0;
01122                 virtual bool IsolatedMessageSeriesEnd(bool /* blocking */) {return false;}
01123 
01124                 //! initialize or reinitialize this object
01125                 virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
01126                 //! flush buffered input and/or output
01127                 /*! \param hardFlush is used to indicate whether all data should be flushed
01128                         \note Hard flushes must be used with care. It means try to process and output everything, even if
01129                         there may not be enough data to complete the action. For example, hard flushing a HexDecoder would
01130                         cause an error if you do it after inputing an odd number of hex encoded characters.
01131                         For some types of filters, for example ZlibDecompressor, hard flushes can only
01132                         be done at "synchronization points". These synchronization points are positions in the data
01133                         stream that are created by hard flushes on the corresponding reverse filters, in this
01134                         example ZlibCompressor. This is useful when zlib compressed data is moved across a
01135                         network in packets and compression state is preserved across packets, as in the ssh2 protocol.
01136                 */
01137                 virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
01138                 //! mark end of a series of messages
01139                 /*! There should be a MessageEnd immediately before MessageSeriesEnd. */
01140                 virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
01141 
01142                 //! set propagation of automatically generated and transferred signals
01143                 /*! propagation == 0 means do not automaticly generate signals */
01144                 virtual void SetAutoSignalPropagation(int /* propagation */) {}
01145 
01146                 //!
01147                 virtual int GetAutoSignalPropagation() const {return 0;}
01148 public:
01149 
01150         //@}
01151 
01152         //!     \name RETRIEVAL OF ONE MESSAGE
01153         //@{
01154                 //! returns number of bytes that is currently ready for retrieval
01155                 /*! All retrieval functions return the actual number of bytes
01156                         retrieved, which is the lesser of the request number and
01157                         MaxRetrievable(). */
01158                 virtual unsigned long MaxRetrievable() const;
01159 
01160                 //! returns whether any bytes are currently ready for retrieval
01161                 virtual bool AnyRetrievable() const;
01162 
01163                 //! try to retrieve a single byte
01164                 virtual unsigned int Get(byte &outByte);
01165                 //! try to retrieve multiple bytes
01166                 virtual unsigned int Get(byte *outString, unsigned int getMax);
01167 
01168                 //! peek at the next byte without removing it from the output buffer
01169                 virtual unsigned int Peek(byte &outByte) const;
01170                 //! peek at multiple bytes without removing them from the output buffer
01171                 virtual unsigned int Peek(byte *outString, unsigned int peekMax) const;
01172 
01173                 //! try to retrieve a 16-bit word
01174                 unsigned int GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER);
01175                 //! try to retrieve a 32-bit word
01176                 unsigned int GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER);
01177 
01178                 //! try to peek at a 16-bit word
01179                 unsigned int PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER);
01180                 //! try to peek at a 32-bit word
01181                 unsigned int PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER);
01182 
01183                 //! move transferMax bytes of the buffered output to target as input
01184                 unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX, const std::string &channel=NULL_CHANNEL)
01185                         {TransferTo2(target, transferMax, channel); return transferMax;}
01186 
01187                 //! discard skipMax bytes from the output buffer
01188                 virtual unsigned long Skip(unsigned long skipMax=ULONG_MAX);
01189 
01190                 //! copy copyMax bytes of the buffered output to target as input
01191                 unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX, const std::string &channel=NULL_CHANNEL) const
01192                         {return CopyRangeTo(target, 0, copyMax, channel);}
01193 
01194                 //! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input
01195                 unsigned long CopyRangeTo(BufferedTransformation &target, unsigned long position, unsigned long copyMax=ULONG_MAX, const std::string &channel=NULL_CHANNEL) const
01196                         {unsigned long i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;}
01197 
01198         //@}
01199 
01200         //!     \name RETRIEVAL OF MULTIPLE MESSAGES
01201         //@{
01202                 //!
01203                 virtual unsigned long TotalBytesRetrievable() const;
01204                 //! number of times MessageEnd() has been received minus messages retrieved or skipped
01205                 virtual unsigned int NumberOfMessages() const;
01206                 //! returns true if NumberOfMessages() > 0
01207                 virtual bool AnyMessages() const;
01208                 //! start retrieving the next message
01209                 /*!
01210                         Returns false if no more messages exist or this message
01211                         is not completely retrieved.
01212                 */
01213                 virtual bool GetNextMessage();
01214                 //! skip count number of messages
01215                 virtual unsigned int SkipMessages(unsigned int count=UINT_MAX);
01216                 //!
01217                 unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL)
01218                         {TransferMessagesTo2(target, count, channel); return count;}
01219                 //!
01220                 unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL) const;
01221 
01222                 //!
01223                 virtual void SkipAll();
01224                 //!
01225                 void TransferAllTo(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL)
01226                         {TransferAllTo2(target, channel);}
01227                 //!
01228                 void CopyAllTo(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL) const;
01229 
01230                 virtual bool GetNextMessageSeries() {return false;}
01231                 virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();}
01232                 virtual unsigned int NumberOfMessageSeries() const {return 0;}
01233         //@}
01234 
01235         //!     \name NON-BLOCKING TRANSFER OF OUTPUT
01236         //@{
01237                 virtual unsigned int TransferTo2(BufferedTransformation &target, unsigned long &byteCount, const std::string &channel=NULL_CHANNEL, bool blocking=true) =0;
01238                 virtual unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const =0;
01239                 unsigned int TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=NULL_CHANNEL, bool blocking=true);
01240                 unsigned int TransferAllTo2(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL, bool blocking=true);
01241         //@}
01242 
01243         //!     \name CHANNELS
01244         //@{
01245                 struct NoChannelSupport : public NotImplemented
01246                         {NoChannelSupport() : NotImplemented("BufferedTransformation: this object doesn't support multiple channels") {}};
01247 
01248                 unsigned int ChannelPut(const std::string &channel, byte inByte, bool blocking=true)
01249                         {return ChannelPut(channel, &inByte, 1, blocking);}
01250                 unsigned int ChannelPut(const std::string &channel, const byte *inString, unsigned int length, bool blocking=true)
01251                         {return ChannelPut2(channel, inString, length, 0, blocking);}
01252 
01253                 unsigned int ChannelPutModifiable(const std::string &channel, byte *inString, unsigned int length, bool blocking=true)
01254                         {return ChannelPutModifiable2(channel, inString, length, 0, blocking);}
01255 
01256                 unsigned int ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
01257                 unsigned int ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
01258 
01259                 bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true)
01260                         {return !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
01261                 unsigned int ChannelPutMessageEnd(const std::string &channel, const byte *inString, unsigned int length, int propagation=-1, bool blocking=true)
01262                         {return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
01263 
01264                 virtual byte * ChannelCreatePutSpace(const std::string &channel, unsigned int &size);
01265 
01266                 virtual unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking);
01267                 virtual unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking);
01268 
01269                 virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true);
01270                 virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true);
01271 
01272                 virtual void SetRetrievalChannel(const std::string &channel);
01273         //@}
01274 
01275         //!     \name ATTACHMENT
01276         /*! Some BufferedTransformation objects (e.g. Filter objects)
01277                 allow other BufferedTransformation objects to be attached. When
01278                 this is done, the first object instead of buffering its output,
01279                 sents that output to the attached object as input. The entire
01280                 attachment chain is deleted when the anchor object is destructed.
01281         */
01282         //@{
01283                 //! returns whether this object allows attachment
01284                 virtual bool Attachable() {return false;}
01285                 //! returns the object immediately attached to this object or NULL for no attachment
01286                 virtual BufferedTransformation *AttachedTransformation() {assert(!Attachable()); return 0;}
01287                 //!
01288                 virtual const BufferedTransformation *AttachedTransformation() const
01289                         {return const_cast<BufferedTransformation *>(this)->AttachedTransformation();}
01290                 //! delete the current attachment chain and replace it with newAttachment
01291                 virtual void Detach(BufferedTransformation* /* newAttachment */ = 0)
01292                         {assert(!Attachable()); throw NotImplemented("BufferedTransformation: this object is not attachable");}
01293                 //! add newAttachment to the end of attachment chain
01294                 virtual void Attach(BufferedTransformation *newAttachment);
01295         //@}
01296 
01297 protected:
01298         static int DecrementPropagation(int propagation)
01299                 {return propagation != 0 ? propagation - 1 : 0;}
01300 };
01301 
01302 //! returns a reference to a BufferedTransformation object that discards all input
01303 BufferedTransformation & TheBitBucket();
01304 
01305 //! interface for crypto material, such as public and private keys, and crypto parameters
01306 
01307 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoMaterial : public NameValuePairs
01308 {
01309 public:
01310         //! exception thrown when invalid crypto material is detected
01311         class CRYPTOPP_DLL InvalidMaterial : public InvalidDataFormat
01312         {
01313         public:
01314                 explicit InvalidMaterial(const std::string &s) : InvalidDataFormat(s) {}
01315         };
01316 
01317         //! assign values from source to this object
01318         /*! \note This function can be used to create a public key from a private key. */
01319         virtual void AssignFrom(const NameValuePairs &source) =0;
01320 
01321         //! check this object for errors
01322         /*! \param level denotes the level of thoroughness:
01323                 0 - using this object won't cause a crash or exception (rng is ignored)
01324                 1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such)
01325                 2 - make sure this object will function correctly, and do reasonable security checks
01326                 3 - do checks that may take a long time
01327                 \return true if the tests pass */
01328         virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0;
01329 
01330         //! throws InvalidMaterial if this object fails Validate() test
01331         virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const
01332                 {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");}
01333 
01334 //      virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false);
01335 
01336         //! save key into a BufferedTransformation
01337         virtual void Save(BufferedTransformation& /* bt */) const
01338                 {throw NotImplemented("CryptoMaterial: this object does not support saving");}
01339 
01340         //! load key from a BufferedTransformation
01341         /*! \throws KeyingErr if decode fails
01342                 \note Generally does not check that the key is valid.
01343                         Call ValidateKey() or ThrowIfInvalidKey() to check that. */
01344         virtual void Load(BufferedTransformation& /* bt */)
01345                 {throw NotImplemented("CryptoMaterial: this object does not support loading");}
01346 
01347         //! \return whether this object supports precomputation
01348         virtual bool SupportsPrecomputation() const {return false;}
01349         //! do precomputation
01350         /*! The exact semantics of Precompute() is varies, but
01351                 typically it means calculate a table of n objects
01352                 that can be used later to speed up computation. */
01353         virtual void Precompute(unsigned int /* n */)
01354                 {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
01355         //! retrieve previously saved precomputation
01356         virtual void LoadPrecomputation(BufferedTransformation& /* storedPrecomputation */)
01357                 {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
01358         //! save precomputation for later use
01359         virtual void SavePrecomputation(BufferedTransformation& /* storedPrecomputation */) const
01360                 {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
01361 
01362         // for internal library use
01363         void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);}
01364 };
01365 
01366 //! interface for generatable crypto material, such as private keys and crypto parameters
01367 
01368 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public CryptoMaterial
01369 {
01370 public:
01371         //! generate a random key or crypto parameters
01372         /*! \throws KeyingErr if algorithm parameters are invalid, or if a key can't be generated
01373                 (e.g., if this is a public key object) */
01374         virtual void GenerateRandom(RandomNumberGenerator& /* rng */, const NameValuePairs& /* params */ = g_nullNameValuePairs)
01375                 {throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation");}
01376 
01377         //! calls the above function with a NameValuePairs object that just specifies "KeySize"
01378         void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize);
01379 };
01380 
01381 //! interface for public keys
01382 
01383 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKey : virtual public CryptoMaterial
01384 {
01385 };
01386 
01387 //! interface for private keys
01388 
01389 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKey : public GeneratableCryptoMaterial
01390 {
01391 };
01392 
01393 //! interface for asymmetric algorithms
01394 
01395 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : public Algorithm
01396 {
01397 public:
01398         //! returns a reference to the crypto material used by this object
01399         virtual CryptoMaterial & AccessMaterial() =0;
01400         //! returns a const reference to the crypto material used by this object
01401         virtual const CryptoMaterial & GetMaterial() const =0;
01402 
01403         //! for backwards compatibility, calls AccessMaterial().Load(bt)
01404         void BERDecode(BufferedTransformation &bt)
01405                 {AccessMaterial().Load(bt);}
01406         //! for backwards compatibility, calls GetMaterial().Save(bt)
01407         void DEREncode(BufferedTransformation &bt) const
01408                 {GetMaterial().Save(bt);}
01409 };
01410 
01411 //! interface for asymmetric algorithms using public keys
01412 
01413 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : public AsymmetricAlgorithm
01414 {
01415 public:
01416         // VC60 workaround: no co-variant return type
01417         CryptoMaterial & AccessMaterial() {return AccessPublicKey();}
01418         const CryptoMaterial & GetMaterial() const {return GetPublicKey();}
01419 
01420         virtual PublicKey & AccessPublicKey() =0;
01421         virtual const PublicKey & GetPublicKey() const {return const_cast<PublicKeyAlgorithm *>(this)->AccessPublicKey();}
01422 };
01423 
01424 //! interface for asymmetric algorithms using private keys
01425 
01426 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : public AsymmetricAlgorithm
01427 {
01428 public:
01429         CryptoMaterial & AccessMaterial() {return AccessPrivateKey();}
01430         const CryptoMaterial & GetMaterial() const {return GetPrivateKey();}
01431 
01432         virtual PrivateKey & AccessPrivateKey() =0;
01433         virtual const PrivateKey & GetPrivateKey() const {return const_cast<PrivateKeyAlgorithm *>(this)->AccessPrivateKey();}
01434 };
01435 
01436 /*! This class provides an interface common to encryptors and decryptors
01437         for querying their plaintext and ciphertext lengths.
01438 */
01439 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_CryptoSystem
01440 {
01441 public:
01442         virtual ~PK_CryptoSystem() {}
01443 
01444         //! maximum length of plaintext for a given ciphertext length
01445         /*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */
01446         virtual unsigned int MaxPlaintextLength(unsigned int ciphertextLength) const =0;
01447 
01448         //! calculate length of ciphertext given length of plaintext
01449         /*! \note This function returns 0 if plaintextLength is not valid (too long). */
01450         virtual unsigned int CiphertextLength(unsigned int plaintextLength) const =0;
01451 
01452         //! this object supports the use of the parameter with the given name
01453         /*! some possible parameter names: EncodingParameters, KeyDerivationParameters */
01454         virtual bool ParameterSupported(const char *name) const =0;
01455 
01456         //! return fixed ciphertext length, if one exists, otherwise return 0
01457         /*! \note "Fixed" here means length of ciphertext does not depend on length of plaintext.
01458                 It usually does depend on the key length. */
01459         virtual unsigned int FixedCiphertextLength() const {return 0;}
01460 
01461         //! return maximum plaintext length given the fixed ciphertext length, if one exists, otherwise return 0
01462         virtual unsigned int FixedMaxPlaintextLength() const {return 0;}
01463 
01464 };
01465 
01466 //! interface for public-key encryptors
01467 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : virtual public PK_CryptoSystem, public PublicKeyAlgorithm
01468 {
01469 public:
01470         //! exception thrown when trying to encrypt plaintext of invalid length
01471         class CRYPTOPP_DLL InvalidPlaintextLength : public Exception
01472         {
01473         public:
01474                 InvalidPlaintextLength() : Exception(OTHER_ERROR, "PK_Encryptor: invalid plaintext length") {}
01475         };
01476 
01477         //! encrypt a byte string
01478         /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long)
01479                 \pre size of ciphertext == CiphertextLength(plaintextLength)
01480         */
01481         virtual void Encrypt(RandomNumberGenerator &rng,
01482                 const byte *plaintext, unsigned int plaintextLength,
01483                 byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const =0;
01484 
01485         //! create a new encryption filter
01486         /*! \note The caller is responsible for deleting the returned pointer.
01487                 \note Encoding parameters should be passed in the "EP" channel.
01488         */
01489         virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng,
01490                 BufferedTransformation *attachment=NULL, const NameValuePairs &parameters = g_nullNameValuePairs) const;
01491 };
01492 
01493 //! interface for public-key signers and verifiers
01494 
01495 /*! This class provides an interface common to signers and verifiers
01496         for querying scheme properties.
01497 */
01498 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme
01499 {
01500 public:
01501         //! invalid key exception, may be thrown by any function in this class if the private or public key has a length that can't be used
01502         class CRYPTOPP_DLL InvalidKeyLength : public Exception
01503         {
01504         public:
01505                 InvalidKeyLength(const std::string &message) : Exception(OTHER_ERROR, message) {}
01506         };
01507 
01508         //! key too short exception, may be thrown by any function in this class if the private or public key is too short to sign or verify anything
01509         class CRYPTOPP_DLL KeyTooShort : public InvalidKeyLength
01510         {
01511         public:
01512                 KeyTooShort() : InvalidKeyLength("PK_Signer: key too short for this signature scheme") {}
01513         };
01514 
01515         virtual ~PK_SignatureScheme() {}
01516 
01517         //! signature length if it only depends on the key, otherwise 0
01518         virtual unsigned int SignatureLength() const =0;
01519 
01520         //! maximum signature length produced for a given length of recoverable message part
01521         virtual unsigned int MaxSignatureLength(unsigned int /* recoverablePartLength */ = 0) const {return SignatureLength();}
01522 
01523         //! length of longest message that can be recovered, or 0 if this signature scheme does not support message recovery
01524         virtual unsigned int MaxRecoverableLength() const =0;
01525 
01526         //! length of longest message that can be recovered from a signature of given length, or 0 if this signature scheme does not support message recovery
01527         virtual unsigned int MaxRecoverableLengthFromSignatureLength(unsigned int signatureLength) const =0;
01528 
01529         //! requires a random number generator to sign
01530         /*! if this returns false, NullRNG() can be passed to functions that take RandomNumberGenerator & */
01531         virtual bool IsProbabilistic() const =0;
01532 
01533         //! whether or not a non-recoverable message part can be signed
01534         virtual bool AllowNonrecoverablePart() const =0;
01535 
01536         //! if this function returns true, during verification you must input the signature before the message, otherwise you can input it at anytime */
01537         virtual bool SignatureUpfront() const {return false;}
01538 
01539         //! whether you must input the recoverable part before the non-recoverable part during signing
01540         virtual bool RecoverablePartFirst() const =0;
01541 };
01542 
01543 //! interface for accumulating messages to be signed or verified
01544 /*! Only Update() should be called
01545         on this class. No other functions inherited from HashTransformation should be called.
01546 */
01547 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulator : public HashTransformation
01548 {
01549 public:
01550         //! should not be called on PK_MessageAccumulator
01551         unsigned int DigestSize() const
01552                 {throw NotImplemented("PK_MessageAccumulator: DigestSize() should not be called");}
01553         //! should not be called on PK_MessageAccumulator
01554         void TruncatedFinal(byte* /* digest */, unsigned int /* digestSize */)
01555                 {throw NotImplemented("PK_MessageAccumulator: TruncatedFinal() should not be called");}
01556 };
01557 
01558 //! interface for public-key signers
01559 
01560 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Signer : public PK_SignatureScheme, public PrivateKeyAlgorithm
01561 {
01562 public:
01563         //! create a new HashTransformation to accumulate the message to be signed
01564         virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0;
01565 
01566         virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const =0;
01567 
01568         //! sign and delete messageAccumulator (even in case of exception thrown)
01569         /*! \pre size of signature == MaxSignatureLength()
01570                 \return actual signature length
01571         */
01572         virtual unsigned int Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const;
01573 
01574         //! sign and restart messageAccumulator
01575         /*! \pre size of signature == MaxSignatureLength()
01576                 \return actual signature length
01577         */
01578         virtual unsigned int SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0;
01579 
01580         //! sign a message
01581         /*! \pre size of signature == MaxSignatureLength()
01582                 \return actual signature length
01583         */
01584         virtual unsigned int SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const;
01585 
01586         //! sign a recoverable message
01587         /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength)
01588                 \return actual signature length
01589         */
01590         virtual unsigned int SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, unsigned int recoverableMessageLength,
01591                 const byte *nonrecoverableMessage, unsigned int nonrecoverableMessageLength, byte *signature) const;
01592 };
01593 
01594 //! interface for public-key signature verifiers
01595 /*! The Recover* functions throw NotImplemented if the signature scheme does not support
01596         message recovery.
01597         The Verify* functions throw InvalidDataFormat if the scheme does support message
01598         recovery and the signature contains a non-empty recoverable message part. The
01599         Recovery* functions should be used in that case.
01600 */
01601 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Verifier : public PK_SignatureScheme, public PublicKeyAlgorithm
01602 {
01603 public:
01604         //! create a new HashTransformation to accumulate the message to be verified
01605         virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0;
01606 
01607         //! input signature into a message accumulator
01608         virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const =0;
01609 
01610         //! check whether messageAccumulator contains a valid signature and message, and delete messageAccumulator (even in case of exception thrown)
01611         virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const;
01612 
01613         //! check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator
01614         virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0;
01615 
01616         //! check whether input signature is a valid signature for input message
01617         virtual bool VerifyMessage(const byte *message, unsigned int messageLen,
01618                 const byte *signature, unsigned int signatureLength) const;
01619 
01620         //! recover a message from its signature
01621         /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
01622         */
01623         virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const;
01624 
01625         //! recover a message from its signature
01626         /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
01627         */
01628         virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0;
01629 
01630         //! recover a message from its signature
01631         /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
01632         */
01633         virtual DecodingResult RecoverMessage(byte *recoveredMessage,
01634                 const byte *nonrecoverableMessage, unsigned int nonrecoverableMessageLength,
01635                 const byte *signature, unsigned int signatureLength) const;
01636 };
01637 
01638 //! interface for domains of authenticated key agreement protocols
01639 
01640 //! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation
01641 class CRYPTOPP_DLL BERDecodeErr : public InvalidArgument
01642 {
01643 public:
01644         BERDecodeErr() : InvalidArgument("BER decode error") {}
01645         BERDecodeErr(const std::string &s) : InvalidArgument(s) {}
01646 };
01647 
01648 //! interface for encoding and decoding ASN1 objects
01649 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object
01650 {
01651 public:
01652         virtual ~ASN1Object() {}
01653         //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules)
01654         virtual void BERDecode(BufferedTransformation &bt) =0;
01655         //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules)
01656         virtual void DEREncode(BufferedTransformation &bt) const =0;
01657         //! encode this object into a BufferedTransformation, using BER
01658         /*! this may be useful if DEREncode() would be too inefficient */
01659         virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);}
01660 };
01661 
01662 NAMESPACE_END
01663 
01664 #endif
01665 ////////////////////////////////////////////////////////////////////////////////
01666 
01667 
01668 ////////////////////////////////////////////////////////////////////////////////
01669 #ifndef CRYPTOPP_SMARTPTR_H
01670 #define CRYPTOPP_SMARTPTR_H
01671 
01672 //- #include "config.h"
01673 #include <algorithm>
01674 
01675 NAMESPACE_BEGIN(CryptoPP)
01676 
01677 template <class T> class simple_ptr
01678 {
01679 public:
01680         simple_ptr() : m_p(NULL) {}
01681         ~simple_ptr() {delete m_p;}
01682         T *m_p;
01683 };
01684 
01685 template <class T> class member_ptr
01686 {
01687 public:
01688         explicit member_ptr(T *p = NULL) : m_p(p) {}
01689 
01690         ~member_ptr();
01691 
01692         const T& operator*() const { return *m_p; }
01693         T& operator*() { return *m_p; }
01694 
01695         const T* operator->() const { return m_p; }
01696         T* operator->() { return m_p; }
01697 
01698         const T* get() const { return m_p; }
01699         T* get() { return m_p; }
01700 
01701         T* release()
01702         {
01703                 T *old_p = m_p;
01704                 m_p = 0;
01705                 return old_p;
01706         }
01707 
01708         void reset(T *p = 0);
01709 
01710 protected:
01711         member_ptr(const member_ptr<T>& rhs);           // copy not allowed
01712         void operator=(const member_ptr<T>& rhs);       // assignment not allowed
01713 
01714         T *m_p;
01715 };
01716 
01717 template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
01718 template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
01719 
01720 NAMESPACE_END
01721 
01722 #endif
01723 ////////////////////////////////////////////////////////////////////////////////
01724 
01725 
01726 ////////////////////////////////////////////////////////////////////////////////
01727 #ifndef CRYPTOPP_MISC_H
01728 #define CRYPTOPP_MISC_H
01729 
01730 //- #include "cryptlib.h"
01731 //- #include "smartptr.h"
01732 
01733 #ifdef INTEL_INTRINSICS
01734 #include <stdlib.h>
01735 #endif
01736 
01737 NAMESPACE_BEGIN(CryptoPP)
01738 
01739 // ************** compile-time assertion ***************
01740 
01741 template<int>
01742 struct CompileTimeAssert;
01743 
01744 template<>
01745 struct CompileTimeAssert<true> {};
01746 
01747 
01748 #define CRYPTOPP_COMPILE_ASSERT( x ) \
01749     { CompileTimeAssert<((x) != 0)> ERROR; (void)ERROR; }
01750 
01751 #define CRYPTOPP_COMPILE_ASSERT_GLOBAL(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
01752 #if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
01753 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
01754 #else
01755 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
01756         CompileTimeAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
01757 #endif
01758 #define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
01759 #define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
01760 
01761 // ************** misc classes ***************
01762 
01763 class CRYPTOPP_DLL Empty
01764 {
01765 };
01766 
01767 //! _
01768 template <class BASE1, class BASE2>
01769 class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2
01770 {
01771 };
01772 
01773 template <class T>
01774 class ObjectHolder
01775 {
01776 protected:
01777         T m_object;
01778 };
01779 
01780 class NotCopyable
01781 {
01782 public:
01783         NotCopyable() {}
01784 private:
01785     NotCopyable(const NotCopyable &);
01786     void operator=(const NotCopyable &);
01787 };
01788 
01789 template <class T>
01790 struct NewObject
01791 {
01792         T* operator()() const {return new T;}
01793 };
01794 
01795 /*! This function safely initializes a static object in a multithreaded environment without using locks.
01796         It may leak memory when two threads try to initialize the static object at the same time
01797         but this should be acceptable since each static object is only initialized once per session.
01798 */
01799 template <class T, class F = NewObject<T>, int instance=0>
01800 class Singleton
01801 {
01802 public:
01803         Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {}
01804 
01805         // VC60 workaround: use "..." to prevent this function from being inlined
01806         const T & Ref(...) const;
01807 
01808 private:
01809         F m_objectFactory;
01810 };
01811 
01812 template <class T, class F, int instance>
01813 const T & Singleton<T, F, instance>::Ref(...) const
01814 {
01815         static simple_ptr<T> s_pObject;
01816         static char s_objectState = 0;
01817 
01818 retry:
01819         switch (s_objectState)
01820         {
01821         case 0:
01822                 s_objectState = 1;
01823                 try
01824                 {
01825                         s_pObject.m_p = m_objectFactory();
01826                 }
01827                 catch(...)
01828                 {
01829                         s_objectState = 0;
01830                         throw;
01831                 }
01832                 s_objectState = 2;
01833                 break;
01834         case 1:
01835                 goto retry;
01836         default:
01837                 break;
01838         }
01839         return *s_pObject.m_p;
01840 }
01841 
01842 // ************** misc functions ***************
01843 
01844 // can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
01845 template <class T> inline const T& STDMIN(const T& a, const T& b)
01846 {
01847         return b < a ? b : a;
01848 }
01849 
01850 template <class T> inline const T& STDMAX(const T& a, const T& b)
01851 {
01852         return a < b ? b : a;
01853 }
01854 
01855 #define RETURN_IF_NONZERO(x) unsigned int returnedValue = x; if (returnedValue) return returnedValue
01856 
01857 // this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
01858 #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
01859 // these may be faster on other CPUs/compilers
01860 // #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
01861 // #define GETBYTE(x, y) (((byte *)&(x))[y])
01862 
01863 CRYPTOPP_DLL unsigned int Parity(unsigned long);
01864 CRYPTOPP_DLL unsigned int BytePrecision(unsigned long);
01865 CRYPTOPP_DLL unsigned int BitPrecision(unsigned long);
01866 CRYPTOPP_DLL unsigned long Crop(unsigned long, unsigned int size);
01867 
01868 inline unsigned int BitsToBytes(unsigned int bitCount)
01869 {
01870         return ((bitCount+7)/(8));
01871 }
01872 
01873 inline unsigned int BytesToWords(unsigned int byteCount)
01874 {
01875         return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
01876 }
01877 
01878 inline unsigned int BitsToWords(unsigned int bitCount)
01879 {
01880         return ((bitCount+WORD_BITS-1)/(WORD_BITS));
01881 }
01882 
01883 inline unsigned int BitsToDwords(unsigned int bitCount)
01884 {
01885         return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
01886 }
01887 
01888 CRYPTOPP_DLL void xorbuf(byte *buf, const byte *mask, unsigned int count);
01889 CRYPTOPP_DLL void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count);
01890 
01891 template <class T>
01892 inline bool IsPowerOf2(T n)
01893 {
01894         return n > 0 && (n & (n-1)) == 0;
01895 }
01896 
01897 template <class T1, class T2>
01898 inline T2 ModPowerOf2(T1 a, T2 b)
01899 {
01900         assert(IsPowerOf2(b));
01901         return T2(a) & (b-1);
01902 }
01903 
01904 template <class T>
01905 inline T RoundDownToMultipleOf(T n, T m)
01906 {
01907         return n - (IsPowerOf2(m) ? ModPowerOf2(n, m) : (n%m));
01908 }
01909 
01910 template <class T>
01911 inline T RoundUpToMultipleOf(T n, T m)
01912 {
01913         return RoundDownToMultipleOf(n+m-1, m);
01914 }
01915 
01916 template <class T>
01917 inline unsigned int GetAlignment(T* /* dummy */ = NULL) // VC60 workaround
01918 {
01919 #if (_MSC_VER >= 1300)
01920         return __alignof(T);
01921 #elif defined(__GNUC__)
01922         return __alignof__(T);
01923 #else
01924         return sizeof(T);
01925 #endif
01926 }
01927 
01928 inline bool IsAlignedOn(const void *p, unsigned int alignment)
01929 {
01930         return IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0;
01931 }
01932 
01933 template <class T>
01934 inline bool IsAligned(const void *p, T* /* dummy */ = NULL)     // VC60 workaround
01935 {
01936         return IsAlignedOn(p, GetAlignment<T>());
01937 }
01938 
01939 #ifdef IS_LITTLE_ENDIAN
01940         typedef LittleEndian NativeByteOrder;
01941 #else
01942         typedef BigEndian NativeByteOrder;
01943 #endif
01944 
01945 inline ByteOrder GetNativeByteOrder()
01946 {
01947         return NativeByteOrder::ToEnum();
01948 }
01949 
01950 inline bool NativeByteOrderIs(ByteOrder order)
01951 {
01952         return order == GetNativeByteOrder();
01953 }
01954 
01955 template <class T>              // can't use <sstream> because GCC 2.95.2 doesn't have it
01956 inline std::string IntToString(T a, unsigned int base = 10)
01957 {
01958         if (a == 0)
01959                 return "0";
01960         bool negate = false;
01961         if (a < 0)
01962         {
01963                 negate = true;
01964                 a = 0-a;        // VC .NET does not like -a
01965         }
01966         std::string result;
01967         while (a > 0)
01968         {
01969                 T digit = a % base;
01970                 result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
01971                 a /= base;
01972         }
01973         if (negate)
01974                 result = "-" + result;
01975         return result;
01976 }
01977 
01978 // Avoid warnings about compare against zero for unsigned
01979 template <>        // can't use <sstream> because GCC 2.95.2 doesn't have it
01980 inline std::string IntToString<unsigned int>(unsigned int a, unsigned int base)
01981 {
01982         if (a == 0)
01983                 return "0";
01984         std::string result;
01985         while (a > 0)
01986         {
01987                 unsigned digit = a % base;
01988                 result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
01989                 a /= base;
01990         }
01991         return result;
01992 }
01993 
01994 template <class T1, class T2>
01995 inline T1 SaturatingSubtract(T1 a, T2 b)
01996 {
01997 /*      CRYPTOPP_COMPILE_ASSERT(T1(-1)>0);      // T1 is unsigned type
01998         CRYPTOPP_COMPILE_ASSERT(T2(-1)>0);      // T2 is unsigned type
01999 */
02000         return T1((a > b) ? (a - b) : 0);
02001 }
02002 
02003 template <class T>
02004 inline CipherDir GetCipherDir(const T &obj)
02005 {
02006         return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
02007 }
02008 
02009 void CallNewHandler();
02010 
02011 // ************** rotate functions ***************
02012 
02013 template <class T> inline T rotlFixed(T x, unsigned int y)
02014 {
02015         assert(y < sizeof(T)*8);
02016         return (x<<y) | (x>>(sizeof(T)*8-y));
02017 }
02018 
02019 template <class T> inline T rotrFixed(T x, unsigned int y)
02020 {
02021         assert(y < sizeof(T)*8);
02022         return (x>>y) | (x<<(sizeof(T)*8-y));
02023 }
02024 
02025 template <class T> inline T rotlVariable(T x, unsigned int y)
02026 {
02027         assert(y < sizeof(T)*8);
02028         return (x<<y) | (x>>(sizeof(T)*8-y));
02029 }
02030 
02031 template <class T> inline T rotrVariable(T x, unsigned int y)
02032 {
02033         assert(y < sizeof(T)*8);
02034         return (x>>y) | (x<<(sizeof(T)*8-y));
02035 }
02036 
02037 template <class T> inline T rotlMod(T x, unsigned int y)
02038 {
02039         y %= sizeof(T)*8;
02040         return (x<<y) | (x>>(sizeof(T)*8-y));
02041 }
02042 
02043 template <class T> inline T rotrMod(T x, unsigned int y)
02044 {
02045         y %= sizeof(T)*8;
02046         return (x>>y) | (x<<(sizeof(T)*8-y));
02047 }
02048 
02049 #ifdef INTEL_INTRINSICS
02050 
02051 #pragma intrinsic(_lrotl, _lrotr)
02052 
02053 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
02054 {
02055         assert(y < 32);
02056         return y ? _lrotl(x, y) : x;
02057 }
02058 
02059 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
02060 {
02061         assert(y < 32);
02062         return y ? _lrotr(x, y) : x;
02063 }
02064 
02065 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
02066 {
02067         assert(y < 32);
02068         return _lrotl(x, y);
02069 }
02070 
02071 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
02072 {
02073         assert(y < 32);
02074         return _lrotr(x, y);
02075 }
02076 
02077 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
02078 {
02079         return _lrotl(x, y);
02080 }
02081 
02082 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
02083 {
02084         return _lrotr(x, y);
02085 }
02086 
02087 #endif // #ifdef INTEL_INTRINSICS
02088 
02089 #ifdef PPC_INTRINSICS
02090 
02091 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
02092 {
02093         assert(y < 32);
02094         return y ? __rlwinm(x,y,0,31) : x;
02095 }
02096 
02097 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
02098 {
02099         assert(y < 32);
02100         return y ? __rlwinm(x,32-y,0,31) : x;
02101 }
02102 
02103 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
02104 {
02105         assert(y < 32);
02106         return (__rlwnm(x,y,0,31));
02107 }
02108 
02109 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
02110 {
02111         assert(y < 32);
02112         return (__rlwnm(x,32-y,0,31));
02113 }
02114 
02115 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
02116 {
02117         return (__rlwnm(x,y,0,31));
02118 }
02119 
02120 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
02121 {
02122         return (__rlwnm(x,32-y,0,31));
02123 }
02124 
02125 #endif // #ifdef PPC_INTRINSICS
02126 
02127 // ************** endian reversal ***************
02128 
02129 template <class T>
02130 inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
02131 {
02132         if (order == LITTLE_ENDIAN_ORDER)
02133                 return GETBYTE(value, index);
02134         else
02135                 return GETBYTE(value, sizeof(T)-index-1);
02136 }
02137 
02138 inline byte ByteReverse(byte value)
02139 {
02140         return value;
02141 }
02142 
02143 inline word16 ByteReverse(word16 value)
02144 {
02145         return rotlFixed(value, 8U);
02146 }
02147 
02148 inline word32 ByteReverse(word32 value)
02149 {
02150 #ifdef PPC_INTRINSICS
02151         // PPC: load reverse indexed instruction
02152         return (word32)__lwbrx(&value,0);
02153 #elif defined(FAST_ROTATE)
02154         // 5 instructions with rotate instruction, 9 without
02155         return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
02156 #else
02157         // 6 instructions with rotate instruction, 8 without
02158         value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
02159         return rotlFixed(value, 16U);
02160 #endif
02161 }
02162 
02163 #ifdef WORD64_AVAILABLE
02164 inline word64 ByteReverse(word64 value)
02165 {
02166 #ifdef CRYPTOPP_SLOW_WORD64
02167         return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
02168 #else
02169         value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
02170         value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
02171         return rotlFixed(value, 32U);
02172 #endif
02173 }
02174 #endif
02175 
02176 inline byte BitReverse(byte value)
02177 {
02178         value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
02179         value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
02180         return rotlFixed(value, 4);
02181 }
02182 
02183 inline word16 BitReverse(word16 value)
02184 {
02185         value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
02186         value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
02187         value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
02188         return ByteReverse(value);
02189 }
02190 
02191 inline word32 BitReverse(word32 value)
02192 {
02193         value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
02194         value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
02195         value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
02196         return ByteReverse(value);
02197 }
02198 
02199 #ifdef WORD64_AVAILABLE
02200 inline word64 BitReverse(word64 value)
02201 {
02202 #ifdef CRYPTOPP_SLOW_WORD64
02203         return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
02204 #else
02205         value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
02206         value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
02207         value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
02208         return ByteReverse(value);
02209 #endif
02210 }
02211 #endif
02212 
02213 template <class T>
02214 inline T BitReverse(T value)
02215 {
02216         if (sizeof(T) == 1)
02217                 return (T)BitReverse((byte)value);
02218         else if (sizeof(T) == 2)
02219                 return (T)BitReverse((word16)value);
02220         else if (sizeof(T) == 4)
02221                 return (T)BitReverse((word32)value);
02222         else
02223         {
02224 #ifdef WORD64_AVAILABLE
02225                 assert(sizeof(T) == 8);
02226                 return (T)BitReverse((word64)value);
02227 #else
02228                 assert(false);
02229                 return 0;
02230 #endif
02231         }
02232 }
02233 
02234 template <class T>
02235 inline T ConditionalByteReverse(ByteOrder order, T value)
02236 {
02237         return NativeByteOrderIs(order) ? value : ByteReverse(value);
02238 }
02239 
02240 template <class T>
02241 void ByteReverse(T *out, const T *in, unsigned int byteCount)
02242 {
02243         assert(byteCount % sizeof(T) == 0);
02244         unsigned int count = byteCount/sizeof(T);
02245         for (unsigned int i=0; i<count; i++)
02246                 out[i] = ByteReverse(in[i]);
02247 }
02248 
02249 template <class T>
02250 inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, unsigned int byteCount)
02251 {
02252         if (!NativeByteOrderIs(order))
02253                 ByteReverse(out, in, byteCount);
02254         else if (in != out)
02255                 memcpy(out, in, byteCount);
02256 }
02257 
02258 template <class T>
02259 inline void GetUserKey(ByteOrder order, T *out, unsigned int outlen, const byte *in, unsigned int inlen)
02260 {
02261         const unsigned int U = sizeof(T);
02262         assert(inlen <= outlen*U);
02263         memcpy(out, in, inlen);
02264         memset((byte *)out+inlen, 0, outlen*U-inlen);
02265         ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
02266 }
02267 
02268 inline byte UnalignedGetWordNonTemplate(ByteOrder /*order*/, const byte *block, byte*)
02269 {
02270         return block[0];
02271 }
02272 
02273 inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word16*)
02274 {
02275         return (order == BIG_ENDIAN_ORDER)
02276                 ? block[1] | (block[0] << 8)
02277                 : block[0] | (block[1] << 8);
02278 }
02279 
02280 inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word32*)
02281 {
02282         return (order == BIG_ENDIAN_ORDER)
02283                 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
02284                 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
02285 }
02286 
02287 #ifdef WORD64_AVAILABLE
02288 inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word64*)
02289 {
02290         return (order == BIG_ENDIAN_ORDER)
02291                 ?
02292                 (word64(block[7]) |
02293                 (word64(block[6]) <<  8) |
02294                 (word64(block[5]) << 16) |
02295                 (word64(block[4]) << 24) |
02296                 (word64(block[3]) << 32) |
02297                 (word64(block[2]) << 40) |
02298                 (word64(block[1]) << 48) |
02299                 (word64(block[0]) << 56))
02300                 :
02301                 (word64(block[0]) |
02302                 (word64(block[1]) <<  8) |
02303                 (word64(block[2]) << 16) |
02304                 (word64(block[3]) << 24) |
02305                 (word64(block[4]) << 32) |
02306                 (word64(block[5]) << 40) |
02307                 (word64(block[6]) << 48) |
02308                 (word64(block[7]) << 56));
02309 }
02310 #endif
02311 
02312 template <class T>
02313 inline T UnalignedGetWord(ByteOrder order, const byte *block, T*dummy=NULL)
02314 {
02315         return UnalignedGetWordNonTemplate(order, block, dummy);
02316 }
02317 
02318 inline void UnalignedPutWord(ByteOrder /*order*/, byte *block, byte value, const byte *xorBlock = NULL)
02319 {
02320         block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
02321 }
02322 
02323 inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value, const byte *xorBlock = NULL)
02324 {
02325         if (order == BIG_ENDIAN_ORDER)
02326         {
02327                 block[0] = GETBYTE(value, 1);
02328                 block[1] = GETBYTE(value, 0);
02329         }
02330         else
02331         {
02332                 block[0] = GETBYTE(value, 0);
02333                 block[1] = GETBYTE(value, 1);
02334         }
02335 
02336         if (xorBlock)
02337         {
02338                 block[0] ^= xorBlock[0];
02339                 block[1] ^= xorBlock[1];
02340         }
02341 }
02342 
02343 inline void UnalignedPutWord(ByteOrder order, byte *block, word32 value, const byte *xorBlock = NULL)
02344 {
02345         if (order == BIG_ENDIAN_ORDER)
02346         {
02347                 block[0] = GETBYTE(value, 3);
02348                 block[1] = GETBYTE(value, 2);
02349                 block[2] = GETBYTE(value, 1);
02350                 block[3] = GETBYTE(value, 0);
02351         }
02352         else
02353         {
02354                 block[0] = GETBYTE(value, 0);
02355                 block[1] = GETBYTE(value, 1);
02356                 block[2] = GETBYTE(value, 2);
02357                 block[3] = GETBYTE(value, 3);
02358         }
02359 
02360         if (xorBlock)
02361         {
02362                 block[0] ^= xorBlock[0];
02363                 block[1] ^= xorBlock[1];
02364                 block[2] ^= xorBlock[2];
02365                 block[3] ^= xorBlock[3];
02366         }
02367 }
02368 
02369 #ifdef WORD64_AVAILABLE
02370 inline void UnalignedPutWord(ByteOrder order, byte *block, word64 value, const byte *xorBlock = NULL)
02371 {
02372         if (order == BIG_ENDIAN_ORDER)
02373         {
02374                 block[0] = GETBYTE(value, 7);
02375                 block[1] = GETBYTE(value, 6);
02376                 block[2] = GETBYTE(value, 5);
02377                 block[3] = GETBYTE(value, 4);
02378                 block[4] = GETBYTE(value, 3);
02379                 block[5] = GETBYTE(value, 2);
02380                 block[6] = GETBYTE(value, 1);
02381                 block[7] = GETBYTE(value, 0);
02382         }
02383         else
02384         {
02385                 block[0] = GETBYTE(value, 0);
02386                 block[1] = GETBYTE(value, 1);
02387                 block[2] = GETBYTE(value, 2);
02388                 block[3] = GETBYTE(value, 3);
02389                 block[4] = GETBYTE(value, 4);
02390                 block[5] = GETBYTE(value, 5);
02391                 block[6] = GETBYTE(value, 6);
02392                 block[7] = GETBYTE(value, 7);
02393         }
02394 
02395         if (xorBlock)
02396         {
02397                 block[0] ^= xorBlock[0];
02398                 block[1] ^= xorBlock[1];
02399                 block[2] ^= xorBlock[2];
02400                 block[3] ^= xorBlock[3];
02401                 block[4] ^= xorBlock[4];
02402                 block[5] ^= xorBlock[5];
02403                 block[6] ^= xorBlock[6];
02404                 block[7] ^= xorBlock[7];
02405         }
02406 }
02407 #endif
02408 
02409 template <class T>
02410 inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
02411 {
02412         if (assumeAligned)
02413         {
02414                 assert(IsAligned<T>(block));
02415                 return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
02416         }
02417         else
02418                 return UnalignedGetWord<T>(order, block);
02419 }
02420 
02421 template <class T>
02422 inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
02423 {
02424         result = GetWord<T>(assumeAligned, order, block);
02425 }
02426 
02427 template <class T>
02428 inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
02429 {
02430         if (assumeAligned)
02431         {
02432                 assert(IsAligned<T>(block));
02433                 if (xorBlock)
02434                         *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ *reinterpret_cast<const T *>(xorBlock);
02435                 else
02436                         *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value);
02437         }
02438         else
02439                 UnalignedPutWord(order, block, value, xorBlock);
02440 }
02441 
02442 template <class T, class B, bool A=true>
02443 class GetBlock
02444 {
02445 public:
02446         GetBlock(const void *block)
02447                 : m_block((const byte *)block) {}
02448 
02449         template <class U>
02450         inline GetBlock<T, B, A> & operator()(U &x)
02451         {
02452 //              CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
02453                 x = GetWord<T>(A, B::ToEnum(), m_block);
02454                 m_block += sizeof(T);
02455                 return *this;
02456         }
02457 
02458 private:
02459         const byte *m_block;
02460 };
02461 
02462 // ************** help remove warning on g++ ***************
02463 
02464 template <bool overflow> struct SafeShifter;
02465 
02466 template<> struct SafeShifter<true>
02467 {
02468         template <class T>
02469         static inline T RightShift(T /* value */, unsigned int /* bits */)
02470         {
02471                 return 0;
02472         }
02473 
02474         template <class T>
02475         static inline T LeftShift(T /* value */, unsigned int /* bits */)
02476         {
02477                 return 0;
02478         }
02479 };
02480 
02481 template<> struct SafeShifter<false>
02482 {
02483         template <class T>
02484         static inline T RightShift(T value, unsigned int bits)
02485         {
02486                 return value >> bits;
02487         }
02488 
02489         template <class T>
02490         static inline T LeftShift(T value, unsigned int bits)
02491         {
02492                 return value << bits;
02493         }
02494 };
02495 
02496 template <unsigned int bits, class T>
02497 inline T SafeRightShift(T value)
02498 {
02499         return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
02500 }
02501 
02502 template <unsigned int bits, class T>
02503 inline T SafeLeftShift(T value)
02504 {
02505         return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
02506 }
02507 
02508 NAMESPACE_END
02509 
02510 #endif // MISC_H
02511 ////////////////////////////////////////////////////////////////////////////////
02512 
02513 
02514 
02515 ////////////////////////////////////////////////////////////////////////////////
02516 // secblock.h - written and placed in the public domain by Wei Dai
02517 
02518 #ifndef CRYPTOPP_SECBLOCK_H
02519 #define CRYPTOPP_SECBLOCK_H
02520 
02521 //- #include "config.h"
02522 //- #include "misc.h"
02523 #include <string.h>             // CodeWarrior doesn't have memory.h
02524 #include <assert.h>
02525 
02526 NAMESPACE_BEGIN(CryptoPP)
02527 
02528 // ************** secure memory allocation ***************
02529 
02530 template<class T>
02531 class AllocatorBase
02532 {
02533 public:
02534         typedef T value_type;
02535         typedef size_t size_type;
02536 #ifdef CRYPTOPP_MSVCRT6
02537         typedef ptrdiff_t difference_type;
02538 #else
02539         typedef std::ptrdiff_t difference_type;
02540 #endif
02541         typedef T * pointer;
02542         typedef const T * const_pointer;
02543         typedef T & reference;
02544         typedef const T & const_reference;
02545 
02546         pointer address(reference r) const {return (&r);}
02547         const_pointer address(const_reference r) const {return (&r); }
02548         void construct(pointer p, const T& val) {new (p) T(val);}
02549         void destroy(pointer p) {p->~T();}
02550         size_type max_size() const {return ~size_type(0)/sizeof(T);}    // switch to std::numeric_limits<T>::max later
02551 
02552 protected:
02553         static void CheckSize(size_t n)
02554         {
02555                 if (n > ~size_t(0) / sizeof(T))
02556                         throw InvalidArgument("AllocatorBase: requested size would cause integer overflow");
02557         }
02558 };
02559 
02560 #define CRYPTOPP_INHERIT_ALLOCATOR_TYPES        \
02561 typedef typename AllocatorBase<T>::value_type value_type;\
02562 typedef typename AllocatorBase<T>::size_type size_type;\
02563 typedef typename AllocatorBase<T>::difference_type difference_type;\
02564 typedef typename AllocatorBase<T>::pointer pointer;\
02565 typedef typename AllocatorBase<T>::const_pointer const_pointer;\
02566 typedef typename AllocatorBase<T>::reference reference;\
02567 typedef typename AllocatorBase<T>::const_reference const_reference;
02568 
02569 template <class T, class A>
02570 typename A::pointer StandardReallocate(A& a, T *p, typename A::size_type oldSize, typename A::size_type newSize, bool preserve)
02571 {
02572         if (oldSize == newSize)
02573                 return p;
02574 
02575         if (preserve)
02576         {
02577                 A b;
02578                 typename A::pointer newPointer = b.allocate(newSize, NULL);
02579                 memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize));
02580                 a.deallocate(p, oldSize);
02581                 std::swap(a, b);
02582                 return newPointer;
02583         }
02584         else
02585         {
02586                 a.deallocate(p, oldSize);
02587                 return a.allocate(newSize, NULL);
02588         }
02589 }
02590 
02591 template <class T>
02592 class AllocatorWithCleanup : public AllocatorBase<T>
02593 {
02594 public:
02595         CRYPTOPP_INHERIT_ALLOCATOR_TYPES
02596 
02597         pointer allocate(size_type n, const void * = NULL)
02598         {
02599                 CheckSize(n);
02600                 if (n == 0)
02601                         return NULL;
02602                 return new T[n];
02603         }
02604 
02605         void deallocate(void *p, size_type n)
02606         {
02607                 memset(p, 0, n*sizeof(T));
02608                 delete [] (T *)p;
02609         }
02610 
02611         pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve)
02612         {
02613                 return StandardReallocate(*this, p, oldSize, newSize, preserve);
02614         }
02615 
02616         // VS.NET STL enforces the policy of "All STL-compliant allocators have to provide a
02617         // template class member called rebind".
02618     template <class U> struct rebind { typedef AllocatorWithCleanup<U> other; };
02619 };
02620 
02621 template <class T>
02622 class NullAllocator : public AllocatorBase<T>
02623 {
02624 public:
02625         CRYPTOPP_INHERIT_ALLOCATOR_TYPES
02626 
02627         pointer allocate(size_type /* n */, const void * = NULL)
02628         {
02629                 assert(false);
02630                 return NULL;
02631         }
02632 
02633         void deallocate(void* /* p */, size_type /* n */)
02634         {
02635                 assert(false);
02636         }
02637 
02638         size_type max_size() const {return 0;}
02639 };
02640 
02641 // This allocator can't be used with standard collections because
02642 // they require that all objects of the same allocator type are equivalent.
02643 // So this is for use with SecBlock only.
02644 template <class T, size_t S, class A = NullAllocator<T> >
02645 class FixedSizeAllocatorWithCleanup : public AllocatorBase<T>
02646 {
02647 public:
02648         CRYPTOPP_INHERIT_ALLOCATOR_TYPES
02649 
02650         FixedSizeAllocatorWithCleanup() : m_allocated(false) {}
02651 
02652         pointer allocate(size_type n)
02653         {
02654                 if (n <= S && !m_allocated)
02655                 {
02656                         m_allocated = true;
02657                         return m_array;
02658                 }
02659                 else
02660                         return m_fallbackAllocator.allocate(n);
02661         }
02662 
02663         pointer allocate(size_type n, const void *hint)
02664         {
02665                 if (n <= S && !m_allocated)
02666                 {
02667                         m_allocated = true;
02668                         return m_array;
02669                 }
02670                 else
02671                         return m_fallbackAllocator.allocate(n, hint);
02672         }
02673 
02674         void deallocate(void *p, size_type n)
02675         {
02676                 if (p == m_array)
02677                 {
02678                         assert(n <= S);
02679                         assert(m_allocated);
02680                         m_allocated = false;
02681                         memset(p, 0, n*sizeof(T));
02682                 }
02683                 else
02684                         m_fallbackAllocator.deallocate(p, n);
02685         }
02686 
02687         pointer reallocate(pointer p, size_type oldSize, size_type newSize, bool preserve)
02688         {
02689                 if (p == m_array && newSize <= S)
02690                 {
02691                         assert(oldSize <= S);
02692                         if (oldSize > newSize)
02693                                 memset(p + newSize, 0, (oldSize-newSize)*sizeof(T));
02694                         return p;
02695                 }
02696 
02697                 pointer newPointer = allocate(newSize, NULL);
02698                 if (preserve)
02699                         memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize));
02700                 deallocate(p, oldSize);
02701                 return newPointer;
02702         }
02703 
02704         size_type max_size() const {return STDMAX(m_fallbackAllocator.max_size(), S);}
02705 
02706 private:
02707         T m_array[S];
02708         A m_fallbackAllocator;
02709         bool m_allocated;
02710 };
02711 
02712 //! a block of memory allocated using A
02713 template <class T, class A = AllocatorWithCleanup<T> >
02714 class SecBlock
02715 {
02716 public:
02717     explicit SecBlock(unsigned int size=0)
02718                 : m_size(size) {m_ptr = m_alloc.allocate(size, NULL);}
02719         SecBlock(const SecBlock<T, A> &t)
02720                 : m_size(t.m_size) {m_ptr = m_alloc.allocate(m_size, NULL); memcpy(m_ptr, t.m_ptr, m_size*sizeof(T));}
02721         SecBlock(const T *t, unsigned int len)
02722                 : m_size(len)
02723         {
02724                 m_ptr = m_alloc.allocate(len, NULL);
02725                 if (t == NULL)
02726                         memset(m_ptr, 0, len*sizeof(T));
02727                 else
02728                         memcpy(m_ptr, t, len*sizeof(T));
02729         }
02730 
02731         ~SecBlock()
02732                 {m_alloc.deallocate(m_ptr, m_size);}
02733 
02734         operator const void *() const
02735                 {return m_ptr;}
02736         operator void *()
02737                 {return m_ptr;}
02738 #if defined(__GNUC__) && __GNUC__ < 3   // reduce warnings
02739         operator const void *()
02740                 {return m_ptr;}
02741 #endif
02742 
02743         operator const T *() const
02744                 {return m_ptr;}
02745         operator T *()
02746                 {return m_ptr;}
02747 #if defined(__GNUC__) && __GNUC__ < 3   // reduce warnings
02748         operator const T *()
02749                 {return m_ptr;}
02750 #endif
02751 
02752         template <typename I>
02753         T *operator +(I offset)
02754                 {return m_ptr+offset;}
02755 
02756         template <typename I>
02757         const T *operator +(I offset) const
02758                 {return m_ptr+offset;}
02759 
02760         template <typename I>
02761         T& operator[](I index)
02762                 {assert((unsigned int)index < m_size); return m_ptr[index];}
02763 
02764         template <typename I>
02765         const T& operator[](I index) const
02766                 {assert((unsigned int)index < m_size); return m_ptr[index];}
02767 
02768         typedef typename A::value_type value_type;
02769         typedef typename A::pointer iterator;
02770         typedef typename A::const_pointer const_iterator;
02771         typedef typename A::size_type size_type;
02772 
02773         iterator begin()
02774                 {return m_ptr;}
02775         const_iterator begin() const
02776                 {return m_ptr;}
02777         iterator end()
02778                 {return m_ptr+m_size;}
02779         const_iterator end() const
02780                 {return m_ptr+m_size;}
02781 
02782         typename A::pointer data() {return m_ptr;}
02783         typename A::const_pointer data() const {return m_ptr;}
02784 
02785         size_type size() const {return m_size;}
02786         bool empty() const {return m_size == 0;}
02787 
02788         void Assign(const T *t, unsigned int len)
02789         {
02790                 New(len);
02791                 memcpy(m_ptr, t, len*sizeof(T));
02792         }
02793 
02794         void Assign(const SecBlock<T, A> &t)
02795         {
02796                 New(t.m_size);
02797                 memcpy(m_ptr, t.m_ptr, m_size*sizeof(T));
02798         }
02799 
02800         SecBlock& operator=(const SecBlock<T, A> &t)
02801         {
02802                 Assign(t);
02803                 return *this;
02804         }
02805 
02806         bool operator==(const SecBlock<T, A> &t) const
02807         {
02808                 return m_size == t.m_size && memcmp(m_ptr, t.m_ptr, m_size*sizeof(T)) == 0;
02809         }
02810 
02811         bool operator!=(const SecBlock<T, A> &t) const
02812         {
02813                 return !operator==(t);
02814         }
02815 
02816         void New(unsigned int newSize)
02817         {
02818                 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, false);
02819                 m_size = newSize;
02820         }
02821 
02822         void CleanNew(unsigned int newSize)
02823         {
02824                 New(newSize);
02825                 memset(m_ptr, 0, m_size*sizeof(T));
02826         }
02827 
02828         void Grow(unsigned int newSize)
02829         {
02830                 if (newSize > m_size)
02831                 {
02832                         m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
02833                         m_size = newSize;
02834                 }
02835         }
02836 
02837         void CleanGrow(unsigned int newSize)
02838         {
02839                 if (newSize > m_size)
02840                 {
02841                         m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
02842                         memset(m_ptr+m_size, 0, (newSize-m_size)*sizeof(T));
02843                         m_size = newSize;
02844                 }
02845         }
02846 
02847         void resize(unsigned int newSize)
02848         {
02849                 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
02850                 m_size = newSize;
02851         }
02852 
02853         void swap(SecBlock<T, A> &b)
02854         {
02855                 std::swap(m_alloc, b.m_alloc);
02856                 std::swap(m_size, b.m_size);
02857                 std::swap(m_ptr, b.m_ptr);
02858         }
02859 
02860 //private:
02861         A m_alloc;
02862         unsigned int m_size;
02863         T *m_ptr;
02864 };
02865 
02866 typedef SecBlock<byte> SecByteBlock;
02867 typedef SecBlock<word> SecWordBlock;
02868 
02869 template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S> >
02870 class FixedSizeSecBlock : public SecBlock<T, A>
02871 {
02872 public:
02873         explicit FixedSizeSecBlock() : SecBlock<T, A>(S) {}
02874 };
02875 
02876 template<class T, class U>
02877 inline bool operator==(const CryptoPP::AllocatorWithCleanup<T>&, const CryptoPP::AllocatorWithCleanup<U>&) {return (true);}
02878 template<class T, class U>
02879 inline bool operator!=(const CryptoPP::AllocatorWithCleanup<T>&, const CryptoPP::AllocatorWithCleanup<U>&) {return (false);}
02880 
02881 NAMESPACE_END
02882 
02883 NAMESPACE_BEGIN(std)
02884 template <class T, class A>
02885 inline void swap(CryptoPP::SecBlock<T, A> &a, CryptoPP::SecBlock<T, A> &b)
02886 {
02887         a.swap(b);
02888 }
02889 
02890 #if defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES)
02891 template <class _Tp1, class _Tp2>
02892 inline CryptoPP::AllocatorWithCleanup<_Tp2>&
02893 __stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*)
02894 {
02895         return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a);
02896 }
02897 #endif
02898 
02899 NAMESPACE_END
02900 
02901 #endif
02902 ////////////////////////////////////////////////////////////////////////////////
02903 
02904 
02905 
02906 ////////////////////////////////////////////////////////////////////////////////
02907 #ifndef CRYPTOPP_INTEGER_H
02908 #define CRYPTOPP_INTEGER_H
02909 
02910 /** \file */
02911 
02912 //- #include "cryptlib.h"
02913 //- #include "secblock.h"
02914 
02915 #include <iosfwd>
02916 #include <algorithm>
02917 
02918 #ifdef CRYPTOPP_X86ASM_AVAILABLE
02919 
02920 #ifdef _M_IX86
02921         #if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 500)) || (defined(__ICL) && (__ICL >= 500))
02922                 #define SSE2_INTRINSICS_AVAILABLE
02923                 #define CRYPTOPP_MM_MALLOC_AVAILABLE
02924         #elif defined(_MSC_VER)
02925                 // _mm_free seems to be the only way to tell if the Processor Pack is installed or not
02926                 #include <malloc.h>
02927                 #if defined(_mm_free)
02928                         #define SSE2_INTRINSICS_AVAILABLE
02929                         #define CRYPTOPP_MM_MALLOC_AVAILABLE
02930                 #endif
02931         #endif
02932 #endif
02933 
02934 // SSE2 intrinsics work in GCC 3.3 or later
02935 #if defined(__SSE2__) && (__GNUC_MAJOR__ > 3 || __GNUC_MINOR__ > 2)
02936         #define SSE2_INTRINSICS_AVAILABLE
02937 #endif
02938 
02939 #endif
02940 
02941 NAMESPACE_BEGIN(CryptoPP)
02942 
02943 #if defined(SSE2_INTRINSICS_AVAILABLE)
02944         template <class T>
02945         class AlignedAllocator : public AllocatorBase<T>
02946         {
02947         public:
02948                 CRYPTOPP_INHERIT_ALLOCATOR_TYPES
02949 
02950                 pointer allocate(size_type n, const void *);
02951                 void deallocate(void *p, size_type n);
02952                 pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve)
02953                 {
02954                         return StandardReallocate(*this, p, oldSize, newSize, preserve);
02955                 }
02956 
02957         #if !(defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) || defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE))
02958         #define CRYPTOPP_NO_ALIGNED_ALLOC
02959                 AlignedAllocator() : m_pBlock(NULL) {}
02960         protected:
02961                 void *m_pBlock;
02962         #endif
02963         };
02964 
02965         template class CRYPTOPP_DLL AlignedAllocator<word>;
02966         typedef SecBlock<word, AlignedAllocator<word> > SecAlignedWordBlock;
02967 #else
02968         typedef SecWordBlock SecAlignedWordBlock;
02969 #endif
02970 
02971 void CRYPTOPP_DLL DisableSSE2();
02972 
02973 //! multiple precision integer and basic arithmetics
02974 /*! This class can represent positive and negative integers
02975         with absolute value less than (256**sizeof(word)) ** (256**sizeof(int)).
02976         \nosubgrouping
02977 */
02978 class CRYPTOPP_DLL Integer : public ASN1Object
02979 {
02980 public:
02981         //! \name ENUMS, EXCEPTIONS, and TYPEDEFS
02982         //@{
02983                 //! division by zero exception
02984                 class DivideByZero : public Exception
02985                 {
02986                 public:
02987                         DivideByZero() : Exception(OTHER_ERROR, "Integer: division by zero") {}
02988                 };
02989 
02990                 //!
02991                 class RandomNumberNotFound : public Exception
02992                 {
02993                 public:
02994                         RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {}
02995                 };
02996 
02997                 //!
02998                 enum Sign {POSITIVE=0, NEGATIVE=1};
02999 
03000                 //!
03001                 enum Signedness {
03002                 //!
03003                         UNSIGNED,
03004                 //!
03005                         SIGNED};
03006 
03007                 //!
03008                 enum RandomNumberType {
03009                 //!
03010                         ANY,
03011                 //!
03012                         PRIME};
03013         //@}
03014 
03015         //! \name CREATORS
03016         //@{
03017                 //! creates the zero integer
03018                 Integer();
03019 
03020                 //! copy constructor
03021                 Integer(const Integer& t);
03022 
03023                 //! convert from signed long
03024                 Integer(signed long value);
03025 
03026                 //! convert from lword
03027                 Integer(Sign s, lword value);
03028 
03029                 //! convert from two words
03030                 Integer(Sign s, word highWord, word lowWord);
03031 
03032                 //! convert from string
03033                 /*! str can be in base 2, 8, 10, or 16.  Base is determined by a
03034                         case insensitive suffix of 'h', 'o', or 'b'.  No suffix means base 10.
03035                 */
03036                 explicit Integer(const char *str);
03037                 explicit Integer(const wchar_t *str);
03038 
03039                 //! convert from big-endian byte array
03040                 Integer(const byte *encodedInteger, unsigned int byteCount, Signedness s=UNSIGNED);
03041 
03042                 //! convert from big-endian form stored in a BufferedTransformation
03043                 Integer(BufferedTransformation &bt, unsigned int byteCount, Signedness s=UNSIGNED);
03044 
03045                 //! convert from BER encoded byte array stored in a BufferedTransformation object
03046                 explicit Integer(BufferedTransformation &bt);
03047 
03048                 //! create a random integer
03049                 /*! The random integer created is uniformly distributed over [0, 2**bitcount). */
03050                 Integer(RandomNumberGenerator &rng, unsigned int bitcount);
03051 
03052                 //! avoid calling constructors for these frequently used integers
03053                 static const Integer &Zero();
03054                 //! avoid calling constructors for these frequently used integers
03055                 static const Integer &One();
03056                 //! avoid calling constructors for these frequently used integers
03057                 static const Integer &Two();
03058 
03059                 //! create a random integer of special type
03060                 /*! Ideally, the random integer created should be uniformly distributed
03061                         over {x | min <= x <= max and x is of rnType and x % mod == equiv}.
03062                         However the actual distribution may not be uniform because sequential
03063                         search is used to find an appropriate number from a random starting
03064                         point.
03065                         May return (with very small probability) a pseudoprime when a prime
03066                         is requested and max > lastSmallPrime*lastSmallPrime (lastSmallPrime
03067                         is declared in nbtheory.h).
03068                         \throw RandomNumberNotFound if the set is empty.
03069                 */
03070                 Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One());
03071 
03072                 //! return the integer 2**e
03073                 static Integer Power2(unsigned int e);
03074         //@}
03075 
03076         //! \name ENCODE/DECODE
03077         //@{
03078                 //! minimum number of bytes to encode this integer
03079                 /*! MinEncodedSize of 0 is 1 */
03080                 unsigned int MinEncodedSize(Signedness=UNSIGNED) const;
03081                 //! encode in big-endian format
03082                 /*! unsigned means encode absolute value, signed means encode two's complement if negative.
03083                         if outputLen < MinEncodedSize, the most significant bytes will be dropped
03084                         if outputLen > MinEncodedSize, the most significant bytes will be padded
03085                 */
03086                 unsigned int Encode(byte *output, unsigned int outputLen, Signedness=UNSIGNED) const;
03087                 //!
03088                 unsigned int Encode(BufferedTransformation &bt, unsigned int outputLen, Signedness=UNSIGNED) const;
03089 
03090                 //! encode using Distinguished Encoding Rules, put result into a BufferedTransformation object
03091                 void DEREncode(BufferedTransformation &bt) const;
03092 
03093                 //! encode absolute value as big-endian octet string
03094                 void DEREncodeAsOctetString(BufferedTransformation &bt, unsigned int length) const;
03095 
03096                 //! encode absolute value in OpenPGP format, return length of output
03097                 unsigned int OpenPGPEncode(byte *output, unsigned int bufferSize) const;
03098                 //! encode absolute value in OpenPGP format, put result into a BufferedTransformation object
03099                 unsigned int OpenPGPEncode(BufferedTransformation &bt) const;
03100 
03101                 //!
03102                 void Decode(const byte *input, unsigned int inputLen, Signedness=UNSIGNED);
03103                 //!
03104                 //* Precondition: bt.MaxRetrievable() >= inputLen
03105                 void Decode(BufferedTransformation &bt, unsigned int inputLen, Signedness=UNSIGNED);
03106 
03107                 //!
03108                 void BERDecode(const byte *input, unsigned int inputLen);
03109                 //!
03110                 void BERDecode(BufferedTransformation &bt);
03111 
03112                 //! decode nonnegative value as big-endian octet string
03113                 void BERDecodeAsOctetString(BufferedTransformation &bt, unsigned int length);
03114 
03115                 class OpenPGPDecodeErr : public Exception
03116                 {
03117                 public:
03118                         OpenPGPDecodeErr() : Exception(INVALID_DATA_FORMAT, "OpenPGP decode error") {}
03119                 };
03120 
03121                 //!
03122                 void OpenPGPDecode(const byte *input, unsigned int inputLen);
03123                 //!
03124                 void OpenPGPDecode(BufferedTransformation &bt);
03125         //@}
03126 
03127         //! \name ACCESSORS
03128         //@{
03129                 //! return true if *this can be represented as a signed long
03130                 bool IsConvertableToLong() const;
03131                 //! return equivalent signed long if possible, otherwise undefined
03132                 signed long ConvertToLong() const;
03133 
03134                 //! number of significant bits = floor(log2(abs(*this))) + 1
03135                 unsigned int BitCount() const;
03136                 //! number of significant bytes = ceiling(BitCount()/8)
03137                 unsigned int ByteCount() const;
03138                 //! number of significant words = ceiling(ByteCount()/sizeof(word))
03139                 unsigned int WordCount() const;
03140 
03141                 //! return the i-th bit, i=0 being the least significant bit
03142                 bool GetBit(unsigned int i) const;
03143                 //! return the i-th byte
03144                 byte GetByte(unsigned int i) const;
03145                 //! return n lowest bits of *this >> i
03146                 unsigned long GetBits(unsigned int i, unsigned int n) const;
03147 
03148                 //!
03149                 bool IsZero() const {return !*this;}
03150                 //!
03151                 bool NotZero() const {return !IsZero();}
03152                 //!
03153                 bool IsNegative() const {return sign == NEGATIVE;}
03154                 //!
03155                 bool NotNegative() const {return !IsNegative();}
03156                 //!
03157                 bool IsPositive() const {return NotNegative() && NotZero();}
03158                 //!
03159                 bool NotPositive() const {return !IsPositive();}
03160                 //!
03161                 bool IsEven() const {return GetBit(0) == 0;}
03162                 //!
03163                 bool IsOdd() const      {return GetBit(0) == 1;}
03164         //@}
03165 
03166         //! \name MANIPULATORS
03167         //@{
03168                 //!
03169                 Integer&  operator=(const Integer& t);
03170 
03171                 //!
03172                 Integer&  operator+=(const Integer& t);
03173                 //!
03174                 Integer&  operator-=(const Integer& t);
03175                 //!
03176                 Integer&  operator*=(const Integer& t)  {return *this = Times(t);}
03177                 //!
03178                 Integer&  operator/=(const Integer& t)  {return *this = DividedBy(t);}
03179                 //!
03180                 Integer&  operator%=(const Integer& t)  {return *this = Modulo(t);}
03181                 //!
03182                 Integer&  operator/=(word t)  {return *this = DividedBy(t);}
03183                 //!
03184                 Integer&  operator%=(word t)  {return *this = Modulo(t);}
03185 
03186                 //!
03187                 Integer&  operator<<=(unsigned int);
03188                 //!
03189                 Integer&  operator>>=(unsigned int);
03190 
03191                 //!
03192                 void Randomize(RandomNumberGenerator &rng, unsigned int bitcount);
03193                 //!
03194                 void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max);
03195                 //! set this Integer to a random element of {x | min <= x <= max and x is of rnType and x % mod == equiv}
03196                 /*! returns false if the set is empty */
03197                 bool Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv=Zero(), const Integer &mod=One());
03198 
03199                 bool GenerateRandomNoThrow(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs);
03200                 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs)
03201                 {
03202                         if (!GenerateRandomNoThrow(rng, params))
03203                                 throw RandomNumberNotFound();
03204                 }
03205 
03206                 //! set the n-th bit to value
03207                 void SetBit(unsigned int n, bool value=1);
03208                 //! set the n-th byte to value
03209                 void SetByte(unsigned int n, byte value);
03210 
03211                 //!
03212                 void Negate();
03213                 //!
03214                 void SetPositive() {sign = POSITIVE;}
03215                 //!
03216                 void SetNegative() {if (!!(*this)) sign = NEGATIVE;}
03217 
03218                 //!
03219                 void swap(Integer &a);
03220         //@}
03221 
03222         //! \name UNARY OPERATORS
03223         //@{
03224                 //!
03225                 bool            operator!() const;
03226                 //!
03227                 Integer         operator+() const {return *this;}
03228                 //!
03229                 Integer         operator-() const;
03230                 //!
03231                 Integer&        operator++();
03232                 //!
03233                 Integer&        operator--();
03234                 //!
03235                 Integer         operator++(int) {Integer temp = *this; ++*this; return temp;}
03236                 //!
03237                 Integer         operator--(int) {Integer temp = *this; --*this; return temp;}
03238         //@}
03239 
03240         //! \name BINARY OPERATORS
03241         //@{
03242                 //! signed comparison
03243                 /*! \retval -1 if *this < a
03244                         \retval  0 if *this = a
03245                         \retval  1 if *this > a
03246                 */
03247                 int Compare(const Integer& a) const;
03248 
03249                 //!
03250                 Integer Plus(const Integer &b) const;
03251                 //!
03252                 Integer Minus(const Integer &b) const;
03253                 //!
03254                 Integer Times(const Integer &b) const;
03255                 //!
03256                 Integer DividedBy(const Integer &b) const;
03257                 //!
03258                 Integer Modulo(const Integer &b) const;
03259                 //!
03260                 Integer DividedBy(word b) const;
03261                 //!
03262                 word Modulo(word b) const;
03263 
03264                 //!
03265                 Integer operator>>(unsigned int n) const        {return Integer(*this)>>=n;}
03266                 //!
03267                 Integer operator<<(unsigned int n) const        {return Integer(*this)<<=n;}
03268         //@}
03269 
03270         //! \name OTHER ARITHMETIC FUNCTIONS
03271         //@{
03272                 //!
03273                 Integer AbsoluteValue() const;
03274                 //!
03275                 Integer Doubled() const {return Plus(*this);}
03276                 //!
03277                 Integer Squared() const {return Times(*this);}
03278                 //! extract square root, if negative return 0, else return floor of square root
03279                 Integer SquareRoot() const;
03280                 //! return whether this integer is a perfect square
03281                 bool IsSquare() const;
03282 
03283                 //! is 1 or -1
03284                 bool IsUnit() const;
03285                 //! return inverse if 1 or -1, otherwise return 0
03286                 Integer MultiplicativeInverse() const;
03287 
03288                 //! modular multiplication
03289                 CRYPTOPP_DLL friend Integer a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
03290                 //! modular exponentiation
03291                 CRYPTOPP_DLL friend Integer a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
03292 
03293                 //! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
03294                 static void Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
03295                 //! use a faster division algorithm when divisor is short
03296                 static void Divide(word &r, Integer &q, const Integer &a, word d);
03297 
03298                 //! returns same result as Divide(r, q, a, Power2(n)), but faster
03299                 static void DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n);
03300 
03301                 //! greatest common divisor
03302                 static Integer Gcd(const Integer &a, const Integer &n);
03303                 //! calculate multiplicative inverse of *this mod n
03304                 Integer InverseMod(const Integer &n) const;
03305                 //!
03306                 word InverseMod(word n) const;
03307         //@}
03308 
03309         //! \name INPUT/OUTPUT
03310         //@{
03311                 //!
03312                 friend CRYPTOPP_DLL std::istream& operator>>(std::istream& in, Integer &a);
03313                 //!
03314                 friend CRYPTOPP_DLL std::ostream& operator<<(std::ostream& out, const Integer &a);
03315         //@}
03316 
03317 private:
03318         friend class ModularArithmetic;
03319         friend class MontgomeryRepresentation;
03320         friend class HalfMontgomeryRepresentation;
03321 
03322         Integer(word value, unsigned int length);
03323 
03324         int PositiveCompare(const Integer &t) const;
03325         friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b);
03326         friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b);
03327         friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b);
03328         friend void PositiveDivide(Integer &remainder, Integer &quotient, const Integer &dividend, const Integer &divisor);
03329 
03330         SecAlignedWordBlock reg;
03331         Sign sign;
03332 };
03333 
03334 //!
03335 inline bool operator==(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)==0;}
03336 //!
03337 inline bool operator!=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)!=0;}
03338 //!
03339 inline bool operator> (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)> 0;}
03340 //!
03341 inline bool operator>=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)>=0;}
03342 //!
03343 inline bool operator< (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)< 0;}
03344 //!
03345 inline bool operator<=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)<=0;}
03346 //!
03347 inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Plus(b);}
03348 //!
03349 inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);}
03350 //!
03351 inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);}
03352 //!
03353 inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);}
03354 //!
03355 inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);}
03356 //!
03357 inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);}
03358 //!
03359 inline CryptoPP::word    operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);}
03360 
03361 NAMESPACE_END
03362 
03363 NAMESPACE_BEGIN(std)
03364 template<> inline void swap(CryptoPP::Integer &a, CryptoPP::Integer &b)
03365 {
03366         a.swap(b);
03367 }
03368 NAMESPACE_END
03369 
03370 #endif
03371 ////////////////////////////////////////////////////////////////////////////////
03372 
03373 
03374 ////////////////////////////////////////////////////////////////////////////////
03375 #ifndef CRYPTOPP_ALGEBRA_H
03376 #define CRYPTOPP_ALGEBRA_H
03377 
03378 //- #include "config.h"
03379 
03380 NAMESPACE_BEGIN(CryptoPP)
03381 
03382 class Integer;
03383 
03384 // "const Element&" returned by member functions are references
03385 // to internal data members. Since each object may have only
03386 // one such data member for holding results, the following code
03387 // will produce incorrect results:
03388 // abcd = group.Add(group.Add(a,b), group.Add(c,d));
03389 // But this should be fine:
03390 // abcd = group.Add(a, group.Add(b, group.Add(c,d));
03391 
03392 //! Abstract Group
03393 template <class T> class CRYPTOPP_NO_VTABLE AbstractGroup
03394 {
03395 public:
03396         typedef T Element;
03397 
03398         virtual ~AbstractGroup() {}
03399 
03400         virtual bool Equal(const Element &a, const Element &b) const =0;
03401         virtual const Element& Identity() const =0;
03402         virtual const Element& Add(const Element &a, const Element &b) const =0;
03403         virtual const Element& Inverse(const Element &a) const =0;
03404         virtual bool InversionIsFast() const {return false;}
03405 
03406         virtual const Element& Double(const Element &a) const;
03407         virtual const Element& Subtract(const Element &a, const Element &b) const;
03408         virtual Element& Accumulate(Element &a, const Element &b) const;
03409         virtual Element& Reduce(Element &a, const Element &b) const;
03410 
03411         virtual Element ScalarMultiply(const Element &a, const Integer &e) const;
03412         virtual Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
03413 
03414         virtual void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
03415 };
03416 
03417 //! Abstract Ring
03418 template <class T> class CRYPTOPP_NO_VTABLE AbstractRing : public AbstractGroup<T>
03419 {
03420 public:
03421         typedef T Element;
03422 
03423         AbstractRing() {m_mg.m_pRing = this;}
03424         AbstractRing(const AbstractRing &source) {m_mg.m_pRing = this;}
03425         AbstractRing& operator=(const AbstractRing &source) {return *this;}
03426 
03427         virtual bool IsUnit(const Element &a) const =0;
03428         virtual const Element& MultiplicativeIdentity() const =0;
03429         virtual const Element& Multiply(const Element &a, const Element &b) const =0;
03430         virtual const Element& MultiplicativeInverse(const Element &a) const =0;
03431 
03432         virtual const Element& Square(const Element &a) const;
03433         virtual const Element& Divide(const Element &a, const Element &b) const;
03434 
03435         virtual Element Exponentiate(const Element &a, const Integer &e) const;
03436         virtual Element CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
03437 
03438         virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
03439 
03440         virtual const AbstractGroup<T>& MultiplicativeGroup() const
03441                 {return m_mg;}
03442 
03443 private:
03444         class MultiplicativeGroupT : public AbstractGroup<T>
03445         {
03446         public:
03447                 const AbstractRing<T>& GetRing() const
03448                         {return *m_pRing;}
03449 
03450                 bool Equal(const Element &a, const Element &b) const
03451                         {return GetRing().Equal(a, b);}
03452 
03453                 const Element& Identity() const
03454                         {return GetRing().MultiplicativeIdentity();}
03455 
03456                 const Element& Add(const Element &a, const Element &b) const
03457                         {return GetRing().Multiply(a, b);}
03458 
03459                 Element& Accumulate(Element &a, const Element &b) const
03460                         {return a = GetRing().Multiply(a, b);}
03461 
03462                 const Element& Inverse(const Element &a) const
03463                         {return GetRing().MultiplicativeInverse(a);}
03464 
03465                 const Element& Subtract(const Element &a, const Element &b) const
03466                         {return GetRing().Divide(a, b);}
03467 
03468                 Element& Reduce(Element &a, const Element &b) const
03469                         {return a = GetRing().Divide(a, b);}
03470 
03471                 const Element& Double(const Element &a) const
03472                         {return GetRing().Square(a);}
03473 
03474                 Element ScalarMultiply(const Element &a, const Integer &e) const
03475                         {return GetRing().Exponentiate(a, e);}
03476 
03477                 Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
03478                         {return GetRing().CascadeExponentiate(x, e1, y, e2);}
03479 
03480                 void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
03481                         {GetRing().SimultaneousExponentiate(results, base, exponents, exponentsCount);}
03482 
03483                 const AbstractRing<T> *m_pRing;
03484         };
03485 
03486         MultiplicativeGroupT m_mg;
03487 };
03488 
03489 // ********************************************************
03490 
03491 //! Abstract Euclidean Domain
03492 template <class T> class CRYPTOPP_NO_VTABLE AbstractEuclideanDomain : public AbstractRing<T>
03493 {
03494 public:
03495         typedef T Element;
03496 
03497         virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const =0;
03498 
03499         virtual const Element& Mod(const Element &a, const Element &b) const =0;
03500         virtual const Element& Gcd(const Element &a, const Element &b) const;
03501 
03502 protected:
03503         mutable Element result;
03504 };
03505 
03506 // ********************************************************
03507 
03508 //! EuclideanDomainOf
03509 template <class T> class EuclideanDomainOf : public AbstractEuclideanDomain<T>
03510 {
03511 public:
03512         typedef T Element;
03513 
03514         EuclideanDomainOf() {}
03515 
03516         bool Equal(const Element &a, const Element &b) const
03517                 {return a==b;}
03518 
03519         const Element& Identity() const
03520                 {return Element::Zero();}
03521 
03522         const Element& Add(const Element &a, const Element &b) const
03523                 {return result = a+b;}
03524 
03525         Element& Accumulate(Element &a, const Element &b) const
03526                 {return a+=b;}
03527 
03528         const Element& Inverse(const Element &a) const
03529                 {return result = -a;}
03530 
03531         const Element& Subtract(const Element &a, const Element &b) const
03532                 {return result = a-b;}
03533 
03534         Element& Reduce(Element &a, const Element &b) const
03535                 {return a-=b;}
03536 
03537         const Element& Double(const Element &a) const
03538                 {return result = a.Doubled();}
03539 
03540         const Element& MultiplicativeIdentity() const
03541                 {return Element::One();}
03542 
03543         const Element& Multiply(const Element &a, const Element &b) const
03544                 {return result = a*b;}
03545 
03546         const Element& Square(const Element &a) const
03547                 {return result = a.Squared();}
03548 
03549         bool IsUnit(const Element &a) const
03550                 {return a.IsUnit();}
03551 
03552         const Element& MultiplicativeInverse(const Element &a) const
03553                 {return result = a.MultiplicativeInverse();}
03554 
03555         const Element& Divide(const Element &a, const Element &b) const
03556                 {return result = a/b;}
03557 
03558         const Element& Mod(const Element &a, const Element &b) const
03559                 {return result = a%b;}
03560 
03561         void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const
03562                 {Element::Divide(r, q, a, d);}
03563 
03564         bool operator==(const EuclideanDomainOf<T> &rhs) const
03565                 {return true;}
03566 
03567 private:
03568         mutable Element result;
03569 };
03570 
03571 NAMESPACE_END
03572 
03573 #endif
03574 ////////////////////////////////////////////////////////////////////////////////
03575 
03576 
03577 ////////////////////////////////////////////////////////////////////////////////
03578 #ifndef CRYPTOPP_MODARITH_H
03579 #define CRYPTOPP_MODARITH_H
03580 
03581 // implementations are in integer.cpp
03582 
03583 //- #include "cryptlib.h"
03584 //- #include "misc.h"
03585 //- #include "integer.h"
03586 //- #include "algebra.h"
03587 
03588 NAMESPACE_BEGIN(CryptoPP)
03589 
03590 //! ring of congruence classes modulo n
03591 /*! \note this implementation represents each congruence class as the smallest non-negative integer in that class */
03592 class CRYPTOPP_DLL ModularArithmetic : public AbstractRing<Integer>
03593 {
03594 public:
03595 
03596         typedef int RandomizationParameter;
03597         typedef Integer Element;
03598 
03599         ModularArithmetic(const Integer &modulus = Integer::One())
03600                 : AbstractRing<Integer>(),
03601                   modulus(modulus), result((word)0, modulus.reg.size()) {}
03602 
03603         ModularArithmetic(const ModularArithmetic &ma)
03604                 : AbstractRing<Integer>(),
03605                   modulus(ma.modulus), result((word)0, modulus.reg.size()) {}
03606 
03607         ModularArithmetic(BufferedTransformation &bt);  // construct from BER encoded parameters
03608 
03609         virtual ModularArithmetic * Clone() const {return new ModularArithmetic(*this);}
03610 
03611         void DEREncode(BufferedTransformation &bt) const;
03612 
03613         void DEREncodeElement(BufferedTransformation &out, const Element &a) const;
03614         void BERDecodeElement(BufferedTransformation &in, Element &a) const;
03615 
03616         const Integer& GetModulus() const {return modulus;}
03617         void SetModulus(const Integer &newModulus) {modulus = newModulus; result.reg.resize(modulus.reg.size());}
03618 
03619         virtual bool IsMontgomeryRepresentation() const {return false;}
03620 
03621         virtual Integer ConvertIn(const Integer &a) const
03622                 {return a%modulus;}
03623 
03624         virtual Integer ConvertOut(const Integer &a) const
03625                 {return a;}
03626 
03627         const Integer& Half(const Integer &a) const;
03628 
03629         bool Equal(const Integer &a, const Integer &b) const
03630                 {return a==b;}
03631 
03632         const Integer& Identity() const
03633                 {return Integer::Zero();}
03634 
03635         const Integer& Add(const Integer &a, const Integer &b) const;
03636 
03637         Integer& Accumulate(Integer &a, const Integer &b) const;
03638 
03639         const Integer& Inverse(const Integer &a) const;
03640 
03641         const Integer& Subtract(const Integer &a, const Integer &b) const;
03642 
03643         Integer& Reduce(Integer &a, const Integer &b) const;
03644 
03645         const Integer& Double(const Integer &a) const
03646                 {return Add(a, a);}
03647 
03648         const Integer& MultiplicativeIdentity() const
03649                 {return Integer::One();}
03650 
03651         const Integer& Multiply(const Integer &a, const Integer &b) const
03652                 {return result1 = a*b%modulus;}
03653 
03654         const Integer& Square(const Integer &a) const
03655                 {return result1 = a.Squared()%modulus;}
03656 
03657         bool IsUnit(const Integer &a) const
03658                 {return Integer::Gcd(a, modulus).IsUnit();}
03659 
03660         const Integer& MultiplicativeInverse(const Integer &a) const
03661                 {return result1 = a.InverseMod(modulus);}
03662 
03663         const Integer& Divide(const Integer &a, const Integer &b) const
03664                 {return Multiply(a, MultiplicativeInverse(b));}
03665 
03666         Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const;
03667 
03668         void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
03669 
03670         unsigned int MaxElementBitLength() const
03671                 {return (modulus-1).BitCount();}
03672 
03673         unsigned int MaxElementByteLength() const
03674                 {return (modulus-1).ByteCount();}
03675 
03676         Element RandomElement( RandomNumberGenerator &rng , const RandomizationParameter& /*ignore_for_now*/ = 0 ) const
03677                 // left RandomizationParameter arg as ref in case RandomizationParameter becomes a more complicated struct
03678         {
03679                 return Element( rng , Integer( (long) 0) , modulus - Integer( (long) 1 )   ) ;
03680         }
03681 
03682         bool operator==(const ModularArithmetic &rhs) const
03683                 {return modulus == rhs.modulus;}
03684 
03685         static const RandomizationParameter DefaultRandomizationParameter ;
03686 
03687 protected:
03688         Integer modulus;
03689         mutable Integer result, result1;
03690 
03691 };
03692 
03693 // const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ;
03694 
03695 //! do modular arithmetics in Montgomery representation for increased speed
03696 /*! \note the Montgomery representation represents each congruence class [a] as a*r%n, where r is a convenient power of 2 */
03697 class CRYPTOPP_DLL MontgomeryRepresentation : public ModularArithmetic
03698 {
03699 public:
03700         MontgomeryRepresentation(const Integer &modulus);       // modulus must be odd
03701 
03702         virtual ModularArithmetic * Clone() const {return new MontgomeryRepresentation(*this);}
03703 
03704         bool IsMontgomeryRepresentation() const {return true;}
03705 
03706         Integer ConvertIn(const Integer &a) const
03707                 {return (a<<(WORD_BITS*modulus.reg.size()))%modulus;}
03708 
03709         Integer ConvertOut(const Integer &a) const;
03710 
03711         const Integer& MultiplicativeIdentity() const
03712                 {return result1 = Integer::Power2(WORD_BITS*modulus.reg.size())%modulus;}
03713 
03714         const Integer& Multiply(const Integer &a, const Integer &b) const;
03715 
03716         const Integer& Square(const Integer &a) const;
03717 
03718         const Integer& MultiplicativeInverse(const Integer &a) const;
03719 
03720         Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const
03721                 {return AbstractRing<Integer>::CascadeExponentiate(x, e1, y, e2);}
03722 
03723         void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
03724                 {AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);}
03725 
03726 private:
03727         Integer u;
03728         mutable SecAlignedWordBlock workspace;
03729 };
03730 
03731 NAMESPACE_END
03732 
03733 #endif
03734 ////////////////////////////////////////////////////////////////////////////////
03735 
03736 
03737 ////////////////////////////////////////////////////////////////////////////////
03738 // simple.h - written and placed in the public domain by Wei Dai
03739 /*! \file
03740         Simple non-interface classes derived from classes in cryptlib.h.
03741 */
03742 
03743 #ifndef CRYPTOPP_SIMPLE_H
03744 #define CRYPTOPP_SIMPLE_H
03745 
03746 //- #include "cryptlib.h"
03747 //- #include "misc.h"
03748 
03749 NAMESPACE_BEGIN(CryptoPP)
03750 
03751 //! _
03752 template <class DERIVED, class BASE>
03753 class CRYPTOPP_NO_VTABLE ClonableImpl : public BASE
03754 {
03755 public:
03756         Clonable * Clone() const {return new DERIVED(*static_cast<const DERIVED *>(this));}
03757 };
03758 
03759 //! _
03760 template <class BASE, class ALGORITHM_INFO=BASE>
03761 class CRYPTOPP_NO_VTABLE AlgorithmImpl : public BASE
03762 {
03763 public:
03764         static std::string StaticAlgorithmName() {return ALGORITHM_INFO::StaticAlgorithmName();}
03765         std::string AlgorithmName() const {return ALGORITHM_INFO::StaticAlgorithmName();}
03766 };
03767 
03768 //! _
03769 class CRYPTOPP_DLL InvalidKeyLength : public InvalidArgument
03770 {
03771 public:
03772         explicit InvalidKeyLength(const std::string &algorithm, unsigned int length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid key length") {}
03773 };
03774 
03775 //! _
03776 // TODO: look into this virtual inheritance
03777 class CRYPTOPP_DLL ASN1CryptoMaterial : virtual public ASN1Object, virtual public CryptoMaterial
03778 {
03779 public:
03780         void Save(BufferedTransformation &bt) const
03781                 {BEREncode(bt);}
03782         void Load(BufferedTransformation &bt)
03783                 {BERDecode(bt);}
03784 };
03785 
03786 // *****************************
03787 
03788 //! _
03789 template <class T>
03790 class CRYPTOPP_NO_VTABLE Bufferless : public T
03791 {
03792 public:
03793         bool IsolatedFlush(bool /* hardFlush */, bool /* blocking */) {return false;}
03794 };
03795 
03796 //! _
03797 template <class T>
03798 class CRYPTOPP_NO_VTABLE Unflushable : public T
03799 {
03800 public:
03801         bool Flush(bool completeFlush, int propagation=-1, bool blocking=true)
03802                 {return ChannelFlush(this->NULL_CHANNEL, completeFlush, propagation, blocking);}
03803         bool IsolatedFlush(bool /* hardFlush */, bool /* blocking */)
03804                 {assert(false); return false;}
03805         bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true)
03806         {
03807                 if (hardFlush && !InputBufferIsEmpty())
03808                         throw CannotFlush("Unflushable<T>: this object has buffered input that cannot be flushed");
03809                 else
03810                 {
03811                         BufferedTransformation *attached = this->AttachedTransformation();
03812                         return attached && propagation ? attached->ChannelFlush(channel, hardFlush, propagation-1, blocking) : false;
03813                 }
03814         }
03815 
03816 protected:
03817         virtual bool InputBufferIsEmpty() const {return false;}
03818 };
03819 
03820 //! _
03821 template <class T>
03822 class CRYPTOPP_NO_VTABLE InputRejecting : public T
03823 {
03824 public:
03825         struct InputRejected : public NotImplemented
03826                 {InputRejected() : NotImplemented("BufferedTransformation: this object doesn't allow input") {}};
03827 
03828         // shouldn't be calling these functions on this class
03829         unsigned int Put2(const byte* /* begin */, unsigned int /* length */, int /* messageEnd */, bool /* blocking */)
03830                 {throw InputRejected();}
03831         bool IsolatedFlush(bool, bool) {return false;}
03832         bool IsolatedMessageSeriesEnd(bool) {throw InputRejected();}
03833 
03834         unsigned int ChannelPut2(const std::string& /* channel */, const byte* /* begin */, unsigned int /* length */, int /* messageEnd */, bool /* blocking */)
03835                 {throw InputRejected();}
03836         bool ChannelMessageSeriesEnd(const std::string &, int, bool) {throw InputRejected();}
03837 };
03838 
03839 //! _
03840 template <class T>
03841 class CRYPTOPP_NO_VTABLE CustomFlushPropagation : public T
03842 {
03843 public:
03844         virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) =0;
03845 
03846 private:
03847         bool IsolatedFlush(bool /* hardFlush */, bool /* blocking */) {assert(false); return false;}
03848 };
03849 
03850 //! _
03851 template <class T>
03852 class CRYPTOPP_NO_VTABLE CustomSignalPropagation : public CustomFlushPropagation<T>
03853 {
03854 public:
03855         virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1) =0;
03856 
03857 private:
03858         void IsolatedInitialize(const NameValuePairs& /* parameters */) {assert(false);}
03859 };
03860 
03861 //! _
03862 template <class T>
03863 class CRYPTOPP_NO_VTABLE AutoSignaling : public T
03864 {
03865 public:
03866         AutoSignaling(int propagation=-1) : m_autoSignalPropagation(propagation) {}
03867 
03868         void SetAutoSignalPropagation(int propagation)
03869                 {m_autoSignalPropagation = propagation;}
03870         int GetAutoSignalPropagation() const
03871                 {return m_autoSignalPropagation;}
03872 
03873 private:
03874         int m_autoSignalPropagation;
03875 };
03876 
03877 //! A BufferedTransformation that only contains pre-existing data as "output"
03878 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Store : public AutoSignaling<InputRejecting<BufferedTransformation> >
03879 {
03880 public:
03881         Store() : m_messageEnd(false) {}
03882 
03883         void IsolatedInitialize(const NameValuePairs &parameters)
03884         {
03885                 m_messageEnd = false;
03886                 StoreInitialize(parameters);
03887         }
03888 
03889         unsigned int NumberOfMessages() const {return m_messageEnd ? 0 : 1;}
03890         bool GetNextMessage();
03891         unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL) const;
03892 
03893 protected:
03894         virtual void StoreInitialize(const NameValuePairs &parameters) =0;
03895 
03896         bool m_messageEnd;
03897 };
03898 
03899 //! A BufferedTransformation that doesn't produce any retrievable output
03900 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Sink : public BufferedTransformation
03901 {
03902 protected:
03903         // make these functions protected to help prevent unintentional calls to them
03904         BufferedTransformation::Get;
03905         BufferedTransformation::Peek;
03906         BufferedTransformation::TransferTo;
03907         BufferedTransformation::CopyTo;
03908         BufferedTransformation::CopyRangeTo;
03909         BufferedTransformation::TransferMessagesTo;
03910         BufferedTransformation::CopyMessagesTo;
03911         BufferedTransformation::TransferAllTo;
03912         BufferedTransformation::CopyAllTo;
03913         unsigned int TransferTo2(BufferedTransformation& /* target */, unsigned long &transferBytes, const std::string& /* channel */ = NULL_CHANNEL, bool /* blocking */ = true)
03914                 {transferBytes = 0; return 0;}
03915         unsigned int CopyRangeTo2(BufferedTransformation& /* target */, unsigned long& /* begin */, unsigned long /* end */ = ULONG_MAX, const std::string& /* channel */ = NULL_CHANNEL, bool /* blocking */ = true) const
03916                 {return 0;}
03917 };
03918 
03919 class CRYPTOPP_DLL BitBucket : public Bufferless<Sink>
03920 {
03921 public:
03922         std::string AlgorithmName() const {return "BitBucket";}
03923         void IsolatedInitialize(const NameValuePairs& /* parameters */) {}
03924         unsigned int Put2(const byte* /* begin */, unsigned int /* length */, int /* messageEnd */, bool /* blocking */)
03925                 {return 0;}
03926 };
03927 
03928 NAMESPACE_END
03929 
03930 #endif
03931 ////////////////////////////////////////////////////////////////////////////////
03932 
03933 
03934 ////////////////////////////////////////////////////////////////////////////////
03935 // specification file for an unlimited queue for storing bytes
03936 
03937 #ifndef CRYPTOPP_QUEUE_H
03938 #define CRYPTOPP_QUEUE_H
03939 
03940 //- #include "simple.h"
03941 //#include <algorithm>
03942 
03943 NAMESPACE_BEGIN(CryptoPP)
03944 
03945 /** The queue is implemented as a linked list of byte arrays, but you don't need to
03946     know about that.  So just ignore this next line. :) */
03947 class ByteQueueNode;
03948 
03949 //! Byte Queue
03950 class CRYPTOPP_DLL ByteQueue : public Bufferless<BufferedTransformation>
03951 {
03952 public:
03953         ByteQueue(unsigned int nodeSize=0);
03954         ByteQueue(const ByteQueue &copy);
03955         ~ByteQueue();
03956 
03957         unsigned long MaxRetrievable() const
03958                 {return CurrentSize();}
03959         bool AnyRetrievable() const
03960                 {return !IsEmpty();}
03961 
03962         void IsolatedInitialize(const NameValuePairs &parameters);
03963         byte * CreatePutSpace(unsigned int &size);
03964         unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking);
03965 
03966         unsigned int Get(byte &outByte);
03967         unsigned int Get(byte *outString, unsigned int getMax);
03968 
03969         unsigned int Peek(byte &outByte) const;
03970         unsigned int Peek(byte *outString, unsigned int peekMax) const;
03971 
03972         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
03973         unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
03974 
03975         // these member functions are not inherited
03976         void SetNodeSize(unsigned int nodeSize);
03977 
03978         unsigned long CurrentSize() const;
03979         bool IsEmpty() const;
03980 
03981         void Clear();
03982 
03983         void Unget(byte inByte);
03984         void Unget(const byte *inString, unsigned int length);
03985 
03986         const byte * Spy(unsigned int &contiguousSize) const;
03987 
03988         void LazyPut(const byte *inString, unsigned int size);
03989         void LazyPutModifiable(byte *inString, unsigned int size);
03990         void UndoLazyPut(unsigned int size);
03991         void FinalizeLazyPut();
03992 
03993         ByteQueue & operator=(const ByteQueue &rhs);
03994         bool operator==(const ByteQueue &rhs) const;
03995         byte operator[](unsigned long i) const;
03996         void swap(ByteQueue &rhs);
03997 
03998         class Walker : public InputRejecting<BufferedTransformation>
03999         {
04000         public:
04001                 Walker(const ByteQueue &queue)
04002                         : m_queue(queue) {Initialize();}
04003 
04004                 unsigned long GetCurrentPosition() {return m_position;}
04005 
04006                 unsigned long MaxRetrievable() const
04007                         {return m_queue.CurrentSize() - m_position;}
04008 
04009                 void IsolatedInitialize(const NameValuePairs &parameters);
04010 
04011                 unsigned int Get(byte &outByte);
04012                 unsigned int Get(byte *outString, unsigned int getMax);
04013 
04014                 unsigned int Peek(byte &outByte) const;
04015                 unsigned int Peek(byte *outString, unsigned int peekMax) const;
04016 
04017                 unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
04018                 unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
04019 
04020         private:
04021                 const ByteQueue &m_queue;
04022                 const ByteQueueNode *m_node;
04023                 unsigned long m_position;
04024                 unsigned int m_offset;
04025                 const byte *m_lazyString;
04026                 unsigned int m_lazyLength;
04027         };
04028 
04029         friend class Walker;
04030 
04031 private:
04032         void CleanupUsedNodes();
04033         void CopyFrom(const ByteQueue &copy);
04034         void Destroy();
04035 
04036         bool m_autoNodeSize;
04037         unsigned int m_nodeSize;
04038         ByteQueueNode *m_head, *m_tail;
04039         byte *m_lazyString;
04040         unsigned int m_lazyLength;
04041         bool m_lazyStringModifiable;
04042 };
04043 
04044 NAMESPACE_END
04045 
04046 NAMESPACE_BEGIN(std)
04047 template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b)
04048 {
04049         a.swap(b);
04050 }
04051 NAMESPACE_END
04052 
04053 #endif
04054 ////////////////////////////////////////////////////////////////////////////////
04055 
04056 
04057 ////////////////////////////////////////////////////////////////////////////////
04058 #ifndef CRYPTOPP_ALGPARAM_H
04059 #define CRYPTOPP_ALGPARAM_H
04060 
04061 //- #include "cryptlib.h"
04062 //- #include "smartptr.h"
04063 //- #include "secblock.h"
04064 
04065 NAMESPACE_BEGIN(CryptoPP)
04066 
04067 //! used to pass byte array input as part of a NameValuePairs object
04068 /*! the deepCopy option is used when the NameValuePairs object can't
04069         keep a copy of the data available */
04070 class ConstByteArrayParameter
04071 {
04072 public:
04073         ConstByteArrayParameter(const char *data = NULL, bool deepCopy = false)
04074         {
04075                 Assign((const byte *)data, data ? strlen(data) : 0, deepCopy);
04076         }
04077         ConstByteArrayParameter(const byte *data, unsigned int size, bool deepCopy = false)
04078         {
04079                 Assign(data, size, deepCopy);
04080         }
04081         template <class T> ConstByteArrayParameter(const T &string, bool deepCopy = false)
04082         {
04083 //        CRYPTOPP_COMPILE_ASSERT(sizeof(CPP_TYPENAME T::value_type) == 1);
04084                 Assign((const byte *)string.data(), string.size(), deepCopy);
04085         }
04086 
04087         void Assign(const byte *data, unsigned int size, bool deepCopy)
04088         {
04089                 if (deepCopy)
04090                         m_block.Assign(data, size);
04091                 else
04092                 {
04093                         m_data = data;
04094                         m_size = size;
04095                 }
04096                 m_deepCopy = deepCopy;
04097         }
04098 
04099         const byte *begin() const {return m_deepCopy ? m_block.begin() : m_data;}
04100         const byte *end() const {return m_deepCopy ? m_block.end() : m_data + m_size;}
04101         unsigned int size() const {return m_deepCopy ? m_block.size() : m_size;}
04102 
04103 private:
04104         bool m_deepCopy;
04105         const byte *m_data;
04106         unsigned int m_size;
04107         SecByteBlock m_block;
04108 };
04109 
04110 class ByteArrayParameter
04111 {
04112 public:
04113         ByteArrayParameter(byte *data = NULL, unsigned int size = 0)
04114                 : m_data(data), m_size(size) {}
04115         ByteArrayParameter(SecByteBlock &block)
04116                 : m_data(block.begin()), m_size(block.size()) {}
04117 
04118         byte *begin() const {return m_data;}
04119         byte *end() const {return m_data + m_size;}
04120         unsigned int size() const {return m_size;}
04121 
04122 private:
04123         byte *m_data;
04124         unsigned int m_size;
04125 };
04126 
04127 class CRYPTOPP_DLL CombinedNameValuePairs : public NameValuePairs
04128 {
04129 public:
04130         CombinedNameValuePairs(const NameValuePairs &pairs1, const NameValuePairs &pairs2)
04131                 : m_pairs1(pairs1), m_pairs2(pairs2) {}
04132 
04133         bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
04134 
04135 private:
04136         const NameValuePairs &m_pairs1, &m_pairs2;
04137 };
04138 
04139 template <class T, class BASE>
04140 class GetValueHelperClass
04141 {
04142 public:
04143         GetValueHelperClass(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst)
04144                 : m_pObject(pObject), m_name(name), m_valueType(&valueType), m_pValue(pValue), m_found(false), m_getValueNames(false)
04145         {
04146                 if (strcmp(m_name, "ValueNames") == 0)
04147                 {
04148                         m_found = m_getValueNames = true;
04149                         NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(std::string), *m_valueType);
04150                         if (searchFirst)
04151                                 searchFirst->GetVoidValue(m_name, valueType, pValue);
04152                         if (typeid(T) != typeid(BASE))
04153                                 pObject->BASE::GetVoidValue(m_name, valueType, pValue);
04154                         ((*reinterpret_cast<std::string *>(m_pValue) += "ThisPointer:") += typeid(T).name()) += ';';
04155                 }
04156 
04157                 if (!m_found && strncmp(m_name, "ThisPointer:", 12) == 0 && strcmp(m_name+12, typeid(T).name()) == 0)
04158                 {
04159                         NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T *), *m_valueType);
04160                         *reinterpret_cast<const T **>(pValue) = pObject;
04161                         m_found = true;
04162                         return;
04163                 }
04164 
04165                 if (!m_found && searchFirst)
04166                         m_found = searchFirst->GetVoidValue(m_name, valueType, pValue);
04167 
04168                 if (!m_found && typeid(T) != typeid(BASE))
04169                         m_found = pObject->BASE::GetVoidValue(m_name, valueType, pValue);
04170         }
04171 
04172         operator bool() const {return m_found;}
04173 
04174         template <class R>
04175         GetValueHelperClass<T,BASE> & operator()(const char *name, const R & (T::*pm)() const)
04176         {
04177                 if (m_getValueNames)
04178                         (*reinterpret_cast<std::string *>(m_pValue) += name) += ";";
04179                 if (!m_found && strcmp(name, m_name) == 0)
04180                 {
04181                         NameValuePairs::ThrowIfTypeMismatch(name, typeid(R), *m_valueType);
04182                         *reinterpret_cast<R *>(m_pValue) = (m_pObject->*pm)();
04183                         m_found = true;
04184                 }
04185                 return *this;
04186         }
04187 
04188         GetValueHelperClass<T,BASE> &Assignable()
04189         {
04190                 if (m_getValueNames)
04191                         ((*reinterpret_cast<std::string *>(m_pValue) += "ThisObject:") += typeid(T).name()) += ';';
04192                 if (!m_found && strncmp(m_name, "ThisObject:", 11) == 0 && strcmp(m_name+11, typeid(T).name()) == 0)
04193                 {
04194                         NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T), *m_valueType);
04195                         *reinterpret_cast<T *>(m_pValue) = *m_pObject;
04196                         m_found = true;
04197                 }
04198                 return *this;
04199         }
04200 
04201 private:
04202         const T *m_pObject;
04203         const char *m_name;
04204         const std::type_info *m_valueType;
04205         void *m_pValue;
04206         bool m_found, m_getValueNames;
04207 };
04208 
04209 template <class BASE, class T>
04210 GetValueHelperClass<T, BASE> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL, BASE* /* dummy */ = NULL)
04211 {
04212         return GetValueHelperClass<T, BASE>(pObject, name, valueType, pValue, searchFirst);
04213 }
04214 
04215 template <class T>
04216 GetValueHelperClass<T, T> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL)
04217 {
04218         return GetValueHelperClass<T, T>(pObject, name, valueType, pValue, searchFirst);
04219 }
04220 
04221 // ********************************************************
04222 
04223 template <class R>
04224 R Hack_DefaultValueFromConstReferenceType(const R &)
04225 {
04226         return R();
04227 }
04228 
04229 template <class R>
04230 bool Hack_GetValueIntoConstReference(const NameValuePairs &source, const char *name, const R &value)
04231 {
04232         return source.GetValue(name, const_cast<R &>(value));
04233 }
04234 
04235 template <class T, class BASE>
04236 class AssignFromHelperClass
04237 {
04238 public:
04239         AssignFromHelperClass(T *pObject, const NameValuePairs &source)
04240                 : m_pObject(pObject), m_source(source), m_done(false)
04241         {
04242                 if (source.GetThisObject(*pObject))
04243                         m_done = true;
04244                 else if (typeid(BASE) != typeid(T))
04245                         pObject->BASE::AssignFrom(source);
04246         }
04247 
04248         template <class R>
04249         AssignFromHelperClass & operator()(const char *name, void (T::*pm)(R))  // VC60 workaround: "const R &" here causes compiler error
04250         {
04251                 if (!m_done)
04252                 {
04253                         R value = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<R>(*(int *)NULL));
04254                         if (!Hack_GetValueIntoConstReference(m_source, name, value))
04255                                 throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name + "'");
04256                         (m_pObject->*pm)(value);
04257                 }
04258                 return *this;
04259         }
04260 
04261         template <class R, class S>
04262         AssignFromHelperClass & operator()(const char *name1, const char *name2, void (T::*pm)(R, S))   // VC60 workaround: "const R &" here causes compiler error
04263         {
04264                 if (!m_done)
04265                 {
04266                         R value1 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<R>(*(int *)NULL));
04267                         if (!Hack_GetValueIntoConstReference(m_source, name1, value1))
04268                                 throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name1 + "'");
04269                         S value2 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<S>(*(int *)NULL));
04270                         if (!Hack_GetValueIntoConstReference(m_source, name2, value2))
04271                                 throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name2 + "'");
04272                         (m_pObject->*pm)(value1, value2);
04273                 }
04274                 return *this;
04275         }
04276 
04277 private:
04278         T *m_pObject;
04279         const NameValuePairs &m_source;
04280         bool m_done;
04281 };
04282 
04283 template <class BASE, class T>
04284 AssignFromHelperClass<T, BASE> AssignFromHelper(T *pObject, const NameValuePairs &source, BASE* /* dummy */ = NULL)
04285 {
04286         return AssignFromHelperClass<T, BASE>(pObject, source);
04287 }
04288 
04289 template <class T>
04290 AssignFromHelperClass<T, T> AssignFromHelper(T *pObject, const NameValuePairs &source)
04291 {
04292         return AssignFromHelperClass<T, T>(pObject, source);
04293 }
04294 
04295 // ********************************************************
04296 
04297 // This should allow the linker to discard Integer code if not needed.
04298 CRYPTOPP_DLL extern bool (*AssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt);
04299 
04300 CRYPTOPP_DLL const std::type_info & IntegerTypeId();
04301 
04302 class CRYPTOPP_DLL AlgorithmParametersBase : public NameValuePairs
04303 {
04304 public:
04305         class ParameterNotUsed : public Exception
04306         {
04307         public:
04308                 ParameterNotUsed(const char *name) : Exception(OTHER_ERROR, std::string("AlgorithmParametersBase: parameter \"") + name + "\" not used") {}
04309         };
04310 
04311         AlgorithmParametersBase(const char *name, bool throwIfNotUsed)
04312                 : m_name(name), m_throwIfNotUsed(throwIfNotUsed), m_used(false) {}
04313 
04314         ~AlgorithmParametersBase()
04315         {
04316 #ifdef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
04317                 if (!std::uncaught_exception())
04318 #else
04319                 try
04320 #endif
04321                 {
04322                         if (m_throwIfNotUsed && !m_used)
04323                                 throw ParameterNotUsed(m_name);
04324                 }
04325 #ifndef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
04326                 catch(...)
04327                 {
04328                 }
04329 #endif
04330         }
04331 
04332         bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
04333 
04334 protected:
04335         virtual void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const =0;
04336         virtual const NameValuePairs & GetParent() const =0;
04337 
04338         const char *m_name;
04339         bool m_throwIfNotUsed;
04340         mutable bool m_used;
04341 };
04342 
04343 template <class T>
04344 class AlgorithmParametersBase2 : public AlgorithmParametersBase
04345 {
04346 public:
04347         AlgorithmParametersBase2(const char *name, const T &value, bool throwIfNotUsed) : AlgorithmParametersBase(name, throwIfNotUsed), m_value(value) {}
04348 
04349         void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const
04350         {
04351                 // special case for retrieving an Integer parameter when an int was passed in
04352                 if (!(AssignIntToInteger != NULL && typeid(T) == typeid(int) && AssignIntToInteger(valueType, pValue, &m_value)))
04353                 {
04354                         ThrowIfTypeMismatch(name, typeid(T), valueType);
04355                         *reinterpret_cast<T *>(pValue) = m_value;
04356                 }
04357         }
04358 
04359 protected:
04360         T m_value;
04361 };
04362 
04363 template <class PARENT, class T>
04364 class AlgorithmParameters : public AlgorithmParametersBase2<T>
04365 {
04366 public:
04367         AlgorithmParameters(const PARENT &parent, const char *name, const T &value, bool throwIfNotUsed)
04368                 : AlgorithmParametersBase2<T>(name, value, throwIfNotUsed), m_parent(parent)
04369         {}
04370 
04371         AlgorithmParameters(const AlgorithmParameters &copy)
04372                 : AlgorithmParametersBase2<T>(copy), m_parent(copy.m_parent)
04373         {
04374                 copy.m_used = true;
04375         }
04376 
04377         template <class R>
04378         AlgorithmParameters<AlgorithmParameters<PARENT,T>, R> operator()(const char *name, const R &value) const
04379         {
04380                 return AlgorithmParameters<AlgorithmParameters<PARENT,T>, R>(*this, name, value, this->m_throwIfNotUsed);
04381         }
04382 
04383         template <class R>
04384         AlgorithmParameters<AlgorithmParameters<PARENT,T>, R> operator()(const char *name, const R &value, bool throwIfNotUsed) const
04385         {
04386                 return AlgorithmParameters<AlgorithmParameters<PARENT,T>, R>(*this, name, value, throwIfNotUsed);
04387         }
04388 
04389 private:
04390         const NameValuePairs & GetParent() const {return m_parent;}
04391         PARENT m_parent;
04392 };
04393 
04394 //! Create an object that implements NameValuePairs for passing parameters
04395 /*! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
04396         \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(),
04397         such as MSVC 7.0 and earlier.
04398         \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by
04399         repeatedly using operator() on the object returned by MakeParameters, for example:
04400         const NameValuePairs &parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
04401 */
04402 template <class T>
04403 AlgorithmParameters<NullNameValuePairs,T> MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true)
04404 {
04405         return AlgorithmParameters<NullNameValuePairs,T>(g_nullNameValuePairs, name, value, throwIfNotUsed);
04406 }
04407 
04408 #define CRYPTOPP_GET_FUNCTION_ENTRY(name)               (Name::name(), &ThisClass::Get##name)
04409 #define CRYPTOPP_SET_FUNCTION_ENTRY(name)               (Name::name(), &ThisClass::Set##name)
04410 #define CRYPTOPP_SET_FUNCTION_ENTRY2(name1, name2)      (Name::name1(), Name::name2(), &ThisClass::Set##name1##And##name2)
04411 
04412 NAMESPACE_END
04413 
04414 #endif
04415 ////////////////////////////////////////////////////////////////////////////////
04416 
04417 
04418 ////////////////////////////////////////////////////////////////////////////////
04419 #ifndef CRYPTOPP_FILTERS_H
04420 #define CRYPTOPP_FILTERS_H
04421 
04422 //- #include "simple.h"
04423 //- #include "secblock.h"
04424 //- #include "misc.h"
04425 //- #include "smartptr.h"
04426 //- #include "queue.h"
04427 //- #include "algparam.h"
04428 
04429 NAMESPACE_BEGIN(CryptoPP)
04430 
04431 /// provides an implementation of BufferedTransformation's attachment interface
04432 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Filter : public BufferedTransformation, public NotCopyable
04433 {
04434 public:
04435         Filter(BufferedTransformation *attachment = NULL);
04436 
04437         bool Attachable() {return true;}
04438         BufferedTransformation *AttachedTransformation();
04439         const BufferedTransformation *AttachedTransformation() const;
04440         void Detach(BufferedTransformation *newAttachment = NULL);
04441 
04442         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
04443         unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
04444 
04445         void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
04446         bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
04447         bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
04448 
04449 protected:
04450         virtual BufferedTransformation * NewDefaultAttachment() const;
04451         void Insert(Filter *nextFilter);        // insert filter after this one
04452 
04453         virtual bool ShouldPropagateMessageEnd() const {return true;}
04454         virtual bool ShouldPropagateMessageSeriesEnd() const {return true;}
04455 
04456         void PropagateInitialize(const NameValuePairs &parameters, int propagation);
04457 
04458         unsigned int Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL);
04459         unsigned int OutputModifiable(int outputSite, byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL);
04460         bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
04461         bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
04462         bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
04463 
04464 private:
04465         member_ptr<BufferedTransformation> m_attachment;
04466 
04467 protected:
04468         unsigned int m_inputPosition;
04469         int m_continueAt;
04470 };
04471 
04472 struct CRYPTOPP_DLL FilterPutSpaceHelper
04473 {
04474         // desiredSize is how much to ask target, bufferSize is how much to allocate in m_tempSpace
04475         byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize, unsigned int desiredSize, unsigned int &bufferSize)
04476         {
04477                 assert(desiredSize >= minSize && bufferSize >= minSize);
04478                 if (m_tempSpace.size() < minSize)
04479                 {
04480                         byte *result = target.ChannelCreatePutSpace(channel, desiredSize);
04481                         if (desiredSize >= minSize)
04482                         {
04483                                 bufferSize = desiredSize;
04484                                 return result;
04485                         }
04486                         m_tempSpace.New(bufferSize);
04487                 }
04488 
04489                 bufferSize = m_tempSpace.size();
04490                 return m_tempSpace.begin();
04491         }
04492         byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize)
04493                 {return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);}
04494         byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize, unsigned int bufferSize)
04495                 {return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);}
04496         SecByteBlock m_tempSpace;
04497 };
04498 
04499 /*! FilterWithBufferedInput divides up the input stream into
04500         a first block, a number of middle blocks, and a last block.
04501         First and last blocks are optional, and middle blocks may
04502         be a stream instead (i.e. blockSize == 1).
04503 */
04504 class CRYPTOPP_DLL FilterWithBufferedInput : public Filter
04505 {
04506 public:
04507         FilterWithBufferedInput(BufferedTransformation *attachment);
04508         //! firstSize and lastSize may be 0, blockSize must be at least 1
04509         FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *attachment);
04510 
04511         void IsolatedInitialize(const NameValuePairs &parameters);
04512         unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
04513         {
04514                 return PutMaybeModifiable(const_cast<byte *>(inString), length, messageEnd, blocking, false);
04515         }
04516         unsigned int PutModifiable2(byte *inString, unsigned int length, int messageEnd, bool blocking)
04517         {
04518                 return PutMaybeModifiable(inString, length, messageEnd, blocking, true);
04519         }
04520         /*! calls ForceNextPut() if hardFlush is true */
04521         bool IsolatedFlush(bool hardFlush, bool blocking);
04522 
04523         /*! The input buffer may contain more than blockSize bytes if lastSize != 0.
04524                 ForceNextPut() forces a call to NextPut() if this is the case.
04525         */
04526         void ForceNextPut();
04527 
04528 protected:
04529         bool DidFirstPut() {return m_firstInputDone;}
04530 
04531         virtual void InitializeDerivedAndReturnNewSizes(const NameValuePairs& parameters, unsigned int& /* firstSize */, unsigned int& /* blockSize */, unsigned int& /* lastSize */)
04532                 {InitializeDerived(parameters);}
04533         virtual void InitializeDerived(const NameValuePairs& /* parameters */) {}
04534         // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize)
04535         // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received))
04536         virtual void FirstPut(const byte *inString) =0;
04537         // NextPut() is called if totalLength >= firstSize+blockSize+lastSize
04538         virtual void NextPutSingle(const byte* /* inString */) {assert(false);}
04539         // Same as NextPut() except length can be a multiple of blockSize
04540         // Either NextPut() or NextPutMultiple() must be overriden
04541         virtual void NextPutMultiple(const byte *inString, unsigned int length);
04542         // Same as NextPutMultiple(), but inString can be modified
04543         virtual void NextPutModifiable(byte *inString, unsigned int length)
04544                 {NextPutMultiple(inString, length);}
04545         // LastPut() is always called
04546         // if totalLength < firstSize then length == totalLength
04547         // else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
04548         // else lastSize <= length < lastSize+blockSize
04549         virtual void LastPut(const byte *inString, unsigned int length) =0;
04550         virtual void FlushDerived() {}
04551 
04552 private:
04553         unsigned int PutMaybeModifiable(byte *begin, unsigned int length, int messageEnd, bool blocking, bool modifiable);
04554         void NextPutMaybeModifiable(byte *inString, unsigned int length, bool modifiable)
04555         {
04556                 if (modifiable) NextPutModifiable(inString, length);
04557                 else NextPutMultiple(inString, length);
04558         }
04559 
04560         // This function should no longer be used, put this here to cause a compiler error
04561         // if someone tries to override NextPut().
04562         virtual int NextPut(const byte* /* inString */, unsigned int /* length */) {assert(false); return 0;}
04563 
04564         class BlockQueue
04565         {
04566         public:
04567                 void ResetQueue(unsigned int blockSize, unsigned int maxBlocks);
04568                 byte *GetBlock();
04569                 byte *GetContigousBlocks(unsigned int &numberOfBytes);
04570                 unsigned int GetAll(byte *outString);
04571                 void Put(const byte *inString, unsigned int length);
04572                 unsigned int CurrentSize() const {return m_size;}
04573                 unsigned int MaxSize() const {return m_buffer.size();}
04574 
04575         private:
04576                 SecByteBlock m_buffer;
04577                 unsigned int m_blockSize, m_maxBlocks, m_size;
04578                 byte *m_begin;
04579         };
04580 
04581         unsigned int m_firstSize, m_blockSize, m_lastSize;
04582         bool m_firstInputDone;
04583         BlockQueue m_queue;
04584 };
04585 
04586 //! Filter Wrapper for HashTransformation
04587 class CRYPTOPP_DLL HashFilter : public Bufferless<Filter>, private FilterPutSpaceHelper
04588 {
04589 public:
04590         HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false)
04591                 : m_hashModule(hm), m_putMessage(putMessage) {Detach(attachment);}
04592 
04593         void IsolatedInitialize(const NameValuePairs &parameters);
04594         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
04595 
04596         byte * CreatePutSpace(unsigned int &size) {return m_hashModule.CreateUpdateSpace(size);}
04597 
04598 private:
04599         HashTransformation &m_hashModule;
04600         bool m_putMessage;
04601         byte *m_space;
04602 };
04603 
04604 // Used By ProxyFilter
04605 class CRYPTOPP_DLL OutputProxy : public CustomSignalPropagation<Sink>
04606 {
04607 public:
04608         OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {}
04609 
04610         bool GetPassSignal() const {return m_passSignal;}
04611         void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
04612 
04613         byte * CreatePutSpace(unsigned int &size)
04614                 {return m_owner.AttachedTransformation()->CreatePutSpace(size);}
04615         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
04616                 {return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
04617         unsigned int PutModifiable2(byte *begin, unsigned int length, int messageEnd, bool blocking)
04618                 {return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
04619         void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
04620                 {if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);}
04621         bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
04622                 {return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;}
04623         bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
04624                 {return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;}
04625 
04626         unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
04627                 {return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
04628         unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
04629                 {return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
04630         bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
04631                 {return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
04632         bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
04633                 {return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
04634 
04635 private:
04636         BufferedTransformation &m_owner;
04637         bool m_passSignal;
04638 };
04639 
04640 //! Base class for Filter classes that are proxies for a chain of other filters.
04641 class CRYPTOPP_DLL ProxyFilter : public FilterWithBufferedInput
04642 {
04643 public:
04644         ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment);
04645 
04646         bool IsolatedFlush(bool hardFlush, bool blocking);
04647 
04648         void SetFilter(Filter *filter);
04649         void NextPutMultiple(const byte *s, unsigned int len);
04650         void NextPutModifiable(byte *inString, unsigned int length);
04651 
04652 protected:
04653         member_ptr<BufferedTransformation> m_filter;
04654 };
04655 
04656 //! simple proxy filter that doesn't modify the underlying filter's input or output
04657 class CRYPTOPP_DLL SimpleProxyFilter : public ProxyFilter
04658 {
04659 public:
04660         SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment)
04661                 : ProxyFilter(filter, 0, 0, attachment) {}
04662 
04663         void FirstPut(const byte *) {}
04664         void LastPut(const byte *, unsigned int) {m_filter->MessageEnd();}
04665 };
04666 
04667 //! Append input to a string object
04668 template <class T>
04669 class StringSinkTemplate : public Bufferless<Sink>
04670 {
04671 public:
04672         // VC60 workaround: no T::char_type
04673         typedef typename T::traits_type::char_type char_type;
04674 
04675         StringSinkTemplate(T &output)
04676                 : m_output(&output) {assert(sizeof(output[0])==1);}
04677 
04678         void IsolatedInitialize(const NameValuePairs &parameters)
04679                 {if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
04680 
04681         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
04682         {
04683                 if (length > 0)
04684                 {
04685                         typename T::size_type size = m_output->size();
04686                         if (length < size && size + length > m_output->capacity())
04687                                 m_output->reserve(2*size);
04688                 m_output->append((const char_type *)begin, (const char_type *)begin+length);
04689                 }
04690                 return 0;
04691         }
04692 
04693 private:
04694         T *m_output;
04695 };
04696 
04697 //! Append input to an std::string
04698 typedef StringSinkTemplate<std::string> StringSink;
04699 
04700 //! Copy input to a memory buffer
04701 class CRYPTOPP_DLL ArraySink : public Bufferless<Sink>
04702 {
04703 public:
04704         ArraySink(const NameValuePairs &parameters = g_nullNameValuePairs) {IsolatedInitialize(parameters);}
04705         ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {}
04706 
04707         unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);}
04708         unsigned long TotalPutLength() {return m_total;}
04709 
04710         void IsolatedInitialize(const NameValuePairs &parameters);
04711         byte * CreatePutSpace(unsigned int &size);
04712         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
04713 
04714 protected:
04715         byte *m_buf;
04716         unsigned int m_size;
04717         unsigned long m_total;
04718 };
04719 
04720 //! Xor input to a memory buffer
04721 class CRYPTOPP_DLL ArrayXorSink : public ArraySink
04722 {
04723 public:
04724         ArrayXorSink(byte *buf, unsigned int size)
04725                 : ArraySink(buf, size) {}
04726 
04727         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
04728         byte * CreatePutSpace(unsigned int &size) {return BufferedTransformation::CreatePutSpace(size);}
04729 };
04730 
04731 //! string-based implementation of Store interface
04732 class StringStore : public Store
04733 {
04734 public:
04735         StringStore(const char *string = NULL)
04736                 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
04737         StringStore(const byte *string, unsigned int length)
04738                 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
04739         template <class T> StringStore(const T &string)
04740                 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
04741 
04742         CRYPTOPP_DLL unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
04743         CRYPTOPP_DLL unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
04744 
04745 private:
04746         CRYPTOPP_DLL void StoreInitialize(const NameValuePairs &parameters);
04747 
04748         const byte *m_store;
04749         unsigned int m_length, m_count;
04750 };
04751 
04752 //! A Filter that pumps data into its attachment as input
04753 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting<Filter>
04754 {
04755 public:
04756         Source(BufferedTransformation *attachment = NULL)
04757                 {Source::Detach(attachment);}
04758 
04759         unsigned long Pump(unsigned long pumpMax=ULONG_MAX)
04760                 {Pump2(pumpMax); return pumpMax;}
04761         unsigned int PumpMessages(unsigned int count=UINT_MAX)
04762                 {PumpMessages2(count); return count;}
04763         void PumpAll()
04764                 {PumpAll2();}
04765         virtual unsigned int Pump2(unsigned long &byteCount, bool blocking=true) =0;
04766         virtual unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true) =0;
04767         virtual unsigned int PumpAll2(bool blocking=true);
04768         virtual bool SourceExhausted() const =0;
04769 
04770 protected:
04771         void SourceInitialize(bool pumpAll, const NameValuePairs &parameters)
04772         {
04773                 IsolatedInitialize(parameters);
04774                 if (pumpAll)
04775                         PumpAll();
04776         }
04777 };
04778 
04779 //! Turn a Store into a Source
04780 template <class T>
04781 class SourceTemplate : public Source
04782 {
04783 public:
04784         SourceTemplate<T>(BufferedTransformation *attachment)
04785                 : Source(attachment) {}
04786         void IsolatedInitialize(const NameValuePairs &parameters)
04787                 {m_store.IsolatedInitialize(parameters);}
04788         unsigned int Pump2(unsigned long &byteCount, bool blocking=true)
04789                 {return m_store.TransferTo2(*AttachedTransformation(), byteCount, NULL_CHANNEL, blocking);}
04790         unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true)
04791                 {return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, NULL_CHANNEL, blocking);}
04792         unsigned int PumpAll2(bool blocking=true)
04793                 {return m_store.TransferAllTo2(*AttachedTransformation(), NULL_CHANNEL, blocking);}
04794         bool SourceExhausted() const
04795                 {return !m_store.AnyRetrievable() && !m_store.AnyMessages();}
04796         void SetAutoSignalPropagation(int propagation)
04797                 {m_store.SetAutoSignalPropagation(propagation);}
04798         int GetAutoSignalPropagation() const
04799                 {return m_store.GetAutoSignalPropagation();}
04800 
04801 protected:
04802         T m_store;
04803 };
04804 
04805 //! string-based implementation of Source interface
04806 class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore>
04807 {
04808 public:
04809         StringSource(BufferedTransformation *attachment = NULL)
04810                 : SourceTemplate<StringStore>(attachment) {}
04811         StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
04812                 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
04813         StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
04814                 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
04815         StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
04816                 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
04817 };
04818 
04819 NAMESPACE_END
04820 
04821 #endif
04822 ////////////////////////////////////////////////////////////////////////////////
04823 
04824 
04825 
04826 ////////////////////////////////////////////////////////////////////////////////
04827 #ifndef CRYPTOPP_ARGNAMES_H
04828 #define CRYPTOPP_ARGNAMES_H
04829 
04830 //- #include "cryptlib.h"
04831 
04832 NAMESPACE_BEGIN(CryptoPP)
04833 
04834 DOCUMENTED_NAMESPACE_BEGIN(Name)
04835 
04836 #define CRYPTOPP_DEFINE_NAME_STRING(name)       inline const char *name() {return #name;}
04837 
04838 CRYPTOPP_DEFINE_NAME_STRING(ValueNames)                 //!< string, a list of value names with a semicolon (';') after each name
04839 CRYPTOPP_DEFINE_NAME_STRING(Version)                    //!< int
04840 CRYPTOPP_DEFINE_NAME_STRING(Seed)                               //!< ConstByteArrayParameter
04841 CRYPTOPP_DEFINE_NAME_STRING(Key)                                //!< ConstByteArrayParameter
04842 CRYPTOPP_DEFINE_NAME_STRING(IV)                                 //!< const byte *
04843 CRYPTOPP_DEFINE_NAME_STRING(StolenIV)                   //!< byte *
04844 CRYPTOPP_DEFINE_NAME_STRING(Rounds)                             //!< int
04845 CRYPTOPP_DEFINE_NAME_STRING(FeedbackSize)               //!< int
04846 CRYPTOPP_DEFINE_NAME_STRING(WordSize)                   //!< int, in bytes
04847 CRYPTOPP_DEFINE_NAME_STRING(BlockSize)                  //!< int, in bytes
04848 CRYPTOPP_DEFINE_NAME_STRING(EffectiveKeyLength) //!< int, in bits
04849 CRYPTOPP_DEFINE_NAME_STRING(KeySize)                    //!< int, in bits
04850 CRYPTOPP_DEFINE_NAME_STRING(ModulusSize)                //!< int, in bits
04851 CRYPTOPP_DEFINE_NAME_STRING(SubgroupOrderSize)  //!< int, in bits
04852 CRYPTOPP_DEFINE_NAME_STRING(PrivateExponentSize)//!< int, in bits
04853 CRYPTOPP_DEFINE_NAME_STRING(Modulus)                    //!< Integer
04854 CRYPTOPP_DEFINE_NAME_STRING(PublicExponent)             //!< Integer
04855 CRYPTOPP_DEFINE_NAME_STRING(PrivateExponent)    //!< Integer
04856 CRYPTOPP_DEFINE_NAME_STRING(PublicElement)              //!< Integer
04857 CRYPTOPP_DEFINE_NAME_STRING(SubgroupOrder)              //!< Integer
04858 CRYPTOPP_DEFINE_NAME_STRING(Cofactor)                   //!< Integer
04859 CRYPTOPP_DEFINE_NAME_STRING(SubgroupGenerator)  //!< Integer, ECP::Point, or EC2N::Point
04860 CRYPTOPP_DEFINE_NAME_STRING(Curve)                              //!< ECP or EC2N
04861 CRYPTOPP_DEFINE_NAME_STRING(GroupOID)                   //!< OID
04862 CRYPTOPP_DEFINE_NAME_STRING(PointerToPrimeSelector)             //!< const PrimeSelector *
04863 CRYPTOPP_DEFINE_NAME_STRING(Prime1)                             //!< Integer
04864 CRYPTOPP_DEFINE_NAME_STRING(Prime2)                             //!< Integer
04865 CRYPTOPP_DEFINE_NAME_STRING(ModPrime1PrivateExponent)   //!< Integer
04866 CRYPTOPP_DEFINE_NAME_STRING(ModPrime2PrivateExponent)   //!< Integer
04867 CRYPTOPP_DEFINE_NAME_STRING(MultiplicativeInverseOfPrime2ModPrime1)     //!< Integer
04868 CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime1)  //!< Integer
04869 CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime2)  //!< Integer
04870 CRYPTOPP_DEFINE_NAME_STRING(PutMessage)                 //!< bool
04871 CRYPTOPP_DEFINE_NAME_STRING(HashVerificationFilterFlags)                //!< word32
04872 CRYPTOPP_DEFINE_NAME_STRING(SignatureVerificationFilterFlags)   //!< word32
04873 CRYPTOPP_DEFINE_NAME_STRING(InputBuffer)                //!< ConstByteArrayParameter
04874 CRYPTOPP_DEFINE_NAME_STRING(OutputBuffer)               //!< ByteArrayParameter
04875 CRYPTOPP_DEFINE_NAME_STRING(XMACC_Counter)              //!< word32
04876 CRYPTOPP_DEFINE_NAME_STRING(InputFileName)              //!< const char *
04877 CRYPTOPP_DEFINE_NAME_STRING(InputStreamPointer) //!< std::istream *
04878 CRYPTOPP_DEFINE_NAME_STRING(InputBinaryMode)    //!< bool
04879 CRYPTOPP_DEFINE_NAME_STRING(OutputFileName)             //!< const char *
04880 CRYPTOPP_DEFINE_NAME_STRING(OutputStreamPointer)        //!< std::ostream *
04881 CRYPTOPP_DEFINE_NAME_STRING(OutputBinaryMode)   //!< bool
04882 CRYPTOPP_DEFINE_NAME_STRING(EncodingParameters) //!< ConstByteArrayParameter
04883 CRYPTOPP_DEFINE_NAME_STRING(KeyDerivationParameters)    //!< ConstByteArrayParameter
04884 CRYPTOPP_DEFINE_NAME_STRING(Separator)                  //< ConstByteArrayParameter
04885 CRYPTOPP_DEFINE_NAME_STRING(Terminator)                 //< ConstByteArrayParameter
04886 CRYPTOPP_DEFINE_NAME_STRING(Uppercase)                  //< bool
04887 CRYPTOPP_DEFINE_NAME_STRING(GroupSize)                  //< int
04888 CRYPTOPP_DEFINE_NAME_STRING(Pad)                                //< bool
04889 CRYPTOPP_DEFINE_NAME_STRING(PaddingByte)                //< byte
04890 CRYPTOPP_DEFINE_NAME_STRING(Log2Base)                   //< int
04891 CRYPTOPP_DEFINE_NAME_STRING(EncodingLookupArray)        //< const byte *
04892 CRYPTOPP_DEFINE_NAME_STRING(DecodingLookupArray)        //< const byte *
04893 CRYPTOPP_DEFINE_NAME_STRING(InsertLineBreaks)   //< bool
04894 CRYPTOPP_DEFINE_NAME_STRING(MaxLineLength)              //< int
04895 
04896 DOCUMENTED_NAMESPACE_END
04897 
04898 NAMESPACE_END
04899 
04900 #endif
04901 ////////////////////////////////////////////////////////////////////////////////
04902 
04903 
04904 ////////////////////////////////////////////////////////////////////////////////
04905 // pubkey.h - written and placed in the public domain by Wei Dai
04906 
04907 #ifndef CRYPTOPP_PUBKEY_H
04908 #define CRYPTOPP_PUBKEY_H
04909 
04910 /** \file
04911 
04912         This file contains helper classes/functions for implementing public key algorithms.
04913 
04914         The class hierachies in this .h file tend to look like this:
04915 <pre>
04916                   x1
04917                  / \
04918                 y1  z1
04919                  |  |
04920             x2<y1>  x2<z1>
04921                  |  |
04922                 y2  z2
04923                  |  |
04924             x3<y2>  x3<z2>
04925                  |  |
04926                 y3  z3
04927 </pre>
04928         - x1, y1, z1 are abstract interface classes defined in cryptlib.h
04929         - x2, y2, z2 are implementations of the interfaces using "abstract policies", which
04930           are pure virtual functions that should return interfaces to interchangeable algorithms.
04931           These classes have "Base" suffixes.
04932         - x3, y3, z3 hold actual algorithms and implement those virtual functions.
04933           These classes have "Impl" suffixes.
04934 
04935         The "TF_" prefix means an implementation using trapdoor functions on integers.
04936         The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard).
04937 */
04938 
04939 //- #include "modarith.h"
04940 //- #include "filters.h"
04941 //- #include "eprecomp.h"
04942 //- #include "fips140.h"
04943 //- #include "argnames.h"
04944 #include <memory>
04945 
04946 // VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file
04947 #undef INTERFACE
04948 
04949 NAMESPACE_BEGIN(CryptoPP)
04950 
04951 //! _
04952 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
04953 {
04954 public:
04955         virtual ~TrapdoorFunctionBounds() {}
04956 
04957         virtual Integer PreimageBound() const =0;
04958         virtual Integer ImageBound() const =0;
04959         virtual Integer MaxPreimage() const {return --PreimageBound();}
04960         virtual Integer MaxImage() const {return --ImageBound();}
04961 };
04962 
04963 //! _
04964 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
04965 {
04966 public:
04967         virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
04968         virtual bool IsRandomized() const {return true;}
04969 };
04970 
04971 //! _
04972 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
04973 {
04974 public:
04975         Integer ApplyRandomizedFunction(RandomNumberGenerator& /* rng */, const Integer &x) const
04976                 {return ApplyFunction(x);}
04977         bool IsRandomized() const {return false;}
04978 
04979         virtual Integer ApplyFunction(const Integer &x) const =0;
04980 };
04981 
04982 //! _
04983 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
04984 {
04985 public:
04986         virtual ~RandomizedTrapdoorFunctionInverse() {}
04987 
04988         virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
04989         virtual bool IsRandomized() const {return true;}
04990 };
04991 
04992 //! _
04993 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
04994 {
04995 public:
04996         virtual ~TrapdoorFunctionInverse() {}
04997 
04998         Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
04999                 {return CalculateInverse(rng, x);}
05000         bool IsRandomized() const {return false;}
05001 
05002         virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
05003 };
05004 
05005 // ********************************************************
05006 
05007 //! message encoding method for public key encryption
05008 class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
05009 {
05010 public:
05011         virtual ~PK_EncryptionMessageEncodingMethod() {}
05012 
05013         virtual bool ParameterSupported(const char* /* name */) const {return false;}
05014 
05015         //! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
05016         virtual unsigned int MaxUnpaddedLength(unsigned int paddedLength) const =0;
05017 
05018         virtual void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedBitLength, const NameValuePairs &parameters) const =0;
05019 
05020         virtual DecodingResult Unpad(const byte *padded, unsigned int paddedBitLength, byte *raw, const NameValuePairs &parameters) const =0;
05021 };
05022 
05023 // ********************************************************
05024 
05025 //! _
05026 template <class TFI, class MEI>
05027 class CRYPTOPP_NO_VTABLE TF_Base
05028 {
05029 protected:
05030         virtual ~TF_Base() {}
05031 
05032         virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
05033 
05034         typedef TFI TrapdoorFunctionInterface;
05035         virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
05036 
05037         typedef MEI MessageEncodingInterface;
05038         virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
05039 };
05040 
05041 // ********************************************************
05042 
05043 typedef std::pair<const byte *, unsigned int> HashIdentifier;
05044 
05045 //! interface for message encoding method for public key signature schemes
05046 class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
05047 {
05048 public:
05049         virtual ~PK_SignatureMessageEncodingMethod() {}
05050 
05051         virtual unsigned int MaxRecoverableLength(unsigned int /* representativeBitLength */, unsigned int /* hashIdentifierLength */, unsigned int /* digestLength */) const
05052                 {return 0;}
05053 
05054         bool IsProbabilistic() const
05055                 {return true;}
05056         bool AllowNonrecoverablePart() const
05057                 {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
05058         virtual bool RecoverablePartFirst() const
05059                 {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
05060 
05061         // for verification, DL
05062         virtual void ProcessSemisignature(HashTransformation& /* hash */, const byte* /* semisignature */, unsigned int /* semisignatureLength */) const {}
05063 
05064         // for signature
05065         virtual void ProcessRecoverableMessage(HashTransformation& /* hash */,
05066                 const byte* /* recoverableMessage */, unsigned int /* recoverableMessageLength */,
05067                 const byte* /* presignature */, unsigned int /* presignatureLength */,
05068                 SecByteBlock& /* semisignature */) const
05069         {
05070                 if (RecoverablePartFirst())
05071                         assert(!"ProcessRecoverableMessage() not implemented");
05072         }
05073 
05074         virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
05075                 const byte *recoverableMessage, unsigned int recoverableMessageLength,
05076                 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
05077                 byte *representative, unsigned int representativeBitLength) const =0;
05078 
05079         virtual bool VerifyMessageRepresentative(
05080                 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
05081                 byte *representative, unsigned int representativeBitLength) const =0;
05082 
05083         virtual DecodingResult RecoverMessageFromRepresentative(        // for TF
05084                 HashTransformation& /* hash */, HashIdentifier /* hashIdentifier */, bool /* messageEmpty */,
05085                 byte* /* representative */, unsigned int /* representativeBitLength */,
05086                 byte* /* recoveredMessage */) const
05087                 {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
05088 
05089         virtual DecodingResult RecoverMessageFromSemisignature(         // for DL
05090                 HashTransformation& /* hash */, HashIdentifier /* hashIdentifier */,
05091                 const byte* /* presignature */, unsigned int /* presignatureLength */,
05092                 const byte* /* semisignature */, unsigned int /* semisignatureLength */,
05093                 byte* /* recoveredMessage */) const
05094                 {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
05095 
05096         // VC60 workaround
05097         struct HashIdentifierLookup
05098         {
05099                 template <class H> struct HashIdentifierLookup2
05100                 {
05101                         static HashIdentifier Lookup()
05102                         {
05103                                 return HashIdentifier(NULL, 0);
05104                         }
05105                 };
05106         };
05107 };
05108 
05109 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
05110 {
05111 public:
05112         bool VerifyMessageRepresentative(
05113                 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
05114                 byte *representative, unsigned int representativeBitLength) const;
05115 };
05116 
05117 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
05118 {
05119 public:
05120         PK_MessageAccumulatorBase() : m_empty(true) {}
05121 
05122         virtual HashTransformation & AccessHash() =0;
05123 
05124         void Update(const byte *input, unsigned int length)
05125         {
05126                 AccessHash().Update(input, length);
05127                 m_empty = m_empty && length == 0;
05128         }
05129 
05130         SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
05131         Integer m_k, m_s;
05132         bool m_empty;
05133 };
05134 
05135 template <class HASH_ALGORITHM>
05136 class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
05137 {
05138 public:
05139         HashTransformation & AccessHash() {return this->m_object;}
05140 };
05141 
05142 //! _
05143 template <class INTERFACE, class BASE>
05144 class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTERFACE, protected BASE
05145 {
05146 public:
05147         unsigned int SignatureLength() const
05148                 {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
05149         unsigned int MaxRecoverableLength() const
05150                 {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
05151         unsigned int MaxRecoverableLengthFromSignatureLength(unsigned int /* signatureLength */) const
05152                 {return this->MaxRecoverableLength();}
05153 
05154         bool IsProbabilistic() const
05155                 {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
05156         bool AllowNonrecoverablePart() const
05157                 {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
05158         bool RecoverablePartFirst() const
05159                 {return this->GetMessageEncodingInterface().RecoverablePartFirst();}
05160 
05161 protected:
05162         unsigned int MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
05163         unsigned int MessageRepresentativeBitLength() const {return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
05164         virtual HashIdentifier GetHashIdentifier() const =0;
05165         virtual unsigned int GetDigestSize() const =0;
05166 };
05167 
05168 //! _
05169 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
05170 {
05171 public:
05172         void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const;
05173         unsigned int SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
05174 };
05175 
05176 //! _
05177 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
05178 {
05179 public:
05180         void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const;
05181         bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
05182         DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
05183 };
05184 
05185 // ********************************************************
05186 
05187 //! _
05188 template <class T1, class T2, class T3>
05189 struct TF_CryptoSchemeOptions
05190 {
05191         typedef T1 AlgorithmInfo;
05192         typedef T2 Keys;
05193         typedef typename Keys::PrivateKey PrivateKey;
05194         typedef typename Keys::PublicKey PublicKey;
05195         typedef T3 MessageEncodingMethod;
05196 };
05197 
05198 //! _
05199 template <class T1, class T2, class T3, class T4>
05200 struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3>
05201 {
05202         typedef T4 HashFunction;
05203 };
05204 
05205 //! _
05206 template <class KEYS>
05207 class CRYPTOPP_NO_VTABLE PublicKeyCopier
05208 {
05209 public:
05210         virtual ~PublicKeyCopier() {}
05211 
05212         typedef typename KEYS::PublicKey KeyClass;
05213         virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0;
05214 };
05215 
05216 //! _
05217 template <class KEYS>
05218 class CRYPTOPP_NO_VTABLE PrivateKeyCopier
05219 {
05220 public:
05221         virtual ~PrivateKeyCopier() {}
05222 
05223         typedef typename KEYS::PrivateKey KeyClass;
05224         virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0;
05225         virtual void CopyKeyInto(typename KEYS::PrivateKey &key) const =0;
05226 };
05227 
05228 //! _
05229 template <class BASE, class SCHEME_OPTIONS, class KEY>
05230 class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
05231 {
05232 public:
05233         typedef SCHEME_OPTIONS SchemeOptions;
05234         typedef KEY KeyClass;
05235 
05236         PublicKey & AccessPublicKey() {return AccessKey();}
05237         const PublicKey & GetPublicKey() const {return GetKey();}
05238 
05239         PrivateKey & AccessPrivateKey() {return AccessKey();}
05240         const PrivateKey & GetPrivateKey() const {return GetKey();}
05241 
05242         virtual const KeyClass & GetKey() const =0;
05243         virtual KeyClass & AccessKey() =0;
05244 
05245         const KeyClass & GetTrapdoorFunction() const {return GetKey();}
05246 
05247         PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator& /* rng */) const
05248         {
05249                 return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
05250         }
05251         PK_MessageAccumulator * NewVerificationAccumulator() const
05252         {
05253                 return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
05254         }
05255 
05256 protected:
05257         const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
05258                 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
05259         const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
05260                 {return GetKey();}
05261         const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
05262                 {return GetKey();}
05263 
05264         // for signature scheme
05265         HashIdentifier GetHashIdentifier() const
05266         {
05267         typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
05268         return L::Lookup();
05269         }
05270         unsigned int GetDigestSize() const
05271         {
05272                 typedef CPP_TYPENAME SchemeOptions::HashFunction H;
05273                 return H::DIGESTSIZE;
05274         }
05275 };
05276 
05277 //! _
05278 template <class BASE, class SCHEME_OPTIONS, class KEY_COPIER>
05279 class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<TwoBases<BASE, KEY_COPIER>, SCHEME_OPTIONS, typename KEY_COPIER::KeyClass>
05280 {
05281 public:
05282         typedef typename KEY_COPIER::KeyClass KeyClass;
05283 
05284         const KeyClass & GetKey() const {return m_trapdoorFunction;}
05285         KeyClass & AccessKey() {return m_trapdoorFunction;}
05286 
05287         void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const {key = GetKey();}
05288         void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {key = GetKey();}
05289 
05290 private:
05291         KeyClass m_trapdoorFunction;
05292 };
05293 
05294 //! _
05295 template <class SCHEME_OPTIONS>
05296 class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, PrivateKeyCopier<typename SCHEME_OPTIONS::Keys> >
05297 {
05298 };
05299 
05300 //! _
05301 template <class SCHEME_OPTIONS>
05302 class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, PublicKeyCopier<typename SCHEME_OPTIONS::Keys> >
05303 {
05304 };
05305 
05306 // ********************************************************
05307 
05308 CRYPTOPP_DLL void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength, bool mask, unsigned int counterStart);
05309 
05310 // ********************************************************
05311 
05312 //! _
05313 template <class H>
05314 class P1363_KDF2
05315 {
05316 public:
05317         static void DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength)
05318         {
05319                 H h;
05320                 P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
05321         }
05322 };
05323 
05324 // ********************************************************
05325 
05326 //! A template implementing constructors for public key algorithm classes
05327 template <class BASE>
05328 class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
05329 {
05330 public:
05331         PK_FinalTemplate() {}
05332 
05333         PK_FinalTemplate(const Integer &v1)
05334                 {this->AccessKey().Initialize(v1);}
05335 
05336         PK_FinalTemplate(const typename BASE::KeyClass &key)  {this->AccessKey().operator=(key);}
05337 
05338         template <class T>
05339         PK_FinalTemplate(const PublicKeyCopier<T> &key)
05340                 {key.CopyKeyInto(this->AccessKey());}
05341 
05342         template <class T>
05343         PK_FinalTemplate(const PrivateKeyCopier<T> &key)
05344                 {key.CopyKeyInto(this->AccessKey());}
05345 
05346         PK_FinalTemplate(BufferedTransformation &bt) {this->AccessKey().BERDecode(bt);}
05347 
05348 #if (defined(_MSC_VER) && _MSC_VER < 1300)
05349 
05350         template <class T1, class T2>
05351         PK_FinalTemplate(T1 &v1, T2 &v2)
05352                 {this->AccessKey().Initialize(v1, v2);}
05353 
05354         template <class T1, class T2, class T3>
05355         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
05356                 {this->AccessKey().Initialize(v1, v2, v3);}
05357 
05358         template <class T1, class T2, class T3, class T4>
05359         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
05360                 {this->AccessKey().Initialize(v1, v2, v3, v4);}
05361 
05362         template <class T1, class T2, class T3, class T4, class T5>
05363         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
05364                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
05365 
05366         template <class T1, class T2, class T3, class T4, class T5, class T6>
05367         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
05368                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
05369 
05370         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
05371         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
05372                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
05373 
05374         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
05375         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
05376                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
05377 
05378 #else
05379 
05380         template <class T1, class T2>
05381         PK_FinalTemplate(const T1 &v1, const T2 &v2)
05382                 {this->AccessKey().Initialize(v1, v2);}
05383 
05384         template <class T1, class T2, class T3>
05385         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
05386                 {this->AccessKey().Initialize(v1, v2, v3);}
05387 
05388         template <class T1, class T2, class T3, class T4>
05389         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
05390                 {this->AccessKey().Initialize(v1, v2, v3, v4);}
05391 
05392         template <class T1, class T2, class T3, class T4, class T5>
05393         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
05394                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
05395 
05396         template <class T1, class T2, class T3, class T4, class T5, class T6>
05397         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
05398                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
05399 
05400         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
05401         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
05402                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
05403 
05404         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
05405         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8)
05406                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
05407 
05408         template <class T1, class T2>
05409         PK_FinalTemplate(T1 &v1, const T2 &v2)
05410                 {this->AccessKey().Initialize(v1, v2);}
05411 
05412         template <class T1, class T2, class T3>
05413         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
05414                 {this->AccessKey().Initialize(v1, v2, v3);}
05415 
05416         template <class T1, class T2, class T3, class T4>
05417         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
05418                 {this->AccessKey().Initialize(v1, v2, v3, v4);}
05419 
05420         template <class T1, class T2, class T3, class T4, class T5>
05421         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
05422                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
05423 
05424         template <class T1, class T2, class T3, class T4, class T5, class T6>
05425         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
05426                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
05427 
05428         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
05429         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
05430                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
05431 
05432         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
05433         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8)
05434                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
05435 
05436 #endif
05437 };
05438 
05439 //! Base class for public key encryption standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
05440 struct EncryptionStandard {};
05441 
05442 //! Base class for public key signature standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
05443 struct SignatureStandard {};
05444 
05445 template <class STANDARD, class H, class KEYS, class ALG_INFO>  // VC60 workaround: doesn't work if KEYS is first parameter
05446 class TF_SS;
05447 
05448 //! Trapdoor Function Based Signature Scheme
05449 template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> > // VC60 workaround: doesn't work if KEYS is first parameter
05450 class TF_SS : public KEYS
05451 {
05452 public:
05453         //! see SignatureStandard for a list of standards
05454         typedef STANDARD Standard;
05455         typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
05456         typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
05457 
05458         static std::string StaticAlgorithmName() {return KEYS::StaticAlgorithmName() + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
05459 
05460         //! implements PK_Signer interface
05461         typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
05462         //! implements PK_Verifier interface
05463         typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
05464 };
05465 
05466 NAMESPACE_END
05467 
05468 #endif
05469 ////////////////////////////////////////////////////////////////////////////////
05470 
05471 
05472 
05473 ////////////////////////////////////////////////////////////////////////////////
05474 #ifndef CRYPTOPP_ITERHASH_H
05475 #define CRYPTOPP_ITERHASH_H
05476 
05477 //- #include "cryptlib.h"
05478 //- #include "secblock.h"
05479 //- #include "misc.h"
05480 //- #include "simple.h"
05481 
05482 NAMESPACE_BEGIN(CryptoPP)
05483 
05484 //! _
05485 template <class T, class BASE>
05486 class CRYPTOPP_NO_VTABLE IteratedHashBase : public BASE
05487 {
05488 public:
05489         typedef T HashWordType;
05490 
05491         IteratedHashBase() : m_countLo(0), m_countHi(0) {}
05492         unsigned int BlockSize() const {return m_data.size() * sizeof(T);}
05493         unsigned int OptimalBlockSize() const {return BlockSize();}
05494         unsigned int OptimalDataAlignment() const {return sizeof(T);}
05495         void Update(const byte *input, unsigned int length);
05496         byte * CreateUpdateSpace(unsigned int &size);
05497         void Restart();
05498 
05499 protected:
05500         void SetBlockSize(unsigned int blockSize) {m_data.resize(blockSize / sizeof(HashWordType));}
05501         void SetStateSize(unsigned int stateSize) {m_digest.resize(stateSize / sizeof(HashWordType));}
05502 
05503         T GetBitCountHi() const {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);}
05504         T GetBitCountLo() const {return m_countLo << 3;}
05505 
05506         virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length);
05507         void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80);
05508         virtual void Init() =0;
05509         virtual void HashBlock(const T *input) =0;
05510 
05511         SecBlock<T> m_data;                     // Data buffer
05512         SecBlock<T> m_digest;           // Message digest
05513 
05514 private:
05515         T m_countLo, m_countHi;
05516 };
05517 
05518 
05519 //! _
05520 template <class T, class B, class BASE>
05521 class CRYPTOPP_NO_VTABLE IteratedHashBase2 : public IteratedHashBase<T, BASE>
05522 {
05523 public:
05524         typedef B ByteOrderClass;
05525         typedef typename IteratedHashBase<T, BASE>::HashWordType HashWordType;
05526 
05527         inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, unsigned int byteCount)
05528         {
05529                 ConditionalByteReverse(B::ToEnum(), out, in, byteCount);
05530         }
05531 
05532         void TruncatedFinal(byte *digest, unsigned int size);
05533 
05534 protected:
05535         void HashBlock(const HashWordType *input);
05536         virtual void HashEndianCorrectedBlock(const HashWordType *data) =0;
05537 };
05538 
05539 //! _
05540 template <class T_HashWordType, class T_Endianness, unsigned int T_BlockSize, class T_Base = HashTransformation>
05541 class CRYPTOPP_NO_VTABLE IteratedHash : public IteratedHashBase2<T_HashWordType, T_Endianness, T_Base>
05542 {
05543 public:
05544         enum {BLOCKSIZE = T_BlockSize};
05545         CRYPTOPP_COMPILE_ASSERT_GLOBAL((BLOCKSIZE & (BLOCKSIZE - 1)) == 0);             // blockSize is a power of 2
05546 
05547 protected:
05548         IteratedHash()
05549                 : IteratedHashBase2<T_HashWordType, T_Endianness, T_Base>()
05550         {this->SetBlockSize(T_BlockSize);}
05551 };
05552 
05553 //! _
05554 template <class T_HashWordType, class T_Endianness, unsigned int T_BlockSize, unsigned int T_StateSize, class T_Transform, unsigned int T_DigestSize = T_StateSize>
05555 class CRYPTOPP_NO_VTABLE IteratedHashWithStaticTransform
05556         : public ClonableImpl<T_Transform, AlgorithmImpl<IteratedHash<T_HashWordType, T_Endianness, T_BlockSize>, T_Transform> >
05557 {
05558 public:
05559         enum {DIGESTSIZE = T_DigestSize};
05560         unsigned int DigestSize() const {return DIGESTSIZE;};
05561 
05562 protected:
05563         IteratedHashWithStaticTransform()
05564         {
05565                 this->SetStateSize(T_StateSize);
05566                 Init();
05567         }
05568         void HashEndianCorrectedBlock(const T_HashWordType *data) {T_Transform::Transform(this->m_digest, data);}
05569         void Init() {T_Transform::InitState(this->m_digest);}
05570 };
05571 
05572 // *************************************************************
05573 
05574 template <class T, class B, class BASE> void IteratedHashBase2<T, B, BASE>::TruncatedFinal(byte *digest, unsigned int size)
05575 {
05576         this->ThrowIfInvalidTruncatedSize(size);
05577 
05578         PadLastBlock(this->BlockSize() - 2*sizeof(HashWordType));
05579         CorrectEndianess(this->m_data, this->m_data, this->BlockSize() - 2*sizeof(HashWordType));
05580 
05581         this->m_data[this->m_data.size()-2] = B::ToEnum() ? this->GetBitCountHi() : this->GetBitCountLo();
05582         this->m_data[this->m_data.size()-1] = B::ToEnum() ? this->GetBitCountLo() : this->GetBitCountHi();
05583 
05584         HashEndianCorrectedBlock(this->m_data);
05585         CorrectEndianess(this->m_digest, this->m_digest, this->DigestSize());
05586         memcpy(digest, this->m_digest, size);
05587 
05588         this->Restart();                // reinit for next use
05589 }
05590 
05591 template <class T, class B, class BASE> void IteratedHashBase2<T, B, BASE>::HashBlock(const HashWordType *input)
05592 {
05593         if (NativeByteOrderIs(B::ToEnum()))
05594                 HashEndianCorrectedBlock(input);
05595         else
05596         {
05597                 ByteReverse(this->m_data.begin(), input, this->BlockSize());
05598                 HashEndianCorrectedBlock(this->m_data);
05599         }
05600 }
05601 
05602 NAMESPACE_END
05603 
05604 #endif
05605 ////////////////////////////////////////////////////////////////////////////////
05606 
05607 
05608 
05609 ////////////////////////////////////////////////////////////////////////////////
05610 #ifndef CRYPTOPP_SHA_H
05611 #define CRYPTOPP_SHA_H
05612 
05613 //- #include "iterhash.h"
05614 
05615 NAMESPACE_BEGIN(CryptoPP)
05616 
05617 /// <a href="http://www.weidai.com/scan-mirror/md.html#SHA-1">SHA-1</a>
05618 class CRYPTOPP_DLL SHA : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 20, SHA>
05619 {
05620 public:
05621         static void InitState(HashWordType *state);
05622         static void Transform(word32 *digest, const word32 *data);
05623         static const char *StaticAlgorithmName() {return "SHA-1";}
05624 };
05625 
05626 typedef SHA SHA1;
05627 
05628 NAMESPACE_END
05629 
05630 #endif
05631 ////////////////////////////////////////////////////////////////////////////////
05632 
05633 
05634 
05635 ////////////////////////////////////////////////////////////////////////////////
05636 #ifndef CRYPTOPP_PKCSPAD_H
05637 #define CRYPTOPP_PKCSPAD_H
05638 
05639 //- #include "cryptlib.h"
05640 //- #include "pubkey.h"
05641 
05642 #ifdef CRYPTOPP_IS_DLL
05643 //- #include "sha.h"
05644 #endif
05645 
05646 NAMESPACE_BEGIN(CryptoPP)
05647 
05648 //! <a href="http://www.weidai.com/scan-mirror/ca.html#cem_PKCS1-1.5">EME-PKCS1-v1_5</a>
05649 class PKCS_EncryptionPaddingScheme : public PK_EncryptionMessageEncodingMethod
05650 {
05651 public:
05652         static const char * StaticAlgorithmName() {return "EME-PKCS1-v1_5";}
05653 
05654         unsigned int MaxUnpaddedLength(unsigned int paddedLength) const;
05655         void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedLength, const NameValuePairs &parameters) const;
05656         DecodingResult Unpad(const byte *padded, unsigned int paddedLength, byte *raw, const NameValuePairs &parameters) const;
05657 };
05658 
05659 template <class H> class PKCS_DigestDecoration
05660 {
05661 public:
05662         static const byte decoration[];
05663         static const unsigned int length;
05664 };
05665 
05666 // PKCS_DigestDecoration can be instantiated with the following
05667 // classes as specified in PKCS#1 v2.0 and P1363a
05668 class SHA;
05669 // end of list
05670 
05671 //! <a href="http://www.weidai.com/scan-mirror/sig.html#sem_PKCS1-1.5">EMSA-PKCS1-v1_5</a>
05672 class CRYPTOPP_DLL PKCS1v15_SignatureMessageEncodingMethod : public PK_DeterministicSignatureMessageEncodingMethod
05673 {
05674 public:
05675         static const char * StaticAlgorithmName() {return "EMSA-PKCS1-v1_5";}
05676 
05677         void ComputeMessageRepresentative(RandomNumberGenerator &rng,
05678                 const byte *recoverableMessage, unsigned int recoverableMessageLength,
05679                 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
05680                 byte *representative, unsigned int representativeBitLength) const;
05681 
05682         struct HashIdentifierLookup
05683         {
05684                 template <class H> struct HashIdentifierLookup2
05685                 {
05686                         static HashIdentifier Lookup()
05687                         {
05688                                 return HashIdentifier(PKCS_DigestDecoration<H>::decoration, PKCS_DigestDecoration<H>::length);
05689                         }
05690                 };
05691         };
05692 };
05693 
05694 //! PKCS #1 version 1.5, for use with RSAES and RSASS
05695 /*! Only the following hash functions are supported by this signature standard:
05696         \dontinclude pkcspad.h
05697         \skip can be instantiated
05698         \until end of list
05699 */
05700 struct PKCS1v15 : public SignatureStandard, public EncryptionStandard
05701 {
05702         typedef PKCS_EncryptionPaddingScheme EncryptionMessageEncodingMethod;
05703         typedef PKCS1v15_SignatureMessageEncodingMethod SignatureMessageEncodingMethod;
05704 };
05705 
05706 NAMESPACE_END
05707 
05708 #endif
05709 ////////////////////////////////////////////////////////////////////////////////
05710 
05711 
05712 
05713 ////////////////////////////////////////////////////////////////////////////////
05714 #ifndef CRYPTOPP_ASN_H
05715 #define CRYPTOPP_ASN_H
05716 
05717 //- #include "filters.h"
05718 //- #include "queue.h"
05719 #include <vector>
05720 
05721 NAMESPACE_BEGIN(CryptoPP)
05722 
05723 // these tags and flags are not complete
05724 enum ASNTag
05725 {
05726         BOOLEAN                         = 0x01,
05727         INTEGER                         = 0x02,
05728         BIT_STRING                      = 0x03,
05729         OCTET_STRING            = 0x04,
05730         TAG_NULL                        = 0x05,
05731         OBJECT_IDENTIFIER       = 0x06,
05732         OBJECT_DESCRIPTOR       = 0x07,
05733         EXTERNAL                        = 0x08,
05734         REAL                            = 0x09,
05735         ENUMERATED                      = 0x0a,
05736         UTF8_STRING                     = 0x0c,
05737         SEQUENCE                        = 0x10,
05738         SET                             = 0x11,
05739         NUMERIC_STRING          = 0x12,
05740         PRINTABLE_STRING        = 0x13,
05741         T61_STRING                      = 0x14,
05742         VIDEOTEXT_STRING        = 0x15,
05743         IA5_STRING                      = 0x16,
05744         UTC_TIME                        = 0x17,
05745         GENERALIZED_TIME        = 0x18,
05746         GRAPHIC_STRING          = 0x19,
05747         VISIBLE_STRING          = 0x1a,
05748         GENERAL_STRING          = 0x1b
05749 };
05750 
05751 enum ASNIdFlag
05752 {
05753         UNIVERSAL                       = 0x00,
05754 //      DATA                            = 0x01,
05755 //      HEADER                          = 0x02,
05756         CONSTRUCTED             = 0x20,
05757         APPLICATION             = 0x40,
05758         CONTEXT_SPECIFIC        = 0x80,
05759         PRIVATE                         = 0xc0
05760 };
05761 
05762 inline void BERDecodeError() {throw BERDecodeErr();}
05763 
05764 // unsigned int DERLengthEncode(unsigned int length, byte *output=0);
05765 CRYPTOPP_DLL unsigned int DERLengthEncode(BufferedTransformation &out, unsigned int length);
05766 // returns false if indefinite length
05767 CRYPTOPP_DLL bool BERLengthDecode(BufferedTransformation &in, unsigned int &length);
05768 
05769 CRYPTOPP_DLL void DEREncodeNull(BufferedTransformation &out);
05770 CRYPTOPP_DLL void BERDecodeNull(BufferedTransformation &in);
05771 
05772 CRYPTOPP_DLL unsigned int DEREncodeOctetString(BufferedTransformation &out, const byte *str, unsigned int strLen);
05773 CRYPTOPP_DLL unsigned int DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str);
05774 
05775 // BER decode from source and DER reencode into dest
05776 CRYPTOPP_DLL void DERReencode(BufferedTransformation &source, BufferedTransformation &dest);
05777 
05778 //! Object Identifier
05779 class CRYPTOPP_DLL OID
05780 {
05781 public:
05782         OID() {}
05783         OID(unsigned long v) : m_values(1, v) {}
05784         OID(BufferedTransformation &bt) {BERDecode(bt);}
05785 
05786         inline OID & operator+=(unsigned long rhs) {m_values.push_back(rhs); return *this;}
05787 
05788         void DEREncode(BufferedTransformation &bt) const;
05789         void BERDecode(BufferedTransformation &bt);
05790 
05791         // throw BERDecodeErr() if decoded value doesn't equal this OID
05792         void BERDecodeAndCheck(BufferedTransformation &bt) const;
05793 
05794         std::vector<unsigned long> m_values;
05795 
05796 private:
05797         static void EncodeValue(BufferedTransformation &bt, unsigned long v);
05798         static unsigned int DecodeValue(BufferedTransformation &bt, unsigned long &v);
05799 };
05800 
05801 //! BER General Decoder
05802 class CRYPTOPP_DLL BERGeneralDecoder : public Store
05803 {
05804 public:
05805         explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
05806         explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
05807         ~BERGeneralDecoder();
05808 
05809         bool IsDefiniteLength() const {return m_definiteLength;}
05810         unsigned int RemainingLength() const {assert(m_definiteLength); return m_length;}
05811         bool EndReached() const;
05812         byte PeekByte() const;
05813         void CheckByte(byte b);
05814 
05815         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
05816         unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
05817 
05818         // call this to denote end of sequence
05819         void MessageEnd();
05820 
05821 protected:
05822         BufferedTransformation &m_inQueue;
05823         bool m_finished, m_definiteLength;
05824         unsigned int m_length;
05825 
05826 private:
05827         void Init(byte asnTag);
05828         void StoreInitialize(const NameValuePairs& /* parameters */) {assert(false);}
05829         unsigned int ReduceLength(unsigned int delta);
05830 };
05831 
05832 //! DER General Encoder
05833 class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue
05834 {
05835 public:
05836         explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
05837         explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
05838         ~DERGeneralEncoder();
05839 
05840         // call this to denote end of sequence
05841         void MessageEnd();
05842 
05843 private:
05844         BufferedTransformation &m_outQueue;
05845         bool m_finished;
05846 
05847         byte m_asnTag;
05848 };
05849 
05850 //! BER Sequence Decoder
05851 class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder
05852 {
05853 public:
05854         explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
05855                 : BERGeneralDecoder(inQueue, asnTag) {}
05856         explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
05857                 : BERGeneralDecoder(inQueue, asnTag) {}
05858 };
05859 
05860 //! DER Sequence Encoder
05861 class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder
05862 {
05863 public:
05864         explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
05865                 : DERGeneralEncoder(outQueue, asnTag) {}
05866         explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
05867                 : DERGeneralEncoder(outQueue, asnTag) {}
05868 };
05869 
05870 //! key that can be ASN.1 encoded
05871 /** derived class should override either BERDecodeKey or BERDecodeKey2 */
05872 class CRYPTOPP_DLL ASN1Key : public ASN1CryptoMaterial
05873 {
05874 public:
05875         virtual OID GetAlgorithmID() const =0;
05876         virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
05877                 {BERDecodeNull(bt); return false;}
05878         virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
05879                 {DEREncodeNull(bt); return false;}      // see RFC 2459, section 7.3.1
05880         //! decode subjectPublicKey part of subjectPublicKeyInfo, or privateKey part of privateKeyInfo, without the BIT STRING or OCTET STRING header
05881         virtual void BERDecodeKey(BufferedTransformation& /* bt */) {assert(false);}
05882         virtual void BERDecodeKey2(BufferedTransformation& bt, bool /* parametersPresent */, unsigned int /* size */)
05883                 {BERDecodeKey(bt);}
05884         //! encode subjectPublicKey part of subjectPublicKeyInfo, or privateKey part of privateKeyInfo, without the BIT STRING or OCTET STRING header
05885         virtual void DEREncodeKey(BufferedTransformation &bt) const =0;
05886 };
05887 
05888 //! encodes/decodes subjectPublicKeyInfo
05889 class CRYPTOPP_DLL X509PublicKey : virtual public ASN1Key, public PublicKey
05890 {
05891 public:
05892         void BERDecode(BufferedTransformation &bt);
05893         void DEREncode(BufferedTransformation &bt) const;
05894 };
05895 
05896 //! encodes/decodes privateKeyInfo
05897 class CRYPTOPP_DLL PKCS8PrivateKey : virtual public ASN1Key, public PrivateKey
05898 {
05899 public:
05900         void BERDecode(BufferedTransformation &bt);
05901         void DEREncode(BufferedTransformation &bt) const;
05902 
05903         //! decode optional attributes including context-specific tag
05904         /*! /note default implementation stores attributes to be output in DEREncodeOptionalAttributes */
05905         virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt);
05906         //! encode optional attributes including context-specific tag
05907         virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const;
05908 
05909 private:
05910         ByteQueue m_optionalAttributes;
05911 };
05912 
05913 // ********************************************************
05914 
05915 //! DER Encode Unsigned
05916 /*! for INTEGER, BOOLEAN, and ENUM */
05917 template <class T>
05918 unsigned int DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER)
05919 {
05920         byte buf[sizeof(w)+1];
05921         unsigned int bc;
05922         if (asnTag == BOOLEAN)
05923         {
05924                 buf[sizeof(w)] = w ? 0xff : 0;
05925                 bc = 1;
05926         }
05927         else
05928         {
05929                 buf[0] = 0;
05930                 for (unsigned int i=0; i<sizeof(w); i++)
05931                         buf[i+1] = byte(w >> (sizeof(w)-1-i)*8);
05932                 bc = sizeof(w);
05933                 while (bc > 1 && buf[sizeof(w)+1-bc] == 0)
05934                         --bc;
05935                 if (buf[sizeof(w)+1-bc] & 0x80)
05936                         ++bc;
05937         }
05938         out.Put(asnTag);
05939         unsigned int lengthBytes = DERLengthEncode(out, bc);
05940         out.Put(buf+sizeof(w)+1-bc, bc);
05941         return 1+lengthBytes+bc;
05942 }
05943 
05944 //! BER Decode Unsigned
05945 // VC60 workaround: std::numeric_limits<T>::max conflicts with MFC max macro
05946 // CW41 workaround: std::numeric_limits<T>::max causes a template error
05947 template <class T>
05948 void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
05949                                            T minValue = 0, T maxValue = 0xffffffff)
05950 {
05951         byte b;
05952         if (!in.Get(b) || b != asnTag)
05953                 BERDecodeError();
05954 
05955         unsigned int bc;
05956         BERLengthDecode(in, bc);
05957 
05958         SecByteBlock buf(bc);
05959 
05960         if (bc != in.Get(buf, bc))
05961                 BERDecodeError();
05962 
05963         const byte *ptr = buf;
05964         while (bc > sizeof(w) && *ptr == 0)
05965         {
05966                 bc--;
05967                 ptr++;
05968         }
05969         if (bc > sizeof(w))
05970                 BERDecodeError();
05971 
05972         w = 0;
05973         for (unsigned int i=0; i<bc; i++)
05974                 w = (w << 8) | ptr[i];
05975 
05976         if (w < minValue || w > maxValue)
05977                 BERDecodeError();
05978 }
05979 
05980 inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
05981         {return lhs.m_values == rhs.m_values;}
05982 inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
05983         {return lhs.m_values != rhs.m_values;}
05984 inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
05985         {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());}
05986 inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs)
05987         {return ::CryptoPP::OID(lhs)+=rhs;}
05988 
05989 NAMESPACE_END
05990 
05991 #endif
05992 ////////////////////////////////////////////////////////////////////////////////
05993 
05994 
05995 
05996 ////////////////////////////////////////////////////////////////////////////////
05997 #ifndef CRYPTOPP_RSA_H
05998 #define CRYPTOPP_RSA_H
05999 
06000 /** \file
06001         This file contains classes that implement the RSA
06002         ciphers and signature schemes as defined in PKCS #1 v2.0.
06003 */
06004 
06005 //- #include "pkcspad.h"
06006 //- #include "oaep.h"
06007 //- #include "integer.h"
06008 //- #include "asn.h"
06009 
06010 NAMESPACE_BEGIN(CryptoPP)
06011 
06012 //! _
06013 class CRYPTOPP_DLL RSAFunction : public TrapdoorFunction, public X509PublicKey
06014 {
06015         typedef RSAFunction ThisClass;
06016 
06017 public:
06018         void Initialize(const Integer &n, const Integer &e)
06019                 {m_n = n; m_e = e;}
06020 
06021         // X509PublicKey
06022         OID GetAlgorithmID() const;
06023         void BERDecodeKey(BufferedTransformation &bt);
06024         void DEREncodeKey(BufferedTransformation &bt) const;
06025 
06026         // CryptoMaterial
06027         bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
06028         bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
06029         void AssignFrom(const NameValuePairs &source);
06030 
06031         // TrapdoorFunction
06032         Integer ApplyFunction(const Integer &x) const;
06033         Integer PreimageBound() const {return m_n;}
06034         Integer ImageBound() const {return m_n;}
06035 
06036         // non-derived
06037         const Integer & GetModulus() const {return m_n;}
06038         const Integer & GetPublicExponent() const {return m_e;}
06039 
06040         void SetModulus(const Integer &n) {m_n = n;}
06041         void SetPublicExponent(const Integer &e) {m_e = e;}
06042 
06043 protected:
06044         Integer m_n, m_e;
06045 };
06046 
06047 //! _
06048 class CRYPTOPP_DLL InvertibleRSAFunction : public RSAFunction, public TrapdoorFunctionInverse, public PKCS8PrivateKey
06049 {
06050         typedef InvertibleRSAFunction ThisClass;
06051 
06052 public:
06053         void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits, const Integer &e = 17);
06054         void Initialize(const Integer &n, const Integer &e, const Integer &d, const Integer &p, const Integer &q, const Integer &dp, const Integer &dq, const Integer &u)
06055                 {m_n = n; m_e = e; m_d = d; m_p = p; m_q = q; m_dp = dp; m_dq = dq; m_u = u;}
06056         //! factor n given private exponent
06057         void Initialize(const Integer &n, const Integer &e, const Integer &d);
06058 
06059         // PKCS8PrivateKey
06060         void BERDecode(BufferedTransformation &bt)
06061                 {PKCS8PrivateKey::BERDecode(bt);}
06062         void DEREncode(BufferedTransformation &bt) const
06063                 {PKCS8PrivateKey::DEREncode(bt);}
06064         void BERDecodeKey(BufferedTransformation &bt);
06065         void DEREncodeKey(BufferedTransformation &bt) const;
06066 
06067         // TrapdoorFunctionInverse
06068         Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const;
06069 
06070         // GeneratableCryptoMaterial
06071         bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
06072         /*! parameters: (ModulusSize, PublicExponent (default 17)) */
06073         void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
06074         bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
06075         void AssignFrom(const NameValuePairs &source);
06076 
06077         // non-derived interface
06078         const Integer& GetPrime1() const {return m_p;}
06079         const Integer& GetPrime2() const {return m_q;}
06080         const Integer& GetPrivateExponent() const {return m_d;}
06081         const Integer& GetModPrime1PrivateExponent() const {return m_dp;}
06082         const Integer& GetModPrime2PrivateExponent() const {return m_dq;}
06083         const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;}
06084 
06085         void SetPrime1(const Integer &p) {m_p = p;}
06086         void SetPrime2(const Integer &q) {m_q = q;}
06087         void SetPrivateExponent(const Integer &d) {m_d = d;}
06088         void SetModPrime1PrivateExponent(const Integer &dp) {m_dp = dp;}
06089         void SetModPrime2PrivateExponent(const Integer &dq) {m_dq = dq;}
06090         void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;}
06091 
06092 protected:
06093         Integer m_d, m_p, m_q, m_dp, m_dq, m_u;
06094 };
06095 
06096 //! RSA
06097 struct CRYPTOPP_DLL RSA
06098 {
06099         static std::string StaticAlgorithmName() {return "RSA";}
06100         typedef RSAFunction PublicKey;
06101         typedef InvertibleRSAFunction PrivateKey;
06102 };
06103 
06104 //! <a href="http://www.weidai.com/scan-mirror/sig.html#RSA">RSA signature scheme with appendix</a>
06105 /*! See documentation of PKCS1v15 for a list of hash functions that can be used with it. */
06106 template <class STANDARD, class H>
06107 struct RSASS : public TF_SS<STANDARD, H, RSA>
06108 {
06109 };
06110 
06111 // The three RSA signature schemes defined in PKCS #1 v2.0
06112 typedef RSASS<PKCS1v15, SHA>::Signer RSASSA_PKCS1v15_SHA_Signer;
06113 typedef RSASS<PKCS1v15, SHA>::Verifier RSASSA_PKCS1v15_SHA_Verifier;
06114 
06115 NAMESPACE_END
06116 
06117 #endif
06118 ////////////////////////////////////////////////////////////////////////////////
06119 
06120 
06121 
06122 ////////////////////////////////////////////////////////////////////////////////
06123 #ifndef CRYPTOPP_BASECODE_H
06124 #define CRYPTOPP_BASECODE_H
06125 
06126 //- #include "filters.h"
06127 //- #include "algparam.h"
06128 //- #include "argnames.h"
06129 
06130 NAMESPACE_BEGIN(CryptoPP)
06131 
06132 //! base n encoder, where n is a power of 2
06133 class CRYPTOPP_DLL BaseN_Encoder : public Unflushable<Filter>
06134 {
06135 public:
06136         BaseN_Encoder(BufferedTransformation *attachment=NULL)
06137                 {Detach(attachment);}
06138 
06139         BaseN_Encoder(const byte *alphabet, int log2base, BufferedTransformation *attachment=NULL, int padding=-1)
06140         {
06141                 Detach(attachment);
06142                 IsolatedInitialize(MakeParameters(Name::EncodingLookupArray(), alphabet)
06143                         (Name::Log2Base(), log2base)
06144                         (Name::Pad(), padding != -1)
06145                         (Name::PaddingByte(), byte(padding)));
06146         }
06147 
06148         void IsolatedInitialize(const NameValuePairs &parameters);
06149         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
06150 
06151 private:
06152         const byte *m_alphabet;
06153         int m_padding, m_bitsPerChar, m_outputBlockSize;
06154         int m_bytePos, m_bitPos;
06155         SecByteBlock m_outBuf;
06156 };
06157 
06158 //! base n decoder, where n is a power of 2
06159 class CRYPTOPP_DLL BaseN_Decoder : public Unflushable<Filter>
06160 {
06161 public:
06162         BaseN_Decoder(BufferedTransformation *attachment=NULL)
06163                 {Detach(attachment);}
06164 
06165         BaseN_Decoder(const int *lookup, int log2base, BufferedTransformation *attachment=NULL)
06166         {
06167                 Detach(attachment);
06168                 IsolatedInitialize(MakeParameters(Name::DecodingLookupArray(), lookup)(Name::Log2Base(), log2base));
06169         }
06170 
06171         void IsolatedInitialize(const NameValuePairs &parameters);
06172         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
06173 
06174         static void InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive);
06175 
06176 private:
06177         const int *m_lookup;
06178         int m_padding, m_bitsPerChar, m_outputBlockSize;
06179         int m_bytePos, m_bitPos;
06180         SecByteBlock m_outBuf;
06181 };
06182 
06183 //! filter that breaks input stream into groups of fixed size
06184 class CRYPTOPP_DLL Grouper : public Bufferless<Filter>
06185 {
06186 public:
06187         Grouper(BufferedTransformation *attachment=NULL)
06188                 {Detach(attachment);}
06189 
06190         Grouper(int groupSize, const std::string &separator, const std::string &terminator, BufferedTransformation *attachment=NULL)
06191         {
06192                 Detach(attachment);
06193                 IsolatedInitialize(MakeParameters(Name::GroupSize(), groupSize)
06194                         (Name::Separator(), ConstByteArrayParameter(separator))
06195                         (Name::Terminator(), ConstByteArrayParameter(terminator)));
06196         }
06197 
06198         void IsolatedInitialize(const NameValuePairs &parameters);
06199         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
06200 
06201 private:
06202         SecByteBlock m_separator, m_terminator;
06203         unsigned int m_groupSize, m_counter;
06204 };
06205 
06206 NAMESPACE_END
06207 
06208 #endif
06209 ////////////////////////////////////////////////////////////////////////////////
06210 
06211 
06212 
06213 ////////////////////////////////////////////////////////////////////////////////
06214 #ifndef CRYPTOPP_BASE64_H
06215 #define CRYPTOPP_BASE64_H
06216 
06217 //- #include "basecode.h"
06218 
06219 NAMESPACE_BEGIN(CryptoPP)
06220 
06221 //! Base64 Encoder Class
06222 class Base64Encoder : public SimpleProxyFilter
06223 {
06224 public:
06225         Base64Encoder(BufferedTransformation *attachment = NULL, bool insertLineBreaks = true, int maxLineLength = 72)
06226                 : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment)
06227         {
06228                 IsolatedInitialize(MakeParameters(Name::InsertLineBreaks(), insertLineBreaks)(Name::MaxLineLength(), maxLineLength));
06229         }
06230 
06231         void IsolatedInitialize(const NameValuePairs &parameters);
06232 };
06233 
06234 //! Base64 Decoder Class
06235 class Base64Decoder : public BaseN_Decoder
06236 {
06237 public:
06238         Base64Decoder(BufferedTransformation *attachment = NULL)
06239                 : BaseN_Decoder(GetDecodingLookupArray(), 6, attachment) {}
06240 
06241         void IsolatedInitialize(const NameValuePairs& /* parameters */) {}
06242 
06243 private:
06244         static const int *GetDecodingLookupArray();
06245 };
06246 
06247 NAMESPACE_END
06248 
06249 #endif
06250 ////////////////////////////////////////////////////////////////////////////////
06251 
06252 
06253 
06254 ////////////////////////////////////////////////////////////////////////////////
06255 #ifndef CRYPTOPP_FILES_H
06256 #define CRYPTOPP_FILES_H
06257 
06258 //- #include "cryptlib.h"
06259 //- #include "filters.h"
06260 //- #include "argnames.h"
06261 
06262 #include <iostream>
06263 #include <fstream>
06264 
06265 NAMESPACE_BEGIN(CryptoPP)
06266 
06267 //! file-based implementation of Store interface
06268 class CRYPTOPP_DLL FileStore : public Store, private FilterPutSpaceHelper, public NotCopyable
06269 {
06270 public:
06271         class Err : public Exception
06272         {
06273         public:
06274                 Err(const std::string &s) : Exception(IO_ERROR, s) {}
06275         };
06276         class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileStore: error opening file for reading: " + filename) {}};
06277         class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}};
06278 
06279         FileStore() : m_stream(NULL) {}
06280         FileStore(std::istream &in)
06281                 {StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));}
06282         FileStore(const char *filename)
06283                 {StoreInitialize(MakeParameters(Name::InputFileName(), filename));}
06284 
06285         std::istream* GetStream() {return m_stream;}
06286 
06287         unsigned long MaxRetrievable() const;
06288         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
06289         unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
06290         unsigned long Skip(unsigned long skipMax=ULONG_MAX);
06291 
06292 private:
06293         void StoreInitialize(const NameValuePairs &parameters);
06294 
06295         member_ptr<std::ifstream> m_file;
06296         std::istream *m_stream;
06297         byte *m_space;
06298         unsigned int m_len;
06299         bool m_waiting;
06300 };
06301 
06302 //! file-based implementation of Source interface
06303 class CRYPTOPP_DLL FileSource : public SourceTemplate<FileStore>
06304 {
06305 public:
06306         typedef FileStore::Err Err;
06307         typedef FileStore::OpenErr OpenErr;
06308         typedef FileStore::ReadErr ReadErr;
06309 
06310         FileSource(BufferedTransformation *attachment = NULL)
06311                 : SourceTemplate<FileStore>(attachment) {}
06312         FileSource(std::istream &in, bool pumpAll, BufferedTransformation *attachment = NULL)
06313                 : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputStreamPointer(), &in));}
06314         FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true)
06315                 : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputFileName(), filename)(Name::InputBinaryMode(), binary));}
06316 
06317         std::istream* GetStream() {return m_store.GetStream();}
06318 };
06319 
06320 //! file-based implementation of Sink interface
06321 class CRYPTOPP_DLL FileSink : public Sink, public NotCopyable
06322 {
06323 public:
06324         class Err : public Exception
06325         {
06326         public:
06327                 Err(const std::string &s) : Exception(IO_ERROR, s) {}
06328         };
06329         class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileSink: error opening file for writing: " + filename) {}};
06330         class WriteErr : public Err {public: WriteErr() : Err("FileSink: error writing file") {}};
06331 
06332         FileSink() : m_stream(NULL) {}
06333         FileSink(std::ostream &out)
06334                 {IsolatedInitialize(MakeParameters(Name::OutputStreamPointer(), &out));}
06335         FileSink(const char *filename, bool binary=true)
06336                 {IsolatedInitialize(MakeParameters(Name::OutputFileName(), filename)("OutputBinaryMode", binary));}
06337 
06338         std::ostream* GetStream() {return m_stream;}
06339 
06340         void IsolatedInitialize(const NameValuePairs &parameters);
06341         unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking);
06342         bool IsolatedFlush(bool hardFlush, bool blocking);
06343 
06344 private:
06345         member_ptr<std::ofstream> m_file;
06346         std::ostream *m_stream;
06347 };
06348 
06349 NAMESPACE_END
06350 
06351 #endif
06352 ////////////////////////////////////////////////////////////////////////////////
06353 
06354 
06355 
06356 ////////////////////////////////////////////////////////////////////////////////
06357 #ifndef CRYPTOPP_RANDPOOL_H
06358 #define CRYPTOPP_RANDPOOL_H
06359 
06360 //- #include "cryptlib.h"
06361 //- #include "filters.h"
06362 
06363 NAMESPACE_BEGIN(CryptoPP)
06364 
06365 //! Randomness Pool
06366 /*! This class can be used to generate
06367         pseudorandom bytes after seeding the pool with
06368         the Put() methods */
06369 class CRYPTOPP_DLL RandomPool : public RandomNumberGenerator,
06370                                    public Bufferless<BufferedTransformation>
06371 {
06372 public:
06373         //! poolSize must be greater than 16
06374         RandomPool(unsigned int poolSize=384);
06375 
06376         unsigned int Put2(const byte *begin, unsigned int, int messageEnd, bool blocking);
06377 
06378         bool AnyRetrievable() const {return true;}
06379         unsigned long MaxRetrievable() const {return ULONG_MAX;}
06380 
06381         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
06382         unsigned int CopyRangeTo2(BufferedTransformation& /* target */, unsigned long& /* begin */, unsigned long /* end */ = ULONG_MAX, const std::string& /* channel */ = NULL_CHANNEL, bool /* blocking */ = true) const
06383         {
06384                 throw NotImplemented("RandomPool: CopyRangeTo2() is not supported by this store");
06385         }
06386 
06387         byte GenerateByte();
06388         void GenerateBlock(byte *output, unsigned int size);
06389 
06390         void IsolatedInitialize(const NameValuePairs& /* parameters */) {}
06391 
06392 protected:
06393         void Stir();
06394 
06395 private:
06396         SecByteBlock pool, key;
06397         unsigned int addPos, getPos;
06398 };
06399 
06400 NAMESPACE_END
06401 
06402 #endif
06403 ////////////////////////////////////////////////////////////////////////////////
06404 
06405 
06406 
06407 ////////////////////////////////////////////////////////////////////////////////
06408 // seckey.h - written and placed in the public domain by Wei Dai
06409 
06410 // This file contains helper classes/functions for implementing secret key algorithms.
06411 
06412 #ifndef CRYPTOPP_SECKEY_H
06413 #define CRYPTOPP_SECKEY_H
06414 
06415 //- #include "cryptlib.h"
06416 //- #include "misc.h"
06417 //- #include "simple.h"
06418 
06419 NAMESPACE_BEGIN(CryptoPP)
06420 
06421 //! to be inherited by block ciphers with fixed block size
06422 template <unsigned int N>
06423 class FixedBlockSize
06424 {
06425 public:
06426         enum {BLOCKSIZE = N};
06427 };
06428 
06429 // ************** key length ***************
06430 
06431 //! to be inherited by keyed algorithms with fixed key length
06432 template <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE>
06433 class FixedKeyLength
06434 {
06435 public:
06436         enum {KEYLENGTH=N, MIN_KEYLENGTH=N, MAX_KEYLENGTH=N, DEFAULT_KEYLENGTH=N};
06437         enum {IV_REQUIREMENT = IV_REQ};
06438         static unsigned int StaticGetValidKeyLength(unsigned int) {return KEYLENGTH;}
06439 };
06440 
06441 // ************** implementation helper for SimpledKeyed ***************
06442 
06443 template <class T>
06444 static inline void CheckedSetKey(T *obj, Empty empty, const byte *key, unsigned int length, const NameValuePairs &param)
06445 {
06446         obj->ThrowIfInvalidKeyLength(length);
06447         obj->UncheckedSetKey(key, length);
06448 }
06449 
06450 template <class T>
06451 static inline void CheckedSetKey(T *obj, CipherDir dir, const byte *key, unsigned int length, const NameValuePairs& /* param */)
06452 {
06453         obj->ThrowIfInvalidKeyLength(length);
06454         obj->UncheckedSetKey(dir, key, length);
06455 }
06456 
06457 //! _
06458 template <class BASE, class INFO = BASE>
06459 class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE
06460 {
06461 public:
06462         unsigned int MinKeyLength() const {return INFO::MIN_KEYLENGTH;}
06463         unsigned int MaxKeyLength() const {return (unsigned int)INFO::MAX_KEYLENGTH;}
06464         unsigned int DefaultKeyLength() const {return INFO::DEFAULT_KEYLENGTH;}
06465         unsigned int GetValidKeyLength(unsigned int n) const {return INFO::StaticGetValidKeyLength(n);}
06466         typename BASE::IV_Requirement IVRequirement() const {return (typename BASE::IV_Requirement)INFO::IV_REQUIREMENT;}
06467 
06468 protected:
06469         void AssertValidKeyLength(unsigned int length) {assert(GetValidKeyLength(length) == length);}
06470 };
06471 
06472 template <class INFO, class BASE = BlockCipher>
06473 class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > >
06474 {
06475 public:
06476         unsigned int BlockSize() const {return this->BLOCKSIZE;}
06477 };
06478 
06479 //! _
06480 template <CipherDir DIR, class BASE>
06481 class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE>
06482 {
06483 public:
06484         BlockCipherFinal() {}
06485         BlockCipherFinal(const byte *key)
06486                 {SetKey(key, this->DEFAULT_KEYLENGTH);}
06487         BlockCipherFinal(const byte *key, unsigned int length)
06488                 {SetKey(key, length);}
06489         BlockCipherFinal(const byte *key, unsigned int length, unsigned int rounds)
06490                 {this->SetKeyWithRounds(key, length, rounds);}
06491 
06492         bool IsForwardTransformation() const {return DIR == ENCRYPTION;}
06493 
06494         void SetKey(const byte *key, unsigned int length, const NameValuePairs &param = g_nullNameValuePairs)
06495         {
06496                 CheckedSetKey(this, DIR, key, length, param);
06497         }
06498 };
06499 
06500 // ************** documentation ***************
06501 
06502 /*! \brief Each class derived from this one defines two types, Encryption and Decryption,
06503         both of which implement the SymmetricCipher interface. Two types of classes derive
06504         from this class: stream ciphers and block cipher modes. Stream ciphers can be used
06505         alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation
06506         for more for information about using cipher modes and block ciphers. */
06507 struct SymmetricCipherDocumentation
06508 {
06509         //! implements the SymmetricCipher interface
06510         typedef SymmetricCipher Encryption;
06511         //! implements the SymmetricCipher interface
06512         typedef SymmetricCipher Decryption;
06513 };
06514 
06515 NAMESPACE_END
06516 
06517 #endif
06518 ////////////////////////////////////////////////////////////////////////////////
06519 
06520 
06521 
06522 ////////////////////////////////////////////////////////////////////////////////
06523 #ifndef CRYPTOPP_OSRNG_H
06524 #define CRYPTOPP_OSRNG_H
06525 
06526 //- #include "config.h"
06527 
06528 #ifdef OS_RNG_AVAILABLE
06529 
06530 //- #include "randpool.h"
06531 //- #include "rng.h"
06532 //- #include "des.h"
06533 //- #include "fips140.h"
06534 
06535 NAMESPACE_BEGIN(CryptoPP)
06536 
06537 //! Exception class for Operating-System Random Number Generator.
06538 class CRYPTOPP_DLL OS_RNG_Err : public Exception
06539 {
06540 public:
06541         OS_RNG_Err(const std::string &operation);
06542 };
06543 
06544 #ifdef NONBLOCKING_RNG_AVAILABLE
06545 
06546 #ifdef CRYPTOPP_WIN32_AVAILABLE
06547 class CRYPTOPP_DLL MicrosoftCryptoProvider
06548 {
06549 public:
06550         MicrosoftCryptoProvider();
06551         ~MicrosoftCryptoProvider();
06552 #if defined(_WIN64)
06553         typedef unsigned __int64 ProviderHandle;        // type HCRYPTPROV, avoid #include <windows.h>
06554 #else
06555         typedef unsigned long ProviderHandle;
06556 #endif
06557         ProviderHandle GetProviderHandle() const {return m_hProvider;}
06558 private:
06559         ProviderHandle m_hProvider;
06560 };
06561 
06562 #pragma comment(lib, "advapi32.lib")
06563 #endif
06564 
06565 //! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom
06566 class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
06567 {
06568 public:
06569         NonblockingRng();
06570         ~NonblockingRng();
06571         byte GenerateByte();
06572         void GenerateBlock(byte *output, unsigned int size);
06573 
06574 protected:
06575 #ifdef CRYPTOPP_WIN32_AVAILABLE
06576 #       ifndef WORKAROUND_MS_BUG_Q258000
06577                 MicrosoftCryptoProvider m_Provider;
06578 #       endif
06579 #else
06580         int m_fd;
06581 #endif
06582 };
06583 
06584 #endif
06585 
06586 #ifdef BLOCKING_RNG_AVAILABLE
06587 
06588 //! encapsulate /dev/random
06589 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
06590 {
06591 public:
06592         BlockingRng();
06593         ~BlockingRng();
06594         byte GenerateByte();
06595         void GenerateBlock(byte *output, unsigned int size);
06596 
06597 protected:
06598         int m_fd;
06599 };
06600 
06601 #endif
06602 
06603 CRYPTOPP_DLL void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size);
06604 
06605 //! Automaticly Seeded Randomness Pool
06606 /*! This class seeds itself using an operating system provided RNG. */
06607 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
06608 {
06609 public:
06610         //! blocking will be ignored if the prefered RNG isn't available
06611         explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
06612                 {Reseed(blocking, seedSize);}
06613         void Reseed(bool blocking = false, unsigned int seedSize = 32);
06614 };
06615 
06616 NAMESPACE_END
06617 
06618 #endif
06619 
06620 #endif
06621 ////////////////////////////////////////////////////////////////////////////////
06622 
06623 #endif
06624 
06625 #endif
06626