added a subset of Crypto++ 5.6.0 with 48% faster ASM SHA-256, combined speedup 2...
author--author=Satoshi Nakamoto <satoshin@gmx.com>
Tue, 27 Jul 2010 20:43:55 +0000 (20:43 +0000)
committerGavin Andresen <gavinandresen@gmail.com>
Tue, 27 Jul 2010 20:43:55 +0000 (20:43 +0000)
26 files changed:
cryptopp/License.txt [new file with mode: 0644]
cryptopp/Readme.txt [new file with mode: 0644]
cryptopp/config.h [new file with mode: 0644]
cryptopp/cpu.cpp [new file with mode: 0644]
cryptopp/cpu.h [new file with mode: 0644]
cryptopp/cryptlib.h [new file with mode: 0644]
cryptopp/iterhash.h [new file with mode: 0644]
cryptopp/misc.h [new file with mode: 0644]
cryptopp/obj/.gitignore [new file with mode: 0644]
cryptopp/pch.h [new file with mode: 0644]
cryptopp/secblock.h [new file with mode: 0644]
cryptopp/sha.cpp [new file with mode: 0644]
cryptopp/sha.h [new file with mode: 0644]
cryptopp/simple.h [new file with mode: 0644]
cryptopp/smartptr.h [new file with mode: 0644]
cryptopp/stdcpp.h [new file with mode: 0644]
main.cpp
makefile.mingw
makefile.osx
makefile.unix
makefile.vc
obj/.gitignore [new file with mode: 0644]
obj/nogui/.gitignore [new file with mode: 0644]
sha.cpp [deleted file]
sha.h [deleted file]
util.h

diff --git a/cryptopp/License.txt b/cryptopp/License.txt
new file mode 100644 (file)
index 0000000..fc3f054
--- /dev/null
@@ -0,0 +1,67 @@
+Compilation Copyright (c) 1995-2009 by Wei Dai.  All rights reserved.
+This copyright applies only to this software distribution package 
+as a compilation, and does not imply a copyright on any particular 
+file in the package.
+
+The following files are copyrighted by their respective original authors,
+and their use is subject to additional licenses included in these files.
+
+mars.cpp - Copyright 1998 Brian Gladman.
+
+All other files in this compilation are placed in the public domain by
+Wei Dai and other contributors.
+
+I would like to thank the following authors for placing their works into
+the public domain:
+
+Joan Daemen - 3way.cpp
+Leonard Janke - cast.cpp, seal.cpp
+Steve Reid - cast.cpp
+Phil Karn - des.cpp
+Andrew M. Kuchling - md2.cpp, md4.cpp
+Colin Plumb - md5.cpp
+Seal Woods - rc6.cpp
+Chris Morgan - rijndael.cpp
+Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp
+Richard De Moliner - safer.cpp
+Matthew Skala - twofish.cpp
+Kevin Springle - camellia.cpp, shacal2.cpp, ttmac.cpp, whrlpool.cpp, ripemd.cpp
+
+Permission to use, copy, modify, and distribute this compilation for
+any purpose, including commercial applications, is hereby granted
+without fee, subject to the following restrictions:
+
+1. Any copy or modification of this compilation in any form, except
+in object code form as part of an application software, must include
+the above copyright notice and this license.
+
+2. Users of this software agree that any modification or extension
+they provide to Wei Dai will be considered public domain and not
+copyrighted unless it includes an explicit copyright notice.
+
+3. Wei Dai makes no warranty or representation that the operation of the
+software in this compilation will be error-free, and Wei Dai is under no
+obligation to provide any services, by way of maintenance, update, or
+otherwise.  THE SOFTWARE AND ANY DOCUMENTATION ARE PROVIDED "AS IS"
+WITHOUT EXPRESS OR IMPLIED WARRANTY INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. IN NO EVENT WILL WEI DAI OR ANY OTHER CONTRIBUTOR BE LIABLE FOR
+DIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+4. Users will not use Wei Dai or any other contributor's name in any 
+publicity or advertising, without prior written consent in each case.
+
+5. Export of this software from the United States may require a
+specific license from the United States Government.  It is the
+responsibility of any person or organization contemplating export
+to obtain such a license before exporting.
+
+6. Certain parts of this software may be protected by patents.  It
+is the users' responsibility to obtain the appropriate
+licenses before using those parts.
+
+If this compilation is used in object code form in an application
+software, acknowledgement of the author is not required but would be
+appreciated. The contribution of any useful modifications or extensions
+to Wei Dai is not required but would also be appreciated.
diff --git a/cryptopp/Readme.txt b/cryptopp/Readme.txt
new file mode 100644 (file)
index 0000000..861c036
--- /dev/null
@@ -0,0 +1,429 @@
+Crypto++: a C++ Class Library of Cryptographic Schemes
+Version 5.6.0 (3/15/2009)
+
+Crypto++ Library is a free C++ class library of cryptographic schemes.
+Currently the library contains the following algorithms:
+
+                   algorithm type  name
+
+ authenticated encryption schemes  GCM, CCM, EAX
+        high speed stream ciphers  Panama, Sosemanuk, Salsa20, XSalsa20
+
+           AES and AES candidates  AES (Rijndael), RC6, MARS, Twofish, Serpent,
+                                   CAST-256
+
+                                   IDEA, Triple-DES (DES-EDE2 and DES-EDE3),
+              other block ciphers  Camellia, SEED, RC5, Blowfish, TEA, XTEA,
+                                   Skipjack, SHACAL-2
+
+  block cipher modes of operation  ECB, CBC, CBC ciphertext stealing (CTS),
+                                   CFB, OFB, counter mode (CTR)
+
+     message authentication codes  VMAC, HMAC, CMAC, CBC-MAC, DMAC, 
+                                   Two-Track-MAC
+
+                                   SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, and
+                   hash functions  SHA-512), Tiger, WHIRLPOOL, RIPEMD-128,
+                                   RIPEMD-256, RIPEMD-160, RIPEMD-320
+
+                                   RSA, DSA, ElGamal, Nyberg-Rueppel (NR),
+          public-key cryptography  Rabin, Rabin-Williams (RW), LUC, LUCELG,
+                                   DLIES (variants of DHAES), ESIGN
+
+   padding schemes for public-key  PKCS#1 v2.0, OAEP, PSS, PSSR, IEEE P1363
+                          systems  EMSA2 and EMSA5
+
+                                   Diffie-Hellman (DH), Unified Diffie-Hellman
+            key agreement schemes  (DH2), Menezes-Qu-Vanstone (MQV), LUCDIF,
+                                   XTR-DH
+
+      elliptic curve cryptography  ECDSA, ECNR, ECIES, ECDH, ECMQV
+
+          insecure or obsolescent  MD2, MD4, MD5, Panama Hash, DES, ARC4, SEAL
+algorithms retained for backwards  3.0, WAKE, WAKE-OFB, DESX (DES-XEX3), RC2,
+     compatibility and historical  SAFER, 3-WAY, GOST, SHARK, CAST-128, Square
+                            value
+
+Other features include:
+
+  * pseudo random number generators (PRNG): ANSI X9.17 appendix C, RandomPool
+  * password based key derivation functions: PBKDF1 and PBKDF2 from PKCS #5,
+    PBKDF from PKCS #12 appendix B
+  * Shamir's secret sharing scheme and Rabin's information dispersal algorithm
+    (IDA)
+  * fast multi-precision integer (bignum) and polynomial operations
+  * finite field arithmetics, including GF(p) and GF(2^n)
+  * prime number generation and verification
+  * useful non-cryptographic algorithms
+      + DEFLATE (RFC 1951) compression/decompression with gzip (RFC 1952) and
+        zlib (RFC 1950) format support
+      + hex, base-32, and base-64 coding/decoding
+      + 32-bit CRC and Adler32 checksum
+  * class wrappers for these operating system features (optional):
+      + high resolution timers on Windows, Unix, and Mac OS
+      + Berkeley and Windows style sockets
+      + Windows named pipes
+      + /dev/random, /dev/urandom, /dev/srandom
+      + Microsoft's CryptGenRandom on Windows
+  * A high level interface for most of the above, using a filter/pipeline
+    metaphor
+  * benchmarks and validation testing
+  * x86, x86-64 (x64), MMX, and SSE2 assembly code for the most commonly used
+    algorithms, with run-time CPU feature detection and code selection
+  * some versions are available in FIPS 140-2 validated form
+
+You are welcome to use it for any purpose without paying me, but see
+License.txt for the fine print.
+
+The following compilers are supported for this release. Please visit
+http://www.cryptopp.com the most up to date build instructions and porting notes.
+
+  * MSVC 6.0 - 2008
+  * GCC 3.3 - 4.3
+  * C++Builder 2009
+  * Intel C++ Compiler 9 - 11
+  * Sun Studio 12 (CC 5.9)
+
+*** Important Usage Notes ***
+
+1. If a constructor for A takes a pointer to an object B (except primitive
+types such as int and char), then A owns B and will delete B at A's
+destruction.  If a constructor for A takes a reference to an object B,
+then the caller retains ownership of B and should not destroy it until
+A no longer needs it. 
+
+2. Crypto++ is thread safe at the class level. This means you can use
+Crypto++ safely in a multithreaded application, but you must provide
+synchronization when multiple threads access a common Crypto++ object.
+
+*** MSVC-Specific Information ***
+
+On Windows, Crypto++ can be compiled into 3 forms: a static library
+including all algorithms, a DLL with only FIPS Approved algorithms, and
+a static library with only algorithms not in the DLL.
+(FIPS Approved means Approved according to the FIPS 140-2 standard.)
+The DLL may be used by itself, or it may be used together with the second
+form of the static library. MSVC project files are included to build
+all three forms, and sample applications using each of the three forms
+are also included.
+
+To compile Crypto++ with MSVC, open the "cryptest.dsw" (for MSVC 6 and MSVC .NET 
+2003) or "cryptest.sln" (for MSVC .NET 2005) workspace file and build one or 
+more of the following projects:
+
+cryptdll - This builds the DLL. Please note that if you wish to use Crypto++
+  as a FIPS validated module, you must use a pre-built DLL that has undergone
+  the FIPS validation process instead of building your own.
+dlltest - This builds a sample application that only uses the DLL.
+cryptest Non-DLL-Import Configuration - This builds the full static library
+  along with a full test driver.
+cryptest DLL-Import Configuration - This builds a static library containing
+  only algorithms not in the DLL, along with a full test driver that uses
+  both the DLL and the static library.
+
+To use the Crypto++ DLL in your application, #include "dll.h" before including
+any other Crypto++ header files, and place the DLL in the same directory as
+your .exe file. dll.h includes the line #pragma comment(lib, "cryptopp")
+so you don't have to explicitly list the import library in your project
+settings. To use a static library form of Crypto++, specify it as
+an additional library to link with in your project settings.
+In either case you should check the compiler options to
+make sure that the library and your application are using the same C++
+run-time libraries and calling conventions.
+
+*** DLL Memory Management ***
+
+Because it's possible for the Crypto++ DLL to delete objects allocated 
+by the calling application, they must use the same C++ memory heap. Three 
+methods are provided to achieve this.
+1.  The calling application can tell Crypto++ what heap to use. This method 
+    is required when the calling application uses a non-standard heap.
+2.  Crypto++ can tell the calling application what heap to use. This method 
+    is required when the calling application uses a statically linked C++ Run 
+    Time Library. (Method 1 does not work in this case because the Crypto++ DLL 
+    is initialized before the calling application's heap is initialized.)
+3.  Crypto++ can automatically use the heap provided by the calling application's 
+    dynamically linked C++ Run Time Library. The calling application must
+    make sure that the dynamically linked C++ Run Time Library is initialized
+    before Crypto++ is loaded. (At this time it is not clear if it is possible
+    to control the order in which DLLs are initialized on Windows 9x machines,
+    so it might be best to avoid using this method.)
+
+When Crypto++ attaches to a new process, it searches all modules loaded 
+into the process space for exported functions "GetNewAndDeleteForCryptoPP" 
+and "SetNewAndDeleteFromCryptoPP". If one of these functions is found, 
+Crypto++ uses methods 1 or 2, respectively, by calling the function. 
+Otherwise, method 3 is used. 
+
+*** GCC-Specific Information ***
+
+A makefile is included for you to compile Crypto++ with GCC. Make sure
+you are using GNU Make and GNU ld. The make process will produce two files,
+libcryptopp.a and cryptest.exe. Run "cryptest.exe v" for the validation
+suite.
+
+*** Documentation and Support ***
+
+Crypto++ is documented through inline comments in header files, which are
+processed through Doxygen to produce an HTML reference manual. You can find
+a link to the manual from http://www.cryptopp.com. Also at that site is
+the Crypto++ FAQ, which you should browse through before attempting to 
+use this library, because it will likely answer many of questions that
+may come up.
+
+If you run into any problems, please try the Crypto++ mailing list.
+The subscription information and the list archive are available on
+http://www.cryptopp.com. You can also email me directly by visiting
+http://www.weidai.com, but you will probably get a faster response through
+the mailing list.
+
+*** History ***
+
+1.0 - First public release.  Withdrawn at the request of RSA DSI.
+    - included Blowfish, BBS, DES, DH, Diamond, DSA, ElGamal, IDEA,
+      MD5, RC4, RC5, RSA, SHA, WAKE, secret sharing, DEFLATE compression
+    - had a serious bug in the RSA key generation code.
+
+1.1 - Removed RSA, RC4, RC5
+    - Disabled calls to RSAREF's non-public functions
+    - Minor bugs fixed
+
+2.0 - a completely new, faster multiprecision integer class
+    - added MD5-MAC, HAVAL, 3-WAY, TEA, SAFER, LUC, Rabin, BlumGoldwasser,
+      elliptic curve algorithms
+    - added the Lucas strong probable primality test
+    - ElGamal encryption and signature schemes modified to avoid weaknesses
+    - Diamond changed to Diamond2 because of key schedule weakness
+    - fixed bug in WAKE key setup
+    - SHS class renamed to SHA
+    - lots of miscellaneous optimizations
+
+2.1 - added Tiger, HMAC, GOST, RIPE-MD160, LUCELG, LUCDIF, XOR-MAC,
+      OAEP, PSSR, SHARK
+    - added precomputation to DH, ElGamal, DSA, and elliptic curve algorithms
+    - added back RC5 and a new RSA
+    - optimizations in elliptic curves over GF(p)
+    - changed Rabin to use OAEP and PSSR
+    - changed many classes to allow copy constructors to work correctly
+    - improved exception generation and handling
+
+2.2 - added SEAL, CAST-128, Square
+    - fixed bug in HAVAL (padding problem)
+    - fixed bug in triple-DES (decryption order was reversed)
+    - fixed bug in RC5 (couldn't handle key length not a multiple of 4)
+    - changed HMAC to conform to RFC-2104 (which is not compatible
+      with the original HMAC)
+    - changed secret sharing and information dispersal to use GF(2^32)
+      instead of GF(65521)
+    - removed zero knowledge prover/verifier for graph isomorphism
+    - removed several utility classes in favor of the C++ standard library
+
+2.3 - ported to EGCS
+    - fixed incomplete workaround of min/max conflict in MSVC
+
+3.0 - placed all names into the "CryptoPP" namespace
+    - added MD2, RC2, RC6, MARS, RW, DH2, MQV, ECDHC, CBC-CTS
+    - added abstract base classes PK_SimpleKeyAgreementDomain and
+      PK_AuthenticatedKeyAgreementDomain
+    - changed DH and LUCDIF to implement the PK_SimpleKeyAgreementDomain
+      interface and to perform domain parameter and key validation
+    - changed interfaces of PK_Signer and PK_Verifier to sign and verify
+      messages instead of message digests
+    - changed OAEP to conform to PKCS#1 v2.0
+    - changed benchmark code to produce HTML tables as output
+    - changed PSSR to track IEEE P1363a
+    - renamed ElGamalSignature to NR and changed it to track IEEE P1363
+    - renamed ECKEP to ECMQVC and changed it to track IEEE P1363
+    - renamed several other classes for clarity
+    - removed support for calling RSAREF
+    - removed option to compile old SHA (SHA-0)
+    - removed option not to throw exceptions
+
+3.1 - added ARC4, Rijndael, Twofish, Serpent, CBC-MAC, DMAC
+    - added interface for querying supported key lengths of symmetric ciphers
+      and MACs
+    - added sample code for RSA signature and verification
+    - changed CBC-CTS to be compatible with RFC 2040
+    - updated SEAL to version 3.0 of the cipher specification
+    - optimized multiprecision squaring and elliptic curves over GF(p)
+    - fixed bug in MARS key setup
+    - fixed bug with attaching objects to Deflator
+
+3.2 - added DES-XEX3, ECDSA, DefaultEncryptorWithMAC
+    - renamed DES-EDE to DES-EDE2 and TripleDES to DES-EDE3
+    - optimized ARC4
+    - generalized DSA to allow keys longer than 1024 bits
+    - fixed bugs in GF2N and ModularArithmetic that can cause calculation errors
+    - fixed crashing bug in Inflator when given invalid inputs
+    - fixed endian bug in Serpent
+    - fixed padding bug in Tiger
+
+4.0 - added Skipjack, CAST-256, Panama, SHA-2 (SHA-256, SHA-384, and SHA-512),
+      and XTR-DH
+    - added a faster variant of Rabin's Information Dispersal Algorithm (IDA)
+    - added class wrappers for these operating system features:
+      - high resolution timers on Windows, Unix, and MacOS
+      - Berkeley and Windows style sockets
+      - Windows named pipes
+      - /dev/random and /dev/urandom on Linux and FreeBSD
+      - Microsoft's CryptGenRandom on Windows
+    - added support for SEC 1 elliptic curve key format and compressed points
+    - added support for X.509 public key format (subjectPublicKeyInfo) for
+      RSA, DSA, and elliptic curve schemes
+    - added support for DER and OpenPGP signature format for DSA
+    - added support for ZLIB compressed data format (RFC 1950)
+    - changed elliptic curve encryption to use ECIES (as defined in SEC 1)
+    - changed MARS key schedule to reflect the latest specification
+    - changed BufferedTransformation interface to support multiple channels
+      and messages
+    - changed CAST and SHA-1 implementations to use public domain source code
+    - fixed bug in StringSource
+    - optmized multi-precision integer code for better performance
+
+4.1 - added more support for the recommended elliptic curve parameters in SEC 2
+    - added Panama MAC, MARC4
+    - added IV stealing feature to CTS mode
+    - added support for PKCS #8 private key format for RSA, DSA, and elliptic
+      curve schemes
+    - changed Deflate, MD5, Rijndael, and Twofish to use public domain code
+    - fixed a bug with flushing compressed streams
+    - fixed a bug with decompressing stored blocks
+    - fixed a bug with EC point decompression using non-trinomial basis
+    - fixed a bug in NetworkSource::GeneralPump()
+    - fixed a performance issue with EC over GF(p) decryption
+    - fixed syntax to allow GCC to compile without -fpermissive
+    - relaxed some restrictions in the license
+
+4.2 - added support for longer HMAC keys
+    - added MD4 (which is not secure so use for compatibility purposes only)
+    - added compatibility fixes/workarounds for STLport 4.5, GCC 3.0.2,
+      and MSVC 7.0
+    - changed MD2 to use public domain code
+    - fixed a bug with decompressing multiple messages with the same object
+    - fixed a bug in CBC-MAC with MACing multiple messages with the same object
+    - fixed a bug in RC5 and RC6 with zero-length keys
+    - fixed a bug in Adler32 where incorrect checksum may be generated
+
+5.0 - added ESIGN, DLIES, WAKE-OFB, PBKDF1 and PBKDF2 from PKCS #5
+    - added key validation for encryption and signature public/private keys
+    - renamed StreamCipher interface to SymmetricCipher, which is now implemented
+      by both stream ciphers and block cipher modes including ECB and CBC
+    - added keying interfaces to support resetting of keys and IVs without
+      having to destroy and recreate objects
+    - changed filter interface to support non-blocking input/output
+    - changed SocketSource and SocketSink to use overlapped I/O on Microsoft Windows
+    - grouped related classes inside structs to help templates, for example
+      AESEncryption and AESDecryption are now AES::Encryption and AES::Decryption
+    - where possible, typedefs have been added to improve backwards 
+      compatibility when the CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY macro is defined
+    - changed Serpent, HAVAL and IDEA to use public domain code
+    - implemented SSE2 optimizations for Integer operations
+    - fixed a bug in HMAC::TruncatedFinal()
+    - fixed SKIPJACK byte ordering following NIST clarification dated 5/9/02
+
+5.01 - added known answer test for X9.17 RNG in FIPS 140 power-up self test
+     - submitted to NIST/CSE, but not publicly released
+
+5.02 - changed EDC test to MAC integrity check using HMAC/SHA1
+     - improved performance of integrity check
+     - added blinding to defend against RSA timing attack
+
+5.03 - created DLL version of Crypto++ for FIPS 140-2 validation
+     - fixed vulnerabilities in GetNextIV for CTR and OFB modes
+
+5.0.4 - Removed DES, SHA-256, SHA-384, SHA-512 from DLL
+
+5.1 - added PSS padding and changed PSSR to track IEEE P1363a draft standard
+    - added blinding for RSA and Rabin to defend against timing attacks
+      on decryption operations
+    - changed signing and decryption APIs to support the above
+    - changed WaitObjectContainer to allow waiting for more than 64
+      objects at a time on Win32 platforms
+    - fixed a bug in CBC and ECB modes with processing non-aligned data
+    - fixed standard conformance bugs in DLIES (DHAES mode) and RW/EMSA2
+      signature scheme (these fixes are not backwards compatible)
+    - fixed a number of compiler warnings, minor bugs, and portability problems
+    - removed Sapphire
+
+5.2 - merged in changes for 5.01 - 5.0.4
+    - added support for using encoding parameters and key derivation parameters
+      with public key encryption (implemented by OAEP and DL/ECIES)
+    - added Camellia, SHACAL-2, Two-Track-MAC, Whirlpool, RIPEMD-320,
+      RIPEMD-128, RIPEMD-256, Base-32 coding, FIPS variant of CFB mode
+    - added ThreadUserTimer for timing thread CPU usage
+    - added option for password-based key derivation functions
+      to iterate until a mimimum elapsed thread CPU time is reached
+    - added option (on by default) for DEFLATE compression to detect
+      uncompressible files and process them more quickly
+    - improved compatibility and performance on 64-bit platforms,
+      including Alpha, IA-64, x86-64, PPC64, Sparc64, and MIPS64
+    - fixed ONE_AND_ZEROS_PADDING to use 0x80 instead 0x01 as padding.
+    - fixed encoding/decoding of PKCS #8 privateKeyInfo to properly
+      handle optional attributes
+
+5.2.1 - fixed bug in the "dlltest" DLL testing program
+      - fixed compiling with STLport using VC .NET
+      - fixed compiling with -fPIC using GCC
+      - fixed compiling with -msse2 on systems without memalign()
+      - fixed inability to instantiate PanamaMAC
+      - fixed problems with inline documentation
+
+5.2.2 - added SHA-224
+      - put SHA-256, SHA-384, SHA-512, RSASSA-PSS into DLL
+      
+5.2.3 - fixed issues with FIPS algorithm test vectors
+      - put RSASSA-ISO into DLL
+
+5.3 - ported to MSVC 2005 with support for x86-64
+    - added defense against AES timing attacks, and more AES test vectors
+    - changed StaticAlgorithmName() of Rijndael to "AES", CTR to "CTR"
+
+5.4 - added Salsa20
+    - updated Whirlpool to version 3.0
+    - ported to GCC 4.1, Sun C++ 5.8, and Borland C++Builder 2006
+
+5.5 - added VMAC and Sosemanuk (with x86-64 and SSE2 assembly)
+    - improved speed of integer arithmetic, AES, SHA-512, Tiger, Salsa20,
+      Whirlpool, and PANAMA cipher using assembly (x86-64, MMX, SSE2)
+    - optimized Camellia and added defense against timing attacks
+    - updated benchmarks code to show cycles per byte and to time key/IV setup
+    - started using OpenMP for increased multi-core speed
+    - enabled GCC optimization flags by default in GNUmakefile
+    - added blinding and computational error checking for RW signing
+    - changed RandomPool, X917RNG, GetNextIV, DSA/NR/ECDSA/ECNR to reduce
+      the risk of reusing random numbers and IVs after virtual machine state
+      rollback
+    - changed default FIPS mode RNG from AutoSeededX917RNG<DES_EDE3> to
+      AutoSeededX917RNG<AES>
+    - fixed PANAMA cipher interface to accept 256-bit key and 256-bit IV
+    - moved MD2, MD4, MD5, PanamaHash, ARC4, WAKE_CFB into the namespace "Weak"
+    - removed HAVAL, MD5-MAC, XMAC
+
+5.5.1 - fixed VMAC validation failure on 32-bit big-endian machines
+
+5.5.2 - ported x64 assembly language code for AES, Salsa20, Sosemanuk, and Panama
+        to MSVC 2005 (using MASM since MSVC doesn't support inline assembly on x64)
+      - fixed Salsa20 initialization crash on non-SSE2 machines
+      - fixed Whirlpool crash on Pentium 2 machines
+      - fixed possible branch prediction analysis (BPA) vulnerability in
+        MontgomeryReduce(), which may affect security of RSA, RW, LUC
+      - fixed link error with MSVC 2003 when using "debug DLL" form of runtime library
+      - fixed crash in SSE2_Add on P4 machines when compiled with 
+        MSVC 6.0 SP5 with Processor Pack
+      - ported to MSVC 2008, GCC 4.2, Sun CC 5.9, Intel C++ Compiler 10.0, 
+        and Borland C++Builder 2007
+
+5.6 - added AuthenticatedSymmetricCipher interface class and Filter wrappers
+    - added CCM, GCM (with SSE2 assembly), EAX, CMAC, XSalsa20, and SEED
+    - added support for variable length IVs
+    - improved AES and SHA-256 speed on x86 and x64
+    - fixed incorrect VMAC computation on message lengths 
+      that are >64 mod 128 (x86 assembly version is not affected)
+    - fixed compiler error in vmac.cpp on x86 with GCC -fPIC
+    - fixed run-time validation error on x86-64 with GCC 4.3.2 -O2
+    - fixed HashFilter bug when putMessage=true
+    - removed WORD64_AVAILABLE; compiler support for 64-bit int is now required
+    - ported to GCC 4.3, C++Builder 2009, Sun CC 5.10, Intel C++ Compiler 11
+
+Written by Wei Dai
diff --git a/cryptopp/config.h b/cryptopp/config.h
new file mode 100644 (file)
index 0000000..de6b0d7
--- /dev/null
@@ -0,0 +1,455 @@
+#ifndef CRYPTOPP_CONFIG_H
+#define CRYPTOPP_CONFIG_H
+
+// ***************** Important Settings ********************
+
+// define this if running on a big-endian CPU
+#if !defined(IS_LITTLE_ENDIAN) && (defined(__BIG_ENDIAN__) || defined(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__mips__) || (defined(__MWERKS__) && !defined(__INTEL__)))
+#      define IS_BIG_ENDIAN
+#endif
+
+// define this if running on a little-endian CPU
+// big endian will be assumed if IS_LITTLE_ENDIAN is not defined
+#ifndef IS_BIG_ENDIAN
+#      define IS_LITTLE_ENDIAN
+#endif
+
+// define this if you want to disable all OS-dependent features,
+// such as sockets and OS-provided random number generators
+// #define NO_OS_DEPENDENCE
+
+// Define this to use features provided by Microsoft's CryptoAPI.
+// Currently the only feature used is random number generation.
+// This macro will be ignored if NO_OS_DEPENDENCE is defined.
+#define USE_MS_CRYPTOAPI
+
+// Define this to 1 to enforce the requirement in FIPS 186-2 Change Notice 1 that only 1024 bit moduli be used
+#ifndef DSA_1024_BIT_MODULUS_ONLY
+#      define DSA_1024_BIT_MODULUS_ONLY 1
+#endif
+
+// ***************** Less Important Settings ***************
+
+// define this to retain (as much as possible) old deprecated function and class names
+// #define CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+
+#define GZIP_OS_CODE 0
+
+// Try this if your CPU has 256K internal cache or a slow multiply instruction
+// and you want a (possibly) faster IDEA implementation using log tables
+// #define IDEA_LARGECACHE
+
+// Define this if, for the linear congruential RNG, you want to use
+// the original constants as specified in S.K. Park and K.W. Miller's
+// CACM paper.
+// #define LCRNG_ORIGINAL_NUMBERS
+
+// choose which style of sockets to wrap (mostly useful for cygwin which has both)
+#define PREFER_BERKELEY_STYLE_SOCKETS
+// #define PREFER_WINDOWS_STYLE_SOCKETS
+
+// set the name of Rijndael cipher, was "Rijndael" before version 5.3
+#define CRYPTOPP_RIJNDAEL_NAME "AES"
+
+// ***************** Important Settings Again ********************
+// But the defaults should be ok.
+
+// namespace support is now required
+#ifdef NO_NAMESPACE
+#      error namespace support is now required
+#endif
+
+// Define this to workaround a Microsoft CryptoAPI bug where
+// each call to CryptAcquireContext causes a 100 KB memory leak.
+// Defining this will cause Crypto++ to make only one call to CryptAcquireContext.
+#define WORKAROUND_MS_BUG_Q258000
+
+#ifdef CRYPTOPP_DOXYGEN_PROCESSING
+// Avoid putting "CryptoPP::" in front of everything in Doxygen output
+#      define CryptoPP
+#      define NAMESPACE_BEGIN(x)
+#      define NAMESPACE_END
+// Get Doxygen to generate better documentation for these typedefs
+#      define DOCUMENTED_TYPEDEF(x, y) class y : public x {};
+#else
+#      define NAMESPACE_BEGIN(x) namespace x {
+#      define NAMESPACE_END }
+#      define DOCUMENTED_TYPEDEF(x, y) typedef x y;
+#endif
+#define ANONYMOUS_NAMESPACE_BEGIN namespace {
+#define USING_NAMESPACE(x) using namespace x;
+#define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x {
+#define DOCUMENTED_NAMESPACE_END }
+
+// What is the type of the third parameter to bind?
+// For Unix, the new standard is ::socklen_t (typically unsigned int), and the old standard is int.
+// Unfortunately there is no way to tell whether or not socklen_t is defined.
+// To work around this, TYPE_OF_SOCKLEN_T is a macro so that you can change it from the makefile.
+#ifndef TYPE_OF_SOCKLEN_T
+#      if defined(_WIN32) || defined(__CYGWIN__)
+#              define TYPE_OF_SOCKLEN_T int
+#      else
+#              define TYPE_OF_SOCKLEN_T ::socklen_t
+#      endif
+#endif
+
+#if defined(__CYGWIN__) && defined(PREFER_WINDOWS_STYLE_SOCKETS)
+#      define __USE_W32_SOCKETS
+#endif
+
+typedef unsigned char byte;            // put in global namespace to avoid ambiguity with other byte typedefs
+
+NAMESPACE_BEGIN(CryptoPP)
+
+typedef unsigned short word16;
+typedef unsigned int word32;
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+       typedef unsigned __int64 word64;
+       #define W64LIT(x) x##ui64
+#else
+       typedef unsigned long long word64;
+       #define W64LIT(x) x##ULL
+#endif
+
+// define large word type, used for file offsets and such
+typedef word64 lword;
+const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
+
+#ifdef __GNUC__
+       #define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
+
+// define hword, word, and dword. these are used for multiprecision integer arithmetic
+// Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx
+#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__))
+       typedef word32 hword;
+       typedef word64 word;
+#else
+       #define CRYPTOPP_NATIVE_DWORD_AVAILABLE
+       #if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || defined(__x86_64__) || defined(__mips64) || defined(__sparc64__)
+               #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !(CRYPTOPP_GCC_VERSION == 40001 && defined(__APPLE__)) && CRYPTOPP_GCC_VERSION >= 30400
+                       // GCC 4.0.1 on MacOS X is missing __umodti3 and __udivti3
+                       // mode(TI) division broken on amd64 with GCC earlier than GCC 3.4
+                       typedef word32 hword;
+                       typedef word64 word;
+                       typedef __uint128_t dword;
+                       typedef __uint128_t word128;
+                       #define CRYPTOPP_WORD128_AVAILABLE
+               #else
+                       // if we're here, it means we're on a 64-bit CPU but we don't have a way to obtain 128-bit multiplication results
+                       typedef word16 hword;
+                       typedef word32 word;
+                       typedef word64 dword;
+               #endif
+       #else
+               // being here means the native register size is probably 32 bits or less
+               #define CRYPTOPP_BOOL_SLOW_WORD64 1
+               typedef word16 hword;
+               typedef word32 word;
+               typedef word64 dword;
+       #endif
+#endif
+#ifndef CRYPTOPP_BOOL_SLOW_WORD64
+       #define CRYPTOPP_BOOL_SLOW_WORD64 0
+#endif
+
+const unsigned int WORD_SIZE = sizeof(word);
+const unsigned int WORD_BITS = WORD_SIZE * 8;
+
+NAMESPACE_END
+
+#ifndef CRYPTOPP_L1_CACHE_LINE_SIZE
+       // This should be a lower bound on the L1 cache line size. It's used for defense against timing attacks.
+       #if defined(_M_X64) || defined(__x86_64__)
+               #define CRYPTOPP_L1_CACHE_LINE_SIZE 64
+       #else
+               // L1 cache line size is 32 on Pentium III and earlier
+               #define CRYPTOPP_L1_CACHE_LINE_SIZE 32
+       #endif
+#endif
+
+#if defined(_MSC_VER)
+       #if _MSC_VER == 1200
+               #include <malloc.h>
+       #endif
+       #if _MSC_VER > 1200 || defined(_mm_free)
+               #define CRYPTOPP_MSVC6PP_OR_LATER               // VC 6 processor pack or later
+       #else
+               #define CRYPTOPP_MSVC6_NO_PP                    // VC 6 without processor pack
+       #endif
+#endif
+
+#ifndef CRYPTOPP_ALIGN_DATA
+       #if defined(CRYPTOPP_MSVC6PP_OR_LATER)
+               #define CRYPTOPP_ALIGN_DATA(x) __declspec(align(x))
+       #elif defined(__GNUC__)
+               #define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x)))
+       #else
+               #define CRYPTOPP_ALIGN_DATA(x)
+       #endif
+#endif
+
+#ifndef CRYPTOPP_SECTION_ALIGN16
+       #if defined(__GNUC__) && !defined(__APPLE__)
+               // the alignment attribute doesn't seem to work without this section attribute when -fdata-sections is turned on
+               #define CRYPTOPP_SECTION_ALIGN16 __attribute__((section ("CryptoPP_Align16")))
+       #else
+               #define CRYPTOPP_SECTION_ALIGN16
+       #endif
+#endif
+
+#if defined(_MSC_VER) || defined(__fastcall)
+       #define CRYPTOPP_FASTCALL __fastcall
+#else
+       #define CRYPTOPP_FASTCALL
+#endif
+
+// VC60 workaround: it doesn't allow typename in some places
+#if defined(_MSC_VER) && (_MSC_VER < 1300)
+#define CPP_TYPENAME
+#else
+#define CPP_TYPENAME typename
+#endif
+
+// VC60 workaround: can't cast unsigned __int64 to float or double
+#if defined(_MSC_VER) && !defined(CRYPTOPP_MSVC6PP_OR_LATER)
+#define CRYPTOPP_VC6_INT64 (__int64)
+#else
+#define CRYPTOPP_VC6_INT64
+#endif
+
+#ifdef _MSC_VER
+#define CRYPTOPP_NO_VTABLE __declspec(novtable)
+#else
+#define CRYPTOPP_NO_VTABLE
+#endif
+
+#ifdef _MSC_VER
+       // 4231: nonstandard extension used : 'extern' before template explicit instantiation
+       // 4250: dominance
+       // 4251: member needs to have dll-interface
+       // 4275: base needs to have dll-interface
+       // 4660: explicitly instantiating a class that's already implicitly instantiated
+       // 4661: no suitable definition provided for explicit template instantiation request
+       // 4786: identifer was truncated in debug information
+       // 4355: 'this' : used in base member initializer list
+       // 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation
+#      pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355 4910)
+#endif
+
+#ifdef __BORLANDC__
+// 8037: non-const function called for const object. needed to work around BCB2006 bug
+#      pragma warn -8037
+#endif
+
+#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__MWERKS__) || defined(_STLPORT_VERSION)
+#define CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION
+#endif
+
+#ifndef CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION
+#define CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
+#endif
+
+#ifdef CRYPTOPP_DISABLE_X86ASM         // for backwards compatibility: this macro had both meanings
+#define CRYPTOPP_DISABLE_ASM
+#define CRYPTOPP_DISABLE_SSE2
+#endif
+
+#if !defined(CRYPTOPP_DISABLE_ASM) && ((defined(_MSC_VER) && defined(_M_IX86)) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))))
+       #define CRYPTOPP_X86_ASM_AVAILABLE
+
+       #if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || CRYPTOPP_GCC_VERSION >= 30300)
+               #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1
+       #else
+               #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0
+       #endif
+
+       // SSSE3 was actually introduced in GNU as 2.17, which was released 6/23/2006, but we can't tell what version of binutils is installed.
+       // GCC 4.1.2 was released on 2/13/2007, so we'll use that as a proxy for the binutils version.
+       #if !defined(CRYPTOPP_DISABLE_SSSE3) && (_MSC_VER >= 1400 || CRYPTOPP_GCC_VERSION >= 40102)
+               #define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 1
+       #else
+               #define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0
+       #endif
+#endif
+
+#if !defined(CRYPTOPP_DISABLE_ASM) && defined(_MSC_VER) && defined(_M_X64)
+       #define CRYPTOPP_X64_MASM_AVAILABLE
+#endif
+
+#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__GNUC__) && defined(__x86_64__)
+       #define CRYPTOPP_X64_ASM_AVAILABLE
+#endif
+
+#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__))
+       #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 1
+#else
+       #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 0
+#endif
+
+#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)
+       #define CRYPTOPP_BOOL_ALIGN16_ENABLED 1
+#else
+       #define CRYPTOPP_BOOL_ALIGN16_ENABLED 0
+#endif
+
+// how to allocate 16-byte aligned memory (for SSE2)
+#if defined(CRYPTOPP_MSVC6PP_OR_LATER)
+       #define CRYPTOPP_MM_MALLOC_AVAILABLE
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+       #define CRYPTOPP_MALLOC_ALIGNMENT_IS_16
+#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
+       #define CRYPTOPP_MEMALIGN_AVAILABLE
+#else
+       #define CRYPTOPP_NO_ALIGNED_ALLOC
+#endif
+
+// how to disable inlining
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+#      define CRYPTOPP_NOINLINE_DOTDOTDOT
+#      define CRYPTOPP_NOINLINE __declspec(noinline)
+#elif defined(__GNUC__)
+#      define CRYPTOPP_NOINLINE_DOTDOTDOT
+#      define CRYPTOPP_NOINLINE __attribute__((noinline))
+#else
+#      define CRYPTOPP_NOINLINE_DOTDOTDOT ...
+#      define CRYPTOPP_NOINLINE 
+#endif
+
+// how to declare class constants
+#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__INTEL_COMPILER)
+#      define CRYPTOPP_CONSTANT(x) enum {x};
+#else
+#      define CRYPTOPP_CONSTANT(x) static const int x;
+#endif
+
+#if defined(_M_X64) || defined(__x86_64__)
+       #define CRYPTOPP_BOOL_X64 1
+#else
+       #define CRYPTOPP_BOOL_X64 0
+#endif
+
+// see http://predef.sourceforge.net/prearch.html
+#if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(_X86_) || defined(__I86__) || defined(__INTEL__)
+       #define CRYPTOPP_BOOL_X86 1
+#else
+       #define CRYPTOPP_BOOL_X86 0
+#endif
+
+#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || defined(__powerpc__)
+       #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
+#endif
+
+#define CRYPTOPP_VERSION 560
+
+// ***************** determine availability of OS features ********************
+
+#ifndef NO_OS_DEPENDENCE
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define CRYPTOPP_WIN32_AVAILABLE
+#endif
+
+#if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) || defined(__sun)
+#define CRYPTOPP_UNIX_AVAILABLE
+#endif
+
+#if defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE)
+#      define HIGHRES_TIMER_AVAILABLE
+#endif
+
+#ifdef CRYPTOPP_UNIX_AVAILABLE
+#      define HAS_BERKELEY_STYLE_SOCKETS
+#endif
+
+#ifdef CRYPTOPP_WIN32_AVAILABLE
+#      define HAS_WINDOWS_STYLE_SOCKETS
+#endif
+
+#if defined(HIGHRES_TIMER_AVAILABLE) && (defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(HAS_WINDOWS_STYLE_SOCKETS))
+#      define SOCKETS_AVAILABLE
+#endif
+
+#if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS))
+#      define USE_WINDOWS_STYLE_SOCKETS
+#else
+#      define USE_BERKELEY_STYLE_SOCKETS
+#endif
+
+#if defined(HIGHRES_TIMER_AVAILABLE) && defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS)
+#      define WINDOWS_PIPES_AVAILABLE
+#endif
+
+#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(USE_MS_CRYPTOAPI)
+#      define NONBLOCKING_RNG_AVAILABLE
+#      define OS_RNG_AVAILABLE
+#endif
+
+#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
+#      define NONBLOCKING_RNG_AVAILABLE
+#      define BLOCKING_RNG_AVAILABLE
+#      define OS_RNG_AVAILABLE
+#      define HAS_PTHREADS
+#      define THREADS_AVAILABLE
+#endif
+
+#ifdef CRYPTOPP_WIN32_AVAILABLE
+#      define HAS_WINTHREADS
+#      define THREADS_AVAILABLE
+#endif
+
+#endif // NO_OS_DEPENDENCE
+
+// ***************** DLL related ********************
+
+#ifdef CRYPTOPP_WIN32_AVAILABLE
+
+#ifdef CRYPTOPP_EXPORTS
+#define CRYPTOPP_IS_DLL
+#define CRYPTOPP_DLL __declspec(dllexport)
+#elif defined(CRYPTOPP_IMPORTS)
+#define CRYPTOPP_IS_DLL
+#define CRYPTOPP_DLL __declspec(dllimport)
+#else
+#define CRYPTOPP_DLL
+#endif
+
+#define CRYPTOPP_API __cdecl
+
+#else  // CRYPTOPP_WIN32_AVAILABLE
+
+#define CRYPTOPP_DLL
+#define CRYPTOPP_API
+
+#endif // CRYPTOPP_WIN32_AVAILABLE
+
+#if defined(__MWERKS__)
+#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern class CRYPTOPP_DLL
+#elif defined(__BORLANDC__) || defined(__SUNPRO_CC)
+#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL
+#else
+#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern template class CRYPTOPP_DLL
+#endif
+
+#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_IMPORTS)
+#define CRYPTOPP_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL
+#else
+#define CRYPTOPP_DLL_TEMPLATE_CLASS CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS
+#endif
+
+#if defined(__MWERKS__)
+#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern class
+#elif defined(__BORLANDC__) || defined(__SUNPRO_CC)
+#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS template class
+#else
+#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern template class
+#endif
+
+#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_EXPORTS)
+#define CRYPTOPP_STATIC_TEMPLATE_CLASS template class
+#else
+#define CRYPTOPP_STATIC_TEMPLATE_CLASS CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS
+#endif
+
+#endif
diff --git a/cryptopp/cpu.cpp b/cryptopp/cpu.cpp
new file mode 100644 (file)
index 0000000..3e46804
--- /dev/null
@@ -0,0 +1,199 @@
+// cpu.cpp - written and placed in the public domain by Wei Dai
+
+#include "pch.h"
+
+#ifndef CRYPTOPP_IMPORTS
+
+#include "cpu.h"
+#include "misc.h"
+#include <algorithm>
+
+#ifdef __GNUC__
+#include <signal.h>
+#include <setjmp.h>
+#endif
+
+#ifdef CRYPTOPP_MSVC6PP_OR_LATER
+#include <emmintrin.h>
+#endif
+
+NAMESPACE_BEGIN(CryptoPP)
+
+#ifdef CRYPTOPP_X86_ASM_AVAILABLE
+
+#ifndef _MSC_VER
+typedef void (*SigHandler)(int);
+
+static jmp_buf s_jmpNoCPUID;
+static void SigIllHandlerCPUID(int)
+{
+       longjmp(s_jmpNoCPUID, 1);
+}
+#endif
+
+bool CpuId(word32 input, word32 *output)
+{
+#ifdef _MSC_VER
+    __try
+       {
+               __asm
+               {
+                       mov eax, input
+                       cpuid
+                       mov edi, output
+                       mov [edi], eax
+                       mov [edi+4], ebx
+                       mov [edi+8], ecx
+                       mov [edi+12], edx
+               }
+       }
+    __except (1)
+       {
+               return false;
+    }
+       return true;
+#else
+       SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
+       if (oldHandler == SIG_ERR)
+               return false;
+
+       bool result = true;
+       if (setjmp(s_jmpNoCPUID))
+               result = false;
+       else
+       {
+               __asm__
+               (
+                       // save ebx in case -fPIC is being used
+#if CRYPTOPP_BOOL_X86
+                       "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
+#else
+                       "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
+#endif
+                       : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3])
+                       : "a" (input)
+               );
+       }
+
+       signal(SIGILL, oldHandler);
+       return result;
+#endif
+}
+
+#ifndef _MSC_VER
+static jmp_buf s_jmpNoSSE2;
+static void SigIllHandlerSSE2(int)
+{
+       longjmp(s_jmpNoSSE2, 1);
+}
+#endif
+
+#elif _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64
+
+bool CpuId(word32 input, word32 *output)
+{
+       __cpuid((int *)output, input);
+       return true;
+}
+
+#endif
+
+#ifdef CRYPTOPP_CPUID_AVAILABLE
+
+static bool TrySSE2()
+{
+#if CRYPTOPP_BOOL_X64
+       return true;
+#elif defined(_MSC_VER)
+    __try
+       {
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+        AS2(por xmm0, xmm0)        // executing SSE2 instruction
+#elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
+               __mm128i x = _mm_setzero_si128();
+               return _mm_cvtsi128_si32(x) == 0;
+#endif
+       }
+    __except (1)
+       {
+               return false;
+    }
+       return true;
+#elif defined(__GNUC__)
+       SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
+       if (oldHandler == SIG_ERR)
+               return false;
+
+       bool result = true;
+       if (setjmp(s_jmpNoSSE2))
+               result = false;
+       else
+       {
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+               __asm __volatile ("por %xmm0, %xmm0");
+#elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
+               __mm128i x = _mm_setzero_si128();
+               result = _mm_cvtsi128_si32(x) == 0;
+#endif
+       }
+
+       signal(SIGILL, oldHandler);
+       return result;
+#else
+       return false;
+#endif
+}
+
+bool g_x86DetectionDone = false;
+bool g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasMMX = false, g_isP4 = false;
+word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
+
+void DetectX86Features()
+{
+       word32 cpuid[4], cpuid1[4];
+       if (!CpuId(0, cpuid))
+               return;
+       if (!CpuId(1, cpuid1))
+               return;
+
+       g_hasMMX = (cpuid1[3] & (1 << 23)) != 0;
+       if ((cpuid1[3] & (1 << 26)) != 0)
+               g_hasSSE2 = TrySSE2();
+       g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9));
+
+       if ((cpuid1[3] & (1 << 25)) != 0)
+               g_hasISSE = true;
+       else
+       {
+               word32 cpuid2[4];
+               CpuId(0x080000000, cpuid2);
+               if (cpuid2[0] >= 0x080000001)
+               {
+                       CpuId(0x080000001, cpuid2);
+                       g_hasISSE = (cpuid2[3] & (1 << 22)) != 0;
+               }
+       }
+
+       std::swap(cpuid[2], cpuid[3]);
+       if (memcmp(cpuid+1, "GenuineIntel", 12) == 0)
+       {
+               g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
+               g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
+       }
+       else if (memcmp(cpuid+1, "AuthenticAMD", 12) == 0)
+       {
+               CpuId(0x80000005, cpuid);
+               g_cacheLineSize = GETBYTE(cpuid[2], 0);
+       }
+
+       if (!g_cacheLineSize)
+               g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
+
+       g_x86DetectionDone = true;
+}
+
+#endif
+
+NAMESPACE_END
+
+#endif
diff --git a/cryptopp/cpu.h b/cryptopp/cpu.h
new file mode 100644 (file)
index 0000000..7f01dad
--- /dev/null
@@ -0,0 +1,263 @@
+#ifndef CRYPTOPP_CPU_H
+#define CRYPTOPP_CPU_H
+
+#ifdef CRYPTOPP_GENERATE_X64_MASM
+
+#define CRYPTOPP_X86_ASM_AVAILABLE
+#define CRYPTOPP_BOOL_X64 1
+#define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1
+#define NAMESPACE_END
+
+#else
+
+#include "config.h"
+
+#ifdef CRYPTOPP_MSVC6PP_OR_LATER
+       #include <emmintrin.h>
+#endif
+
+NAMESPACE_BEGIN(CryptoPP)
+
+#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || (_MSC_VER >= 1400 && CRYPTOPP_BOOL_X64)
+
+#define CRYPTOPP_CPUID_AVAILABLE
+
+// these should not be used directly
+extern CRYPTOPP_DLL bool g_x86DetectionDone;
+extern CRYPTOPP_DLL bool g_hasSSE2;
+extern CRYPTOPP_DLL bool g_hasISSE;
+extern CRYPTOPP_DLL bool g_hasMMX;
+extern CRYPTOPP_DLL bool g_hasSSSE3;
+extern CRYPTOPP_DLL bool g_isP4;
+extern CRYPTOPP_DLL word32 g_cacheLineSize;
+CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features();
+
+CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 input, word32 *output);
+
+#if CRYPTOPP_BOOL_X64
+inline bool HasSSE2()  {return true;}
+inline bool HasISSE()  {return true;}
+inline bool HasMMX()   {return true;}
+#else
+
+inline bool HasSSE2()
+{
+       if (!g_x86DetectionDone)
+               DetectX86Features();
+       return g_hasSSE2;
+}
+
+inline bool HasISSE()
+{
+       if (!g_x86DetectionDone)
+               DetectX86Features();
+       return g_hasISSE;
+}
+
+inline bool HasMMX()
+{
+       if (!g_x86DetectionDone)
+               DetectX86Features();
+       return g_hasMMX;
+}
+
+#endif
+
+inline bool HasSSSE3()
+{
+       if (!g_x86DetectionDone)
+               DetectX86Features();
+       return g_hasSSSE3;
+}
+
+inline bool IsP4()
+{
+       if (!g_x86DetectionDone)
+               DetectX86Features();
+       return g_isP4;
+}
+
+inline int GetCacheLineSize()
+{
+       if (!g_x86DetectionDone)
+               DetectX86Features();
+       return g_cacheLineSize;
+}
+
+#else
+
+inline int GetCacheLineSize()
+{
+       return CRYPTOPP_L1_CACHE_LINE_SIZE;
+}
+
+inline bool HasSSSE3() {return false;}
+inline bool IsP4()             {return false;}
+
+// assume MMX and SSE2 if intrinsics are enabled
+#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_X64
+inline bool HasSSE2()  {return true;}
+inline bool HasISSE()  {return true;}
+inline bool HasMMX()   {return true;}
+#else
+inline bool HasSSE2()  {return false;}
+inline bool HasISSE()  {return false;}
+inline bool HasMMX()   {return false;}
+#endif
+
+#endif         // #ifdef CRYPTOPP_X86_ASM_AVAILABLE || _MSC_VER >= 1400
+
+#endif
+
+#ifdef CRYPTOPP_GENERATE_X64_MASM
+       #define AS1(x) x*newline*
+       #define AS2(x, y) x, y*newline*
+       #define AS3(x, y, z) x, y, z*newline*
+       #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline*
+       #define ASL(x) label##x:*newline*
+       #define ASJ(x, y, z) x label##y*newline*
+       #define ASC(x, y) x label##y*newline*
+       #define AS_HEX(y) 0##y##h
+#elif defined(__GNUC__)
+       // define these in two steps to allow arguments to be expanded
+       #define GNU_AS1(x) #x ";"
+       #define GNU_AS2(x, y) #x ", " #y ";"
+       #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";"
+       #define GNU_ASL(x) "\n" #x ":"
+       #define GNU_ASJ(x, y, z) #x " " #y #z ";"
+       #define AS1(x) GNU_AS1(x)
+       #define AS2(x, y) GNU_AS2(x, y)
+       #define AS3(x, y, z) GNU_AS3(x, y, z)
+       #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";"
+       #define ASL(x) GNU_ASL(x)
+       #define ASJ(x, y, z) GNU_ASJ(x, y, z)
+       #define ASC(x, y) #x " " #y ";"
+       #define CRYPTOPP_NAKED
+       #define AS_HEX(y) 0x##y
+#else
+       #define AS1(x) __asm {x}
+       #define AS2(x, y) __asm {x, y}
+       #define AS3(x, y, z) __asm {x, y, z}
+       #define ASS(x, y, a, b, c, d) __asm {x, y, _MM_SHUFFLE(a, b, c, d)}
+       #define ASL(x) __asm {label##x:}
+       #define ASJ(x, y, z) __asm {x label##y}
+       #define ASC(x, y) __asm {x label##y}
+       #define CRYPTOPP_NAKED __declspec(naked)
+       #define AS_HEX(y) 0x##y
+#endif
+
+#define IF0(y)
+#define IF1(y) y
+
+#ifdef CRYPTOPP_GENERATE_X64_MASM
+#define ASM_MOD(x, y) ((x) MOD (y))
+#define XMMWORD_PTR XMMWORD PTR
+#else
+// GNU assembler doesn't seem to have mod operator
+#define ASM_MOD(x, y) ((x)-((x)/(y))*(y))
+// GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM
+#define XMMWORD_PTR
+#endif
+
+#if CRYPTOPP_BOOL_X86
+       #define AS_REG_1 ecx
+       #define AS_REG_2 edx
+       #define AS_REG_3 esi
+       #define AS_REG_4 edi
+       #define AS_REG_5 eax
+       #define AS_REG_6 ebx
+       #define AS_REG_7 ebp
+       #define AS_REG_1d ecx
+       #define AS_REG_2d edx
+       #define AS_REG_3d esi
+       #define AS_REG_4d edi
+       #define AS_REG_5d eax
+       #define AS_REG_6d ebx
+       #define AS_REG_7d ebp
+       #define WORD_SZ 4
+       #define WORD_REG(x)     e##x
+       #define WORD_PTR DWORD PTR
+       #define AS_PUSH_IF86(x) AS1(push e##x)
+       #define AS_POP_IF86(x) AS1(pop e##x)
+       #define AS_JCXZ jecxz
+#elif CRYPTOPP_BOOL_X64
+       #ifdef CRYPTOPP_GENERATE_X64_MASM
+               #define AS_REG_1 rcx
+               #define AS_REG_2 rdx
+               #define AS_REG_3 r8
+               #define AS_REG_4 r9
+               #define AS_REG_5 rax
+               #define AS_REG_6 r10
+               #define AS_REG_7 r11
+               #define AS_REG_1d ecx
+               #define AS_REG_2d edx
+               #define AS_REG_3d r8d
+               #define AS_REG_4d r9d
+               #define AS_REG_5d eax
+               #define AS_REG_6d r10d
+               #define AS_REG_7d r11d
+       #else
+               #define AS_REG_1 rdi
+               #define AS_REG_2 rsi
+               #define AS_REG_3 rdx
+               #define AS_REG_4 rcx
+               #define AS_REG_5 r8
+               #define AS_REG_6 r9
+               #define AS_REG_7 r10
+               #define AS_REG_1d edi
+               #define AS_REG_2d esi
+               #define AS_REG_3d edx
+               #define AS_REG_4d ecx
+               #define AS_REG_5d r8d
+               #define AS_REG_6d r9d
+               #define AS_REG_7d r10d
+       #endif
+       #define WORD_SZ 8
+       #define WORD_REG(x)     r##x
+       #define WORD_PTR QWORD PTR
+       #define AS_PUSH_IF86(x)
+       #define AS_POP_IF86(x)
+       #define AS_JCXZ jrcxz
+#endif
+
+// helper macro for stream cipher output
+#define AS_XMM_OUTPUT4(labelPrefix, inputPtr, outputPtr, x0, x1, x2, x3, t, p0, p1, p2, p3, increment)\
+       AS2(    test    inputPtr, inputPtr)\
+       ASC(    jz,             labelPrefix##3)\
+       AS2(    test    inputPtr, 15)\
+       ASC(    jnz,    labelPrefix##7)\
+       AS2(    pxor    xmm##x0, [inputPtr+p0*16])\
+       AS2(    pxor    xmm##x1, [inputPtr+p1*16])\
+       AS2(    pxor    xmm##x2, [inputPtr+p2*16])\
+       AS2(    pxor    xmm##x3, [inputPtr+p3*16])\
+       AS2(    add             inputPtr, increment*16)\
+       ASC(    jmp,    labelPrefix##3)\
+       ASL(labelPrefix##7)\
+       AS2(    movdqu  xmm##t, [inputPtr+p0*16])\
+       AS2(    pxor    xmm##x0, xmm##t)\
+       AS2(    movdqu  xmm##t, [inputPtr+p1*16])\
+       AS2(    pxor    xmm##x1, xmm##t)\
+       AS2(    movdqu  xmm##t, [inputPtr+p2*16])\
+       AS2(    pxor    xmm##x2, xmm##t)\
+       AS2(    movdqu  xmm##t, [inputPtr+p3*16])\
+       AS2(    pxor    xmm##x3, xmm##t)\
+       AS2(    add             inputPtr, increment*16)\
+       ASL(labelPrefix##3)\
+       AS2(    test    outputPtr, 15)\
+       ASC(    jnz,    labelPrefix##8)\
+       AS2(    movdqa  [outputPtr+p0*16], xmm##x0)\
+       AS2(    movdqa  [outputPtr+p1*16], xmm##x1)\
+       AS2(    movdqa  [outputPtr+p2*16], xmm##x2)\
+       AS2(    movdqa  [outputPtr+p3*16], xmm##x3)\
+       ASC(    jmp,    labelPrefix##9)\
+       ASL(labelPrefix##8)\
+       AS2(    movdqu  [outputPtr+p0*16], xmm##x0)\
+       AS2(    movdqu  [outputPtr+p1*16], xmm##x1)\
+       AS2(    movdqu  [outputPtr+p2*16], xmm##x2)\
+       AS2(    movdqu  [outputPtr+p3*16], xmm##x3)\
+       ASL(labelPrefix##9)\
+       AS2(    add             outputPtr, increment*16)
+
+NAMESPACE_END
+
+#endif
diff --git a/cryptopp/cryptlib.h b/cryptopp/cryptlib.h
new file mode 100644 (file)
index 0000000..15cd6da
--- /dev/null
@@ -0,0 +1,1668 @@
+// cryptlib.h - written and placed in the public domain by Wei Dai
+/*! \file
+       This file contains the declarations for the abstract base
+       classes that provide a uniform interface to this library.
+*/
+
+/*!    \mainpage Crypto++ Library 5.6.0 API Reference
+<dl>
+<dt>Abstract Base Classes<dd>
+       cryptlib.h
+<dt>Authenticated Encryption<dd>
+       AuthenticatedSymmetricCipherDocumentation
+<dt>Symmetric Ciphers<dd>
+       SymmetricCipherDocumentation
+<dt>Hash Functions<dd>
+       SHA1, SHA224, SHA256, SHA384, SHA512, Tiger, Whirlpool, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, Weak1::MD2, Weak1::MD4, Weak1::MD5
+<dt>Non-Cryptographic Checksums<dd>
+       CRC32, Adler32
+<dt>Message Authentication Codes<dd>
+       VMAC, HMAC, CBC_MAC, CMAC, DMAC, TTMAC, GCM (GMAC)
+<dt>Random Number Generators<dd>
+       NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG, DefaultAutoSeededRNG
+<dt>Password-based Cryptography<dd>
+       PasswordBasedKeyDerivationFunction
+<dt>Public Key Cryptosystems<dd>
+       DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES
+<dt>Public Key Signature Schemes<dd>
+       DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN
+<dt>Key Agreement<dd>
+       #DH, DH2, #MQV, ECDH, ECMQV, XTR_DH
+<dt>Algebraic Structures<dd>
+       Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver,
+       ModularArithmetic, MontgomeryRepresentation, GFP2_ONB,
+       GF2NP, GF256, GF2_32, EC2N, ECP
+<dt>Secret Sharing and Information Dispersal<dd>
+       SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery
+<dt>Compression<dd>
+       Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor
+<dt>Input Source Classes<dd>
+       StringSource, ArraySource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource
+<dt>Output Sink Classes<dd>
+       StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink, RandomNumberSink
+<dt>Filter Wrappers<dd>
+       StreamTransformationFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter
+<dt>Binary to Text Encoders and Decoders<dd>
+       HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base32Encoder, Base32Decoder
+<dt>Wrappers for OS features<dd>
+       Timer, Socket, WindowsHandle, ThreadLocalStorage, ThreadUserTimer
+<dt>FIPS 140 related<dd>
+       fips140.h
+</dl>
+
+In the FIPS 140-2 validated DLL version of Crypto++, only the following implementation class are available.
+<dl>
+<dt>Block Ciphers<dd>
+       AES, DES_EDE2, DES_EDE3, SKIPJACK
+<dt>Cipher Modes (replace template parameter BC with one of the block ciphers above)<dd>
+       ECB_Mode\<BC\>, CTR_Mode\<BC\>, CBC_Mode\<BC\>, CFB_FIPS_Mode\<BC\>, OFB_Mode\<BC\>
+<dt>Hash Functions<dd>
+       SHA1, SHA224, SHA256, SHA384, SHA512
+<dt>Public Key Signature Schemes (replace template parameter H with one of the hash functions above)<dd>
+       RSASS\<PKCS1v15, H\>, RSASS\<PSS, H\>, RSASS_ISO\<H\>, RWSS\<P1363_EMSA2, H\>, DSA, ECDSA\<ECP, H\>, ECDSA\<EC2N, H\>
+<dt>Message Authentication Codes (replace template parameter H with one of the hash functions above)<dd>
+       HMAC\<H\>, CBC_MAC\<DES_EDE2\>, CBC_MAC\<DES_EDE3\>
+<dt>Random Number Generators<dd>
+       DefaultAutoSeededRNG (AutoSeededX917RNG\<AES\>)
+<dt>Key Agreement<dd>
+       #DH
+<dt>Public Key Cryptosystems<dd>
+       RSAES\<OAEP\<SHA1\> \>
+</dl>
+
+<p>This reference manual is a work in progress. Some classes are still lacking detailed descriptions.
+<p>Click <a href="CryptoPPRef.zip">here</a> to download a zip archive containing this manual.
+<p>Thanks to Ryan Phillips for providing the Doxygen configuration file
+and getting me started with this manual.
+*/
+
+#ifndef CRYPTOPP_CRYPTLIB_H
+#define CRYPTOPP_CRYPTLIB_H
+
+#include "config.h"
+#include "stdcpp.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// forward declarations
+class Integer;
+class RandomNumberGenerator;
+class BufferedTransformation;
+
+//! used to specify a direction for a cipher to operate in (encrypt or decrypt)
+enum CipherDir {ENCRYPTION, DECRYPTION};
+
+//! used to represent infinite time
+const unsigned long INFINITE_TIME = ULONG_MAX;
+
+// VC60 workaround: using enums as template parameters causes problems
+template <typename ENUM_TYPE, int VALUE>
+struct EnumToType
+{
+       static ENUM_TYPE ToEnum() {return (ENUM_TYPE)VALUE;}
+};
+
+enum ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1};
+typedef EnumToType<ByteOrder, LITTLE_ENDIAN_ORDER> LittleEndian;
+typedef EnumToType<ByteOrder, BIG_ENDIAN_ORDER> BigEndian;
+
+//! base class for all exceptions thrown by Crypto++
+class CRYPTOPP_DLL Exception : public std::exception
+{
+public:
+       //! error types
+       enum ErrorType {
+               //! a method is not implemented
+               NOT_IMPLEMENTED,
+               //! invalid function argument
+               INVALID_ARGUMENT,
+               //! BufferedTransformation received a Flush(true) signal but can't flush buffers
+               CANNOT_FLUSH,
+               //! data integerity check (such as CRC or MAC) failed
+               DATA_INTEGRITY_CHECK_FAILED,
+               //! received input data that doesn't conform to expected format
+               INVALID_DATA_FORMAT,
+               //! error reading from input device or writing to output device
+               IO_ERROR,
+               //! some error not belong to any of the above categories
+               OTHER_ERROR
+       };
+
+       explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {}
+       virtual ~Exception() throw() {}
+       const char *what() const throw() {return (m_what.c_str());}
+       const std::string &GetWhat() const {return m_what;}
+       void SetWhat(const std::string &s) {m_what = s;}
+       ErrorType GetErrorType() const {return m_errorType;}
+       void SetErrorType(ErrorType errorType) {m_errorType = errorType;}
+
+private:
+       ErrorType m_errorType;
+       std::string m_what;
+};
+
+//! exception thrown when an invalid argument is detected
+class CRYPTOPP_DLL InvalidArgument : public Exception
+{
+public:
+       explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {}
+};
+
+//! exception thrown when input data is received that doesn't conform to expected format
+class CRYPTOPP_DLL InvalidDataFormat : public Exception
+{
+public:
+       explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {}
+};
+
+//! exception thrown by decryption filters when trying to decrypt an invalid ciphertext
+class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat
+{
+public:
+       explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {}
+};
+
+//! exception thrown by a class if a non-implemented method is called
+class CRYPTOPP_DLL NotImplemented : public Exception
+{
+public:
+       explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {}
+};
+
+//! exception thrown by a class when Flush(true) is called but it can't completely flush its buffers
+class CRYPTOPP_DLL CannotFlush : public Exception
+{
+public:
+       explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {}
+};
+
+//! error reported by the operating system
+class CRYPTOPP_DLL OS_Error : public Exception
+{
+public:
+       OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode)
+               : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {}
+       ~OS_Error() throw() {}
+
+       // the operating system API that reported the error
+       const std::string & GetOperation() const {return m_operation;}
+       // the error code return by the operating system
+       int GetErrorCode() const {return m_errorCode;}
+
+protected:
+       std::string m_operation;
+       int m_errorCode;
+};
+
+//! used to return decoding results
+struct CRYPTOPP_DLL DecodingResult
+{
+       explicit DecodingResult() : isValidCoding(false), messageLength(0) {}
+       explicit DecodingResult(size_t len) : isValidCoding(true), messageLength(len) {}
+
+       bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;}
+       bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);}
+
+       bool isValidCoding;
+       size_t messageLength;
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+       operator size_t() const {return isValidCoding ? messageLength : 0;}
+#endif
+};
+
+//! interface for retrieving values given their names
+/*! \note This class is used to safely pass a variable number of arbitrarily typed arguments to functions
+       and to read values from keys and crypto parameters.
+       \note To obtain an object that implements NameValuePairs for the purpose of parameter
+       passing, use the MakeParameters() function.
+       \note To get a value from NameValuePairs, you need to know the name and the type of the value. 
+       Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports.
+       Then look at the Name namespace documentation to see what the type of each value is, or
+       alternatively, call GetIntValue() with the value name, and if the type is not int, a
+       ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object.
+*/
+class CRYPTOPP_NO_VTABLE NameValuePairs
+{
+public:
+       virtual ~NameValuePairs() {}
+
+       //! exception thrown when trying to retrieve a value using a different type than expected
+       class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument
+       {
+       public:
+               ValueTypeMismatch(const std::string &name, const std::type_info &stored, const std::type_info &retrieving)
+                       : InvalidArgument("NameValuePairs: type mismatch for '" + name + "', stored '" + stored.name() + "', trying to retrieve '" + retrieving.name() + "'")
+                       , m_stored(stored), m_retrieving(retrieving) {}
+
+               const std::type_info & GetStoredTypeInfo() const {return m_stored;}
+               const std::type_info & GetRetrievingTypeInfo() const {return m_retrieving;}
+
+       private:
+               const std::type_info &m_stored;
+               const std::type_info &m_retrieving;
+       };
+
+       //! get a copy of this object or a subobject of it
+       template <class T>
+       bool GetThisObject(T &object) const
+       {
+               return GetValue((std::string("ThisObject:")+typeid(T).name()).c_str(), object);
+       }
+
+       //! get a pointer to this object, as a pointer to T
+       template <class T>
+       bool GetThisPointer(T *&p) const
+       {
+               return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), p);
+       }
+
+       //! get a named value, returns true if the name exists
+       template <class T>
+       bool GetValue(const char *name, T &value) const
+       {
+               return GetVoidValue(name, typeid(T), &value);
+       }
+
+       //! get a named value, returns the default if the name doesn't exist
+       template <class T>
+       T GetValueWithDefault(const char *name, T defaultValue) const
+       {
+               GetValue(name, defaultValue);
+               return defaultValue;
+       }
+
+       //! get a list of value names that can be retrieved
+       CRYPTOPP_DLL std::string GetValueNames() const
+               {std::string result; GetValue("ValueNames", result); return result;}
+
+       //! get a named value with type int
+       /*! used to ensure we don't accidentally try to get an unsigned int
+               or some other type when we mean int (which is the most common case) */
+       CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const
+               {return GetValue(name, value);}
+
+       //! get a named value with type int, with default
+       CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
+               {return GetValueWithDefault(name, defaultValue);}
+
+       //! used by derived classes to check for type mismatch
+       CRYPTOPP_DLL static void CRYPTOPP_API ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving)
+               {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);}
+
+       template <class T>
+       void GetRequiredParameter(const char *className, const char *name, T &value) const
+       {
+               if (!GetValue(name, value))
+                       throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'");
+       }
+
+       CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const
+       {
+               if (!GetIntValue(name, value))
+                       throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'");
+       }
+
+       //! to be implemented by derived classes, users should use one of the above functions instead
+       CRYPTOPP_DLL virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0;
+};
+
+//! namespace containing value name definitions
+/*!    value names, types and semantics:
+
+       ThisObject:ClassName (ClassName, copy of this object or a subobject)
+       ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject)
+*/
+DOCUMENTED_NAMESPACE_BEGIN(Name)
+// more names defined in argnames.h
+DOCUMENTED_NAMESPACE_END
+
+//! empty set of name-value pairs
+class CRYPTOPP_DLL NullNameValuePairs : public NameValuePairs
+{
+public:
+       bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;}
+};
+
+//! _
+extern CRYPTOPP_DLL const NullNameValuePairs g_nullNameValuePairs;
+
+// ********************************************************
+
+//! interface for cloning objects, this is not implemented by most classes yet
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable
+{
+public:
+       virtual ~Clonable() {}
+       //! this is not implemented by most classes yet
+       virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");}      // TODO: make this =0
+};
+
+//! interface for all crypto algorithms
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Algorithm : public Clonable
+{
+public:
+       /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true,
+               this constructor throws SelfTestFailure if the self test hasn't been run or fails. */
+       Algorithm(bool checkSelfTestStatus = true);
+       //! returns name of this algorithm, not universally implemented yet
+       virtual std::string AlgorithmName() const {return "unknown";}
+};
+
+//! keying interface for crypto algorithms that take byte strings as keys
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyingInterface
+{
+public:
+       virtual ~SimpleKeyingInterface() {}
+
+       //! returns smallest valid key length in bytes */
+       virtual size_t MinKeyLength() const =0;
+       //! returns largest valid key length in bytes */
+       virtual size_t MaxKeyLength() const =0;
+       //! returns default (recommended) key length in bytes */
+       virtual size_t DefaultKeyLength() const =0;
+
+       //! returns the smallest valid key length in bytes that is >= min(n, GetMaxKeyLength())
+       virtual size_t GetValidKeyLength(size_t n) const =0;
+
+       //! returns whether n is a valid key length
+       virtual bool IsValidKeyLength(size_t n) const
+               {return n == GetValidKeyLength(n);}
+
+       //! set or reset the key of this object
+       /*! \param params is used to specify Rounds, BlockSize, etc. */
+       virtual void SetKey(const byte *key, size_t length, const NameValuePairs &params = g_nullNameValuePairs);
+
+       //! calls SetKey() with an NameValuePairs object that just specifies "Rounds"
+       void SetKeyWithRounds(const byte *key, size_t length, int rounds);
+
+       //! calls SetKey() with an NameValuePairs object that just specifies "IV"
+       void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength);
+
+       //! calls SetKey() with an NameValuePairs object that just specifies "IV"
+       void SetKeyWithIV(const byte *key, size_t length, const byte *iv)
+               {SetKeyWithIV(key, length, iv, IVSize());}
+
+       enum IV_Requirement {UNIQUE_IV = 0, RANDOM_IV, UNPREDICTABLE_RANDOM_IV, INTERNALLY_GENERATED_IV, NOT_RESYNCHRONIZABLE};
+       //! returns the minimal requirement for secure IVs
+       virtual IV_Requirement IVRequirement() const =0;
+
+       //! returns whether this object can be resynchronized (i.e. supports initialization vectors)
+       /*! If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, an IV of all 0's will be assumed. */
+       bool IsResynchronizable() const {return IVRequirement() < NOT_RESYNCHRONIZABLE;}
+       //! returns whether this object can use random IVs (in addition to ones returned by GetNextIV)
+       bool CanUseRandomIVs() const {return IVRequirement() <= UNPREDICTABLE_RANDOM_IV;}
+       //! returns whether this object can use random but possibly predictable IVs (in addition to ones returned by GetNextIV)
+       bool CanUsePredictableIVs() const {return IVRequirement() <= RANDOM_IV;}
+       //! returns whether this object can use structured IVs, for example a counter (in addition to ones returned by GetNextIV)
+       bool CanUseStructuredIVs() const {return IVRequirement() <= UNIQUE_IV;}
+
+       virtual unsigned int IVSize() const {throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");}
+       //! returns default length of IVs accepted by this object
+       unsigned int DefaultIVLength() const {return IVSize();}
+       //! returns minimal length of IVs accepted by this object
+       virtual unsigned int MinIVLength() const {return IVSize();}
+       //! returns maximal length of IVs accepted by this object
+       virtual unsigned int MaxIVLength() const {return IVSize();}
+       //! resynchronize with an IV. ivLength=-1 means use IVSize()
+       virtual void Resynchronize(const byte *iv, int ivLength=-1) {throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");}
+       //! get a secure IV for the next message
+       /*! This method should be called after you finish encrypting one message and are ready to start the next one.
+               After calling it, you must call SetKey() or Resynchronize() before using this object again. 
+               This method is not implemented on decryption objects. */
+       virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV);
+
+protected:
+       virtual const Algorithm & GetAlgorithm() const =0;
+       virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params) =0;
+
+       void ThrowIfInvalidKeyLength(size_t length);
+       void ThrowIfResynchronizable();                 // to be called when no IV is passed
+       void ThrowIfInvalidIV(const byte *iv);  // check for NULL IV if it can't be used
+       size_t ThrowIfInvalidIVLength(int size);
+       const byte * GetIVAndThrowIfInvalid(const NameValuePairs &params, size_t &size);
+       inline void AssertValidKeyLength(size_t length) const
+               {assert(IsValidKeyLength(length));}
+};
+
+//! interface for the data processing part of block ciphers
+
+/*! Classes derived from BlockTransformation are block ciphers
+       in ECB mode (for example the DES::Encryption class), which are stateless.
+       These classes should not be used directly, but only in combination with
+       a mode class (see CipherModeDocumentation in modes.h).
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm
+{
+public:
+       //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock
+       virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0;
+
+       //! encrypt or decrypt one block
+       /*! \pre size of inBlock and outBlock == BlockSize() */
+       void ProcessBlock(const byte *inBlock, byte *outBlock) const
+               {ProcessAndXorBlock(inBlock, NULL, outBlock);}
+
+       //! encrypt or decrypt one block in place
+       void ProcessBlock(byte *inoutBlock) const
+               {ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);}
+
+       //! block size of the cipher in bytes
+       virtual unsigned int BlockSize() const =0;
+
+       //! returns how inputs and outputs should be aligned for optimal performance
+       virtual unsigned int OptimalDataAlignment() const;
+
+       //! returns true if this is a permutation (i.e. there is an inverse transformation)
+       virtual bool IsPermutation() const {return true;}
+
+       //! returns true if this is an encryption object
+       virtual bool IsForwardTransformation() const =0;
+
+       //! return number of blocks that can be processed in parallel, for bit-slicing implementations
+       virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;}
+
+       enum {BT_InBlockIsCounter=1, BT_DontIncrementInOutPointers=2, BT_XorInput=4, BT_ReverseDirection=8} FlagsForAdvancedProcessBlocks;
+
+       //! encrypt and xor blocks according to flags (see FlagsForAdvancedProcessBlocks)
+       /*! /note If BT_InBlockIsCounter is set, last byte of inBlocks may be modified. */
+       virtual size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
+
+       inline CipherDir GetCipherDirection() const {return IsForwardTransformation() ? ENCRYPTION : DECRYPTION;}
+};
+
+//! interface for the data processing part of stream ciphers
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm
+{
+public:
+       //! return a reference to this object, 
+       /*! This function is useful for passing a temporary StreamTransformation object to a 
+               function that takes a non-const reference. */
+       StreamTransformation& Ref() {return *this;}
+
+       //! returns block size, if input must be processed in blocks, otherwise 1
+       virtual unsigned int MandatoryBlockSize() const {return 1;}
+
+       //! returns the input block size that is most efficient for this cipher
+       /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */
+       virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();}
+       //! returns how much of the current block is used up
+       virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;}
+
+       //! returns how input should be aligned for optimal performance
+       virtual unsigned int OptimalDataAlignment() const;
+
+       //! encrypt or decrypt an array of bytes of specified length
+       /*! \note either inString == outString, or they don't overlap */
+       virtual void ProcessData(byte *outString, const byte *inString, size_t length) =0;
+
+       //! for ciphers where the last block of data is special, encrypt or decrypt the last block of data
+       /*! For now the only use of this function is for CBC-CTS mode. */
+       virtual void ProcessLastBlock(byte *outString, const byte *inString, size_t length);
+       //! returns the minimum size of the last block, 0 indicating the last block is not special
+       virtual unsigned int MinLastBlockSize() const {return 0;}
+
+       //! same as ProcessData(inoutString, inoutString, length)
+       inline void ProcessString(byte *inoutString, size_t length)
+               {ProcessData(inoutString, inoutString, length);}
+       //! same as ProcessData(outString, inString, length)
+       inline void ProcessString(byte *outString, const byte *inString, size_t length)
+               {ProcessData(outString, inString, length);}
+       //! implemented as {ProcessData(&input, &input, 1); return input;}
+       inline byte ProcessByte(byte input)
+               {ProcessData(&input, &input, 1); return input;}
+
+       //! returns whether this cipher supports random access
+       virtual bool IsRandomAccess() const =0;
+       //! for random access ciphers, seek to an absolute position
+       virtual void Seek(lword n)
+       {
+               assert(!IsRandomAccess());
+               throw NotImplemented("StreamTransformation: this object doesn't support random access");
+       }
+
+       //! returns whether this transformation is self-inverting (e.g. xor with a keystream)
+       virtual bool IsSelfInverting() const =0;
+       //! returns whether this is an encryption object
+       virtual bool IsForwardTransformation() const =0;
+};
+
+//! interface for hash functions and data processing part of MACs
+
+/*! HashTransformation objects are stateful.  They are created in an initial state,
+       change state as Update() is called, and return to the initial
+       state when Final() is called.  This interface allows a large message to
+       be hashed in pieces by calling Update() on each piece followed by
+       calling Final().
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm
+{
+public:
+       //! return a reference to this object, 
+       /*! This function is useful for passing a temporary HashTransformation object to a 
+               function that takes a non-const reference. */
+       HashTransformation& Ref() {return *this;}
+
+       //! process more input
+       virtual void Update(const byte *input, size_t length) =0;
+
+       //! request space to write input into
+       virtual byte * CreateUpdateSpace(size_t &size) {size=0; return NULL;}
+
+       //! compute hash for current message, then restart for a new message
+       /*!     \pre size of digest == DigestSize(). */
+       virtual void Final(byte *digest)
+               {TruncatedFinal(digest, DigestSize());}
+
+       //! discard the current state, and restart with a new message
+       virtual void Restart()
+               {TruncatedFinal(NULL, 0);}
+
+       //! size of the hash/digest/MAC returned by Final()
+       virtual unsigned int DigestSize() const =0;
+
+       //! same as DigestSize()
+       unsigned int TagSize() const {return DigestSize();}
+
+
+       //! block size of underlying compression function, or 0 if not block based
+       virtual unsigned int BlockSize() const {return 0;}
+
+       //! input to Update() should have length a multiple of this for optimal speed
+       virtual unsigned int OptimalBlockSize() const {return 1;}
+
+       //! returns how input should be aligned for optimal performance
+       virtual unsigned int OptimalDataAlignment() const;
+
+       //! use this if your input is in one piece and you don't want to call Update() and Final() separately
+       virtual void CalculateDigest(byte *digest, const byte *input, size_t length)
+               {Update(input, length); Final(digest);}
+
+       //! verify that digest is a valid digest for the current message, then reinitialize the object
+       /*! Default implementation is to call Final() and do a bitwise comparison
+               between its output and digest. */
+       virtual bool Verify(const byte *digest)
+               {return TruncatedVerify(digest, DigestSize());}
+
+       //! use this if your input is in one piece and you don't want to call Update() and Verify() separately
+       virtual bool VerifyDigest(const byte *digest, const byte *input, size_t length)
+               {Update(input, length); return Verify(digest);}
+
+       //! truncated version of Final()
+       virtual void TruncatedFinal(byte *digest, size_t digestSize) =0;
+
+       //! truncated version of CalculateDigest()
+       virtual void CalculateTruncatedDigest(byte *digest, size_t digestSize, const byte *input, size_t length)
+               {Update(input, length); TruncatedFinal(digest, digestSize);}
+
+       //! truncated version of Verify()
+       virtual bool TruncatedVerify(const byte *digest, size_t digestLength);
+
+       //! truncated version of VerifyDigest()
+       virtual bool VerifyTruncatedDigest(const byte *digest, size_t digestLength, const byte *input, size_t length)
+               {Update(input, length); return TruncatedVerify(digest, digestLength);}
+
+protected:
+       void ThrowIfInvalidTruncatedSize(size_t size) const;
+};
+
+typedef HashTransformation HashFunction;
+
+//! interface for one direction (encryption or decryption) of a block cipher
+/*! \note These objects usually should not be used directly. See BlockTransformation for more details. */
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockCipher : public SimpleKeyingInterface, public BlockTransformation
+{
+protected:
+       const Algorithm & GetAlgorithm() const {return *this;}
+};
+
+//! interface for one direction (encryption or decryption) of a stream cipher or cipher mode
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SymmetricCipher : public SimpleKeyingInterface, public StreamTransformation
+{
+protected:
+       const Algorithm & GetAlgorithm() const {return *this;}
+};
+
+//! interface for message authentication codes
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE MessageAuthenticationCode : public SimpleKeyingInterface, public HashTransformation
+{
+protected:
+       const Algorithm & GetAlgorithm() const {return *this;}
+};
+
+//! interface for for one direction (encryption or decryption) of a stream cipher or block cipher mode with authentication
+/*! The StreamTransformation part of this interface is used to encrypt/decrypt the data, and the MessageAuthenticationCode part of this
+       interface is used to input additional authenticated data (AAD, which is MAC'ed but not encrypted), and to generate/verify the MAC. */
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipher : public MessageAuthenticationCode, public StreamTransformation
+{
+public:
+       //! this indicates that a member function was called in the wrong state, for example trying to encrypt a message before having set the key or IV
+       class BadState : public Exception
+       {
+       public:
+               explicit BadState(const std::string &name, const char *message) : Exception(OTHER_ERROR, name + ": " + message) {}
+               explicit BadState(const std::string &name, const char *function, const char *state) : Exception(OTHER_ERROR, name + ": " + function + " was called before " + state) {}
+       };
+
+       //! the maximum length of AAD that can be input before the encrypted data
+       virtual lword MaxHeaderLength() const =0;
+       //! the maximum length of encrypted data
+       virtual lword MaxMessageLength() const =0;
+       //! the maximum length of AAD that can be input after the encrypted data
+       virtual lword MaxFooterLength() const {return 0;}
+       //! if this function returns true, SpecifyDataLengths() must be called before attempting to input data
+       /*! This is the case for some schemes, such as CCM. */
+       virtual bool NeedsPrespecifiedDataLengths() const {return false;}
+       //! this function only needs to be called if NeedsPrespecifiedDataLengths() returns true
+       void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0);
+       //! encrypt and generate MAC in one call. will truncate MAC if macSize < TagSize()
+       virtual void EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *message, size_t messageLength);
+       //! decrypt and verify MAC in one call, returning true iff MAC is valid. will assume MAC is truncated if macLength < TagSize()
+       virtual bool DecryptAndVerify(byte *message, const byte *mac, size_t macLength, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *ciphertext, size_t ciphertextLength);
+
+       // redeclare this to avoid compiler ambiguity errors
+       virtual std::string AlgorithmName() const =0;
+
+protected:
+       const Algorithm & GetAlgorithm() const {return *static_cast<const MessageAuthenticationCode *>(this);}
+       virtual void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) {}
+};
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+typedef SymmetricCipher StreamCipher;
+#endif
+
+//! interface for random number generators
+/*! All return values are uniformly distributed over the range specified.
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm
+{
+public:
+       //! update RNG state with additional unpredictable values
+       virtual void IncorporateEntropy(const byte *input, size_t length) {throw NotImplemented("RandomNumberGenerator: IncorporateEntropy not implemented");}
+
+       //! returns true if IncorporateEntropy is implemented
+       virtual bool CanIncorporateEntropy() const {return false;}
+
+       //! generate new random byte and return it
+       virtual byte GenerateByte();
+
+       //! generate new random bit and return it
+       /*! Default implementation is to call GenerateByte() and return its lowest bit. */
+       virtual unsigned int GenerateBit();
+
+       //! generate a random 32 bit word in the range min to max, inclusive
+       virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL);
+
+       //! generate random array of bytes
+       virtual void GenerateBlock(byte *output, size_t size);
+
+       //! generate and discard n bytes
+       virtual void DiscardBytes(size_t n);
+
+       //! generate random bytes as input to a BufferedTransformation
+       virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length);
+
+       //! randomly shuffle the specified array, resulting permutation is uniformly distributed
+       template <class IT> void Shuffle(IT begin, IT end)
+       {
+               for (; begin != end; ++begin)
+                       std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1));
+       }
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+       byte GetByte() {return GenerateByte();}
+       unsigned int GetBit() {return GenerateBit();}
+       word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);}
+       word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);}
+       void GetBlock(byte *output, size_t size) {GenerateBlock(output, size);}
+#endif
+};
+
+//! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it
+CRYPTOPP_DLL RandomNumberGenerator & CRYPTOPP_API NullRNG();
+
+class WaitObjectContainer;
+class CallStack;
+
+//! interface for objects that you can wait for
+
+class CRYPTOPP_NO_VTABLE Waitable
+{
+public:
+       virtual ~Waitable() {}
+
+       //! maximum number of wait objects that this object can return
+       virtual unsigned int GetMaxWaitObjectCount() const =0;
+       //! put wait objects into container
+       /*! \param callStack is used for tracing no wait loops, example:
+                    something.GetWaitObjects(c, CallStack("my func after X", 0));
+                          - or in an outer GetWaitObjects() method that itself takes a callStack parameter:
+                            innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack)); */
+       virtual void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) =0;
+       //! wait on this object
+       /*! same as creating an empty container, calling GetWaitObjects(), and calling Wait() on the container */
+       bool Wait(unsigned long milliseconds, CallStack const& callStack);
+};
+
+//! the default channel for BufferedTransformation, equal to the empty string
+extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL;
+
+//! channel for additional authenticated data, equal to "AAD"
+extern CRYPTOPP_DLL const std::string AAD_CHANNEL;
+
+//! interface for buffered transformations
+
+/*! BufferedTransformation is a generalization of BlockTransformation,
+       StreamTransformation, and HashTransformation.
+
+       A buffered transformation is an object that takes a stream of bytes
+       as input (this may be done in stages), does some computation on them, and
+       then places the result into an internal buffer for later retrieval.  Any
+       partial result already in the output buffer is not modified by further
+       input.
+
+       If a method takes a "blocking" parameter, and you
+       pass "false" for it, the method will return before all input has been processed if
+       the input cannot be processed without waiting (for network buffers to become available, for example).
+       In this case the method will return true
+       or a non-zero integer value. When this happens you must continue to call the method with the same
+       parameters until it returns false or zero, before calling any other method on it or
+       attached BufferedTransformation. The integer return value in this case is approximately
+       the number of bytes left to be processed, and can be used to implement a progress bar.
+
+       For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached
+       BufferedTransformation objects, with propagation decremented at each step until it reaches 0.
+       -1 means unlimited propagation.
+
+       \nosubgrouping
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable
+{
+public:
+       // placed up here for CW8
+       static const std::string &NULL_CHANNEL; // same as DEFAULT_CHANNEL, for backwards compatibility
+
+       BufferedTransformation() : Algorithm(false) {}
+
+       //! return a reference to this object
+       /*! This function is useful for passing a temporary BufferedTransformation object to a 
+               function that takes a non-const reference. */
+       BufferedTransformation& Ref() {return *this;}
+
+       //!     \name INPUT
+       //@{
+               //! input a byte for processing
+               size_t Put(byte inByte, bool blocking=true)
+                       {return Put(&inByte, 1, blocking);}
+               //! input multiple bytes
+               size_t Put(const byte *inString, size_t length, bool blocking=true)
+                       {return Put2(inString, length, 0, blocking);}
+
+               //! input a 16-bit word
+               size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
+               //! input a 32-bit word
+               size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
+
+               //! request space which can be written into by the caller, and then used as input to Put()
+               /*! \param size is requested size (as a hint) for input, and size of the returned space for output */
+               /*! \note The purpose of this method is to help avoid doing extra memory allocations. */
+               virtual byte * CreatePutSpace(size_t &size) {size=0; return NULL;}
+
+               virtual bool CanModifyInput() const {return false;}
+
+               //! input multiple bytes that may be modified by callee
+               size_t PutModifiable(byte *inString, size_t length, bool blocking=true)
+                       {return PutModifiable2(inString, length, 0, blocking);}
+
+               bool MessageEnd(int propagation=-1, bool blocking=true)
+                       {return !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
+               size_t PutMessageEnd(const byte *inString, size_t length, int propagation=-1, bool blocking=true)
+                       {return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
+
+               //! input multiple bytes for blocking or non-blocking processing
+               /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */
+               virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) =0;
+               //! input multiple bytes that may be modified by callee for blocking or non-blocking processing
+               /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */
+               virtual size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
+                       {return Put2(inString, length, messageEnd, blocking);}
+
+               //! thrown by objects that have not implemented nonblocking input processing
+               struct BlockingInputOnly : public NotImplemented
+                       {BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}};
+       //@}
+
+       //!     \name WAITING
+       //@{
+               unsigned int GetMaxWaitObjectCount() const;
+               void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
+       //@}
+
+       //!     \name SIGNALS
+       //@{
+               virtual void IsolatedInitialize(const NameValuePairs &parameters) {throw NotImplemented("BufferedTransformation: this object can't be reinitialized");}
+               virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0;
+               virtual bool IsolatedMessageSeriesEnd(bool blocking) {return false;}
+
+               //! initialize or reinitialize this object
+               virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
+               //! flush buffered input and/or output
+               /*! \param hardFlush is used to indicate whether all data should be flushed
+                       \note Hard flushes must be used with care. It means try to process and output everything, even if
+                       there may not be enough data to complete the action. For example, hard flushing a HexDecoder would
+                       cause an error if you do it after inputing an odd number of hex encoded characters.
+                       For some types of filters, for example ZlibDecompressor, hard flushes can only
+                       be done at "synchronization points". These synchronization points are positions in the data
+                       stream that are created by hard flushes on the corresponding reverse filters, in this
+                       example ZlibCompressor. This is useful when zlib compressed data is moved across a
+                       network in packets and compression state is preserved across packets, as in the ssh2 protocol.
+               */
+               virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
+               //! mark end of a series of messages
+               /*! There should be a MessageEnd immediately before MessageSeriesEnd. */
+               virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
+
+               //! set propagation of automatically generated and transferred signals
+               /*! propagation == 0 means do not automaticly generate signals */
+               virtual void SetAutoSignalPropagation(int propagation) {}
+
+               //!
+               virtual int GetAutoSignalPropagation() const {return 0;}
+public:
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+               void Close() {MessageEnd();}
+#endif
+       //@}
+
+       //!     \name RETRIEVAL OF ONE MESSAGE
+       //@{
+               //! returns number of bytes that is currently ready for retrieval
+               /*! All retrieval functions return the actual number of bytes
+                       retrieved, which is the lesser of the request number and
+                       MaxRetrievable(). */
+               virtual lword MaxRetrievable() const;
+
+               //! returns whether any bytes are currently ready for retrieval
+               virtual bool AnyRetrievable() const;
+
+               //! try to retrieve a single byte
+               virtual size_t Get(byte &outByte);
+               //! try to retrieve multiple bytes
+               virtual size_t Get(byte *outString, size_t getMax);
+
+               //! peek at the next byte without removing it from the output buffer
+               virtual size_t Peek(byte &outByte) const;
+               //! peek at multiple bytes without removing them from the output buffer
+               virtual size_t Peek(byte *outString, size_t peekMax) const;
+
+               //! try to retrieve a 16-bit word
+               size_t GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER);
+               //! try to retrieve a 32-bit word
+               size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER);
+
+               //! try to peek at a 16-bit word
+               size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
+               //! try to peek at a 32-bit word
+               size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
+
+               //! move transferMax bytes of the buffered output to target as input
+               lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL)
+                       {TransferTo2(target, transferMax, channel); return transferMax;}
+
+               //! discard skipMax bytes from the output buffer
+               virtual lword Skip(lword skipMax=LWORD_MAX);
+
+               //! copy copyMax bytes of the buffered output to target as input
+               lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
+                       {return CopyRangeTo(target, 0, copyMax, channel);}
+
+               //! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input
+               lword CopyRangeTo(BufferedTransformation &target, lword position, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
+                       {lword i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;}
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+               unsigned long MaxRetrieveable() const {return MaxRetrievable();}
+#endif
+       //@}
+
+       //!     \name RETRIEVAL OF MULTIPLE MESSAGES
+       //@{
+               //!
+               virtual lword TotalBytesRetrievable() const;
+               //! number of times MessageEnd() has been received minus messages retrieved or skipped
+               virtual unsigned int NumberOfMessages() const;
+               //! returns true if NumberOfMessages() > 0
+               virtual bool AnyMessages() const;
+               //! start retrieving the next message
+               /*!
+                       Returns false if no more messages exist or this message 
+                       is not completely retrieved.
+               */
+               virtual bool GetNextMessage();
+               //! skip count number of messages
+               virtual unsigned int SkipMessages(unsigned int count=UINT_MAX);
+               //!
+               unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL)
+                       {TransferMessagesTo2(target, count, channel); return count;}
+               //!
+               unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const;
+
+               //!
+               virtual void SkipAll();
+               //!
+               void TransferAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL)
+                       {TransferAllTo2(target, channel);}
+               //!
+               void CopyAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) const;
+
+               virtual bool GetNextMessageSeries() {return false;}
+               virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();}
+               virtual unsigned int NumberOfMessageSeries() const {return 0;}
+       //@}
+
+       //!     \name NON-BLOCKING TRANSFER OF OUTPUT
+       //@{
+               //! upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
+               virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) =0;
+               //! upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block
+               virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0;
+               //! upon return, messageCount contains number of messages that have finished being transfered, and returns the number of bytes left in the current transfer block
+               size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
+               //! returns the number of bytes left in the current transfer block
+               size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
+       //@}
+
+       //!     \name CHANNELS
+       //@{
+               struct NoChannelSupport : public NotImplemented
+                       {NoChannelSupport(const std::string &name) : NotImplemented(name + ": this object doesn't support multiple channels") {}};
+               struct InvalidChannelName : public InvalidArgument
+                       {InvalidChannelName(const std::string &name, const std::string &channel) : InvalidArgument(name + ": unexpected channel name \"" + channel + "\"") {}};
+
+               size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true)
+                       {return ChannelPut(channel, &inByte, 1, blocking);}
+               size_t ChannelPut(const std::string &channel, const byte *inString, size_t length, bool blocking=true)
+                       {return ChannelPut2(channel, inString, length, 0, blocking);}
+
+               size_t ChannelPutModifiable(const std::string &channel, byte *inString, size_t length, bool blocking=true)
+                       {return ChannelPutModifiable2(channel, inString, length, 0, blocking);}
+
+               size_t ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
+               size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
+
+               bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true)
+                       {return !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
+               size_t ChannelPutMessageEnd(const std::string &channel, const byte *inString, size_t length, int propagation=-1, bool blocking=true)
+                       {return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
+
+               virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size);
+
+               virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking);
+               virtual size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking);
+
+               virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true);
+               virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true);
+
+               virtual void SetRetrievalChannel(const std::string &channel);
+       //@}
+
+       //!     \name ATTACHMENT
+       /*! Some BufferedTransformation objects (e.g. Filter objects)
+               allow other BufferedTransformation objects to be attached. When
+               this is done, the first object instead of buffering its output,
+               sents that output to the attached object as input. The entire
+               attachment chain is deleted when the anchor object is destructed.
+       */
+       //@{
+               //! returns whether this object allows attachment
+               virtual bool Attachable() {return false;}
+               //! returns the object immediately attached to this object or NULL for no attachment
+               virtual BufferedTransformation *AttachedTransformation() {assert(!Attachable()); return 0;}
+               //!
+               virtual const BufferedTransformation *AttachedTransformation() const
+                       {return const_cast<BufferedTransformation *>(this)->AttachedTransformation();}
+               //! delete the current attachment chain and replace it with newAttachment
+               virtual void Detach(BufferedTransformation *newAttachment = 0)
+                       {assert(!Attachable()); throw NotImplemented("BufferedTransformation: this object is not attachable");}
+               //! add newAttachment to the end of attachment chain
+               virtual void Attach(BufferedTransformation *newAttachment);
+       //@}
+
+protected:
+       static int DecrementPropagation(int propagation)
+               {return propagation != 0 ? propagation - 1 : 0;}
+
+private:
+       byte m_buf[4];  // for ChannelPutWord16 and ChannelPutWord32, to ensure buffer isn't deallocated before non-blocking operation completes
+};
+
+//! returns a reference to a BufferedTransformation object that discards all input
+BufferedTransformation & TheBitBucket();
+
+//! interface for crypto material, such as public and private keys, and crypto parameters
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoMaterial : public NameValuePairs
+{
+public:
+       //! exception thrown when invalid crypto material is detected
+       class CRYPTOPP_DLL InvalidMaterial : public InvalidDataFormat
+       {
+       public:
+               explicit InvalidMaterial(const std::string &s) : InvalidDataFormat(s) {}
+       };
+
+       //! assign values from source to this object
+       /*! \note This function can be used to create a public key from a private key. */
+       virtual void AssignFrom(const NameValuePairs &source) =0;
+
+       //! check this object for errors
+       /*! \param level denotes the level of thoroughness:
+               0 - using this object won't cause a crash or exception (rng is ignored)
+               1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such)
+               2 - make sure this object will function correctly, and do reasonable security checks
+               3 - do checks that may take a long time
+               \return true if the tests pass */
+       virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0;
+
+       //! throws InvalidMaterial if this object fails Validate() test
+       virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const
+               {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");}
+
+//     virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false);
+
+       //! save key into a BufferedTransformation
+       virtual void Save(BufferedTransformation &bt) const
+               {throw NotImplemented("CryptoMaterial: this object does not support saving");}
+
+       //! load key from a BufferedTransformation
+       /*! \throws KeyingErr if decode fails
+               \note Generally does not check that the key is valid.
+                       Call ValidateKey() or ThrowIfInvalidKey() to check that. */
+       virtual void Load(BufferedTransformation &bt)
+               {throw NotImplemented("CryptoMaterial: this object does not support loading");}
+
+       //! \return whether this object supports precomputation
+       virtual bool SupportsPrecomputation() const {return false;}
+       //! do precomputation
+       /*! The exact semantics of Precompute() is varies, but
+               typically it means calculate a table of n objects
+               that can be used later to speed up computation. */
+       virtual void Precompute(unsigned int n)
+               {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
+       //! retrieve previously saved precomputation
+       virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
+               {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
+       //! save precomputation for later use
+       virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
+               {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
+
+       // for internal library use
+       void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);}
+
+#if (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
+       // Sun Studio 11/CC 5.8 workaround: it generates incorrect code when casting to an empty virtual base class
+       char m_sunCCworkaround;
+#endif
+};
+
+//! interface for generatable crypto material, such as private keys and crypto parameters
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public CryptoMaterial
+{
+public:
+       //! generate a random key or crypto parameters
+       /*! \throws KeyingErr if algorithm parameters are invalid, or if a key can't be generated
+               (e.g., if this is a public key object) */
+       virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs)
+               {throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation");}
+
+       //! calls the above function with a NameValuePairs object that just specifies "KeySize"
+       void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize);
+};
+
+//! interface for public keys
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKey : virtual public CryptoMaterial
+{
+};
+
+//! interface for private keys
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKey : public GeneratableCryptoMaterial
+{
+};
+
+//! interface for crypto prameters
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoParameters : public GeneratableCryptoMaterial
+{
+};
+
+//! interface for asymmetric algorithms
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : public Algorithm
+{
+public:
+       //! returns a reference to the crypto material used by this object
+       virtual CryptoMaterial & AccessMaterial() =0;
+       //! returns a const reference to the crypto material used by this object
+       virtual const CryptoMaterial & GetMaterial() const =0;
+
+       //! for backwards compatibility, calls AccessMaterial().Load(bt)
+       void BERDecode(BufferedTransformation &bt)
+               {AccessMaterial().Load(bt);}
+       //! for backwards compatibility, calls GetMaterial().Save(bt)
+       void DEREncode(BufferedTransformation &bt) const
+               {GetMaterial().Save(bt);}
+};
+
+//! interface for asymmetric algorithms using public keys
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : public AsymmetricAlgorithm
+{
+public:
+       // VC60 workaround: no co-variant return type
+       CryptoMaterial & AccessMaterial() {return AccessPublicKey();}
+       const CryptoMaterial & GetMaterial() const {return GetPublicKey();}
+
+       virtual PublicKey & AccessPublicKey() =0;
+       virtual const PublicKey & GetPublicKey() const {return const_cast<PublicKeyAlgorithm *>(this)->AccessPublicKey();}
+};
+
+//! interface for asymmetric algorithms using private keys
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : public AsymmetricAlgorithm
+{
+public:
+       CryptoMaterial & AccessMaterial() {return AccessPrivateKey();}
+       const CryptoMaterial & GetMaterial() const {return GetPrivateKey();}
+
+       virtual PrivateKey & AccessPrivateKey() =0;
+       virtual const PrivateKey & GetPrivateKey() const {return const_cast<PrivateKeyAlgorithm *>(this)->AccessPrivateKey();}
+};
+
+//! interface for key agreement algorithms
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE KeyAgreementAlgorithm : public AsymmetricAlgorithm
+{
+public:
+       CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();}
+       const CryptoMaterial & GetMaterial() const {return GetCryptoParameters();}
+
+       virtual CryptoParameters & AccessCryptoParameters() =0;
+       virtual const CryptoParameters & GetCryptoParameters() const {return const_cast<KeyAgreementAlgorithm *>(this)->AccessCryptoParameters();}
+};
+
+//! interface for public-key encryptors and decryptors
+
+/*! This class provides an interface common to encryptors and decryptors
+       for querying their plaintext and ciphertext lengths.
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_CryptoSystem
+{
+public:
+       virtual ~PK_CryptoSystem() {}
+
+       //! maximum length of plaintext for a given ciphertext length
+       /*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */
+       virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0;
+
+       //! calculate length of ciphertext given length of plaintext
+       /*! \note This function returns 0 if plaintextLength is not valid (too long). */
+       virtual size_t CiphertextLength(size_t plaintextLength) const =0;
+
+       //! this object supports the use of the parameter with the given name
+       /*! some possible parameter names: EncodingParameters, KeyDerivationParameters */
+       virtual bool ParameterSupported(const char *name) const =0;
+
+       //! return fixed ciphertext length, if one exists, otherwise return 0
+       /*! \note "Fixed" here means length of ciphertext does not depend on length of plaintext.
+               It usually does depend on the key length. */
+       virtual size_t FixedCiphertextLength() const {return 0;}
+
+       //! return maximum plaintext length given the fixed ciphertext length, if one exists, otherwise return 0
+       virtual size_t FixedMaxPlaintextLength() const {return 0;}
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+       size_t MaxPlainTextLength(size_t cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);}
+       size_t CipherTextLength(size_t plainTextLength) const {return CiphertextLength(plainTextLength);}
+#endif
+};
+
+//! interface for public-key encryptors
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : public PK_CryptoSystem, public PublicKeyAlgorithm
+{
+public:
+       //! exception thrown when trying to encrypt plaintext of invalid length
+       class CRYPTOPP_DLL InvalidPlaintextLength : public Exception
+       {
+       public:
+               InvalidPlaintextLength() : Exception(OTHER_ERROR, "PK_Encryptor: invalid plaintext length") {}
+       };
+
+       //! encrypt a byte string
+       /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long)
+               \pre size of ciphertext == CiphertextLength(plaintextLength)
+       */
+       virtual void Encrypt(RandomNumberGenerator &rng, 
+               const byte *plaintext, size_t plaintextLength, 
+               byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const =0;
+
+       //! create a new encryption filter
+       /*! \note The caller is responsible for deleting the returned pointer.
+               \note Encoding parameters should be passed in the "EP" channel.
+       */
+       virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, 
+               BufferedTransformation *attachment=NULL, const NameValuePairs &parameters = g_nullNameValuePairs) const;
+};
+
+//! interface for public-key decryptors
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : public PK_CryptoSystem, public PrivateKeyAlgorithm
+{
+public:
+       //! decrypt a byte string, and return the length of plaintext
+       /*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes.
+               \return the actual length of the plaintext, indication that decryption failed.
+       */
+       virtual DecodingResult Decrypt(RandomNumberGenerator &rng, 
+               const byte *ciphertext, size_t ciphertextLength, 
+               byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const =0;
+
+       //! create a new decryption filter
+       /*! \note caller is responsible for deleting the returned pointer
+       */
+       virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, 
+               BufferedTransformation *attachment=NULL, const NameValuePairs &parameters = g_nullNameValuePairs) const;
+
+       //! decrypt a fixed size ciphertext
+       DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
+               {return Decrypt(rng, ciphertext, FixedCiphertextLength(), plaintext, parameters);}
+};
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+typedef PK_CryptoSystem PK_FixedLengthCryptoSystem;
+typedef PK_Encryptor PK_FixedLengthEncryptor;
+typedef PK_Decryptor PK_FixedLengthDecryptor;
+#endif
+
+//! interface for public-key signers and verifiers
+
+/*! This class provides an interface common to signers and verifiers
+       for querying scheme properties.
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme
+{
+public:
+       //! 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
+       class CRYPTOPP_DLL InvalidKeyLength : public Exception
+       {
+       public:
+               InvalidKeyLength(const std::string &message) : Exception(OTHER_ERROR, message) {}
+       };
+
+       //! 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
+       class CRYPTOPP_DLL KeyTooShort : public InvalidKeyLength
+       {
+       public:
+               KeyTooShort() : InvalidKeyLength("PK_Signer: key too short for this signature scheme") {}
+       };
+
+       virtual ~PK_SignatureScheme() {}
+
+       //! signature length if it only depends on the key, otherwise 0
+       virtual size_t SignatureLength() const =0;
+
+       //! maximum signature length produced for a given length of recoverable message part
+       virtual size_t MaxSignatureLength(size_t recoverablePartLength = 0) const {return SignatureLength();}
+
+       //! length of longest message that can be recovered, or 0 if this signature scheme does not support message recovery
+       virtual size_t MaxRecoverableLength() const =0;
+
+       //! length of longest message that can be recovered from a signature of given length, or 0 if this signature scheme does not support message recovery
+       virtual size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const =0;
+
+       //! requires a random number generator to sign
+       /*! if this returns false, NullRNG() can be passed to functions that take RandomNumberGenerator & */
+       virtual bool IsProbabilistic() const =0;
+
+       //! whether or not a non-recoverable message part can be signed
+       virtual bool AllowNonrecoverablePart() const =0;
+
+       //! if this function returns true, during verification you must input the signature before the message, otherwise you can input it at anytime */
+       virtual bool SignatureUpfront() const {return false;}
+
+       //! whether you must input the recoverable part before the non-recoverable part during signing
+       virtual bool RecoverablePartFirst() const =0;
+};
+
+//! interface for accumulating messages to be signed or verified
+/*! Only Update() should be called
+       on this class. No other functions inherited from HashTransformation should be called.
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulator : public HashTransformation
+{
+public:
+       //! should not be called on PK_MessageAccumulator
+       unsigned int DigestSize() const
+               {throw NotImplemented("PK_MessageAccumulator: DigestSize() should not be called");}
+       //! should not be called on PK_MessageAccumulator
+       void TruncatedFinal(byte *digest, size_t digestSize) 
+               {throw NotImplemented("PK_MessageAccumulator: TruncatedFinal() should not be called");}
+};
+
+//! interface for public-key signers
+
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Signer : public PK_SignatureScheme, public PrivateKeyAlgorithm
+{
+public:
+       //! create a new HashTransformation to accumulate the message to be signed
+       virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0;
+
+       virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const =0;
+
+       //! sign and delete messageAccumulator (even in case of exception thrown)
+       /*! \pre size of signature == MaxSignatureLength()
+               \return actual signature length
+       */
+       virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const;
+
+       //! sign and restart messageAccumulator
+       /*! \pre size of signature == MaxSignatureLength()
+               \return actual signature length
+       */
+       virtual size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0;
+
+       //! sign a message
+       /*! \pre size of signature == MaxSignatureLength()
+               \return actual signature length
+       */
+       virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const;
+
+       //! sign a recoverable message
+       /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength)
+               \return actual signature length
+       */
+       virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, 
+               const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const;
+};
+
+//! interface for public-key signature verifiers
+/*! The Recover* functions throw NotImplemented if the signature scheme does not support
+       message recovery.
+       The Verify* functions throw InvalidDataFormat if the scheme does support message
+       recovery and the signature contains a non-empty recoverable message part. The
+       Recovery* functions should be used in that case.
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Verifier : public PK_SignatureScheme, public PublicKeyAlgorithm
+{
+public:
+       //! create a new HashTransformation to accumulate the message to be verified
+       virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0;
+
+       //! input signature into a message accumulator
+       virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0;
+
+       //! check whether messageAccumulator contains a valid signature and message, and delete messageAccumulator (even in case of exception thrown)
+       virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const;
+
+       //! check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator
+       virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0;
+
+       //! check whether input signature is a valid signature for input message
+       virtual bool VerifyMessage(const byte *message, size_t messageLen, 
+               const byte *signature, size_t signatureLength) const;
+
+       //! recover a message from its signature
+       /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
+       */
+       virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const;
+
+       //! recover a message from its signature
+       /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
+       */
+       virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0;
+
+       //! recover a message from its signature
+       /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
+       */
+       virtual DecodingResult RecoverMessage(byte *recoveredMessage, 
+               const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, 
+               const byte *signature, size_t signatureLength) const;
+};
+
+//! interface for domains of simple key agreement protocols
+
+/*! A key agreement domain is a set of parameters that must be shared
+       by two parties in a key agreement protocol, along with the algorithms
+       for generating key pairs and deriving agreed values.
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyAgreementDomain : public KeyAgreementAlgorithm
+{
+public:
+       //! return length of agreed value produced
+       virtual unsigned int AgreedValueLength() const =0;
+       //! return length of private keys in this domain
+       virtual unsigned int PrivateKeyLength() const =0;
+       //! return length of public keys in this domain
+       virtual unsigned int PublicKeyLength() const =0;
+       //! generate private key
+       /*! \pre size of privateKey == PrivateKeyLength() */
+       virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
+       //! generate public key
+       /*!     \pre size of publicKey == PublicKeyLength() */
+       virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
+       //! generate private/public key pair
+       /*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */
+       virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
+       //! derive agreed value from your private key and couterparty's public key, return false in case of failure
+       /*! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time.
+               \pre size of agreedValue == AgreedValueLength()
+               \pre length of privateKey == PrivateKeyLength()
+               \pre length of otherPublicKey == PublicKeyLength()
+       */
+       virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0;
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+       bool ValidateDomainParameters(RandomNumberGenerator &rng) const
+               {return GetCryptoParameters().Validate(rng, 2);}
+#endif
+};
+
+//! interface for domains of authenticated key agreement protocols
+
+/*! In an authenticated key agreement protocol, each party has two
+       key pairs. The long-lived key pair is called the static key pair,
+       and the short-lived key pair is called the ephemeral key pair.
+*/
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm
+{
+public:
+       //! return length of agreed value produced
+       virtual unsigned int AgreedValueLength() const =0;
+
+       //! return length of static private keys in this domain
+       virtual unsigned int StaticPrivateKeyLength() const =0;
+       //! return length of static public keys in this domain
+       virtual unsigned int StaticPublicKeyLength() const =0;
+       //! generate static private key
+       /*! \pre size of privateKey == PrivateStaticKeyLength() */
+       virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
+       //! generate static public key
+       /*!     \pre size of publicKey == PublicStaticKeyLength() */
+       virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
+       //! generate private/public key pair
+       /*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */
+       virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
+
+       //! return length of ephemeral private keys in this domain
+       virtual unsigned int EphemeralPrivateKeyLength() const =0;
+       //! return length of ephemeral public keys in this domain
+       virtual unsigned int EphemeralPublicKeyLength() const =0;
+       //! generate ephemeral private key
+       /*! \pre size of privateKey == PrivateEphemeralKeyLength() */
+       virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
+       //! generate ephemeral public key
+       /*!     \pre size of publicKey == PublicEphemeralKeyLength() */
+       virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
+       //! generate private/public key pair
+       /*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */
+       virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
+
+       //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure
+       /*! \note The ephemeral public key will always be validated.
+                     If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.
+               \pre size of agreedValue == AgreedValueLength()
+               \pre length of staticPrivateKey == StaticPrivateKeyLength()
+               \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
+               \pre length of staticOtherPublicKey == StaticPublicKeyLength()
+               \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
+       */
+       virtual bool Agree(byte *agreedValue,
+               const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
+               const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
+               bool validateStaticOtherPublicKey=true) const =0;
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+       bool ValidateDomainParameters(RandomNumberGenerator &rng) const
+               {return GetCryptoParameters().Validate(rng, 2);}
+#endif
+};
+
+// interface for password authenticated key agreement protocols, not implemented yet
+#if 0
+//! interface for protocol sessions
+/*! The methods should be called in the following order:
+
+       InitializeSession(rng, parameters);     // or call initialize method in derived class
+       while (true)
+       {
+               if (OutgoingMessageAvailable())
+               {
+                       length = GetOutgoingMessageLength();
+                       GetOutgoingMessage(message);
+                       ; // send outgoing message
+               }
+
+               if (LastMessageProcessed())
+                       break;
+
+               ; // receive incoming message
+               ProcessIncomingMessage(message);
+       }
+       ; // call methods in derived class to obtain result of protocol session
+*/
+class ProtocolSession
+{
+public:
+       //! exception thrown when an invalid protocol message is processed
+       class ProtocolError : public Exception
+       {
+       public:
+               ProtocolError(ErrorType errorType, const std::string &s) : Exception(errorType, s) {}
+       };
+
+       //! exception thrown when a function is called unexpectedly
+       /*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */
+       class UnexpectedMethodCall : public Exception
+       {
+       public:
+               UnexpectedMethodCall(const std::string &s) : Exception(OTHER_ERROR, s) {}
+       };
+
+       ProtocolSession() : m_rng(NULL), m_throwOnProtocolError(true), m_validState(false) {}
+       virtual ~ProtocolSession() {}
+
+       virtual void InitializeSession(RandomNumberGenerator &rng, const NameValuePairs &parameters) =0;
+
+       bool GetThrowOnProtocolError() const {return m_throwOnProtocolError;}
+       void SetThrowOnProtocolError(bool throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;}
+
+       bool HasValidState() const {return m_validState;}
+
+       virtual bool OutgoingMessageAvailable() const =0;
+       virtual unsigned int GetOutgoingMessageLength() const =0;
+       virtual void GetOutgoingMessage(byte *message) =0;
+
+       virtual bool LastMessageProcessed() const =0;
+       virtual void ProcessIncomingMessage(const byte *message, unsigned int messageLength) =0;
+
+protected:
+       void HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const;
+       void CheckAndHandleInvalidState() const;
+       void SetValidState(bool valid) {m_validState = valid;}
+
+       RandomNumberGenerator *m_rng;
+
+private:
+       bool m_throwOnProtocolError, m_validState;
+};
+
+class KeyAgreementSession : public ProtocolSession
+{
+public:
+       virtual unsigned int GetAgreedValueLength() const =0;
+       virtual void GetAgreedValue(byte *agreedValue) const =0;
+};
+
+class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession
+{
+public:
+       void InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng, 
+               const byte *myId, unsigned int myIdLength, 
+               const byte *counterPartyId, unsigned int counterPartyIdLength, 
+               const byte *passwordOrVerifier, unsigned int passwordOrVerifierLength);
+};
+
+class PasswordAuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm
+{
+public:
+       //! return whether the domain parameters stored in this object are valid
+       virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const
+               {return GetCryptoParameters().Validate(rng, 2);}
+
+       virtual unsigned int GetPasswordVerifierLength(const byte *password, unsigned int passwordLength) const =0;
+       virtual void GeneratePasswordVerifier(RandomNumberGenerator &rng, const byte *userId, unsigned int userIdLength, const byte *password, unsigned int passwordLength, byte *verifier) const =0;
+
+       enum RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8};
+
+       virtual bool IsValidRole(unsigned int role) =0;
+       virtual PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(unsigned int role) const =0;
+};
+#endif
+
+//! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation
+class CRYPTOPP_DLL BERDecodeErr : public InvalidArgument
+{
+public: 
+       BERDecodeErr() : InvalidArgument("BER decode error") {}
+       BERDecodeErr(const std::string &s) : InvalidArgument(s) {}
+};
+
+//! interface for encoding and decoding ASN1 objects
+class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object
+{
+public:
+       virtual ~ASN1Object() {}
+       //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules)
+       virtual void BERDecode(BufferedTransformation &bt) =0;
+       //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules)
+       virtual void DEREncode(BufferedTransformation &bt) const =0;
+       //! encode this object into a BufferedTransformation, using BER
+       /*! this may be useful if DEREncode() would be too inefficient */
+       virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);}
+};
+
+#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
+typedef PK_SignatureScheme PK_SignatureSystem;
+typedef SimpleKeyAgreementDomain PK_SimpleKeyAgreementDomain;
+typedef AuthenticatedKeyAgreementDomain PK_AuthenticatedKeyAgreementDomain;
+#endif
+
+NAMESPACE_END
+
+#endif
diff --git a/cryptopp/iterhash.h b/cryptopp/iterhash.h
new file mode 100644 (file)
index 0000000..2f5895e
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef CRYPTOPP_ITERHASH_H
+#define CRYPTOPP_ITERHASH_H
+
+#include "secblock.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// *** trimmed down dependency from iterhash.h ***
+template <class T_HashWordType, class T_Endianness, unsigned int T_BlockSize, unsigned int T_StateSize, class T_Transform, unsigned int T_DigestSize = 0, bool T_StateAligned = false>
+class CRYPTOPP_NO_VTABLE IteratedHashWithStaticTransform
+{
+public:
+       CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize ? T_DigestSize : T_StateSize)
+       unsigned int DigestSize() const {return DIGESTSIZE;};
+    typedef T_HashWordType HashWordType;
+    CRYPTOPP_CONSTANT(BLOCKSIZE = T_BlockSize)
+
+protected:
+       IteratedHashWithStaticTransform() {this->Init();}
+       void HashEndianCorrectedBlock(const T_HashWordType *data) {T_Transform::Transform(this->m_state, data);}
+       void Init() {T_Transform::InitState(this->m_state);}
+
+       T_HashWordType* StateBuf() {return this->m_state;}
+       FixedSizeAlignedSecBlock<T_HashWordType, T_BlockSize/sizeof(T_HashWordType), T_StateAligned> m_state;
+};
+
+NAMESPACE_END
+
+#endif
diff --git a/cryptopp/misc.h b/cryptopp/misc.h
new file mode 100644 (file)
index 0000000..de8037b
--- /dev/null
@@ -0,0 +1,1134 @@
+#ifndef CRYPTOPP_MISC_H
+#define CRYPTOPP_MISC_H
+
+#include "cryptlib.h"
+#include "smartptr.h"
+#include <string.h>            // for memcpy and memmove
+
+#ifdef _MSC_VER
+       #include <stdlib.h>
+       #if _MSC_VER >= 1400
+               // VC2005 workaround: disable declarations that conflict with winnt.h
+               #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1
+               #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2
+               #define _interlockedbittestandset64 CRYPTOPP_DISABLED_INTRINSIC_3
+               #define _interlockedbittestandreset64 CRYPTOPP_DISABLED_INTRINSIC_4
+               #include <intrin.h>
+               #undef _interlockedbittestandset
+               #undef _interlockedbittestandreset
+               #undef _interlockedbittestandset64
+               #undef _interlockedbittestandreset64
+               #define CRYPTOPP_FAST_ROTATE(x) 1
+       #elif _MSC_VER >= 1300
+               #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
+       #else
+               #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
+       #endif
+#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
+       (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
+       #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
+#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86)    // depend on GCC's peephole optimization to generate rotate instructions
+       #define CRYPTOPP_FAST_ROTATE(x) 1
+#else
+       #define CRYPTOPP_FAST_ROTATE(x) 0
+#endif
+
+#ifdef __BORLANDC__
+#include <mem.h>
+#endif
+
+#if defined(__GNUC__) && defined(__linux__)
+#define CRYPTOPP_BYTESWAP_AVAILABLE
+#include <byteswap.h>
+#endif
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// ************** compile-time assertion ***************
+
+template <bool b>
+struct CompileAssert
+{
+       static char dummy[2*b-1];
+};
+
+#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
+#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
+#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
+#else
+#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
+#endif
+#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
+#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
+
+// ************** misc classes ***************
+
+class CRYPTOPP_DLL Empty
+{
+};
+
+//! _
+template <class BASE1, class BASE2>
+class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2
+{
+};
+
+//! _
+template <class BASE1, class BASE2, class BASE3>
+class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3
+{
+};
+
+template <class T>
+class ObjectHolder
+{
+protected:
+       T m_object;
+};
+
+class NotCopyable
+{
+public:
+       NotCopyable() {}
+private:
+    NotCopyable(const NotCopyable &);
+    void operator=(const NotCopyable &);
+};
+
+template <class T>
+struct NewObject
+{
+       T* operator()() const {return new T;}
+};
+
+/*! This function safely initializes a static object in a multithreaded environment without using locks.
+       It may leak memory when two threads try to initialize the static object at the same time
+       but this should be acceptable since each static object is only initialized once per session.
+*/
+template <class T, class F = NewObject<T>, int instance=0>
+class Singleton
+{
+public:
+       Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {}
+
+       // prevent this function from being inlined
+       CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const;
+
+private:
+       F m_objectFactory;
+};
+
+template <class T, class F, int instance>
+const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
+{
+       static simple_ptr<T> s_pObject;
+       static char s_objectState = 0;
+
+retry:
+       switch (s_objectState)
+       {
+       case 0:
+               s_objectState = 1;
+               try
+               {
+                       s_pObject.m_p = m_objectFactory();
+               }
+               catch(...)
+               {
+                       s_objectState = 0;
+                       throw;
+               }
+               s_objectState = 2;
+               break;
+       case 1:
+               goto retry;
+       default:
+               break;
+       }
+       return *s_pObject.m_p;
+}
+
+// ************** misc functions ***************
+
+#if (!__STDC_WANT_SECURE_LIB__)
+inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
+{
+       if (count > sizeInBytes)
+               throw InvalidArgument("memcpy_s: buffer overflow");
+       memcpy(dest, src, count);
+}
+
+inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
+{
+       if (count > sizeInBytes)
+               throw InvalidArgument("memmove_s: buffer overflow");
+       memmove(dest, src, count);
+}
+#endif
+
+inline void * memset_z(void *ptr, int value, size_t num)
+{
+// avoid extranous warning on GCC 4.3.2 Ubuntu 8.10
+#if CRYPTOPP_GCC_VERSION >= 30001
+       if (__builtin_constant_p(num) && num==0)
+               return ptr;
+#endif
+       return memset(ptr, value, num);
+}
+
+// can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
+template <class T> inline const T& STDMIN(const T& a, const T& b)
+{
+       return b < a ? b : a;
+}
+
+template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b)
+{
+       CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0));
+       assert(a==0 || a>0);    // GCC workaround: get rid of the warning "comparison is always true due to limited range of data type"
+       assert(b>=0);
+
+       if (sizeof(T1)<=sizeof(T2))
+               return b < (T2)a ? (T1)b : a;
+       else
+               return (T1)b < a ? (T1)b : a;
+}
+
+template <class T> inline const T& STDMAX(const T& a, const T& b)
+{
+       return a < b ? b : a;
+}
+
+#define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue
+
+// this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
+#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
+// these may be faster on other CPUs/compilers
+// #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
+// #define GETBYTE(x, y) (((byte *)&(x))[y])
+
+#define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y)))
+
+template <class T>
+unsigned int Parity(T value)
+{
+       for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
+               value ^= value >> i;
+       return (unsigned int)value&1;
+}
+
+template <class T>
+unsigned int BytePrecision(const T &value)
+{
+       if (!value)
+               return 0;
+
+       unsigned int l=0, h=8*sizeof(value);
+
+       while (h-l > 8)
+       {
+               unsigned int t = (l+h)/2;
+               if (value >> t)
+                       l = t;
+               else
+                       h = t;
+       }
+
+       return h/8;
+}
+
+template <class T>
+unsigned int BitPrecision(const T &value)
+{
+       if (!value)
+               return 0;
+
+       unsigned int l=0, h=8*sizeof(value);
+
+       while (h-l > 1)
+       {
+               unsigned int t = (l+h)/2;
+               if (value >> t)
+                       l = t;
+               else
+                       h = t;
+       }
+
+       return h;
+}
+
+template <class T>
+inline T Crop(T value, size_t size)
+{
+       if (size < 8*sizeof(value))
+       return T(value & ((T(1) << size) - 1));
+       else
+               return value;
+}
+
+template <class T1, class T2>
+inline bool SafeConvert(T1 from, T2 &to)
+{
+       to = (T2)from;
+       if (from != to || (from > 0) != (to > 0))
+               return false;
+       return true;
+}
+
+inline size_t BitsToBytes(size_t bitCount)
+{
+       return ((bitCount+7)/(8));
+}
+
+inline size_t BytesToWords(size_t byteCount)
+{
+       return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
+}
+
+inline size_t BitsToWords(size_t bitCount)
+{
+       return ((bitCount+WORD_BITS-1)/(WORD_BITS));
+}
+
+inline size_t BitsToDwords(size_t bitCount)
+{
+       return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
+}
+
+CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count);
+CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count);
+
+CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count);
+
+template <class T>
+inline bool IsPowerOf2(const T &n)
+{
+       return n > 0 && (n & (n-1)) == 0;
+}
+
+template <class T1, class T2>
+inline T2 ModPowerOf2(const T1 &a, const T2 &b)
+{
+       assert(IsPowerOf2(b));
+       return T2(a) & (b-1);
+}
+
+template <class T1, class T2>
+inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
+{
+       if (IsPowerOf2(m))
+               return n - ModPowerOf2(n, m);
+       else
+               return n - n%m;
+}
+
+template <class T1, class T2>
+inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
+{
+       if (n+m-1 < n)
+               throw InvalidArgument("RoundUpToMultipleOf: integer overflow");
+       return RoundDownToMultipleOf(n+m-1, m);
+}
+
+template <class T>
+inline unsigned int GetAlignmentOf(T *dummy=NULL)      // VC60 workaround
+{
+#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
+       if (sizeof(T) < 16)
+               return 1;
+#endif
+
+#if (_MSC_VER >= 1300)
+       return __alignof(T);
+#elif defined(__GNUC__)
+       return __alignof__(T);
+#elif CRYPTOPP_BOOL_SLOW_WORD64
+       return UnsignedMin(4U, sizeof(T));
+#else
+       return sizeof(T);
+#endif
+}
+
+inline bool IsAlignedOn(const void *p, unsigned int alignment)
+{
+       return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0);
+}
+
+template <class T>
+inline bool IsAligned(const void *p, T *dummy=NULL)    // VC60 workaround
+{
+       return IsAlignedOn(p, GetAlignmentOf<T>());
+}
+
+#ifdef IS_LITTLE_ENDIAN
+       typedef LittleEndian NativeByteOrder;
+#else
+       typedef BigEndian NativeByteOrder;
+#endif
+
+inline ByteOrder GetNativeByteOrder()
+{
+       return NativeByteOrder::ToEnum();
+}
+
+inline bool NativeByteOrderIs(ByteOrder order)
+{
+       return order == GetNativeByteOrder();
+}
+
+template <class T>
+std::string IntToString(T a, unsigned int base = 10)
+{
+       if (a == 0)
+               return "0";
+       bool negate = false;
+       if (a < 0)
+       {
+               negate = true;
+               a = 0-a;        // VC .NET does not like -a
+       }
+       std::string result;
+       while (a > 0)
+       {
+               T digit = a % base;
+               result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
+               a /= base;
+       }
+       if (negate)
+               result = "-" + result;
+       return result;
+}
+
+template <class T1, class T2>
+inline T1 SaturatingSubtract(const T1 &a, const T2 &b)
+{
+       return T1((a > b) ? (a - b) : 0);
+}
+
+template <class T>
+inline CipherDir GetCipherDir(const T &obj)
+{
+       return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
+}
+
+CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler();
+
+inline void IncrementCounterByOne(byte *inout, unsigned int s)
+{
+       for (int i=s-1, carry=1; i>=0 && carry; i--)
+               carry = !++inout[i];
+}
+
+inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
+{
+       int i, carry;
+       for (i=s-1, carry=1; i>=0 && carry; i--)
+               carry = ((output[i] = input[i]+1) == 0);
+       memcpy_s(output, s, input, i+1);
+}
+
+// ************** rotate functions ***************
+
+template <class T> inline T rotlFixed(T x, unsigned int y)
+{
+       assert(y < sizeof(T)*8);
+       return T((x<<y) | (x>>(sizeof(T)*8-y)));
+}
+
+template <class T> inline T rotrFixed(T x, unsigned int y)
+{
+       assert(y < sizeof(T)*8);
+       return T((x>>y) | (x<<(sizeof(T)*8-y)));
+}
+
+template <class T> inline T rotlVariable(T x, unsigned int y)
+{
+       assert(y < sizeof(T)*8);
+       return T((x<<y) | (x>>(sizeof(T)*8-y)));
+}
+
+template <class T> inline T rotrVariable(T x, unsigned int y)
+{
+       assert(y < sizeof(T)*8);
+       return T((x>>y) | (x<<(sizeof(T)*8-y)));
+}
+
+template <class T> inline T rotlMod(T x, unsigned int y)
+{
+       y %= sizeof(T)*8;
+       return T((x<<y) | (x>>(sizeof(T)*8-y)));
+}
+
+template <class T> inline T rotrMod(T x, unsigned int y)
+{
+       y %= sizeof(T)*8;
+       return T((x>>y) | (x<<(sizeof(T)*8-y)));
+}
+
+#ifdef _MSC_VER
+
+template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return y ? _lrotl(x, y) : x;
+}
+
+template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return y ? _lrotr(x, y) : x;
+}
+
+template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return _lrotl(x, y);
+}
+
+template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return _lrotr(x, y);
+}
+
+template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
+{
+       return _lrotl(x, y);
+}
+
+template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
+{
+       return _lrotr(x, y);
+}
+
+#endif // #ifdef _MSC_VER
+
+#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
+// Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions
+
+template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return y ? _rotl64(x, y) : x;
+}
+
+template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return y ? _rotr64(x, y) : x;
+}
+
+template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return _rotl64(x, y);
+}
+
+template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return _rotr64(x, y);
+}
+
+template<> inline word64 rotlMod<word64>(word64 x, unsigned int y)
+{
+       return _rotl64(x, y);
+}
+
+template<> inline word64 rotrMod<word64>(word64 x, unsigned int y)
+{
+       return _rotr64(x, y);
+}
+
+#endif // #if _MSC_VER >= 1310
+
+#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)
+// Intel C++ Compiler 10.0 gives undefined externals with these
+
+template<> inline word16 rotlFixed<word16>(word16 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return y ? _rotl16(x, y) : x;
+}
+
+template<> inline word16 rotrFixed<word16>(word16 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return y ? _rotr16(x, y) : x;
+}
+
+template<> inline word16 rotlVariable<word16>(word16 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return _rotl16(x, y);
+}
+
+template<> inline word16 rotrVariable<word16>(word16 x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return _rotr16(x, y);
+}
+
+template<> inline word16 rotlMod<word16>(word16 x, unsigned int y)
+{
+       return _rotl16(x, y);
+}
+
+template<> inline word16 rotrMod<word16>(word16 x, unsigned int y)
+{
+       return _rotr16(x, y);
+}
+
+template<> inline byte rotlFixed<byte>(byte x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return y ? _rotl8(x, y) : x;
+}
+
+template<> inline byte rotrFixed<byte>(byte x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return y ? _rotr8(x, y) : x;
+}
+
+template<> inline byte rotlVariable<byte>(byte x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return _rotl8(x, y);
+}
+
+template<> inline byte rotrVariable<byte>(byte x, unsigned int y)
+{
+       assert(y < 8*sizeof(x));
+       return _rotr8(x, y);
+}
+
+template<> inline byte rotlMod<byte>(byte x, unsigned int y)
+{
+       return _rotl8(x, y);
+}
+
+template<> inline byte rotrMod<byte>(byte x, unsigned int y)
+{
+       return _rotr8(x, y);
+}
+
+#endif // #if _MSC_VER >= 1400
+
+#if (defined(__MWERKS__) && TARGET_CPU_PPC)
+
+template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
+{
+       assert(y < 32);
+       return y ? __rlwinm(x,y,0,31) : x;
+}
+
+template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
+{
+       assert(y < 32);
+       return y ? __rlwinm(x,32-y,0,31) : x;
+}
+
+template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
+{
+       assert(y < 32);
+       return (__rlwnm(x,y,0,31));
+}
+
+template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
+{
+       assert(y < 32);
+       return (__rlwnm(x,32-y,0,31));
+}
+
+template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
+{
+       return (__rlwnm(x,y,0,31));
+}
+
+template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
+{
+       return (__rlwnm(x,32-y,0,31));
+}
+
+#endif // #if (defined(__MWERKS__) && TARGET_CPU_PPC)
+
+// ************** endian reversal ***************
+
+template <class T>
+inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
+{
+       if (order == LITTLE_ENDIAN_ORDER)
+               return GETBYTE(value, index);
+       else
+               return GETBYTE(value, sizeof(T)-index-1);
+}
+
+inline byte ByteReverse(byte value)
+{
+       return value;
+}
+
+inline word16 ByteReverse(word16 value)
+{
+#ifdef CRYPTOPP_BYTESWAP_AVAILABLE
+       return bswap_16(value);
+#elif defined(_MSC_VER) && _MSC_VER >= 1300
+       return _byteswap_ushort(value);
+#else
+       return rotlFixed(value, 8U);
+#endif
+}
+
+inline word32 ByteReverse(word32 value)
+{
+#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
+       __asm__ ("bswap %0" : "=r" (value) : "0" (value));
+       return value;
+#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
+       return bswap_32(value);
+#elif defined(__MWERKS__) && TARGET_CPU_PPC
+       return (word32)__lwbrx(&value,0);
+#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
+       return _byteswap_ulong(value);
+#elif CRYPTOPP_FAST_ROTATE(32)
+       // 5 instructions with rotate instruction, 9 without
+       return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
+#else
+       // 6 instructions with rotate instruction, 8 without
+       value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
+       return rotlFixed(value, 16U);
+#endif
+}
+
+inline word64 ByteReverse(word64 value)
+{
+#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
+       __asm__ ("bswap %0" : "=r" (value) : "0" (value));
+       return value;
+#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
+       return bswap_64(value);
+#elif defined(_MSC_VER) && _MSC_VER >= 1300
+       return _byteswap_uint64(value);
+#elif CRYPTOPP_BOOL_SLOW_WORD64
+       return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
+#else
+       value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
+       value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
+       return rotlFixed(value, 32U);
+#endif
+}
+
+inline byte BitReverse(byte value)
+{
+       value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
+       value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
+       return rotlFixed(value, 4U);
+}
+
+inline word16 BitReverse(word16 value)
+{
+       value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
+       value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
+       value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
+       return ByteReverse(value);
+}
+
+inline word32 BitReverse(word32 value)
+{
+       value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
+       value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
+       value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
+       return ByteReverse(value);
+}
+
+inline word64 BitReverse(word64 value)
+{
+#if CRYPTOPP_BOOL_SLOW_WORD64
+       return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
+#else
+       value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
+       value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
+       value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
+       return ByteReverse(value);
+#endif
+}
+
+template <class T>
+inline T BitReverse(T value)
+{
+       if (sizeof(T) == 1)
+               return (T)BitReverse((byte)value);
+       else if (sizeof(T) == 2)
+               return (T)BitReverse((word16)value);
+       else if (sizeof(T) == 4)
+               return (T)BitReverse((word32)value);
+       else
+       {
+               assert(sizeof(T) == 8);
+               return (T)BitReverse((word64)value);
+       }
+}
+
+template <class T>
+inline T ConditionalByteReverse(ByteOrder order, T value)
+{
+       return NativeByteOrderIs(order) ? value : ByteReverse(value);
+}
+
+template <class T>
+void ByteReverse(T *out, const T *in, size_t byteCount)
+{
+       assert(byteCount % sizeof(T) == 0);
+       size_t count = byteCount/sizeof(T);
+       for (size_t i=0; i<count; i++)
+               out[i] = ByteReverse(in[i]);
+}
+
+template <class T>
+inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount)
+{
+       if (!NativeByteOrderIs(order))
+               ByteReverse(out, in, byteCount);
+       else if (in != out)
+               memcpy_s(out, byteCount, in, byteCount);
+}
+
+template <class T>
+inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
+{
+       const size_t U = sizeof(T);
+       assert(inlen <= outlen*U);
+       memcpy_s(out, outlen*U, in, inlen);
+       memset_z((byte *)out+inlen, 0, outlen*U-inlen);
+       ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
+}
+
+#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
+inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *)
+{
+       return block[0];
+}
+
+inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *)
+{
+       return (order == BIG_ENDIAN_ORDER)
+               ? block[1] | (block[0] << 8)
+               : block[0] | (block[1] << 8);
+}
+
+inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *)
+{
+       return (order == BIG_ENDIAN_ORDER)
+               ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
+               : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
+}
+
+inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *)
+{
+       return (order == BIG_ENDIAN_ORDER)
+               ?
+               (word64(block[7]) |
+               (word64(block[6]) <<  8) |
+               (word64(block[5]) << 16) |
+               (word64(block[4]) << 24) |
+               (word64(block[3]) << 32) |
+               (word64(block[2]) << 40) |
+               (word64(block[1]) << 48) |
+               (word64(block[0]) << 56))
+               :
+               (word64(block[0]) |
+               (word64(block[1]) <<  8) |
+               (word64(block[2]) << 16) |
+               (word64(block[3]) << 24) |
+               (word64(block[4]) << 32) |
+               (word64(block[5]) << 40) |
+               (word64(block[6]) << 48) |
+               (word64(block[7]) << 56));
+}
+
+inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock)
+{
+       block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
+}
+
+inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock)
+{
+       if (order == BIG_ENDIAN_ORDER)
+       {
+               if (xorBlock)
+               {
+                       block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+               }
+               else
+               {
+                       block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+               }
+       }
+       else
+       {
+               if (xorBlock)
+               {
+                       block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+                       block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+               }
+               else
+               {
+                       block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+                       block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+               }
+       }
+}
+
+inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock)
+{
+       if (order == BIG_ENDIAN_ORDER)
+       {
+               if (xorBlock)
+               {
+                       block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
+                       block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
+                       block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+               }
+               else
+               {
+                       block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
+                       block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
+                       block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+               }
+       }
+       else
+       {
+               if (xorBlock)
+               {
+                       block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+                       block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
+                       block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
+               }
+               else
+               {
+                       block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+                       block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
+                       block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
+               }
+       }
+}
+
+inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock)
+{
+       if (order == BIG_ENDIAN_ORDER)
+       {
+               if (xorBlock)
+               {
+                       block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
+                       block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
+                       block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
+                       block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
+                       block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
+                       block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
+                       block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+               }
+               else
+               {
+                       block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
+                       block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
+                       block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
+                       block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
+                       block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
+                       block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
+                       block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+               }
+       }
+       else
+       {
+               if (xorBlock)
+               {
+                       block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+                       block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
+                       block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
+                       block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
+                       block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
+                       block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
+                       block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
+               }
+               else
+               {
+                       block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
+                       block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
+                       block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
+                       block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
+                       block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
+                       block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
+                       block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
+                       block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
+               }
+       }
+}
+#endif // #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
+
+template <class T>
+inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
+{
+#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
+       if (!assumeAligned)
+               return UnalignedGetWordNonTemplate(order, block, (T*)NULL);
+       assert(IsAligned<T>(block));
+#endif
+       return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
+}
+
+template <class T>
+inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
+{
+       result = GetWord<T>(assumeAligned, order, block);
+}
+
+template <class T>
+inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
+{
+#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
+       if (!assumeAligned)
+               return UnalignedPutWordNonTemplate(order, block, value, xorBlock);
+       assert(IsAligned<T>(block));
+       assert(IsAligned<T>(xorBlock));
+#endif
+       *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ (xorBlock ? *reinterpret_cast<const T *>(xorBlock) : 0);
+}
+
+template <class T, class B, bool A=false>
+class GetBlock
+{
+public:
+       GetBlock(const void *block)
+               : m_block((const byte *)block) {}
+
+       template <class U>
+       inline GetBlock<T, B, A> & operator()(U &x)
+       {
+               CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
+               x = GetWord<T>(A, B::ToEnum(), m_block);
+               m_block += sizeof(T);
+               return *this;
+       }
+
+private:
+       const byte *m_block;
+};
+
+template <class T, class B, bool A=false>
+class PutBlock
+{
+public:
+       PutBlock(const void *xorBlock, void *block)
+               : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
+
+       template <class U>
+       inline PutBlock<T, B, A> & operator()(U x)
+       {
+               PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
+               m_block += sizeof(T);
+               if (m_xorBlock)
+                       m_xorBlock += sizeof(T);
+               return *this;
+       }
+
+private:
+       const byte *m_xorBlock;
+       byte *m_block;
+};
+
+template <class T, class B, bool GA=false, bool PA=false>
+struct BlockGetAndPut
+{
+       // function needed because of C++ grammatical ambiguity between expression-statements and declarations
+       static inline GetBlock<T, B, GA> Get(const void *block) {return GetBlock<T, B, GA>(block);}
+       typedef PutBlock<T, B, PA> Put;
+};
+
+template <class T>
+std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
+{
+       if (!NativeByteOrderIs(order))
+               value = ByteReverse(value);
+
+       return std::string((char *)&value, sizeof(value));
+}
+
+template <class T>
+T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
+{
+       T value = 0;
+       memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value)));
+       return NativeByteOrderIs(order) ? value : ByteReverse(value);
+}
+
+// ************** help remove warning on g++ ***************
+
+template <bool overflow> struct SafeShifter;
+
+template<> struct SafeShifter<true>
+{
+       template <class T>
+       static inline T RightShift(T value, unsigned int bits)
+       {
+               return 0;
+       }
+
+       template <class T>
+       static inline T LeftShift(T value, unsigned int bits)
+       {
+               return 0;
+       }
+};
+
+template<> struct SafeShifter<false>
+{
+       template <class T>
+       static inline T RightShift(T value, unsigned int bits)
+       {
+               return value >> bits;
+       }
+
+       template <class T>
+       static inline T LeftShift(T value, unsigned int bits)
+       {
+               return value << bits;
+       }
+};
+
+template <unsigned int bits, class T>
+inline T SafeRightShift(T value)
+{
+       return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
+}
+
+template <unsigned int bits, class T>
+inline T SafeLeftShift(T value)
+{
+       return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
+}
+
+// ************** use one buffer for multiple data members ***************
+
+#define CRYPTOPP_BLOCK_1(n, t, s) t* m_##n() {return (t *)(m_aggregate+0);}     size_t SS1() {return       sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
+#define CRYPTOPP_BLOCK_2(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS1());} size_t SS2() {return SS1()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
+#define CRYPTOPP_BLOCK_3(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS2());} size_t SS3() {return SS2()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
+#define CRYPTOPP_BLOCK_4(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS3());} size_t SS4() {return SS3()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
+#define CRYPTOPP_BLOCK_5(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS4());} size_t SS5() {return SS4()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
+#define CRYPTOPP_BLOCK_6(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS5());} size_t SS6() {return SS5()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
+#define CRYPTOPP_BLOCK_7(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS6());} size_t SS7() {return SS6()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
+#define CRYPTOPP_BLOCK_8(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS7());} size_t SS8() {return SS7()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
+#define CRYPTOPP_BLOCKS_END(i) size_t SST() {return SS##i();} void AllocateBlocks() {m_aggregate.New(SST());} AlignedSecByteBlock m_aggregate;
+
+NAMESPACE_END
+
+#endif
diff --git a/cryptopp/obj/.gitignore b/cryptopp/obj/.gitignore
new file mode 100644 (file)
index 0000000..d6b7ef3
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/cryptopp/pch.h b/cryptopp/pch.h
new file mode 100644 (file)
index 0000000..418c390
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef CRYPTOPP_PCH_H
+#define CRYPTOPP_PCH_H
+
+#ifdef CRYPTOPP_GENERATE_X64_MASM
+
+       #include "cpu.h"
+
+#else
+
+       #include "config.h"
+
+       #ifdef USE_PRECOMPILED_HEADERS
+               #include "simple.h"
+               #include "secblock.h"
+               #include "misc.h"
+               #include "smartptr.h"
+       #endif
+
+#endif
+
+#endif
diff --git a/cryptopp/secblock.h b/cryptopp/secblock.h
new file mode 100644 (file)
index 0000000..d66470e
--- /dev/null
@@ -0,0 +1,500 @@
+// secblock.h - written and placed in the public domain by Wei Dai
+
+#ifndef CRYPTOPP_SECBLOCK_H
+#define CRYPTOPP_SECBLOCK_H
+
+#include "config.h"
+#include "misc.h"
+#include <assert.h>
+
+#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX)
+       #include <malloc.h>
+#else
+       #include <stdlib.h>
+#endif
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// ************** secure memory allocation ***************
+
+template<class T>
+class AllocatorBase
+{
+public:
+       typedef T value_type;
+       typedef size_t size_type;
+#ifdef CRYPTOPP_MSVCRT6
+       typedef ptrdiff_t difference_type;
+#else
+       typedef std::ptrdiff_t difference_type;
+#endif
+       typedef T * pointer;
+       typedef const T * const_pointer;
+       typedef T & reference;
+       typedef const T & const_reference;
+
+       pointer address(reference r) const {return (&r);}
+       const_pointer address(const_reference r) const {return (&r); }
+       void construct(pointer p, const T& val) {new (p) T(val);}
+       void destroy(pointer p) {p->~T();}
+       size_type max_size() const {return ~size_type(0)/sizeof(T);}    // switch to std::numeric_limits<T>::max later
+
+protected:
+       static void CheckSize(size_t n)
+       {
+               if (n > ~size_t(0) / sizeof(T))
+                       throw InvalidArgument("AllocatorBase: requested size would cause integer overflow");
+       }
+};
+
+#define CRYPTOPP_INHERIT_ALLOCATOR_TYPES       \
+typedef typename AllocatorBase<T>::value_type value_type;\
+typedef typename AllocatorBase<T>::size_type size_type;\
+typedef typename AllocatorBase<T>::difference_type difference_type;\
+typedef typename AllocatorBase<T>::pointer pointer;\
+typedef typename AllocatorBase<T>::const_pointer const_pointer;\
+typedef typename AllocatorBase<T>::reference reference;\
+typedef typename AllocatorBase<T>::const_reference const_reference;
+
+#if defined(_MSC_VER) && (_MSC_VER < 1300)
+// this pragma causes an internal compiler error if placed immediately before std::swap(a, b)
+#pragma warning(push)
+#pragma warning(disable: 4700) // VC60 workaround: don't know how to get rid of this warning
+#endif
+
+template <class T, class A>
+typename A::pointer StandardReallocate(A& a, T *p, typename A::size_type oldSize, typename A::size_type newSize, bool preserve)
+{
+       if (oldSize == newSize)
+               return p;
+
+       if (preserve)
+       {
+               typename A::pointer newPointer = a.allocate(newSize, NULL);
+               memcpy_s(newPointer, sizeof(T)*newSize, p, sizeof(T)*STDMIN(oldSize, newSize));
+               a.deallocate(p, oldSize);
+               return newPointer;
+       }
+       else
+       {
+               a.deallocate(p, oldSize);
+               return a.allocate(newSize, NULL);
+       }
+}
+
+#if defined(_MSC_VER) && (_MSC_VER < 1300)
+#pragma warning(pop)
+#endif
+
+template <class T, bool T_Align16 = false>
+class AllocatorWithCleanup : public AllocatorBase<T>
+{
+public:
+       CRYPTOPP_INHERIT_ALLOCATOR_TYPES
+
+       pointer allocate(size_type n, const void * = NULL)
+       {
+               CheckSize(n);
+               if (n == 0)
+                       return NULL;
+
+               if (CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16 && n*sizeof(T) >= 16)
+               {
+                       byte *p;
+               #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
+                       while (!(p = (byte *)_mm_malloc(sizeof(T)*n, 16)))
+               #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
+                       while (!(p = (byte *)memalign(16, sizeof(T)*n)))
+               #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16)
+                       while (!(p = (byte *)malloc(sizeof(T)*n)))
+               #else
+                       while (!(p = (byte *)malloc(sizeof(T)*n + 16)))
+               #endif
+                               CallNewHandler();
+
+               #ifdef CRYPTOPP_NO_ALIGNED_ALLOC
+                       size_t adjustment = 16-((size_t)p%16);
+                       p += adjustment;
+                       p[-1] = (byte)adjustment;
+               #endif
+
+                       assert(IsAlignedOn(p, 16));
+                       return (pointer)p;
+               }
+
+               pointer p;
+               while (!(p = (pointer)malloc(sizeof(T)*n)))
+                       CallNewHandler();
+               return p;
+       }
+
+       void deallocate(void *p, size_type n)
+       {
+               memset_z(p, 0, n*sizeof(T));
+
+               if (CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16 && n*sizeof(T) >= 16)
+               {
+               #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
+                       _mm_free(p);
+               #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC)
+                       p = (byte *)p - ((byte *)p)[-1];
+                       free(p);
+               #else
+                       free(p);
+               #endif
+                       return;
+               }
+
+               free(p);
+       }
+
+       pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve)
+       {
+               return StandardReallocate(*this, p, oldSize, newSize, preserve);
+       }
+
+       // VS.NET STL enforces the policy of "All STL-compliant allocators have to provide a
+       // template class member called rebind".
+    template <class U> struct rebind { typedef AllocatorWithCleanup<U, T_Align16> other; };
+#if _MSC_VER >= 1500
+       AllocatorWithCleanup() {}
+       template <class U, bool A> AllocatorWithCleanup(const AllocatorWithCleanup<U, A> &) {}
+#endif
+};
+
+CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<byte>;
+CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word16>;
+CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word32>;
+CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word64>;
+#if CRYPTOPP_BOOL_X86
+CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word, true>;  // for Integer
+#endif
+
+template <class T>
+class NullAllocator : public AllocatorBase<T>
+{
+public:
+       CRYPTOPP_INHERIT_ALLOCATOR_TYPES
+
+       pointer allocate(size_type n, const void * = NULL)
+       {
+               assert(false);
+               return NULL;
+       }
+
+       void deallocate(void *p, size_type n)
+       {
+               assert(false);
+       }
+
+       size_type max_size() const {return 0;}
+};
+
+// This allocator can't be used with standard collections because
+// they require that all objects of the same allocator type are equivalent.
+// So this is for use with SecBlock only.
+template <class T, size_t S, class A = NullAllocator<T>, bool T_Align16 = false>
+class FixedSizeAllocatorWithCleanup : public AllocatorBase<T>
+{
+public:
+       CRYPTOPP_INHERIT_ALLOCATOR_TYPES
+
+       FixedSizeAllocatorWithCleanup() : m_allocated(false) {}
+
+       pointer allocate(size_type n)
+       {
+               assert(IsAlignedOn(m_array, 8));
+
+               if (n <= S && !m_allocated)
+               {
+                       m_allocated = true;
+                       return GetAlignedArray();
+               }
+               else
+                       return m_fallbackAllocator.allocate(n);
+       }
+
+       pointer allocate(size_type n, const void *hint)
+       {
+               if (n <= S && !m_allocated)
+               {
+                       m_allocated = true;
+                       return GetAlignedArray();
+               }
+               else
+                       return m_fallbackAllocator.allocate(n, hint);
+       }
+
+       void deallocate(void *p, size_type n)
+       {
+               if (p == GetAlignedArray())
+               {
+                       assert(n <= S);
+                       assert(m_allocated);
+                       m_allocated = false;
+                       memset(p, 0, n*sizeof(T));
+               }
+               else
+                       m_fallbackAllocator.deallocate(p, n);
+       }
+
+       pointer reallocate(pointer p, size_type oldSize, size_type newSize, bool preserve)
+       {
+               if (p == GetAlignedArray() && newSize <= S)
+               {
+                       assert(oldSize <= S);
+                       if (oldSize > newSize)
+                               memset(p + newSize, 0, (oldSize-newSize)*sizeof(T));
+                       return p;
+               }
+
+               pointer newPointer = allocate(newSize, NULL);
+               if (preserve)
+                       memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize));
+               deallocate(p, oldSize);
+               return newPointer;
+       }
+
+       size_type max_size() const {return STDMAX(m_fallbackAllocator.max_size(), S);}
+
+private:
+#ifdef __BORLANDC__
+       T* GetAlignedArray() {return m_array;}
+       T m_array[S];
+#else
+       T* GetAlignedArray() {return (CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? (T*)(((byte *)m_array) + (0-(size_t)m_array)%16) : m_array;}
+       CRYPTOPP_ALIGN_DATA(8) T m_array[(CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? S+8/sizeof(T) : S];
+#endif
+       A m_fallbackAllocator;
+       bool m_allocated;
+};
+
+//! a block of memory allocated using A
+template <class T, class A = AllocatorWithCleanup<T> >
+class SecBlock
+{
+public:
+       typedef typename A::value_type value_type;
+       typedef typename A::pointer iterator;
+       typedef typename A::const_pointer const_iterator;
+       typedef typename A::size_type size_type;
+
+       explicit SecBlock(size_type size=0)
+               : m_size(size) {m_ptr = m_alloc.allocate(size, NULL);}
+       SecBlock(const SecBlock<T, A> &t)
+               : m_size(t.m_size) {m_ptr = m_alloc.allocate(m_size, NULL); memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));}
+       SecBlock(const T *t, size_type len)
+               : m_size(len)
+       {
+               m_ptr = m_alloc.allocate(len, NULL);
+               if (t == NULL)
+                       memset_z(m_ptr, 0, len*sizeof(T));
+               else
+                       memcpy(m_ptr, t, len*sizeof(T));
+       }
+
+       ~SecBlock()
+               {m_alloc.deallocate(m_ptr, m_size);}
+
+#ifdef __BORLANDC__
+       operator T *() const
+               {return (T*)m_ptr;}
+#else
+       operator const void *() const
+               {return m_ptr;}
+       operator void *()
+               {return m_ptr;}
+
+       operator const T *() const
+               {return m_ptr;}
+       operator T *()
+               {return m_ptr;}
+#endif
+
+//     T *operator +(size_type offset)
+//             {return m_ptr+offset;}
+
+//     const T *operator +(size_type offset) const
+//             {return m_ptr+offset;}
+
+//     T& operator[](size_type index)
+//             {assert(index >= 0 && index < m_size); return m_ptr[index];}
+
+//     const T& operator[](size_type index) const
+//             {assert(index >= 0 && index < m_size); return m_ptr[index];}
+
+       iterator begin()
+               {return m_ptr;}
+       const_iterator begin() const
+               {return m_ptr;}
+       iterator end()
+               {return m_ptr+m_size;}
+       const_iterator end() const
+               {return m_ptr+m_size;}
+
+       typename A::pointer data() {return m_ptr;}
+       typename A::const_pointer data() const {return m_ptr;}
+
+       size_type size() const {return m_size;}
+       bool empty() const {return m_size == 0;}
+
+       byte * BytePtr() {return (byte *)m_ptr;}
+       const byte * BytePtr() const {return (const byte *)m_ptr;}
+       size_type SizeInBytes() const {return m_size*sizeof(T);}
+
+       //! set contents and size
+       void Assign(const T *t, size_type len)
+       {
+               New(len);
+               memcpy_s(m_ptr, m_size*sizeof(T), t, len*sizeof(T));
+       }
+
+       //! copy contents and size from another SecBlock
+       void Assign(const SecBlock<T, A> &t)
+       {
+               New(t.m_size);
+               memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));
+       }
+
+       SecBlock<T, A>& operator=(const SecBlock<T, A> &t)
+       {
+               Assign(t);
+               return *this;
+       }
+
+       // append to this object
+       SecBlock<T, A>& operator+=(const SecBlock<T, A> &t)
+       {
+               size_type oldSize = m_size;
+               Grow(m_size+t.m_size);
+               memcpy_s(m_ptr+oldSize, m_size*sizeof(T), t.m_ptr, t.m_size*sizeof(T));
+               return *this;
+       }
+
+       // append operator
+       SecBlock<T, A> operator+(const SecBlock<T, A> &t)
+       {
+               SecBlock<T, A> result(m_size+t.m_size);
+               memcpy_s(result.m_ptr, result.m_size*sizeof(T), m_ptr, m_size*sizeof(T));
+               memcpy_s(result.m_ptr+m_size, t.m_size*sizeof(T), t.m_ptr, t.m_size*sizeof(T));
+               return result;
+       }
+
+       bool operator==(const SecBlock<T, A> &t) const
+       {
+               return m_size == t.m_size && VerifyBufsEqual(m_ptr, t.m_ptr, m_size*sizeof(T));
+       }
+
+       bool operator!=(const SecBlock<T, A> &t) const
+       {
+               return !operator==(t);
+       }
+
+       //! change size, without preserving contents
+       void New(size_type newSize)
+       {
+               m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, false);
+               m_size = newSize;
+       }
+
+       //! change size and set contents to 0
+       void CleanNew(size_type newSize)
+       {
+               New(newSize);
+               memset_z(m_ptr, 0, m_size*sizeof(T));
+       }
+
+       //! change size only if newSize > current size. contents are preserved
+       void Grow(size_type newSize)
+       {
+               if (newSize > m_size)
+               {
+                       m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
+                       m_size = newSize;
+               }
+       }
+
+       //! change size only if newSize > current size. contents are preserved and additional area is set to 0
+       void CleanGrow(size_type newSize)
+       {
+               if (newSize > m_size)
+               {
+                       m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
+                       memset(m_ptr+m_size, 0, (newSize-m_size)*sizeof(T));
+                       m_size = newSize;
+               }
+       }
+
+       //! change size and preserve contents
+       void resize(size_type newSize)
+       {
+               m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
+               m_size = newSize;
+       }
+
+       //! swap contents and size with another SecBlock
+       void swap(SecBlock<T, A> &b)
+       {
+               std::swap(m_alloc, b.m_alloc);
+               std::swap(m_size, b.m_size);
+               std::swap(m_ptr, b.m_ptr);
+       }
+
+//private:
+       A m_alloc;
+       size_type m_size;
+       T *m_ptr;
+};
+
+typedef SecBlock<byte> SecByteBlock;
+typedef SecBlock<byte, AllocatorWithCleanup<byte, true> > AlignedSecByteBlock;
+typedef SecBlock<word> SecWordBlock;
+
+//! a SecBlock with fixed size, allocated statically
+template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S> >
+class FixedSizeSecBlock : public SecBlock<T, A>
+{
+public:
+       explicit FixedSizeSecBlock() : SecBlock<T, A>(S) {}
+};
+
+template <class T, unsigned int S, bool T_Align16 = true>
+class FixedSizeAlignedSecBlock : public FixedSizeSecBlock<T, S, FixedSizeAllocatorWithCleanup<T, S, NullAllocator<T>, T_Align16> >
+{
+};
+
+//! a SecBlock that preallocates size S statically, and uses the heap when this size is exceeded
+template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S, AllocatorWithCleanup<T> > >
+class SecBlockWithHint : public SecBlock<T, A>
+{
+public:
+       explicit SecBlockWithHint(size_t size) : SecBlock<T, A>(size) {}
+};
+
+template<class T, bool A, class U, bool B>
+inline bool operator==(const CryptoPP::AllocatorWithCleanup<T, A>&, const CryptoPP::AllocatorWithCleanup<U, B>&) {return (true);}
+template<class T, bool A, class U, bool B>
+inline bool operator!=(const CryptoPP::AllocatorWithCleanup<T, A>&, const CryptoPP::AllocatorWithCleanup<U, B>&) {return (false);}
+
+NAMESPACE_END
+
+NAMESPACE_BEGIN(std)
+template <class T, class A>
+inline void swap(CryptoPP::SecBlock<T, A> &a, CryptoPP::SecBlock<T, A> &b)
+{
+       a.swap(b);
+}
+
+#if defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) || (defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES))
+// working for STLport 5.1.3 and MSVC 6 SP5
+template <class _Tp1, class _Tp2>
+inline CryptoPP::AllocatorWithCleanup<_Tp2>&
+__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*)
+{
+       return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a);
+}
+#endif
+
+NAMESPACE_END
+
+#endif
diff --git a/cryptopp/sha.cpp b/cryptopp/sha.cpp
new file mode 100644 (file)
index 0000000..fd0b0a2
--- /dev/null
@@ -0,0 +1,899 @@
+// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c
+
+// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2.
+// Both are in the public domain.
+
+// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM sha.cpp" to generate MASM code
+
+#include "pch.h"
+
+#ifndef CRYPTOPP_IMPORTS
+#ifndef CRYPTOPP_GENERATE_X64_MASM
+
+#include "sha.h"
+#include "misc.h"
+#include "cpu.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// start of Steve Reid's code
+
+#define blk0(i) (W[i] = data[i])
+#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
+
+void SHA1::InitState(HashWordType *state)
+{
+       state[0] = 0x67452301L;
+       state[1] = 0xEFCDAB89L;
+       state[2] = 0x98BADCFEL;
+       state[3] = 0x10325476L;
+       state[4] = 0xC3D2E1F0L;
+}
+
+#define f1(x,y,z) (z^(x&(y^z)))
+#define f2(x,y,z) (x^y^z)
+#define f3(x,y,z) ((x&y)|(z&(x|y)))
+#define f4(x,y,z) (x^y^z)
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
+#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
+#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
+#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
+#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
+
+void SHA1::Transform(word32 *state, const word32 *data)
+{
+       word32 W[16];
+    /* Copy context->state[] to working vars */
+    word32 a = state[0];
+    word32 b = state[1];
+    word32 c = state[2];
+    word32 d = state[3];
+    word32 e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+}
+
+// end of Steve Reid's code
+
+// *************************************************************
+
+void SHA224::InitState(HashWordType *state)
+{
+       static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
+       memcpy(state, s, sizeof(s));
+}
+
+void SHA256::InitState(HashWordType *state)
+{
+       static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
+       memcpy(state, s, sizeof(s));
+}
+
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+CRYPTOPP_ALIGN_DATA(16) extern const word32 SHA256_K[64] CRYPTOPP_SECTION_ALIGN16 = {
+#else
+extern const word32 SHA256_K[64] = {
+#endif
+       0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+       0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+       0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+       0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+       0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+       0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+       0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+       0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+       0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+       0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+       0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+       0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+       0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+       0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+       0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+       0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
+
+#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM)
+
+#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code
+
+static void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len
+#if defined(_MSC_VER) && (_MSC_VER == 1200)
+       , ...   // VC60 workaround: prevent VC 6 from inlining this function
+#endif
+       )
+{
+#if defined(_MSC_VER) && (_MSC_VER == 1200)
+       AS2(mov ecx, [state])
+       AS2(mov edx, [data])
+#endif
+
+       #define LOCALS_SIZE     8*4 + 16*4 + 4*WORD_SZ
+       #define H(i)            [BASE+ASM_MOD(1024+7-(i),8)*4]
+       #define G(i)            H(i+1)
+       #define F(i)            H(i+2)
+       #define E(i)            H(i+3)
+       #define D(i)            H(i+4)
+       #define C(i)            H(i+5)
+       #define B(i)            H(i+6)
+       #define A(i)            H(i+7)
+       #define Wt(i)           BASE+8*4+ASM_MOD(1024+15-(i),16)*4
+       #define Wt_2(i)         Wt((i)-2)
+       #define Wt_15(i)        Wt((i)-15)
+       #define Wt_7(i)         Wt((i)-7)
+       #define K_END           [BASE+8*4+16*4+0*WORD_SZ]
+       #define STATE_SAVE      [BASE+8*4+16*4+1*WORD_SZ]
+       #define DATA_SAVE       [BASE+8*4+16*4+2*WORD_SZ]
+       #define DATA_END        [BASE+8*4+16*4+3*WORD_SZ]
+       #define Kt(i)           WORD_REG(si)+(i)*4
+#if CRYPTOPP_BOOL_X86
+       #define BASE            esp+4
+#elif defined(__GNUC__)
+       #define BASE            r8
+#else
+       #define BASE            rsp
+#endif
+
+#define RA0(i, edx, edi)               \
+       AS2(    add edx, [Kt(i)]        )\
+       AS2(    add edx, [Wt(i)]        )\
+       AS2(    add edx, H(i)           )\
+
+#define RA1(i, edx, edi)
+
+#define RB0(i, edx, edi)
+
+#define RB1(i, edx, edi)       \
+       AS2(    mov AS_REG_7d, [Wt_2(i)]        )\
+       AS2(    mov edi, [Wt_15(i)])\
+       AS2(    mov ebx, AS_REG_7d      )\
+       AS2(    shr AS_REG_7d, 10               )\
+       AS2(    ror ebx, 17             )\
+       AS2(    xor AS_REG_7d, ebx      )\
+       AS2(    ror ebx, 2              )\
+       AS2(    xor ebx, AS_REG_7d      )/* s1(W_t-2) */\
+       AS2(    add ebx, [Wt_7(i)])\
+       AS2(    mov AS_REG_7d, edi      )\
+       AS2(    shr AS_REG_7d, 3                )\
+       AS2(    ror edi, 7              )\
+       AS2(    add ebx, [Wt(i)])/* s1(W_t-2) + W_t-7 + W_t-16 */\
+       AS2(    xor AS_REG_7d, edi      )\
+       AS2(    add edx, [Kt(i)])\
+       AS2(    ror edi, 11             )\
+       AS2(    add edx, H(i)   )\
+       AS2(    xor AS_REG_7d, edi      )/* s0(W_t-15) */\
+       AS2(    add AS_REG_7d, ebx      )/* W_t = s1(W_t-2) + W_t-7 + s0(W_t-15) W_t-16*/\
+       AS2(    mov [Wt(i)], AS_REG_7d)\
+       AS2(    add edx, AS_REG_7d      )\
+
+#define ROUND(i, r, eax, ecx, edi, edx)\
+       /* in: edi = E  */\
+       /* unused: eax, ecx, temp: ebx, AS_REG_7d, out: edx = T1 */\
+       AS2(    mov edx, F(i)   )\
+       AS2(    xor edx, G(i)   )\
+       AS2(    and edx, edi    )\
+       AS2(    xor edx, G(i)   )/* Ch(E,F,G) = (G^(E&(F^G))) */\
+       AS2(    mov AS_REG_7d, edi      )\
+       AS2(    ror edi, 6              )\
+       AS2(    ror AS_REG_7d, 25               )\
+       RA##r(i, edx, edi               )/* H + Wt + Kt + Ch(E,F,G) */\
+       AS2(    xor AS_REG_7d, edi      )\
+       AS2(    ror edi, 5              )\
+       AS2(    xor AS_REG_7d, edi      )/* S1(E) */\
+       AS2(    add edx, AS_REG_7d      )/* T1 = S1(E) + Ch(E,F,G) + H + Wt + Kt */\
+       RB##r(i, edx, edi               )/* H + Wt + Kt + Ch(E,F,G) */\
+       /* in: ecx = A, eax = B^C, edx = T1 */\
+       /* unused: edx, temp: ebx, AS_REG_7d, out: eax = A, ecx = B^C, edx = E */\
+       AS2(    mov ebx, ecx    )\
+       AS2(    xor ecx, B(i)   )/* A^B */\
+       AS2(    and eax, ecx    )\
+       AS2(    xor eax, B(i)   )/* Maj(A,B,C) = B^((A^B)&(B^C) */\
+       AS2(    mov AS_REG_7d, ebx      )\
+       AS2(    ror ebx, 2              )\
+       AS2(    add eax, edx    )/* T1 + Maj(A,B,C) */\
+       AS2(    add edx, D(i)   )\
+       AS2(    mov D(i), edx   )\
+       AS2(    ror AS_REG_7d, 22               )\
+       AS2(    xor AS_REG_7d, ebx      )\
+       AS2(    ror ebx, 11             )\
+       AS2(    xor AS_REG_7d, ebx      )\
+       AS2(    add eax, AS_REG_7d      )/* T1 + S0(A) + Maj(A,B,C) */\
+       AS2(    mov H(i), eax   )\
+
+#define SWAP_COPY(i)           \
+       AS2(    mov             WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\
+       AS1(    bswap   WORD_REG(bx))\
+       AS2(    mov             [Wt(i*(1+CRYPTOPP_BOOL_X64)+CRYPTOPP_BOOL_X64)], WORD_REG(bx))
+
+#if defined(__GNUC__)
+       #if CRYPTOPP_BOOL_X64
+               FixedSizeAlignedSecBlock<byte, LOCALS_SIZE> workspace;
+       #endif
+       __asm__ __volatile__
+       (
+       #if CRYPTOPP_BOOL_X64
+               "lea %4, %%r8;"
+       #endif
+       ".intel_syntax noprefix;"
+#elif defined(CRYPTOPP_GENERATE_X64_MASM)
+               ALIGN   8
+       X86_SHA256_HashBlocks   PROC FRAME
+               rex_push_reg rsi
+               push_reg rdi
+               push_reg rbx
+               push_reg rbp
+               alloc_stack(LOCALS_SIZE+8)
+               .endprolog
+               mov rdi, r8
+               lea rsi, [?SHA256_K@CryptoPP@@3QBIB + 48*4]
+#endif
+
+#if CRYPTOPP_BOOL_X86
+       #ifndef __GNUC__
+               AS2(    mov             edi, [len])
+               AS2(    lea             WORD_REG(si), [SHA256_K+48*4])
+       #endif
+       #if !defined(_MSC_VER) || (_MSC_VER < 1400)
+               AS_PUSH_IF86(bx)
+       #endif
+
+       AS_PUSH_IF86(bp)
+       AS2(    mov             ebx, esp)
+       AS2(    and             esp, -16)
+       AS2(    sub             WORD_REG(sp), LOCALS_SIZE)
+       AS_PUSH_IF86(bx)
+#endif
+       AS2(    mov             STATE_SAVE, WORD_REG(cx))
+       AS2(    mov             DATA_SAVE, WORD_REG(dx))
+       AS2(    add             WORD_REG(di), WORD_REG(dx))
+       AS2(    mov             DATA_END, WORD_REG(di))
+       AS2(    mov             K_END, WORD_REG(si))
+
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+#if CRYPTOPP_BOOL_X86
+       AS2(    test    edi, 1)
+       ASJ(    jnz,    2, f)
+#endif
+       AS2(    movdqa  xmm0, XMMWORD_PTR [WORD_REG(cx)+0*16])
+       AS2(    movdqa  xmm1, XMMWORD_PTR [WORD_REG(cx)+1*16])
+#endif
+
+#if CRYPTOPP_BOOL_X86
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+       ASJ(    jmp,    0, f)
+#endif
+       ASL(2)  // non-SSE2
+       AS2(    mov             esi, ecx)
+       AS2(    lea             edi, A(0))
+       AS2(    mov             ecx, 8)
+       AS1(    rep movsd)
+       AS2(    mov             esi, K_END)
+       ASJ(    jmp,    3, f)
+#endif
+
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+       ASL(0)
+       AS2(    movdqa  E(0), xmm1)
+       AS2(    movdqa  A(0), xmm0)
+#endif
+#if CRYPTOPP_BOOL_X86
+       ASL(3)
+#endif
+       AS2(    sub             WORD_REG(si), 48*4)
+       SWAP_COPY(0)    SWAP_COPY(1)    SWAP_COPY(2)    SWAP_COPY(3)
+       SWAP_COPY(4)    SWAP_COPY(5)    SWAP_COPY(6)    SWAP_COPY(7)
+#if CRYPTOPP_BOOL_X86
+       SWAP_COPY(8)    SWAP_COPY(9)    SWAP_COPY(10)   SWAP_COPY(11)
+       SWAP_COPY(12)   SWAP_COPY(13)   SWAP_COPY(14)   SWAP_COPY(15)
+#endif
+       AS2(    mov             edi, E(0))      // E
+       AS2(    mov             eax, B(0))      // B
+       AS2(    xor             eax, C(0))      // B^C
+       AS2(    mov             ecx, A(0))      // A
+
+       ROUND(0, 0, eax, ecx, edi, edx)
+       ROUND(1, 0, ecx, eax, edx, edi)
+       ROUND(2, 0, eax, ecx, edi, edx)
+       ROUND(3, 0, ecx, eax, edx, edi)
+       ROUND(4, 0, eax, ecx, edi, edx)
+       ROUND(5, 0, ecx, eax, edx, edi)
+       ROUND(6, 0, eax, ecx, edi, edx)
+       ROUND(7, 0, ecx, eax, edx, edi)
+       ROUND(8, 0, eax, ecx, edi, edx)
+       ROUND(9, 0, ecx, eax, edx, edi)
+       ROUND(10, 0, eax, ecx, edi, edx)
+       ROUND(11, 0, ecx, eax, edx, edi)
+       ROUND(12, 0, eax, ecx, edi, edx)
+       ROUND(13, 0, ecx, eax, edx, edi)
+       ROUND(14, 0, eax, ecx, edi, edx)
+       ROUND(15, 0, ecx, eax, edx, edi)
+
+       ASL(1)
+       AS2(add WORD_REG(si), 4*16)
+       ROUND(0, 1, eax, ecx, edi, edx)
+       ROUND(1, 1, ecx, eax, edx, edi)
+       ROUND(2, 1, eax, ecx, edi, edx)
+       ROUND(3, 1, ecx, eax, edx, edi)
+       ROUND(4, 1, eax, ecx, edi, edx)
+       ROUND(5, 1, ecx, eax, edx, edi)
+       ROUND(6, 1, eax, ecx, edi, edx)
+       ROUND(7, 1, ecx, eax, edx, edi)
+       ROUND(8, 1, eax, ecx, edi, edx)
+       ROUND(9, 1, ecx, eax, edx, edi)
+       ROUND(10, 1, eax, ecx, edi, edx)
+       ROUND(11, 1, ecx, eax, edx, edi)
+       ROUND(12, 1, eax, ecx, edi, edx)
+       ROUND(13, 1, ecx, eax, edx, edi)
+       ROUND(14, 1, eax, ecx, edi, edx)
+       ROUND(15, 1, ecx, eax, edx, edi)
+       AS2(    cmp             WORD_REG(si), K_END)
+       ASJ(    jne,    1, b)
+
+       AS2(    mov             WORD_REG(dx), DATA_SAVE)
+       AS2(    add             WORD_REG(dx), 64)
+       AS2(    mov             AS_REG_7, STATE_SAVE)
+       AS2(    mov             DATA_SAVE, WORD_REG(dx))
+
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+#if CRYPTOPP_BOOL_X86
+       AS2(    test    DWORD PTR DATA_END, 1)
+       ASJ(    jnz,    4, f)
+#endif
+       AS2(    movdqa  xmm1, XMMWORD_PTR [AS_REG_7+1*16])
+       AS2(    movdqa  xmm0, XMMWORD_PTR [AS_REG_7+0*16])
+       AS2(    paddd   xmm1, E(0))
+       AS2(    paddd   xmm0, A(0))
+       AS2(    movdqa  [AS_REG_7+1*16], xmm1)
+       AS2(    movdqa  [AS_REG_7+0*16], xmm0)
+       AS2(    cmp             WORD_REG(dx), DATA_END)
+       ASJ(    jl,             0, b)
+#endif
+
+#if CRYPTOPP_BOOL_X86
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+       ASJ(    jmp,    5, f)
+       ASL(4)  // non-SSE2
+#endif
+       AS2(    add             [AS_REG_7+0*4], ecx)    // A
+       AS2(    add             [AS_REG_7+4*4], edi)    // E
+       AS2(    mov             eax, B(0))
+       AS2(    mov             ebx, C(0))
+       AS2(    mov             ecx, D(0))
+       AS2(    add             [AS_REG_7+1*4], eax)
+       AS2(    add             [AS_REG_7+2*4], ebx)
+       AS2(    add             [AS_REG_7+3*4], ecx)
+       AS2(    mov             eax, F(0))
+       AS2(    mov             ebx, G(0))
+       AS2(    mov             ecx, H(0))
+       AS2(    add             [AS_REG_7+5*4], eax)
+       AS2(    add             [AS_REG_7+6*4], ebx)
+       AS2(    add             [AS_REG_7+7*4], ecx)
+       AS2(    mov             ecx, AS_REG_7d)
+       AS2(    cmp             WORD_REG(dx), DATA_END)
+       ASJ(    jl,             2, b)
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+       ASL(5)
+#endif
+#endif
+
+       AS_POP_IF86(sp)
+       AS_POP_IF86(bp)
+       #if !defined(_MSC_VER) || (_MSC_VER < 1400)
+               AS_POP_IF86(bx)
+       #endif
+
+#ifdef CRYPTOPP_GENERATE_X64_MASM
+       add             rsp, LOCALS_SIZE+8
+       pop             rbp
+       pop             rbx
+       pop             rdi
+       pop             rsi
+       ret
+       X86_SHA256_HashBlocks ENDP
+#endif
+
+#ifdef __GNUC__
+       ".att_syntax prefix;"
+       : 
+       : "c" (state), "d" (data), "S" (SHA256_K+48), "D" (len)
+       #if CRYPTOPP_BOOL_X64
+               , "m" (workspace[0])
+       #endif
+       : "memory", "cc", "%eax"
+       #if CRYPTOPP_BOOL_X64
+               , "%rbx", "%r8"
+       #endif
+       );
+#endif
+}
+
+#endif // #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM)
+
+#ifndef CRYPTOPP_GENERATE_X64_MASM
+
+#ifdef CRYPTOPP_X64_MASM_AVAILABLE
+extern "C" {
+void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len);
+}
+#endif
+
+#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
+
+size_t SHA256::HashMultipleBlocks(const word32 *input, size_t length)
+{
+       X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2());
+       return length % BLOCKSIZE;
+}
+
+size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length)
+{
+       X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2());
+       return length % BLOCKSIZE;
+}
+
+#endif
+
+#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
+
+#define Ch(x,y,z) (z^(x&(y^z)))
+#define Maj(x,y,z) (y^((x^y)&(y^z)))
+
+#define a(i) T[(0-i)&7]
+#define b(i) T[(1-i)&7]
+#define c(i) T[(2-i)&7]
+#define d(i) T[(3-i)&7]
+#define e(i) T[(4-i)&7]
+#define f(i) T[(5-i)&7]
+#define g(i) T[(6-i)&7]
+#define h(i) T[(7-i)&7]
+
+#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\
+       d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
+
+// for SHA256
+#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
+#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
+#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
+#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
+
+void SHA256::Transform(word32 *state, const word32 *data)
+{
+       word32 W[16];
+#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
+       // this byte reverse is a waste of time, but this function is only called by MDC
+       ByteReverse(W, data, BLOCKSIZE);
+       X86_SHA256_HashBlocks(state, W, BLOCKSIZE - !HasSSE2());
+#else
+       word32 T[8];
+    /* Copy context->state[] to working vars */
+       memcpy(T, state, sizeof(T));
+    /* 64 operations, partially loop unrolled */
+       for (unsigned int j=0; j<64; j+=16)
+       {
+               R( 0); R( 1); R( 2); R( 3);
+               R( 4); R( 5); R( 6); R( 7);
+               R( 8); R( 9); R(10); R(11);
+               R(12); R(13); R(14); R(15);
+       }
+    /* Add the working vars back into context.state[] */
+    state[0] += a(0);
+    state[1] += b(0);
+    state[2] += c(0);
+    state[3] += d(0);
+    state[4] += e(0);
+    state[5] += f(0);
+    state[6] += g(0);
+    state[7] += h(0);
+#endif
+}
+
+/* 
+// smaller but slower
+void SHA256::Transform(word32 *state, const word32 *data)
+{
+       word32 T[20];
+       word32 W[32];
+       unsigned int i = 0, j = 0;
+       word32 *t = T+8;
+
+       memcpy(t, state, 8*4);
+       word32 e = t[4], a = t[0];
+
+       do 
+       {
+               word32 w = data[j];
+               W[j] = w;
+               w += SHA256_K[j];
+               w += t[7];
+               w += S1(e);
+               w += Ch(e, t[5], t[6]);
+               e = t[3] + w;
+               t[3] = t[3+8] = e;
+               w += S0(t[0]);
+               a = w + Maj(a, t[1], t[2]);
+               t[-1] = t[7] = a;
+               --t;
+               ++j;
+               if (j%8 == 0)
+                       t += 8;
+       } while (j<16);
+
+       do
+       {
+               i = j&0xf;
+               word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7];
+               W[i+16] = W[i] = w;
+               w += SHA256_K[j];
+               w += t[7];
+               w += S1(e);
+               w += Ch(e, t[5], t[6]);
+               e = t[3] + w;
+               t[3] = t[3+8] = e;
+               w += S0(t[0]);
+               a = w + Maj(a, t[1], t[2]);
+               t[-1] = t[7] = a;
+
+               w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7];
+               W[(i+1)+16] = W[(i+1)] = w;
+               w += SHA256_K[j+1];
+               w += (t-1)[7];
+               w += S1(e);
+               w += Ch(e, (t-1)[5], (t-1)[6]);
+               e = (t-1)[3] + w;
+               (t-1)[3] = (t-1)[3+8] = e;
+               w += S0((t-1)[0]);
+               a = w + Maj(a, (t-1)[1], (t-1)[2]);
+               (t-1)[-1] = (t-1)[7] = a;
+
+               t-=2;
+               j+=2;
+               if (j%8 == 0)
+                       t += 8;
+       } while (j<64);
+
+    state[0] += a;
+    state[1] += t[1];
+    state[2] += t[2];
+    state[3] += t[3];
+    state[4] += e;
+    state[5] += t[5];
+    state[6] += t[6];
+    state[7] += t[7];
+}
+*/
+
+#undef S0
+#undef S1
+#undef s0
+#undef s1
+#undef R
+
+// *************************************************************
+
+void SHA384::InitState(HashWordType *state)
+{
+       static const word64 s[8] = {
+               W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507),
+               W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939),
+               W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511),
+               W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)};
+       memcpy(state, s, sizeof(s));
+}
+
+void SHA512::InitState(HashWordType *state)
+{
+       static const word64 s[8] = {
+               W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
+               W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
+               W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
+               W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)};
+       memcpy(state, s, sizeof(s));
+}
+
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
+CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = {
+#else
+static const word64 SHA512_K[80] = {
+#endif
+       W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
+       W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
+       W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
+       W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
+       W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
+       W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
+       W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
+       W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
+       W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
+       W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
+       W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
+       W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
+       W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
+       W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
+       W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
+       W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
+       W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
+       W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
+       W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
+       W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
+       W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
+       W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
+       W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
+       W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
+       W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
+       W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
+       W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
+       W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
+       W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
+       W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
+       W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
+       W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
+       W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
+       W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
+       W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
+       W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
+       W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
+       W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
+       W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
+       W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
+};
+
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
+// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version
+CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data)
+{
+#ifdef __GNUC__
+       __asm__ __volatile__
+       (
+               ".intel_syntax noprefix;"
+       AS1(    push    ebx)
+       AS2(    mov             ebx, eax)
+#else
+       AS1(    push    ebx)
+       AS1(    push    esi)
+       AS1(    push    edi)
+       AS2(    lea             ebx, SHA512_K)
+#endif
+
+       AS2(    mov             eax, esp)
+       AS2(    and             esp, 0xfffffff0)
+       AS2(    sub             esp, 27*16)                             // 17*16 for expanded data, 20*8 for state
+       AS1(    push    eax)
+       AS2(    xor             eax, eax)
+       AS2(    lea             edi, [esp+4+8*8])               // start at middle of state buffer. will decrement pointer each round to avoid copying
+       AS2(    lea             esi, [esp+4+20*8+8])    // 16-byte alignment, then add 8
+
+       AS2(    movdqa  xmm0, [ecx+0*16])
+       AS2(    movdq2q mm4, xmm0)
+       AS2(    movdqa  [edi+0*16], xmm0)
+       AS2(    movdqa  xmm0, [ecx+1*16])
+       AS2(    movdqa  [edi+1*16], xmm0)
+       AS2(    movdqa  xmm0, [ecx+2*16])
+       AS2(    movdq2q mm5, xmm0)
+       AS2(    movdqa  [edi+2*16], xmm0)
+       AS2(    movdqa  xmm0, [ecx+3*16])
+       AS2(    movdqa  [edi+3*16], xmm0)
+       ASJ(    jmp,    0, f)
+
+#define SSE2_S0_S1(r, a, b, c) \
+       AS2(    movq    mm6, r)\
+       AS2(    psrlq   r, a)\
+       AS2(    movq    mm7, r)\
+       AS2(    psllq   mm6, 64-c)\
+       AS2(    pxor    mm7, mm6)\
+       AS2(    psrlq   r, b-a)\
+       AS2(    pxor    mm7, r)\
+       AS2(    psllq   mm6, c-b)\
+       AS2(    pxor    mm7, mm6)\
+       AS2(    psrlq   r, c-b)\
+       AS2(    pxor    r, mm7)\
+       AS2(    psllq   mm6, b-a)\
+       AS2(    pxor    r, mm6)
+
+#define SSE2_s0(r, a, b, c)    \
+       AS2(    movdqa  xmm6, r)\
+       AS2(    psrlq   r, a)\
+       AS2(    movdqa  xmm7, r)\
+       AS2(    psllq   xmm6, 64-c)\
+       AS2(    pxor    xmm7, xmm6)\
+       AS2(    psrlq   r, b-a)\
+       AS2(    pxor    xmm7, r)\
+       AS2(    psrlq   r, c-b)\
+       AS2(    pxor    r, xmm7)\
+       AS2(    psllq   xmm6, c-a)\
+       AS2(    pxor    r, xmm6)
+
+#define SSE2_s1(r, a, b, c)    \
+       AS2(    movdqa  xmm6, r)\
+       AS2(    psrlq   r, a)\
+       AS2(    movdqa  xmm7, r)\
+       AS2(    psllq   xmm6, 64-c)\
+       AS2(    pxor    xmm7, xmm6)\
+       AS2(    psrlq   r, b-a)\
+       AS2(    pxor    xmm7, r)\
+       AS2(    psllq   xmm6, c-b)\
+       AS2(    pxor    xmm7, xmm6)\
+       AS2(    psrlq   r, c-b)\
+       AS2(    pxor    r, xmm7)
+
+       ASL(SHA512_Round)
+       // k + w is in mm0, a is in mm4, e is in mm5
+       AS2(    paddq   mm0, [edi+7*8])         // h
+       AS2(    movq    mm2, [edi+5*8])         // f
+       AS2(    movq    mm3, [edi+6*8])         // g
+       AS2(    pxor    mm2, mm3)
+       AS2(    pand    mm2, mm5)
+       SSE2_S0_S1(mm5,14,18,41)
+       AS2(    pxor    mm2, mm3)
+       AS2(    paddq   mm0, mm2)                       // h += Ch(e,f,g)
+       AS2(    paddq   mm5, mm0)                       // h += S1(e)
+       AS2(    movq    mm2, [edi+1*8])         // b
+       AS2(    movq    mm1, mm2)
+       AS2(    por             mm2, mm4)
+       AS2(    pand    mm2, [edi+2*8])         // c
+       AS2(    pand    mm1, mm4)
+       AS2(    por             mm1, mm2)
+       AS2(    paddq   mm1, mm5)                       // temp = h + Maj(a,b,c)
+       AS2(    paddq   mm5, [edi+3*8])         // e = d + h
+       AS2(    movq    [edi+3*8], mm5)
+       AS2(    movq    [edi+11*8], mm5)
+       SSE2_S0_S1(mm4,28,34,39)                        // S0(a)
+       AS2(    paddq   mm4, mm1)                       // a = temp + S0(a)
+       AS2(    movq    [edi-8], mm4)
+       AS2(    movq    [edi+7*8], mm4)
+       AS1(    ret)
+
+       // first 16 rounds
+       ASL(0)
+       AS2(    movq    mm0, [edx+eax*8])
+       AS2(    movq    [esi+eax*8], mm0)
+       AS2(    movq    [esi+eax*8+16*8], mm0)
+       AS2(    paddq   mm0, [ebx+eax*8])
+       ASC(    call,   SHA512_Round)
+       AS1(    inc             eax)
+       AS2(    sub             edi, 8)
+       AS2(    test    eax, 7)
+       ASJ(    jnz,    0, b)
+       AS2(    add             edi, 8*8)
+       AS2(    cmp             eax, 16)
+       ASJ(    jne,    0, b)
+
+       // rest of the rounds
+       AS2(    movdqu  xmm0, [esi+(16-2)*8])
+       ASL(1)
+       // data expansion, W[i-2] already in xmm0
+       AS2(    movdqu  xmm3, [esi])
+       AS2(    paddq   xmm3, [esi+(16-7)*8])
+       AS2(    movdqa  xmm2, [esi+(16-15)*8])
+       SSE2_s1(xmm0, 6, 19, 61)
+       AS2(    paddq   xmm0, xmm3)
+       SSE2_s0(xmm2, 1, 7, 8)
+       AS2(    paddq   xmm0, xmm2)
+       AS2(    movdq2q mm0, xmm0)
+       AS2(    movhlps xmm1, xmm0)
+       AS2(    paddq   mm0, [ebx+eax*8])
+       AS2(    movlps  [esi], xmm0)
+       AS2(    movlps  [esi+8], xmm1)
+       AS2(    movlps  [esi+8*16], xmm0)
+       AS2(    movlps  [esi+8*17], xmm1)
+       // 2 rounds
+       ASC(    call,   SHA512_Round)
+       AS2(    sub             edi, 8)
+       AS2(    movdq2q mm0, xmm1)
+       AS2(    paddq   mm0, [ebx+eax*8+8])
+       ASC(    call,   SHA512_Round)
+       // update indices and loop
+       AS2(    add             esi, 16)
+       AS2(    add             eax, 2)
+       AS2(    sub             edi, 8)
+       AS2(    test    eax, 7)
+       ASJ(    jnz,    1, b)
+       // do housekeeping every 8 rounds
+       AS2(    mov             esi, 0xf)
+       AS2(    and             esi, eax)
+       AS2(    lea             esi, [esp+4+20*8+8+esi*8])
+       AS2(    add             edi, 8*8)
+       AS2(    cmp             eax, 80)
+       ASJ(    jne,    1, b)
+
+#define SSE2_CombineState(i)   \
+       AS2(    movdqa  xmm0, [edi+i*16])\
+       AS2(    paddq   xmm0, [ecx+i*16])\
+       AS2(    movdqa  [ecx+i*16], xmm0)
+
+       SSE2_CombineState(0)
+       SSE2_CombineState(1)
+       SSE2_CombineState(2)
+       SSE2_CombineState(3)
+
+       AS1(    pop             esp)
+       AS1(    emms)
+
+#if defined(__GNUC__)
+       AS1(    pop             ebx)
+       ".att_syntax prefix;"
+               :
+               : "a" (SHA512_K), "c" (state), "d" (data)
+               : "%esi", "%edi", "memory", "cc"
+       );
+#else
+       AS1(    pop             edi)
+       AS1(    pop             esi)
+       AS1(    pop             ebx)
+       AS1(    ret)
+#endif
+}
+#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+
+void SHA512::Transform(word64 *state, const word64 *data)
+{
+#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
+       if (HasSSE2())
+       {
+               SHA512_SSE2_Transform(state, data);
+               return;
+       }
+#endif
+
+#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
+#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
+#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
+#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
+
+#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\
+       d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
+
+       word64 W[16];
+       word64 T[8];
+    /* Copy context->state[] to working vars */
+       memcpy(T, state, sizeof(T));
+    /* 80 operations, partially loop unrolled */
+       for (unsigned int j=0; j<80; j+=16)
+       {
+               R( 0); R( 1); R( 2); R( 3);
+               R( 4); R( 5); R( 6); R( 7);
+               R( 8); R( 9); R(10); R(11);
+               R(12); R(13); R(14); R(15);
+       }
+    /* Add the working vars back into context.state[] */
+    state[0] += a(0);
+    state[1] += b(0);
+    state[2] += c(0);
+    state[3] += d(0);
+    state[4] += e(0);
+    state[5] += f(0);
+    state[6] += g(0);
+    state[7] += h(0);
+}
+
+NAMESPACE_END
+
+#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
+#endif // #ifndef CRYPTOPP_IMPORTS
diff --git a/cryptopp/sha.h b/cryptopp/sha.h
new file mode 100644 (file)
index 0000000..679081e
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef CRYPTOPP_SHA_H
+#define CRYPTOPP_SHA_H
+
+#include "iterhash.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+/// <a href="http://www.weidai.com/scan-mirror/md.html#SHA-1">SHA-1</a>
+class CRYPTOPP_DLL SHA1 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 20, SHA1>
+{
+public:
+       static void CRYPTOPP_API InitState(HashWordType *state);
+       static void CRYPTOPP_API Transform(word32 *digest, const word32 *data);
+       static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-1";}
+};
+
+typedef SHA1 SHA;      // for backwards compatibility
+
+//! implements the SHA-256 standard
+class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA256, 32, true>
+{
+public:
+#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
+       size_t HashMultipleBlocks(const word32 *input, size_t length);
+#endif
+       static void CRYPTOPP_API InitState(HashWordType *state);
+       static void CRYPTOPP_API Transform(word32 *digest, const word32 *data);
+       static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-256";}
+};
+
+//! implements the SHA-224 standard
+class CRYPTOPP_DLL SHA224 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA224, 28, true>
+{
+public:
+#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
+       size_t HashMultipleBlocks(const word32 *input, size_t length);
+#endif
+       static void CRYPTOPP_API InitState(HashWordType *state);
+       static void CRYPTOPP_API Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);}
+       static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-224";}
+};
+
+//! implements the SHA-512 standard
+class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA512, 64, CRYPTOPP_BOOL_X86>
+{
+public:
+       static void CRYPTOPP_API InitState(HashWordType *state);
+       static void CRYPTOPP_API Transform(word64 *digest, const word64 *data);
+       static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-512";}
+};
+
+//! implements the SHA-384 standard
+class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA384, 48, CRYPTOPP_BOOL_X86>
+{
+public:
+       static void CRYPTOPP_API InitState(HashWordType *state);
+       static void CRYPTOPP_API Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);}
+       static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-384";}
+};
+
+NAMESPACE_END
+
+#endif
diff --git a/cryptopp/simple.h b/cryptopp/simple.h
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/cryptopp/smartptr.h b/cryptopp/smartptr.h
new file mode 100644 (file)
index 0000000..6b4040e
--- /dev/null
@@ -0,0 +1,223 @@
+#ifndef CRYPTOPP_SMARTPTR_H
+#define CRYPTOPP_SMARTPTR_H
+
+#include "config.h"
+#include <algorithm>
+
+NAMESPACE_BEGIN(CryptoPP)
+
+template <class T> class simple_ptr
+{
+public:
+       simple_ptr() : m_p(NULL) {}
+       ~simple_ptr() {delete m_p;}
+       T *m_p;
+};
+
+template <class T> class member_ptr
+{
+public:
+       explicit member_ptr(T *p = NULL) : m_p(p) {}
+
+       ~member_ptr();
+
+       const T& operator*() const { return *m_p; }
+       T& operator*() { return *m_p; }
+
+       const T* operator->() const { return m_p; }
+       T* operator->() { return m_p; }
+
+       const T* get() const { return m_p; }
+       T* get() { return m_p; }
+
+       T* release()
+       {
+               T *old_p = m_p;
+               m_p = 0;
+               return old_p;
+       } 
+
+       void reset(T *p = 0);
+
+protected:
+       member_ptr(const member_ptr<T>& rhs);           // copy not allowed
+       void operator=(const member_ptr<T>& rhs);       // assignment not allowed
+
+       T *m_p;
+};
+
+template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
+template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
+
+// ********************************************************
+
+template<class T> class value_ptr : public member_ptr<T>
+{
+public:
+       value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {}
+       value_ptr(T *p = NULL) : member_ptr<T>(p) {}
+       value_ptr(const value_ptr<T>& rhs)
+               : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULL) {}
+
+       value_ptr<T>& operator=(const value_ptr<T>& rhs);
+       bool operator==(const value_ptr<T>& rhs)
+       {
+               return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p);
+       }
+};
+
+template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs)
+{
+       T *old_p = this->m_p;
+       this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULL;
+       delete old_p;
+       return *this;
+}
+
+// ********************************************************
+
+template<class T> class clonable_ptr : public member_ptr<T>
+{
+public:
+       clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {}
+       clonable_ptr(T *p = NULL) : member_ptr<T>(p) {}
+       clonable_ptr(const clonable_ptr<T>& rhs)
+               : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULL) {}
+
+       clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs);
+};
+
+template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs)
+{
+       T *old_p = this->m_p;
+       this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULL;
+       delete old_p;
+       return *this;
+}
+
+// ********************************************************
+
+template<class T> class counted_ptr
+{
+public:
+       explicit counted_ptr(T *p = 0);
+       counted_ptr(const T &r) : m_p(0) {attach(r);}
+       counted_ptr(const counted_ptr<T>& rhs);
+
+       ~counted_ptr();
+
+       const T& operator*() const { return *m_p; }
+       T& operator*() { return *m_p; }
+
+       const T* operator->() const { return m_p; }
+       T* operator->() { return get(); }
+
+       const T* get() const { return m_p; }
+       T* get();
+
+       void attach(const T &p);
+
+       counted_ptr<T> & operator=(const counted_ptr<T>& rhs);
+
+private:
+       T *m_p;
+};
+
+template <class T> counted_ptr<T>::counted_ptr(T *p)
+       : m_p(p) 
+{
+       if (m_p)
+               m_p->m_referenceCount = 1;
+}
+
+template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs)
+       : m_p(rhs.m_p)
+{
+       if (m_p)
+               m_p->m_referenceCount++;
+}
+
+template <class T> counted_ptr<T>::~counted_ptr()
+{
+       if (m_p && --m_p->m_referenceCount == 0)
+               delete m_p;
+}
+
+template <class T> void counted_ptr<T>::attach(const T &r)
+{
+       if (m_p && --m_p->m_referenceCount == 0)
+               delete m_p;
+       if (r.m_referenceCount == 0)
+       {
+               m_p = r.clone();
+               m_p->m_referenceCount = 1;
+       }
+       else
+       {
+               m_p = const_cast<T *>(&r);
+               m_p->m_referenceCount++;
+       }
+}
+
+template <class T> T* counted_ptr<T>::get()
+{
+       if (m_p && m_p->m_referenceCount > 1)
+       {
+               T *temp = m_p->clone();
+               m_p->m_referenceCount--;
+               m_p = temp;
+               m_p->m_referenceCount = 1;
+       }
+       return m_p;
+}
+
+template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs)
+{
+       if (m_p != rhs.m_p)
+       {
+               if (m_p && --m_p->m_referenceCount == 0)
+                       delete m_p;
+               m_p = rhs.m_p;
+               if (m_p)
+                       m_p->m_referenceCount++;
+       }
+       return *this;
+}
+
+// ********************************************************
+
+template <class T> class vector_member_ptrs
+{
+public:
+       vector_member_ptrs(size_t size=0)
+               : m_size(size), m_ptr(new member_ptr<T>[size]) {}
+       ~vector_member_ptrs()
+               {delete [] this->m_ptr;}
+
+       member_ptr<T>& operator[](size_t index)
+               {assert(index<this->m_size); return this->m_ptr[index];}
+       const member_ptr<T>& operator[](size_t index) const
+               {assert(index<this->m_size); return this->m_ptr[index];}
+
+       size_t size() const {return this->m_size;}
+       void resize(size_t newSize)
+       {
+               member_ptr<T> *newPtr = new member_ptr<T>[newSize];
+               for (size_t i=0; i<this->m_size && i<newSize; i++)
+                       newPtr[i].reset(this->m_ptr[i].release());
+               delete [] this->m_ptr;
+               this->m_size = newSize;
+               this->m_ptr = newPtr;
+       }
+
+private:
+       vector_member_ptrs(const vector_member_ptrs<T> &c);     // copy not allowed
+       void operator=(const vector_member_ptrs<T> &x);         // assignment not allowed
+
+       size_t m_size;
+       member_ptr<T> *m_ptr;
+};
+
+NAMESPACE_END
+
+#endif
diff --git a/cryptopp/stdcpp.h b/cryptopp/stdcpp.h
new file mode 100644 (file)
index 0000000..9a468ab
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef CRYPTOPP_STDCPP_H
+#define CRYPTOPP_STDCPP_H
+
+#include <stddef.h>
+#include <assert.h>
+#include <limits.h>
+#include <memory>
+#include <string>
+#include <exception>
+#include <typeinfo>
+
+
+#ifdef _MSC_VER
+#include <string.h>    // CodeWarrior doesn't have memory.h
+#include <algorithm>
+#include <map>
+#include <vector>
+
+// re-disable this
+#pragma warning(disable: 4231)
+#endif
+
+#if defined(_MSC_VER) && defined(_CRTAPI1)
+#define CRYPTOPP_MSVCRT6
+#endif
+
+#endif
index f16fce7..15a182d 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -3,7 +3,7 @@
 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
 
 #include "headers.h"
-#include "sha.h"
+#include "cryptopp/sha.h"
 
 
 
@@ -1369,6 +1369,8 @@ bool CBlock::AcceptBlock()
         return error("AcceptBlock() : rejected by checkpoint lockin at 33333");
     if (pindexPrev->nHeight+1 == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a"))
         return error("AcceptBlock() : rejected by checkpoint lockin at 68555");
+    if (pindexPrev->nHeight+1 == 70567 && hash != uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a"))
+        return error("AcceptBlock() : rejected by checkpoint lockin at 70567");
 
     // Write block to history file
     if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
@@ -2551,82 +2553,11 @@ using CryptoPP::ByteReverse;
 static const unsigned int pSHA256InitState[8] =
 {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
 
-static const unsigned int SHA256_K[64] = {
-    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
-    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
-    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
-    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
-    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
-    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
-    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-
-#define blk0(i) (W[i] = dat[i])
-
-#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
-
-#define Ch(x,y,z) (z^(x&(y^z)))
-#define Maj(x,y,z) ((x&y)|(z&(x|y)))
-
-#define a(i) T[(0-i)&7]
-#define b(i) T[(1-i)&7]
-#define c(i) T[(2-i)&7]
-#define d(i) T[(3-i)&7]
-#define e(i) T[(4-i)&7]
-#define f(i) T[(5-i)&7]
-#define g(i) T[(6-i)&7]
-#define h(i) T[(7-i)&7]
-
-#define R(i,j) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\
-                                         d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
-
-#define rotrFixed(x,y) ((x>>y) | (x<<(sizeof(unsigned int)*8-y)))
-
-// for SHA256
-#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
-#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
-#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
-#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
-
-#if 1
-inline void SHA256Transform(void* pout, const void* pin, const void* pinit)
-{
-    memcpy(pout, pinit, 32);
-    unsigned int* dat = (unsigned int*)pin;
-    unsigned int* T = (unsigned int*)pout;
-    unsigned int* initstate = (unsigned int*)pinit;
-    unsigned int W[16];
-
-    R( 0,  0); R( 1,  0); R( 2,  0); R( 3,  0); R( 4,  0); R( 5,  0); R( 6,  0); R( 7,  0); R( 8,  0); R( 9,  0); R(10,  0); R(11,  0); R(12,  0); R(13,  0); R(14,  0); R(15,  0);
-    R( 0, 16); R( 1, 16); R( 2, 16); R( 3, 16); R( 4, 16); R( 5, 16); R( 6, 16); R( 7, 16); R( 8, 16); R( 9, 16); R(10, 16); R(11, 16); R(12, 16); R(13, 16); R(14, 16); R(15, 16);
-    R( 0, 32); R( 1, 32); R( 2, 32); R( 3, 32); R( 4, 32); R( 5, 32); R( 6, 32); R( 7, 32); R( 8, 32); R( 9, 32); R(10, 32); R(11, 32); R(12, 32); R(13, 32); R(14, 32); R(15, 32);
-    R( 0, 48); R( 1, 48); R( 2, 48); R( 3, 48); R( 4, 48); R( 5, 48); R( 6, 48); R( 7, 48); R( 8, 48); R( 9, 48); R(10, 48); R(11, 48); R(12, 48); R(13, 48); R(14, 48); R(15, 48);
-
-    T[0] += initstate[0];
-    T[1] += initstate[1];
-    T[2] += initstate[2];
-    T[3] += initstate[3];
-    T[4] += initstate[4];
-    T[5] += initstate[5];
-    T[6] += initstate[6];
-    T[7] += initstate[7];
-}
-#else
 inline void SHA256Transform(void* pstate, void* pinput, const void* pinit)
 {
     memcpy(pstate, pinit, 32);
     CryptoPP::SHA256::Transform((CryptoPP::word32*)pstate, (CryptoPP::word32*)pinput);
 }
-#endif
 
 
 
@@ -2645,7 +2576,7 @@ void BitcoinMiner()
         Sleep(50);
         if (fShutdown)
             return;
-        while (vNodes.empty())
+        while (vNodes.empty() || IsInitialBlockDownload())
         {
             Sleep(1000);
             if (fShutdown)
@@ -2728,7 +2659,7 @@ void BitcoinMiner()
         //
         // Prebuild hash buffer
         //
-        struct unnamed1
+        struct tmpworkspace
         {
             struct unnamed2
             {
@@ -2743,8 +2674,9 @@ void BitcoinMiner()
             unsigned char pchPadding0[64];
             uint256 hash1;
             unsigned char pchPadding1[64];
-        }
-        tmp;
+        };
+        char tmpbuf[sizeof(tmpworkspace)+16];
+        tmpworkspace& tmp = *(tmpworkspace*)alignup<16>(tmpbuf);
 
         tmp.block.nVersion       = pblock->nVersion;
         tmp.block.hashPrevBlock  = pblock->hashPrevBlock  = (pindexPrev ? pindexPrev->GetBlockHash() : 0);
@@ -2761,7 +2693,8 @@ void BitcoinMiner()
             ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
 
         // Precalc the first half of the first hash, which stays constant
-        uint256 midstate;
+        uint256 midstatebuf[2];
+        uint256& midstate = *alignup<16>(midstatebuf);
         SHA256Transform(&midstate, &tmp.block, pSHA256InitState);
 
 
@@ -2770,7 +2703,8 @@ void BitcoinMiner()
         //
         int64 nStart = GetTime();
         uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
-        uint256 hash;
+        uint256 hashbuf[2];
+        uint256& hash = *alignup<16>(hashbuf);
         loop
         {
             SHA256Transform(&tmp.hash1, (char*)&tmp.block + 64, &midstate);
@@ -2868,25 +2802,7 @@ void BitcoinMiner()
                 if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
                     break;
                 if (pindexPrev != pindexBest)
-                {
-                    // Pause generating during initial download
-                    if (GetTime() - nStart < 20)
-                    {
-                        CBlockIndex* pindexTmp;
-                        do
-                        {
-                            pindexTmp = pindexBest;
-                            for (int i = 0; i < 10; i++)
-                            {
-                                Sleep(1000);
-                                if (fShutdown)
-                                    return;
-                            }
-                        }
-                        while (pindexTmp != pindexBest);
-                    }
                     break;
-                }
 
                 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
                 tmp.block.nTime = ByteReverse(pblock->nTime);
index 0eeeb6a..9140c23 100644 (file)
@@ -32,7 +32,19 @@ DEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
 DEBUGFLAGS=-g -D__WXDEBUG__
 CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
 HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
-    script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h sha.h
+    script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h
+
+OBJS= \
+    obj/util.o \
+    obj/script.o \
+    obj/db.o \
+    obj/net.o \
+    obj/irc.o \
+    obj/main.o \
+    obj/rpc.o \
+    obj/init.o \
+    cryptopp/obj/sha.o \
+    cryptopp/obj/cpu.o
 
 
 all: bitcoin.exe
@@ -41,34 +53,25 @@ all: bitcoin.exe
 obj/%.o: %.cpp $(HEADERS)
        g++ -c $(CFLAGS) -DGUI -o $@ $<
 
-obj/sha.o: sha.cpp sha.h
-       g++ -c $(CFLAGS) -O3 -o $@ $<
+cryptopp/obj/%.o: cryptopp/%.cpp
+       g++ -c $(CFLAGS) -O3 -DCRYPTOPP_X86_ASM_AVAILABLE -o $@ $<
 
 obj/ui_res.o: ui.rc  rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
        windres $(DEFS) $(INCLUDEPATHS) -o $@ -i $<
 
-OBJS= \
-    obj/util.o \
-    obj/script.o \
-    obj/db.o \
-    obj/net.o \
-    obj/irc.o \
-    obj/main.o \
-    obj/rpc.o \
-    obj/init.o
-
-bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o
+bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/ui_res.o
        g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
 
 
 obj/nogui/%.o: %.cpp $(HEADERS)
        g++ -c $(CFLAGS) -o $@ $<
 
-bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o
+bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/ui_res.o
        g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
 
 
 clean:
        -del /Q obj\*
        -del /Q obj\nogui\*
+       -del /Q cryptopp\obj\*
        -del /Q headers.h.gch
index b31de9b..39ca449 100644 (file)
@@ -29,17 +29,7 @@ DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0
 # ppc doesn't work because we don't support big-endian
 CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
 HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
-    script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h sha.h
-
-
-all: bitcoin
-
-
-obj/%.o: %.cpp $(HEADERS)
-       g++ -c $(CFLAGS) -DGUI -o $@ $<
-
-obj/sha.o: sha.cpp sha.h
-       g++ -c $(CFLAGS) -O3 -o $@ $<
+    script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h
 
 OBJS= \
     obj/util.o \
@@ -49,16 +39,28 @@ OBJS= \
     obj/irc.o \
     obj/main.o \
     obj/rpc.o \
-    obj/init.o
+    obj/init.o \
+    cryptopp/obj/sha.o \
+    cryptopp/obj/cpu.o
        
-bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o
+
+all: bitcoin
+
+
+obj/%.o: %.cpp $(HEADERS)
+       g++ -c $(CFLAGS) -DGUI -o $@ $<
+
+cryptopp/obj/%.o: cryptopp/%.cpp
+       g++ -c $(CFLAGS) -O3 -o $@ $<
+
+bitcoin: $(OBJS) obj/ui.o obj/uibase.o
        g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
 
 
 obj/nogui/%.o: %.cpp $(HEADERS)
        g++ -c $(CFLAGS) -o $@ $<
 
-bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o
+bitcoind: $(OBJS:obj/%=obj/nogui/%)
        g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
 
 
index 0935c6c..4c8ded5 100644 (file)
@@ -33,7 +33,19 @@ DEFS=-D__WXGTK__ -DNOPCH
 DEBUGFLAGS=-g -D__WXDEBUG__
 CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
 HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
-    script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h sha.h
+    script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h
+
+OBJS= \
+    obj/util.o \
+    obj/script.o \
+    obj/db.o \
+    obj/net.o \
+    obj/irc.o \
+    obj/main.o \
+    obj/rpc.o \
+    obj/init.o \
+    cryptopp/obj/sha.o \
+    cryptopp/obj/cpu.o
 
 
 all: bitcoin
@@ -45,31 +57,22 @@ headers.h.gch: headers.h $(HEADERS)
 obj/%.o: %.cpp $(HEADERS) headers.h.gch
        g++ -c $(CFLAGS) -DGUI -o $@ $<
 
-obj/sha.o: sha.cpp sha.h
+cryptopp/obj/%.o: cryptopp/%.cpp
        g++ -c $(CFLAGS) -O3 -o $@ $<
 
-OBJS= \
-    obj/util.o \
-    obj/script.o \
-    obj/db.o \
-    obj/net.o \
-    obj/irc.o \
-    obj/main.o \
-    obj/rpc.o \
-    obj/init.o
-
-bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o
+bitcoin: $(OBJS) obj/ui.o obj/uibase.o
        g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
 
 
 obj/nogui/%.o: %.cpp $(HEADERS)
        g++ -c $(CFLAGS) -o $@ $<
 
-bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o
+bitcoind: $(OBJS:obj/%=obj/nogui/%)
        g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
 
 
 clean:
        -rm -f obj/*.o
        -rm -f obj/nogui/*.o
+       -rm -f cryptopp/obj/*.o
        -rm -f headers.h.gch
index 1ce781f..e8e1ea6 100644 (file)
@@ -28,17 +28,29 @@ LIBS= \
   kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib
 
 DEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
-DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
+DEBUGFLAGS=/Zi /D__WXDEBUG__
 CFLAGS=/c /nologo /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
 HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
-    script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h sha.h
+    script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h
+
+OBJS= \
+    obj\util.obj \
+    obj\script.obj \
+    obj\db.obj \
+    obj\net.obj \
+    obj\irc.obj \
+    obj\main.obj \
+    obj\rpc.obj \
+    obj\init.obj \
+    cryptopp\obj\sha.obj \
+    cryptopp\obj\cpu.obj
 
 
 all: bitcoin.exe
 
 
 .cpp{obj}.obj:
-       cl $(CFLAGS) /DGUI /Fo$@ %s
+    cl $(CFLAGS) /DGUI /Fo$@ %s
 
 obj\util.obj: $(HEADERS)
 
@@ -60,28 +72,21 @@ obj\ui.obj: $(HEADERS)
 
 obj\uibase.obj: $(HEADERS)
 
-obj\sha.obj: sha.cpp sha.h
-       cl $(CFLAGS) /O2 /Fo$@ %s
+cryptopp\obj\sha.obj: cryptopp\sha.cpp
+    cl $(CFLAGS) /O2 /Fo$@ %s
 
-obj\ui.res: ui.rc  rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
-       rc $(INCLUDEPATHS) $(DEFS) /Fo$@ %s
+cryptopp\obj\cpu.obj: cryptopp\cpu.cpp
+    cl $(CFLAGS) /O2 /Fo$@ %s
 
-OBJS= \
-    obj\util.obj \
-    obj\script.obj \
-    obj\db.obj \
-    obj\net.obj \
-    obj\irc.obj \
-    obj\main.obj \
-    obj\rpc.obj \
-    obj\init.obj
+obj\ui.res: ui.rc  rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
+    rc $(INCLUDEPATHS) $(DEFS) /Fo$@ %s
 
-bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res
+bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\ui.res
     link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(WXLIBS) $(LIBS)
 
 
 .cpp{obj\nogui}.obj:
-       cl $(CFLAGS) /Fo$@ %s
+    cl $(CFLAGS) /Fo$@ %s
 
 obj\nogui\util.obj: $(HEADERS)
 
@@ -99,11 +104,13 @@ obj\nogui\rpc.obj: $(HEADERS)
 
 obj\nogui\init.obj: $(HEADERS)
 
-bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res
-       link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS)
+bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\ui.res
+    link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS)
 
 
 clean:
-       -del /Q obj\*
-       -del *.ilk
-       -del *.pdb
+    -del /Q obj\*
+    -del /Q obj\nogui\*
+    -del /Q cryptopp\obj\*
+    -del /Q *.ilk
+    -del /Q *.pdb
diff --git a/obj/.gitignore b/obj/.gitignore
new file mode 100644 (file)
index 0000000..d6b7ef3
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/obj/nogui/.gitignore b/obj/nogui/.gitignore
new file mode 100644 (file)
index 0000000..d6b7ef3
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/sha.cpp b/sha.cpp
deleted file mode 100644 (file)
index e691674..0000000
--- a/sha.cpp
+++ /dev/null
@@ -1,554 +0,0 @@
-// This file is public domain
-// SHA routines extracted as a standalone file from:
-// Crypto++: a C++ Class Library of Cryptographic Schemes
-// Version 5.5.2 (9/24/2007)
-// http://www.cryptopp.com
-
-// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c
-
-// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2.
-// Both are in the public domain.
-
-#include <assert.h>
-#include <memory.h>
-#include "sha.h"
-
-namespace CryptoPP
-{
-
-// start of Steve Reid's code
-
-#define blk0(i) (W[i] = data[i])
-#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
-
-void SHA1::InitState(HashWordType *state)
-{
-    state[0] = 0x67452301L;
-    state[1] = 0xEFCDAB89L;
-    state[2] = 0x98BADCFEL;
-    state[3] = 0x10325476L;
-    state[4] = 0xC3D2E1F0L;
-}
-
-#define f1(x,y,z) (z^(x&(y^z)))
-#define f2(x,y,z) (x^y^z)
-#define f3(x,y,z) ((x&y)|(z&(x|y)))
-#define f4(x,y,z) (x^y^z)
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
-#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
-#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
-#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
-#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
-
-void SHA1::Transform(word32 *state, const word32 *data)
-{
-    word32 W[16];
-    /* Copy context->state[] to working vars */
-    word32 a = state[0];
-    word32 b = state[1];
-    word32 c = state[2];
-    word32 d = state[3];
-    word32 e = state[4];
-    /* 4 rounds of 20 operations each. Loop unrolled. */
-    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
-    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
-    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
-    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
-    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
-    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
-    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
-    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
-    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
-    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
-    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
-    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
-    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
-    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
-    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
-    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
-    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
-    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
-    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
-    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-    /* Add the working vars back into context.state[] */
-    state[0] += a;
-    state[1] += b;
-    state[2] += c;
-    state[3] += d;
-    state[4] += e;
-}
-
-// end of Steve Reid's code
-
-// *************************************************************
-
-void SHA224::InitState(HashWordType *state)
-{
-    static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
-    memcpy(state, s, sizeof(s));
-}
-
-void SHA256::InitState(HashWordType *state)
-{
-    static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
-    memcpy(state, s, sizeof(s));
-}
-
-static const word32 SHA256_K[64] = {
-    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
-    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
-    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
-    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
-    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
-    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
-    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-
-#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
-
-#define Ch(x,y,z) (z^(x&(y^z)))
-#define Maj(x,y,z) ((x&y)|(z&(x|y)))
-
-#define a(i) T[(0-i)&7]
-#define b(i) T[(1-i)&7]
-#define c(i) T[(2-i)&7]
-#define d(i) T[(3-i)&7]
-#define e(i) T[(4-i)&7]
-#define f(i) T[(5-i)&7]
-#define g(i) T[(6-i)&7]
-#define h(i) T[(7-i)&7]
-
-#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\
-    d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
-
-// for SHA256
-#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
-#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
-#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
-#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
-
-void SHA256::Transform(word32 *state, const word32 *data)
-{
-    word32 W[16];
-    word32 T[8];
-    /* Copy context->state[] to working vars */
-    memcpy(T, state, sizeof(T));
-    /* 64 operations, partially loop unrolled */
-    for (unsigned int j=0; j<64; j+=16)
-    {
-        R( 0); R( 1); R( 2); R( 3);
-        R( 4); R( 5); R( 6); R( 7);
-        R( 8); R( 9); R(10); R(11);
-        R(12); R(13); R(14); R(15);
-    }
-    /* Add the working vars back into context.state[] */
-    state[0] += a(0);
-    state[1] += b(0);
-    state[2] += c(0);
-    state[3] += d(0);
-    state[4] += e(0);
-    state[5] += f(0);
-    state[6] += g(0);
-    state[7] += h(0);
-}
-
-/*
-// smaller but slower
-void SHA256_Transform(word32 *state, const word32 *data)
-{
-    word32 T[20];
-    word32 W[32];
-    unsigned int i = 0, j = 0;
-    word32 *t = T+8;
-
-    memcpy(t, state, 8*4);
-    word32 e = t[4], a = t[0];
-
-    do
-    {
-        word32 w = data[j];
-        W[j] = w;
-        w += K[j];
-        w += t[7];
-        w += S1(e);
-        w += Ch(e, t[5], t[6]);
-        e = t[3] + w;
-        t[3] = t[3+8] = e;
-        w += S0(t[0]);
-        a = w + Maj(a, t[1], t[2]);
-        t[-1] = t[7] = a;
-        --t;
-        ++j;
-        if (j%8 == 0)
-            t += 8;
-    } while (j<16);
-
-    do
-    {
-        i = j&0xf;
-        word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7];
-        W[i+16] = W[i] = w;
-        w += K[j];
-        w += t[7];
-        w += S1(e);
-        w += Ch(e, t[5], t[6]);
-        e = t[3] + w;
-        t[3] = t[3+8] = e;
-        w += S0(t[0]);
-        a = w + Maj(a, t[1], t[2]);
-        t[-1] = t[7] = a;
-
-        w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7];
-        W[(i+1)+16] = W[(i+1)] = w;
-        w += K[j+1];
-        w += (t-1)[7];
-        w += S1(e);
-        w += Ch(e, (t-1)[5], (t-1)[6]);
-        e = (t-1)[3] + w;
-        (t-1)[3] = (t-1)[3+8] = e;
-        w += S0((t-1)[0]);
-        a = w + Maj(a, (t-1)[1], (t-1)[2]);
-        (t-1)[-1] = (t-1)[7] = a;
-
-        t-=2;
-        j+=2;
-        if (j%8 == 0)
-            t += 8;
-    } while (j<64);
-
-    state[0] += a;
-    state[1] += t[1];
-    state[2] += t[2];
-    state[3] += t[3];
-    state[4] += e;
-    state[5] += t[5];
-    state[6] += t[6];
-    state[7] += t[7];
-}
-*/
-
-#undef S0
-#undef S1
-#undef s0
-#undef s1
-#undef R
-
-// *************************************************************
-
-#ifdef WORD64_AVAILABLE
-
-void SHA384::InitState(HashWordType *state)
-{
-    static const word64 s[8] = {
-        W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507),
-        W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939),
-        W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511),
-        W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)};
-    memcpy(state, s, sizeof(s));
-}
-
-void SHA512::InitState(HashWordType *state)
-{
-    static const word64 s[8] = {
-        W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
-        W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
-        W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
-        W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)};
-    memcpy(state, s, sizeof(s));
-}
-
-CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = {
-    W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
-    W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
-    W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
-    W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
-    W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
-    W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
-    W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
-    W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
-    W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
-    W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
-    W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
-    W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
-    W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
-    W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
-    W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
-    W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
-    W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
-    W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
-    W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
-    W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
-    W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
-    W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
-    W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
-    W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
-    W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
-    W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
-    W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
-    W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
-    W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
-    W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
-    W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
-    W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
-    W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
-    W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
-    W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
-    W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
-    W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
-    W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
-    W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
-    W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
-};
-
-#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
-// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version
-CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data)
-{
-#ifdef __GNUC__
-    __asm__ __volatile__
-    (
-        ".intel_syntax noprefix;"
-    AS1(    push    ebx)
-    AS2(    mov     ebx, eax)
-#else
-    AS1(    push    ebx)
-    AS1(    push    esi)
-    AS1(    push    edi)
-    AS2(    lea     ebx, SHA512_K)
-#endif
-
-    AS2(    mov     eax, esp)
-    AS2(    and     esp, 0xfffffff0)
-    AS2(    sub     esp, 27*16)             // 17*16 for expanded data, 20*8 for state
-    AS1(    push    eax)
-    AS2(    xor     eax, eax)
-    AS2(    lea     edi, [esp+4+8*8])       // start at middle of state buffer. will decrement pointer each round to avoid copying
-    AS2(    lea     esi, [esp+4+20*8+8])    // 16-byte alignment, then add 8
-
-    AS2(    movq    mm4, [ecx+0*8])
-    AS2(    movq    [edi+0*8], mm4)
-    AS2(    movq    mm0, [ecx+1*8])
-    AS2(    movq    [edi+1*8], mm0)
-    AS2(    movq    mm0, [ecx+2*8])
-    AS2(    movq    [edi+2*8], mm0)
-    AS2(    movq    mm0, [ecx+3*8])
-    AS2(    movq    [edi+3*8], mm0)
-    AS2(    movq    mm5, [ecx+4*8])
-    AS2(    movq    [edi+4*8], mm5)
-    AS2(    movq    mm0, [ecx+5*8])
-    AS2(    movq    [edi+5*8], mm0)
-    AS2(    movq    mm0, [ecx+6*8])
-    AS2(    movq    [edi+6*8], mm0)
-    AS2(    movq    mm0, [ecx+7*8])
-    AS2(    movq    [edi+7*8], mm0)
-    ASJ(    jmp,    0, f)
-
-#define SSE2_S0_S1(r, a, b, c)  \
-    AS2(    movq    mm6, r)\
-    AS2(    psrlq   r, a)\
-    AS2(    movq    mm7, r)\
-    AS2(    psllq   mm6, 64-c)\
-    AS2(    pxor    mm7, mm6)\
-    AS2(    psrlq   r, b-a)\
-    AS2(    pxor    mm7, r)\
-    AS2(    psllq   mm6, c-b)\
-    AS2(    pxor    mm7, mm6)\
-    AS2(    psrlq   r, c-b)\
-    AS2(    pxor    r, mm7)\
-    AS2(    psllq   mm6, b-a)\
-    AS2(    pxor    r, mm6)
-
-#define SSE2_s0(r, a, b, c) \
-    AS2(    movdqa  xmm6, r)\
-    AS2(    psrlq   r, a)\
-    AS2(    movdqa  xmm7, r)\
-    AS2(    psllq   xmm6, 64-c)\
-    AS2(    pxor    xmm7, xmm6)\
-    AS2(    psrlq   r, b-a)\
-    AS2(    pxor    xmm7, r)\
-    AS2(    psrlq   r, c-b)\
-    AS2(    pxor    r, xmm7)\
-    AS2(    psllq   xmm6, c-a)\
-    AS2(    pxor    r, xmm6)
-
-#define SSE2_s1(r, a, b, c) \
-    AS2(    movdqa  xmm6, r)\
-    AS2(    psrlq   r, a)\
-    AS2(    movdqa  xmm7, r)\
-    AS2(    psllq   xmm6, 64-c)\
-    AS2(    pxor    xmm7, xmm6)\
-    AS2(    psrlq   r, b-a)\
-    AS2(    pxor    xmm7, r)\
-    AS2(    psllq   xmm6, c-b)\
-    AS2(    pxor    xmm7, xmm6)\
-    AS2(    psrlq   r, c-b)\
-    AS2(    pxor    r, xmm7)
-
-    ASL(SHA512_Round)
-    // k + w is in mm0, a is in mm4, e is in mm5
-    AS2(    paddq   mm0, [edi+7*8])     // h
-    AS2(    movq    mm2, [edi+5*8])     // f
-    AS2(    movq    mm3, [edi+6*8])     // g
-    AS2(    pxor    mm2, mm3)
-    AS2(    pand    mm2, mm5)
-    SSE2_S0_S1(mm5,14,18,41)
-    AS2(    pxor    mm2, mm3)
-    AS2(    paddq   mm0, mm2)           // h += Ch(e,f,g)
-    AS2(    paddq   mm5, mm0)           // h += S1(e)
-    AS2(    movq    mm2, [edi+1*8])     // b
-    AS2(    movq    mm1, mm2)
-    AS2(    por     mm2, mm4)
-    AS2(    pand    mm2, [edi+2*8])     // c
-    AS2(    pand    mm1, mm4)
-    AS2(    por     mm1, mm2)
-    AS2(    paddq   mm1, mm5)           // temp = h + Maj(a,b,c)
-    AS2(    paddq   mm5, [edi+3*8])     // e = d + h
-    AS2(    movq    [edi+3*8], mm5)
-    AS2(    movq    [edi+11*8], mm5)
-    SSE2_S0_S1(mm4,28,34,39)            // S0(a)
-    AS2(    paddq   mm4, mm1)           // a = temp + S0(a)
-    AS2(    movq    [edi-8], mm4)
-    AS2(    movq    [edi+7*8], mm4)
-    AS1(    ret)
-
-    // first 16 rounds
-    ASL(0)
-    AS2(    movq    mm0, [edx+eax*8])
-    AS2(    movq    [esi+eax*8], mm0)
-    AS2(    movq    [esi+eax*8+16*8], mm0)
-    AS2(    paddq   mm0, [ebx+eax*8])
-    ASC(    call,   SHA512_Round)
-    AS1(    inc     eax)
-    AS2(    sub     edi, 8)
-    AS2(    test    eax, 7)
-    ASJ(    jnz,    0, b)
-    AS2(    add     edi, 8*8)
-    AS2(    cmp     eax, 16)
-    ASJ(    jne,    0, b)
-
-    // rest of the rounds
-    AS2(    movdqu  xmm0, [esi+(16-2)*8])
-    ASL(1)
-    // data expansion, W[i-2] already in xmm0
-    AS2(    movdqu  xmm3, [esi])
-    AS2(    paddq   xmm3, [esi+(16-7)*8])
-    AS2(    movdqa  xmm2, [esi+(16-15)*8])
-    SSE2_s1(xmm0, 6, 19, 61)
-    AS2(    paddq   xmm0, xmm3)
-    SSE2_s0(xmm2, 1, 7, 8)
-    AS2(    paddq   xmm0, xmm2)
-    AS2(    movdq2q mm0, xmm0)
-    AS2(    movhlps xmm1, xmm0)
-    AS2(    paddq   mm0, [ebx+eax*8])
-    AS2(    movlps  [esi], xmm0)
-    AS2(    movlps  [esi+8], xmm1)
-    AS2(    movlps  [esi+8*16], xmm0)
-    AS2(    movlps  [esi+8*17], xmm1)
-    // 2 rounds
-    ASC(    call,   SHA512_Round)
-    AS2(    sub     edi, 8)
-    AS2(    movdq2q mm0, xmm1)
-    AS2(    paddq   mm0, [ebx+eax*8+8])
-    ASC(    call,   SHA512_Round)
-    // update indices and loop
-    AS2(    add     esi, 16)
-    AS2(    add     eax, 2)
-    AS2(    sub     edi, 8)
-    AS2(    test    eax, 7)
-    ASJ(    jnz,    1, b)
-    // do housekeeping every 8 rounds
-    AS2(    mov     esi, 0xf)
-    AS2(    and     esi, eax)
-    AS2(    lea     esi, [esp+4+20*8+8+esi*8])
-    AS2(    add     edi, 8*8)
-    AS2(    cmp     eax, 80)
-    ASJ(    jne,    1, b)
-
-#define SSE2_CombineState(i)    \
-    AS2(    movq    mm0, [edi+i*8])\
-    AS2(    paddq   mm0, [ecx+i*8])\
-    AS2(    movq    [ecx+i*8], mm0)
-
-    SSE2_CombineState(0)
-    SSE2_CombineState(1)
-    SSE2_CombineState(2)
-    SSE2_CombineState(3)
-    SSE2_CombineState(4)
-    SSE2_CombineState(5)
-    SSE2_CombineState(6)
-    SSE2_CombineState(7)
-
-    AS1(    pop     esp)
-    AS1(    emms)
-
-#if defined(__GNUC__)
-    AS1(    pop     ebx)
-    ".att_syntax prefix;"
-        :
-        : "a" (SHA512_K), "c" (state), "d" (data)
-        : "%esi", "%edi", "memory", "cc"
-    );
-#else
-    AS1(    pop     edi)
-    AS1(    pop     esi)
-    AS1(    pop     ebx)
-    AS1(    ret)
-#endif
-}
-#endif  // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
-
-void SHA512::Transform(word64 *state, const word64 *data)
-{
-#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
-    if (HasSSE2())
-    {
-        SHA512_SSE2_Transform(state, data);
-        return;
-    }
-#endif
-
-#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
-#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
-#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
-#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
-
-#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\
-    d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
-
-    word64 W[16];
-    word64 T[8];
-    /* Copy context->state[] to working vars */
-    memcpy(T, state, sizeof(T));
-    /* 80 operations, partially loop unrolled */
-    for (unsigned int j=0; j<80; j+=16)
-    {
-        R( 0); R( 1); R( 2); R( 3);
-        R( 4); R( 5); R( 6); R( 7);
-        R( 8); R( 9); R(10); R(11);
-        R(12); R(13); R(14); R(15);
-    }
-    /* Add the working vars back into context.state[] */
-    state[0] += a(0);
-    state[1] += b(0);
-    state[2] += c(0);
-    state[3] += d(0);
-    state[4] += e(0);
-    state[5] += f(0);
-    state[6] += g(0);
-    state[7] += h(0);
-}
-
-#endif
-
-}
diff --git a/sha.h b/sha.h
deleted file mode 100644 (file)
index e3af7b4..0000000
--- a/sha.h
+++ /dev/null
@@ -1,177 +0,0 @@
-// This file is public domain
-// SHA routines extracted as a standalone file from:
-// Crypto++: a C++ Class Library of Cryptographic Schemes
-// Version 5.5.2 (9/24/2007)
-// http://www.cryptopp.com
-#ifndef CRYPTOPP_SHA_H
-#define CRYPTOPP_SHA_H
-#include <stdlib.h>
-
-namespace CryptoPP
-{
-
-//
-// Dependencies
-//
-
-typedef unsigned char byte;
-typedef unsigned short word16;
-typedef unsigned int word32;
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef unsigned __int64 word64;
-#else
-typedef unsigned long long word64;
-#endif
-
-template <class T> inline T rotlFixed(T x, unsigned int y)
-{
-    assert(y < sizeof(T)*8);
-    return T((x<<y) | (x>>(sizeof(T)*8-y)));
-}
-
-template <class T> inline T rotrFixed(T x, unsigned int y)
-{
-    assert(y < sizeof(T)*8);
-    return T((x>>y) | (x<<(sizeof(T)*8-y)));
-}
-
-// ************** endian reversal ***************
-
-#ifdef _MSC_VER
-    #if _MSC_VER >= 1400
-        #define CRYPTOPP_FAST_ROTATE(x) 1
-    #elif _MSC_VER >= 1300
-        #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
-    #else
-        #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
-    #endif
-#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
-    (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
-    #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
-#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions
-    #define CRYPTOPP_FAST_ROTATE(x) 1
-#else
-    #define CRYPTOPP_FAST_ROTATE(x) 0
-#endif
-
-inline byte ByteReverse(byte value)
-{
-    return value;
-}
-
-inline word16 ByteReverse(word16 value)
-{
-#ifdef CRYPTOPP_BYTESWAP_AVAILABLE
-    return bswap_16(value);
-#elif defined(_MSC_VER) && _MSC_VER >= 1300
-    return _byteswap_ushort(value);
-#else
-    return rotlFixed(value, 8U);
-#endif
-}
-
-inline word32 ByteReverse(word32 value)
-{
-#if defined(__GNUC__)
-    __asm__ ("bswap %0" : "=r" (value) : "0" (value));
-    return value;
-#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
-    return bswap_32(value);
-#elif defined(__MWERKS__) && TARGET_CPU_PPC
-    return (word32)__lwbrx(&value,0);
-#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
-    return _byteswap_ulong(value);
-#elif CRYPTOPP_FAST_ROTATE(32)
-    // 5 instructions with rotate instruction, 9 without
-    return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
-#else
-    // 6 instructions with rotate instruction, 8 without
-    value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
-    return rotlFixed(value, 16U);
-#endif
-}
-
-#ifdef WORD64_AVAILABLE
-inline word64 ByteReverse(word64 value)
-{
-#if defined(__GNUC__) && defined(__x86_64__)
-    __asm__ ("bswap %0" : "=r" (value) : "0" (value));
-    return value;
-#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
-    return bswap_64(value);
-#elif defined(_MSC_VER) && _MSC_VER >= 1300
-    return _byteswap_uint64(value);
-#elif defined(CRYPTOPP_SLOW_WORD64)
-    return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
-#else
-    value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
-    value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
-    return rotlFixed(value, 32U);
-#endif
-}
-#endif
-
-
-//
-// SHA
-//
-
-// http://www.weidai.com/scan-mirror/md.html#SHA-1
-class SHA1
-{
-public:
-    typedef word32 HashWordType;
-    static void InitState(word32 *state);
-    static void Transform(word32 *digest, const word32 *data);
-    static const char * StaticAlgorithmName() {return "SHA-1";}
-};
-
-typedef SHA1 SHA;   // for backwards compatibility
-
-// implements the SHA-256 standard
-class SHA256
-{
-public:
-    typedef word32 HashWordType;
-    static void InitState(word32 *state);
-    static void Transform(word32 *digest, const word32 *data);
-    static const char * StaticAlgorithmName() {return "SHA-256";}
-};
-
-// implements the SHA-224 standard
-class SHA224
-{
-public:
-    typedef word32 HashWordType;
-    static void InitState(word32 *state);
-    static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);}
-    static const char * StaticAlgorithmName() {return "SHA-224";}
-};
-
-#ifdef WORD64_AVAILABLE
-
-// implements the SHA-512 standard
-class SHA512
-{
-public:
-    typedef word64 HashWordType;
-    static void InitState(word64 *state);
-    static void Transform(word64 *digest, const word64 *data);
-    static const char * StaticAlgorithmName() {return "SHA-512";}
-};
-
-// implements the SHA-384 standard
-class SHA384
-{
-public:
-    typedef word64 HashWordType;
-    static void InitState(word64 *state);
-    static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);}
-    static const char * StaticAlgorithmName() {return "SHA-384";}
-};
-
-#endif
-
-}
-
-#endif
diff --git a/util.h b/util.h
index d05ab69..1981ec9 100644 (file)
--- a/util.h
+++ b/util.h
@@ -54,6 +54,20 @@ inline T& REF(const T& val)
     return (T&)val;
 }
 
+// Align by increasing pointer, must have extra space at end of buffer
+template <size_t nBytes, typename T>
+T* alignup(T* p)
+{
+    union
+    {
+        T* ptr;
+        size_t n;
+    } u;
+    u.ptr = p;
+    u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
+    return u.ptr;
+}
+
 #ifdef __WXMSW__
 #define MSG_NOSIGNAL        0
 #define MSG_DONTWAIT        0