Merge pull request #4100
a0495bb
Add <Hasher>::OUTPUT_SIZE (Pieter Wuille)4791b99
crypto: create a separate lib for crypto functions (Cory Fields)f2647cc
crypto: explicitly check for byte read/write functions (Cory Fields)5437248
build: move bitcoin-config.h to its own directory (Cory Fields)3820e01
Extend and move all crypto tests to crypto_tests.cpp (Pieter Wuille)7ecd973
Move {Read,Write}{LE,BE}{32,64} to common.h and use builtins if possible (Pieter Wuille)a5bc9c0
Add built-in RIPEMD-160 implementation (Pieter Wuille)13b5dfe
Move crypto implementations to src/crypto/ (Pieter Wuille)1cc344c
Add built-in SHA-1 implementation. (Pieter Wuille)85aab2a
Switch miner.cpp to use sha2 instead of OpenSSL. (Pieter Wuille)cf0c47b
Remove getwork() RPC call (Pieter Wuille)7b4737c
Switch script.cpp and hash.cpp to use sha2.cpp instead of OpenSSL. (Pieter Wuille)977cdad
Add a built-in SHA256/SHA512 implementation. (Pieter Wuille)
This commit is contained in:
commit
8f59251b83
26 changed files with 1387 additions and 610 deletions
|
@ -111,7 +111,7 @@ AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[spec
|
||||||
|
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([src])
|
AC_CONFIG_SRCDIR([src])
|
||||||
AC_CONFIG_HEADERS([src/bitcoin-config.h])
|
AC_CONFIG_HEADERS([src/config/bitcoin-config.h])
|
||||||
|
|
||||||
dnl Checks for programs.
|
dnl Checks for programs.
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
|
@ -368,7 +368,12 @@ if test x$TARGET_OS = xdarwin; then
|
||||||
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
|
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_CHECK_HEADERS([stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h])
|
AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h])
|
||||||
|
|
||||||
|
AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,,
|
||||||
|
[#if HAVE_ENDIAN_H
|
||||||
|
#include <endian.h>
|
||||||
|
#endif])
|
||||||
|
|
||||||
dnl Check for MSG_NOSIGNAL
|
dnl Check for MSG_NOSIGNAL
|
||||||
AC_MSG_CHECKING(for MSG_NOSIGNAL)
|
AC_MSG_CHECKING(for MSG_NOSIGNAL)
|
||||||
|
|
|
@ -17,12 +17,14 @@ $(LIBLEVELDB) $(LIBMEMENV):
|
||||||
OPT="$(CXXFLAGS) $(CPPFLAGS)"
|
OPT="$(CXXFLAGS) $(CPPFLAGS)"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS)
|
BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
|
||||||
|
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BITCOIN_CONFIG_INCLUDES) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS)
|
||||||
|
|
||||||
noinst_LIBRARIES = \
|
noinst_LIBRARIES = \
|
||||||
libbitcoin_server.a \
|
libbitcoin_server.a \
|
||||||
libbitcoin_common.a \
|
libbitcoin_common.a \
|
||||||
libbitcoin_cli.a
|
libbitcoin_cli.a \
|
||||||
|
crypto/libbitcoin_crypto.a
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
|
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
|
||||||
noinst_LIBRARIES += libbitcoin_wallet.a
|
noinst_LIBRARIES += libbitcoin_wallet.a
|
||||||
|
@ -140,6 +142,16 @@ libbitcoin_wallet_a_SOURCES = \
|
||||||
walletdb.cpp \
|
walletdb.cpp \
|
||||||
$(BITCOIN_CORE_H)
|
$(BITCOIN_CORE_H)
|
||||||
|
|
||||||
|
crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES)
|
||||||
|
crypto_libbitcoin_crypto_a_SOURCES = \
|
||||||
|
crypto/sha1.cpp \
|
||||||
|
crypto/sha2.cpp \
|
||||||
|
crypto/ripemd160.cpp \
|
||||||
|
crypto/common.h \
|
||||||
|
crypto/sha2.h \
|
||||||
|
crypto/sha1.h \
|
||||||
|
crypto/ripemd160.h
|
||||||
|
|
||||||
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||||
libbitcoin_common_a_SOURCES = \
|
libbitcoin_common_a_SOURCES = \
|
||||||
base58.cpp \
|
base58.cpp \
|
||||||
|
@ -175,6 +187,7 @@ nodist_libbitcoin_common_a_SOURCES = $(srcdir)/obj/build.h
|
||||||
bitcoind_LDADD = \
|
bitcoind_LDADD = \
|
||||||
libbitcoin_server.a \
|
libbitcoin_server.a \
|
||||||
libbitcoin_common.a \
|
libbitcoin_common.a \
|
||||||
|
crypto/libbitcoin_crypto.a \
|
||||||
$(LIBLEVELDB) \
|
$(LIBLEVELDB) \
|
||||||
$(LIBMEMENV)
|
$(LIBMEMENV)
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
|
@ -194,6 +207,7 @@ bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||||
bitcoin_cli_LDADD = \
|
bitcoin_cli_LDADD = \
|
||||||
libbitcoin_cli.a \
|
libbitcoin_cli.a \
|
||||||
libbitcoin_common.a \
|
libbitcoin_common.a \
|
||||||
|
crypto/libbitcoin_crypto.a \
|
||||||
$(BOOST_LIBS)
|
$(BOOST_LIBS)
|
||||||
bitcoin_cli_SOURCES = bitcoin-cli.cpp
|
bitcoin_cli_SOURCES = bitcoin-cli.cpp
|
||||||
bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
|
bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||||
|
@ -212,6 +226,7 @@ EXTRA_DIST = leveldb
|
||||||
clean-local:
|
clean-local:
|
||||||
-$(MAKE) -C leveldb clean
|
-$(MAKE) -C leveldb clean
|
||||||
rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno
|
rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno
|
||||||
|
-rm -f config.h
|
||||||
|
|
||||||
.rc.o:
|
.rc.o:
|
||||||
@test -f $(WINDRES)
|
@test -f $(WINDRES)
|
||||||
|
@ -229,6 +244,7 @@ LIBBITCOIN_SERVER=libbitcoin_server.a
|
||||||
LIBBITCOIN_WALLET=libbitcoin_wallet.a
|
LIBBITCOIN_WALLET=libbitcoin_wallet.a
|
||||||
LIBBITCOIN_COMMON=libbitcoin_common.a
|
LIBBITCOIN_COMMON=libbitcoin_common.a
|
||||||
LIBBITCOIN_CLI=libbitcoin_cli.a
|
LIBBITCOIN_CLI=libbitcoin_cli.a
|
||||||
|
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
|
||||||
LIBBITCOINQT=qt/libbitcoinqt.a
|
LIBBITCOINQT=qt/libbitcoinqt.a
|
||||||
|
|
||||||
if ENABLE_TESTS
|
if ENABLE_TESTS
|
||||||
|
|
|
@ -355,7 +355,7 @@ qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
|
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
|
||||||
endif
|
endif
|
||||||
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \
|
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||||
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
|
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
|
||||||
qt_bitcoin_qt_LDFLAGS = $(QT_LDFLAGS)
|
qt_bitcoin_qt_LDFLAGS = $(QT_LDFLAGS)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER)
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
|
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
|
||||||
endif
|
endif
|
||||||
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) \
|
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) \
|
||||||
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
|
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
|
||||||
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
|
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
|
||||||
qt_test_test_bitcoin_qt_LDFLAGS = $(QT_LDFLAGS)
|
qt_test_test_bitcoin_qt_LDFLAGS = $(QT_LDFLAGS)
|
||||||
|
|
|
@ -31,8 +31,10 @@ BITCOIN_TESTS =\
|
||||||
test/checkblock_tests.cpp \
|
test/checkblock_tests.cpp \
|
||||||
test/Checkpoints_tests.cpp \
|
test/Checkpoints_tests.cpp \
|
||||||
test/compress_tests.cpp \
|
test/compress_tests.cpp \
|
||||||
|
test/crypto_tests.cpp \
|
||||||
test/DoS_tests.cpp \
|
test/DoS_tests.cpp \
|
||||||
test/getarg_tests.cpp \
|
test/getarg_tests.cpp \
|
||||||
|
test/hash_tests.cpp \
|
||||||
test/key_tests.cpp \
|
test/key_tests.cpp \
|
||||||
test/main_tests.cpp \
|
test/main_tests.cpp \
|
||||||
test/miner_tests.cpp \
|
test/miner_tests.cpp \
|
||||||
|
@ -61,7 +63,7 @@ endif
|
||||||
|
|
||||||
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
||||||
test_test_bitcoin_CPPFLAGS = $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS)
|
test_test_bitcoin_CPPFLAGS = $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS)
|
||||||
test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \
|
test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||||
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB)
|
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB)
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
|
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
|
||||||
|
|
0
src/config/.empty
Normal file
0
src/config/.empty
Normal file
93
src/crypto/common.h
Normal file
93
src/crypto/common.h
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_CRYPTO_COMMON_H
|
||||||
|
#define BITCOIN_CRYPTO_COMMON_H
|
||||||
|
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include "bitcoin-config.h"
|
||||||
|
#endif
|
||||||
|
#include <stdint.h>
|
||||||
|
#if defined(HAVE_ENDIAN_H)
|
||||||
|
#include <endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t static inline ReadLE32(const unsigned char *ptr) {
|
||||||
|
#if HAVE_DECL_LE32TOH == 1
|
||||||
|
return le32toh(*((uint32_t*)ptr));
|
||||||
|
#elif !defined(WORDS_BIGENDIAN)
|
||||||
|
return *((uint32_t*)ptr);
|
||||||
|
#else
|
||||||
|
return ((uint32_t)ptr[3] << 24 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t static inline ReadLE64(const unsigned char *ptr) {
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE64TOH == 1
|
||||||
|
return le64toh(*((uint64_t*)ptr));
|
||||||
|
#elif !defined(WORDS_BIGENDIAN)
|
||||||
|
return *((uint64_t*)ptr);
|
||||||
|
#else
|
||||||
|
return ((uint64_t)ptr[7] << 56 | (uint64_t)ptr[6] << 48 | (uint64_t)ptr[5] << 40 | (uint64_t)ptr[4] << 32 |
|
||||||
|
(uint64_t)ptr[3] << 24 | (uint64_t)ptr[2] << 16 | (uint64_t)ptr[1] << 8 | (uint64_t)ptr[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void static inline WriteLE32(unsigned char *ptr, uint32_t x) {
|
||||||
|
#if HAVE_DECL_HTOLE32 == 1
|
||||||
|
*((uint32_t*)ptr) = htole32(x);
|
||||||
|
#elif !defined(WORDS_BIGENDIAN)
|
||||||
|
*((uint32_t*)ptr) = x;
|
||||||
|
#else
|
||||||
|
ptr[3] = x >> 24; ptr[2] = x >> 16; ptr[1] = x >> 8; ptr[0] = x;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void static inline WriteLE64(unsigned char *ptr, uint64_t x) {
|
||||||
|
#if HAVE_DECL_HTOLE64 == 1
|
||||||
|
*((uint64_t*)ptr) = htole64(x);
|
||||||
|
#elif !defined(WORDS_BIGENDIAN)
|
||||||
|
*((uint64_t*)ptr) = x;
|
||||||
|
#else
|
||||||
|
ptr[7] = x >> 56; ptr[6] = x >> 48; ptr[5] = x >> 40; ptr[4] = x >> 32;
|
||||||
|
ptr[3] = x >> 24; ptr[2] = x >> 16; ptr[1] = x >> 8; ptr[0] = x;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t static inline ReadBE32(const unsigned char *ptr) {
|
||||||
|
#if HAVE_DECL_BE32TOH == 1
|
||||||
|
return be32toh(*((uint32_t*)ptr));
|
||||||
|
#else
|
||||||
|
return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t static inline ReadBE64(const unsigned char *ptr) {
|
||||||
|
#if HAVE_DECL_BE64TOH == 1
|
||||||
|
return be64toh(*((uint64_t*)ptr));
|
||||||
|
#else
|
||||||
|
return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 |
|
||||||
|
(uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void static inline WriteBE32(unsigned char *ptr, uint32_t x) {
|
||||||
|
#if HAVE_DECL_HTOBE32 == 1
|
||||||
|
*((uint32_t*)ptr) = htobe32(x);
|
||||||
|
#else
|
||||||
|
ptr[0] = x >> 24; ptr[1] = x >> 16; ptr[2] = x >> 8; ptr[3] = x;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void static inline WriteBE64(unsigned char *ptr, uint64_t x) {
|
||||||
|
#if HAVE_DECL_HTOBE64 == 1
|
||||||
|
*((uint64_t*)ptr) = htobe64(x);
|
||||||
|
#else
|
||||||
|
ptr[0] = x >> 56; ptr[1] = x >> 48; ptr[2] = x >> 40; ptr[3] = x >> 32;
|
||||||
|
ptr[4] = x >> 24; ptr[5] = x >> 16; ptr[6] = x >> 8; ptr[7] = x;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
204
src/crypto/ripemd160.cpp
Normal file
204
src/crypto/ripemd160.cpp
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "crypto/ripemd160.h"
|
||||||
|
|
||||||
|
#include "crypto/common.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Internal implementation code.
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/// Internal RIPEMD-160 implementation.
|
||||||
|
namespace ripemd160 {
|
||||||
|
|
||||||
|
uint32_t inline f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; }
|
||||||
|
uint32_t inline f2(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); }
|
||||||
|
uint32_t inline f3(uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; }
|
||||||
|
uint32_t inline f4(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~z); }
|
||||||
|
uint32_t inline f5(uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); }
|
||||||
|
|
||||||
|
/** Initialize RIPEMD-160 state. */
|
||||||
|
void inline Initialize(uint32_t *s) {
|
||||||
|
s[0] = 0x67452301ul;
|
||||||
|
s[1] = 0xEFCDAB89ul;
|
||||||
|
s[2] = 0x98BADCFEul;
|
||||||
|
s[3] = 0x10325476ul;
|
||||||
|
s[4] = 0xC3D2E1F0ul;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32-i)); }
|
||||||
|
|
||||||
|
void inline Round(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r) {
|
||||||
|
a = rol(a + f + x + k, r) + e;
|
||||||
|
c = rol(c, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void inline R11(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }
|
||||||
|
void inline R21(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); }
|
||||||
|
void inline R31(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); }
|
||||||
|
void inline R41(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); }
|
||||||
|
void inline R51(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); }
|
||||||
|
|
||||||
|
void inline R12(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); }
|
||||||
|
void inline R22(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); }
|
||||||
|
void inline R32(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); }
|
||||||
|
void inline R42(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); }
|
||||||
|
void inline R52(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }
|
||||||
|
|
||||||
|
/** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */
|
||||||
|
void Transform(uint32_t *s, const unsigned char *chunk) {
|
||||||
|
uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4];
|
||||||
|
uint32_t a2 = a1 , b2 = b1 , c2 = c1 , d2 = d1 , e2 = e1 ;
|
||||||
|
uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12);
|
||||||
|
uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28);
|
||||||
|
uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44);
|
||||||
|
uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52), w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60);
|
||||||
|
|
||||||
|
R11(a1, b1, c1, d1, e1, w0 , 11); R12(a2, b2, c2, d2, e2, w5 , 8);
|
||||||
|
R11(e1, a1, b1, c1, d1, w1 , 14); R12(e2, a2, b2, c2, d2, w14, 9);
|
||||||
|
R11(d1, e1, a1, b1, c1, w2 , 15); R12(d2, e2, a2, b2, c2, w7 , 9);
|
||||||
|
R11(c1, d1, e1, a1, b1, w3 , 12); R12(c2, d2, e2, a2, b2, w0 , 11);
|
||||||
|
R11(b1, c1, d1, e1, a1, w4 , 5); R12(b2, c2, d2, e2, a2, w9 , 13);
|
||||||
|
R11(a1, b1, c1, d1, e1, w5 , 8); R12(a2, b2, c2, d2, e2, w2 , 15);
|
||||||
|
R11(e1, a1, b1, c1, d1, w6 , 7); R12(e2, a2, b2, c2, d2, w11, 15);
|
||||||
|
R11(d1, e1, a1, b1, c1, w7 , 9); R12(d2, e2, a2, b2, c2, w4 , 5);
|
||||||
|
R11(c1, d1, e1, a1, b1, w8 , 11); R12(c2, d2, e2, a2, b2, w13, 7);
|
||||||
|
R11(b1, c1, d1, e1, a1, w9 , 13); R12(b2, c2, d2, e2, a2, w6 , 7);
|
||||||
|
R11(a1, b1, c1, d1, e1, w10, 14); R12(a2, b2, c2, d2, e2, w15, 8);
|
||||||
|
R11(e1, a1, b1, c1, d1, w11, 15); R12(e2, a2, b2, c2, d2, w8 , 11);
|
||||||
|
R11(d1, e1, a1, b1, c1, w12, 6); R12(d2, e2, a2, b2, c2, w1 , 14);
|
||||||
|
R11(c1, d1, e1, a1, b1, w13, 7); R12(c2, d2, e2, a2, b2, w10, 14);
|
||||||
|
R11(b1, c1, d1, e1, a1, w14, 9); R12(b2, c2, d2, e2, a2, w3 , 12);
|
||||||
|
R11(a1, b1, c1, d1, e1, w15, 8); R12(a2, b2, c2, d2, e2, w12, 6);
|
||||||
|
|
||||||
|
R21(e1, a1, b1, c1, d1, w7 , 7); R22(e2, a2, b2, c2, d2, w6 , 9);
|
||||||
|
R21(d1, e1, a1, b1, c1, w4 , 6); R22(d2, e2, a2, b2, c2, w11, 13);
|
||||||
|
R21(c1, d1, e1, a1, b1, w13, 8); R22(c2, d2, e2, a2, b2, w3 , 15);
|
||||||
|
R21(b1, c1, d1, e1, a1, w1 , 13); R22(b2, c2, d2, e2, a2, w7 , 7);
|
||||||
|
R21(a1, b1, c1, d1, e1, w10, 11); R22(a2, b2, c2, d2, e2, w0 , 12);
|
||||||
|
R21(e1, a1, b1, c1, d1, w6 , 9); R22(e2, a2, b2, c2, d2, w13, 8);
|
||||||
|
R21(d1, e1, a1, b1, c1, w15, 7); R22(d2, e2, a2, b2, c2, w5 , 9);
|
||||||
|
R21(c1, d1, e1, a1, b1, w3 , 15); R22(c2, d2, e2, a2, b2, w10, 11);
|
||||||
|
R21(b1, c1, d1, e1, a1, w12, 7); R22(b2, c2, d2, e2, a2, w14, 7);
|
||||||
|
R21(a1, b1, c1, d1, e1, w0 , 12); R22(a2, b2, c2, d2, e2, w15, 7);
|
||||||
|
R21(e1, a1, b1, c1, d1, w9 , 15); R22(e2, a2, b2, c2, d2, w8 , 12);
|
||||||
|
R21(d1, e1, a1, b1, c1, w5 , 9); R22(d2, e2, a2, b2, c2, w12, 7);
|
||||||
|
R21(c1, d1, e1, a1, b1, w2 , 11); R22(c2, d2, e2, a2, b2, w4 , 6);
|
||||||
|
R21(b1, c1, d1, e1, a1, w14, 7); R22(b2, c2, d2, e2, a2, w9 , 15);
|
||||||
|
R21(a1, b1, c1, d1, e1, w11, 13); R22(a2, b2, c2, d2, e2, w1 , 13);
|
||||||
|
R21(e1, a1, b1, c1, d1, w8 , 12); R22(e2, a2, b2, c2, d2, w2 , 11);
|
||||||
|
|
||||||
|
R31(d1, e1, a1, b1, c1, w3 , 11); R32(d2, e2, a2, b2, c2, w15, 9);
|
||||||
|
R31(c1, d1, e1, a1, b1, w10, 13); R32(c2, d2, e2, a2, b2, w5 , 7);
|
||||||
|
R31(b1, c1, d1, e1, a1, w14, 6); R32(b2, c2, d2, e2, a2, w1 , 15);
|
||||||
|
R31(a1, b1, c1, d1, e1, w4 , 7); R32(a2, b2, c2, d2, e2, w3 , 11);
|
||||||
|
R31(e1, a1, b1, c1, d1, w9 , 14); R32(e2, a2, b2, c2, d2, w7 , 8);
|
||||||
|
R31(d1, e1, a1, b1, c1, w15, 9); R32(d2, e2, a2, b2, c2, w14, 6);
|
||||||
|
R31(c1, d1, e1, a1, b1, w8 , 13); R32(c2, d2, e2, a2, b2, w6 , 6);
|
||||||
|
R31(b1, c1, d1, e1, a1, w1 , 15); R32(b2, c2, d2, e2, a2, w9 , 14);
|
||||||
|
R31(a1, b1, c1, d1, e1, w2 , 14); R32(a2, b2, c2, d2, e2, w11, 12);
|
||||||
|
R31(e1, a1, b1, c1, d1, w7 , 8); R32(e2, a2, b2, c2, d2, w8 , 13);
|
||||||
|
R31(d1, e1, a1, b1, c1, w0 , 13); R32(d2, e2, a2, b2, c2, w12, 5);
|
||||||
|
R31(c1, d1, e1, a1, b1, w6 , 6); R32(c2, d2, e2, a2, b2, w2 , 14);
|
||||||
|
R31(b1, c1, d1, e1, a1, w13, 5); R32(b2, c2, d2, e2, a2, w10, 13);
|
||||||
|
R31(a1, b1, c1, d1, e1, w11, 12); R32(a2, b2, c2, d2, e2, w0 , 13);
|
||||||
|
R31(e1, a1, b1, c1, d1, w5 , 7); R32(e2, a2, b2, c2, d2, w4 , 7);
|
||||||
|
R31(d1, e1, a1, b1, c1, w12, 5); R32(d2, e2, a2, b2, c2, w13, 5);
|
||||||
|
|
||||||
|
R41(c1, d1, e1, a1, b1, w1 , 11); R42(c2, d2, e2, a2, b2, w8 , 15);
|
||||||
|
R41(b1, c1, d1, e1, a1, w9 , 12); R42(b2, c2, d2, e2, a2, w6 , 5);
|
||||||
|
R41(a1, b1, c1, d1, e1, w11, 14); R42(a2, b2, c2, d2, e2, w4 , 8);
|
||||||
|
R41(e1, a1, b1, c1, d1, w10, 15); R42(e2, a2, b2, c2, d2, w1 , 11);
|
||||||
|
R41(d1, e1, a1, b1, c1, w0 , 14); R42(d2, e2, a2, b2, c2, w3 , 14);
|
||||||
|
R41(c1, d1, e1, a1, b1, w8 , 15); R42(c2, d2, e2, a2, b2, w11, 14);
|
||||||
|
R41(b1, c1, d1, e1, a1, w12, 9); R42(b2, c2, d2, e2, a2, w15, 6);
|
||||||
|
R41(a1, b1, c1, d1, e1, w4 , 8); R42(a2, b2, c2, d2, e2, w0 , 14);
|
||||||
|
R41(e1, a1, b1, c1, d1, w13, 9); R42(e2, a2, b2, c2, d2, w5 , 6);
|
||||||
|
R41(d1, e1, a1, b1, c1, w3 , 14); R42(d2, e2, a2, b2, c2, w12, 9);
|
||||||
|
R41(c1, d1, e1, a1, b1, w7 , 5); R42(c2, d2, e2, a2, b2, w2 , 12);
|
||||||
|
R41(b1, c1, d1, e1, a1, w15, 6); R42(b2, c2, d2, e2, a2, w13, 9);
|
||||||
|
R41(a1, b1, c1, d1, e1, w14, 8); R42(a2, b2, c2, d2, e2, w9 , 12);
|
||||||
|
R41(e1, a1, b1, c1, d1, w5 , 6); R42(e2, a2, b2, c2, d2, w7 , 5);
|
||||||
|
R41(d1, e1, a1, b1, c1, w6 , 5); R42(d2, e2, a2, b2, c2, w10, 15);
|
||||||
|
R41(c1, d1, e1, a1, b1, w2 , 12); R42(c2, d2, e2, a2, b2, w14, 8);
|
||||||
|
|
||||||
|
R51(b1, c1, d1, e1, a1, w4 , 9); R52(b2, c2, d2, e2, a2, w12, 8);
|
||||||
|
R51(a1, b1, c1, d1, e1, w0 , 15); R52(a2, b2, c2, d2, e2, w15, 5);
|
||||||
|
R51(e1, a1, b1, c1, d1, w5 , 5); R52(e2, a2, b2, c2, d2, w10, 12);
|
||||||
|
R51(d1, e1, a1, b1, c1, w9 , 11); R52(d2, e2, a2, b2, c2, w4 , 9);
|
||||||
|
R51(c1, d1, e1, a1, b1, w7 , 6); R52(c2, d2, e2, a2, b2, w1 , 12);
|
||||||
|
R51(b1, c1, d1, e1, a1, w12, 8); R52(b2, c2, d2, e2, a2, w5 , 5);
|
||||||
|
R51(a1, b1, c1, d1, e1, w2 , 13); R52(a2, b2, c2, d2, e2, w8 , 14);
|
||||||
|
R51(e1, a1, b1, c1, d1, w10, 12); R52(e2, a2, b2, c2, d2, w7 , 6);
|
||||||
|
R51(d1, e1, a1, b1, c1, w14, 5); R52(d2, e2, a2, b2, c2, w6 , 8);
|
||||||
|
R51(c1, d1, e1, a1, b1, w1 , 12); R52(c2, d2, e2, a2, b2, w2 , 13);
|
||||||
|
R51(b1, c1, d1, e1, a1, w3 , 13); R52(b2, c2, d2, e2, a2, w13, 6);
|
||||||
|
R51(a1, b1, c1, d1, e1, w8 , 14); R52(a2, b2, c2, d2, e2, w14, 5);
|
||||||
|
R51(e1, a1, b1, c1, d1, w11, 11); R52(e2, a2, b2, c2, d2, w0 , 15);
|
||||||
|
R51(d1, e1, a1, b1, c1, w6 , 8); R52(d2, e2, a2, b2, c2, w3 , 13);
|
||||||
|
R51(c1, d1, e1, a1, b1, w15, 5); R52(c2, d2, e2, a2, b2, w9 , 11);
|
||||||
|
R51(b1, c1, d1, e1, a1, w13, 6); R52(b2, c2, d2, e2, a2, w11, 11);
|
||||||
|
|
||||||
|
uint32_t t = s[0];
|
||||||
|
s[0] = s[1] + c1 + d2;
|
||||||
|
s[1] = s[2] + d1 + e2;
|
||||||
|
s[2] = s[3] + e1 + a2;
|
||||||
|
s[3] = s[4] + a1 + b2;
|
||||||
|
s[4] = t + b1 + c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ripemd160
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
////// RIPEMD160
|
||||||
|
|
||||||
|
CRIPEMD160::CRIPEMD160() : bytes(0) {
|
||||||
|
ripemd160::Initialize(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
CRIPEMD160& CRIPEMD160::Write(const unsigned char *data, size_t len) {
|
||||||
|
const unsigned char *end = data + len;
|
||||||
|
size_t bufsize = bytes % 64;
|
||||||
|
if (bufsize && bufsize + len >= 64) {
|
||||||
|
// Fill the buffer, and process it.
|
||||||
|
memcpy(buf + bufsize, data, 64 - bufsize);
|
||||||
|
bytes += 64 - bufsize;
|
||||||
|
data += 64 - bufsize;
|
||||||
|
ripemd160::Transform(s, buf);
|
||||||
|
bufsize = 0;
|
||||||
|
}
|
||||||
|
while (end >= data + 64) {
|
||||||
|
// Process full chunks directly from the source.
|
||||||
|
ripemd160::Transform(s, data);
|
||||||
|
bytes += 64;
|
||||||
|
data += 64;
|
||||||
|
}
|
||||||
|
if (end > data) {
|
||||||
|
// Fill the buffer with what remains.
|
||||||
|
memcpy(buf + bufsize, data, end - data);
|
||||||
|
bytes += end - data;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE]) {
|
||||||
|
static const unsigned char pad[64] = {0x80};
|
||||||
|
unsigned char sizedesc[8];
|
||||||
|
WriteLE64(sizedesc, bytes << 3);
|
||||||
|
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
|
||||||
|
Write(sizedesc, 8);
|
||||||
|
WriteLE32(hash, s[0]);
|
||||||
|
WriteLE32(hash+4, s[1]);
|
||||||
|
WriteLE32(hash+8, s[2]);
|
||||||
|
WriteLE32(hash+12, s[3]);
|
||||||
|
WriteLE32(hash+16, s[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CRIPEMD160& CRIPEMD160::Reset() {
|
||||||
|
bytes = 0;
|
||||||
|
ripemd160::Initialize(s);
|
||||||
|
return *this;
|
||||||
|
}
|
27
src/crypto/ripemd160.h
Normal file
27
src/crypto/ripemd160.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_RIPEMD160_H
|
||||||
|
#define BITCOIN_RIPEMD160_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/** A hasher class for RIPEMD-160. */
|
||||||
|
class CRIPEMD160 {
|
||||||
|
private:
|
||||||
|
uint32_t s[5];
|
||||||
|
unsigned char buf[64];
|
||||||
|
size_t bytes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const size_t OUTPUT_SIZE = 20;
|
||||||
|
|
||||||
|
CRIPEMD160();
|
||||||
|
CRIPEMD160& Write(const unsigned char *data, size_t len);
|
||||||
|
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||||
|
CRIPEMD160& Reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
192
src/crypto/sha1.cpp
Normal file
192
src/crypto/sha1.cpp
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "crypto/sha1.h"
|
||||||
|
|
||||||
|
#include "crypto/common.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Internal implementation code.
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/// Internal SHA-1 implementation.
|
||||||
|
namespace sha1 {
|
||||||
|
|
||||||
|
/** One round of SHA-1. */
|
||||||
|
void inline Round(uint32_t a, uint32_t &b, uint32_t c, uint32_t d, uint32_t &e,
|
||||||
|
uint32_t f, uint32_t k, uint32_t w) {
|
||||||
|
e += ((a << 5) | (a >> 27)) + f + k + w;
|
||||||
|
b = (b << 30) | (b >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t inline f1(uint32_t b, uint32_t c, uint32_t d) { return d ^ (b & (c ^ d)); }
|
||||||
|
uint32_t inline f2(uint32_t b, uint32_t c, uint32_t d) { return b ^ c ^ d; }
|
||||||
|
uint32_t inline f3(uint32_t b, uint32_t c, uint32_t d) { return (b & c) | (d & (b | c)); }
|
||||||
|
|
||||||
|
uint32_t inline left(uint32_t x) { return (x << 1) | (x >> 31); }
|
||||||
|
|
||||||
|
/** Initialize SHA-1 state. */
|
||||||
|
void inline Initialize(uint32_t *s) {
|
||||||
|
s[0] = 0x67452301ul;
|
||||||
|
s[1] = 0xEFCDAB89ul;
|
||||||
|
s[2] = 0x98BADCFEul;
|
||||||
|
s[3] = 0x10325476ul;
|
||||||
|
s[4] = 0xC3D2E1F0ul;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t k1 = 0x5A827999ul;
|
||||||
|
const uint32_t k2 = 0x6ED9EBA1ul;
|
||||||
|
const uint32_t k3 = 0x8F1BBCDCul;
|
||||||
|
const uint32_t k4 = 0xCA62C1D6ul;
|
||||||
|
|
||||||
|
/** Perform a SHA-1 transformation, processing a 64-byte chunk. */
|
||||||
|
void Transform(uint32_t *s, const unsigned char *chunk) {
|
||||||
|
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];
|
||||||
|
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0));
|
||||||
|
Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4));
|
||||||
|
Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8));
|
||||||
|
Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12));
|
||||||
|
Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16));
|
||||||
|
Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20));
|
||||||
|
Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24));
|
||||||
|
Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28));
|
||||||
|
Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32));
|
||||||
|
Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36));
|
||||||
|
Round(a, b, c, d, e, f1(b, c, d), k1, w10 = ReadBE32(chunk + 40));
|
||||||
|
Round(e, a, b, c, d, f1(a, b, c), k1, w11 = ReadBE32(chunk + 44));
|
||||||
|
Round(d, e, a, b, c, f1(e, a, b), k1, w12 = ReadBE32(chunk + 48));
|
||||||
|
Round(c, d, e, a, b, f1(d, e, a), k1, w13 = ReadBE32(chunk + 52));
|
||||||
|
Round(b, c, d, e, a, f1(c, d, e), k1, w14 = ReadBE32(chunk + 56));
|
||||||
|
Round(a, b, c, d, e, f1(b, c, d), k1, w15 = ReadBE32(chunk + 60));
|
||||||
|
|
||||||
|
Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2 ));
|
||||||
|
Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3 ));
|
||||||
|
Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4 ));
|
||||||
|
Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5 ));
|
||||||
|
Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6 ));
|
||||||
|
Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7 ));
|
||||||
|
Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8 ));
|
||||||
|
Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9 ));
|
||||||
|
Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10));
|
||||||
|
Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11));
|
||||||
|
Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12));
|
||||||
|
Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13));
|
||||||
|
Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14));
|
||||||
|
Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15));
|
||||||
|
Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0 ));
|
||||||
|
Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1 ));
|
||||||
|
|
||||||
|
Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2 ));
|
||||||
|
Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3 ));
|
||||||
|
Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4 ));
|
||||||
|
Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5 ));
|
||||||
|
Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6 ));
|
||||||
|
Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7 ));
|
||||||
|
Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8 ));
|
||||||
|
Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9 ));
|
||||||
|
Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
|
||||||
|
Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
|
||||||
|
Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
|
||||||
|
Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
|
||||||
|
Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14));
|
||||||
|
Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15));
|
||||||
|
Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0 ));
|
||||||
|
Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1 ));
|
||||||
|
|
||||||
|
Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2 ));
|
||||||
|
Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3 ));
|
||||||
|
Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4 ));
|
||||||
|
Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5 ));
|
||||||
|
Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6 ));
|
||||||
|
Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7 ));
|
||||||
|
Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8 ));
|
||||||
|
Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9 ));
|
||||||
|
Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
|
||||||
|
Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
|
||||||
|
Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
|
||||||
|
Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
|
||||||
|
Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
|
||||||
|
Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15));
|
||||||
|
Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0 ));
|
||||||
|
Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1 ));
|
||||||
|
|
||||||
|
Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2 ));
|
||||||
|
Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3 ));
|
||||||
|
Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4 ));
|
||||||
|
Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5 ));
|
||||||
|
Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6 ));
|
||||||
|
Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7 ));
|
||||||
|
Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8 ));
|
||||||
|
Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9 ));
|
||||||
|
Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10));
|
||||||
|
Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11));
|
||||||
|
Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12));
|
||||||
|
Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13));
|
||||||
|
Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
|
||||||
|
Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15));
|
||||||
|
Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0 ));
|
||||||
|
Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1 ));
|
||||||
|
|
||||||
|
s[0] += a;
|
||||||
|
s[1] += b;
|
||||||
|
s[2] += c;
|
||||||
|
s[3] += d;
|
||||||
|
s[4] += e;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sha1
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
////// SHA1
|
||||||
|
|
||||||
|
CSHA1::CSHA1() : bytes(0) {
|
||||||
|
sha1::Initialize(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSHA1& CSHA1::Write(const unsigned char *data, size_t len) {
|
||||||
|
const unsigned char *end = data + len;
|
||||||
|
size_t bufsize = bytes % 64;
|
||||||
|
if (bufsize && bufsize + len >= 64) {
|
||||||
|
// Fill the buffer, and process it.
|
||||||
|
memcpy(buf + bufsize, data, 64 - bufsize);
|
||||||
|
bytes += 64 - bufsize;
|
||||||
|
data += 64 - bufsize;
|
||||||
|
sha1::Transform(s, buf);
|
||||||
|
bufsize = 0;
|
||||||
|
}
|
||||||
|
while (end >= data + 64) {
|
||||||
|
// Process full chunks directly from the source.
|
||||||
|
sha1::Transform(s, data);
|
||||||
|
bytes += 64;
|
||||||
|
data += 64;
|
||||||
|
}
|
||||||
|
if (end > data) {
|
||||||
|
// Fill the buffer with what remains.
|
||||||
|
memcpy(buf + bufsize, data, end - data);
|
||||||
|
bytes += end - data;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE]) {
|
||||||
|
static const unsigned char pad[64] = {0x80};
|
||||||
|
unsigned char sizedesc[8];
|
||||||
|
WriteBE64(sizedesc, bytes << 3);
|
||||||
|
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
|
||||||
|
Write(sizedesc, 8);
|
||||||
|
WriteBE32(hash, s[0]);
|
||||||
|
WriteBE32(hash+4, s[1]);
|
||||||
|
WriteBE32(hash+8, s[2]);
|
||||||
|
WriteBE32(hash+12, s[3]);
|
||||||
|
WriteBE32(hash+16, s[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSHA1& CSHA1::Reset() {
|
||||||
|
bytes = 0;
|
||||||
|
sha1::Initialize(s);
|
||||||
|
return *this;
|
||||||
|
}
|
27
src/crypto/sha1.h
Normal file
27
src/crypto/sha1.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_SHA1_H
|
||||||
|
#define BITCOIN_SHA1_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/** A hasher class for SHA1. */
|
||||||
|
class CSHA1 {
|
||||||
|
private:
|
||||||
|
uint32_t s[5];
|
||||||
|
unsigned char buf[64];
|
||||||
|
size_t bytes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const size_t OUTPUT_SIZE = 20;
|
||||||
|
|
||||||
|
CSHA1();
|
||||||
|
CSHA1& Write(const unsigned char *data, size_t len);
|
||||||
|
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||||
|
CSHA1& Reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
398
src/crypto/sha2.cpp
Normal file
398
src/crypto/sha2.cpp
Normal file
|
@ -0,0 +1,398 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "crypto/sha2.h"
|
||||||
|
|
||||||
|
#include "crypto/common.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Internal implementation code.
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/// Internal SHA-256 implementation.
|
||||||
|
namespace sha256 {
|
||||||
|
|
||||||
|
uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
|
||||||
|
uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
|
||||||
|
uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
|
||||||
|
uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
|
||||||
|
uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
|
||||||
|
uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
|
||||||
|
|
||||||
|
/** One round of SHA-256. */
|
||||||
|
void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t &d,
|
||||||
|
uint32_t e, uint32_t f, uint32_t g, uint32_t &h,
|
||||||
|
uint32_t k, uint32_t w) {
|
||||||
|
uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
|
||||||
|
uint32_t t2 = Sigma0(a) + Maj(a, b, c);
|
||||||
|
d += t1;
|
||||||
|
h = t1 + t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Initialize SHA-256 state. */
|
||||||
|
void inline Initialize(uint32_t *s) {
|
||||||
|
s[0] = 0x6a09e667ul;
|
||||||
|
s[1] = 0xbb67ae85ul;
|
||||||
|
s[2] = 0x3c6ef372ul;
|
||||||
|
s[3] = 0xa54ff53aul;
|
||||||
|
s[4] = 0x510e527ful;
|
||||||
|
s[5] = 0x9b05688cul;
|
||||||
|
s[6] = 0x1f83d9abul;
|
||||||
|
s[7] = 0x5be0cd19ul;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
|
||||||
|
void Transform(uint32_t *s, const unsigned char *chunk) {
|
||||||
|
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
|
||||||
|
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0( w1));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0( w2));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1( w0) + w11 + sigma0( w3));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1( w1) + w12 + sigma0( w4));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1( w2) + w13 + sigma0( w5));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1( w3) + w14 + sigma0( w6));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1( w4) + w15 + sigma0( w7));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1( w5) + w0 + sigma0( w8));
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1( w6) + w1 + sigma0( w9));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1( w7) + w2 + sigma0(w10));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1( w8) + w3 + sigma0(w11));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1( w9) + w4 + sigma0(w12));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0( w0));
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0( w1));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0( w2));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1( w0) + w11 + sigma0( w3));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1( w1) + w12 + sigma0( w4));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1( w2) + w13 + sigma0( w5));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1( w3) + w14 + sigma0( w6));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1( w4) + w15 + sigma0( w7));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1( w5) + w0 + sigma0( w8));
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1( w6) + w1 + sigma0( w9));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1( w7) + w2 + sigma0(w10));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1( w8) + w3 + sigma0(w11));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1( w9) + w4 + sigma0(w12));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0( w0));
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0( w1));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0( w2));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1( w0) + w11 + sigma0( w3));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1( w1) + w12 + sigma0( w4));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1( w2) + w13 + sigma0( w5));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1( w3) + w14 + sigma0( w6));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1( w4) + w15 + sigma0( w7));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1( w5) + w0 + sigma0( w8));
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1( w6) + w1 + sigma0( w9));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1( w7) + w2 + sigma0(w10));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1( w8) + w3 + sigma0(w11));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1( w9) + w4 + sigma0(w12));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0( w0));
|
||||||
|
|
||||||
|
s[0] += a;
|
||||||
|
s[1] += b;
|
||||||
|
s[2] += c;
|
||||||
|
s[3] += d;
|
||||||
|
s[4] += e;
|
||||||
|
s[5] += f;
|
||||||
|
s[6] += g;
|
||||||
|
s[7] += h;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sha256
|
||||||
|
|
||||||
|
/// Internal SHA-512 implementation.
|
||||||
|
namespace sha512 {
|
||||||
|
|
||||||
|
uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }
|
||||||
|
uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }
|
||||||
|
uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }
|
||||||
|
uint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); }
|
||||||
|
uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); }
|
||||||
|
uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); }
|
||||||
|
|
||||||
|
/** One round of SHA-512. */
|
||||||
|
void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t &d,
|
||||||
|
uint64_t e, uint64_t f, uint64_t g, uint64_t &h,
|
||||||
|
uint64_t k, uint64_t w) {
|
||||||
|
uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
|
||||||
|
uint64_t t2 = Sigma0(a) + Maj(a, b, c);
|
||||||
|
d += t1;
|
||||||
|
h = t1 + t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Initialize SHA-256 state. */
|
||||||
|
void inline Initialize(uint64_t *s) {
|
||||||
|
s[0] = 0x6a09e667f3bcc908ull;
|
||||||
|
s[1] = 0xbb67ae8584caa73bull;
|
||||||
|
s[2] = 0x3c6ef372fe94f82bull;
|
||||||
|
s[3] = 0xa54ff53a5f1d36f1ull;
|
||||||
|
s[4] = 0x510e527fade682d1ull;
|
||||||
|
s[5] = 0x9b05688c2b3e6c1full;
|
||||||
|
s[6] = 0x1f83d9abfb41bd6bull;
|
||||||
|
s[7] = 0x5be0cd19137e2179ull;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
|
||||||
|
void Transform(uint64_t *s, const unsigned char *chunk) {
|
||||||
|
uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
|
||||||
|
uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56));
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120));
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0( w1));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0( w2));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1( w0) + w11 + sigma0( w3));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1( w1) + w12 + sigma0( w4));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1( w2) + w13 + sigma0( w5));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1( w3) + w14 + sigma0( w6));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1( w4) + w15 + sigma0( w7));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1( w5) + w0 + sigma0( w8));
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1( w6) + w1 + sigma0( w9));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1( w7) + w2 + sigma0(w10));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1( w8) + w3 + sigma0(w11));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1( w9) + w4 + sigma0(w12));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0( w0));
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0( w1));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0( w2));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1( w0) + w11 + sigma0( w3));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1( w1) + w12 + sigma0( w4));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1( w2) + w13 + sigma0( w5));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1( w3) + w14 + sigma0( w6));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1( w4) + w15 + sigma0( w7));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1( w5) + w0 + sigma0( w8));
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1( w6) + w1 + sigma0( w9));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1( w7) + w2 + sigma0(w10));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1( w8) + w3 + sigma0(w11));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1( w9) + w4 + sigma0(w12));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0( w0));
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0( w1));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0( w2));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1( w0) + w11 + sigma0( w3));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1( w1) + w12 + sigma0( w4));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1( w2) + w13 + sigma0( w5));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1( w3) + w14 + sigma0( w6));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1( w4) + w15 + sigma0( w7));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1( w5) + w0 + sigma0( w8));
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1( w6) + w1 + sigma0( w9));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1( w7) + w2 + sigma0(w10));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1( w8) + w3 + sigma0(w11));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1( w9) + w4 + sigma0(w12));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0( w0));
|
||||||
|
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0( w1));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0( w2));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1( w0) + w11 + sigma0( w3));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1( w1) + w12 + sigma0( w4));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1( w2) + w13 + sigma0( w5));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1( w3) + w14 + sigma0( w6));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1( w4) + w15 + sigma0( w7));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1( w5) + w0 + sigma0( w8));
|
||||||
|
Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1( w6) + w1 + sigma0( w9));
|
||||||
|
Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1( w7) + w2 + sigma0(w10));
|
||||||
|
Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1( w8) + w3 + sigma0(w11));
|
||||||
|
Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1( w9) + w4 + sigma0(w12));
|
||||||
|
Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||||
|
Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||||
|
Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||||
|
Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 += sigma1(w13) + w8 + sigma0( w0));
|
||||||
|
|
||||||
|
s[0] += a;
|
||||||
|
s[1] += b;
|
||||||
|
s[2] += c;
|
||||||
|
s[3] += d;
|
||||||
|
s[4] += e;
|
||||||
|
s[5] += f;
|
||||||
|
s[6] += g;
|
||||||
|
s[7] += h;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sha512
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
////// SHA-256
|
||||||
|
|
||||||
|
CSHA256::CSHA256() : bytes(0) {
|
||||||
|
sha256::Initialize(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSHA256& CSHA256::Write(const unsigned char *data, size_t len) {
|
||||||
|
const unsigned char *end = data + len;
|
||||||
|
size_t bufsize = bytes % 64;
|
||||||
|
if (bufsize && bufsize + len >= 64) {
|
||||||
|
// Fill the buffer, and process it.
|
||||||
|
memcpy(buf + bufsize, data, 64 - bufsize);
|
||||||
|
bytes += 64 - bufsize;
|
||||||
|
data += 64 - bufsize;
|
||||||
|
sha256::Transform(s, buf);
|
||||||
|
bufsize = 0;
|
||||||
|
}
|
||||||
|
while (end >= data + 64) {
|
||||||
|
// Process full chunks directly from the source.
|
||||||
|
sha256::Transform(s, data);
|
||||||
|
bytes += 64;
|
||||||
|
data += 64;
|
||||||
|
}
|
||||||
|
if (end > data) {
|
||||||
|
// Fill the buffer with what remains.
|
||||||
|
memcpy(buf + bufsize, data, end - data);
|
||||||
|
bytes += end - data;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) {
|
||||||
|
static const unsigned char pad[64] = {0x80};
|
||||||
|
unsigned char sizedesc[8];
|
||||||
|
WriteBE64(sizedesc, bytes << 3);
|
||||||
|
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
|
||||||
|
Write(sizedesc, 8);
|
||||||
|
WriteBE32(hash, s[0]);
|
||||||
|
WriteBE32(hash+4, s[1]);
|
||||||
|
WriteBE32(hash+8, s[2]);
|
||||||
|
WriteBE32(hash+12, s[3]);
|
||||||
|
WriteBE32(hash+16, s[4]);
|
||||||
|
WriteBE32(hash+20, s[5]);
|
||||||
|
WriteBE32(hash+24, s[6]);
|
||||||
|
WriteBE32(hash+28, s[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSHA256& CSHA256::Reset() {
|
||||||
|
bytes = 0;
|
||||||
|
sha256::Initialize(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
////// SHA-512
|
||||||
|
|
||||||
|
CSHA512::CSHA512() : bytes(0) {
|
||||||
|
sha512::Initialize(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSHA512& CSHA512::Write(const unsigned char *data, size_t len) {
|
||||||
|
const unsigned char *end = data + len;
|
||||||
|
size_t bufsize = bytes % 128;
|
||||||
|
if (bufsize && bufsize + len >= 128) {
|
||||||
|
// Fill the buffer, and process it.
|
||||||
|
memcpy(buf + bufsize, data, 128 - bufsize);
|
||||||
|
bytes += 128 - bufsize;
|
||||||
|
data += 128 - bufsize;
|
||||||
|
sha512::Transform(s, buf);
|
||||||
|
bufsize = 0;
|
||||||
|
}
|
||||||
|
while (end >= data + 128) {
|
||||||
|
// Process full chunks directly from the source.
|
||||||
|
sha512::Transform(s, data);
|
||||||
|
data += 128;
|
||||||
|
bytes += 128;
|
||||||
|
}
|
||||||
|
if (end > data) {
|
||||||
|
// Fill the buffer with what remains.
|
||||||
|
memcpy(buf + bufsize, data, end - data);
|
||||||
|
bytes += end - data;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) {
|
||||||
|
static const unsigned char pad[128] = {0x80};
|
||||||
|
unsigned char sizedesc[16] = {0x00};
|
||||||
|
WriteBE64(sizedesc+8, bytes << 3);
|
||||||
|
Write(pad, 1 + ((239 - (bytes % 128)) % 128));
|
||||||
|
Write(sizedesc, 16);
|
||||||
|
WriteBE64(hash, s[0]);
|
||||||
|
WriteBE64(hash+8, s[1]);
|
||||||
|
WriteBE64(hash+16, s[2]);
|
||||||
|
WriteBE64(hash+24, s[3]);
|
||||||
|
WriteBE64(hash+32, s[4]);
|
||||||
|
WriteBE64(hash+40, s[5]);
|
||||||
|
WriteBE64(hash+48, s[6]);
|
||||||
|
WriteBE64(hash+56, s[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSHA512& CSHA512::Reset() {
|
||||||
|
bytes = 0;
|
||||||
|
sha512::Initialize(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
////// HMAC-SHA-512
|
||||||
|
|
||||||
|
CHMAC_SHA512::CHMAC_SHA512(const unsigned char *key, size_t keylen) {
|
||||||
|
unsigned char rkey[128];
|
||||||
|
if (keylen <= 128) {
|
||||||
|
memcpy(rkey, key, keylen);
|
||||||
|
memset(rkey + keylen, 0, 128 - keylen);
|
||||||
|
} else {
|
||||||
|
CSHA512().Write(key, keylen).Finalize(rkey);
|
||||||
|
memset(rkey + 64, 0, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int n=0; n<128; n++)
|
||||||
|
rkey[n] ^= 0x5c;
|
||||||
|
outer.Write(rkey, 128);
|
||||||
|
|
||||||
|
for (int n=0; n<128; n++)
|
||||||
|
rkey[n] ^= 0x5c ^ 0x36;
|
||||||
|
inner.Write(rkey, 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) {
|
||||||
|
unsigned char temp[64];
|
||||||
|
inner.Finalize(temp);
|
||||||
|
outer.Write(temp, 64).Finalize(hash);
|
||||||
|
}
|
60
src/crypto/sha2.h
Normal file
60
src/crypto/sha2.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_SHA2_H
|
||||||
|
#define BITCOIN_SHA2_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/** A hasher class for SHA-256. */
|
||||||
|
class CSHA256 {
|
||||||
|
private:
|
||||||
|
uint32_t s[8];
|
||||||
|
unsigned char buf[64];
|
||||||
|
size_t bytes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const size_t OUTPUT_SIZE = 32;
|
||||||
|
|
||||||
|
CSHA256();
|
||||||
|
CSHA256& Write(const unsigned char *data, size_t len);
|
||||||
|
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||||
|
CSHA256& Reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A hasher class for SHA-512. */
|
||||||
|
class CSHA512 {
|
||||||
|
private:
|
||||||
|
uint64_t s[8];
|
||||||
|
unsigned char buf[128];
|
||||||
|
size_t bytes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const size_t OUTPUT_SIZE = 64;
|
||||||
|
|
||||||
|
CSHA512();
|
||||||
|
CSHA512& Write(const unsigned char *data, size_t len);
|
||||||
|
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||||
|
CSHA512& Reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A hasher class for HMAC-SHA-512. */
|
||||||
|
class CHMAC_SHA512 {
|
||||||
|
private:
|
||||||
|
CSHA512 outer;
|
||||||
|
CSHA512 inner;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const size_t OUTPUT_SIZE = 64;
|
||||||
|
|
||||||
|
CHMAC_SHA512(const unsigned char *key, size_t keylen);
|
||||||
|
CHMAC_SHA512& Write(const unsigned char *data, size_t len) {
|
||||||
|
inner.Write(data, len);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
41
src/hash.cpp
41
src/hash.cpp
|
@ -56,44 +56,3 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
|
||||||
|
|
||||||
return h1;
|
return h1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int HMAC_SHA512_Init(HMAC_SHA512_CTX *pctx, const void *pkey, size_t len)
|
|
||||||
{
|
|
||||||
unsigned char key[128];
|
|
||||||
if (len <= 128)
|
|
||||||
{
|
|
||||||
memcpy(key, pkey, len);
|
|
||||||
memset(key + len, 0, 128-len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SHA512_CTX ctxKey;
|
|
||||||
SHA512_Init(&ctxKey);
|
|
||||||
SHA512_Update(&ctxKey, pkey, len);
|
|
||||||
SHA512_Final(key, &ctxKey);
|
|
||||||
memset(key + 64, 0, 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int n=0; n<128; n++)
|
|
||||||
key[n] ^= 0x5c;
|
|
||||||
SHA512_Init(&pctx->ctxOuter);
|
|
||||||
SHA512_Update(&pctx->ctxOuter, key, 128);
|
|
||||||
|
|
||||||
for (int n=0; n<128; n++)
|
|
||||||
key[n] ^= 0x5c ^ 0x36;
|
|
||||||
SHA512_Init(&pctx->ctxInner);
|
|
||||||
return SHA512_Update(&pctx->ctxInner, key, 128);
|
|
||||||
}
|
|
||||||
|
|
||||||
int HMAC_SHA512_Update(HMAC_SHA512_CTX *pctx, const void *pdata, size_t len)
|
|
||||||
{
|
|
||||||
return SHA512_Update(&pctx->ctxInner, pdata, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int HMAC_SHA512_Final(unsigned char *pmd, HMAC_SHA512_CTX *pctx)
|
|
||||||
{
|
|
||||||
unsigned char buf[64];
|
|
||||||
SHA512_Final(buf, &pctx->ctxInner);
|
|
||||||
SHA512_Update(&pctx->ctxOuter, buf, 64);
|
|
||||||
return SHA512_Final(pmd, &pctx->ctxOuter);
|
|
||||||
}
|
|
||||||
|
|
189
src/hash.h
189
src/hash.h
|
@ -6,55 +6,138 @@
|
||||||
#ifndef BITCOIN_HASH_H
|
#ifndef BITCOIN_HASH_H
|
||||||
#define BITCOIN_HASH_H
|
#define BITCOIN_HASH_H
|
||||||
|
|
||||||
|
#include "crypto/sha2.h"
|
||||||
|
#include "crypto/ripemd160.h"
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <openssl/ripemd.h>
|
/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
|
||||||
#include <openssl/sha.h>
|
class CHash256 {
|
||||||
|
private:
|
||||||
|
CSHA256 sha;
|
||||||
|
public:
|
||||||
|
static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
|
||||||
|
|
||||||
|
void Finalize(unsigned char hash[OUTPUT_SIZE]) {
|
||||||
|
unsigned char buf[sha.OUTPUT_SIZE];
|
||||||
|
sha.Finalize(buf);
|
||||||
|
sha.Reset().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHash256& Write(const unsigned char *data, size_t len) {
|
||||||
|
sha.Write(data, len);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHash256& Reset() {
|
||||||
|
sha.Reset();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160). */
|
||||||
|
class CHash160 {
|
||||||
|
private:
|
||||||
|
CSHA256 sha;
|
||||||
|
public:
|
||||||
|
static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
|
||||||
|
|
||||||
|
void Finalize(unsigned char hash[OUTPUT_SIZE]) {
|
||||||
|
unsigned char buf[sha.OUTPUT_SIZE];
|
||||||
|
sha.Finalize(buf);
|
||||||
|
CRIPEMD160().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHash160& Write(const unsigned char *data, size_t len) {
|
||||||
|
sha.Write(data, len);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHash160& Reset() {
|
||||||
|
sha.Reset();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Compute the 256-bit hash of an object. */
|
||||||
template<typename T1>
|
template<typename T1>
|
||||||
inline uint256 Hash(const T1 pbegin, const T1 pend)
|
inline uint256 Hash(const T1 pbegin, const T1 pend)
|
||||||
{
|
{
|
||||||
static unsigned char pblank[1];
|
static const unsigned char pblank[1] = {};
|
||||||
uint256 hash1;
|
uint256 result;
|
||||||
SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
|
CHash256().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
|
||||||
uint256 hash2;
|
.Finalize((unsigned char*)&result);
|
||||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
return result;
|
||||||
return hash2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Compute the 256-bit hash of the concatenation of two objects. */
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
inline uint256 Hash(const T1 p1begin, const T1 p1end,
|
||||||
|
const T2 p2begin, const T2 p2end) {
|
||||||
|
static const unsigned char pblank[1] = {};
|
||||||
|
uint256 result;
|
||||||
|
CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
|
||||||
|
.Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
|
||||||
|
.Finalize((unsigned char*)&result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compute the 256-bit hash of the concatenation of three objects. */
|
||||||
|
template<typename T1, typename T2, typename T3>
|
||||||
|
inline uint256 Hash(const T1 p1begin, const T1 p1end,
|
||||||
|
const T2 p2begin, const T2 p2end,
|
||||||
|
const T3 p3begin, const T3 p3end) {
|
||||||
|
static const unsigned char pblank[1] = {};
|
||||||
|
uint256 result;
|
||||||
|
CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
|
||||||
|
.Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
|
||||||
|
.Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]))
|
||||||
|
.Finalize((unsigned char*)&result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compute the 160-bit hash an object. */
|
||||||
|
template<typename T1>
|
||||||
|
inline uint160 Hash160(const T1 pbegin, const T1 pend)
|
||||||
|
{
|
||||||
|
static unsigned char pblank[1] = {};
|
||||||
|
uint160 result;
|
||||||
|
CHash160().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
|
||||||
|
.Finalize((unsigned char*)&result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compute the 160-bit hash of a vector. */
|
||||||
|
inline uint160 Hash160(const std::vector<unsigned char>& vch)
|
||||||
|
{
|
||||||
|
return Hash160(vch.begin(), vch.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A writer stream (for serialization) that computes a 256-bit hash. */
|
||||||
class CHashWriter
|
class CHashWriter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SHA256_CTX ctx;
|
CHash256 ctx;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int nType;
|
int nType;
|
||||||
int nVersion;
|
int nVersion;
|
||||||
|
|
||||||
void Init() {
|
CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}
|
||||||
SHA256_Init(&ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
CHashWriter& write(const char *pch, size_t size) {
|
CHashWriter& write(const char *pch, size_t size) {
|
||||||
SHA256_Update(&ctx, pch, size);
|
ctx.Write((const unsigned char*)pch, size);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalidates the object
|
// invalidates the object
|
||||||
uint256 GetHash() {
|
uint256 GetHash() {
|
||||||
uint256 hash1;
|
uint256 result;
|
||||||
SHA256_Final((unsigned char*)&hash1, &ctx);
|
ctx.Finalize((unsigned char*)&result);
|
||||||
uint256 hash2;
|
return result;
|
||||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
|
||||||
return hash2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -65,41 +148,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Compute the 256-bit hash of an object's serialization. */
|
||||||
template<typename T1, typename T2>
|
|
||||||
inline uint256 Hash(const T1 p1begin, const T1 p1end,
|
|
||||||
const T2 p2begin, const T2 p2end)
|
|
||||||
{
|
|
||||||
static unsigned char pblank[1];
|
|
||||||
uint256 hash1;
|
|
||||||
SHA256_CTX ctx;
|
|
||||||
SHA256_Init(&ctx);
|
|
||||||
SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
|
|
||||||
SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
|
|
||||||
SHA256_Final((unsigned char*)&hash1, &ctx);
|
|
||||||
uint256 hash2;
|
|
||||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
|
||||||
return hash2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3>
|
|
||||||
inline uint256 Hash(const T1 p1begin, const T1 p1end,
|
|
||||||
const T2 p2begin, const T2 p2end,
|
|
||||||
const T3 p3begin, const T3 p3end)
|
|
||||||
{
|
|
||||||
static unsigned char pblank[1];
|
|
||||||
uint256 hash1;
|
|
||||||
SHA256_CTX ctx;
|
|
||||||
SHA256_Init(&ctx);
|
|
||||||
SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
|
|
||||||
SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
|
|
||||||
SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0]));
|
|
||||||
SHA256_Final((unsigned char*)&hash1, &ctx);
|
|
||||||
uint256 hash2;
|
|
||||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
|
||||||
return hash2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
|
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
|
||||||
{
|
{
|
||||||
|
@ -108,32 +157,6 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL
|
||||||
return ss.GetHash();
|
return ss.GetHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T1>
|
|
||||||
inline uint160 Hash160(const T1 pbegin, const T1 pend)
|
|
||||||
{
|
|
||||||
static unsigned char pblank[1];
|
|
||||||
uint256 hash1;
|
|
||||||
SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
|
|
||||||
uint160 hash2;
|
|
||||||
RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
|
||||||
return hash2;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint160 Hash160(const std::vector<unsigned char>& vch)
|
|
||||||
{
|
|
||||||
return Hash160(vch.begin(), vch.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
|
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SHA512_CTX ctxInner;
|
|
||||||
SHA512_CTX ctxOuter;
|
|
||||||
} HMAC_SHA512_CTX;
|
|
||||||
|
|
||||||
int HMAC_SHA512_Init(HMAC_SHA512_CTX *pctx, const void *pkey, size_t len);
|
|
||||||
int HMAC_SHA512_Update(HMAC_SHA512_CTX *pctx, const void *pdata, size_t len);
|
|
||||||
int HMAC_SHA512_Final(unsigned char *pmd, HMAC_SHA512_CTX *pctx);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -116,7 +116,6 @@ void Shutdown()
|
||||||
RenameThread("bitcoin-shutoff");
|
RenameThread("bitcoin-shutoff");
|
||||||
mempool.AddTransactionsUpdated(1);
|
mempool.AddTransactionsUpdated(1);
|
||||||
StopRPCThreads();
|
StopRPCThreads();
|
||||||
ShutdownRPCMining();
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
if (pwalletMain)
|
if (pwalletMain)
|
||||||
bitdb.Flush(false);
|
bitdb.Flush(false);
|
||||||
|
@ -1148,8 +1147,6 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
StartNode(threadGroup);
|
StartNode(threadGroup);
|
||||||
// InitRPCMining is needed here so getwork/getblocktemplate in the GUI debug console works properly.
|
|
||||||
InitRPCMining();
|
|
||||||
if (fServer)
|
if (fServer)
|
||||||
StartRPCThreads();
|
StartRPCThreads();
|
||||||
|
|
||||||
|
|
19
src/key.cpp
19
src/key.cpp
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
|
|
||||||
|
#include "crypto/sha2.h"
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/ecdsa.h>
|
#include <openssl/ecdsa.h>
|
||||||
#include <openssl/obj_mac.h>
|
#include <openssl/obj_mac.h>
|
||||||
|
@ -510,12 +512,10 @@ void static BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, un
|
||||||
num[1] = (nChild >> 16) & 0xFF;
|
num[1] = (nChild >> 16) & 0xFF;
|
||||||
num[2] = (nChild >> 8) & 0xFF;
|
num[2] = (nChild >> 8) & 0xFF;
|
||||||
num[3] = (nChild >> 0) & 0xFF;
|
num[3] = (nChild >> 0) & 0xFF;
|
||||||
HMAC_SHA512_CTX ctx;
|
CHMAC_SHA512(chainCode, 32).Write(&header, 1)
|
||||||
HMAC_SHA512_Init(&ctx, chainCode, 32);
|
.Write(data, 32)
|
||||||
HMAC_SHA512_Update(&ctx, &header, 1);
|
.Write(num, 4)
|
||||||
HMAC_SHA512_Update(&ctx, data, 32);
|
.Finalize(output);
|
||||||
HMAC_SHA512_Update(&ctx, num, 4);
|
|
||||||
HMAC_SHA512_Final(output, &ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const {
|
bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const {
|
||||||
|
@ -562,13 +562,10 @@ bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) {
|
void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) {
|
||||||
static const char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
|
static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
|
||||||
HMAC_SHA512_CTX ctx;
|
|
||||||
HMAC_SHA512_Init(&ctx, hashkey, sizeof(hashkey));
|
|
||||||
HMAC_SHA512_Update(&ctx, seed, nSeedLen);
|
|
||||||
unsigned char out[64];
|
unsigned char out[64];
|
||||||
LockObject(out);
|
LockObject(out);
|
||||||
HMAC_SHA512_Final(out, &ctx);
|
CHMAC_SHA512(hashkey, sizeof(hashkey)).Write(seed, nSeedLen).Finalize(out);
|
||||||
key.Set(&out[0], &out[32], true);
|
key.Set(&out[0], &out[32], true);
|
||||||
memcpy(vchChainCode, &out[32], 32);
|
memcpy(vchChainCode, &out[32], 32);
|
||||||
UnlockObject(out);
|
UnlockObject(out);
|
||||||
|
|
161
src/miner.cpp
161
src/miner.cpp
|
@ -6,6 +6,7 @@
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
#include "hash.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
|
@ -13,47 +14,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// BitcoinMiner
|
// BitcoinMiner
|
||||||
//
|
//
|
||||||
|
|
||||||
int static FormatHashBlocks(void* pbuffer, unsigned int len)
|
|
||||||
{
|
|
||||||
unsigned char* pdata = (unsigned char*)pbuffer;
|
|
||||||
unsigned int blocks = 1 + ((len + 8) / 64);
|
|
||||||
unsigned char* pend = pdata + 64 * blocks;
|
|
||||||
memset(pdata + len, 0, 64 * blocks - len);
|
|
||||||
pdata[len] = 0x80;
|
|
||||||
unsigned int bits = len * 8;
|
|
||||||
pend[-1] = (bits >> 0) & 0xff;
|
|
||||||
pend[-2] = (bits >> 8) & 0xff;
|
|
||||||
pend[-3] = (bits >> 16) & 0xff;
|
|
||||||
pend[-4] = (bits >> 24) & 0xff;
|
|
||||||
return blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const unsigned int pSHA256InitState[8] =
|
|
||||||
{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
|
|
||||||
|
|
||||||
void SHA256Transform(void* pstate, void* pinput, const void* pinit)
|
|
||||||
{
|
|
||||||
SHA256_CTX ctx;
|
|
||||||
unsigned char data[64];
|
|
||||||
|
|
||||||
SHA256_Init(&ctx);
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]);
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
ctx.h[i] = ((uint32_t*)pinit)[i];
|
|
||||||
|
|
||||||
SHA256_Update(&ctx, data, sizeof(data));
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
((uint32_t*)pstate)[i] = ctx.h[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Unconfirmed transactions in the memory pool often depend on other
|
// Unconfirmed transactions in the memory pool often depend on other
|
||||||
// transactions in the memory pool. When we select transactions from the
|
// transactions in the memory pool. When we select transactions from the
|
||||||
|
@ -369,51 +335,6 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Pre-build hash buffers
|
|
||||||
//
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
struct unnamed2
|
|
||||||
{
|
|
||||||
int nVersion;
|
|
||||||
uint256 hashPrevBlock;
|
|
||||||
uint256 hashMerkleRoot;
|
|
||||||
unsigned int nTime;
|
|
||||||
unsigned int nBits;
|
|
||||||
unsigned int nNonce;
|
|
||||||
}
|
|
||||||
block;
|
|
||||||
unsigned char pchPadding0[64];
|
|
||||||
uint256 hash1;
|
|
||||||
unsigned char pchPadding1[64];
|
|
||||||
}
|
|
||||||
tmp;
|
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
|
||||||
|
|
||||||
tmp.block.nVersion = pblock->nVersion;
|
|
||||||
tmp.block.hashPrevBlock = pblock->hashPrevBlock;
|
|
||||||
tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
|
|
||||||
tmp.block.nTime = pblock->nTime;
|
|
||||||
tmp.block.nBits = pblock->nBits;
|
|
||||||
tmp.block.nNonce = pblock->nNonce;
|
|
||||||
|
|
||||||
FormatHashBlocks(&tmp.block, sizeof(tmp.block));
|
|
||||||
FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
|
|
||||||
|
|
||||||
// Byte swap all the input buffer
|
|
||||||
for (unsigned 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
|
|
||||||
SHA256Transform(pmidstate, &tmp.block, pSHA256InitState);
|
|
||||||
|
|
||||||
memcpy(pdata, &tmp.block, 128);
|
|
||||||
memcpy(phash1, &tmp.hash1, 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -424,34 +345,33 @@ int64_t nHPSTimerStart = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// ScanHash scans nonces looking for a hash with at least some zero bits.
|
// ScanHash scans nonces looking for a hash with at least some zero bits.
|
||||||
// It operates on big endian data. Caller does the byte reversing.
|
// The nonce is usually preserved between calls, but periodically or if the
|
||||||
// All input buffers are 16-byte aligned. nNonce is usually preserved
|
// nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at
|
||||||
// between calls, but periodically or if nNonce is 0xffff0000 or above,
|
// zero.
|
||||||
// the block is rebuilt and nNonce starts over at zero.
|
|
||||||
//
|
//
|
||||||
unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
|
bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash) {
|
||||||
{
|
// Write the first 76 bytes of the block header to a double-SHA256 state.
|
||||||
unsigned int& nNonce = *(unsigned int*)(pdata + 12);
|
CHash256 hasher;
|
||||||
for (;;)
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
{
|
ss << *pblock;
|
||||||
// Crypto++ SHA256
|
assert(ss.size() == 80);
|
||||||
// Hash pdata using pmidstate as the starting state into
|
hasher.Write((unsigned char*)&ss[0], 76);
|
||||||
// pre-formatted buffer phash1, then hash phash1 into phash
|
|
||||||
|
for (;;) {
|
||||||
nNonce++;
|
nNonce++;
|
||||||
SHA256Transform(phash1, pdata, pmidstate);
|
|
||||||
SHA256Transform(phash, phash1, pSHA256InitState);
|
// Write the last 4 bytes of the block header (the nonce) to a copy of
|
||||||
|
// the double-SHA256 state, and compute the result.
|
||||||
|
CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash);
|
||||||
|
|
||||||
// Return the nonce if the hash has at least some zero bits,
|
// Return the nonce if the hash has at least some zero bits,
|
||||||
// caller will check if it has enough to reach the target
|
// caller will check if it has enough to reach the target
|
||||||
if (((unsigned short*)phash)[14] == 0)
|
if (((uint16_t*)phash)[15] == 0)
|
||||||
return nNonce;
|
return true;
|
||||||
|
|
||||||
// If nothing found after trying for a while, return -1
|
// If nothing found after trying for a while, return -1
|
||||||
if ((nNonce & 0xffff) == 0)
|
if ((nNonce & 0xffff) == 0)
|
||||||
{
|
return false;
|
||||||
nHashesDone = 0xffff+1;
|
|
||||||
return (unsigned int) -1;
|
|
||||||
}
|
|
||||||
if ((nNonce & 0xfff) == 0)
|
if ((nNonce & 0xfff) == 0)
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
}
|
}
|
||||||
|
@ -538,46 +458,27 @@ void static BitcoinMiner(CWallet *pwallet)
|
||||||
LogPrintf("Running BitcoinMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
|
LogPrintf("Running BitcoinMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
|
||||||
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
|
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
|
||||||
|
|
||||||
//
|
|
||||||
// Pre-build hash buffers
|
|
||||||
//
|
|
||||||
char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf);
|
|
||||||
char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf);
|
|
||||||
char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf);
|
|
||||||
|
|
||||||
FormatHashBuffers(pblock, pmidstate, pdata, phash1);
|
|
||||||
|
|
||||||
unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
|
|
||||||
unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8);
|
|
||||||
unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Search
|
// Search
|
||||||
//
|
//
|
||||||
int64_t nStart = GetTime();
|
int64_t nStart = GetTime();
|
||||||
uint256 hashTarget = uint256().SetCompact(pblock->nBits);
|
uint256 hashTarget = uint256().SetCompact(pblock->nBits);
|
||||||
uint256 hashbuf[2];
|
uint256 hash;
|
||||||
uint256& hash = *alignup<16>(hashbuf);
|
uint32_t nNonce = 0;
|
||||||
|
uint32_t nOldNonce = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
unsigned int nHashesDone = 0;
|
bool fFound = ScanHash(pblock, nNonce, &hash);
|
||||||
unsigned int nNonceFound;
|
uint32_t nHashesDone = nNonce - nOldNonce;
|
||||||
|
nOldNonce = nNonce;
|
||||||
// Crypto++ SHA256
|
|
||||||
nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1,
|
|
||||||
(char*)&hash, nHashesDone);
|
|
||||||
|
|
||||||
// Check if something found
|
// Check if something found
|
||||||
if (nNonceFound != (unsigned int) -1)
|
if (fFound)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < sizeof(hash)/4; i++)
|
|
||||||
((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
|
|
||||||
|
|
||||||
if (hash <= hashTarget)
|
if (hash <= hashTarget)
|
||||||
{
|
{
|
||||||
// Found a solution
|
// Found a solution
|
||||||
pblock->nNonce = ByteReverse(nNonceFound);
|
pblock->nNonce = nNonce;
|
||||||
assert(hash == pblock->GetHash());
|
assert(hash == pblock->GetHash());
|
||||||
|
|
||||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||||
|
@ -626,7 +527,7 @@ void static BitcoinMiner(CWallet *pwallet)
|
||||||
// Regtest mode doesn't require peers
|
// Regtest mode doesn't require peers
|
||||||
if (vNodes.empty() && Params().MiningRequiresPeers())
|
if (vNodes.empty() && Params().MiningRequiresPeers())
|
||||||
break;
|
break;
|
||||||
if (nBlockNonce >= 0xffff0000)
|
if (nNonce >= 0xffff0000)
|
||||||
break;
|
break;
|
||||||
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
|
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
|
||||||
break;
|
break;
|
||||||
|
@ -635,11 +536,9 @@ void static BitcoinMiner(CWallet *pwallet)
|
||||||
|
|
||||||
// Update nTime every few seconds
|
// Update nTime every few seconds
|
||||||
UpdateTime(*pblock, pindexPrev);
|
UpdateTime(*pblock, pindexPrev);
|
||||||
nBlockTime = ByteReverse(pblock->nTime);
|
|
||||||
if (Params().AllowMinDifficultyBlocks())
|
if (Params().AllowMinDifficultyBlocks())
|
||||||
{
|
{
|
||||||
// Changing pblock->nTime can change work required on testnet:
|
// Changing pblock->nTime can change work required on testnet:
|
||||||
nBlockBits = ByteReverse(pblock->nBits);
|
|
||||||
hashTarget.SetCompact(pblock->nBits);
|
hashTarget.SetCompact(pblock->nBits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
|
||||||
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
|
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
|
||||||
/** Modify the extranonce in a block */
|
/** Modify the extranonce in a block */
|
||||||
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
|
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
|
||||||
/** Do mining precalculation */
|
|
||||||
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
|
|
||||||
/** Check mined block */
|
/** Check mined block */
|
||||||
bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
|
bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
|
||||||
/** Base sha256 mining transform */
|
|
||||||
void SHA256Transform(void* pstate, void* pinput, const void* pinit);
|
|
||||||
|
|
||||||
extern double dHashesPerSec;
|
extern double dHashesPerSec;
|
||||||
extern int64_t nHPSTimerStart;
|
extern int64_t nHPSTimerStart;
|
||||||
|
|
|
@ -24,36 +24,6 @@
|
||||||
using namespace json_spirit;
|
using namespace json_spirit;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
// Key used by getwork miners.
|
|
||||||
// Allocated in InitRPCMining, free'd in ShutdownRPCMining
|
|
||||||
static CReserveKey* pMiningKey = NULL;
|
|
||||||
|
|
||||||
void InitRPCMining()
|
|
||||||
{
|
|
||||||
if (!pwalletMain)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// getwork/getblocktemplate mining rewards paid here:
|
|
||||||
pMiningKey = new CReserveKey(pwalletMain);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShutdownRPCMining()
|
|
||||||
{
|
|
||||||
if (!pMiningKey)
|
|
||||||
return;
|
|
||||||
|
|
||||||
delete pMiningKey; pMiningKey = NULL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void InitRPCMining()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void ShutdownRPCMining()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Return average network hashes per second based on the last 'lookup' blocks,
|
// Return average network hashes per second based on the last 'lookup' blocks,
|
||||||
// or from the last difficulty change if 'lookup' is nonpositive.
|
// or from the last difficulty change if 'lookup' is nonpositive.
|
||||||
// If 'height' is nonnegative, compute the estimate at the time when a given block was found.
|
// If 'height' is nonnegative, compute the estimate at the time when a given block was found.
|
||||||
|
@ -131,9 +101,6 @@ Value getgenerate(const Array& params, bool fHelp)
|
||||||
+ HelpExampleRpc("getgenerate", "")
|
+ HelpExampleRpc("getgenerate", "")
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!pMiningKey)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return GetBoolArg("-gen", false);
|
return GetBoolArg("-gen", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,132 +246,6 @@ Value getmininginfo(const Array& params, bool fHelp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
Value getwork(const Array& params, bool fHelp)
|
|
||||||
{
|
|
||||||
if (fHelp || params.size() > 1)
|
|
||||||
throw runtime_error(
|
|
||||||
"getwork ( \"data\" )\n"
|
|
||||||
"\nIf 'data' is not specified, it returns the formatted hash data to work on.\n"
|
|
||||||
"If 'data' is specified, tries to solve the block and returns true if it was successful.\n"
|
|
||||||
"\nArguments:\n"
|
|
||||||
"1. \"data\" (string, optional) The hex encoded data to solve\n"
|
|
||||||
"\nResult (when 'data' is not specified):\n"
|
|
||||||
"{\n"
|
|
||||||
" \"midstate\" : \"xxxx\", (string) The precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
|
|
||||||
" \"data\" : \"xxxxx\", (string) The block data\n"
|
|
||||||
" \"hash1\" : \"xxxxx\", (string) The formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
|
|
||||||
" \"target\" : \"xxxx\" (string) The little endian hash target\n"
|
|
||||||
"}\n"
|
|
||||||
"\nResult (when 'data' is specified):\n"
|
|
||||||
"true|false (boolean) If solving the block specified in the 'data' was successfull\n"
|
|
||||||
"\nExamples:\n"
|
|
||||||
+ HelpExampleCli("getwork", "")
|
|
||||||
+ HelpExampleRpc("getwork", "")
|
|
||||||
);
|
|
||||||
|
|
||||||
if (vNodes.empty())
|
|
||||||
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
|
|
||||||
|
|
||||||
if (IsInitialBlockDownload())
|
|
||||||
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
|
|
||||||
|
|
||||||
typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
|
|
||||||
static mapNewBlock_t mapNewBlock; // FIXME: thread safety
|
|
||||||
static vector<CBlockTemplate*> vNewBlockTemplate;
|
|
||||||
|
|
||||||
if (params.size() == 0)
|
|
||||||
{
|
|
||||||
// Update block
|
|
||||||
static unsigned int nTransactionsUpdatedLast;
|
|
||||||
static CBlockIndex* pindexPrev;
|
|
||||||
static int64_t nStart;
|
|
||||||
static CBlockTemplate* pblocktemplate;
|
|
||||||
if (pindexPrev != chainActive.Tip() ||
|
|
||||||
(mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60))
|
|
||||||
{
|
|
||||||
if (pindexPrev != chainActive.Tip())
|
|
||||||
{
|
|
||||||
// Deallocate old blocks since they're obsolete now
|
|
||||||
mapNewBlock.clear();
|
|
||||||
BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate)
|
|
||||||
delete pblocktemplate;
|
|
||||||
vNewBlockTemplate.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear pindexPrev so future getworks make a new block, despite any failures from here on
|
|
||||||
pindexPrev = NULL;
|
|
||||||
|
|
||||||
// Store the pindexBest used before CreateNewBlock, to avoid races
|
|
||||||
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
|
|
||||||
CBlockIndex* pindexPrevNew = chainActive.Tip();
|
|
||||||
nStart = GetTime();
|
|
||||||
|
|
||||||
// Create new block
|
|
||||||
pblocktemplate = CreateNewBlockWithKey(*pMiningKey);
|
|
||||||
if (!pblocktemplate)
|
|
||||||
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
|
||||||
vNewBlockTemplate.push_back(pblocktemplate);
|
|
||||||
|
|
||||||
// Need to update only after we know CreateNewBlock succeeded
|
|
||||||
pindexPrev = pindexPrevNew;
|
|
||||||
}
|
|
||||||
CBlock* pblock = &pblocktemplate->block; // pointer for convenience
|
|
||||||
|
|
||||||
// Update nTime
|
|
||||||
UpdateTime(*pblock, pindexPrev);
|
|
||||||
pblock->nNonce = 0;
|
|
||||||
|
|
||||||
// Update nExtraNonce
|
|
||||||
static unsigned int nExtraNonce = 0;
|
|
||||||
IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
|
|
||||||
|
|
||||||
// Save
|
|
||||||
mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
|
|
||||||
|
|
||||||
// Pre-build hash buffers
|
|
||||||
char pmidstate[32];
|
|
||||||
char pdata[128];
|
|
||||||
char phash1[64];
|
|
||||||
FormatHashBuffers(pblock, pmidstate, pdata, phash1);
|
|
||||||
|
|
||||||
uint256 hashTarget = uint256().SetCompact(pblock->nBits);
|
|
||||||
|
|
||||||
Object result;
|
|
||||||
result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
|
|
||||||
result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata))));
|
|
||||||
result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated
|
|
||||||
result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget))));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Parse parameters
|
|
||||||
vector<unsigned char> vchData = ParseHex(params[0].get_str());
|
|
||||||
if (vchData.size() != 128)
|
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
|
|
||||||
CBlock* pdata = (CBlock*)&vchData[0];
|
|
||||||
|
|
||||||
// Byte reverse
|
|
||||||
for (int i = 0; i < 128/4; i++)
|
|
||||||
((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
|
|
||||||
|
|
||||||
// Get saved block
|
|
||||||
if (!mapNewBlock.count(pdata->hashMerkleRoot))
|
|
||||||
return false;
|
|
||||||
CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
|
|
||||||
|
|
||||||
pblock->nTime = pdata->nTime;
|
|
||||||
pblock->nNonce = pdata->nNonce;
|
|
||||||
pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
|
|
||||||
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
|
||||||
|
|
||||||
assert(pwalletMain != NULL);
|
|
||||||
return CheckWork(pblock, *pwalletMain, *pMiningKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Value getblocktemplate(const Array& params, bool fHelp)
|
Value getblocktemplate(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() > 1)
|
if (fHelp || params.size() > 1)
|
||||||
|
|
|
@ -315,7 +315,6 @@ static const CRPCCommand vRPCCommands[] =
|
||||||
/* Wallet-enabled mining */
|
/* Wallet-enabled mining */
|
||||||
{ "getgenerate", &getgenerate, true, false, false },
|
{ "getgenerate", &getgenerate, true, false, false },
|
||||||
{ "gethashespersec", &gethashespersec, true, false, false },
|
{ "gethashespersec", &gethashespersec, true, false, false },
|
||||||
{ "getwork", &getwork, true, false, true },
|
|
||||||
{ "setgenerate", &setgenerate, true, true, false },
|
{ "setgenerate", &setgenerate, true, true, false },
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
};
|
};
|
||||||
|
@ -772,7 +771,7 @@ void JSONRequest::parse(const Value& valRequest)
|
||||||
if (valMethod.type() != str_type)
|
if (valMethod.type() != str_type)
|
||||||
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
|
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
|
||||||
strMethod = valMethod.get_str();
|
strMethod = valMethod.get_str();
|
||||||
if (strMethod != "getwork" && strMethod != "getblocktemplate")
|
if (strMethod != "getblocktemplate")
|
||||||
LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod);
|
LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod);
|
||||||
|
|
||||||
// Parse params
|
// Parse params
|
||||||
|
|
|
@ -130,7 +130,6 @@ extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHe
|
||||||
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp);
|
|
||||||
extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "keystore.h"
|
#include "keystore.h"
|
||||||
|
#include "crypto/sha1.h"
|
||||||
|
#include "crypto/sha2.h"
|
||||||
|
#include "crypto/ripemd160.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -801,21 +804,15 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||||
valtype& vch = stacktop(-1);
|
valtype& vch = stacktop(-1);
|
||||||
valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
|
valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
|
||||||
if (opcode == OP_RIPEMD160)
|
if (opcode == OP_RIPEMD160)
|
||||||
RIPEMD160(&vch[0], vch.size(), &vchHash[0]);
|
CRIPEMD160().Write(&vch[0], vch.size()).Finalize(&vchHash[0]);
|
||||||
else if (opcode == OP_SHA1)
|
else if (opcode == OP_SHA1)
|
||||||
SHA1(&vch[0], vch.size(), &vchHash[0]);
|
CSHA1().Write(&vch[0], vch.size()).Finalize(&vchHash[0]);
|
||||||
else if (opcode == OP_SHA256)
|
else if (opcode == OP_SHA256)
|
||||||
SHA256(&vch[0], vch.size(), &vchHash[0]);
|
CSHA256().Write(&vch[0], vch.size()).Finalize(&vchHash[0]);
|
||||||
else if (opcode == OP_HASH160)
|
else if (opcode == OP_HASH160)
|
||||||
{
|
CHash160().Write(&vch[0], vch.size()).Finalize(&vchHash[0]);
|
||||||
uint160 hash160 = Hash160(vch);
|
|
||||||
memcpy(&vchHash[0], &hash160, sizeof(hash160));
|
|
||||||
}
|
|
||||||
else if (opcode == OP_HASH256)
|
else if (opcode == OP_HASH256)
|
||||||
{
|
CHash256().Write(&vch[0], vch.size()).Finalize(&vchHash[0]);
|
||||||
uint256 hash = Hash(vch.begin(), vch.end());
|
|
||||||
memcpy(&vchHash[0], &hash, sizeof(hash));
|
|
||||||
}
|
|
||||||
popstack(stack);
|
popstack(stack);
|
||||||
stack.push_back(vchHash);
|
stack.push_back(vchHash);
|
||||||
}
|
}
|
||||||
|
|
203
src/test/crypto_tests.cpp
Normal file
203
src/test/crypto_tests.cpp
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "crypto/ripemd160.h"
|
||||||
|
#include "crypto/sha1.h"
|
||||||
|
#include "crypto/sha2.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(crypto_tests)
|
||||||
|
|
||||||
|
template<typename Hasher, typename In, typename Out>
|
||||||
|
void TestVector(const Hasher &h, const In &in, const Out &out) {
|
||||||
|
Out hash;
|
||||||
|
BOOST_CHECK(out.size() == h.OUTPUT_SIZE);
|
||||||
|
hash.resize(out.size());
|
||||||
|
{
|
||||||
|
// Test that writing the whole input string at once works.
|
||||||
|
Hasher(h).Write((unsigned char*)&in[0], in.size()).Finalize(&hash[0]);
|
||||||
|
BOOST_CHECK(hash == out);
|
||||||
|
}
|
||||||
|
for (int i=0; i<32; i++) {
|
||||||
|
// Test that writing the string broken up in random pieces works.
|
||||||
|
Hasher hasher(h);
|
||||||
|
size_t pos = 0;
|
||||||
|
while (pos < in.size()) {
|
||||||
|
size_t len = insecure_rand() % ((in.size() - pos + 1) / 2 + 1);
|
||||||
|
hasher.Write((unsigned char*)&in[pos], len);
|
||||||
|
pos += len;
|
||||||
|
if (pos > 0 && pos + 2 * out.size() > in.size()) {
|
||||||
|
// Test that writing the rest at once to a copy of a hasher works.
|
||||||
|
Hasher(hasher).Write((unsigned char*)&in[pos], in.size() - pos).Finalize(&hash[0]);
|
||||||
|
BOOST_CHECK(hash == out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hasher.Finalize(&hash[0]);
|
||||||
|
BOOST_CHECK(hash == out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSHA1(const std::string &in, const std::string &hexout) { TestVector(CSHA1(), in, ParseHex(hexout));}
|
||||||
|
void TestSHA256(const std::string &in, const std::string &hexout) { TestVector(CSHA256(), in, ParseHex(hexout));}
|
||||||
|
void TestSHA512(const std::string &in, const std::string &hexout) { TestVector(CSHA512(), in, ParseHex(hexout));}
|
||||||
|
void TestRIPEMD160(const std::string &in, const std::string &hexout) { TestVector(CRIPEMD160(), in, ParseHex(hexout));}
|
||||||
|
|
||||||
|
void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
|
||||||
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
||||||
|
TestVector(CHMAC_SHA512(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LongTestString(void) {
|
||||||
|
std::string ret;
|
||||||
|
for (int i=0; i<200000; i++) {
|
||||||
|
ret += (unsigned char)(i);
|
||||||
|
ret += (unsigned char)(i >> 4);
|
||||||
|
ret += (unsigned char)(i >> 8);
|
||||||
|
ret += (unsigned char)(i >> 12);
|
||||||
|
ret += (unsigned char)(i >> 16);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string test1 = LongTestString();
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(ripemd160_testvectors) {
|
||||||
|
TestRIPEMD160("", "9c1185a5c5e9fc54612808977ee8f548b2258d31");
|
||||||
|
TestRIPEMD160("abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
|
||||||
|
TestRIPEMD160("message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36");
|
||||||
|
TestRIPEMD160("secure hash algorithm", "20397528223b6a5f4cbc2808aba0464e645544f9");
|
||||||
|
TestRIPEMD160("RIPEMD160 is considered to be safe", "a7d78608c7af8a8e728778e81576870734122b66");
|
||||||
|
TestRIPEMD160("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||||
|
"12a053384a9c0c88e405a06c27dcf49ada62eb2b");
|
||||||
|
TestRIPEMD160("For this sample, this 63-byte string will be used as input data",
|
||||||
|
"de90dbfee14b63fb5abf27c2ad4a82aaa5f27a11");
|
||||||
|
TestRIPEMD160("This is exactly 64 bytes long, not counting the terminating byte",
|
||||||
|
"eda31d51d3a623b81e19eb02e24ff65d27d67b37");
|
||||||
|
TestRIPEMD160(std::string(1000000, 'a'), "52783243c1697bdbe16d37f97f68f08325dc1528");
|
||||||
|
TestRIPEMD160(test1, "464243587bd146ea835cdf57bdae582f25ec45f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(sha1_testvectors) {
|
||||||
|
TestSHA1("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
|
||||||
|
TestSHA1("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
|
||||||
|
TestSHA1("message digest", "c12252ceda8be8994d5fa0290a47231c1d16aae3");
|
||||||
|
TestSHA1("secure hash algorithm", "d4d6d2f0ebe317513bbd8d967d89bac5819c2f60");
|
||||||
|
TestSHA1("SHA1 is considered to be safe", "f2b6650569ad3a8720348dd6ea6c497dee3a842a");
|
||||||
|
TestSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||||
|
"84983e441c3bd26ebaae4aa1f95129e5e54670f1");
|
||||||
|
TestSHA1("For this sample, this 63-byte string will be used as input data",
|
||||||
|
"4f0ea5cd0585a23d028abdc1a6684e5a8094dc49");
|
||||||
|
TestSHA1("This is exactly 64 bytes long, not counting the terminating byte",
|
||||||
|
"fb679f23e7d1ce053313e66e127ab1b444397057");
|
||||||
|
TestSHA1(std::string(1000000, 'a'), "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
|
||||||
|
TestSHA1(test1, "b7755760681cbfd971451668f32af5774f4656b5");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(sha256_testvectors) {
|
||||||
|
TestSHA256("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
||||||
|
TestSHA256("abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
|
||||||
|
TestSHA256("message digest",
|
||||||
|
"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650");
|
||||||
|
TestSHA256("secure hash algorithm",
|
||||||
|
"f30ceb2bb2829e79e4ca9753d35a8ecc00262d164cc077080295381cbd643f0d");
|
||||||
|
TestSHA256("SHA256 is considered to be safe",
|
||||||
|
"6819d915c73f4d1e77e4e1b52d1fa0f9cf9beaead3939f15874bd988e2a23630");
|
||||||
|
TestSHA256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||||
|
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
|
||||||
|
TestSHA256("For this sample, this 63-byte string will be used as input data",
|
||||||
|
"f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342");
|
||||||
|
TestSHA256("This is exactly 64 bytes long, not counting the terminating byte",
|
||||||
|
"ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8");
|
||||||
|
TestSHA256("As Bitcoin relies on 80 byte header hashes, we want to have an example for that.",
|
||||||
|
"7406e8de7d6e4fffc573daef05aefb8806e7790f55eab5576f31349743cca743");
|
||||||
|
TestSHA256(std::string(1000000, 'a'),
|
||||||
|
"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
|
||||||
|
TestSHA256(test1, "a316d55510b49662420f49d145d42fb83f31ef8dc016aa4e32df049991a91e26");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(sha512_testvectors) {
|
||||||
|
TestSHA512("",
|
||||||
|
"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
|
||||||
|
"47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
|
||||||
|
TestSHA512("abc",
|
||||||
|
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
|
||||||
|
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
|
||||||
|
TestSHA512("message digest",
|
||||||
|
"107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f33"
|
||||||
|
"09e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c");
|
||||||
|
TestSHA512("secure hash algorithm",
|
||||||
|
"7746d91f3de30c68cec0dd693120a7e8b04d8073cb699bdce1a3f64127bca7a3"
|
||||||
|
"d5db502e814bb63c063a7a5043b2df87c61133395f4ad1edca7fcf4b30c3236e");
|
||||||
|
TestSHA512("SHA512 is considered to be safe",
|
||||||
|
"099e6468d889e1c79092a89ae925a9499b5408e01b66cb5b0a3bd0dfa51a9964"
|
||||||
|
"6b4a3901caab1318189f74cd8cf2e941829012f2449df52067d3dd5b978456c2");
|
||||||
|
TestSHA512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||||
|
"204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335"
|
||||||
|
"96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445");
|
||||||
|
TestSHA512("For this sample, this 63-byte string will be used as input data",
|
||||||
|
"b3de4afbc516d2478fe9b518d063bda6c8dd65fc38402dd81d1eb7364e72fb6e"
|
||||||
|
"6663cf6d2771c8f5a6da09601712fb3d2a36c6ffea3e28b0818b05b0a8660766");
|
||||||
|
TestSHA512("This is exactly 64 bytes long, not counting the terminating byte",
|
||||||
|
"70aefeaa0e7ac4f8fe17532d7185a289bee3b428d950c14fa8b713ca09814a38"
|
||||||
|
"7d245870e007a80ad97c369d193e41701aa07f3221d15f0e65a1ff970cedf030");
|
||||||
|
TestSHA512("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"
|
||||||
|
"ijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
||||||
|
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
|
||||||
|
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909");
|
||||||
|
TestSHA512(std::string(1000000, 'a'),
|
||||||
|
"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
|
||||||
|
"de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b");
|
||||||
|
TestSHA512(test1,
|
||||||
|
"40cac46c147e6131c5193dd5f34e9d8bb4951395f27b08c558c65ff4ba2de594"
|
||||||
|
"37de8c3ef5459d76a52cedc02dc499a3c9ed9dedbfb3281afd9653b8a112fafc");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) {
|
||||||
|
// test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
|
||||||
|
TestHMACSHA512("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
|
||||||
|
"4869205468657265",
|
||||||
|
"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cde"
|
||||||
|
"daa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854");
|
||||||
|
TestHMACSHA512("4a656665",
|
||||||
|
"7768617420646f2079612077616e7420666f72206e6f7468696e673f",
|
||||||
|
"164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554"
|
||||||
|
"9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737");
|
||||||
|
TestHMACSHA512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
|
||||||
|
"dddddddddddddddddddddddddddddddddddd",
|
||||||
|
"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
|
||||||
|
"bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb");
|
||||||
|
TestHMACSHA512("0102030405060708090a0b0c0d0e0f10111213141516171819",
|
||||||
|
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
|
||||||
|
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
|
||||||
|
"b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3db"
|
||||||
|
"a91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd");
|
||||||
|
TestHMACSHA512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
"aaaaaa",
|
||||||
|
"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a"
|
||||||
|
"65204b6579202d2048617368204b6579204669727374",
|
||||||
|
"80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f352"
|
||||||
|
"6b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598");
|
||||||
|
TestHMACSHA512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
"aaaaaa",
|
||||||
|
"5468697320697320612074657374207573696e672061206c6172676572207468"
|
||||||
|
"616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074"
|
||||||
|
"68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565"
|
||||||
|
"647320746f20626520686173686564206265666f7265206265696e6720757365"
|
||||||
|
"642062792074686520484d414320616c676f726974686d2e",
|
||||||
|
"e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944"
|
||||||
|
"b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
|
@ -1,129 +0,0 @@
|
||||||
// Copyright (c) 2013 The Bitcoin Core developers
|
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
||||||
|
|
||||||
#include "hash.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(hmac_tests)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *pszKey;
|
|
||||||
const char *pszData;
|
|
||||||
const char *pszMAC;
|
|
||||||
} testvec_t;
|
|
||||||
|
|
||||||
// test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
|
|
||||||
static const testvec_t vtest[] = {
|
|
||||||
{
|
|
||||||
"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
|
|
||||||
"0b0b0b0b",
|
|
||||||
"4869205468657265",
|
|
||||||
"87aa7cdea5ef619d4ff0b4241a1d6cb0"
|
|
||||||
"2379f4e2ce4ec2787ad0b30545e17cde"
|
|
||||||
"daa833b7d6b8a702038b274eaea3f4e4"
|
|
||||||
"be9d914eeb61f1702e696c203a126854"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"4a656665",
|
|
||||||
"7768617420646f2079612077616e7420"
|
|
||||||
"666f72206e6f7468696e673f",
|
|
||||||
"164b7a7bfcf819e2e395fbe73b56e0a3"
|
|
||||||
"87bd64222e831fd610270cd7ea250554"
|
|
||||||
"9758bf75c05a994a6d034f65f8f0e6fd"
|
|
||||||
"caeab1a34d4a6b4b636e070a38bce737"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaa",
|
|
||||||
"dddddddddddddddddddddddddddddddd"
|
|
||||||
"dddddddddddddddddddddddddddddddd"
|
|
||||||
"dddddddddddddddddddddddddddddddd"
|
|
||||||
"dddd",
|
|
||||||
"fa73b0089d56a284efb0f0756c890be9"
|
|
||||||
"b1b5dbdd8ee81a3655f83e33b2279d39"
|
|
||||||
"bf3e848279a722c806b485a47e67c807"
|
|
||||||
"b946a337bee8942674278859e13292fb"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"0102030405060708090a0b0c0d0e0f10"
|
|
||||||
"111213141516171819",
|
|
||||||
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
|
|
||||||
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
|
|
||||||
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
|
|
||||||
"cdcd",
|
|
||||||
"b0ba465637458c6990e5a8c5f61d4af7"
|
|
||||||
"e576d97ff94b872de76f8050361ee3db"
|
|
||||||
"a91ca5c11aa25eb4d679275cc5788063"
|
|
||||||
"a5f19741120c4f2de2adebeb10a298dd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaa",
|
|
||||||
"54657374205573696e67204c61726765"
|
|
||||||
"72205468616e20426c6f636b2d53697a"
|
|
||||||
"65204b6579202d2048617368204b6579"
|
|
||||||
"204669727374",
|
|
||||||
"80b24263c7c1a3ebb71493c1dd7be8b4"
|
|
||||||
"9b46d1f41b4aeec1121b013783f8f352"
|
|
||||||
"6b56d037e05f2598bd0fd2215d6a1e52"
|
|
||||||
"95e64f73f63f0aec8b915a985d786598"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
||||||
"aaaaaa",
|
|
||||||
"54686973206973206120746573742075"
|
|
||||||
"73696e672061206c6172676572207468"
|
|
||||||
"616e20626c6f636b2d73697a65206b65"
|
|
||||||
"7920616e642061206c61726765722074"
|
|
||||||
"68616e20626c6f636b2d73697a652064"
|
|
||||||
"6174612e20546865206b6579206e6565"
|
|
||||||
"647320746f2062652068617368656420"
|
|
||||||
"6265666f7265206265696e6720757365"
|
|
||||||
"642062792074686520484d414320616c"
|
|
||||||
"676f726974686d2e",
|
|
||||||
"e37b6a775dc87dbaa4dfa9f96e5e3ffd"
|
|
||||||
"debd71f8867289865df5a32d20cdc944"
|
|
||||||
"b6022cac3c4982b10d5eeb55c3e4de15"
|
|
||||||
"134676fb6de0446065c97440fa8c6a58"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(hmacsha512_testvectors)
|
|
||||||
{
|
|
||||||
for (unsigned int n=0; n<sizeof(vtest)/sizeof(vtest[0]); n++)
|
|
||||||
{
|
|
||||||
vector<unsigned char> vchKey = ParseHex(vtest[n].pszKey);
|
|
||||||
vector<unsigned char> vchData = ParseHex(vtest[n].pszData);
|
|
||||||
vector<unsigned char> vchMAC = ParseHex(vtest[n].pszMAC);
|
|
||||||
unsigned char vchTemp[64];
|
|
||||||
|
|
||||||
HMAC_SHA512_CTX ctx;
|
|
||||||
HMAC_SHA512_Init(&ctx, &vchKey[0], vchKey.size());
|
|
||||||
HMAC_SHA512_Update(&ctx, &vchData[0], vchData.size());
|
|
||||||
HMAC_SHA512_Final(&vchTemp[0], &ctx);
|
|
||||||
|
|
||||||
BOOST_CHECK(memcmp(&vchTemp[0], &vchMAC[0], 64) == 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
extern void SHA256Transform(void* pstate, void* pinput, const void* pinit);
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(miner_tests)
|
BOOST_AUTO_TEST_SUITE(miner_tests)
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -259,30 +257,4 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(sha256transform_equality)
|
|
||||||
{
|
|
||||||
unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
|
|
||||||
|
|
||||||
|
|
||||||
// unsigned char pstate[32];
|
|
||||||
unsigned char pinput[64];
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
|
||||||
pinput[i] = i;
|
|
||||||
pinput[i+32] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint256 hash;
|
|
||||||
|
|
||||||
SHA256Transform(&hash, pinput, pSHA256InitState);
|
|
||||||
|
|
||||||
BOOST_TEST_MESSAGE(hash.GetHex());
|
|
||||||
|
|
||||||
uint256 hash_reference("0x2df5e1c65ef9f8cde240d23cae2ec036d31a15ec64bc68f64be242b1da6631f3");
|
|
||||||
|
|
||||||
BOOST_CHECK(hash == hash_reference);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Add table
Reference in a new issue