Compare commits

..

14 Commits

Author SHA1 Message Date
Satoshi Nakamoto
73aa262647 fixed segfault in bignum.h, additional security limits, refactoring
-- version 0.3.7
2010-07-31 20:12:05 +00:00
--author=Satoshi Nakamoto
e1cb7ce017 simplified makefile.unix, updated build-unix.txt instructions to include boost 1.37 2010-07-31 14:14:41 +00:00
--author=Satoshi Nakamoto
a75560d828 reverted makefile.unix wx-config -- version 0.3.6 2010-07-30 17:36:06 +00:00
--author=Satoshi Nakamoto
ec82517c89 Fredrik Roubert: simplified makefile.unix with wx-config, misc 2010-07-30 17:35:17 +00:00
--author=Satoshi Nakamoto
31ffe954b6 fixed makefile.osx 2010-07-30 17:31:39 +00:00
--author=Satoshi Nakamoto
872d60f6e4 fixed makefile.vc 2010-07-30 17:31:05 +00:00
--author=Satoshi Nakamoto
2689f4d02b better IsInitialBlockDownload 2010-07-27 20:46:41 +00:00
--author=Satoshi Nakamoto
3dd20ff2f8 added a subset of Crypto++ 5.6.0 with 48% faster ASM SHA-256, combined speedup 2.5x faster vs 0.3.3, thanks BlackEye for figuring out the alignment problem 2010-07-27 20:43:55 +00:00
--author=Satoshi Nakamoto
9f35575ca3 tcatm's cached SHA256 state idea, about 70% faster generating 2010-07-27 14:21:02 +00:00
Satoshi Nakamoto
b6dc3b517b bitcoind now compiles without wxWidgets or wxBase 2010-07-26 17:44:51 +00:00
Gavin Andresen
f0c11b1917 Gavin: BIO_FLAGS_BASE64_NO_NL 2010-07-26 17:41:47 +00:00
Satoshi Nakamoto
40cd036941 Gavin Andresen's JSON-RPC HTTP authentication,
faster initial block download
-- version 0.3.3
2010-07-26 17:40:05 +00:00
Gavin Andresen
fe98cf8dc5 Configuration file, HTTP Basic authentication 2010-07-23 13:58:39 +00:00
Gavin Andresen
e96cd730d1 json-rpc password, minor UI tweaks, removed some outdated txt files 2010-07-19 01:18:46 +00:00
60 changed files with 7846 additions and 2167 deletions

View File

@@ -401,7 +401,16 @@ public:
CBigNum& operator>>=(unsigned int shift)
{
// Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number
// Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
// if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
CBigNum a = 1;
a <<= shift;
if (BN_cmp(&a, this) > 0)
{
*this = 0;
return *this;
}
if (!BN_rshift(this, this, shift))
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
return *this;
@@ -510,10 +519,8 @@ inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
{
CBigNum r;
// Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number
if (!BN_rshift(&r, &a, shift))
throw bignum_error("CBigNum:operator>> : BN_rshift failed");
CBigNum r = a;
r >>= shift;
return r;
}

View File

@@ -1,2 +0,0 @@
Known bugs:
- Window flickers when blocks are added (problem with repainting?)

View File

@@ -16,13 +16,12 @@ sudo apt-get install libgtk2.0-dev
sudo apt-get install libssl-dev
sudo apt-get install libdb4.7-dev
sudo apt-get install libdb4.7++-dev
sudo apt-get install libboost-all-dev
Boost 1.40+: sudo apt-get install libboost-all-dev
or Boost 1.37: sudo apt-get install libboost1.37-dev
We're now using wxWidgets 2.9, which uses UTF-8.
If using Boost 1.37, append -mt to the boost libraries in the makefile.
There isn't currently a debian package of wxWidgets we can use. The 2.8
packages for Karmic are UTF-16 unicode and won't work for us, and we've had
trouble building 2.8 on 64-bit.
We're now using wxWidgets 2.9, which uses UTF-8. Don't try 2.8, it won't work.
You need to download wxWidgets from http://www.wxwidgets.org/downloads/
and build it yourself. See the build instructions and configure parameters
@@ -34,11 +33,11 @@ Berkeley DB New BSD license with additional requirement that linked software
Boost MIT-like license
Versions used in this release:
GCC 4.4.3
OpenSSL 0.9.8k
GCC 4.3.3
OpenSSL 0.9.8g
wxWidgets 2.9.0
Berkeley DB 4.7.25.NC
Boost 1.40.0
Boost 1.37
Notes
@@ -55,7 +54,7 @@ wxWidgets
---------
cd /usr/local
tar -xzvf wxWidgets-2.9.0.tar.gz
cd /usr/local/wxWidgets-2.9.0
cd wxWidgets-2.9.0
mkdir buildgtk
cd buildgtk
../configure --with-gtk --enable-debug --disable-shared --enable-monolithic
@@ -63,15 +62,6 @@ make
sudo su
make install
ldconfig
su <username>
cd ..
mkdir buildbase
cd buildbase
../configure --disable-gui --enable-debug --disable-shared --enable-monolithic
make
sudo su
make install
ldconfig
Boost

View File

@@ -1,7 +0,0 @@
Changes after 0.1.5:
--------------------
+ Options dialog layout changed - added the UI options panel
+ Minimize to tray feature
+ Startup on system boot feature
+ Ask before closing
+ NSIS installer

67
cryptopp/License.txt Normal file
View File

@@ -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.

429
cryptopp/Readme.txt Normal file
View File

@@ -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

455
cryptopp/config.h Normal file
View File

@@ -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

199
cryptopp/cpu.cpp Normal file
View File

@@ -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

263
cryptopp/cpu.h Normal file
View File

@@ -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

1668
cryptopp/cryptlib.h Normal file

File diff suppressed because it is too large Load Diff

29
cryptopp/iterhash.h Normal file
View File

@@ -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

1134
cryptopp/misc.h Normal file

File diff suppressed because it is too large Load Diff

2
cryptopp/obj/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

21
cryptopp/pch.h Normal file
View File

@@ -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

500
cryptopp/secblock.h Normal file
View File

@@ -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

899
cryptopp/sha.cpp Normal file
View File

@@ -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

63
cryptopp/sha.h Normal file
View File

@@ -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

1
cryptopp/simple.h Normal file
View File

@@ -0,0 +1 @@

223
cryptopp/smartptr.h Normal file
View File

@@ -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

27
cryptopp/stdcpp.h Normal file
View File

@@ -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

38
db.cpp
View File

@@ -60,7 +60,7 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
return;
string strDataDir = GetDataDir();
string strLogDir = strDataDir + "/database";
_mkdir(strLogDir.c_str());
filesystem::create_directory(strLogDir.c_str());
string strErrorFile = strDataDir + "/db.log";
printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str());
@@ -130,7 +130,14 @@ void CDB::Close()
vTxn.front()->abort();
vTxn.clear();
pdb = NULL;
dbenv.txn_checkpoint(0, 0, 0);
// Flush database activity from memory pool to disk log
unsigned int nMinutes = 0;
if (strFile == "addr.dat")
nMinutes = 2;
if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0)
nMinutes = 1;
dbenv.txn_checkpoint(0, nMinutes, 0);
CRITICAL_BLOCK(cs_db)
--mapFileUseCount[strFile];
@@ -357,11 +364,12 @@ CBlockIndex* InsertBlockIndex(uint256 hash)
bool CTxDB::LoadBlockIndex()
{
// Get cursor
// Get database cursor
Dbc* pcursor = GetCursor();
if (!pcursor)
return false;
// Load mapBlockIndex
unsigned int fFlags = DB_SET_RANGE;
loop
{
@@ -398,7 +406,7 @@ bool CTxDB::LoadBlockIndex()
pindexNew->nBits = diskindex.nBits;
pindexNew->nNonce = diskindex.nNonce;
// Watch for genesis block and best block
// Watch for genesis block
if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock)
pindexGenesisBlock = pindexNew;
}
@@ -409,17 +417,33 @@ bool CTxDB::LoadBlockIndex()
}
pcursor->close();
// Calculate bnChainWork
vector<pair<int, CBlockIndex*> > vSortedByHeight;
vSortedByHeight.reserve(mapBlockIndex.size());
foreach(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
{
CBlockIndex* pindex = item.second;
vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
}
sort(vSortedByHeight.begin(), vSortedByHeight.end());
foreach(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
{
CBlockIndex* pindex = item.second;
pindex->bnChainWork = (pindex->pprev ? pindex->pprev->bnChainWork : 0) + pindex->GetBlockWork();
}
// Load hashBestChain pointer to end of best chain
if (!ReadHashBestChain(hashBestChain))
{
if (pindexGenesisBlock == NULL)
return true;
return error("CTxDB::LoadBlockIndex() : hashBestChain not found");
return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded");
}
if (!mapBlockIndex.count(hashBestChain))
return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found");
return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index");
pindexBest = mapBlockIndex[hashBestChain];
nBestHeight = pindexBest->nHeight;
bnBestChainWork = pindexBest->bnChainWork;
printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
return true;

4
db.h
View File

@@ -16,7 +16,7 @@ extern map<string, string> mapAddressBook;
extern CCriticalSection cs_mapAddressBook;
extern vector<unsigned char> vchDefaultKey;
extern bool fClient;
extern int nBestHeight;
extern unsigned int nWalletDBUpdated;
@@ -210,7 +210,7 @@ public:
if (!pdb)
return false;
DbTxn* ptxn = NULL;
int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0);
int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
if (!ptxn || ret != 0)
return false;
vTxn.push_back(ptxn);

View File

@@ -18,14 +18,21 @@
#define _WIN32_IE 0x0400
#define WIN32_LEAN_AND_MEAN 1
#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h
#ifdef GUI
#include <wx/wx.h>
#include <wx/stdpaths.h>
#include <wx/snglinst.h>
#if wxUSE_GUI
#include <wx/utils.h>
#include <wx/clipbrd.h>
#include <wx/taskbar.h>
#else
#ifdef __WXMAC_OSX__
#define __WXMAC__ 1
#define __WXOSX__ 1
#define __BSD__ 1
#endif
#endif
#include <openssl/buffer.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
@@ -60,10 +67,14 @@
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/thread.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/config.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>
#ifdef __WXMSW__
#include <windows.h>
@@ -78,12 +89,14 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <fcntl.h>
#endif
#ifdef __BSD__
#include <netinet/in.h>
@@ -107,10 +120,12 @@ using namespace boost;
#include "irc.h"
#include "main.h"
#include "rpc.h"
#if wxUSE_GUI
#ifdef GUI
#include "uibase.h"
#endif
#include "ui.h"
#else
#include "noui.h"
#endif
#include "init.h"
#include "xpm/addressbook16.xpm"

425
init.cpp
View File

@@ -7,6 +7,15 @@
//////////////////////////////////////////////////////////////////////////////
//
// Shutdown
//
void ExitTimeout(void* parg)
{
#ifdef __WXMSW__
@@ -55,272 +64,59 @@ void Shutdown(void* parg)
//////////////////////////////////////////////////////////////////////////////
//
// Startup folder
// Start
//
#ifdef __WXMSW__
string StartupShortcutPath()
#ifndef GUI
int main(int argc, char* argv[])
{
return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
}
bool GetStartOnSystemStartup()
{
return filesystem::exists(StartupShortcutPath().c_str());
}
void SetStartOnSystemStartup(bool fAutoStart)
{
// If the shortcut exists already, remove it for updating
remove(StartupShortcutPath().c_str());
if (fAutoStart)
{
CoInitialize(NULL);
// Get a pointer to the IShellLink interface.
IShellLink* psl = NULL;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink,
reinterpret_cast<void**>(&psl));
if (SUCCEEDED(hres))
{
// Get the current executable path
TCHAR pszExePath[MAX_PATH];
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
// Set the path to the shortcut target
psl->SetPath(pszExePath);
PathRemoveFileSpec(pszExePath);
psl->SetWorkingDirectory(pszExePath);
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
IPersistFile* ppf = NULL;
hres = psl->QueryInterface(IID_IPersistFile,
reinterpret_cast<void**>(&ppf));
if (SUCCEEDED(hres))
{
WCHAR pwsz[MAX_PATH];
// Ensure that the string is ANSI.
MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH);
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(pwsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
}
}
#elif defined(__WXGTK__)
//
// Follow the Desktop Application Autostart Spec:
// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
//
boost::filesystem::path GetAutostartDir()
{
namespace fs = boost::filesystem;
char* pszConfigHome = getenv("XDG_CONFIG_HOME");
if (pszConfigHome) return fs::path(pszConfigHome) / fs::path("autostart");
char* pszHome = getenv("HOME");
if (pszHome) return fs::path(pszHome) / fs::path(".config/autostart");
return fs::path();
}
boost::filesystem::path GetAutostartFilePath()
{
return GetAutostartDir() / boost::filesystem::path("bitcoin.desktop");
}
bool GetStartOnSystemStartup()
{
boost::filesystem::ifstream optionFile(GetAutostartFilePath());
if (!optionFile.good())
return false;
// Scan through file for "Hidden=true":
string line;
while (!optionFile.eof())
{
getline(optionFile, line);
if (line.find("Hidden") != string::npos &&
line.find("true") != string::npos)
return false;
}
optionFile.close();
return true;
}
void SetStartOnSystemStartup(bool fAutoStart)
{
if (!fAutoStart)
{
unlink(GetAutostartFilePath().native_file_string().c_str());
}
else
{
boost::filesystem::create_directories(GetAutostartDir());
boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc);
if (!optionFile.good())
{
wxMessageBox(_("Cannot write autostart/bitcoin.desktop file"), "Bitcoin");
return;
}
// Write a bitcoin.desktop file to the autostart directory:
char pszExePath[MAX_PATH+1];
memset(pszExePath, 0, sizeof(pszExePath));
readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1);
optionFile << "[Desktop Entry]\n";
optionFile << "Type=Application\n";
optionFile << "Name=Bitcoin\n";
optionFile << "Exec=" << pszExePath << "\n";
optionFile << "Terminal=false\n";
optionFile << "Hidden=false\n";
optionFile.close();
}
}
#else
// TODO: OSX startup stuff; see:
// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html
bool GetStartOnSystemStartup() { return false; }
void SetStartOnSystemStartup(bool fAutoStart) { }
#endif
//////////////////////////////////////////////////////////////////////////////
//
// CMyApp
//
// Define a new application
class CMyApp : public wxApp
{
public:
wxLocale m_locale;
CMyApp(){};
~CMyApp(){};
bool OnInit();
bool OnInit2();
int OnExit();
// Hook Initialize so we can start without GUI
virtual bool Initialize(int& argc, wxChar** argv);
// 2nd-level exception handling: we get all the exceptions occurring in any
// event handler here
virtual bool OnExceptionInMainLoop();
// 3rd, and final, level exception handling: whenever an unhandled
// exception is caught, this function is called
virtual void OnUnhandledException();
// and now for something different: this function is called in case of a
// crash (e.g. dereferencing null pointer, division by 0, ...)
virtual void OnFatalException();
};
IMPLEMENT_APP(CMyApp)
bool CMyApp::Initialize(int& argc, wxChar** argv)
{
if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
wxString(argv[1]) != "start")
{
fCommandLine = true;
}
else if (!fGUI)
{
fDaemon = true;
}
else
{
// wxApp::Initialize will remove environment-specific parameters,
// so it's too early to call ParseParameters yet
for (int i = 1; i < argc; i++)
{
wxString str = argv[i];
#ifdef __WXMSW__
if (str.size() >= 1 && str[0] == '/')
str[0] = '-';
char pszLower[MAX_PATH];
strlcpy(pszLower, str.c_str(), sizeof(pszLower));
strlwr(pszLower);
str = pszLower;
#endif
// haven't decided which argument to use for this yet
if (str == "-daemon" || str == "-d" || str == "start")
fDaemon = true;
}
}
for (int i = 1; i < argc; i++)
if (!IsSwitchChar(argv[i][0]))
fCommandLine = true;
fDaemon = !fCommandLine;
#ifdef __WXGTK__
if (fDaemon || fCommandLine)
if (!fCommandLine)
{
// Call the original Initialize while suppressing error messages
// and ignoring failure. If unable to initialize GTK, it fails
// near the end so hopefully the last few things don't matter.
// Daemonize
pid_t pid = fork();
if (pid < 0)
{
wxLogNull logNo;
wxApp::Initialize(argc, argv);
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
return 1;
}
if (fDaemon)
{
// Daemonize
pid_t pid = fork();
if (pid < 0)
{
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
return false;
}
if (pid > 0)
pthread_exit((void*)0);
}
return true;
if (pid > 0)
pthread_exit((void*)0);
}
#endif
return wxApp::Initialize(argc, argv);
}
if (!AppInit(argc, argv))
return 1;
bool CMyApp::OnInit()
while (!fShutdown)
Sleep(1000000);
return 0;
}
#endif
bool AppInit(int argc, char* argv[])
{
bool fRet = false;
try
{
fRet = OnInit2();
fRet = AppInit2(argc, argv);
}
catch (std::exception& e) {
PrintException(&e, "OnInit()");
PrintException(&e, "AppInit()");
} catch (...) {
PrintException(NULL, "OnInit()");
PrintException(NULL, "AppInit()");
}
if (!fRet)
Shutdown(NULL);
return fRet;
}
extern int g_isPainting;
bool CMyApp::OnInit2()
bool AppInit2(int argc, char* argv[])
{
#ifdef _MSC_VER
// Turn off microsoft heap dump noise
@@ -331,66 +127,30 @@ bool CMyApp::OnInit2()
// Disable confusing "helpful" text message on abort, ctrl-c
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
#endif
#if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI
// Disable malfunctioning wxWidgets debug assertion
g_isPainting = 10000;
#endif
#if wxUSE_GUI
wxImage::AddHandler(new wxPNGHandler);
#endif
#if defined(__WXMSW__ ) || defined(__WXMAC__)
SetAppName("Bitcoin");
#else
SetAppName("bitcoin");
#endif
#ifndef __WXMSW__
umask(077);
#endif
#ifdef __WXMSW__
#if wxUSE_UNICODE
// Hack to set wxConvLibc codepage to UTF-8 on Windows,
// may break if wxMBConv_win32 implementation in strconv.cpp changes.
class wxMBConv_win32 : public wxMBConv
{
public:
long m_CodePage;
size_t m_minMBCharWidth;
};
if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP)
((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8;
#endif
#endif
// Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file
m_locale.Init(wxLANGUAGE_DEFAULT, 0);
m_locale.AddCatalogLookupPathPrefix("locale");
if (!fWindows)
{
m_locale.AddCatalogLookupPathPrefix("/usr/share/locale");
m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale");
}
m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any
m_locale.AddCatalog("bitcoin");
//
// Parameters
//
if (fCommandLine)
{
int ret = CommandLineRPC(argc, argv);
exit(ret);
}
ParseParameters(argc, argv);
if (mapArgs.count("-datadir"))
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
if (mapArgs.count("-?") || mapArgs.count("--help"))
{
wxString strUsage = string() +
string strUsage = string() +
_("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
" bitcoin [options] \t" + "\n" +
" bitcoin [command] \t" + _("Send command to bitcoin running with -server or -daemon\n") +
" bitcoin [command] -? \t" + _("Get help for a command\n") +
" bitcoin help \t" + _("List commands\n") +
" bitcoin [options] \t " + "\n" +
" bitcoin [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") +
" bitcoin [options] <command> -? \t\t " + _("Get help for a command\n") +
" bitcoin help \t\t\t " + _("List commands\n") +
_("Options:\n") +
" -conf=<file> \t " + _("Specify configuration file (default: bitcoin.conf)\n") +
" -gen \t " + _("Generate coins\n") +
" -gen=0 \t " + _("Don't generate coins\n") +
" -min \t " + _("Start minimized\n") +
@@ -402,32 +162,38 @@ bool CMyApp::OnInit2()
" -daemon \t " + _("Run in the background as a daemon and accept commands\n") +
" -? \t " + _("This help message\n");
#if defined(__WXMSW__) && wxUSE_GUI
#if defined(__WXMSW__) && defined(GUI)
// Tabs make the columns line up in the message box
wxMessageBox(strUsage, "Bitcoin", wxOK);
#else
// Remove tabs
strUsage.Replace("\t", "");
fprintf(stderr, "%s", ((string)strUsage).c_str());
strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
fprintf(stderr, "%s", strUsage.c_str());
#endif
return false;
}
if (mapArgs.count("-datadir"))
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
if (mapArgs.count("-debug"))
fDebug = true;
if (mapArgs.count("-printtodebugger"))
fPrintToDebugger = true;
if (fCommandLine)
{
int ret = CommandLineRPC(argc, argv);
exit(ret);
}
if (!fDebug && !pszSetDataDir[0])
ShrinkDebugFile();
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("Bitcoin version %d.%d.%d%s beta, OS version %s\n", VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str());
printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str());
printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str());
printf("Bitcoin version %d.%d.%d%s beta\n", VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer);
#ifdef GUI
printf("OS version %s\n", ((string)wxGetOsDescription()).c_str());
printf("System default language is %d %s\n", g_locale.GetSystemLanguage(), ((string)g_locale.GetSysName()).c_str());
printf("Language file %s (%s)\n", (string("locale/") + (string)g_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)g_locale.GetLocale()).c_str());
#endif
printf("Default data directory %s\n", GetDefaultDataDir().c_str());
if (mapArgs.count("-loadblockindextest"))
@@ -442,7 +208,7 @@ bool CMyApp::OnInit2()
// Limit to single instance per user
// Required to protect the database files if we're going to keep deleting log.*
//
#ifdef __WXMSW__
#if defined(__WXMSW__) && defined(GUI)
// todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file
// maybe should go by whether successfully bind port 8333 instead
wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
@@ -600,8 +366,10 @@ bool CMyApp::OnInit2()
//
// Create the main window and start the node
//
#ifdef GUI
if (!fDaemon)
CreateMainWindow();
#endif
if (!CheckDiskSpace())
return false;
@@ -614,65 +382,10 @@ bool CMyApp::OnInit2()
if (mapArgs.count("-server") || fDaemon)
CreateThread(ThreadRPCServer, NULL);
#ifdef GUI
if (fFirstRun)
SetStartOnSystemStartup(true);
#endif
return true;
}
int CMyApp::OnExit()
{
Shutdown(NULL);
return wxApp::OnExit();
}
bool CMyApp::OnExceptionInMainLoop()
{
try
{
throw;
}
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
return true;
}
void CMyApp::OnUnhandledException()
{
// this shows how we may let some exception propagate uncaught
try
{
throw;
}
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnUnhandledException()");
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnUnhandledException()");
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
}
void CMyApp::OnFatalException()
{
wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR);
}

4
init.h
View File

@@ -3,5 +3,5 @@
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
void Shutdown(void* parg);
bool GetStartOnSystemStartup();
void SetStartOnSystemStartup(bool fAutoStart);
bool AppInit(int argc, char* argv[]);
bool AppInit2(int argc, char* argv[]);

Binary file not shown.

View File

@@ -216,7 +216,7 @@ msgstr "&Neue Empfangs-Adresse"
#: ../../../ui.cpp:1124
#: ../../../ui.cpp:2352
msgid ""
"It's good policy to use a new address for each payment you receive.\n"
"You should use a new address for each payment you receive.\n"
"\n"
"Label"
msgstr ""

Binary file not shown.

View File

@@ -242,7 +242,7 @@ msgstr "Nueva direccion de recepcion"
#: ../../../ui.cpp:1129
#: ../../../ui.cpp:2369
msgid ""
"It's good policy to use a new address for each payment you receive.\n"
"You should use a new address for each payment you receive.\n"
"\n"
"Label"
msgstr ""

Binary file not shown.

View File

@@ -242,7 +242,7 @@ msgstr "Nouvelle adresse de reception"
#: ../../../ui.cpp:1129
#: ../../../ui.cpp:2369
msgid ""
"It's good policy to use a new address for each payment you receive.\n"
"You should use a new address for each payment you receive.\n"
"\n"
"Label"
msgstr ""

Binary file not shown.

View File

@@ -216,7 +216,7 @@ msgstr "Nuovo indirizzo ricevente"
#: ../../../ui.cpp:1124
#: ../../../ui.cpp:2352
msgid ""
"It's good policy to use a new address for each payment you receive.\n"
"You should use a new address for each payment you receive.\n"
"\n"
"Label"
msgstr ""

Binary file not shown.

View File

@@ -216,7 +216,7 @@ msgstr "Nieuw Ontvangings Adres"
#: ../../../ui.cpp:1124
#: ../../../ui.cpp:2352
msgid ""
"It's good policy to use a new address for each payment you receive.\n"
"You should use a new address for each payment you receive.\n"
"\n"
"Label"
msgstr ""

Binary file not shown.

View File

@@ -216,7 +216,7 @@ msgstr "Novo Endereço de Recepção"
#: ../../../ui.cpp:1124
#: ../../../ui.cpp:2352
msgid ""
"It's good policy to use a new address for each payment you receive.\n"
"You should use a new address for each payment you receive.\n"
"\n"
"Label"
msgstr ""

200
main.cpp
View File

@@ -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"
@@ -24,6 +24,7 @@ map<uint256, CBlockIndex*> mapBlockIndex;
const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
CBlockIndex* pindexGenesisBlock = NULL;
int nBestHeight = -1;
CBigNum bnBestChainWork = 0;
uint256 hashBestChain = 0;
CBlockIndex* pindexBest = NULL;
int64 nTimeBestReceived = 0;
@@ -82,6 +83,7 @@ bool AddKey(const CKey& key)
vector<unsigned char> GenerateNewKey()
{
RandAddSeedPerfmon();
CKey key;
key.MakeNewKey();
if (!AddKey(key))
@@ -804,9 +806,9 @@ int64 CBlock::GetBlockValue(int64 nFees) const
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
{
const unsigned int nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
const unsigned int nTargetSpacing = 10 * 60;
const unsigned int nInterval = nTargetTimespan / nTargetSpacing;
const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
const int64 nTargetSpacing = 10 * 60;
const int64 nInterval = nTargetTimespan / nTargetSpacing;
// Genesis block
if (pindexLast == NULL)
@@ -823,8 +825,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
assert(pindexFirst);
// Limit adjustment step
unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime;
printf(" nActualTimespan = %d before bounds\n", nActualTimespan);
int64 nActualTimespan = (int64)pindexLast->nTime - (int64)pindexFirst->nTime;
printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
if (nActualTimespan < nTargetTimespan/4)
nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
@@ -841,13 +843,27 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
/// debug print
printf("GetNextWorkRequired RETARGET\n");
printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
return bnNew.GetCompact();
}
bool IsInitialBlockDownload()
{
if (pindexBest == NULL)
return true;
static int64 nLastUpdate;
static CBlockIndex* pindexLastBest;
if (pindexBest != pindexLastBest)
{
pindexLastBest = pindexBest;
nLastUpdate = GetTime();
}
return (GetTime() - nLastUpdate < 10 &&
pindexBest->nTime < GetTime() - 24 * 60 * 60);
}
@@ -1208,13 +1224,14 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
pindexNew->pprev = (*miPrev).second;
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
}
pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
CTxDB txdb;
txdb.TxnBegin();
txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
// New best
if (pindexNew->nHeight > nBestHeight)
if (pindexNew->bnChainWork > bnBestChainWork)
{
if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
{
@@ -1253,6 +1270,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
hashBestChain = hash;
pindexBest = pindexNew;
nBestHeight = pindexBest->nHeight;
bnBestChainWork = pindexNew->bnChainWork;
nTimeBestReceived = GetTime();
nTransactionsUpdated++;
printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
@@ -1348,6 +1366,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)))
@@ -1486,7 +1506,7 @@ bool CheckDiskSpace(int64 nAdditionalBytes)
{
fShutdown = true;
printf("*** %s***\n", _("Warning: Disk space is low "));
#if wxUSE_GUI
#ifdef GUI
ThreadSafeMessageBox(_("Warning: Disk space is low "), "Bitcoin", wxOK | wxICON_EXCLAMATION);
#endif
CreateThread(Shutdown, NULL);
@@ -2473,7 +2493,7 @@ void GenerateBitcoins(bool fGenerate)
}
if (fGenerateBitcoins)
{
int nProcessors = wxThread::GetCPUCount();
int nProcessors = boost::thread::hardware_concurrency();
printf("%d processors\n", nProcessors);
if (nProcessors < 1)
nProcessors = 1;
@@ -2525,35 +2545,20 @@ int FormatHashBlocks(void* pbuffer, unsigned int len)
}
using CryptoPP::ByteReverse;
static int detectlittleendian = 1;
void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout)
static const unsigned int pSHA256InitState[8] =
{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
inline void SHA256Transform(void* pstate, void* pinput, const void* pinit)
{
unsigned int* pinput = (unsigned int*)pin;
unsigned int* pstate = (unsigned int*)pout;
CryptoPP::SHA256::InitState(pstate);
if (*(char*)&detectlittleendian != 0)
{
for (int n = 0; n < nBlocks; n++)
{
unsigned int pbuf[16];
for (int i = 0; i < 16; i++)
pbuf[i] = ByteReverse(pinput[n * 16 + i]);
CryptoPP::SHA256::Transform(pstate, pbuf);
}
for (int i = 0; i < 8; i++)
pstate[i] = ByteReverse(pstate[i]);
}
else
{
for (int n = 0; n < nBlocks; n++)
CryptoPP::SHA256::Transform(pstate, pinput + n * 16);
}
memcpy(pstate, pinit, 32);
CryptoPP::SHA256::Transform((CryptoPP::word32*)pstate, (CryptoPP::word32*)pinput);
}
void BitcoinMiner()
{
printf("BitcoinMiner started\n");
@@ -2567,7 +2572,7 @@ void BitcoinMiner()
Sleep(50);
if (fShutdown)
return;
while (vNodes.empty())
while (vNodes.empty() || IsInitialBlockDownload())
{
Sleep(1000);
if (fShutdown)
@@ -2650,7 +2655,7 @@ void BitcoinMiner()
//
// Prebuild hash buffer
//
struct unnamed1
struct tmpworkspace
{
struct unnamed2
{
@@ -2665,66 +2670,84 @@ 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);
tmp.block.hashMerkleRoot = pblock->hashMerkleRoot = pblock->BuildMerkleTree();
tmp.block.nTime = pblock->nTime = max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime());
tmp.block.nBits = pblock->nBits = nBits;
tmp.block.nNonce = pblock->nNonce = 1;
tmp.block.nNonce = pblock->nNonce = 0;
unsigned int nBlocks0 = FormatHashBlocks(&tmp.block, sizeof(tmp.block));
unsigned int nBlocks1 = FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
// Byte swap all the input buffer
for (int i = 0; i < sizeof(tmp)/4; i++)
((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
// Precalc the first half of the first hash, which stays constant
uint256 midstatebuf[2];
uint256& midstate = *alignup<16>(midstatebuf);
SHA256Transform(&midstate, &tmp.block, pSHA256InitState);
//
// Search
//
int64 nStart = GetTime();
uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
uint256 hash;
uint256 hashbuf[2];
uint256& hash = *alignup<16>(hashbuf);
loop
{
BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1);
BlockSHA256(&tmp.hash1, nBlocks1, &hash);
SHA256Transform(&tmp.hash1, (char*)&tmp.block + 64, &midstate);
SHA256Transform(&hash, &tmp.hash1, pSHA256InitState);
if (hash <= hashTarget)
if (((unsigned short*)&hash)[14] == 0)
{
pblock->nNonce = tmp.block.nNonce;
assert(hash == pblock->GetHash());
// Byte swap the result after preliminary check
for (int i = 0; i < sizeof(hash)/4; i++)
((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
//// debug print
printf("BitcoinMiner:\n");
printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
pblock->print();
printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
SetThreadPriority(THREAD_PRIORITY_NORMAL);
CRITICAL_BLOCK(cs_main)
if (hash <= hashTarget)
{
if (pindexPrev == pindexBest)
pblock->nNonce = ByteReverse(tmp.block.nNonce);
assert(hash == pblock->GetHash());
//// debug print
printf("BitcoinMiner:\n");
printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
pblock->print();
printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
SetThreadPriority(THREAD_PRIORITY_NORMAL);
CRITICAL_BLOCK(cs_main)
{
// Save key
if (!AddKey(key))
return;
key.MakeNewKey();
if (pindexPrev == pindexBest)
{
// Save key
if (!AddKey(key))
return;
key.MakeNewKey();
// Track how many getdata requests this block gets
CRITICAL_BLOCK(cs_mapRequestCount)
mapRequestCount[pblock->GetHash()] = 0;
// Track how many getdata requests this block gets
CRITICAL_BLOCK(cs_mapRequestCount)
mapRequestCount[pblock->GetHash()] = 0;
// Process this block the same as if we had received it from another node
if (!ProcessBlock(NULL, pblock.release()))
printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n");
// Process this block the same as if we had received it from another node
if (!ProcessBlock(NULL, pblock.release()))
printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n");
}
}
}
SetThreadPriority(THREAD_PRIORITY_LOWEST);
SetThreadPriority(THREAD_PRIORITY_LOWEST);
Sleep(500);
break;
Sleep(500);
break;
}
}
// Update nTime every few seconds
@@ -2775,27 +2798,10 @@ 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;
}
tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
tmp.block.nTime = ByteReverse(pblock->nTime);
}
}
}
@@ -2845,6 +2851,10 @@ int64 GetBalance()
}
int GetRandInt(int nMax)
{
return GetRand(nMax);
}
bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
{
@@ -2858,9 +2868,14 @@ bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
CRITICAL_BLOCK(cs_mapWallet)
{
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
CWalletTx* pcoin = &(*it).second;
vector<CWalletTx*> vCoins;
vCoins.reserve(mapWallet.size());
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
vCoins.push_back(&(*it).second);
random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
foreach(CWalletTx* pcoin, vCoins)
{
if (!pcoin->IsFinal() || pcoin->fSpent)
continue;
int64 n = pcoin->GetCredit();
@@ -3021,7 +3036,8 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
foreach(CWalletTx* pcoin, setCoins)
for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
if (pcoin->vout[nOut].IsMine())
SignSignature(*pcoin, wtxNew, nIn++);
if (!SignSignature(*pcoin, wtxNew, nIn++))
return false;
// Check that enough fee is included
if (nFee < wtxNew.GetMinFee())

17
main.h
View File

@@ -32,6 +32,7 @@ extern map<uint256, CBlockIndex*> mapBlockIndex;
extern const uint256 hashGenesisBlock;
extern CBlockIndex* pindexGenesisBlock;
extern int nBestHeight;
extern CBigNum bnBestChainWork;
extern uint256 hashBestChain;
extern CBlockIndex* pindexBest;
extern unsigned int nTransactionsUpdated;
@@ -78,6 +79,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx
void GenerateBitcoins(bool fGenerate);
void ThreadBitcoinMiner(void* parg);
void BitcoinMiner();
bool IsInitialBlockDownload();
@@ -986,11 +988,14 @@ public:
// Flush stdio buffers and commit to disk before returning
fflush(fileout);
if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
{
#ifdef __WXMSW__
_commit(_fileno(fileout));
_commit(_fileno(fileout));
#else
fsync(fileno(fileout));
fsync(fileno(fileout));
#endif
}
return true;
}
@@ -1072,6 +1077,7 @@ public:
unsigned int nFile;
unsigned int nBlockPos;
int nHeight;
CBigNum bnChainWork;
// block header
int nVersion;
@@ -1089,6 +1095,7 @@ public:
nFile = 0;
nBlockPos = 0;
nHeight = 0;
bnChainWork = 0;
nVersion = 0;
hashMerkleRoot = 0;
@@ -1105,6 +1112,7 @@ public:
nFile = nFileIn;
nBlockPos = nBlockPosIn;
nHeight = 0;
bnChainWork = 0;
nVersion = block.nVersion;
hashMerkleRoot = block.hashMerkleRoot;
@@ -1118,6 +1126,11 @@ public:
return *phashBlock;
}
CBigNum GetBlockWork() const
{
return (CBigNum(1)<<256) / (CBigNum().SetCompact(nBits)+1);
}
bool IsInMainChain() const
{
return (pnext || this == pindexBest);

View File

@@ -3,8 +3,6 @@
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28"
INCLUDEPATHS= \
-I"/boost" \
-I"/db/build_unix" \
@@ -22,32 +20,19 @@ WXLIBS= \
-l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd
LIBS= \
-l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \
-l libboost_system-mgw34-mt-d \
-l libboost_filesystem-mgw34-mt-d \
-l libboost_program_options-mgw34-mt-d \
-l libboost_thread-mgw34-mt-d \
-l db_cxx \
-l eay32 \
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
DEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
DEBUGFLAGS=-g -D__WXDEBUG__
CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
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 init.h sha.h
all: bitcoin.exe
headers.h.gch: headers.h $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/%.o: %.cpp $(HEADERS) headers.h.gch
g++ -c $(CFLAGS) -o $@ $<
obj/sha.o: sha.cpp sha.h
g++ -c $(CFLAGS) -O3 -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 $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $<
script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h
OBJS= \
obj/util.o \
@@ -57,20 +42,36 @@ 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.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o
all: bitcoin.exe
obj/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -DGUI -o $@ $<
cryptopp/obj/%.o: cryptopp/%.cpp
g++ -c $(CFLAGS) -O3 -DCRYPTOPP_X86_ASM_AVAILABLE -DCRYPTOPP_DISABLE_SSE2 -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 $<
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) -DwxUSE_GUI=0 -o $@ $<
g++ -c $(CFLAGS) -o $@ $<
bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wxbase29ud $(LIBS)
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

View File

@@ -19,25 +19,17 @@ LIBS= -dead_strip \
$(DEPSDIR)/lib/libdb_cxx-4.8.a \
$(DEPSDIR)/lib/libboost_system.a \
$(DEPSDIR)/lib/libboost_filesystem.a \
$(DEPSDIR)/lib/libboost_program_options.a \
$(DEPSDIR)/lib/libboost_thread.a \
$(DEPSDIR)/lib/libcrypto.a
WXDEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -DNOPCH -DMSG_NOSIGNAL=0
DEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -D__WXMAC_OSX__ -DNOPCH -DMSG_NOSIGNAL=0
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) $(WXDEFS) $(INCLUDEPATHS)
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 init.h sha.h
all: bitcoin
obj/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -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 \
@@ -47,17 +39,29 @@ 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 -DCRYPTOPP_DISABLE_ASM -o $@ $<
bitcoin: $(OBJS) obj/ui.o obj/uibase.o
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
obj/nogui/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
g++ -c $(CFLAGS) -o $@ $<
bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
bitcoind: $(OBJS:obj/%=obj/nogui/%)
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
clean:

View File

@@ -3,48 +3,33 @@
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
INCLUDEPATHS= \
-I"/usr/include" \
-I"/usr/local/include/wx-2.9" \
-I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9"
LIBPATHS= \
-L"/usr/lib" \
-L"/usr/local/lib"
WXLIBS= \
-Wl,-Bstatic \
-l wx_gtk2ud-2.9 \
-Wl,-Bdynamic \
-l gtk-x11-2.0 -l SM
# for boost 1.37, add -mt to the boost libraries
LIBS= \
-Wl,-Bstatic \
-l boost_system -l boost_filesystem \
-l boost_system \
-l boost_filesystem \
-l boost_program_options \
-l boost_thread \
-l db_cxx \
-l crypto \
-Wl,-Bdynamic \
-l gthread-2.0
WXDEFS=-D__WXGTK__ -DNOPCH
DEFS=-D__WXGTK__ -DNOPCH
DEBUGFLAGS=-g -D__WXDEBUG__
CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
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 init.h sha.h
all: bitcoin
headers.h.gch: headers.h $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/%.o: %.cpp $(HEADERS) headers.h.gch
g++ -c $(CFLAGS) -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 \
@@ -54,20 +39,33 @@ 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
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
all: bitcoin
obj/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -DGUI -o $@ $<
cryptopp/obj/%.o: cryptopp/%.cpp
g++ -c $(CFLAGS) -O3 -DCRYPTOPP_DISABLE_SSE2 -o $@ $<
bitcoin: $(OBJS) obj/ui.o obj/uibase.o
g++ $(CFLAGS) -o $@ $^ $(WXLIBS) $(LIBS)
obj/nogui/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
g++ -c $(CFLAGS) -o $@ $<
bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wx_baseud-2.9 $(LIBS)
bitcoind: $(OBJS:obj/%=obj/nogui/%)
g++ $(CFLAGS) -o $@ $^ $(LIBS)
clean:
-rm -f obj/*.o
-rm -f obj/nogui/*.o
-rm -f cryptopp/obj/*.o
-rm -f headers.h.gch

View File

@@ -3,8 +3,6 @@
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28"
INCLUDEPATHS= \
/I"/boost" \
/I"/db/build_windows" \
@@ -18,25 +16,41 @@ LIBPATHS= \
/LIBPATH:"/openssl/out" \
/LIBPATH:"/wxwidgets/lib/vc_lib"
WXLIBS=wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib
LIBS= \
libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \
libboost_system-vc80-mt-gd.lib \
libboost_filesystem-vc80-mt-gd.lib \
libboost_program_options-vc80-mt-gd.lib \
libboost_thread-vc80-mt-gd.lib \
libdb47sd.lib \
libeay32.lib \
wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib \
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
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
DEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
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 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) /Fo$@ %s
cl $(CFLAGS) /DGUI /Fo$@ %s
obj\util.obj: $(HEADERS)
@@ -58,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 /DCRYPTOPP_DISABLE_ASM /Fo$@ %s
cryptopp\obj\cpu.obj: cryptopp\cpu.cpp
cl $(CFLAGS) /O2 /DCRYPTOPP_DISABLE_ASM /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) $(WXDEFS) /Fo$@ %s
rc $(INCLUDEPATHS) $(DEFS) /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
bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res
link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS)
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) /DwxUSE_GUI=0 /Fo$@ %s
cl $(CFLAGS) /Fo$@ %s
obj\nogui\util.obj: $(HEADERS)
@@ -97,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
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\nogui\*
-del /Q cryptopp\obj\*
-del /Q *.ilk
-del /Q *.pdb

View File

@@ -64,7 +64,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (hSocket == INVALID_SOCKET)
return false;
#if defined(__BSD__) || defined(__WXOSX__)
#if defined(__BSD__) || defined(__WXMAC_OSX__)
int set = 1;
setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
#endif
@@ -1163,7 +1163,7 @@ bool BindListenPort(string& strError)
return false;
}
#if defined(__BSD__) || defined(__WXOSX__)
#if defined(__BSD__) || defined(__WXMAC_OSX__)
// Different way of disabling SIGPIPE on BSD
setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
#endif

34
noui.h Normal file
View File

@@ -0,0 +1,34 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
inline int MyMessageBox(const string& message, const string& caption="Message", int style=4, void* parent=NULL, int x=-1, int y=-1)
{
printf("%s: %s\n", caption.c_str(), message.c_str());
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
return 4;
}
#define wxMessageBox MyMessageBox
inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, void* parent, int x, int y)
{
return MyMessageBox(message, caption, style, parent, x, y);
}
inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, void* parent)
{
return true;
}
inline void CalledSetStatusBar(const string& strText, int nField)
{
}
inline void UIThreadCall(boost::function0<void> fn)
{
}
inline void MainFrameRepaint()
{
}

2
obj/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

2
obj/nogui/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

244
rpc.cpp
View File

@@ -23,6 +23,28 @@ extern map<string, rpcfn_type> mapCallTable;
void PrintConsole(const char* format, ...)
{
char buffer[50000];
int limit = sizeof(buffer);
va_list arg_ptr;
va_start(arg_ptr, format);
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
va_end(arg_ptr);
if (ret < 0 || ret >= limit)
{
ret = limit - 1;
buffer[limit-1] = 0;
}
#if defined(__WXMSW__) && defined(GUI)
MyMessageBox(buffer, "Bitcoin", wxOK | wxICON_EXCLAMATION);
#else
fprintf(stdout, "%s", buffer);
#endif
}
@@ -32,7 +54,6 @@ extern map<string, rpcfn_type> mapCallTable;
///
Value help(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
@@ -41,12 +62,20 @@ Value help(const Array& params, bool fHelp)
"List commands.");
string strRet;
set<rpcfn_type> setDone;
for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
{
string strMethod = (*mi).first;
// We already filter duplicates, but these deprecated screw up the sort order
if (strMethod == "getamountreceived" ||
strMethod == "getallreceived")
continue;
try
{
Array params;
(*(*mi).second)(params, true);
rpcfn_type pfn = (*mi).second;
if (setDone.insert(pfn).second)
(*pfn)(params, true);
}
catch (std::exception& e)
{
@@ -603,7 +632,6 @@ pair<string, rpcfn_type> pCallTable[] =
make_pair("getlabel", &getlabel),
make_pair("getaddressesbylabel", &getaddressesbylabel),
make_pair("sendtoaddress", &sendtoaddress),
make_pair("listtransactions", &listtransactions),
make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress
make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress
make_pair("getreceivedbyaddress", &getreceivedbyaddress),
@@ -623,23 +651,41 @@ map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)
// and to be compatible with other JSON-RPC implementations.
//
string HTTPPost(const string& strMsg)
string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders)
{
return strprintf(
"POST / HTTP/1.1\r\n"
"User-Agent: json-rpc/1.0\r\n"
"Host: 127.0.0.1\r\n"
"Content-Type: application/json\r\n"
"Content-Length: %d\r\n"
"Accept: application/json\r\n"
"\r\n"
"%s",
strMsg.size(),
strMsg.c_str());
ostringstream s;
s << "POST / HTTP/1.1\r\n"
<< "User-Agent: json-rpc/1.0\r\n"
<< "Host: 127.0.0.1\r\n"
<< "Content-Type: application/json\r\n"
<< "Content-Length: " << strMsg.size() << "\r\n"
<< "Accept: application/json\r\n";
for (map<string,string>::const_iterator it = mapRequestHeaders.begin(); it != mapRequestHeaders.end(); ++it)
s << it->first << ": " << it->second << "\r\n";
s << "\r\n" << strMsg;
return s.str();
}
string HTTPReply(const string& strMsg, int nStatus=200)
{
if (nStatus == 401)
return "HTTP/1.0 401 Authorization Required\r\n"
"Server: HTTPd/1.0\r\n"
"Date: Sat, 08 Jul 2006 12:04:08 GMT\r\n"
"WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 311\r\n"
"\r\n"
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
"\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
"<HTML>\r\n"
"<HEAD>\r\n"
"<TITLE>Error</TITLE>\r\n"
"<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
"</HEAD>\r\n"
"<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
"</HTML>\r\n";
string strStatus;
if (nStatus == 200) strStatus = "OK";
if (nStatus == 500) strStatus = "Internal Server Error";
@@ -658,7 +704,17 @@ string HTTPReply(const string& strMsg, int nStatus=200)
strMsg.c_str());
}
int ReadHTTPHeader(tcp::iostream& stream)
int ReadHTTPStatus(tcp::iostream& stream)
{
string str;
getline(stream, str);
vector<string> vWords;
boost::split(vWords, str, boost::is_any_of(" "));
int nStatus = atoi(vWords[1].c_str());
return nStatus;
}
int ReadHTTPHeader(tcp::iostream& stream, map<string, string>& mapHeadersRet)
{
int nLen = 0;
loop
@@ -667,26 +723,93 @@ int ReadHTTPHeader(tcp::iostream& stream)
std::getline(stream, str);
if (str.empty() || str == "\r")
break;
if (str.substr(0,15) == "Content-Length:")
nLen = atoi(str.substr(15));
string::size_type nColon = str.find(":");
if (nColon != string::npos)
{
string strHeader = str.substr(0, nColon);
boost::trim(strHeader);
string strValue = str.substr(nColon+1);
boost::trim(strValue);
mapHeadersRet[strHeader] = strValue;
if (strHeader == "Content-Length")
nLen = atoi(strValue.c_str());
}
}
return nLen;
}
inline string ReadHTTP(tcp::iostream& stream)
int ReadHTTP(tcp::iostream& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
{
mapHeadersRet.clear();
strMessageRet = "";
// Read status
int nStatus = ReadHTTPStatus(stream);
// Read header
int nLen = ReadHTTPHeader(stream);
int nLen = ReadHTTPHeader(stream, mapHeadersRet);
if (nLen <= 0)
return string();
return 500;
// Read message
vector<char> vch(nLen);
stream.read(&vch[0], nLen);
return string(vch.begin(), vch.end());
strMessageRet = string(vch.begin(), vch.end());
return nStatus;
}
string EncodeBase64(string s)
{
BIO *b64, *bmem;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, s.c_str(), s.size());
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
string result(bptr->data, bptr->length);
BIO_free_all(b64);
return result;
}
string DecodeBase64(string s)
{
BIO *b64, *bmem;
char* buffer = static_cast<char*>(calloc(s.size(), sizeof(char)));
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new_mem_buf(const_cast<char*>(s.c_str()), s.size());
bmem = BIO_push(b64, bmem);
BIO_read(bmem, buffer, s.size());
BIO_free_all(bmem);
string result(buffer);
free(buffer);
return result;
}
bool HTTPAuthorized(map<string, string>& mapHeaders)
{
string strAuth = mapHeaders["Authorization"];
if (strAuth.substr(0,6) != "Basic ")
return false;
string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
string strUserPass = DecodeBase64(strUserPass64);
string::size_type nColon = strUserPass.find(":");
if (nColon == string::npos)
return false;
string strUser = strUserPass.substr(0, nColon);
string strPassword = strUserPass.substr(nColon+1);
return (strUser == mapArgs["-rpcuser"] && strPassword == mapArgs["-rpcpassword"]);
}
//
// JSON-RPC protocol
@@ -742,6 +865,22 @@ void ThreadRPCServer2(void* parg)
{
printf("ThreadRPCServer started\n");
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
{
string strWhatAmI = "To use bitcoind";
if (mapArgs.count("-server"))
strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
else if (mapArgs.count("-daemon"))
strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
PrintConsole(
_("Warning: %s, you must set rpcpassword=<password>\nin the configuration file: %s\n"
"If the file does not exist, create it with owner-readable-only file permissions.\n"),
strWhatAmI.c_str(),
GetConfigFile().c_str());
CreateThread(Shutdown, NULL);
return;
}
// Bind to loopback 127.0.0.1 so the socket can only be accessed locally
boost::asio::io_service io_service;
tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332);
@@ -763,8 +902,26 @@ void ThreadRPCServer2(void* parg)
continue;
// Receive request
string strRequest = ReadHTTP(stream);
printf("ThreadRPCServer request=%s", strRequest.c_str());
map<string, string> mapHeaders;
string strRequest;
ReadHTTP(stream, mapHeaders, strRequest);
// Check authorization
if (mapHeaders.count("Authorization") == 0)
{
stream << HTTPReply("", 401) << std::flush;
continue;
}
if (!HTTPAuthorized(mapHeaders))
{
// Deter brute-forcing short passwords
if (mapArgs["-rpcpassword"].size() < 15)
Sleep(50);
stream << HTTPReply("", 401) << std::flush;
printf("ThreadRPCServer incorrect password attempt\n");
continue;
}
// Handle multiple invocations per request
string::iterator begin = strRequest.begin();
@@ -787,6 +944,8 @@ void ThreadRPCServer2(void* parg)
const Array& params = find_value(request, "params").get_array();
id = find_value(request, "id");
printf("ThreadRPCServer method=%s\n", strMethod.c_str());
// Execute
map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
if (mi == mapCallTable.end())
@@ -814,18 +973,36 @@ void ThreadRPCServer2(void* parg)
Value CallRPC(const string& strMethod, const Array& params)
{
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
throw runtime_error(strprintf(
_("You must set rpcpassword=<password> in the configuration file:\n%s\n"
"If the file does not exist, create it with owner-readable-only file permissions."),
GetConfigFile().c_str()));
// Connect to localhost
tcp::iostream stream("127.0.0.1", "8332");
if (stream.fail())
throw runtime_error("couldn't connect to server");
// HTTP basic authentication
string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
map<string, string> mapRequestHeaders;
mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
// Send request
string strRequest = JSONRPCRequest(strMethod, params, 1);
stream << HTTPPost(strRequest) << std::flush;
string strPost = HTTPPost(strRequest, mapRequestHeaders);
stream << strPost << std::flush;
// Receive reply
string strReply = ReadHTTP(stream);
if (strReply.empty())
map<string, string> mapHeaders;
string strReply;
int nStatus = ReadHTTP(stream, mapHeaders, strReply);
if (nStatus == 401)
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
else if (nStatus >= 400 && nStatus != 500)
throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
else if (strReply.empty())
throw runtime_error("no response from server");
// Parse reply
@@ -871,7 +1048,14 @@ int CommandLineRPC(int argc, char *argv[])
{
try
{
// Check that method exists
// Skip switches
while (argc > 1 && IsSwitchChar(argv[1][0]))
{
argc--;
argv++;
}
// Check that the method exists
if (argc < 2)
throw runtime_error("too few parameters");
string strMethod = argv[1];
@@ -927,7 +1111,7 @@ int CommandLineRPC(int argc, char *argv[])
string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true));
if (result.type() != null_type)
{
#if defined(__WXMSW__) && wxUSE_GUI
#if defined(__WXMSW__) && defined(GUI)
// Windows GUI apps can't print to command line,
// so settle for a message box yuck
MyMessageBox(strResult.c_str(), "Bitcoin", wxOK);
@@ -938,7 +1122,7 @@ int CommandLineRPC(int argc, char *argv[])
return 0;
}
catch (std::exception& e) {
#if defined(__WXMSW__) && wxUSE_GUI
#if defined(__WXMSW__) && defined(GUI)
MyMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK);
#else
fprintf(stderr, "error: %s\n", e.what());

1464
script.cpp

File diff suppressed because it is too large Load Diff

View File

@@ -136,6 +136,20 @@ enum opcodetype
OP_CHECKMULTISIG,
OP_CHECKMULTISIGVERIFY,
// expansion
OP_NOP1,
OP_NOP2,
OP_NOP3,
OP_NOP4,
OP_NOP5,
OP_NOP6,
OP_NOP7,
OP_NOP8,
OP_NOP9,
OP_NOP10,
// multi-byte opcodes
OP_SINGLEBYTE_END = 0xF0,
@@ -276,6 +290,18 @@ inline const char* GetOpName(opcodetype opcode)
case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG";
case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY";
// expanson
case OP_NOP1 : return "OP_NOP1";
case OP_NOP2 : return "OP_NOP2";
case OP_NOP3 : return "OP_NOP3";
case OP_NOP4 : return "OP_NOP4";
case OP_NOP5 : return "OP_NOP5";
case OP_NOP6 : return "OP_NOP6";
case OP_NOP7 : return "OP_NOP7";
case OP_NOP8 : return "OP_NOP8";
case OP_NOP9 : return "OP_NOP9";
case OP_NOP10 : return "OP_NOP10";
// multi-byte opcodes
@@ -285,7 +311,6 @@ inline const char* GetOpName(opcodetype opcode)
case OP_PUBKEYHASH : return "OP_PUBKEYHASH";
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
default:
return "UNKNOWN_OPCODE";
@@ -632,8 +657,6 @@ public:
bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0,
vector<vector<unsigned char> >* pvStackRet=NULL);
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
bool IsMine(const CScript& scriptPubKey);
bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet);

View File

@@ -19,7 +19,7 @@ class CScript;
class CDataStream;
class CAutoFile;
static const int VERSION = 302;
static const int VERSION = 307;
static const char* pszSubVer = "";

View File

@@ -7,7 +7,7 @@ RequestExecutionLevel highest
# General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)"
!define VERSION 0.3.2
!define VERSION 0.3.7
!define COMPANY "Bitcoin project"
!define URL http://www.bitcoin.org/
@@ -42,12 +42,12 @@ Var StartMenuGroup
!insertmacro MUI_LANGUAGE English
# Installer attributes
OutFile bitcoin-0.3.2-win32-setup.exe
OutFile bitcoin-0.3.7-win32-setup.exe
InstallDir $PROGRAMFILES\Bitcoin
CRCCheck on
XPStyle on
ShowInstDetails show
VIProductVersion 0.3.2.0
VIProductVersion 0.3.7.0
VIAddVersionKey ProductName Bitcoin
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"

554
sha.cpp
View File

@@ -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
}

177
sha.h
View File

@@ -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

356
ui.cpp
View File

@@ -14,6 +14,7 @@ DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL)
CMainFrame* pframeMain = NULL;
CMyTaskBarIcon* ptaskbaricon = NULL;
bool fClosedToTray = false;
wxLocale g_locale;
@@ -263,7 +264,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
m_listCtrl->SetFocus();
ptaskbaricon = new CMyTaskBarIcon();
#ifdef __WXMAC__
#ifdef __WXMAC_OSX__
// Mac automatically moves wxID_EXIT, wxID_PREFERENCES and wxID_ABOUT
// to their standard places, leaving these menus empty.
GetMenuBar()->Remove(2); // remove Help menu
@@ -274,7 +275,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8;
if (!strstr(DateTimeStr(1229413914).c_str(), "2008"))
nDateWidth += 12;
#ifdef __WXMAC__
#ifdef __WXMAC_OSX__
nDateWidth += 5;
dResize -= 0.01;
#endif
@@ -1132,7 +1133,7 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event)
// Ask name
CGetTextFromUserDialog dialog(this,
_("New Receiving Address"),
_("It's good policy to use a new address for each payment you receive.\n\nLabel"),
_("You should use a new address for each payment you receive.\n\nLabel"),
"");
if (!dialog.ShowModal())
return;
@@ -1437,6 +1438,154 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event)
//////////////////////////////////////////////////////////////////////////////
//
// Startup folder
//
#ifdef __WXMSW__
string StartupShortcutPath()
{
return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
}
bool GetStartOnSystemStartup()
{
return filesystem::exists(StartupShortcutPath().c_str());
}
void SetStartOnSystemStartup(bool fAutoStart)
{
// If the shortcut exists already, remove it for updating
remove(StartupShortcutPath().c_str());
if (fAutoStart)
{
CoInitialize(NULL);
// Get a pointer to the IShellLink interface.
IShellLink* psl = NULL;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink,
reinterpret_cast<void**>(&psl));
if (SUCCEEDED(hres))
{
// Get the current executable path
TCHAR pszExePath[MAX_PATH];
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
// Set the path to the shortcut target
psl->SetPath(pszExePath);
PathRemoveFileSpec(pszExePath);
psl->SetWorkingDirectory(pszExePath);
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
IPersistFile* ppf = NULL;
hres = psl->QueryInterface(IID_IPersistFile,
reinterpret_cast<void**>(&ppf));
if (SUCCEEDED(hres))
{
WCHAR pwsz[MAX_PATH];
// Ensure that the string is ANSI.
MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH);
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(pwsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
}
}
#elif defined(__WXGTK__)
// Follow the Desktop Application Autostart Spec:
// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
boost::filesystem::path GetAutostartDir()
{
namespace fs = boost::filesystem;
char* pszConfigHome = getenv("XDG_CONFIG_HOME");
if (pszConfigHome) return fs::path(pszConfigHome) / fs::path("autostart");
char* pszHome = getenv("HOME");
if (pszHome) return fs::path(pszHome) / fs::path(".config/autostart");
return fs::path();
}
boost::filesystem::path GetAutostartFilePath()
{
return GetAutostartDir() / boost::filesystem::path("bitcoin.desktop");
}
bool GetStartOnSystemStartup()
{
boost::filesystem::ifstream optionFile(GetAutostartFilePath());
if (!optionFile.good())
return false;
// Scan through file for "Hidden=true":
string line;
while (!optionFile.eof())
{
getline(optionFile, line);
if (line.find("Hidden") != string::npos &&
line.find("true") != string::npos)
return false;
}
optionFile.close();
return true;
}
void SetStartOnSystemStartup(bool fAutoStart)
{
if (!fAutoStart)
{
unlink(GetAutostartFilePath().native_file_string().c_str());
}
else
{
boost::filesystem::create_directories(GetAutostartDir());
boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc);
if (!optionFile.good())
{
wxMessageBox(_("Cannot write autostart/bitcoin.desktop file"), "Bitcoin");
return;
}
// Write a bitcoin.desktop file to the autostart directory:
char pszExePath[MAX_PATH+1];
memset(pszExePath, 0, sizeof(pszExePath));
readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1);
optionFile << "[Desktop Entry]\n";
optionFile << "Type=Application\n";
optionFile << "Name=Bitcoin\n";
optionFile << "Exec=" << pszExePath << "\n";
optionFile << "Terminal=false\n";
optionFile << "Hidden=false\n";
optionFile.close();
}
}
#else
// TODO: OSX startup stuff; see:
// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html
bool GetStartOnSystemStartup() { return false; }
void SetStartOnSystemStartup(bool fAutoStart) { }
#endif
//////////////////////////////////////////////////////////////////////////////
//
// COptionsDialog
@@ -1606,6 +1755,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
//////////////////////////////////////////////////////////////////////////////
//
// CAboutDialog
@@ -1613,7 +1763,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
{
m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d beta"), VERSION/10000, (VERSION/100)%100, VERSION%100));
m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d%s beta"), VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer));
// Change (c) into UTF-8 or ANSI copyright symbol
wxString str = m_staticTextMain->GetLabel();
@@ -2372,7 +2522,7 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
// Ask name
CGetTextFromUserDialog dialog(this,
_("New Receiving Address"),
_("It's good policy to use a new address for each payment you receive.\n\nLabel"),
_("You should use a new address for each payment you receive.\n\nLabel"),
"");
if (!dialog.ShowModal())
return;
@@ -2537,12 +2687,10 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu()
//////////////////////////////////////////////////////////////////////////////
//
// CMyApp
//
void CreateMainWindow()
{
@@ -2560,3 +2708,189 @@ void CreateMainWindow()
ptaskbaricon->Show(fMinimizeToTray || fClosedToTray);
CreateThread(ThreadDelayedRepaint, NULL);
}
// Define a new application
class CMyApp : public wxApp
{
public:
CMyApp(){};
~CMyApp(){};
bool OnInit();
bool OnInit2();
int OnExit();
// Hook Initialize so we can start without GUI
virtual bool Initialize(int& argc, wxChar** argv);
// 2nd-level exception handling: we get all the exceptions occurring in any
// event handler here
virtual bool OnExceptionInMainLoop();
// 3rd, and final, level exception handling: whenever an unhandled
// exception is caught, this function is called
virtual void OnUnhandledException();
// and now for something different: this function is called in case of a
// crash (e.g. dereferencing null pointer, division by 0, ...)
virtual void OnFatalException();
};
IMPLEMENT_APP(CMyApp)
bool CMyApp::Initialize(int& argc, wxChar** argv)
{
for (int i = 1; i < argc; i++)
if (!IsSwitchChar(argv[i][0]))
fCommandLine = true;
if (!fCommandLine)
{
// wxApp::Initialize will remove environment-specific parameters,
// so it's too early to call ParseParameters yet
for (int i = 1; i < argc; i++)
{
wxString str = argv[i];
#ifdef __WXMSW__
if (str.size() >= 1 && str[0] == '/')
str[0] = '-';
char pszLower[MAX_PATH];
strlcpy(pszLower, str.c_str(), sizeof(pszLower));
strlwr(pszLower);
str = pszLower;
#endif
if (str == "-daemon")
fDaemon = true;
}
}
#ifdef __WXGTK__
if (fDaemon || fCommandLine)
{
// Call the original Initialize while suppressing error messages
// and ignoring failure. If unable to initialize GTK, it fails
// near the end so hopefully the last few things don't matter.
{
wxLogNull logNo;
wxApp::Initialize(argc, argv);
}
if (fDaemon)
{
// Daemonize
pid_t pid = fork();
if (pid < 0)
{
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
return false;
}
if (pid > 0)
pthread_exit((void*)0);
}
return true;
}
#endif
return wxApp::Initialize(argc, argv);
}
bool CMyApp::OnInit()
{
#if defined(__WXMSW__) && defined(__WXDEBUG__) && defined(GUI)
// Disable malfunctioning wxWidgets debug assertion
extern int g_isPainting;
g_isPainting = 10000;
#endif
#ifdef GUI
wxImage::AddHandler(new wxPNGHandler);
#endif
#if defined(__WXMSW__ ) || defined(__WXMAC_OSX__)
SetAppName("Bitcoin");
#else
SetAppName("bitcoin");
#endif
#ifdef __WXMSW__
#if wxUSE_UNICODE
// Hack to set wxConvLibc codepage to UTF-8 on Windows,
// may break if wxMBConv_win32 implementation in strconv.cpp changes.
class wxMBConv_win32 : public wxMBConv
{
public:
long m_CodePage;
size_t m_minMBCharWidth;
};
if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP)
((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8;
#endif
#endif
// Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file
g_locale.Init(wxLANGUAGE_DEFAULT, 0);
g_locale.AddCatalogLookupPathPrefix("locale");
#ifndef __WXMSW__
g_locale.AddCatalogLookupPathPrefix("/usr/share/locale");
g_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale");
#endif
g_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any
g_locale.AddCatalog("bitcoin");
return AppInit(argc, argv);
}
int CMyApp::OnExit()
{
Shutdown(NULL);
return wxApp::OnExit();
}
bool CMyApp::OnExceptionInMainLoop()
{
try
{
throw;
}
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
return true;
}
void CMyApp::OnUnhandledException()
{
// this shows how we may let some exception propagate uncaught
try
{
throw;
}
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnUnhandledException()");
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnUnhandledException()");
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
}
void CMyApp::OnFatalException()
{
wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR);
}

63
ui.h
View File

@@ -4,24 +4,9 @@
DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1)
#if wxUSE_GUI
static const bool fGUI=true;
#else
static const bool fGUI=false;
#endif
inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
{
#if wxUSE_GUI
if (!fDaemon)
return wxMessageBox(message, caption, style, parent, x, y);
#endif
printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str());
fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str());
return wxOK;
}
#define wxMessageBox MyMessageBox
extern wxLocale g_locale;
@@ -33,38 +18,23 @@ bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* pa
void CalledSetStatusBar(const string& strText, int nField);
void MainFrameRepaint();
void CreateMainWindow();
void SetStartOnSystemStartup(bool fAutoStart);
#if !wxUSE_GUI
inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y)
inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
{
return MyMessageBox(message, caption, style, parent, x, y);
#ifdef GUI
if (!fDaemon)
return wxMessageBox(message, caption, style, parent, x, y);
#endif
printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str());
fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str());
return wxOK;
}
#define wxMessageBox MyMessageBox
inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent)
{
return true;
}
inline void CalledSetStatusBar(const string& strText, int nField)
{
}
inline void UIThreadCall(boost::function0<void> fn)
{
}
inline void MainFrameRepaint()
{
}
inline void CreateMainWindow()
{
}
#else // wxUSE_GUI
@@ -334,11 +304,10 @@ public:
m_textCtrl2->SetValue(strValue2);
y += 46 + wxString(strMessage2).Freq('\n') * 14;
}
if (!fWindows)
{
x *= 1.14;
y *= 1.14;
}
#ifndef __WXMSW__
x *= 1.14;
y *= 1.14;
#endif
SetSize(x, y);
}
@@ -375,5 +344,3 @@ public:
DECLARE_EVENT_TABLE()
};
#endif // wxUSE_GUI

View File

@@ -227,7 +227,7 @@ class CAboutDialogBase : public wxDialog
public:
wxStaticText* m_staticTextVersion;
CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE );
CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,333 ), long style = wxDEFAULT_DIALOG_STYLE );
~CAboutDialogBase();
};

View File

@@ -2866,7 +2866,7 @@
<property name="minimum_size"></property>
<property name="name">CAboutDialogBase</property>
<property name="pos"></property>
<property name="size">532,329</property>
<property name="size">532,333</property>
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
<property name="subclass"></property>
<property name="title">About Bitcoin</property>

View File

@@ -134,7 +134,7 @@ uint64 GetRand(uint64 nMax)
inline int OutputDebugStringF(const char* pszFormat, ...)
{
int ret = 0;
if (fPrintToConsole || wxTheApp == NULL)
if (fPrintToConsole)
{
// print to console
va_list arg_ptr;
@@ -416,7 +416,7 @@ void ParseParameters(int argc, char* argv[])
{
mapArgs.clear();
mapMultiArgs.clear();
for (int i = 0; i < argc; i++)
for (int i = 1; i < argc; i++)
{
char psz[10000];
strlcpy(psz, argv[i], sizeof(psz));
@@ -431,6 +431,8 @@ void ParseParameters(int argc, char* argv[])
if (psz[0] == '/')
psz[0] = '-';
#endif
if (psz[0] != '-')
break;
mapArgs[psz] = pszValue;
mapMultiArgs[psz].push_back(pszValue);
}
@@ -439,6 +441,7 @@ void ParseParameters(int argc, char* argv[])
const char* wxGetTranslation(const char* pszEnglish)
{
#ifdef GUI
// Wrapper of wxGetTranslation returning the same const char* type as was passed in
static CCriticalSection cs;
CRITICAL_BLOCK(cs)
@@ -465,6 +468,9 @@ const char* wxGetTranslation(const char* pszEnglish)
return pszCached;
}
return NULL;
#else
return pszEnglish;
#endif
}
@@ -483,8 +489,6 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea
pszModule[0] = '\0';
GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
#else
// might not be thread safe, uses wxString
//const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str();
const char* pszModule = "bitcoin";
#endif
if (pex)
@@ -508,8 +512,10 @@ void PrintException(std::exception* pex, const char* pszThread)
FormatException(pszMessage, pex, pszThread);
printf("\n\n************************\n%s\n", pszMessage);
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
if (wxTheApp && !fDaemon && fGUI)
#ifdef GUI
if (wxTheApp && !fDaemon)
MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
#endif
throw;
//DebugBreak();
}
@@ -572,10 +578,10 @@ string GetDefaultDataDir()
string strHome = pszHome;
if (strHome[strHome.size()-1] != '/')
strHome += '/';
#ifdef __WXOSX__
#ifdef __WXMAC_OSX__
// Mac
strHome += "Library/Application Support/";
_mkdir(strHome.c_str());
filesystem::create_directory(strHome.c_str());
return strHome + "Bitcoin";
#else
// Unix
@@ -594,7 +600,7 @@ void GetDataDir(char* pszDir)
if (!fMkdirDone)
{
fMkdirDone = true;
_mkdir(pszDir);
filesystem::create_directory(pszDir);
}
}
else
@@ -604,9 +610,8 @@ void GetDataDir(char* pszDir)
static char pszCachedDir[MAX_PATH];
if (pszCachedDir[0] == 0)
{
//strlcpy(pszCachedDir, wxStandardPaths::Get().GetUserDataDir().c_str(), sizeof(pszCachedDir));
strlcpy(pszCachedDir, GetDefaultDataDir().c_str(), sizeof(pszCachedDir));
_mkdir(pszCachedDir);
filesystem::create_directory(pszCachedDir);
}
strlcpy(pszDir, pszCachedDir, MAX_PATH);
}
@@ -619,6 +624,38 @@ string GetDataDir()
return pszDir;
}
string GetConfigFile()
{
namespace fs = boost::filesystem;
fs::path pathConfig(mapArgs.count("-conf") ? mapArgs["-conf"] : string("bitcoin.conf"));
if (!pathConfig.is_complete())
pathConfig = fs::path(GetDataDir()) / pathConfig;
return pathConfig.string();
}
void ReadConfigFile(map<string, string>& mapSettingsRet,
map<string, vector<string> >& mapMultiSettingsRet)
{
namespace fs = boost::filesystem;
namespace pod = boost::program_options::detail;
fs::ifstream streamConfig(GetConfigFile());
if (!streamConfig.good())
return;
set<string> setOptions;
setOptions.insert("*");
for (pod::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
{
// Don't overwrite existing settings so command line settings override bitcoin.conf
string strKey = string("-") + it->string_key;
if (mapSettingsRet.count(strKey) == 0)
mapSettingsRet[strKey] = it->value[0];
mapMultiSettingsRet[strKey].push_back(it->value[0]);
}
}
int GetFilesize(FILE* file)
{
int nSavePos = ftell(file);
@@ -656,9 +693,6 @@ void ShrinkDebugFile()
//
// "Never go to sea with two chronometers; take one or three."
// Our three chronometers are:
@@ -701,12 +735,13 @@ void AddTimeData(unsigned int ip, int64 nTime)
sort(vTimeOffsets.begin(), vTimeOffsets.end());
int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
nTimeOffset = nMedian;
if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60)
if ((nMedian > 0 ? nMedian : -nMedian) > 70 * 60)
{
// Only let other nodes change our clock so far before we
// go to the NTP servers
/// todo: Get time from NTP servers, then set a flag
/// to make sure it doesn't get changed again
nTimeOffset = 0;
}
foreach(int64 n, vTimeOffsets)
printf("%+"PRI64d" ", n);

40
util.h
View File

@@ -54,8 +54,21 @@ 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__
static const bool fWindows = true;
#define MSG_NOSIGNAL 0
#define MSG_DONTWAIT 0
#ifndef UINT64_MAX
@@ -70,7 +83,6 @@ static const bool fWindows = true;
#define unlink _unlink
typedef int socklen_t;
#else
static const bool fWindows = false;
#define WSAGetLastError() errno
#define WSAEWOULDBLOCK EWOULDBLOCK
#define WSAEMSGSIZE EMSGSIZE
@@ -84,10 +96,12 @@ typedef u_int SOCKET;
#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
#define strlwr(psz) to_lower(psz)
#define _strlwr(psz) to_lower(psz)
#define _mkdir(psz) filesystem::create_directory(psz)
#define MAX_PATH 1024
#define Sleep(n) wxMilliSleep(n)
#define Beep(n1,n2) (0)
inline void Sleep(int64 n)
{
boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n));
}
#endif
inline int myclosesocket(SOCKET& hSocket)
@@ -104,6 +118,13 @@ inline int myclosesocket(SOCKET& hSocket)
}
#define closesocket(s) myclosesocket(s)
#ifndef GUI
inline const char* _(const char* psz)
{
return psz;
}
#endif
@@ -141,6 +162,8 @@ void ParseParameters(int argc, char* argv[]);
const char* wxGetTranslation(const char* psz);
int GetFilesize(FILE* file);
void GetDataDir(char* pszDirRet);
string GetConfigFile();
void ReadConfigFile(map<string, string>& mapSettingsRet, map<string, vector<string> >& mapMultiSettingsRet);
#ifdef __WXMSW__
string MyGetSpecialFolderPath(int nFolder, bool fCreate);
#endif
@@ -348,7 +371,14 @@ void skipspaces(T& it)
++it;
}
inline bool IsSwitchChar(char c)
{
#ifdef __WXMSW__
return c == '-' || c == '/';
#else
return c == '-';
#endif
}