r1
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: false
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackParameters: false
|
||||
BreakBeforeBinaryOperators: false
|
||||
BreakBeforeBraces: Linux
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
ColumnLimit: 0
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, BOOST_REVERSE_FOREACH ]
|
||||
IndentCaseLabels: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
IndentWidth: 4
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: None
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
Standard: Cpp03
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
+599
@@ -0,0 +1,599 @@
|
||||
# Copyright (c) 2013-2016 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
DIST_SUBDIRS = secp256k1 univalue
|
||||
|
||||
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS)
|
||||
AM_CXXFLAGS = $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(WARN_CXXFLAGS) $(NOWARN_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS)
|
||||
AM_CPPFLAGS = $(DEBUG_CPPFLAGS) $(HARDENED_CPPFLAGS)
|
||||
AM_LIBTOOLFLAGS = --preserve-dup-deps
|
||||
EXTRA_LIBRARIES =
|
||||
|
||||
if EMBEDDED_UNIVALUE
|
||||
LIBUNIVALUE = univalue/libunivalue.la
|
||||
|
||||
$(LIBUNIVALUE): $(wildcard univalue/lib/*) $(wildcard univalue/include/*)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
|
||||
else
|
||||
LIBUNIVALUE = $(UNIVALUE_LIBS)
|
||||
endif
|
||||
|
||||
BITCOIN_INCLUDES=-I$(builddir) $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
|
||||
|
||||
BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
|
||||
BITCOIN_INCLUDES += $(UNIVALUE_CFLAGS)
|
||||
|
||||
LIBBITCOIN_SERVER=libbitcoin_server.a
|
||||
LIBBITCOIN_COMMON=libbitcoin_common.a
|
||||
LIBBITCOIN_CLI=libbitcoin_cli.a
|
||||
LIBBITCOIN_UTIL=libbitcoin_util.a
|
||||
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
|
||||
LIBBITCOIN_ZEROCOIN=libzerocoin/libbitcoin_zerocoin.a
|
||||
LIBBITCOINQT=qt/libbitcoinqt.a
|
||||
LIBSECP256K1=secp256k1/libsecp256k1.la
|
||||
|
||||
if ENABLE_ZMQ
|
||||
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
|
||||
endif
|
||||
if BUILD_BITCOIN_LIBS
|
||||
LIBBITCOINCONSENSUS=libbitcoinconsensus.la
|
||||
endif
|
||||
if ENABLE_WALLET
|
||||
LIBBITCOIN_WALLET=libbitcoin_wallet.a
|
||||
endif
|
||||
|
||||
$(LIBSECP256K1): $(wildcard secp256k1/src/*.h) $(wildcard secp256k1/src/*.c) $(wildcard secp256k1/include/*)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
|
||||
|
||||
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
|
||||
# But to build the less dependent modules first, we manually select their order here:
|
||||
EXTRA_LIBRARIES += \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBBITCOIN_ZEROCOIN) \
|
||||
$(LIBBITCOIN_SERVER) \
|
||||
$(LIBBITCOIN_CLI) \
|
||||
$(LIBBITCOIN_WALLET) \
|
||||
$(LIBBITCOIN_ZMQ)
|
||||
|
||||
lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS)
|
||||
|
||||
bin_PROGRAMS =
|
||||
noinst_PROGRAMS =
|
||||
TESTS =
|
||||
BENCHMARKS =
|
||||
|
||||
if BUILD_BITCOIND
|
||||
bin_PROGRAMS += agrariand
|
||||
endif
|
||||
|
||||
if BUILD_BITCOIN_UTILS
|
||||
bin_PROGRAMS += agrarian-cli agrarian-tx
|
||||
endif
|
||||
|
||||
.PHONY: FORCE check-symbols check-security
|
||||
# agrarian core #
|
||||
BITCOIN_CORE_H = \
|
||||
activemasternode.h \
|
||||
addrman.h \
|
||||
alert.h \
|
||||
allocators.h \
|
||||
amount.h \
|
||||
base58.h \
|
||||
bip38.h \
|
||||
bloom.h \
|
||||
blocksignature.h \
|
||||
chain.h \
|
||||
chainparams.h \
|
||||
chainparamsbase.h \
|
||||
chainparamsseeds.h \
|
||||
checkpoints.h \
|
||||
checkqueue.h \
|
||||
clientversion.h \
|
||||
coincontrol.h \
|
||||
coins.h \
|
||||
compat.h \
|
||||
compat/byteswap.h \
|
||||
compat/endian.h \
|
||||
compat/sanity.h \
|
||||
compressor.h \
|
||||
primitives/block.h \
|
||||
primitives/transaction.h \
|
||||
core_io.h \
|
||||
crypter.h \
|
||||
denomination_functions.h \
|
||||
obfuscation.h \
|
||||
obfuscation-relay.h \
|
||||
wallet/db.h \
|
||||
hash.h \
|
||||
httprpc.h \
|
||||
httpserver.h \
|
||||
init.h \
|
||||
invalid.h \
|
||||
invalid_outpoints.json.h \
|
||||
invalid_serials.json.h \
|
||||
kernel.h \
|
||||
swifttx.h \
|
||||
key.h \
|
||||
keystore.h \
|
||||
leveldbwrapper.h \
|
||||
limitedmap.h \
|
||||
main.h \
|
||||
masternode.h \
|
||||
masternode-payments.h \
|
||||
masternode-budget.h \
|
||||
masternode-sync.h \
|
||||
masternodeman.h \
|
||||
masternodeconfig.h \
|
||||
merkleblock.h \
|
||||
miner.h \
|
||||
mruset.h \
|
||||
netbase.h \
|
||||
net.h \
|
||||
noui.h \
|
||||
pow.h \
|
||||
protocol.h \
|
||||
pubkey.h \
|
||||
random.h \
|
||||
reverselock.h \
|
||||
reverse_iterate.h \
|
||||
rpc/client.h \
|
||||
rpc/protocol.h \
|
||||
rpc/server.h \
|
||||
scheduler.h \
|
||||
script/interpreter.h \
|
||||
script/script.h \
|
||||
script/sigcache.h \
|
||||
script/sign.h \
|
||||
script/standard.h \
|
||||
script/script_error.h \
|
||||
serialize.h \
|
||||
spork.h \
|
||||
sporkdb.h \
|
||||
stakeinput.h \
|
||||
streams.h \
|
||||
support/cleanse.h \
|
||||
sync.h \
|
||||
threadsafety.h \
|
||||
timedata.h \
|
||||
tinyformat.h \
|
||||
torcontrol.h \
|
||||
txdb.h \
|
||||
txmempool.h \
|
||||
guiinterface.h \
|
||||
uint256.h \
|
||||
undo.h \
|
||||
util.h \
|
||||
utilstrencodings.h \
|
||||
utilmoneystr.h \
|
||||
utiltime.h \
|
||||
validationinterface.h \
|
||||
version.h \
|
||||
wallet/wallet.h \
|
||||
wallet/wallet_ismine.h \
|
||||
wallet/walletdb.h \
|
||||
zagrchain.h \
|
||||
zagr/accumulators.h \
|
||||
zagr/accumulatorcheckpoints.h \
|
||||
zagr/accumulatorcheckpoints.json.h \
|
||||
zagr/accumulatormap.h \
|
||||
zagr/deterministicmint.h \
|
||||
zagr/mintpool.h \
|
||||
zagr/witness.h \
|
||||
zagr/zerocoin.h \
|
||||
zagr/zagrtracker.h \
|
||||
zagr/zagrwallet.h \
|
||||
zagr/zagrmodule.h \
|
||||
genwit.h \
|
||||
concurrentqueue.h \
|
||||
lightzagrthread.h \
|
||||
zmq/zmqabstractnotifier.h \
|
||||
zmq/zmqconfig.h \
|
||||
zmq/zmqnotificationinterface.h \
|
||||
zmq/zmqpublishnotifier.h
|
||||
|
||||
obj/build.h: FORCE
|
||||
@$(MKDIR_P) $(builddir)/obj
|
||||
@$(top_srcdir)/share/genbuild.sh "$(abs_top_builddir)/src/obj/build.h" \
|
||||
"$(abs_top_srcdir)"
|
||||
libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
|
||||
|
||||
# server: shared between agrariand and agrarian-qt
|
||||
libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS)
|
||||
libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_server_a_SOURCES = \
|
||||
addrman.cpp \
|
||||
alert.cpp \
|
||||
bloom.cpp \
|
||||
blocksignature.cpp \
|
||||
chain.cpp \
|
||||
checkpoints.cpp \
|
||||
httprpc.cpp \
|
||||
httpserver.cpp \
|
||||
init.cpp \
|
||||
leveldbwrapper.cpp \
|
||||
main.cpp \
|
||||
merkleblock.cpp \
|
||||
miner.cpp \
|
||||
net.cpp \
|
||||
noui.cpp \
|
||||
pow.cpp \
|
||||
rest.cpp \
|
||||
rpc/blockchain.cpp \
|
||||
rpc/masternode.cpp \
|
||||
rpc/budget.cpp \
|
||||
rpc/mining.cpp \
|
||||
rpc/misc.cpp \
|
||||
rpc/net.cpp \
|
||||
rpc/rawtransaction.cpp \
|
||||
rpc/server.cpp \
|
||||
script/sigcache.cpp \
|
||||
sporkdb.cpp \
|
||||
timedata.cpp \
|
||||
torcontrol.cpp \
|
||||
txdb.cpp \
|
||||
txmempool.cpp \
|
||||
validationinterface.cpp \
|
||||
zagrchain.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
if ENABLE_ZMQ
|
||||
libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
|
||||
libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_zmq_a_SOURCES = \
|
||||
zmq/zmqabstractnotifier.cpp \
|
||||
zmq/zmqnotificationinterface.cpp \
|
||||
zmq/zmqpublishnotifier.cpp
|
||||
endif
|
||||
|
||||
# wallet: shared between agrariand and agrarian-qt, but only linked
|
||||
# when wallet enabled
|
||||
libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_wallet_a_SOURCES = \
|
||||
activemasternode.cpp \
|
||||
bip38.cpp \
|
||||
denomination_functions.cpp \
|
||||
obfuscation.cpp \
|
||||
obfuscation-relay.cpp \
|
||||
wallet/db.cpp \
|
||||
crypter.cpp \
|
||||
swifttx.cpp \
|
||||
masternode.cpp \
|
||||
masternode-budget.cpp \
|
||||
masternode-payments.cpp \
|
||||
masternode-sync.cpp \
|
||||
masternodeconfig.cpp \
|
||||
masternodeman.cpp \
|
||||
wallet/rpcdump.cpp \
|
||||
wallet/rpcwallet.cpp \
|
||||
kernel.cpp \
|
||||
wallet/wallet.cpp \
|
||||
wallet/wallet_ismine.cpp \
|
||||
wallet/walletdb.cpp \
|
||||
zagr/deterministicmint.cpp \
|
||||
zagr/zerocoin.cpp \
|
||||
zagr/accumulators.cpp \
|
||||
zagr/mintpool.cpp \
|
||||
zagr/witness.cpp \
|
||||
zagr/zagrwallet.cpp \
|
||||
zagr/zagrtracker.cpp \
|
||||
stakeinput.cpp \
|
||||
genwit.cpp \
|
||||
zagr/zagrmodule.cpp \
|
||||
lightzagrthread.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
# crypto primitives library
|
||||
crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(PIC_FLAGS)
|
||||
crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIC_FLAGS)
|
||||
crypto_libbitcoin_crypto_a_SOURCES = \
|
||||
crypto/sha1.cpp \
|
||||
crypto/sha256.cpp \
|
||||
crypto/sha512.cpp \
|
||||
crypto/hmac_sha256.cpp \
|
||||
crypto/rfc6979_hmac_sha256.cpp \
|
||||
crypto/hmac_sha512.cpp \
|
||||
crypto/scrypt.cpp \
|
||||
crypto/ripemd160.cpp \
|
||||
crypto/aes_helper.c \
|
||||
crypto/blake.c \
|
||||
crypto/bmw.c \
|
||||
crypto/groestl.c \
|
||||
crypto/jh.c \
|
||||
crypto/keccak.c \
|
||||
crypto/skein.c \
|
||||
crypto/common.h \
|
||||
crypto/sha256.h \
|
||||
crypto/sha512.h \
|
||||
crypto/hmac_sha256.h \
|
||||
crypto/rfc6979_hmac_sha256.h \
|
||||
crypto/hmac_sha512.h \
|
||||
crypto/scrypt.h \
|
||||
crypto/sha1.h \
|
||||
crypto/ripemd160.h \
|
||||
crypto/sph_blake.h \
|
||||
crypto/sph_bmw.h \
|
||||
crypto/sph_groestl.h \
|
||||
crypto/sph_jh.h \
|
||||
crypto/sph_keccak.h \
|
||||
crypto/sph_skein.h \
|
||||
crypto/sph_types.h
|
||||
|
||||
# libzerocoin library
|
||||
libzerocoin_libbitcoin_zerocoin_a_CPPFLAGS = $(AM_CPPFLAGS) $(BOOST_CPPFLAGS)
|
||||
libzerocoin_libbitcoin_zerocoin_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libzerocoin_libbitcoin_zerocoin_a_SOURCES = \
|
||||
libzerocoin/Accumulator.h \
|
||||
libzerocoin/AccumulatorProofOfKnowledge.h \
|
||||
libzerocoin/bignum.h \
|
||||
libzerocoin/Coin.h \
|
||||
libzerocoin/CoinSpend.h \
|
||||
libzerocoin/Commitment.h \
|
||||
libzerocoin/Denominations.h \
|
||||
libzerocoin/ParamGeneration.h \
|
||||
libzerocoin/Params.h \
|
||||
libzerocoin/SerialNumberSignatureOfKnowledge.h \
|
||||
libzerocoin/SpendType.h \
|
||||
libzerocoin/ZerocoinDefines.h \
|
||||
libzerocoin/bignum.cpp \
|
||||
libzerocoin/Accumulator.cpp \
|
||||
libzerocoin/AccumulatorProofOfKnowledge.cpp \
|
||||
libzerocoin/Coin.cpp \
|
||||
libzerocoin/Denominations.cpp \
|
||||
libzerocoin/CoinSpend.cpp \
|
||||
libzerocoin/Commitment.cpp \
|
||||
libzerocoin/ParamGeneration.cpp \
|
||||
libzerocoin/Params.cpp \
|
||||
libzerocoin/SerialNumberSignatureOfKnowledge.cpp
|
||||
if USE_NUM_GMP
|
||||
libzerocoin_libbitcoin_zerocoin_a_SOURCES += libzerocoin/bignum_gmp.cpp
|
||||
endif
|
||||
if USE_NUM_OPENSSL
|
||||
libzerocoin_libbitcoin_zerocoin_a_SOURCES += libzerocoin/bignum_openssl.cpp
|
||||
endif
|
||||
|
||||
# common: shared between agrariand, and agrarian-qt and non-server tools
|
||||
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_common_a_SOURCES = \
|
||||
zagr/accumulators.cpp \
|
||||
zagr/accumulatorcheckpoints.cpp \
|
||||
zagr/accumulatormap.cpp \
|
||||
allocators.cpp \
|
||||
amount.cpp \
|
||||
base58.cpp \
|
||||
bip38.cpp \
|
||||
chainparams.cpp \
|
||||
coins.cpp \
|
||||
compressor.cpp \
|
||||
primitives/block.cpp \
|
||||
zagr/deterministicmint.cpp \
|
||||
primitives/transaction.cpp \
|
||||
zagr/zerocoin.cpp \
|
||||
core_read.cpp \
|
||||
core_write.cpp \
|
||||
hash.cpp \
|
||||
invalid.cpp \
|
||||
key.cpp \
|
||||
keystore.cpp \
|
||||
netbase.cpp \
|
||||
protocol.cpp \
|
||||
pubkey.cpp \
|
||||
scheduler.cpp \
|
||||
script/interpreter.cpp \
|
||||
script/script.cpp \
|
||||
script/sign.cpp \
|
||||
script/standard.cpp \
|
||||
script/script_error.cpp \
|
||||
spork.cpp \
|
||||
sporkdb.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
# util: shared between all executables.
|
||||
# This library *must* be included to make sure that the glibc
|
||||
# backward-compatibility objects and their sanity checks are linked.
|
||||
libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_util_a_SOURCES = \
|
||||
allocators.cpp \
|
||||
chainparamsbase.cpp \
|
||||
clientversion.cpp \
|
||||
compat/glibc_sanity.cpp \
|
||||
compat/glibcxx_sanity.cpp \
|
||||
compat/strnlen.cpp \
|
||||
random.cpp \
|
||||
rpc/protocol.cpp \
|
||||
support/cleanse.cpp \
|
||||
sync.cpp \
|
||||
uint256.cpp \
|
||||
util.cpp \
|
||||
utilmoneystr.cpp \
|
||||
utilstrencodings.cpp \
|
||||
utiltime.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
if GLIBC_BACK_COMPAT
|
||||
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
|
||||
AM_LDFLAGS += $(COMPAT_LDFLAGS)
|
||||
endif
|
||||
|
||||
# cli: shared between agrarian-cli and agrarian-qt
|
||||
libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_cli_a_SOURCES = \
|
||||
rpc/client.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
|
||||
#
|
||||
|
||||
# agrariand binary #
|
||||
agrariand_SOURCES = agrariand.cpp
|
||||
agrariand_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
agrariand_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
agrariand_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
||||
if TARGET_WINDOWS
|
||||
agrariand_SOURCES += agrariand-res.rc
|
||||
endif
|
||||
agrariand_LDADD = \
|
||||
$(LIBBITCOIN_SERVER) \
|
||||
$(LIBBITCOIN_WALLET) \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBUNIVALUE) \
|
||||
$(LIBBITCOIN_ZEROCOIN) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_ZMQ) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBLEVELDB) \
|
||||
$(LIBLEVELDB_SSE42) \
|
||||
$(LIBMEMENV) \
|
||||
$(LIBSECP256K1)
|
||||
|
||||
agrariand_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
|
||||
|
||||
# agrarian-cli binary #
|
||||
agrarian_cli_SOURCES = agrarian-cli.cpp
|
||||
agrarian_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS)
|
||||
agrarian_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
agrarian_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
||||
if TARGET_WINDOWS
|
||||
agrarian_cli_SOURCES += agrarian-cli-res.rc
|
||||
endif
|
||||
|
||||
agrarian_cli_LDADD = \
|
||||
$(LIBBITCOIN_CLI) \
|
||||
$(LIBUNIVALUE) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_CRYPTO)
|
||||
|
||||
agrarian_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS)
|
||||
#
|
||||
|
||||
# agrarian-tx binary #
|
||||
agrarian_tx_SOURCES = agrarian-tx.cpp
|
||||
agrarian_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
agrarian_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
agrarian_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
||||
if TARGET_WINDOWS
|
||||
agrarian_tx_SOURCES += agrarian-tx-res.rc
|
||||
endif
|
||||
|
||||
agrarian_tx_LDADD = \
|
||||
$(LIBUNIVALUE) \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBBITCOIN_ZEROCOIN) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBSECP256K1)
|
||||
|
||||
agrarian_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
|
||||
#
|
||||
|
||||
# bitcoinconsensus library #
|
||||
if BUILD_BITCOIN_LIBS
|
||||
include_HEADERS = script/bitcoinconsensus.h
|
||||
libbitcoinconsensus_la_SOURCES = \
|
||||
allocators.cpp \
|
||||
primitives/transaction.cpp \
|
||||
crypto/hmac_sha512.cpp \
|
||||
crypto/scrypt.cpp \
|
||||
crypto/sha1.cpp \
|
||||
crypto/sha256.cpp \
|
||||
crypto/sha512.cpp \
|
||||
crypto/ripemd160.cpp \
|
||||
hash.cpp \
|
||||
pubkey.cpp \
|
||||
script/script.cpp \
|
||||
script/interpreter.cpp \
|
||||
script/bitcoinconsensus.cpp \
|
||||
uint256.cpp \
|
||||
utilstrencodings.cpp
|
||||
|
||||
if GLIBC_BACK_COMPAT
|
||||
libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
|
||||
endif
|
||||
|
||||
libbitcoinconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
|
||||
libbitcoinconsensus_la_LIBADD = $(LIBSECP256K1)
|
||||
libbitcoinconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL
|
||||
libbitcoinconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
|
||||
endif
|
||||
#
|
||||
|
||||
CLEANFILES = $(EXTRA_LIBRARIES)
|
||||
|
||||
CLEANFILES += *.gcda *.gcno
|
||||
CLEANFILES += compat/*.gcda compat/*.gcno
|
||||
CLEANFILES += crypto/*.gcda crypto/*.gcno
|
||||
CLEANFILES += libzerocoin/*.gcda libzerocoin/*.gcno
|
||||
CLEANFILES += primitives/*.gcda primitives/*.gcno
|
||||
CLEANFILES += rpc/*.gcda rpc/*.gcno
|
||||
CLEANFILES += script/*.gcda script/*.gcno
|
||||
CLEANFILES += support/*.gcda support/*.gcno
|
||||
CLEANFILES += univalue/*.gcda univalue/*.gcno
|
||||
CLEANFILES += wallet/*.gcda wallet/*.gcno
|
||||
CLEANFILES += wallet/test/*.gcda wallet/test/*.gcno
|
||||
CLEANFILES += zmq/*.gcda zmq/*.gcno
|
||||
CLEANFILES += zagr/*.gcda zagr/*.gcno
|
||||
CLEANFILES += obj/build.h
|
||||
|
||||
EXTRA_DIST =
|
||||
|
||||
|
||||
config/agrarian-config.h: config/stamp-h1
|
||||
@$(MAKE) -C $(top_builddir) $(subdir)/$(@)
|
||||
config/stamp-h1: $(top_srcdir)/$(subdir)/config/agrarian-config.h.in $(top_builddir)/config.status
|
||||
$(AM_V_at)$(MAKE) -C $(top_builddir) $(subdir)/$(@)
|
||||
$(top_srcdir)/$(subdir)/config/agrarian-config.h.in: $(am__configure_deps)
|
||||
$(AM_V_at)$(MAKE) -C $(top_srcdir) $(subdir)/config/agrarian-config.h.in
|
||||
|
||||
clean-local:
|
||||
-$(MAKE) -C secp256k1 clean
|
||||
-$(MAKE) -C univalue clean
|
||||
-rm -f leveldb/*/*.gcda leveldb/*/*.gcno leveldb/helpers/memenv/*.gcda leveldb/helpers/memenv/*.gcno
|
||||
-rm -f config.h
|
||||
-rm -rf test/__pycache__
|
||||
|
||||
.rc.o:
|
||||
@test -f $(WINDRES)
|
||||
## FIXME: How to get the appropriate modulename_CPPFLAGS in here?
|
||||
$(AM_V_GEN) $(WINDRES) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -DWINDRES_PREPROC -i $< -o $@
|
||||
|
||||
check-symbols: $(bin_PROGRAMS)
|
||||
if GLIBC_BACK_COMPAT
|
||||
@echo "Checking glibc back compat..."
|
||||
$(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py < $(bin_PROGRAMS)
|
||||
endif
|
||||
|
||||
check-security: $(bin_PROGRAMS)
|
||||
if HARDEN
|
||||
@echo "Checking binary security..."
|
||||
$(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS)
|
||||
endif
|
||||
|
||||
%.pb.cc %.pb.h: %.proto
|
||||
@test -f $(PROTOC)
|
||||
$(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(<D) $<
|
||||
|
||||
if EMBEDDED_LEVELDB
|
||||
include Makefile.leveldb.include
|
||||
endif
|
||||
|
||||
if ENABLE_TESTS
|
||||
include Makefile.test.include
|
||||
endif
|
||||
|
||||
if ENABLE_QT
|
||||
include Makefile.qt.include
|
||||
endif
|
||||
|
||||
if ENABLE_QT_TESTS
|
||||
include Makefile.qttest.include
|
||||
endif
|
||||
@@ -0,0 +1,149 @@
|
||||
# Copyright (c) 2016 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
LIBLEVELDB_INT = leveldb/libleveldb.a
|
||||
LIBMEMENV_INT = leveldb/libmemenv.a
|
||||
LIBLEVELDB_SSE42_INT = leveldb/libleveldb_sse42.a
|
||||
|
||||
EXTRA_LIBRARIES += $(LIBLEVELDB_INT)
|
||||
EXTRA_LIBRARIES += $(LIBMEMENV_INT)
|
||||
EXTRA_LIBRARIES += $(LIBLEVELDB_SSE42_INT)
|
||||
|
||||
LIBLEVELDB += $(LIBLEVELDB_INT)
|
||||
LIBMEMENV += $(LIBMEMENV_INT)
|
||||
LIBLEVELDB_SSE42 = $(LIBLEVELDB_SSE42_INT)
|
||||
|
||||
LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include
|
||||
LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/helpers/memenv
|
||||
|
||||
LEVELDB_CPPFLAGS_INT =
|
||||
LEVELDB_CPPFLAGS_INT += -I$(srcdir)/leveldb
|
||||
LEVELDB_CPPFLAGS_INT += $(LEVELDB_TARGET_FLAGS)
|
||||
LEVELDB_CPPFLAGS_INT += -DLEVELDB_ATOMIC_PRESENT
|
||||
LEVELDB_CPPFLAGS_INT += -D__STDC_LIMIT_MACROS
|
||||
|
||||
if TARGET_WINDOWS
|
||||
LEVELDB_CPPFLAGS_INT += -DLEVELDB_PLATFORM_WINDOWS -DWINVER=0x0500 -D__USE_MINGW_ANSI_STDIO=1
|
||||
else
|
||||
LEVELDB_CPPFLAGS_INT += -DLEVELDB_PLATFORM_POSIX
|
||||
endif
|
||||
|
||||
leveldb_libleveldb_a_CPPFLAGS = $(AM_CPPFLAGS) $(LEVELDB_CPPFLAGS_INT) $(LEVELDB_CPPFLAGS)
|
||||
leveldb_libleveldb_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
|
||||
leveldb_libleveldb_a_SOURCES=
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/port/atomic_pointer.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/port/port_example.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/port/port_posix.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/port/win/stdint.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/port/port.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/port/port_win.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/port/thread_annotations.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/db.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/options.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/comparator.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/filter_policy.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/slice.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/table_builder.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/env.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/c.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/iterator.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/cache.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/dumpfile.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/table.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/write_batch.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/status.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/log_format.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/memtable.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/version_set.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/write_batch_internal.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/filename.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/version_edit.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/dbformat.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/builder.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/log_writer.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/db_iter.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/skiplist.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/db_impl.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/table_cache.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/snapshot.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/log_reader.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/filter_block.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/block_builder.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/block.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/two_level_iterator.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/merger.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/format.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/iterator_wrapper.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/crc32c.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/env_posix_test_helper.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/arena.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/random.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/posix_logger.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/hash.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/histogram.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/coding.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/testutil.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/mutexlock.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/logging.h
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/testharness.h
|
||||
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/builder.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/c.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/dbformat.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/db_impl.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/db_iter.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/dumpfile.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/filename.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/log_reader.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/log_writer.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/memtable.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/repair.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/table_cache.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/version_edit.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/version_set.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/db/write_batch.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/block_builder.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/block.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/filter_block.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/format.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/iterator.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/merger.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/table_builder.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/table.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/table/two_level_iterator.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/arena.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/bloom.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/cache.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/coding.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/comparator.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/crc32c.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/env.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/env_posix.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/filter_policy.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/hash.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/histogram.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/logging.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/options.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/status.cc
|
||||
|
||||
if TARGET_WINDOWS
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/util/env_win.cc
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/port/port_win.cc
|
||||
else
|
||||
leveldb_libleveldb_a_SOURCES += leveldb/port/port_posix.cc
|
||||
endif
|
||||
|
||||
leveldb_libmemenv_a_CPPFLAGS = $(leveldb_libleveldb_a_CPPFLAGS)
|
||||
leveldb_libmemenv_a_CXXFLAGS = $(leveldb_libleveldb_a_CXXFLAGS)
|
||||
leveldb_libmemenv_a_SOURCES = leveldb/helpers/memenv/memenv.cc
|
||||
leveldb_libmemenv_a_SOURCES += leveldb/helpers/memenv/memenv.h
|
||||
|
||||
leveldb_libleveldb_sse42_a_CPPFLAGS = $(leveldb_libleveldb_a_CPPFLAGS)
|
||||
leveldb_libleveldb_sse42_a_CXXFLAGS = $(leveldb_libleveldb_a_CXXFLAGS)
|
||||
if ENABLE_HWCRC32
|
||||
leveldb_libleveldb_sse42_a_CPPFLAGS += -DLEVELDB_PLATFORM_POSIX_SSE
|
||||
leveldb_libleveldb_sse42_a_CXXFLAGS += $(SSE42_CXXFLAGS)
|
||||
endif
|
||||
leveldb_libleveldb_sse42_a_SOURCES = leveldb/port/port_posix_sse.cc
|
||||
@@ -0,0 +1,473 @@
|
||||
# Copyright (c) 2013-2016 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
bin_PROGRAMS += qt/agrarian-qt
|
||||
EXTRA_LIBRARIES += qt/libbitcoinqt.a
|
||||
|
||||
# agrarian qt core #
|
||||
QT_TS = \
|
||||
qt/locale/agrarian_bg.ts \
|
||||
qt/locale/agrarian_ca.ts \
|
||||
qt/locale/agrarian_cs.ts \
|
||||
qt/locale/agrarian_da.ts \
|
||||
qt/locale/agrarian_de.ts \
|
||||
qt/locale/agrarian_en.ts \
|
||||
qt/locale/agrarian_en_GB.ts \
|
||||
qt/locale/agrarian_en_US.ts \
|
||||
qt/locale/agrarian_eo.ts \
|
||||
qt/locale/agrarian_es.ts \
|
||||
qt/locale/agrarian_es_ES.ts \
|
||||
qt/locale/agrarian_fi.ts \
|
||||
qt/locale/agrarian_fr_FR.ts \
|
||||
qt/locale/agrarian_hi_IN.ts \
|
||||
qt/locale/agrarian_hr.ts \
|
||||
qt/locale/agrarian_hr_HR.ts \
|
||||
qt/locale/agrarian_it.ts \
|
||||
qt/locale/agrarian_ja.ts \
|
||||
qt/locale/agrarian_ko_KR.ts \
|
||||
qt/locale/agrarian_lt_LT.ts \
|
||||
qt/locale/agrarian_nl.ts \
|
||||
qt/locale/agrarian_pl.ts \
|
||||
qt/locale/agrarian_pt.ts \
|
||||
qt/locale/agrarian_pt_BR.ts \
|
||||
qt/locale/agrarian_ro_RO.ts \
|
||||
qt/locale/agrarian_ru.ts \
|
||||
qt/locale/agrarian_sk.ts \
|
||||
qt/locale/agrarian_sv.ts \
|
||||
qt/locale/agrarian_tr.ts \
|
||||
qt/locale/agrarian_uk.ts \
|
||||
qt/locale/agrarian_vi.ts \
|
||||
qt/locale/agrarian_zh_CN.ts \
|
||||
qt/locale/agrarian_zh_TW.ts
|
||||
|
||||
QT_FORMS_UI = \
|
||||
qt/forms/addressbookpage.ui \
|
||||
qt/forms/askpassphrasedialog.ui \
|
||||
qt/forms/bip38tooldialog.ui \
|
||||
qt/forms/coincontroldialog.ui \
|
||||
qt/forms/blockexplorer.ui \
|
||||
qt/forms/editaddressdialog.ui \
|
||||
qt/forms/governancepage.ui \
|
||||
qt/forms/helpmessagedialog.ui \
|
||||
qt/forms/intro.ui \
|
||||
qt/forms/masternodelist.ui \
|
||||
qt/forms/multisenddialog.ui \
|
||||
qt/forms/multisigdialog.ui\
|
||||
qt/forms/openuridialog.ui \
|
||||
qt/forms/optionsdialog.ui \
|
||||
qt/forms/overviewpage.ui \
|
||||
qt/forms/receivecoinsdialog.ui \
|
||||
qt/forms/privacydialog.ui \
|
||||
qt/forms/receiverequestdialog.ui \
|
||||
qt/forms/rpcconsole.ui \
|
||||
qt/forms/sendcoinsdialog.ui \
|
||||
qt/forms/sendcoinsentry.ui \
|
||||
qt/forms/signverifymessagedialog.ui \
|
||||
qt/forms/transactiondescdialog.ui \
|
||||
qt/forms/zagrcontroldialog.ui
|
||||
|
||||
QT_MOC_CPP = \
|
||||
qt/moc_addressbookpage.cpp \
|
||||
qt/moc_addresstablemodel.cpp \
|
||||
qt/moc_askpassphrasedialog.cpp \
|
||||
qt/moc_bantablemodel.cpp \
|
||||
qt/moc_bip38tooldialog.cpp \
|
||||
qt/moc_bitcoinaddressvalidator.cpp \
|
||||
qt/moc_bitcoinamountfield.cpp \
|
||||
qt/moc_bitcoingui.cpp \
|
||||
qt/moc_bitcoinunits.cpp \
|
||||
qt/moc_blockexplorer.cpp \
|
||||
qt/moc_clientmodel.cpp \
|
||||
qt/moc_coincontroldialog.cpp \
|
||||
qt/moc_coincontroltreewidget.cpp \
|
||||
qt/moc_csvmodelwriter.cpp \
|
||||
qt/moc_editaddressdialog.cpp \
|
||||
qt/moc_governancepage.cpp \
|
||||
qt/moc_guiutil.cpp \
|
||||
qt/moc_intro.cpp \
|
||||
qt/moc_macdockiconhandler.cpp \
|
||||
qt/moc_macnotificationhandler.cpp \
|
||||
qt/moc_masternodelist.cpp \
|
||||
qt/moc_multisenddialog.cpp \
|
||||
qt/moc_multisigdialog.cpp\
|
||||
qt/moc_notificator.cpp \
|
||||
qt/moc_openuridialog.cpp \
|
||||
qt/moc_optionsdialog.cpp \
|
||||
qt/moc_optionsmodel.cpp \
|
||||
qt/moc_overviewpage.cpp \
|
||||
qt/moc_peertablemodel.cpp \
|
||||
qt/moc_paymentserver.cpp \
|
||||
qt/moc_qvalidatedlineedit.cpp \
|
||||
qt/moc_qvaluecombobox.cpp \
|
||||
qt/moc_receivecoinsdialog.cpp \
|
||||
qt/moc_privacydialog.cpp \
|
||||
qt/moc_proposalframe.cpp \
|
||||
qt/moc_receiverequestdialog.cpp \
|
||||
qt/moc_recentrequeststablemodel.cpp \
|
||||
qt/moc_rpcconsole.cpp \
|
||||
qt/moc_sendcoinsdialog.cpp \
|
||||
qt/moc_sendcoinsentry.cpp \
|
||||
qt/moc_signverifymessagedialog.cpp \
|
||||
qt/moc_splashscreen.cpp \
|
||||
qt/moc_trafficgraphwidget.cpp \
|
||||
qt/moc_transactiondesc.cpp \
|
||||
qt/moc_transactiondescdialog.cpp \
|
||||
qt/moc_transactionfilterproxy.cpp \
|
||||
qt/moc_transactiontablemodel.cpp \
|
||||
qt/moc_transactionview.cpp \
|
||||
qt/moc_utilitydialog.cpp \
|
||||
qt/moc_walletframe.cpp \
|
||||
qt/moc_walletmodel.cpp \
|
||||
qt/moc_walletview.cpp \
|
||||
qt/moc_zagrcontroldialog.cpp
|
||||
|
||||
BITCOIN_MM = \
|
||||
qt/macdockiconhandler.mm \
|
||||
qt/macnotificationhandler.mm
|
||||
|
||||
QT_MOC = \
|
||||
qt/agrarian.moc \
|
||||
qt/bitcoinamountfield.moc \
|
||||
qt/intro.moc \
|
||||
qt/overviewpage.moc \
|
||||
qt/rpcconsole.moc
|
||||
|
||||
QT_QRC_CPP = qt/qrc_agrarian.cpp
|
||||
QT_QRC = qt/agrarian.qrc
|
||||
QT_QRC_LOCALE_CPP = qt/qrc_agrarian_locale.cpp
|
||||
QT_QRC_LOCALE = qt/agrarian_locale.qrc
|
||||
|
||||
PROTOBUF_CC = qt/paymentrequest.pb.cc
|
||||
PROTOBUF_H = qt/paymentrequest.pb.h
|
||||
PROTOBUF_PROTO = qt/paymentrequest.proto
|
||||
|
||||
BITCOIN_QT_H = \
|
||||
qt/addressbookpage.h \
|
||||
qt/addresstablemodel.h \
|
||||
qt/askpassphrasedialog.h \
|
||||
qt/bantablemodel.h \
|
||||
qt/bip38tooldialog.h \
|
||||
qt/bitcoinaddressvalidator.h \
|
||||
qt/bitcoinamountfield.h \
|
||||
qt/bitcoingui.h \
|
||||
qt/bitcoinunits.h \
|
||||
qt/blockexplorer.h \
|
||||
qt/clientmodel.h \
|
||||
qt/coincontroldialog.h \
|
||||
qt/coincontroltreewidget.h \
|
||||
qt/csvmodelwriter.h \
|
||||
qt/editaddressdialog.h \
|
||||
qt/governancepage.h \
|
||||
qt/guiconstants.h \
|
||||
qt/guiutil.h \
|
||||
qt/intro.h \
|
||||
qt/macdockiconhandler.h \
|
||||
qt/macnotificationhandler.h \
|
||||
qt/masternodelist.h \
|
||||
qt/multisenddialog.h \
|
||||
qt/multisigdialog.h\
|
||||
qt/networkstyle.h \
|
||||
qt/notificator.h \
|
||||
qt/openuridialog.h \
|
||||
qt/optionsdialog.h \
|
||||
qt/optionsmodel.h \
|
||||
qt/overviewpage.h \
|
||||
qt/paymentrequestplus.h \
|
||||
qt/paymentserver.h \
|
||||
qt/peertablemodel.h \
|
||||
qt/platformstyle.h \
|
||||
qt/proposalframe.h \
|
||||
qt/qvalidatedlineedit.h \
|
||||
qt/qvaluecombobox.h \
|
||||
qt/receivecoinsdialog.h \
|
||||
qt/privacydialog.h \
|
||||
qt/receiverequestdialog.h \
|
||||
qt/recentrequeststablemodel.h \
|
||||
qt/rpcconsole.h \
|
||||
qt/sendcoinsdialog.h \
|
||||
qt/sendcoinsentry.h \
|
||||
qt/signverifymessagedialog.h \
|
||||
qt/splashscreen.h \
|
||||
qt/trafficgraphwidget.h \
|
||||
qt/transactiondesc.h \
|
||||
qt/transactiondescdialog.h \
|
||||
qt/transactionfilterproxy.h \
|
||||
qt/transactionrecord.h \
|
||||
qt/transactiontablemodel.h \
|
||||
qt/transactionview.h \
|
||||
qt/utilitydialog.h \
|
||||
qt/walletframe.h \
|
||||
qt/walletmodel.h \
|
||||
qt/walletmodeltransaction.h \
|
||||
qt/walletview.h \
|
||||
qt/winshutdownmonitor.h \
|
||||
qt/zagrcontroldialog.h
|
||||
|
||||
RES_ICONS = \
|
||||
qt/res/icons/add.png \
|
||||
qt/res/icons/address-book.png \
|
||||
qt/res/icons/automint_active.png \
|
||||
qt/res/icons/automint_inactive.png \
|
||||
qt/res/icons/bitcoin.ico \
|
||||
qt/res/icons/bitcoin.png \
|
||||
qt/res/icons/bitcoin_testnet.ico \
|
||||
qt/res/icons/bitcoin_testnet.png \
|
||||
qt/res/icons/bitcoin_regtest.png \
|
||||
qt/res/icons/browse.png \
|
||||
qt/res/icons/clock1.png \
|
||||
qt/res/icons/clock2.png \
|
||||
qt/res/icons/clock3.png \
|
||||
qt/res/icons/clock4.png \
|
||||
qt/res/icons/clock5.png \
|
||||
qt/res/icons/configure.png \
|
||||
qt/res/icons/connect0_16.png \
|
||||
qt/res/icons/connect1_16.png \
|
||||
qt/res/icons/connect2_16.png \
|
||||
qt/res/icons/connect3_16.png \
|
||||
qt/res/icons/connect4_16.png \
|
||||
qt/res/icons/debugwindow.png \
|
||||
qt/res/icons/edit.png \
|
||||
qt/res/icons/editcopy.png \
|
||||
qt/res/icons/editpaste.png \
|
||||
qt/res/icons/explorer.png \
|
||||
qt/res/icons/export.png \
|
||||
qt/res/icons/eye.png \
|
||||
qt/res/icons/eye_minus.png \
|
||||
qt/res/icons/eye_plus.png \
|
||||
qt/res/icons/filesave.png \
|
||||
qt/res/icons/history.png \
|
||||
qt/res/icons/key.png \
|
||||
qt/res/icons/lock_closed.png \
|
||||
qt/res/icons/lock_open.png \
|
||||
qt/res/icons/masternodes.png \
|
||||
qt/res/icons/onion.png \
|
||||
qt/res/icons/overview.png \
|
||||
qt/res/icons/qrcode.png \
|
||||
qt/res/icons/quit.png \
|
||||
qt/res/icons/receive.png \
|
||||
qt/res/icons/receive_dark.png \
|
||||
qt/res/icons/privacy.png \
|
||||
qt/res/icons/remove.png \
|
||||
qt/res/icons/send.png \
|
||||
qt/res/icons/send_dark.png \
|
||||
qt/res/icons/governance.png \
|
||||
qt/res/icons/governance_dark.png \
|
||||
qt/res/icons/staking_active.png \
|
||||
qt/res/icons/staking_inactive.png \
|
||||
qt/res/icons/synced.png \
|
||||
qt/res/icons/trade.png \
|
||||
qt/res/icons/transaction0.png \
|
||||
qt/res/icons/transaction2.png \
|
||||
qt/res/icons/transaction_conflicted.png \
|
||||
qt/res/icons/tx_inout.png \
|
||||
qt/res/icons/tx_input.png \
|
||||
qt/res/icons/tx_output.png \
|
||||
qt/res/icons/tx_mined.png \
|
||||
qt/res/icons/unit_agrarian.png \
|
||||
qt/res/icons/unit_magrarian.png \
|
||||
qt/res/icons/unit_uagrarian.png \
|
||||
qt/res/icons/unit_tagrarian.png \
|
||||
qt/res/icons/unit_tmagrarian.png \
|
||||
qt/res/icons/unit_tuagrarian.png \
|
||||
qt/res/icons/yesvote.png \
|
||||
qt/res/icons/novote.png \
|
||||
qt/res/icons/abstainvote.png
|
||||
|
||||
BITCOIN_QT_BASE_CPP = \
|
||||
qt/bantablemodel.cpp \
|
||||
qt/bitcoinaddressvalidator.cpp \
|
||||
qt/bitcoinamountfield.cpp \
|
||||
qt/bitcoingui.cpp \
|
||||
qt/bitcoinunits.cpp \
|
||||
qt/blockexplorer.cpp \
|
||||
qt/clientmodel.cpp \
|
||||
qt/csvmodelwriter.cpp \
|
||||
qt/guiutil.cpp \
|
||||
qt/intro.cpp \
|
||||
qt/masternodelist.cpp \
|
||||
qt/networkstyle.cpp \
|
||||
qt/notificator.cpp \
|
||||
qt/optionsdialog.cpp \
|
||||
qt/optionsmodel.cpp \
|
||||
qt/peertablemodel.cpp \
|
||||
qt/platformstyle.cpp \
|
||||
qt/qvalidatedlineedit.cpp \
|
||||
qt/qvaluecombobox.cpp \
|
||||
qt/rpcconsole.cpp \
|
||||
qt/splashscreen.cpp \
|
||||
qt/trafficgraphwidget.cpp \
|
||||
qt/utilitydialog.cpp
|
||||
|
||||
BITCOIN_QT_WINDOWS_CPP = qt/winshutdownmonitor.cpp
|
||||
|
||||
BITCOIN_QT_WALLET_CPP = \
|
||||
qt/addressbookpage.cpp \
|
||||
qt/addresstablemodel.cpp \
|
||||
qt/askpassphrasedialog.cpp \
|
||||
qt/bip38tooldialog.cpp \
|
||||
qt/blockexplorer.cpp \
|
||||
qt/coincontroldialog.cpp \
|
||||
qt/coincontroltreewidget.cpp \
|
||||
qt/editaddressdialog.cpp \
|
||||
qt/governancepage.cpp \
|
||||
qt/masternodelist.cpp \
|
||||
qt/multisenddialog.cpp \
|
||||
qt/multisigdialog.cpp\
|
||||
qt/openuridialog.cpp \
|
||||
qt/overviewpage.cpp \
|
||||
qt/paymentrequestplus.cpp \
|
||||
qt/paymentserver.cpp \
|
||||
qt/receivecoinsdialog.cpp \
|
||||
qt/privacydialog.cpp \
|
||||
qt/proposalframe.cpp \
|
||||
qt/receiverequestdialog.cpp \
|
||||
qt/recentrequeststablemodel.cpp \
|
||||
qt/sendcoinsdialog.cpp \
|
||||
qt/sendcoinsentry.cpp \
|
||||
qt/signverifymessagedialog.cpp \
|
||||
qt/transactiondesc.cpp \
|
||||
qt/transactiondescdialog.cpp \
|
||||
qt/transactionfilterproxy.cpp \
|
||||
qt/transactionrecord.cpp \
|
||||
qt/transactiontablemodel.cpp \
|
||||
qt/transactionview.cpp \
|
||||
qt/walletframe.cpp \
|
||||
qt/walletmodel.cpp \
|
||||
qt/walletmodeltransaction.cpp \
|
||||
qt/walletview.cpp \
|
||||
qt/zagrcontroldialog.cpp
|
||||
|
||||
BITCOIN_QT_CPP = $(BITCOIN_QT_BASE_CPP)
|
||||
if TARGET_WINDOWS
|
||||
BITCOIN_QT_CPP += $(BITCOIN_QT_WINDOWS_CPP)
|
||||
endif
|
||||
if ENABLE_WALLET
|
||||
BITCOIN_QT_CPP += $(BITCOIN_QT_WALLET_CPP)
|
||||
endif
|
||||
|
||||
RES_IMAGES = \
|
||||
qt/res/images/about.png \
|
||||
qt/res/images/splash.png \
|
||||
qt/res/images/splash_testnet.png \
|
||||
qt/res/images/splash_regtest.png \
|
||||
qt/res/images/agrarian_logo_horizontal.png \
|
||||
qt/res/images/downArrow_dark.png \
|
||||
qt/res/images/downArrow_small_dark.png \
|
||||
qt/res/images/downArrow_small.png \
|
||||
qt/res/images/upArrow_small_dark.png \
|
||||
qt/res/images/upArrow_small.png \
|
||||
qt/res/images/leftArrow_small_dark.png \
|
||||
qt/res/images/rightArrow_small_dark.png \
|
||||
qt/res/images/qtreeview_selected.png
|
||||
|
||||
RES_CSS = \
|
||||
qt/res/css/default.css
|
||||
|
||||
RES_MOVIES = $(wildcard $(srcdir)/qt/res/movies/spinner-*.png)
|
||||
|
||||
BITCOIN_RC = qt/res/agrarian-qt-res.rc
|
||||
|
||||
BITCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \
|
||||
-I$(builddir)/qt/forms
|
||||
|
||||
qt_libbitcoinqt_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
|
||||
$(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
|
||||
qt_libbitcoinqt_a_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)
|
||||
qt_libbitcoinqt_a_OBJCXXFLAGS = $(AM_OBJCXXFLAGS) $(QT_PIE_FLAGS)
|
||||
|
||||
qt_libbitcoinqt_a_SOURCES = $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(QT_FORMS_UI) \
|
||||
$(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_CSS) $(RES_MOVIES)
|
||||
|
||||
nodist_qt_libbitcoinqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(PROTOBUF_CC) \
|
||||
$(PROTOBUF_H) $(QT_QRC_CPP) $(QT_QRC_LOCALE_CPP)
|
||||
|
||||
# forms/foo.h -> forms/ui_foo.h
|
||||
QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h))))
|
||||
|
||||
# Most files will depend on the forms and moc files as includes. Generate them
|
||||
# before anything else.
|
||||
$(QT_MOC): $(QT_FORMS_H)
|
||||
$(qt_libbitcoinqt_a_OBJECTS) $(qt_agrarian_qt_OBJECTS) : | $(QT_MOC)
|
||||
|
||||
#Generating these with a half-written protobuf header leads to wacky results.
|
||||
#This makes sure it's done.
|
||||
$(QT_MOC): $(PROTOBUF_H)
|
||||
$(QT_MOC_CPP): $(PROTOBUF_H)
|
||||
|
||||
# agrarian-qt binary #
|
||||
qt_agrarian_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
|
||||
$(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
|
||||
qt_agrarian_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)
|
||||
|
||||
qt_agrarian_qt_SOURCES = qt/agrarian.cpp
|
||||
if TARGET_DARWIN
|
||||
qt_agrarian_qt_SOURCES += $(BITCOIN_MM)
|
||||
endif
|
||||
if TARGET_WINDOWS
|
||||
qt_agrarian_qt_SOURCES += $(BITCOIN_RC)
|
||||
endif
|
||||
qt_agrarian_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
|
||||
if ENABLE_WALLET
|
||||
qt_agrarian_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
if ENABLE_ZMQ
|
||||
qt_agrarian_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||
endif
|
||||
qt_agrarian_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBBITCOIN_ZEROCOIN) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \
|
||||
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
||||
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
qt_agrarian_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
qt_agrarian_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX
|
||||
|
||||
#locale/foo.ts -> locale/foo.qm
|
||||
QT_QM=$(QT_TS:.ts=.qm)
|
||||
|
||||
SECONDARY: $(QT_QM)
|
||||
|
||||
$(srcdir)/qt/agrarianstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) $(libbitcoin_common_a_SOURCES) $(libbitcoin_zmq_a_SOURCES) $(libbitcoin_util_a_SOURCES)
|
||||
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
|
||||
$(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" $(PYTHON) ../share/qt/extract_strings_qt.py $^
|
||||
|
||||
translate: $(srcdir)/qt/agrarianstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_BASE_CPP) qt/agrarian.cpp $(BITCOIN_QT_WINDOWS_CPP) $(BITCOIN_QT_WALLET_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM)
|
||||
@test -n $(LUPDATE) || echo "lupdate is required for updating translations"
|
||||
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts $(srcdir)/qt/locale/agrarian_en.ts
|
||||
|
||||
$(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM)
|
||||
@test -f $(RCC)
|
||||
@cp -f $< $(@D)/temp_$(<F)
|
||||
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name agrarian_locale $(@D)/temp_$(<F) | \
|
||||
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
|
||||
@rm $(@D)/temp_$(<F)
|
||||
|
||||
$(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_CSS) $(RES_MOVIES) $(PROTOBUF_H)
|
||||
@test -f $(RCC)
|
||||
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name agrarian $< | \
|
||||
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
|
||||
|
||||
CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_agrarian_locale.qrc
|
||||
|
||||
CLEANFILES += $(CLEAN_QT)
|
||||
|
||||
agrarian_qt_clean: FORCE
|
||||
rm -f $(CLEAN_QT) $(qt_libbitcoinqt_a_OBJECTS) $(qt_agrarian_qt_OBJECTS) qt/agrarian-qt$(EXEEXT) $(LIBBITCOINQT)
|
||||
|
||||
agrarian_qt : qt/agrarian-qt$(EXEEXT)
|
||||
|
||||
ui_%.h: %.ui
|
||||
@test -f $(UIC)
|
||||
@$(MKDIR_P) $(@D)
|
||||
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(UIC) -o $@ $< || (echo "Error creating $@"; false)
|
||||
|
||||
%.moc: %.cpp
|
||||
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES) $(MOC_DEFS) $< | \
|
||||
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
|
||||
|
||||
moc_%.cpp: %.h
|
||||
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES) $(MOC_DEFS) $< | \
|
||||
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
|
||||
|
||||
%.qm: %.ts
|
||||
@test -f $(LRELEASE)
|
||||
@$(MKDIR_P) $(@D)
|
||||
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LRELEASE) -silent $< -qm $@
|
||||
@@ -0,0 +1,56 @@
|
||||
# Copyright (c) 2013-2016 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
bin_PROGRAMS += qt/test/test_agrarian-qt
|
||||
TESTS += qt/test/test_agrarian-qt
|
||||
|
||||
TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp
|
||||
|
||||
if ENABLE_WALLET
|
||||
TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
|
||||
endif
|
||||
|
||||
TEST_QT_H = \
|
||||
qt/test/uritests.h \
|
||||
qt/test/paymentrequestdata.h \
|
||||
qt/test/paymentservertests.h
|
||||
|
||||
qt_test_test_agrarian_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
|
||||
$(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS)
|
||||
|
||||
qt_test_test_agrarian_qt_SOURCES = \
|
||||
qt/test/test_main.cpp \
|
||||
qt/test/uritests.cpp \
|
||||
$(TEST_QT_H)
|
||||
if ENABLE_WALLET
|
||||
qt_test_test_agrarian_qt_SOURCES += \
|
||||
qt/test/paymentservertests.cpp
|
||||
endif
|
||||
|
||||
nodist_qt_test_test_agrarian_qt_SOURCES = $(TEST_QT_MOC_CPP)
|
||||
|
||||
qt_test_test_agrarian_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER)
|
||||
if ENABLE_WALLET
|
||||
qt_test_test_agrarian_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
if ENABLE_ZMQ
|
||||
qt_test_test_agrarian_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||
endif
|
||||
qt_test_test_agrarian_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBBITCOIN_ZEROCOIN) $(LIBLEVELDB) \
|
||||
$(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
|
||||
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
||||
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
qt_test_test_agrarian_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
qt_test_test_agrarian_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)
|
||||
|
||||
CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno
|
||||
|
||||
CLEANFILES += $(CLEAN_BITCOIN_QT_TEST)
|
||||
|
||||
test_agrarian_qt : qt/test/test_agrarian-qt$(EXEEXT)
|
||||
|
||||
test_agrarian_qt_check : qt/test/test_agrarian-qt$(EXEEXT) FORCE
|
||||
$(MAKE) check-TESTS TESTS=$^
|
||||
|
||||
test_agrarian_qt_clean: FORCE
|
||||
rm -f $(CLEAN_BITCOIN_QT_TEST) $(qt_test_test_agrarian_qt_OBJECTS)
|
||||
@@ -0,0 +1,147 @@
|
||||
# Copyright (c) 2013-2016 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
bin_PROGRAMS += test/test_agrarian
|
||||
TEST_SRCDIR = test
|
||||
TEST_BINARY=test/test_agrarian$(EXEEXT)
|
||||
|
||||
JSON_TEST_FILES = \
|
||||
test/data/script_valid.json \
|
||||
test/data/base58_keys_valid.json \
|
||||
test/data/sig_canonical.json \
|
||||
test/data/sig_noncanonical.json \
|
||||
test/data/base58_encode_decode.json \
|
||||
test/data/base58_keys_invalid.json \
|
||||
test/data/script_invalid.json \
|
||||
test/data/tx_invalid.json \
|
||||
test/data/tx_valid.json \
|
||||
test/data/sighash.json
|
||||
|
||||
RAW_TEST_FILES = test/data/alertTests.raw
|
||||
|
||||
GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
|
||||
|
||||
BITCOIN_TEST_SUITE = \
|
||||
test/test_agrarian.h \
|
||||
test/test_agrarian.cpp
|
||||
# test_agrarian binary #
|
||||
BITCOIN_TESTS =\
|
||||
test/zerocoin_implementation_tests.cpp\
|
||||
test/zerocoin_denomination_tests.cpp\
|
||||
test/zerocoin_transactions_tests.cpp \
|
||||
test/zerocoin_coinspend_tests.cpp \
|
||||
test/zerocoin_bignum_tests.cpp \
|
||||
test/benchmark_zerocoin.cpp \
|
||||
test/tutorial_zerocoin.cpp \
|
||||
test/libzerocoin_tests.cpp \
|
||||
test/addrman_tests.cpp \
|
||||
test/allocator_tests.cpp \
|
||||
test/base32_tests.cpp \
|
||||
test/base58_tests.cpp \
|
||||
test/base64_tests.cpp \
|
||||
test/budget_tests.cpp \
|
||||
test/checkblock_tests.cpp \
|
||||
test/Checkpoints_tests.cpp \
|
||||
test/coins_tests.cpp \
|
||||
test/compress_tests.cpp \
|
||||
test/crypto_tests.cpp \
|
||||
test/DoS_tests.cpp \
|
||||
test/getarg_tests.cpp \
|
||||
test/hash_tests.cpp \
|
||||
test/key_tests.cpp \
|
||||
test/main_tests.cpp \
|
||||
test/mempool_tests.cpp \
|
||||
test/mruset_tests.cpp \
|
||||
test/multisig_tests.cpp \
|
||||
test/netbase_tests.cpp \
|
||||
test/pmt_tests.cpp \
|
||||
test/reverselock_tests.cpp \
|
||||
test/rpc_tests.cpp \
|
||||
test/sanity_tests.cpp \
|
||||
test/scheduler_tests.cpp \
|
||||
test/script_P2SH_tests.cpp \
|
||||
test/script_tests.cpp \
|
||||
test/scriptnum_tests.cpp \
|
||||
test/serialize_tests.cpp \
|
||||
test/sighash_tests.cpp \
|
||||
test/sigopcount_tests.cpp \
|
||||
test/skiplist_tests.cpp \
|
||||
test/timedata_tests.cpp \
|
||||
test/torcontrol_tests.cpp \
|
||||
test/transaction_tests.cpp \
|
||||
test/uint256_tests.cpp \
|
||||
test/univalue_tests.cpp \
|
||||
test/util_tests.cpp
|
||||
|
||||
if ENABLE_WALLET
|
||||
BITCOIN_TESTS += \
|
||||
test/accounting_tests.cpp \
|
||||
wallet/test/wallet_tests.cpp \
|
||||
test/rpc_wallet_tests.cpp
|
||||
endif
|
||||
|
||||
test_test_agrarian_SOURCES = $(BITCOIN_TEST_SUITE) $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
||||
test_test_agrarian_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_FLAGS)
|
||||
test_test_agrarian_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBBITCOIN_ZEROCOIN) \
|
||||
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
|
||||
if ENABLE_WALLET
|
||||
test_test_agrarian_LDADD += $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
test_test_agrarian_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
|
||||
test_test_agrarian_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
|
||||
test_test_agrarian_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
|
||||
|
||||
if ENABLE_ZMQ
|
||||
test_test_agrarian_LDADD += $(ZMQ_LIBS)
|
||||
endif
|
||||
#
|
||||
|
||||
nodist_test_test_agrarian_SOURCES = $(GENERATED_TEST_FILES)
|
||||
|
||||
$(BITCOIN_TESTS): $(GENERATED_TEST_FILES)
|
||||
|
||||
CLEAN_BITCOIN_TEST = test/*.gcda test/*.gcno $(GENERATED_TEST_FILES)
|
||||
|
||||
CLEANFILES += $(CLEAN_BITCOIN_TEST)
|
||||
|
||||
agrarian_test: $(TEST_BINARY)
|
||||
|
||||
agrarian_test_check: $(TEST_BINARY) FORCE
|
||||
$(MAKE) check-TESTS TESTS=$^
|
||||
|
||||
agrarian_test_clean : FORCE
|
||||
rm -f $(CLEAN_BITCOIN_TEST) $(test_test_agrarian_OBJECTS) $(TEST_BINARY)
|
||||
|
||||
check-local: $(BITCOIN_TESTS:.cpp=.cpp.test)
|
||||
@echo "Running test/util/bitcoin-util-test.py..."
|
||||
$(PYTHON) $(top_builddir)/test/util/bitcoin-util-test.py
|
||||
@echo "Running test/util/rpcauth-test.py..."
|
||||
$(PYTHON) $(top_builddir)/test/util/rpcauth-test.py
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
|
||||
if EMBEDDED_UNIVALUE
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check
|
||||
endif
|
||||
|
||||
%.cpp.test: %.cpp
|
||||
@echo Running tests: `cat $< | grep -E "(BOOST_FIXTURE_TEST_SUITE\\(|BOOST_AUTO_TEST_SUITE\\()" | cut -d '(' -f 2 | cut -d ',' -f 1 | cut -d ')' -f 1` from $<
|
||||
$(AM_V_at)$(TEST_BINARY) -l test_suite -t "`cat $< | grep -E "(BOOST_FIXTURE_TEST_SUITE\\(|BOOST_AUTO_TEST_SUITE\\()" | cut -d '(' -f 2 | cut -d ',' -f 1 | cut -d ')' -f 1`" > $<.log 2>&1 || (cat $<.log && false)
|
||||
|
||||
%.json.h: %.json
|
||||
@$(MKDIR_P) $(@D)
|
||||
@{ \
|
||||
echo "namespace json_tests{" && \
|
||||
echo "static unsigned const char $(*F)[] = {" && \
|
||||
$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' && \
|
||||
echo "};};"; \
|
||||
} > "$@.new" && mv -f "$@.new" "$@"
|
||||
@echo "Generated $@"
|
||||
|
||||
%.raw.h: %.raw
|
||||
@$(MKDIR_P) $(@D)
|
||||
@echo "namespace alert_tests{" > $@
|
||||
@echo "static unsigned const char $(*F)[] = {" >> $@
|
||||
@$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@
|
||||
@echo "};};" >> $@
|
||||
@echo "Generated $@"
|
||||
@@ -0,0 +1,480 @@
|
||||
// Copyright (c) 2014-2016 The Dash developers
|
||||
// Copyright (c) 2015-2019 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "activemasternode.h"
|
||||
#include "addrman.h"
|
||||
#include "masternode.h"
|
||||
#include "masternodeconfig.h"
|
||||
#include "masternodeman.h"
|
||||
#include "protocol.h"
|
||||
#include "spork.h"
|
||||
|
||||
//
|
||||
// Bootup the Masternode, look for a 10000 Agrarian input and register on the network
|
||||
//
|
||||
void CActiveMasternode::ManageStatus()
|
||||
{
|
||||
std::string errorMessage;
|
||||
|
||||
if (!fMasterNode) return;
|
||||
|
||||
if (fDebug) LogPrintf("CActiveMasternode::ManageStatus() - Begin\n");
|
||||
|
||||
//need correct blocks to send ping
|
||||
if (Params().NetworkID() != CBaseChainParams::REGTEST && !masternodeSync.IsBlockchainSynced()) {
|
||||
status = ACTIVE_MASTERNODE_SYNC_IN_PROCESS;
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - %s\n", GetStatus());
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == ACTIVE_MASTERNODE_SYNC_IN_PROCESS) status = ACTIVE_MASTERNODE_INITIAL;
|
||||
|
||||
if (status == ACTIVE_MASTERNODE_INITIAL) {
|
||||
CMasternode* pmn;
|
||||
pmn = mnodeman.Find(pubKeyMasternode);
|
||||
if (pmn != NULL) {
|
||||
pmn->Check();
|
||||
if (pmn->IsEnabled() && pmn->protocolVersion == PROTOCOL_VERSION) EnableHotColdMasterNode(pmn->vin, pmn->addr);
|
||||
}
|
||||
}
|
||||
|
||||
if (status != ACTIVE_MASTERNODE_STARTED) {
|
||||
// Set defaults
|
||||
status = ACTIVE_MASTERNODE_NOT_CAPABLE;
|
||||
notCapableReason = "";
|
||||
|
||||
if (pwalletMain->IsLocked()) {
|
||||
notCapableReason = "Wallet is locked.";
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pwalletMain->GetBalance() == 0) {
|
||||
notCapableReason = "Hot node, waiting for remote activation.";
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strMasterNodeAddr.empty()) {
|
||||
if (!GetLocal(service)) {
|
||||
notCapableReason = "Can't detect external address. Please use the masternodeaddr configuration option.";
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
service = CService(strMasterNodeAddr);
|
||||
}
|
||||
|
||||
// The service needs the correct default port to work properly
|
||||
if(!CMasternodeBroadcast::CheckDefaultPort(strMasterNodeAddr, errorMessage, "CActiveMasternode::ManageStatus()"))
|
||||
return;
|
||||
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString());
|
||||
|
||||
CNode* pnode = ConnectNode((CAddress)service, NULL, false);
|
||||
if (!pnode) {
|
||||
notCapableReason = "Could not connect to " + service.ToString();
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason);
|
||||
return;
|
||||
}
|
||||
pnode->Release();
|
||||
|
||||
// Choose coins to use
|
||||
CPubKey pubKeyCollateralAddress;
|
||||
CKey keyCollateralAddress;
|
||||
|
||||
if (GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress)) {
|
||||
if (GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS) {
|
||||
status = ACTIVE_MASTERNODE_INPUT_TOO_NEW;
|
||||
notCapableReason = strprintf("%s - %d confirmations", GetStatus(), GetInputAge(vin));
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason);
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK(pwalletMain->cs_wallet);
|
||||
pwalletMain->LockCoin(vin.prevout);
|
||||
|
||||
// send to all nodes
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
|
||||
if (!obfuScationSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) {
|
||||
notCapableReason = "Error upon calling SetKey: " + errorMessage;
|
||||
LogPrintf("Register::ManageStatus() - %s\n", notCapableReason);
|
||||
return;
|
||||
}
|
||||
|
||||
CMasternodeBroadcast mnb;
|
||||
if (!CreateBroadcast(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage, mnb)) {
|
||||
notCapableReason = "Error on Register: " + errorMessage;
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason);
|
||||
return;
|
||||
}
|
||||
|
||||
//send to all peers
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Relay broadcast vin = %s\n", vin.ToString());
|
||||
mnb.Relay();
|
||||
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n");
|
||||
status = ACTIVE_MASTERNODE_STARTED;
|
||||
|
||||
return;
|
||||
} else {
|
||||
notCapableReason = "Could not find suitable coins!";
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//send to all peers
|
||||
if (!SendMasternodePing(errorMessage)) {
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s\n", errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
std::string CActiveMasternode::GetStatus()
|
||||
{
|
||||
switch (status) {
|
||||
case ACTIVE_MASTERNODE_INITIAL:
|
||||
return "Node just started, not yet activated";
|
||||
case ACTIVE_MASTERNODE_SYNC_IN_PROCESS:
|
||||
return "Sync in progress. Must wait until sync is complete to start Masternode";
|
||||
case ACTIVE_MASTERNODE_INPUT_TOO_NEW:
|
||||
return strprintf("Masternode input must have at least %d confirmations", MASTERNODE_MIN_CONFIRMATIONS);
|
||||
case ACTIVE_MASTERNODE_NOT_CAPABLE:
|
||||
return "Not capable masternode: " + notCapableReason;
|
||||
case ACTIVE_MASTERNODE_STARTED:
|
||||
return "Masternode successfully started";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
bool CActiveMasternode::SendMasternodePing(std::string& errorMessage)
|
||||
{
|
||||
if (status != ACTIVE_MASTERNODE_STARTED) {
|
||||
errorMessage = "Masternode is not in a running status";
|
||||
return false;
|
||||
}
|
||||
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
|
||||
if (!obfuScationSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) {
|
||||
errorMessage = strprintf("Error upon calling SetKey: %s\n", errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintf("CActiveMasternode::SendMasternodePing() - Relay Masternode Ping vin = %s\n", vin.ToString());
|
||||
|
||||
CMasternodePing mnp(vin);
|
||||
if (!mnp.Sign(keyMasternode, pubKeyMasternode)) {
|
||||
errorMessage = "Couldn't sign Masternode Ping";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update lastPing for our masternode in Masternode list
|
||||
CMasternode* pmn = mnodeman.Find(vin);
|
||||
if (pmn != NULL) {
|
||||
if (pmn->IsPingedWithin(MASTERNODE_PING_SECONDS, mnp.sigTime)) {
|
||||
errorMessage = "Too early to send Masternode Ping";
|
||||
return false;
|
||||
}
|
||||
|
||||
pmn->lastPing = mnp;
|
||||
mnodeman.mapSeenMasternodePing.insert(make_pair(mnp.GetHash(), mnp));
|
||||
|
||||
//mnodeman.mapSeenMasternodeBroadcast.lastPing is probably outdated, so we'll update it
|
||||
CMasternodeBroadcast mnb(*pmn);
|
||||
uint256 hash = mnb.GetHash();
|
||||
if (mnodeman.mapSeenMasternodeBroadcast.count(hash)) mnodeman.mapSeenMasternodeBroadcast[hash].lastPing = mnp;
|
||||
|
||||
mnp.Relay();
|
||||
|
||||
/*
|
||||
* IT'S SAFE TO REMOVE THIS IN FURTHER VERSIONS
|
||||
* AFTER MIGRATION TO V12 IS DONE
|
||||
*/
|
||||
|
||||
if (IsSporkActive(SPORK_10_MASTERNODE_PAY_UPDATED_NODES)) return true;
|
||||
// for migration purposes ping our node on old masternodes network too
|
||||
std::string retErrorMessage;
|
||||
std::vector<unsigned char> vchMasterNodeSignature;
|
||||
int64_t masterNodeSignatureTime = GetAdjustedTime();
|
||||
|
||||
std::string strMessage = service.ToString() + std::to_string(masterNodeSignatureTime) + std::to_string(false);
|
||||
|
||||
if (!obfuScationSigner.SignMessage(strMessage, retErrorMessage, vchMasterNodeSignature, keyMasternode)) {
|
||||
errorMessage = "dseep sign message failed: " + retErrorMessage;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!obfuScationSigner.VerifyMessage(pubKeyMasternode, vchMasterNodeSignature, strMessage, retErrorMessage)) {
|
||||
errorMessage = "dseep verify message failed: " + retErrorMessage;
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrint("masternode", "dseep - relaying from active mn, %s \n", vin.ToString().c_str());
|
||||
LOCK(cs_vNodes);
|
||||
for (CNode* pnode : vNodes)
|
||||
pnode->PushMessage("dseep", vin, vchMasterNodeSignature, masterNodeSignatureTime, false);
|
||||
|
||||
/*
|
||||
* END OF "REMOVE"
|
||||
*/
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// Seems like we are trying to send a ping while the Masternode is not registered in the network
|
||||
errorMessage = "Obfuscation Masternode List doesn't include our Masternode, shutting down Masternode pinging service! " + vin.ToString();
|
||||
status = ACTIVE_MASTERNODE_NOT_CAPABLE;
|
||||
notCapableReason = errorMessage;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CActiveMasternode::CreateBroadcast(std::string strService, std::string strKeyMasternode, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage, CMasternodeBroadcast &mnb, bool fOffline)
|
||||
{
|
||||
CTxIn vin;
|
||||
CPubKey pubKeyCollateralAddress;
|
||||
CKey keyCollateralAddress;
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
|
||||
//need correct blocks to send ping
|
||||
if (!fOffline && !masternodeSync.IsBlockchainSynced()) {
|
||||
errorMessage = "Sync in progress. Must wait until sync is complete to start Masternode";
|
||||
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!obfuScationSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode)) {
|
||||
errorMessage = strprintf("Can't find keys for masternode %s - %s", strService, errorMessage);
|
||||
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress, strTxHash, strOutputIndex)) {
|
||||
errorMessage = strprintf("Could not allocate vin %s:%s for masternode %s", strTxHash, strOutputIndex, strService);
|
||||
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
CService service = CService(strService);
|
||||
|
||||
// The service needs the correct default port to work properly
|
||||
if(!CMasternodeBroadcast::CheckDefaultPort(strService, errorMessage, "CActiveMasternode::CreateBroadcast()"))
|
||||
return false;
|
||||
|
||||
addrman.Add(CAddress(service), CNetAddr("127.0.0.1"), 2 * 60 * 60);
|
||||
|
||||
return CreateBroadcast(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage, mnb);
|
||||
}
|
||||
|
||||
bool CActiveMasternode::CreateBroadcast(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage, CMasternodeBroadcast &mnb)
|
||||
{
|
||||
// wait for reindex and/or import to finish
|
||||
if (fImporting || fReindex) return false;
|
||||
|
||||
CMasternodePing mnp(vin);
|
||||
if (!mnp.Sign(keyMasternode, pubKeyMasternode)) {
|
||||
errorMessage = strprintf("Failed to sign ping, vin: %s", vin.ToString());
|
||||
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
|
||||
mnb = CMasternodeBroadcast();
|
||||
return false;
|
||||
}
|
||||
|
||||
mnb = CMasternodeBroadcast(service, vin, pubKeyCollateralAddress, pubKeyMasternode, PROTOCOL_VERSION);
|
||||
mnb.lastPing = mnp;
|
||||
if (!mnb.Sign(keyCollateralAddress)) {
|
||||
errorMessage = strprintf("Failed to sign broadcast, vin: %s", vin.ToString());
|
||||
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
|
||||
mnb = CMasternodeBroadcast();
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* IT'S SAFE TO REMOVE THIS IN FURTHER VERSIONS
|
||||
* AFTER MIGRATION TO V12 IS DONE
|
||||
*/
|
||||
|
||||
if (IsSporkActive(SPORK_10_MASTERNODE_PAY_UPDATED_NODES)) return true;
|
||||
// for migration purposes inject our node in old masternodes' list too
|
||||
std::string retErrorMessage;
|
||||
std::vector<unsigned char> vchMasterNodeSignature;
|
||||
int64_t masterNodeSignatureTime = GetAdjustedTime();
|
||||
std::string donationAddress = "";
|
||||
int donationPercantage = 0;
|
||||
|
||||
std::string vchPubKey(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
|
||||
std::string vchPubKey2(pubKeyMasternode.begin(), pubKeyMasternode.end());
|
||||
|
||||
std::string strMessage = service.ToString() + std::to_string(masterNodeSignatureTime) + vchPubKey + vchPubKey2 + std::to_string(PROTOCOL_VERSION) + donationAddress + std::to_string(donationPercantage);
|
||||
|
||||
if (!obfuScationSigner.SignMessage(strMessage, retErrorMessage, vchMasterNodeSignature, keyCollateralAddress)) {
|
||||
errorMessage = "dsee sign message failed: " + retErrorMessage;
|
||||
LogPrintf("CActiveMasternode::Register() - Error: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!obfuScationSigner.VerifyMessage(pubKeyCollateralAddress, vchMasterNodeSignature, strMessage, retErrorMessage)) {
|
||||
errorMessage = "dsee verify message failed: " + retErrorMessage;
|
||||
LogPrintf("CActiveMasternode::Register() - Error: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
LOCK(cs_vNodes);
|
||||
for (CNode* pnode : vNodes)
|
||||
pnode->PushMessage("dsee", vin, service, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyCollateralAddress, pubKeyMasternode, -1, -1, masterNodeSignatureTime, PROTOCOL_VERSION, donationAddress, donationPercantage);
|
||||
|
||||
/*
|
||||
* END OF "REMOVE"
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey)
|
||||
{
|
||||
return GetMasterNodeVin(vin, pubkey, secretKey, "", "");
|
||||
}
|
||||
|
||||
bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex)
|
||||
{
|
||||
// wait for reindex and/or import to finish
|
||||
if (fImporting || fReindex) return false;
|
||||
|
||||
// Find possible candidates
|
||||
TRY_LOCK(pwalletMain->cs_wallet, fWallet);
|
||||
if (!fWallet) return false;
|
||||
|
||||
vector<COutput> possibleCoins = SelectCoinsMasternode();
|
||||
COutput* selectedOutput;
|
||||
|
||||
// Find the vin
|
||||
if (!strTxHash.empty()) {
|
||||
// Let's find it
|
||||
uint256 txHash(strTxHash);
|
||||
int outputIndex;
|
||||
try {
|
||||
outputIndex = std::stoi(strOutputIndex.c_str());
|
||||
} catch (const std::exception& e) {
|
||||
LogPrintf("%s: %s on strOutputIndex\n", __func__, e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (COutput& out : possibleCoins) {
|
||||
if (out.tx->GetHash() == txHash && out.i == outputIndex) {
|
||||
selectedOutput = &out;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
LogPrintf("CActiveMasternode::GetMasterNodeVin - Could not locate valid vin\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// No output specified, Select the first one
|
||||
if (possibleCoins.size() > 0) {
|
||||
selectedOutput = &possibleCoins[0];
|
||||
} else {
|
||||
LogPrintf("CActiveMasternode::GetMasterNodeVin - Could not locate specified vin from possible list\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we have a selected output, retrieve the associated info
|
||||
return GetVinFromOutput(*selectedOutput, vin, pubkey, secretKey);
|
||||
}
|
||||
|
||||
|
||||
// Extract Masternode vin information from output
|
||||
bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey)
|
||||
{
|
||||
// wait for reindex and/or import to finish
|
||||
if (fImporting || fReindex) return false;
|
||||
|
||||
CScript pubScript;
|
||||
|
||||
vin = CTxIn(out.tx->GetHash(), out.i);
|
||||
pubScript = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey
|
||||
|
||||
CTxDestination address1;
|
||||
ExtractDestination(pubScript, address1);
|
||||
CBitcoinAddress address2(address1);
|
||||
|
||||
CKeyID keyID;
|
||||
if (!address2.GetKeyID(keyID)) {
|
||||
LogPrintf("CActiveMasternode::GetMasterNodeVin - Address does not refer to a key\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pwalletMain->GetKey(keyID, secretKey)) {
|
||||
LogPrintf("CActiveMasternode::GetMasterNodeVin - Private key for address is not known\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pubkey = secretKey.GetPubKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
// get all possible outputs for running Masternode
|
||||
vector<COutput> CActiveMasternode::SelectCoinsMasternode()
|
||||
{
|
||||
vector<COutput> vCoins;
|
||||
vector<COutput> filteredCoins;
|
||||
vector<COutPoint> confLockedCoins;
|
||||
|
||||
// Temporary unlock MN coins from masternode.conf
|
||||
if (GetBoolArg("-mnconflock", true)) {
|
||||
uint256 mnTxHash;
|
||||
for (CMasternodeConfig::CMasternodeEntry mne : masternodeConfig.getEntries()) {
|
||||
mnTxHash.SetHex(mne.getTxHash());
|
||||
|
||||
int nIndex;
|
||||
if(!mne.castOutputIndex(nIndex))
|
||||
continue;
|
||||
|
||||
COutPoint outpoint = COutPoint(mnTxHash, nIndex);
|
||||
confLockedCoins.push_back(outpoint);
|
||||
pwalletMain->UnlockCoin(outpoint);
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve all possible outputs
|
||||
pwalletMain->AvailableCoins(vCoins);
|
||||
|
||||
// Lock MN coins from masternode.conf back if they where temporary unlocked
|
||||
if (!confLockedCoins.empty()) {
|
||||
for (COutPoint outpoint : confLockedCoins)
|
||||
pwalletMain->LockCoin(outpoint);
|
||||
}
|
||||
|
||||
// Filter
|
||||
for (const COutput& out : vCoins) {
|
||||
if (out.tx->vout[out.i].nValue == 10000 * COIN) { //exactly
|
||||
filteredCoins.push_back(out);
|
||||
}
|
||||
}
|
||||
return filteredCoins;
|
||||
}
|
||||
|
||||
// when starting a Masternode, this can enable to run as a hot wallet with no funds
|
||||
bool CActiveMasternode::EnableHotColdMasterNode(CTxIn& newVin, CService& newService)
|
||||
{
|
||||
if (!fMasterNode) return false;
|
||||
|
||||
status = ACTIVE_MASTERNODE_STARTED;
|
||||
|
||||
//The values below are needed for signing mnping messages going forward
|
||||
vin = newVin;
|
||||
service = newService;
|
||||
|
||||
LogPrintf("CActiveMasternode::EnableHotColdMasterNode() - Enabled! You may shut down the cold daemon.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (c) 2014-2016 The Dash developers
|
||||
// Copyright (c) 2015-2019 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef ACTIVEMASTERNODE_H
|
||||
#define ACTIVEMASTERNODE_H
|
||||
|
||||
#include "init.h"
|
||||
#include "key.h"
|
||||
#include "masternode.h"
|
||||
#include "net.h"
|
||||
#include "obfuscation.h"
|
||||
#include "sync.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#define ACTIVE_MASTERNODE_INITIAL 0 // initial state
|
||||
#define ACTIVE_MASTERNODE_SYNC_IN_PROCESS 1
|
||||
#define ACTIVE_MASTERNODE_INPUT_TOO_NEW 2
|
||||
#define ACTIVE_MASTERNODE_NOT_CAPABLE 3
|
||||
#define ACTIVE_MASTERNODE_STARTED 4
|
||||
|
||||
// Responsible for activating the Masternode and pinging the network
|
||||
class CActiveMasternode
|
||||
{
|
||||
private:
|
||||
// critical section to protect the inner data structures
|
||||
mutable CCriticalSection cs;
|
||||
|
||||
/// Ping Masternode
|
||||
bool SendMasternodePing(std::string& errorMessage);
|
||||
|
||||
/// Create Masternode broadcast, needs to be relayed manually after that
|
||||
bool CreateBroadcast(CTxIn vin, CService service, CKey key, CPubKey pubKey, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage, CMasternodeBroadcast &mnb);
|
||||
|
||||
/// Get 10000 AGR input that can be used for the Masternode
|
||||
bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex);
|
||||
bool GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey);
|
||||
|
||||
public:
|
||||
// Initialized by init.cpp
|
||||
// Keys for the main Masternode
|
||||
CPubKey pubKeyMasternode;
|
||||
|
||||
// Initialized while registering Masternode
|
||||
CTxIn vin;
|
||||
CService service;
|
||||
|
||||
int status;
|
||||
std::string notCapableReason;
|
||||
|
||||
CActiveMasternode()
|
||||
{
|
||||
status = ACTIVE_MASTERNODE_INITIAL;
|
||||
}
|
||||
|
||||
/// Manage status of main Masternode
|
||||
void ManageStatus();
|
||||
std::string GetStatus();
|
||||
|
||||
/// Create Masternode broadcast, needs to be relayed manually after that
|
||||
bool CreateBroadcast(std::string strService, std::string strKey, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage, CMasternodeBroadcast &mnb, bool fOffline = false);
|
||||
|
||||
/// Get 10000 AGR input that can be used for the Masternode
|
||||
bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey);
|
||||
vector<COutput> SelectCoinsMasternode();
|
||||
|
||||
/// Enable cold wallet mode (run a Masternode with no funds)
|
||||
bool EnableHotColdMasterNode(CTxIn& vin, CService& addr);
|
||||
};
|
||||
|
||||
#endif
|
||||
+503
@@ -0,0 +1,503 @@
|
||||
// Copyright (c) 2012 Pieter Wuille
|
||||
// Copyright (c) 2012-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "addrman.h"
|
||||
|
||||
#include "hash.h"
|
||||
#include "serialize.h"
|
||||
#include "streams.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int CAddrInfo::GetTriedBucket(const uint256& nKey) const
|
||||
{
|
||||
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetHash().GetLow64();
|
||||
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetHash().GetLow64();
|
||||
return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
|
||||
}
|
||||
|
||||
int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src) const
|
||||
{
|
||||
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
|
||||
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << vchSourceGroupKey).GetHash().GetLow64();
|
||||
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetHash().GetLow64();
|
||||
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
|
||||
}
|
||||
|
||||
int CAddrInfo::GetBucketPosition(const uint256& nKey, bool fNew, int nBucket) const
|
||||
{
|
||||
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << (fNew ? 'N' : 'K') << nBucket << GetKey()).GetHash().GetLow64();
|
||||
return hash1 % ADDRMAN_BUCKET_SIZE;
|
||||
}
|
||||
|
||||
bool CAddrInfo::IsTerrible(int64_t nNow) const
|
||||
{
|
||||
if (nLastTry && nLastTry >= nNow - 60) // never remove things tried in the last minute
|
||||
return false;
|
||||
|
||||
if (nTime > nNow + 10 * 60) // came in a flying DeLorean
|
||||
return true;
|
||||
|
||||
if (nTime == 0 || nNow - nTime > ADDRMAN_HORIZON_DAYS * 24 * 60 * 60) // not seen in recent history
|
||||
return true;
|
||||
|
||||
if (nLastSuccess == 0 && nAttempts >= ADDRMAN_RETRIES) // tried N times and never a success
|
||||
return true;
|
||||
|
||||
if (nNow - nLastSuccess > ADDRMAN_MIN_FAIL_DAYS * 24 * 60 * 60 && nAttempts >= ADDRMAN_MAX_FAILURES) // N successive failures in the last week
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
double CAddrInfo::GetChance(int64_t nNow) const
|
||||
{
|
||||
double fChance = 1.0;
|
||||
|
||||
int64_t nSinceLastSeen = nNow - nTime;
|
||||
int64_t nSinceLastTry = nNow - nLastTry;
|
||||
|
||||
if (nSinceLastSeen < 0)
|
||||
nSinceLastSeen = 0;
|
||||
if (nSinceLastTry < 0)
|
||||
nSinceLastTry = 0;
|
||||
|
||||
// deprioritize very recent attempts away
|
||||
if (nSinceLastTry < 60 * 10)
|
||||
fChance *= 0.01;
|
||||
|
||||
// deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages.
|
||||
fChance *= pow(0.66, min(nAttempts, 8));
|
||||
|
||||
return fChance;
|
||||
}
|
||||
|
||||
CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int* pnId)
|
||||
{
|
||||
std::map<CNetAddr, int>::iterator it = mapAddr.find(addr);
|
||||
if (it == mapAddr.end())
|
||||
return NULL;
|
||||
if (pnId)
|
||||
*pnId = (*it).second;
|
||||
std::map<int, CAddrInfo>::iterator it2 = mapInfo.find((*it).second);
|
||||
if (it2 != mapInfo.end())
|
||||
return &(*it2).second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CAddrInfo* CAddrMan::Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId)
|
||||
{
|
||||
int nId = nIdCount++;
|
||||
mapInfo[nId] = CAddrInfo(addr, addrSource);
|
||||
mapAddr[addr] = nId;
|
||||
mapInfo[nId].nRandomPos = vRandom.size();
|
||||
vRandom.push_back(nId);
|
||||
if (pnId)
|
||||
*pnId = nId;
|
||||
return &mapInfo[nId];
|
||||
}
|
||||
|
||||
void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
|
||||
{
|
||||
if (nRndPos1 == nRndPos2)
|
||||
return;
|
||||
|
||||
assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size());
|
||||
|
||||
int nId1 = vRandom[nRndPos1];
|
||||
int nId2 = vRandom[nRndPos2];
|
||||
|
||||
assert(mapInfo.count(nId1) == 1);
|
||||
assert(mapInfo.count(nId2) == 1);
|
||||
|
||||
mapInfo[nId1].nRandomPos = nRndPos2;
|
||||
mapInfo[nId2].nRandomPos = nRndPos1;
|
||||
|
||||
vRandom[nRndPos1] = nId2;
|
||||
vRandom[nRndPos2] = nId1;
|
||||
}
|
||||
|
||||
void CAddrMan::Delete(int nId)
|
||||
{
|
||||
assert(mapInfo.count(nId) != 0);
|
||||
CAddrInfo& info = mapInfo[nId];
|
||||
assert(!info.fInTried);
|
||||
assert(info.nRefCount == 0);
|
||||
|
||||
SwapRandom(info.nRandomPos, vRandom.size() - 1);
|
||||
vRandom.pop_back();
|
||||
mapAddr.erase(info);
|
||||
mapInfo.erase(nId);
|
||||
nNew--;
|
||||
}
|
||||
|
||||
void CAddrMan::ClearNew(int nUBucket, int nUBucketPos)
|
||||
{
|
||||
// if there is an entry in the specified bucket, delete it.
|
||||
if (vvNew[nUBucket][nUBucketPos] != -1) {
|
||||
int nIdDelete = vvNew[nUBucket][nUBucketPos];
|
||||
CAddrInfo& infoDelete = mapInfo[nIdDelete];
|
||||
assert(infoDelete.nRefCount > 0);
|
||||
infoDelete.nRefCount--;
|
||||
vvNew[nUBucket][nUBucketPos] = -1;
|
||||
if (infoDelete.nRefCount == 0) {
|
||||
Delete(nIdDelete);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CAddrMan::MakeTried(CAddrInfo& info, int nId)
|
||||
{
|
||||
// remove the entry from all new buckets
|
||||
for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
|
||||
int pos = info.GetBucketPosition(nKey, true, bucket);
|
||||
if (vvNew[bucket][pos] == nId) {
|
||||
vvNew[bucket][pos] = -1;
|
||||
info.nRefCount--;
|
||||
}
|
||||
}
|
||||
nNew--;
|
||||
|
||||
assert(info.nRefCount == 0);
|
||||
|
||||
// which tried bucket to move the entry to
|
||||
int nKBucket = info.GetTriedBucket(nKey);
|
||||
int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
|
||||
|
||||
// first make space to add it (the existing tried entry there is moved to new, deleting whatever is there).
|
||||
if (vvTried[nKBucket][nKBucketPos] != -1) {
|
||||
// find an item to evict
|
||||
int nIdEvict = vvTried[nKBucket][nKBucketPos];
|
||||
assert(mapInfo.count(nIdEvict) == 1);
|
||||
CAddrInfo& infoOld = mapInfo[nIdEvict];
|
||||
|
||||
// Remove the to-be-evicted item from the tried set.
|
||||
infoOld.fInTried = false;
|
||||
vvTried[nKBucket][nKBucketPos] = -1;
|
||||
nTried--;
|
||||
|
||||
// find which new bucket it belongs to
|
||||
int nUBucket = infoOld.GetNewBucket(nKey);
|
||||
int nUBucketPos = infoOld.GetBucketPosition(nKey, true, nUBucket);
|
||||
ClearNew(nUBucket, nUBucketPos);
|
||||
assert(vvNew[nUBucket][nUBucketPos] == -1);
|
||||
|
||||
// Enter it into the new set again.
|
||||
infoOld.nRefCount = 1;
|
||||
vvNew[nUBucket][nUBucketPos] = nIdEvict;
|
||||
nNew++;
|
||||
}
|
||||
assert(vvTried[nKBucket][nKBucketPos] == -1);
|
||||
|
||||
vvTried[nKBucket][nKBucketPos] = nId;
|
||||
nTried++;
|
||||
info.fInTried = true;
|
||||
}
|
||||
|
||||
void CAddrMan::Good_(const CService& addr, int64_t nTime)
|
||||
{
|
||||
int nId;
|
||||
CAddrInfo* pinfo = Find(addr, &nId);
|
||||
|
||||
// if not found, bail out
|
||||
if (!pinfo)
|
||||
return;
|
||||
|
||||
CAddrInfo& info = *pinfo;
|
||||
|
||||
// check whether we are talking about the exact same CService (including same port)
|
||||
if (info != addr)
|
||||
return;
|
||||
|
||||
// update info
|
||||
info.nLastSuccess = nTime;
|
||||
info.nLastTry = nTime;
|
||||
info.nAttempts = 0;
|
||||
// nTime is not updated here, to avoid leaking information about
|
||||
// currently-connected peers.
|
||||
|
||||
// if it is already in the tried set, don't do anything else
|
||||
if (info.fInTried)
|
||||
return;
|
||||
|
||||
// find a bucket it is in now
|
||||
int nRnd = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
|
||||
int nUBucket = -1;
|
||||
for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
|
||||
int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
|
||||
int nBpos = info.GetBucketPosition(nKey, true, nB);
|
||||
if (vvNew[nB][nBpos] == nId) {
|
||||
nUBucket = nB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if no bucket is found, something bad happened;
|
||||
// TODO: maybe re-add the node, but for now, just bail out
|
||||
if (nUBucket == -1)
|
||||
return;
|
||||
|
||||
LogPrint("addrman", "Moving %s to tried\n", addr.ToString());
|
||||
|
||||
// move nId to the tried tables
|
||||
MakeTried(info, nId);
|
||||
}
|
||||
|
||||
bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
{
|
||||
if (!addr.IsRoutable())
|
||||
return false;
|
||||
|
||||
bool fNew = false;
|
||||
int nId;
|
||||
CAddrInfo* pinfo = Find(addr, &nId);
|
||||
|
||||
if (pinfo) {
|
||||
// periodically update nTime
|
||||
bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
|
||||
int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
|
||||
if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty))
|
||||
pinfo->nTime = max((int64_t)0, addr.nTime - nTimePenalty);
|
||||
|
||||
// add services
|
||||
pinfo->nServices |= addr.nServices;
|
||||
|
||||
// do not update if no new information is present
|
||||
if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime))
|
||||
return false;
|
||||
|
||||
// do not update if the entry was already in the "tried" table
|
||||
if (pinfo->fInTried)
|
||||
return false;
|
||||
|
||||
// do not update if the max reference count is reached
|
||||
if (pinfo->nRefCount == ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
|
||||
return false;
|
||||
|
||||
// stochastic test: previous nRefCount == N: 2^N times harder to increase it
|
||||
int nFactor = 1;
|
||||
for (int n = 0; n < pinfo->nRefCount; n++)
|
||||
nFactor *= 2;
|
||||
if (nFactor > 1 && (RandomInt(nFactor) != 0))
|
||||
return false;
|
||||
} else {
|
||||
pinfo = Create(addr, source, &nId);
|
||||
pinfo->nTime = max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
|
||||
nNew++;
|
||||
fNew = true;
|
||||
}
|
||||
|
||||
int nUBucket = pinfo->GetNewBucket(nKey, source);
|
||||
int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket);
|
||||
if (vvNew[nUBucket][nUBucketPos] != nId) {
|
||||
bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
|
||||
if (!fInsert) {
|
||||
CAddrInfo& infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]];
|
||||
if (infoExisting.IsTerrible() || (infoExisting.nRefCount > 1 && pinfo->nRefCount == 0)) {
|
||||
// Overwrite the existing new table entry.
|
||||
fInsert = true;
|
||||
}
|
||||
}
|
||||
if (fInsert) {
|
||||
ClearNew(nUBucket, nUBucketPos);
|
||||
pinfo->nRefCount++;
|
||||
vvNew[nUBucket][nUBucketPos] = nId;
|
||||
} else {
|
||||
if (pinfo->nRefCount == 0) {
|
||||
Delete(nId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return fNew;
|
||||
}
|
||||
|
||||
void CAddrMan::Attempt_(const CService& addr, int64_t nTime)
|
||||
{
|
||||
CAddrInfo* pinfo = Find(addr);
|
||||
|
||||
// if not found, bail out
|
||||
if (!pinfo)
|
||||
return;
|
||||
|
||||
CAddrInfo& info = *pinfo;
|
||||
|
||||
// check whether we are talking about the exact same CService (including same port)
|
||||
if (info != addr)
|
||||
return;
|
||||
|
||||
// update info
|
||||
info.nLastTry = nTime;
|
||||
info.nAttempts++;
|
||||
}
|
||||
|
||||
CAddrInfo CAddrMan::Select_(bool newOnly)
|
||||
{
|
||||
if (size() == 0)
|
||||
return CAddrInfo();
|
||||
|
||||
if (newOnly && nNew == 0)
|
||||
return CAddrInfo();
|
||||
|
||||
// Use a 50% chance for choosing between tried and new table entries.
|
||||
if (!newOnly && (nTried > 0 && (nNew == 0 || RandomInt(2) == 0))) {
|
||||
// use a tried node
|
||||
double fChanceFactor = 1.0;
|
||||
while (1) {
|
||||
int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT);
|
||||
int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
|
||||
while (vvTried[nKBucket][nKBucketPos] == -1) {
|
||||
nKBucket = (nKBucket + insecure_rand()) % ADDRMAN_TRIED_BUCKET_COUNT;
|
||||
nKBucketPos = (nKBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE;
|
||||
}
|
||||
int nId = vvTried[nKBucket][nKBucketPos];
|
||||
assert(mapInfo.count(nId) == 1);
|
||||
CAddrInfo& info = mapInfo[nId];
|
||||
if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
|
||||
return info;
|
||||
fChanceFactor *= 1.2;
|
||||
}
|
||||
} else {
|
||||
// use a new node
|
||||
double fChanceFactor = 1.0;
|
||||
while (1) {
|
||||
int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
|
||||
int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
|
||||
while (vvNew[nUBucket][nUBucketPos] == -1) {
|
||||
nUBucket = (nUBucket + insecure_rand()) % ADDRMAN_NEW_BUCKET_COUNT;
|
||||
nUBucketPos = (nUBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE;
|
||||
}
|
||||
int nId = vvNew[nUBucket][nUBucketPos];
|
||||
assert(mapInfo.count(nId) == 1);
|
||||
CAddrInfo& info = mapInfo[nId];
|
||||
if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
|
||||
return info;
|
||||
fChanceFactor *= 1.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
int CAddrMan::Check_()
|
||||
{
|
||||
std::set<int> setTried;
|
||||
std::map<int, int> mapNew;
|
||||
|
||||
if (vRandom.size() != nTried + nNew)
|
||||
return -7;
|
||||
|
||||
for (std::map<int, CAddrInfo>::iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
|
||||
int n = (*it).first;
|
||||
CAddrInfo& info = (*it).second;
|
||||
if (info.fInTried) {
|
||||
if (!info.nLastSuccess)
|
||||
return -1;
|
||||
if (info.nRefCount)
|
||||
return -2;
|
||||
setTried.insert(n);
|
||||
} else {
|
||||
if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
|
||||
return -3;
|
||||
if (!info.nRefCount)
|
||||
return -4;
|
||||
mapNew[n] = info.nRefCount;
|
||||
}
|
||||
if (mapAddr[info] != n)
|
||||
return -5;
|
||||
if (info.nRandomPos < 0 || info.nRandomPos >= vRandom.size() || vRandom[info.nRandomPos] != n)
|
||||
return -14;
|
||||
if (info.nLastTry < 0)
|
||||
return -6;
|
||||
if (info.nLastSuccess < 0)
|
||||
return -8;
|
||||
}
|
||||
|
||||
if (setTried.size() != nTried)
|
||||
return -9;
|
||||
if (mapNew.size() != nNew)
|
||||
return -10;
|
||||
|
||||
for (int n = 0; n < ADDRMAN_TRIED_BUCKET_COUNT; n++) {
|
||||
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
|
||||
if (vvTried[n][i] != -1) {
|
||||
if (!setTried.count(vvTried[n][i]))
|
||||
return -11;
|
||||
if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey) != n)
|
||||
return -17;
|
||||
if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
|
||||
return -18;
|
||||
setTried.erase(vvTried[n][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
|
||||
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
|
||||
if (vvNew[n][i] != -1) {
|
||||
if (!mapNew.count(vvNew[n][i]))
|
||||
return -12;
|
||||
if (mapInfo[vvNew[n][i]].GetBucketPosition(nKey, true, n) != i)
|
||||
return -19;
|
||||
if (--mapNew[vvNew[n][i]] == 0)
|
||||
mapNew.erase(vvNew[n][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (setTried.size())
|
||||
return -13;
|
||||
if (mapNew.size())
|
||||
return -15;
|
||||
if (nKey.IsNull())
|
||||
return -16;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr)
|
||||
{
|
||||
unsigned int nNodes = ADDRMAN_GETADDR_MAX_PCT * vRandom.size() / 100;
|
||||
if (nNodes > ADDRMAN_GETADDR_MAX)
|
||||
nNodes = ADDRMAN_GETADDR_MAX;
|
||||
|
||||
// gather a list of random nodes, skipping those of low quality
|
||||
for (unsigned int n = 0; n < vRandom.size(); n++) {
|
||||
if (vAddr.size() >= nNodes)
|
||||
break;
|
||||
|
||||
int nRndPos = RandomInt(vRandom.size() - n) + n;
|
||||
SwapRandom(n, nRndPos);
|
||||
assert(mapInfo.count(vRandom[n]) == 1);
|
||||
|
||||
const CAddrInfo& ai = mapInfo[vRandom[n]];
|
||||
if (!ai.IsTerrible())
|
||||
vAddr.push_back(ai);
|
||||
}
|
||||
}
|
||||
|
||||
void CAddrMan::Connected_(const CService& addr, int64_t nTime)
|
||||
{
|
||||
CAddrInfo* pinfo = Find(addr);
|
||||
|
||||
// if not found, bail out
|
||||
if (!pinfo)
|
||||
return;
|
||||
|
||||
CAddrInfo& info = *pinfo;
|
||||
|
||||
// check whether we are talking about the exact same CService (including same port)
|
||||
if (info != addr)
|
||||
return;
|
||||
|
||||
// update info
|
||||
int64_t nUpdateInterval = 20 * 60;
|
||||
if (nTime - info.nTime > nUpdateInterval)
|
||||
info.nTime = nTime;
|
||||
}
|
||||
|
||||
int CAddrMan::RandomInt(int nMax){
|
||||
return GetRandInt(nMax);
|
||||
}
|
||||
+578
@@ -0,0 +1,578 @@
|
||||
// Copyright (c) 2012 Pieter Wuille
|
||||
// Copyright (c) 2012-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_ADDRMAN_H
|
||||
#define BITCOIN_ADDRMAN_H
|
||||
|
||||
#include "netbase.h"
|
||||
#include "protocol.h"
|
||||
#include "random.h"
|
||||
#include "sync.h"
|
||||
#include "timedata.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Extended statistics about a CAddress
|
||||
*/
|
||||
class CAddrInfo : public CAddress
|
||||
{
|
||||
|
||||
|
||||
public:
|
||||
//! last try whatsoever by us (memory only)
|
||||
int64_t nLastTry;
|
||||
|
||||
private:
|
||||
//! where knowledge about this address first came from
|
||||
CNetAddr source;
|
||||
|
||||
//! last successful connection by us
|
||||
int64_t nLastSuccess;
|
||||
|
||||
//! connection attempts since last successful attempt
|
||||
int nAttempts;
|
||||
|
||||
//! reference count in new sets (memory only)
|
||||
int nRefCount;
|
||||
|
||||
//! in tried set? (memory only)
|
||||
bool fInTried;
|
||||
|
||||
//! position in vRandom
|
||||
int nRandomPos;
|
||||
|
||||
friend class CAddrMan;
|
||||
|
||||
public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(*(CAddress*)this);
|
||||
READWRITE(source);
|
||||
READWRITE(nLastSuccess);
|
||||
READWRITE(nAttempts);
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
nLastSuccess = 0;
|
||||
nLastTry = 0;
|
||||
nAttempts = 0;
|
||||
nRefCount = 0;
|
||||
fInTried = false;
|
||||
nRandomPos = -1;
|
||||
}
|
||||
|
||||
CAddrInfo(const CAddress& addrIn, const CNetAddr& addrSource) : CAddress(addrIn), source(addrSource)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
CAddrInfo() : CAddress(), source()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
//! Calculate in which "tried" bucket this entry belongs
|
||||
int GetTriedBucket(const uint256& nKey) const;
|
||||
|
||||
//! Calculate in which "new" bucket this entry belongs, given a certain source
|
||||
int GetNewBucket(const uint256& nKey, const CNetAddr& src) const;
|
||||
|
||||
//! Calculate in which "new" bucket this entry belongs, using its default source
|
||||
int GetNewBucket(const uint256& nKey) const
|
||||
{
|
||||
return GetNewBucket(nKey, source);
|
||||
}
|
||||
|
||||
//! Calculate in which position of a bucket to store this entry.
|
||||
int GetBucketPosition(const uint256& nKey, bool fNew, int nBucket) const;
|
||||
|
||||
//! Determine whether the statistics about this entry are bad enough so that it can just be deleted
|
||||
bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
|
||||
|
||||
//! Calculate the relative chance this entry should be given when selecting nodes to connect to
|
||||
double GetChance(int64_t nNow = GetAdjustedTime()) const;
|
||||
};
|
||||
|
||||
/** Stochastic address manager
|
||||
*
|
||||
* Design goals:
|
||||
* * Keep the address tables in-memory, and asynchronously dump the entire to able in peers.dat.
|
||||
* * Make sure no (localized) attacker can fill the entire table with his nodes/addresses.
|
||||
*
|
||||
* To that end:
|
||||
* * Addresses are organized into buckets.
|
||||
* * Address that have not yet been tried go into 1024 "new" buckets.
|
||||
* * Based on the address range (/16 for IPv4) of source of the information, 64 buckets are selected at random
|
||||
* * The actual bucket is chosen from one of these, based on the range the address itself is located.
|
||||
* * One single address can occur in up to 8 different buckets, to increase selection chances for addresses that
|
||||
* are seen frequently. The chance for increasing this multiplicity decreases exponentially.
|
||||
* * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen
|
||||
* ones) is removed from it first.
|
||||
* * Addresses of nodes that are known to be accessible go into 256 "tried" buckets.
|
||||
* * Each address range selects at random 8 of these buckets.
|
||||
* * The actual bucket is chosen from one of these, based on the full address.
|
||||
* * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently
|
||||
* tried ones) is evicted from it, back to the "new" buckets.
|
||||
* * Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not
|
||||
* be observable by adversaries.
|
||||
* * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN will introduce frequent (and expensive)
|
||||
* consistency checks for the entire data structure.
|
||||
*/
|
||||
|
||||
//! total number of buckets for tried addresses
|
||||
#define ADDRMAN_TRIED_BUCKET_COUNT 256
|
||||
|
||||
//! total number of buckets for new addresses
|
||||
#define ADDRMAN_NEW_BUCKET_COUNT 1024
|
||||
|
||||
//! maximum allowed number of entries in buckets for new and tried addresses
|
||||
#define ADDRMAN_BUCKET_SIZE 64
|
||||
|
||||
//! over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread
|
||||
#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8
|
||||
|
||||
//! over how many buckets entries with new addresses originating from a single group are spread
|
||||
#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64
|
||||
|
||||
//! in how many buckets for entries with new addresses a single address may occur
|
||||
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8
|
||||
|
||||
//! how old addresses can maximally be
|
||||
#define ADDRMAN_HORIZON_DAYS 30
|
||||
|
||||
//! after how many failed attempts we give up on a new node
|
||||
#define ADDRMAN_RETRIES 3
|
||||
|
||||
//! how many successive failures are allowed ...
|
||||
#define ADDRMAN_MAX_FAILURES 10
|
||||
|
||||
//! ... in at least this many days
|
||||
#define ADDRMAN_MIN_FAIL_DAYS 7
|
||||
|
||||
//! the maximum percentage of nodes to return in a getaddr call
|
||||
#define ADDRMAN_GETADDR_MAX_PCT 23
|
||||
|
||||
//! the maximum number of nodes to return in a getaddr call
|
||||
#define ADDRMAN_GETADDR_MAX 2500
|
||||
|
||||
/**
|
||||
* Stochastical (IP) address manager
|
||||
*/
|
||||
class CAddrMan
|
||||
{
|
||||
private:
|
||||
//! critical section to protect the inner data structures
|
||||
mutable CCriticalSection cs;
|
||||
|
||||
//! last used nId
|
||||
int nIdCount;
|
||||
|
||||
//! table with information about all nIds
|
||||
std::map<int, CAddrInfo> mapInfo;
|
||||
|
||||
//! find an nId based on its network address
|
||||
std::map<CNetAddr, int> mapAddr;
|
||||
|
||||
//! randomly-ordered vector of all nIds
|
||||
std::vector<int> vRandom;
|
||||
|
||||
// number of "tried" entries
|
||||
int nTried;
|
||||
|
||||
//! list of "tried" buckets
|
||||
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
|
||||
|
||||
//! number of (unique) "new" entries
|
||||
int nNew;
|
||||
|
||||
//! list of "new" buckets
|
||||
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
|
||||
|
||||
protected:
|
||||
//! secret key to randomize bucket select with
|
||||
uint256 nKey;
|
||||
|
||||
//! Find an entry.
|
||||
CAddrInfo* Find(const CNetAddr& addr, int* pnId = NULL);
|
||||
|
||||
//! find an entry, creating it if necessary.
|
||||
//! nTime and nServices of the found node are updated, if necessary.
|
||||
CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = NULL);
|
||||
|
||||
//! Swap two elements in vRandom.
|
||||
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2);
|
||||
|
||||
//! Move an entry from the "new" table(s) to the "tried" table
|
||||
void MakeTried(CAddrInfo& info, int nId);
|
||||
|
||||
//! Delete an entry. It must not be in tried, and have refcount 0.
|
||||
void Delete(int nId);
|
||||
|
||||
//! Clear a position in a "new" table. This is the only place where entries are actually deleted.
|
||||
void ClearNew(int nUBucket, int nUBucketPos);
|
||||
|
||||
//! Mark an entry "good", possibly moving it from "new" to "tried".
|
||||
void Good_(const CService& addr, int64_t nTime);
|
||||
|
||||
//! Add an entry to the "new" table.
|
||||
bool Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty);
|
||||
|
||||
//! Mark an entry as attempted to connect.
|
||||
void Attempt_(const CService& addr, int64_t nTime);
|
||||
|
||||
//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
|
||||
CAddrInfo Select_(bool newOnly);
|
||||
|
||||
//! Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic.
|
||||
virtual int RandomInt(int nMax);
|
||||
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
//! Perform consistency check. Returns an error code or zero.
|
||||
int Check_();
|
||||
#endif
|
||||
|
||||
//! Select several addresses at once.
|
||||
void GetAddr_(std::vector<CAddress>& vAddr);
|
||||
|
||||
//! Mark an entry as currently-connected-to.
|
||||
void Connected_(const CService& addr, int64_t nTime);
|
||||
|
||||
public:
|
||||
/**
|
||||
* serialized format:
|
||||
* * version byte (currently 1)
|
||||
* * 0x20 + nKey (serialized as if it were a vector, for backward compatibility)
|
||||
* * nNew
|
||||
* * nTried
|
||||
* * number of "new" buckets XOR 2**30
|
||||
* * all nNew addrinfos in vvNew
|
||||
* * all nTried addrinfos in vvTried
|
||||
* * for each bucket:
|
||||
* * number of elements
|
||||
* * for each element: index
|
||||
*
|
||||
* 2**30 is xorred with the number of buckets to make addrman deserializer v0 detect it
|
||||
* as incompatible. This is necessary because it did not check the version number on
|
||||
* deserialization.
|
||||
*
|
||||
* Notice that vvTried, mapAddr and vVector are never encoded explicitly;
|
||||
* they are instead reconstructed from the other information.
|
||||
*
|
||||
* vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change,
|
||||
* otherwise it is reconstructed as well.
|
||||
*
|
||||
* This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
|
||||
* changes to the ADDRMAN_ parameters without breaking the on-disk structure.
|
||||
*
|
||||
* We don't use ADD_SERIALIZE_METHODS since the serialization and deserialization code has
|
||||
* very little in common.
|
||||
*/
|
||||
template <typename Stream>
|
||||
void Serialize(Stream& s, int nType, int nVersionDummy) const
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
unsigned char nVersion = 1;
|
||||
s << nVersion;
|
||||
s << ((unsigned char)32);
|
||||
s << nKey;
|
||||
s << nNew;
|
||||
s << nTried;
|
||||
|
||||
int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
|
||||
s << nUBuckets;
|
||||
std::map<int, int> mapUnkIds;
|
||||
int nIds = 0;
|
||||
for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
|
||||
mapUnkIds[(*it).first] = nIds;
|
||||
const CAddrInfo& info = (*it).second;
|
||||
if (info.nRefCount) {
|
||||
assert(nIds != nNew); // this means nNew was wrong, oh ow
|
||||
s << info;
|
||||
nIds++;
|
||||
}
|
||||
}
|
||||
nIds = 0;
|
||||
for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
|
||||
const CAddrInfo& info = (*it).second;
|
||||
if (info.fInTried) {
|
||||
assert(nIds != nTried); // this means nTried was wrong, oh ow
|
||||
s << info;
|
||||
nIds++;
|
||||
}
|
||||
}
|
||||
for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
|
||||
int nSize = 0;
|
||||
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
|
||||
if (vvNew[bucket][i] != -1)
|
||||
nSize++;
|
||||
}
|
||||
s << nSize;
|
||||
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
|
||||
if (vvNew[bucket][i] != -1) {
|
||||
int nIndex = mapUnkIds[vvNew[bucket][i]];
|
||||
s << nIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s, int nType, int nVersionDummy)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
Clear();
|
||||
|
||||
unsigned char nVersion;
|
||||
s >> nVersion;
|
||||
unsigned char nKeySize;
|
||||
s >> nKeySize;
|
||||
if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman deserialization");
|
||||
s >> nKey;
|
||||
s >> nNew;
|
||||
s >> nTried;
|
||||
int nUBuckets = 0;
|
||||
s >> nUBuckets;
|
||||
if (nVersion != 0) {
|
||||
nUBuckets ^= (1 << 30);
|
||||
}
|
||||
|
||||
// Deserialize entries from the new table.
|
||||
for (int n = 0; n < nNew; n++) {
|
||||
CAddrInfo& info = mapInfo[n];
|
||||
s >> info;
|
||||
mapAddr[info] = n;
|
||||
info.nRandomPos = vRandom.size();
|
||||
vRandom.push_back(n);
|
||||
if (nVersion != 1 || nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) {
|
||||
// In case the new table data cannot be used (nVersion unknown, or bucket count wrong),
|
||||
// immediately try to give them a reference based on their primary source address.
|
||||
int nUBucket = info.GetNewBucket(nKey);
|
||||
int nUBucketPos = info.GetBucketPosition(nKey, true, nUBucket);
|
||||
if (vvNew[nUBucket][nUBucketPos] == -1) {
|
||||
vvNew[nUBucket][nUBucketPos] = n;
|
||||
info.nRefCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
nIdCount = nNew;
|
||||
|
||||
// Deserialize entries from the tried table.
|
||||
int nLost = 0;
|
||||
for (int n = 0; n < nTried; n++) {
|
||||
CAddrInfo info;
|
||||
s >> info;
|
||||
int nKBucket = info.GetTriedBucket(nKey);
|
||||
int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
|
||||
if (vvTried[nKBucket][nKBucketPos] == -1) {
|
||||
info.nRandomPos = vRandom.size();
|
||||
info.fInTried = true;
|
||||
vRandom.push_back(nIdCount);
|
||||
mapInfo[nIdCount] = info;
|
||||
mapAddr[info] = nIdCount;
|
||||
vvTried[nKBucket][nKBucketPos] = nIdCount;
|
||||
nIdCount++;
|
||||
} else {
|
||||
nLost++;
|
||||
}
|
||||
}
|
||||
nTried -= nLost;
|
||||
|
||||
// Deserialize positions in the new table (if possible).
|
||||
for (int bucket = 0; bucket < nUBuckets; bucket++) {
|
||||
int nSize = 0;
|
||||
s >> nSize;
|
||||
for (int n = 0; n < nSize; n++) {
|
||||
int nIndex = 0;
|
||||
s >> nIndex;
|
||||
if (nIndex >= 0 && nIndex < nNew) {
|
||||
CAddrInfo& info = mapInfo[nIndex];
|
||||
int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
|
||||
if (nVersion == 1 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) {
|
||||
info.nRefCount++;
|
||||
vvNew[bucket][nUBucketPos] = nIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prune new entries with refcount 0 (as a result of collisions).
|
||||
int nLostUnk = 0;
|
||||
for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end();) {
|
||||
if (it->second.fInTried == false && it->second.nRefCount == 0) {
|
||||
std::map<int, CAddrInfo>::const_iterator itCopy = it++;
|
||||
Delete(itCopy->first);
|
||||
nLostUnk++;
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
if (nLost + nLostUnk > 0) {
|
||||
LogPrint("addrman", "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
|
||||
}
|
||||
|
||||
Check();
|
||||
}
|
||||
|
||||
unsigned int GetSerializeSize(int nType, int nVersion) const
|
||||
{
|
||||
return (CSizeComputer(nType, nVersion) << *this).size();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
std::vector<int>().swap(vRandom);
|
||||
nKey = GetRandHash();
|
||||
for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
|
||||
for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
|
||||
vvNew[bucket][entry] = -1;
|
||||
}
|
||||
}
|
||||
for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
|
||||
for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
|
||||
vvTried[bucket][entry] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
nIdCount = 0;
|
||||
nTried = 0;
|
||||
nNew = 0;
|
||||
}
|
||||
|
||||
CAddrMan()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
~CAddrMan()
|
||||
{
|
||||
nKey = uint256();
|
||||
}
|
||||
|
||||
//! Return the number of (unique) addresses in all tables.
|
||||
int size()
|
||||
{
|
||||
return vRandom.size();
|
||||
}
|
||||
|
||||
//! Consistency check
|
||||
void Check()
|
||||
{
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
{
|
||||
LOCK(cs);
|
||||
int err;
|
||||
if ((err = Check_()))
|
||||
LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Add a single address.
|
||||
bool Add(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty = 0)
|
||||
{
|
||||
bool fRet = false;
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
fRet |= Add_(addr, source, nTimePenalty);
|
||||
Check();
|
||||
}
|
||||
if (fRet)
|
||||
LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
|
||||
return fRet;
|
||||
}
|
||||
|
||||
//! Add multiple addresses.
|
||||
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
|
||||
{
|
||||
int nAdd = 0;
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
|
||||
nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
|
||||
Check();
|
||||
}
|
||||
if (nAdd)
|
||||
LogPrint("addrman", "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
|
||||
return nAdd > 0;
|
||||
}
|
||||
|
||||
//! Mark an entry as accessible.
|
||||
void Good(const CService& addr, int64_t nTime = GetAdjustedTime())
|
||||
{
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
Good_(addr, nTime);
|
||||
Check();
|
||||
}
|
||||
}
|
||||
|
||||
//! Mark an entry as connection attempted to.
|
||||
void Attempt(const CService& addr, int64_t nTime = GetAdjustedTime())
|
||||
{
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
Attempt_(addr, nTime);
|
||||
Check();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose an address to connect to.
|
||||
* nUnkBias determines how much "new" entries are favored over "tried" ones (0-100).
|
||||
*/
|
||||
CAddrInfo Select(bool newOnly = false)
|
||||
{
|
||||
CAddrInfo addrRet;
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
addrRet = Select_(newOnly);
|
||||
Check();
|
||||
}
|
||||
return addrRet;
|
||||
}
|
||||
|
||||
//! Return a bunch of addresses, selected at random.
|
||||
std::vector<CAddress> GetAddr()
|
||||
{
|
||||
Check();
|
||||
std::vector<CAddress> vAddr;
|
||||
{
|
||||
LOCK(cs);
|
||||
GetAddr_(vAddr);
|
||||
}
|
||||
Check();
|
||||
return vAddr;
|
||||
}
|
||||
|
||||
//! Mark an entry as currently-connected-to.
|
||||
void Connected(const CService& addr, int64_t nTime = GetAdjustedTime())
|
||||
{
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
Connected_(addr, nTime);
|
||||
Check();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BITCOIN_ADDRMAN_H
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <windows.h> // needed for VERSIONINFO
|
||||
#include "clientversion.h" // holds the needed client version information
|
||||
|
||||
#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
|
||||
#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
|
||||
#define VER_FILEVERSION VER_PRODUCTVERSION
|
||||
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4" // U.S. English - multilingual (hex)
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Agrarian"
|
||||
VALUE "FileDescription", "Agrarian-cli (OSS RPC client for Agrarian)"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "agrarian-cli"
|
||||
VALUE "LegalCopyright", COPYRIGHT_STR
|
||||
VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
|
||||
VALUE "OriginalFilename", "agrarian-cli.exe"
|
||||
VALUE "ProductName", "Agrarian-cli"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
|
||||
END
|
||||
END
|
||||
@@ -0,0 +1,321 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2015 The Bitcoin developers
|
||||
// Copyright (c) 2009-2015 The Dash developers
|
||||
// Copyright (c) 2015-2018 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "chainparamsbase.h"
|
||||
#include "clientversion.h"
|
||||
#include "rpc/client.h"
|
||||
#include "rpc/protocol.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <event2/event.h>
|
||||
#include <event2/http.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/keyvalq_struct.h>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
#define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
|
||||
|
||||
std::string HelpMessageCli()
|
||||
{
|
||||
string strUsage;
|
||||
strUsage += HelpMessageGroup(_("Options:"));
|
||||
strUsage += HelpMessageOpt("-?", _("This help message"));
|
||||
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "agrarian.conf"));
|
||||
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
|
||||
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
|
||||
strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be "
|
||||
"solved instantly. This is intended for regression testing tools and app development."));
|
||||
strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1"));
|
||||
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 51335, 61335));
|
||||
strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
|
||||
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
|
||||
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
|
||||
strUsage += HelpMessageOpt("-rpcclienttimeout=<n>", strprintf(_("Timeout during HTTP requests (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT));
|
||||
|
||||
return strUsage;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Start
|
||||
//
|
||||
|
||||
//
|
||||
// Exception thrown on connection error. This error is used to determine
|
||||
// when to wait if -rpcwait is given.
|
||||
//
|
||||
class CConnectionFailed : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit inline CConnectionFailed(const std::string& msg) : std::runtime_error(msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static bool AppInitRPC(int argc, char* argv[])
|
||||
{
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
ParseParameters(argc, argv);
|
||||
if (argc < 2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) {
|
||||
std::string strUsage = _("Agrarian Core RPC client version") + " " + FormatFullVersion() + "\n";
|
||||
if (!mapArgs.count("-version")) {
|
||||
strUsage += "\n" + _("Usage:") + "\n" +
|
||||
" agrarian-cli [options] <command> [params] " + _("Send command to Agrarian Core") + "\n" +
|
||||
" agrarian-cli [options] help " + _("List commands") + "\n" +
|
||||
" agrarian-cli [options] help <command> " + _("Get help for a command") + "\n";
|
||||
|
||||
strUsage += "\n" + HelpMessageCli();
|
||||
}
|
||||
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
return false;
|
||||
}
|
||||
if (!boost::filesystem::is_directory(GetDataDir(false))) {
|
||||
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ReadConfigFile(mapArgs, mapMultiArgs);
|
||||
} catch (std::exception& e) {
|
||||
fprintf(stderr, "Error reading configuration file: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
// Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
|
||||
if (!SelectBaseParamsFromCommandLine()) {
|
||||
fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
|
||||
return false;
|
||||
}
|
||||
if (GetBoolArg("-rpcssl", false))
|
||||
{
|
||||
fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** Reply structure for request_done to fill in */
|
||||
struct HTTPReply
|
||||
{
|
||||
int status;
|
||||
std::string body;
|
||||
};
|
||||
|
||||
static void http_request_done(struct evhttp_request *req, void *ctx)
|
||||
{
|
||||
HTTPReply *reply = static_cast<HTTPReply*>(ctx);
|
||||
|
||||
if (req == NULL) {
|
||||
/* If req is NULL, it means an error occurred while connecting, but
|
||||
* I'm not sure how to find out which one. We also don't really care.
|
||||
*/
|
||||
reply->status = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
reply->status = evhttp_request_get_response_code(req);
|
||||
|
||||
struct evbuffer *buf = evhttp_request_get_input_buffer(req);
|
||||
if (buf)
|
||||
{
|
||||
size_t size = evbuffer_get_length(buf);
|
||||
const char *data = (const char*)evbuffer_pullup(buf, size);
|
||||
if (data)
|
||||
reply->body = std::string(data, size);
|
||||
evbuffer_drain(buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
UniValue CallRPC(const string& strMethod, const UniValue& params)
|
||||
{
|
||||
std::string host = GetArg("-rpcconnect", "127.0.0.1");
|
||||
int port = GetArg("-rpcport", BaseParams().RPCPort());
|
||||
|
||||
// Create event base
|
||||
struct event_base *base = event_base_new(); // TODO RAII
|
||||
if (!base)
|
||||
throw runtime_error("cannot create event_base");
|
||||
|
||||
// Synchronously look up hostname
|
||||
struct evhttp_connection *evcon = evhttp_connection_base_new(base, NULL, host.c_str(), port); // TODO RAII
|
||||
if (evcon == NULL)
|
||||
throw runtime_error("create connection failed");
|
||||
evhttp_connection_set_timeout(evcon, GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT));
|
||||
|
||||
HTTPReply response;
|
||||
struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII
|
||||
if (req == NULL)
|
||||
throw runtime_error("create http request failed");
|
||||
|
||||
// Get credentials
|
||||
std::string strRPCUserColonPass;
|
||||
if (mapArgs["-rpcpassword"] == "") {
|
||||
// Try fall back to cookie-based authentication if no password is provided
|
||||
if (!GetAuthCookie(&strRPCUserColonPass)) {
|
||||
throw runtime_error(strprintf(
|
||||
_("Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"),
|
||||
GetConfigFile().string().c_str()));
|
||||
|
||||
}
|
||||
} else {
|
||||
strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
|
||||
}
|
||||
|
||||
struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req);
|
||||
assert(output_headers);
|
||||
evhttp_add_header(output_headers, "Host", host.c_str());
|
||||
evhttp_add_header(output_headers, "Connection", "close");
|
||||
evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str());
|
||||
|
||||
// Attach request data
|
||||
std::string strRequest = JSONRPCRequest(strMethod, params, 1);
|
||||
struct evbuffer * output_buffer = evhttp_request_get_output_buffer(req);
|
||||
assert(output_buffer);
|
||||
evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
|
||||
|
||||
int r = evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/");
|
||||
if (r != 0) {
|
||||
evhttp_connection_free(evcon);
|
||||
event_base_free(base);
|
||||
throw CConnectionFailed("send http request failed");
|
||||
}
|
||||
|
||||
event_base_dispatch(base);
|
||||
evhttp_connection_free(evcon);
|
||||
event_base_free(base);
|
||||
|
||||
if (response.status == 0)
|
||||
throw CConnectionFailed("couldn't connect to server");
|
||||
else if (response.status == HTTP_UNAUTHORIZED)
|
||||
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
||||
else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
|
||||
throw runtime_error(strprintf("server returned HTTP error %d", response.status));
|
||||
else if (response.body.empty())
|
||||
throw runtime_error("no response from server");
|
||||
|
||||
// Parse reply
|
||||
UniValue valReply(UniValue::VSTR);
|
||||
if (!valReply.read(response.body))
|
||||
throw runtime_error("couldn't parse reply from server");
|
||||
const UniValue& reply = valReply.get_obj();
|
||||
if (reply.empty())
|
||||
throw runtime_error("expected reply to have result, error and id properties");
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
int CommandLineRPC(int argc, char* argv[])
|
||||
{
|
||||
string strPrint;
|
||||
int nRet = 0;
|
||||
try {
|
||||
// Skip switches
|
||||
while (argc > 1 && IsSwitchChar(argv[1][0])) {
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
// Method
|
||||
if (argc < 2)
|
||||
throw runtime_error("too few parameters");
|
||||
string strMethod = argv[1];
|
||||
|
||||
// Parameters default to strings
|
||||
std::vector<std::string> strParams(&argv[2], &argv[argc]);
|
||||
UniValue params = RPCConvertValues(strMethod, strParams);
|
||||
|
||||
// Execute and handle connection failures with -rpcwait
|
||||
const bool fWait = GetBoolArg("-rpcwait", false);
|
||||
do {
|
||||
try {
|
||||
const UniValue reply = CallRPC(strMethod, params);
|
||||
|
||||
// Parse reply
|
||||
const UniValue& result = find_value(reply, "result");
|
||||
const UniValue& error = find_value(reply, "error");
|
||||
|
||||
if (!error.isNull()) {
|
||||
// Error
|
||||
int code = error["code"].get_int();
|
||||
if (fWait && code == RPC_IN_WARMUP)
|
||||
throw CConnectionFailed("server in warmup");
|
||||
strPrint = "error: " + error.write();
|
||||
nRet = abs(code);
|
||||
} else {
|
||||
// Result
|
||||
if (result.isNull())
|
||||
strPrint = "";
|
||||
else if (result.isStr())
|
||||
strPrint = result.get_str();
|
||||
else
|
||||
strPrint = result.write(2);
|
||||
}
|
||||
// Connection succeeded, no need to retry.
|
||||
break;
|
||||
} catch (const CConnectionFailed& e) {
|
||||
if (fWait)
|
||||
MilliSleep(1000);
|
||||
else
|
||||
throw;
|
||||
}
|
||||
} while (fWait);
|
||||
} catch (boost::thread_interrupted) {
|
||||
throw;
|
||||
} catch (std::exception& e) {
|
||||
strPrint = string("error: ") + e.what();
|
||||
nRet = EXIT_FAILURE;
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "CommandLineRPC()");
|
||||
throw;
|
||||
}
|
||||
|
||||
if (strPrint != "") {
|
||||
fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
SetupEnvironment();
|
||||
if (!SetupNetworking()) {
|
||||
fprintf(stderr, "Error: Initializing networking failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!AppInitRPC(argc, argv))
|
||||
return EXIT_FAILURE;
|
||||
} catch (std::exception& e) {
|
||||
PrintExceptionContinue(&e, "AppInitRPC()");
|
||||
return EXIT_FAILURE;
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "AppInitRPC()");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int ret = EXIT_FAILURE;
|
||||
try {
|
||||
ret = CommandLineRPC(argc, argv);
|
||||
} catch (std::exception& e) {
|
||||
PrintExceptionContinue(&e, "CommandLineRPC()");
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "CommandLineRPC()");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <windows.h> // needed for VERSIONINFO
|
||||
#include "clientversion.h" // holds the needed client version information
|
||||
|
||||
#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
|
||||
#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
|
||||
#define VER_FILEVERSION VER_PRODUCTVERSION
|
||||
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4" // U.S. English - multilingual (hex)
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Agrarian"
|
||||
VALUE "FileDescription", "agrarian-tx (CLI Agrarian transaction editor utility)"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "agrarian-tx"
|
||||
VALUE "LegalCopyright", COPYRIGHT_STR
|
||||
VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
|
||||
VALUE "OriginalFilename", "agrarian-tx.exe"
|
||||
VALUE "ProductName", "agrarian-tx"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
|
||||
END
|
||||
END
|
||||
@@ -0,0 +1,642 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2015-2019 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "base58.h"
|
||||
#include "clientversion.h"
|
||||
#include "coins.h"
|
||||
#include "core_io.h"
|
||||
#include "keystore.h"
|
||||
#include "primitives/block.h" // for MAX_BLOCK_SIZE
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
#include "script/sign.h"
|
||||
#include "guiinterface.h" // for _(...)
|
||||
#include <univalue.h>
|
||||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
using namespace boost::assign;
|
||||
using namespace std;
|
||||
|
||||
static bool fCreateBlank;
|
||||
static map<string, UniValue> registers;
|
||||
CClientUIInterface uiInterface;
|
||||
|
||||
static bool AppInitRawTx(int argc, char* argv[])
|
||||
{
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
ParseParameters(argc, argv);
|
||||
|
||||
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
|
||||
if (!SelectParamsFromCommandLine()) {
|
||||
fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
fCreateBlank = GetBoolArg("-create", false);
|
||||
|
||||
if (argc < 2 || mapArgs.count("-?") || mapArgs.count("-help")) {
|
||||
// First part of help message is specific to this utility
|
||||
std::string strUsage = _("Agrarian Core agrarian-tx utility version") + " " + FormatFullVersion() + "\n\n" +
|
||||
_("Usage:") + "\n" +
|
||||
" agrarian-tx [options] <hex-tx> [commands] " + _("Update hex-encoded agrarian transaction") + "\n" +
|
||||
" agrarian-tx [options] -create [commands] " + _("Create hex-encoded agrarian transaction") + "\n" +
|
||||
"\n";
|
||||
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
|
||||
strUsage = HelpMessageGroup(_("Options:"));
|
||||
strUsage += HelpMessageOpt("-?", _("This help message"));
|
||||
strUsage += HelpMessageOpt("-create", _("Create new, empty TX."));
|
||||
strUsage += HelpMessageOpt("-json", _("Select JSON output"));
|
||||
strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction."));
|
||||
strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly."));
|
||||
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
|
||||
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
|
||||
|
||||
strUsage = HelpMessageGroup(_("Commands:"));
|
||||
strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
|
||||
strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
|
||||
strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
|
||||
strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
|
||||
strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
|
||||
strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
|
||||
strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX"));
|
||||
strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
|
||||
_("This command requires JSON registers:") +
|
||||
_("prevtxs=JSON object") + ", " +
|
||||
_("privatekeys=JSON object") + ". " +
|
||||
_("See signrawtransaction docs for format of sighash flags, JSON objects."));
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
|
||||
strUsage = HelpMessageGroup(_("Register Commands:"));
|
||||
strUsage += HelpMessageOpt("load=NAME:FILENAME", _("Load JSON file FILENAME into register NAME"));
|
||||
strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING"));
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void RegisterSetJson(const string& key, const string& rawJson)
|
||||
{
|
||||
UniValue val;
|
||||
if (!val.read(rawJson)) {
|
||||
string strErr = "Cannot parse JSON for key " + key;
|
||||
throw runtime_error(strErr);
|
||||
}
|
||||
|
||||
registers[key] = val;
|
||||
}
|
||||
|
||||
static void RegisterSet(const string& strInput)
|
||||
{
|
||||
// separate NAME:VALUE in string
|
||||
size_t pos = strInput.find(':');
|
||||
if ((pos == string::npos) ||
|
||||
(pos == 0) ||
|
||||
(pos == (strInput.size() - 1)))
|
||||
throw runtime_error("Register input requires NAME:VALUE");
|
||||
|
||||
string key = strInput.substr(0, pos);
|
||||
string valStr = strInput.substr(pos + 1, string::npos);
|
||||
|
||||
RegisterSetJson(key, valStr);
|
||||
}
|
||||
|
||||
static void RegisterLoad(const string& strInput)
|
||||
{
|
||||
// separate NAME:FILENAME in string
|
||||
size_t pos = strInput.find(':');
|
||||
if ((pos == string::npos) ||
|
||||
(pos == 0) ||
|
||||
(pos == (strInput.size() - 1)))
|
||||
throw runtime_error("Register load requires NAME:FILENAME");
|
||||
|
||||
string key = strInput.substr(0, pos);
|
||||
string filename = strInput.substr(pos + 1, string::npos);
|
||||
|
||||
FILE* f = fopen(filename.c_str(), "r");
|
||||
if (!f) {
|
||||
string strErr = "Cannot open file " + filename;
|
||||
throw runtime_error(strErr);
|
||||
}
|
||||
|
||||
// load file chunks into one big buffer
|
||||
string valStr;
|
||||
while ((!feof(f)) && (!ferror(f))) {
|
||||
char buf[4096];
|
||||
int bread = fread(buf, 1, sizeof(buf), f);
|
||||
if (bread <= 0)
|
||||
break;
|
||||
|
||||
valStr.insert(valStr.size(), buf, bread);
|
||||
}
|
||||
|
||||
if (ferror(f)) {
|
||||
string strErr = "Error reading file " + filename;
|
||||
throw runtime_error(strErr);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
// evaluate as JSON buffer register
|
||||
RegisterSetJson(key, valStr);
|
||||
}
|
||||
|
||||
static void MutateTxVersion(CMutableTransaction& tx, const string& cmdVal)
|
||||
{
|
||||
int64_t newVersion = atoi64(cmdVal);
|
||||
if (newVersion < 1 || newVersion > CTransaction::CURRENT_VERSION)
|
||||
throw runtime_error("Invalid TX version requested");
|
||||
|
||||
tx.nVersion = (int)newVersion;
|
||||
}
|
||||
|
||||
static void MutateTxLocktime(CMutableTransaction& tx, const string& cmdVal)
|
||||
{
|
||||
int64_t newLocktime = atoi64(cmdVal);
|
||||
if (newLocktime < 0LL || newLocktime > 0xffffffffLL)
|
||||
throw runtime_error("Invalid TX locktime requested");
|
||||
|
||||
tx.nLockTime = (unsigned int)newLocktime;
|
||||
}
|
||||
|
||||
static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
|
||||
{
|
||||
// separate TXID:VOUT in string
|
||||
size_t pos = strInput.find(':');
|
||||
if ((pos == string::npos) ||
|
||||
(pos == 0) ||
|
||||
(pos == (strInput.size() - 1)))
|
||||
throw runtime_error("TX input missing separator");
|
||||
|
||||
// extract and validate TXID
|
||||
string strTxid = strInput.substr(0, pos);
|
||||
if ((strTxid.size() != 64) || !IsHex(strTxid))
|
||||
throw runtime_error("invalid TX input txid");
|
||||
uint256 txid(strTxid);
|
||||
|
||||
static const unsigned int minTxOutSz = 9;
|
||||
unsigned int nMaxSize = MAX_BLOCK_SIZE_LEGACY;
|
||||
static const unsigned int maxVout = nMaxSize / minTxOutSz;
|
||||
|
||||
// extract and validate vout
|
||||
string strVout = strInput.substr(pos + 1, string::npos);
|
||||
int vout = atoi(strVout);
|
||||
if ((vout < 0) || (vout > (int)maxVout))
|
||||
throw runtime_error("invalid TX input vout");
|
||||
|
||||
// append to transaction input list
|
||||
CTxIn txin(txid, vout);
|
||||
tx.vin.push_back(txin);
|
||||
}
|
||||
|
||||
static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput)
|
||||
{
|
||||
// separate VALUE:ADDRESS in string
|
||||
size_t pos = strInput.find(':');
|
||||
if ((pos == string::npos) ||
|
||||
(pos == 0) ||
|
||||
(pos == (strInput.size() - 1)))
|
||||
throw runtime_error("TX output missing separator");
|
||||
|
||||
// extract and validate VALUE
|
||||
string strValue = strInput.substr(0, pos);
|
||||
CAmount value;
|
||||
if (!ParseMoney(strValue, value))
|
||||
throw runtime_error("invalid TX output value");
|
||||
|
||||
// extract and validate ADDRESS
|
||||
string strAddr = strInput.substr(pos + 1, string::npos);
|
||||
CBitcoinAddress addr(strAddr);
|
||||
if (!addr.IsValid())
|
||||
throw runtime_error("invalid TX output address");
|
||||
|
||||
// build standard output script via GetScriptForDestination()
|
||||
CScript scriptPubKey = GetScriptForDestination(addr.Get());
|
||||
|
||||
// construct TxOut, append to transaction output list
|
||||
CTxOut txout(value, scriptPubKey);
|
||||
tx.vout.push_back(txout);
|
||||
}
|
||||
|
||||
static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput)
|
||||
{
|
||||
// separate VALUE:SCRIPT in string
|
||||
size_t pos = strInput.find(':');
|
||||
if ((pos == string::npos) ||
|
||||
(pos == 0))
|
||||
throw runtime_error("TX output missing separator");
|
||||
|
||||
// extract and validate VALUE
|
||||
string strValue = strInput.substr(0, pos);
|
||||
CAmount value;
|
||||
if (!ParseMoney(strValue, value))
|
||||
throw runtime_error("invalid TX output value");
|
||||
|
||||
// extract and validate script
|
||||
string strScript = strInput.substr(pos + 1, string::npos);
|
||||
CScript scriptPubKey = ParseScript(strScript); // throws on err
|
||||
|
||||
// construct TxOut, append to transaction output list
|
||||
CTxOut txout(value, scriptPubKey);
|
||||
tx.vout.push_back(txout);
|
||||
}
|
||||
|
||||
static void MutateTxDelInput(CMutableTransaction& tx, const string& strInIdx)
|
||||
{
|
||||
// parse requested deletion index
|
||||
int inIdx = atoi(strInIdx);
|
||||
if (inIdx < 0 || inIdx >= (int)tx.vin.size()) {
|
||||
string strErr = "Invalid TX input index '" + strInIdx + "'";
|
||||
throw runtime_error(strErr.c_str());
|
||||
}
|
||||
|
||||
// delete input from transaction
|
||||
tx.vin.erase(tx.vin.begin() + inIdx);
|
||||
}
|
||||
|
||||
static void MutateTxDelOutput(CMutableTransaction& tx, const string& strOutIdx)
|
||||
{
|
||||
// parse requested deletion index
|
||||
int outIdx = atoi(strOutIdx);
|
||||
if (outIdx < 0 || outIdx >= (int)tx.vout.size()) {
|
||||
string strErr = "Invalid TX output index '" + strOutIdx + "'";
|
||||
throw runtime_error(strErr.c_str());
|
||||
}
|
||||
|
||||
// delete output from transaction
|
||||
tx.vout.erase(tx.vout.begin() + outIdx);
|
||||
}
|
||||
|
||||
static const unsigned int N_SIGHASH_OPTS = 6;
|
||||
static const struct {
|
||||
const char* flagStr;
|
||||
int flags;
|
||||
} sighashOptions[N_SIGHASH_OPTS] = {
|
||||
{"ALL", SIGHASH_ALL},
|
||||
{"NONE", SIGHASH_NONE},
|
||||
{"SINGLE", SIGHASH_SINGLE},
|
||||
{"ALL|ANYONECANPAY", SIGHASH_ALL | SIGHASH_ANYONECANPAY},
|
||||
{"NONE|ANYONECANPAY", SIGHASH_NONE | SIGHASH_ANYONECANPAY},
|
||||
{"SINGLE|ANYONECANPAY", SIGHASH_SINGLE | SIGHASH_ANYONECANPAY},
|
||||
};
|
||||
|
||||
static bool findSighashFlags(int& flags, const string& flagStr)
|
||||
{
|
||||
flags = 0;
|
||||
|
||||
for (unsigned int i = 0; i < N_SIGHASH_OPTS; i++) {
|
||||
if (flagStr == sighashOptions[i].flagStr) {
|
||||
flags = sighashOptions[i].flags;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint256 ParseHashUO(map<string, UniValue>& o, string strKey)
|
||||
{
|
||||
if (!o.count(strKey))
|
||||
return 0;
|
||||
return ParseHashUV(o[strKey], strKey);
|
||||
}
|
||||
|
||||
vector<unsigned char> ParseHexUO(map<string, UniValue>& o, string strKey)
|
||||
{
|
||||
if (!o.count(strKey)) {
|
||||
vector<unsigned char> emptyVec;
|
||||
return emptyVec;
|
||||
}
|
||||
return ParseHexUV(o[strKey], strKey);
|
||||
}
|
||||
|
||||
static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
|
||||
{
|
||||
int nHashType = SIGHASH_ALL;
|
||||
|
||||
if (flagStr.size() > 0)
|
||||
if (!findSighashFlags(nHashType, flagStr))
|
||||
throw runtime_error("unknown sighash flag/sign option");
|
||||
|
||||
vector<CTransaction> txVariants;
|
||||
txVariants.push_back(tx);
|
||||
|
||||
// mergedTx will end up with all the signatures; it
|
||||
// starts as a clone of the raw tx:
|
||||
CMutableTransaction mergedTx(txVariants[0]);
|
||||
bool fComplete = true;
|
||||
CCoinsView viewDummy;
|
||||
CCoinsViewCache view(&viewDummy);
|
||||
|
||||
if (!registers.count("privatekeys"))
|
||||
throw runtime_error("privatekeys register variable must be set.");
|
||||
bool fGivenKeys = false;
|
||||
CBasicKeyStore tempKeystore;
|
||||
UniValue keysObj = registers["privatekeys"];
|
||||
fGivenKeys = true;
|
||||
|
||||
for (unsigned int kidx = 0; kidx < keysObj.size(); kidx++) {
|
||||
if (!keysObj[kidx].isStr())
|
||||
throw runtime_error("privatekey not a string");
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(keysObj[kidx].getValStr());
|
||||
if (!fGood)
|
||||
throw runtime_error("privatekey not valid");
|
||||
|
||||
CKey key = vchSecret.GetKey();
|
||||
tempKeystore.AddKey(key);
|
||||
}
|
||||
|
||||
// Add previous txouts given in the RPC call:
|
||||
if (!registers.count("prevtxs"))
|
||||
throw runtime_error("prevtxs register variable must be set.");
|
||||
UniValue prevtxsObj = registers["prevtxs"];
|
||||
{
|
||||
for (unsigned int previdx = 0; previdx < prevtxsObj.size(); previdx++) {
|
||||
UniValue prevOut = prevtxsObj[previdx];
|
||||
if (!prevOut.isObject())
|
||||
throw runtime_error("expected prevtxs internal object");
|
||||
|
||||
map<string, UniValue::VType> types = map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR);
|
||||
if (!prevOut.checkObject(types))
|
||||
throw runtime_error("prevtxs internal object typecheck fail");
|
||||
|
||||
uint256 txid = ParseHashUV(prevOut["txid"], "txid");
|
||||
|
||||
int nOut = atoi(prevOut["vout"].getValStr());
|
||||
if (nOut < 0)
|
||||
throw runtime_error("vout must be positive");
|
||||
|
||||
vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
|
||||
CScript scriptPubKey(pkData.begin(), pkData.end());
|
||||
|
||||
{
|
||||
CCoinsModifier coins = view.ModifyCoins(txid);
|
||||
if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
|
||||
string err("Previous output scriptPubKey mismatch:\n");
|
||||
err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n" +
|
||||
scriptPubKey.ToString();
|
||||
throw runtime_error(err);
|
||||
}
|
||||
if ((unsigned int)nOut >= coins->vout.size())
|
||||
coins->vout.resize(nOut + 1);
|
||||
coins->vout[nOut].scriptPubKey = scriptPubKey;
|
||||
coins->vout[nOut].nValue = 0; // we don't know the actual output value
|
||||
}
|
||||
|
||||
// if redeemScript given and private keys given,
|
||||
// add redeemScript to the tempKeystore so it can be signed:
|
||||
if (fGivenKeys && scriptPubKey.IsPayToScriptHash() &&
|
||||
prevOut.exists("redeemScript")) {
|
||||
UniValue v = prevOut["redeemScript"];
|
||||
vector<unsigned char> rsData(ParseHexUV(v, "redeemScript"));
|
||||
CScript redeemScript(rsData.begin(), rsData.end());
|
||||
tempKeystore.AddCScript(redeemScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CKeyStore& keystore = tempKeystore;
|
||||
|
||||
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
|
||||
|
||||
// Sign what we can:
|
||||
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
|
||||
CTxIn& txin = mergedTx.vin[i];
|
||||
const CCoins* coins = view.AccessCoins(txin.prevout.hash);
|
||||
if (!coins || !coins->IsAvailable(txin.prevout.n)) {
|
||||
fComplete = false;
|
||||
continue;
|
||||
}
|
||||
const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
|
||||
|
||||
txin.scriptSig.clear();
|
||||
// Only sign SIGHASH_SINGLE if there's a corresponding output:
|
||||
if (!fHashSingle || (i < mergedTx.vout.size()))
|
||||
SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
|
||||
|
||||
// ... and merge in other signatures:
|
||||
for (const CTransaction& txv : txVariants) {
|
||||
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
|
||||
}
|
||||
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
|
||||
fComplete = false;
|
||||
}
|
||||
|
||||
if (fComplete) {
|
||||
// do nothing... for now
|
||||
// perhaps store this for later optional JSON output
|
||||
}
|
||||
|
||||
tx = mergedTx;
|
||||
}
|
||||
|
||||
class Secp256k1Init
|
||||
{
|
||||
ECCVerifyHandle globalVerifyHandle;
|
||||
|
||||
public:
|
||||
Secp256k1Init() {
|
||||
ECC_Start();
|
||||
}
|
||||
~Secp256k1Init() {
|
||||
ECC_Stop();
|
||||
}
|
||||
};
|
||||
|
||||
static void MutateTx(CMutableTransaction& tx, const string& command, const string& commandVal)
|
||||
{
|
||||
boost::scoped_ptr<Secp256k1Init> ecc;
|
||||
if (command == "nversion")
|
||||
MutateTxVersion(tx, commandVal);
|
||||
else if (command == "locktime")
|
||||
MutateTxLocktime(tx, commandVal);
|
||||
|
||||
else if (command == "delin")
|
||||
MutateTxDelInput(tx, commandVal);
|
||||
else if (command == "in")
|
||||
MutateTxAddInput(tx, commandVal);
|
||||
|
||||
else if (command == "delout")
|
||||
MutateTxDelOutput(tx, commandVal);
|
||||
else if (command == "outaddr")
|
||||
MutateTxAddOutAddr(tx, commandVal);
|
||||
else if (command == "outscript")
|
||||
MutateTxAddOutScript(tx, commandVal);
|
||||
|
||||
else if (command == "sign"){
|
||||
if (!ecc) { ecc.reset(new Secp256k1Init()); }
|
||||
MutateTxSign(tx, commandVal);
|
||||
}
|
||||
|
||||
else if (command == "load")
|
||||
RegisterLoad(commandVal);
|
||||
|
||||
else if (command == "set")
|
||||
RegisterSet(commandVal);
|
||||
|
||||
else
|
||||
throw runtime_error("unknown command");
|
||||
}
|
||||
|
||||
static void OutputTxJSON(const CTransaction& tx)
|
||||
{
|
||||
UniValue entry(UniValue::VOBJ);
|
||||
TxToUniv(tx, 0, entry);
|
||||
|
||||
string jsonOutput = entry.write(4);
|
||||
fprintf(stdout, "%s\n", jsonOutput.c_str());
|
||||
}
|
||||
|
||||
static void OutputTxHash(const CTransaction& tx)
|
||||
{
|
||||
string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id)
|
||||
|
||||
fprintf(stdout, "%s\n", strHexHash.c_str());
|
||||
}
|
||||
|
||||
static void OutputTxHex(const CTransaction& tx)
|
||||
{
|
||||
string strHex = EncodeHexTx(tx);
|
||||
|
||||
fprintf(stdout, "%s\n", strHex.c_str());
|
||||
}
|
||||
|
||||
static void OutputTx(const CTransaction& tx)
|
||||
{
|
||||
if (GetBoolArg("-json", false))
|
||||
OutputTxJSON(tx);
|
||||
else if (GetBoolArg("-txid", false))
|
||||
OutputTxHash(tx);
|
||||
else
|
||||
OutputTxHex(tx);
|
||||
}
|
||||
|
||||
static string readStdin()
|
||||
{
|
||||
char buf[4096];
|
||||
string ret;
|
||||
|
||||
while (!feof(stdin)) {
|
||||
size_t bread = fread(buf, 1, sizeof(buf), stdin);
|
||||
ret.append(buf, bread);
|
||||
if (bread < sizeof(buf))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ferror(stdin))
|
||||
throw runtime_error("error reading stdin");
|
||||
|
||||
boost::algorithm::trim_right(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int CommandLineRawTx(int argc, char* argv[])
|
||||
{
|
||||
string strPrint;
|
||||
int nRet = 0;
|
||||
try {
|
||||
// Skip switches; Permit common stdin convention "-"
|
||||
while (argc > 1 && IsSwitchChar(argv[1][0]) &&
|
||||
(argv[1][1] != 0)) {
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
CTransaction txDecodeTmp;
|
||||
int startArg;
|
||||
|
||||
if (!fCreateBlank) {
|
||||
// require at least one param
|
||||
if (argc < 2)
|
||||
throw runtime_error("too few parameters");
|
||||
|
||||
// param: hex-encoded agrarian transaction
|
||||
string strHexTx(argv[1]);
|
||||
if (strHexTx == "-") // "-" implies standard input
|
||||
strHexTx = readStdin();
|
||||
|
||||
if (!DecodeHexTx(txDecodeTmp, strHexTx))
|
||||
throw runtime_error("invalid transaction encoding");
|
||||
|
||||
startArg = 2;
|
||||
} else
|
||||
startArg = 1;
|
||||
|
||||
CMutableTransaction tx(txDecodeTmp);
|
||||
|
||||
for (int i = startArg; i < argc; i++) {
|
||||
string arg = argv[i];
|
||||
string key, value;
|
||||
size_t eqpos = arg.find('=');
|
||||
if (eqpos == string::npos)
|
||||
key = arg;
|
||||
else {
|
||||
key = arg.substr(0, eqpos);
|
||||
value = arg.substr(eqpos + 1);
|
||||
}
|
||||
|
||||
MutateTx(tx, key, value);
|
||||
}
|
||||
|
||||
OutputTx(tx);
|
||||
}
|
||||
|
||||
catch (boost::thread_interrupted) {
|
||||
throw;
|
||||
} catch (std::exception& e) {
|
||||
strPrint = string("error: ") + e.what();
|
||||
nRet = EXIT_FAILURE;
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "CommandLineRawTx()");
|
||||
throw;
|
||||
}
|
||||
|
||||
if (strPrint != "") {
|
||||
fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
SetupEnvironment();
|
||||
|
||||
try {
|
||||
if (!AppInitRawTx(argc, argv))
|
||||
return EXIT_FAILURE;
|
||||
} catch (std::exception& e) {
|
||||
PrintExceptionContinue(&e, "AppInitRawTx()");
|
||||
return EXIT_FAILURE;
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "AppInitRawTx()");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int ret = EXIT_FAILURE;
|
||||
try {
|
||||
ret = CommandLineRawTx(argc, argv);
|
||||
} catch (std::exception& e) {
|
||||
PrintExceptionContinue(&e, "CommandLineRawTx()");
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "CommandLineRawTx()");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <windows.h> // needed for VERSIONINFO
|
||||
#include "clientversion.h" // holds the needed client version information
|
||||
|
||||
#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
|
||||
#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
|
||||
#define VER_FILEVERSION VER_PRODUCTVERSION
|
||||
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4" // U.S. English - multilingual (hex)
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Agrarian"
|
||||
VALUE "FileDescription", "agrariand (OSS daemon/client for Agrarian)"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "agrariand"
|
||||
VALUE "LegalCopyright", COPYRIGHT_STR
|
||||
VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
|
||||
VALUE "OriginalFilename", "agrariand.exe"
|
||||
VALUE "ProductName", "agrariand"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
|
||||
END
|
||||
END
|
||||
@@ -0,0 +1,168 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2014-2015 The Dash developers
|
||||
// Copyright (c) 2015-2019 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "clientversion.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
#include "masternodeconfig.h"
|
||||
#include "noui.h"
|
||||
#include "rpc/server.h"
|
||||
#include "guiinterface.h"
|
||||
#include "util.h"
|
||||
#include "httpserver.h"
|
||||
#include "httprpc.h"
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Introduction text for doxygen: */
|
||||
|
||||
/*! \mainpage Developer documentation
|
||||
*
|
||||
* \section intro_sec Introduction
|
||||
*
|
||||
* This is the developer documentation of the reference client for an experimental new digital currency called Agrarian (http://www.agrarian.org),
|
||||
* which enables instant payments to anyone, anywhere in the world. Agrarian uses peer-to-peer technology to operate
|
||||
* with no central authority: managing transactions and issuing money are carried out collectively by the network.
|
||||
*
|
||||
* The software is a community-driven open source project, released under the MIT license.
|
||||
*
|
||||
* \section Navigation
|
||||
* Use the buttons <code>Namespaces</code>, <code>Classes</code> or <code>Files</code> at the top of the page to start navigating the code.
|
||||
*/
|
||||
|
||||
static bool fDaemon;
|
||||
|
||||
void WaitForShutdown()
|
||||
{
|
||||
bool fShutdown = ShutdownRequested();
|
||||
// Tell the main threads to shutdown.
|
||||
while (!fShutdown) {
|
||||
MilliSleep(200);
|
||||
fShutdown = ShutdownRequested();
|
||||
}
|
||||
Interrupt();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Start
|
||||
//
|
||||
bool AppInit(int argc, char* argv[])
|
||||
{
|
||||
bool fRet = false;
|
||||
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
// If Qt is used, parameters/agrarian.conf are parsed in qt/agrarian.cpp's main()
|
||||
ParseParameters(argc, argv);
|
||||
|
||||
// Process help and version before taking care about datadir
|
||||
if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) {
|
||||
std::string strUsage = _("Agrarian Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n";
|
||||
|
||||
if (mapArgs.count("-version")) {
|
||||
strUsage += LicenseInfo();
|
||||
} else {
|
||||
strUsage += "\n" + _("Usage:") + "\n" +
|
||||
" agrariand [options] " + _("Start Agrarian Core Daemon") + "\n";
|
||||
|
||||
strUsage += "\n" + HelpMessage(HMM_BITCOIND);
|
||||
}
|
||||
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!boost::filesystem::is_directory(GetDataDir(false))) {
|
||||
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ReadConfigFile(mapArgs, mapMultiArgs);
|
||||
} catch (std::exception& e) {
|
||||
fprintf(stderr, "Error reading configuration file: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
|
||||
if (!SelectParamsFromCommandLine()) {
|
||||
fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse masternode.conf
|
||||
std::string strErr;
|
||||
if (!masternodeConfig.read(strErr)) {
|
||||
fprintf(stderr, "Error reading masternode configuration file: %s\n", strErr.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Command-line RPC
|
||||
bool fCommandLine = false;
|
||||
for (int i = 1; i < argc; i++)
|
||||
if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "agrarian:"))
|
||||
fCommandLine = true;
|
||||
|
||||
if (fCommandLine) {
|
||||
fprintf(stderr, "Error: There is no RPC client functionality in agrariand anymore. Use the agrarian-cli utility instead.\n");
|
||||
exit(1);
|
||||
}
|
||||
#ifndef WIN32
|
||||
fDaemon = GetBoolArg("-daemon", false);
|
||||
if (fDaemon) {
|
||||
fprintf(stdout, "Agrarian server starting\n");
|
||||
|
||||
// Daemonize
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
|
||||
return false;
|
||||
}
|
||||
if (pid > 0) // Parent process, pid is child process id
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Child process falls through to rest of initialization
|
||||
|
||||
pid_t sid = setsid();
|
||||
if (sid < 0)
|
||||
fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
|
||||
}
|
||||
#endif
|
||||
SoftSetBoolArg("-server", true);
|
||||
|
||||
fRet = AppInit2();
|
||||
} catch (std::exception& e) {
|
||||
PrintExceptionContinue(&e, "AppInit()");
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "AppInit()");
|
||||
}
|
||||
|
||||
if (!fRet) {
|
||||
Interrupt();
|
||||
} else {
|
||||
WaitForShutdown();
|
||||
}
|
||||
Shutdown();
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
SetupEnvironment();
|
||||
|
||||
// Connect agrariand signal handlers
|
||||
noui_connect();
|
||||
|
||||
return (AppInit(argc, argv) ? 0 : 1);
|
||||
}
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "alert.h"
|
||||
|
||||
#include "chainparams.h"
|
||||
#include "clientversion.h"
|
||||
#include "net.h"
|
||||
#include "pubkey.h"
|
||||
#include "timedata.h"
|
||||
#include "guiinterface.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
map<uint256, CAlert> mapAlerts;
|
||||
CCriticalSection cs_mapAlerts;
|
||||
|
||||
void CUnsignedAlert::SetNull()
|
||||
{
|
||||
nVersion = 1;
|
||||
nRelayUntil = 0;
|
||||
nExpiration = 0;
|
||||
nID = 0;
|
||||
nCancel = 0;
|
||||
setCancel.clear();
|
||||
nMinVer = 0;
|
||||
nMaxVer = 0;
|
||||
setSubVer.clear();
|
||||
nPriority = 0;
|
||||
|
||||
strComment.clear();
|
||||
strStatusBar.clear();
|
||||
strReserved.clear();
|
||||
}
|
||||
|
||||
std::string CUnsignedAlert::ToString() const
|
||||
{
|
||||
std::string strSetCancel;
|
||||
for (auto& n: setCancel)
|
||||
strSetCancel += strprintf("%d ", n);
|
||||
std::string strSetSubVer;
|
||||
for (std::string str : setSubVer)
|
||||
strSetSubVer += "\"" + str + "\" ";
|
||||
return strprintf(
|
||||
"CAlert(\n"
|
||||
" nVersion = %d\n"
|
||||
" nRelayUntil = %d\n"
|
||||
" nExpiration = %d\n"
|
||||
" nID = %d\n"
|
||||
" nCancel = %d\n"
|
||||
" setCancel = %s\n"
|
||||
" nMinVer = %d\n"
|
||||
" nMaxVer = %d\n"
|
||||
" setSubVer = %s\n"
|
||||
" nPriority = %d\n"
|
||||
" strComment = \"%s\"\n"
|
||||
" strStatusBar = \"%s\"\n"
|
||||
")\n",
|
||||
nVersion,
|
||||
nRelayUntil,
|
||||
nExpiration,
|
||||
nID,
|
||||
nCancel,
|
||||
strSetCancel,
|
||||
nMinVer,
|
||||
nMaxVer,
|
||||
strSetSubVer,
|
||||
nPriority,
|
||||
strComment,
|
||||
strStatusBar);
|
||||
}
|
||||
|
||||
void CAlert::SetNull()
|
||||
{
|
||||
CUnsignedAlert::SetNull();
|
||||
vchMsg.clear();
|
||||
vchSig.clear();
|
||||
}
|
||||
|
||||
bool CAlert::IsNull() const
|
||||
{
|
||||
return (nExpiration == 0);
|
||||
}
|
||||
|
||||
uint256 CAlert::GetHash() const
|
||||
{
|
||||
return Hash(this->vchMsg.begin(), this->vchMsg.end());
|
||||
}
|
||||
|
||||
bool CAlert::IsInEffect() const
|
||||
{
|
||||
return (GetAdjustedTime() < nExpiration);
|
||||
}
|
||||
|
||||
bool CAlert::Cancels(const CAlert& alert) const
|
||||
{
|
||||
if (!IsInEffect())
|
||||
return false; // this was a no-op before 31403
|
||||
return (alert.nID <= nCancel || setCancel.count(alert.nID));
|
||||
}
|
||||
|
||||
bool CAlert::AppliesTo(int nVersion, std::string strSubVerIn) const
|
||||
{
|
||||
// TODO: rework for client-version-embedded-in-strSubVer ?
|
||||
return (IsInEffect() &&
|
||||
nMinVer <= nVersion && nVersion <= nMaxVer &&
|
||||
(setSubVer.empty() || setSubVer.count(strSubVerIn)));
|
||||
}
|
||||
|
||||
bool CAlert::AppliesToMe() const
|
||||
{
|
||||
return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()));
|
||||
}
|
||||
|
||||
bool CAlert::RelayTo(CNode* pnode) const
|
||||
{
|
||||
if (!IsInEffect())
|
||||
return false;
|
||||
// don't relay to nodes which haven't sent their version message
|
||||
if (pnode->nVersion == 0)
|
||||
return false;
|
||||
// returns true if wasn't already contained in the set
|
||||
if (pnode->setKnown.insert(GetHash()).second) {
|
||||
if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
|
||||
AppliesToMe() ||
|
||||
GetAdjustedTime() < nRelayUntil) {
|
||||
pnode->PushMessage("alert", *this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CAlert::CheckSignature() const
|
||||
{
|
||||
CPubKey key(Params().AlertKey());
|
||||
if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
|
||||
return error("CAlert::CheckSignature() : verify signature failed");
|
||||
|
||||
// Now unserialize the data
|
||||
CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION);
|
||||
sMsg >> *(CUnsignedAlert*)this;
|
||||
return true;
|
||||
}
|
||||
|
||||
CAlert CAlert::getAlertByHash(const uint256& hash)
|
||||
{
|
||||
CAlert retval;
|
||||
{
|
||||
LOCK(cs_mapAlerts);
|
||||
map<uint256, CAlert>::iterator mi = mapAlerts.find(hash);
|
||||
if (mi != mapAlerts.end())
|
||||
retval = mi->second;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool CAlert::ProcessAlert(bool fThread)
|
||||
{
|
||||
if (!CheckSignature())
|
||||
return false;
|
||||
if (!IsInEffect())
|
||||
return false;
|
||||
|
||||
// alert.nID=max is reserved for if the alert key is
|
||||
// compromised. It must have a pre-defined message,
|
||||
// must never expire, must apply to all versions,
|
||||
// and must cancel all previous
|
||||
// alerts or it will be ignored (so an attacker can't
|
||||
// send an "everything is OK, don't panic" version that
|
||||
// cannot be overridden):
|
||||
int maxInt = std::numeric_limits<int>::max();
|
||||
if (nID == maxInt) {
|
||||
if (!(
|
||||
nExpiration == maxInt &&
|
||||
nCancel == (maxInt - 1) &&
|
||||
nMinVer == 0 &&
|
||||
nMaxVer == maxInt &&
|
||||
setSubVer.empty() &&
|
||||
nPriority == maxInt &&
|
||||
strStatusBar == "URGENT: Alert key compromised, upgrade required"))
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
LOCK(cs_mapAlerts);
|
||||
// Cancel previous alerts
|
||||
for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();) {
|
||||
const CAlert& alert = (*mi).second;
|
||||
if (Cancels(alert)) {
|
||||
LogPrint("alert", "cancelling alert %d\n", alert.nID);
|
||||
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
|
||||
mapAlerts.erase(mi++);
|
||||
} else if (!alert.IsInEffect()) {
|
||||
LogPrint("alert", "expiring alert %d\n", alert.nID);
|
||||
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
|
||||
mapAlerts.erase(mi++);
|
||||
} else
|
||||
mi++;
|
||||
}
|
||||
|
||||
// Check if this alert has been cancelled
|
||||
for (PAIRTYPE(const uint256, CAlert) & item : mapAlerts) {
|
||||
const CAlert& alert = item.second;
|
||||
if (alert.Cancels(*this)) {
|
||||
LogPrint("alert", "alert already cancelled by %d\n", alert.nID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add to mapAlerts
|
||||
mapAlerts.insert(make_pair(GetHash(), *this));
|
||||
// Notify UI and -alertnotify if it applies to me
|
||||
if (AppliesToMe()) {
|
||||
uiInterface.NotifyAlertChanged(GetHash(), CT_NEW);
|
||||
Notify(strStatusBar, fThread);
|
||||
}
|
||||
}
|
||||
|
||||
LogPrint("alert", "accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAlert::Notify(const std::string& strMessage, bool fThread)
|
||||
{
|
||||
std::string strCmd = GetArg("-alertnotify", "");
|
||||
if (strCmd.empty()) return;
|
||||
|
||||
// Alert text should be plain ascii coming from a trusted source, but to
|
||||
// be safe we first strip anything not in safeChars, then add single quotes around
|
||||
// the whole string before passing it to the shell:
|
||||
std::string singleQuote("'");
|
||||
std::string safeStatus = SanitizeString(strMessage);
|
||||
safeStatus = singleQuote + safeStatus + singleQuote;
|
||||
boost::replace_all(strCmd, "%s", safeStatus);
|
||||
|
||||
if (fThread)
|
||||
boost::thread t(runCommand, strCmd); // thread runs free
|
||||
else
|
||||
runCommand(strCmd);
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2013 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_ALERT_H
|
||||
#define BITCOIN_ALERT_H
|
||||
|
||||
#include "serialize.h"
|
||||
#include "sync.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
class CAlert;
|
||||
class CNode;
|
||||
class uint256;
|
||||
|
||||
extern std::map<uint256, CAlert> mapAlerts;
|
||||
extern CCriticalSection cs_mapAlerts;
|
||||
|
||||
/** Alerts are for notifying old versions if they become too obsolete and
|
||||
* need to upgrade. The message is displayed in the status bar.
|
||||
* Alert messages are broadcast as a vector of signed data. Unserializing may
|
||||
* not read the entire buffer if the alert is for a newer version, but older
|
||||
* versions can still relay the original data.
|
||||
*/
|
||||
class CUnsignedAlert
|
||||
{
|
||||
public:
|
||||
int nVersion;
|
||||
int64_t nRelayUntil; // when newer nodes stop relaying to newer nodes
|
||||
int64_t nExpiration;
|
||||
int nID;
|
||||
int nCancel;
|
||||
std::set<int> setCancel;
|
||||
int nMinVer; // lowest version inclusive
|
||||
int nMaxVer; // highest version inclusive
|
||||
std::set<std::string> setSubVer; // empty matches all
|
||||
int nPriority;
|
||||
|
||||
// Actions
|
||||
std::string strComment;
|
||||
std::string strStatusBar;
|
||||
std::string strReserved;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(this->nVersion);
|
||||
nVersion = this->nVersion;
|
||||
READWRITE(nRelayUntil);
|
||||
READWRITE(nExpiration);
|
||||
READWRITE(nID);
|
||||
READWRITE(nCancel);
|
||||
READWRITE(setCancel);
|
||||
READWRITE(nMinVer);
|
||||
READWRITE(nMaxVer);
|
||||
READWRITE(setSubVer);
|
||||
READWRITE(nPriority);
|
||||
|
||||
READWRITE(LIMITED_STRING(strComment, 65536));
|
||||
READWRITE(LIMITED_STRING(strStatusBar, 256));
|
||||
READWRITE(LIMITED_STRING(strReserved, 256));
|
||||
}
|
||||
|
||||
void SetNull();
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
/** An alert is a combination of a serialized CUnsignedAlert and a signature. */
|
||||
class CAlert : public CUnsignedAlert
|
||||
{
|
||||
public:
|
||||
std::vector<unsigned char> vchMsg;
|
||||
std::vector<unsigned char> vchSig;
|
||||
|
||||
CAlert()
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(vchMsg);
|
||||
READWRITE(vchSig);
|
||||
}
|
||||
|
||||
void SetNull();
|
||||
bool IsNull() const;
|
||||
uint256 GetHash() const;
|
||||
bool IsInEffect() const;
|
||||
bool Cancels(const CAlert& alert) const;
|
||||
bool AppliesTo(int nVersion, std::string strSubVerIn) const;
|
||||
bool AppliesToMe() const;
|
||||
bool RelayTo(CNode* pnode) const;
|
||||
bool CheckSignature() const;
|
||||
bool ProcessAlert(bool fThread = true); // fThread means run -alertnotify in a free-running thread
|
||||
static void Notify(const std::string& strMessage, bool fThread);
|
||||
|
||||
/*
|
||||
* Get copy of (active) alert object by hash. Returns a null alert if it is not found.
|
||||
*/
|
||||
static CAlert getAlertByHash(const uint256& hash);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_ALERT_H
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2009-2013 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 "allocators.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
// This is used to attempt to keep keying material out of swap
|
||||
// Note that VirtualLock does not provide this as a guarantee on Windows,
|
||||
// but, in practice, memory that has been VirtualLock'd almost never gets written to
|
||||
// the pagefile except in rare circumstances where memory is extremely low.
|
||||
#else
|
||||
#include <limits.h> // for PAGESIZE
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h> // for sysconf
|
||||
#endif
|
||||
|
||||
LockedPageManager* LockedPageManager::_instance = NULL;
|
||||
boost::once_flag LockedPageManager::init_flag = BOOST_ONCE_INIT;
|
||||
|
||||
/** Determine system page size in bytes */
|
||||
static inline size_t GetSystemPageSize()
|
||||
{
|
||||
size_t page_size;
|
||||
#if defined(WIN32)
|
||||
SYSTEM_INFO sSysInfo;
|
||||
GetSystemInfo(&sSysInfo);
|
||||
page_size = sSysInfo.dwPageSize;
|
||||
#elif defined(PAGESIZE) // defined in limits.h
|
||||
page_size = PAGESIZE;
|
||||
#else // assume some POSIX OS
|
||||
page_size = sysconf(_SC_PAGESIZE);
|
||||
#endif
|
||||
return page_size;
|
||||
}
|
||||
|
||||
bool MemoryPageLocker::Lock(const void* addr, size_t len)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return VirtualLock(const_cast<void*>(addr), len) != 0;
|
||||
#else
|
||||
return mlock(addr, len) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MemoryPageLocker::Unlock(const void* addr, size_t len)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return VirtualUnlock(const_cast<void*>(addr), len) != 0;
|
||||
#else
|
||||
return munlock(addr, len) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
LockedPageManager::LockedPageManager() : LockedPageManagerBase<MemoryPageLocker>(GetSystemPageSize())
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2013 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_ALLOCATORS_H
|
||||
#define BITCOIN_ALLOCATORS_H
|
||||
|
||||
#include "support/cleanse.h"
|
||||
|
||||
#include <map>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
/**
|
||||
* Thread-safe class to keep track of locked (ie, non-swappable) memory pages.
|
||||
*
|
||||
* Memory locks do not stack, that is, pages which have been locked several times by calls to mlock()
|
||||
* will be unlocked by a single call to munlock(). This can result in keying material ending up in swap when
|
||||
* those functions are used naively. This class simulates stacking memory locks by keeping a counter per page.
|
||||
*
|
||||
* @note By using a map from each page base address to lock count, this class is optimized for
|
||||
* small objects that span up to a few pages, mostly smaller than a page. To support large allocations,
|
||||
* something like an interval tree would be the preferred data structure.
|
||||
*/
|
||||
template <class Locker>
|
||||
class LockedPageManagerBase
|
||||
{
|
||||
public:
|
||||
LockedPageManagerBase(size_t page_size) : page_size(page_size)
|
||||
{
|
||||
// Determine bitmask for extracting page from address
|
||||
assert(!(page_size & (page_size - 1))); // size must be power of two
|
||||
page_mask = ~(page_size - 1);
|
||||
}
|
||||
|
||||
~LockedPageManagerBase()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// For all pages in affected range, increase lock count
|
||||
void LockRange(void* p, size_t size)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
if (!size)
|
||||
return;
|
||||
const size_t base_addr = reinterpret_cast<size_t>(p);
|
||||
const size_t start_page = base_addr & page_mask;
|
||||
const size_t end_page = (base_addr + size - 1) & page_mask;
|
||||
for (size_t page = start_page; page <= end_page; page += page_size) {
|
||||
Histogram::iterator it = histogram.find(page);
|
||||
if (it == histogram.end()) // Newly locked page
|
||||
{
|
||||
locker.Lock(reinterpret_cast<void*>(page), page_size);
|
||||
histogram.insert(std::make_pair(page, 1));
|
||||
} else // Page was already locked; increase counter
|
||||
{
|
||||
it->second += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For all pages in affected range, decrease lock count
|
||||
void UnlockRange(void* p, size_t size)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
if (!size)
|
||||
return;
|
||||
const size_t base_addr = reinterpret_cast<size_t>(p);
|
||||
const size_t start_page = base_addr & page_mask;
|
||||
const size_t end_page = (base_addr + size - 1) & page_mask;
|
||||
for (size_t page = start_page; page <= end_page; page += page_size) {
|
||||
Histogram::iterator it = histogram.find(page);
|
||||
assert(it != histogram.end()); // Cannot unlock an area that was not locked
|
||||
// Decrease counter for page, when it is zero, the page will be unlocked
|
||||
it->second -= 1;
|
||||
if (it->second == 0) // Nothing on the page anymore that keeps it locked
|
||||
{
|
||||
// Unlock page and remove the count from histogram
|
||||
locker.Unlock(reinterpret_cast<void*>(page), page_size);
|
||||
histogram.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get number of locked pages for diagnostics
|
||||
int GetLockedPageCount()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
return histogram.size();
|
||||
}
|
||||
|
||||
private:
|
||||
Locker locker;
|
||||
boost::mutex mutex;
|
||||
size_t page_size, page_mask;
|
||||
// map of page base address to lock count
|
||||
typedef std::map<size_t, int> Histogram;
|
||||
Histogram histogram;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* OS-dependent memory page locking/unlocking.
|
||||
* Defined as policy class to make stubbing for test possible.
|
||||
*/
|
||||
class MemoryPageLocker
|
||||
{
|
||||
public:
|
||||
/** Lock memory pages.
|
||||
* addr and len must be a multiple of the system page size
|
||||
*/
|
||||
bool Lock(const void* addr, size_t len);
|
||||
/** Unlock memory pages.
|
||||
* addr and len must be a multiple of the system page size
|
||||
*/
|
||||
bool Unlock(const void* addr, size_t len);
|
||||
};
|
||||
|
||||
/**
|
||||
* Singleton class to keep track of locked (ie, non-swappable) memory pages, for use in
|
||||
* std::allocator templates.
|
||||
*
|
||||
* Some implementations of the STL allocate memory in some constructors (i.e., see
|
||||
* MSVC's vector<T> implementation where it allocates 1 byte of memory in the allocator.)
|
||||
* Due to the unpredictable order of static initializers, we have to make sure the
|
||||
* LockedPageManager instance exists before any other STL-based objects that use
|
||||
* secure_allocator are created. So instead of having LockedPageManager also be
|
||||
* static-initialized, it is created on demand.
|
||||
*/
|
||||
class LockedPageManager : public LockedPageManagerBase<MemoryPageLocker>
|
||||
{
|
||||
public:
|
||||
static LockedPageManager& Instance()
|
||||
{
|
||||
boost::call_once(LockedPageManager::CreateInstance, LockedPageManager::init_flag);
|
||||
return *LockedPageManager::_instance;
|
||||
}
|
||||
|
||||
private:
|
||||
LockedPageManager();
|
||||
|
||||
static void CreateInstance()
|
||||
{
|
||||
// Using a local static instance guarantees that the object is initialized
|
||||
// when it's first needed and also deinitialized after all objects that use
|
||||
// it are done with it. I can think of one unlikely scenario where we may
|
||||
// have a static deinitialization order/problem, but the check in
|
||||
// LockedPageManagerBase's destructor helps us detect if that ever happens.
|
||||
static LockedPageManager instance;
|
||||
LockedPageManager::_instance = &instance;
|
||||
}
|
||||
|
||||
static LockedPageManager* _instance;
|
||||
static boost::once_flag init_flag;
|
||||
};
|
||||
|
||||
//
|
||||
// Functions for directly locking/unlocking memory objects.
|
||||
// Intended for non-dynamically allocated structures.
|
||||
//
|
||||
template <typename T>
|
||||
void LockObject(const T& t)
|
||||
{
|
||||
LockedPageManager::Instance().LockRange((void*)(&t), sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void UnlockObject(const T& t)
|
||||
{
|
||||
memory_cleanse((void*)(&t), sizeof(T));
|
||||
LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T));
|
||||
}
|
||||
|
||||
//
|
||||
// Allocator that locks its contents from being paged
|
||||
// out of memory and clears its contents before deletion.
|
||||
//
|
||||
template <typename T>
|
||||
struct secure_allocator : public std::allocator<T> {
|
||||
// MSVC8 default copy constructor is broken
|
||||
typedef std::allocator<T> base;
|
||||
typedef typename base::size_type size_type;
|
||||
typedef typename base::difference_type difference_type;
|
||||
typedef typename base::pointer pointer;
|
||||
typedef typename base::const_pointer const_pointer;
|
||||
typedef typename base::reference reference;
|
||||
typedef typename base::const_reference const_reference;
|
||||
typedef typename base::value_type value_type;
|
||||
secure_allocator() throw() {}
|
||||
secure_allocator(const secure_allocator& a) throw() : base(a) {}
|
||||
template <typename U>
|
||||
secure_allocator(const secure_allocator<U>& a) throw() : base(a)
|
||||
{
|
||||
}
|
||||
~secure_allocator() throw() {}
|
||||
template <typename _Other>
|
||||
struct rebind {
|
||||
typedef secure_allocator<_Other> other;
|
||||
};
|
||||
|
||||
T* allocate(std::size_t n, const void* hint = 0)
|
||||
{
|
||||
T* p;
|
||||
p = std::allocator<T>::allocate(n, hint);
|
||||
if (p != NULL)
|
||||
LockedPageManager::Instance().LockRange(p, sizeof(T) * n);
|
||||
return p;
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t n)
|
||||
{
|
||||
if (p != NULL) {
|
||||
memory_cleanse(p, sizeof(T) * n);
|
||||
LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n);
|
||||
}
|
||||
std::allocator<T>::deallocate(p, n);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Allocator that clears its contents before deletion.
|
||||
//
|
||||
template <typename T>
|
||||
struct zero_after_free_allocator : public std::allocator<T> {
|
||||
// MSVC8 default copy constructor is broken
|
||||
typedef std::allocator<T> base;
|
||||
typedef typename base::size_type size_type;
|
||||
typedef typename base::difference_type difference_type;
|
||||
typedef typename base::pointer pointer;
|
||||
typedef typename base::const_pointer const_pointer;
|
||||
typedef typename base::reference reference;
|
||||
typedef typename base::const_reference const_reference;
|
||||
typedef typename base::value_type value_type;
|
||||
zero_after_free_allocator() throw() {}
|
||||
zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
|
||||
template <typename U>
|
||||
zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a)
|
||||
{
|
||||
}
|
||||
~zero_after_free_allocator() throw() {}
|
||||
template <typename _Other>
|
||||
struct rebind {
|
||||
typedef zero_after_free_allocator<_Other> other;
|
||||
};
|
||||
|
||||
void deallocate(T* p, std::size_t n)
|
||||
{
|
||||
if (p != NULL)
|
||||
memory_cleanse(p, sizeof(T) * n);
|
||||
std::allocator<T>::deallocate(p, n);
|
||||
}
|
||||
};
|
||||
|
||||
// This is exactly like std::string, but with a custom allocator.
|
||||
typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
|
||||
|
||||
// Byte-vector that clears its contents before deletion.
|
||||
typedef std::vector<char, zero_after_free_allocator<char> > CSerializeData;
|
||||
|
||||
#endif // BITCOIN_ALLOCATORS_H
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "amount.h"
|
||||
|
||||
#include "tinyformat.h"
|
||||
|
||||
CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize)
|
||||
{
|
||||
if (nSize > 0)
|
||||
nSatoshisPerK = nFeePaid * 1000 / nSize;
|
||||
else
|
||||
nSatoshisPerK = 0;
|
||||
}
|
||||
|
||||
CAmount CFeeRate::GetFee(size_t nSize) const
|
||||
{
|
||||
CAmount nFee = nSatoshisPerK * nSize / 1000;
|
||||
|
||||
if (nFee == 0 && nSatoshisPerK > 0)
|
||||
nFee = nSatoshisPerK;
|
||||
|
||||
return nFee;
|
||||
}
|
||||
|
||||
std::string CFeeRate::ToString() const
|
||||
{
|
||||
return strprintf("%d.%08d AGR/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_AMOUNT_H
|
||||
#define BITCOIN_AMOUNT_H
|
||||
|
||||
#include "serialize.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
typedef int64_t CAmount;
|
||||
|
||||
static const CAmount COIN = 100000000;
|
||||
static const CAmount CENT = 1000000;
|
||||
|
||||
/** Type-safe wrapper class to for fee rates
|
||||
* (how much to pay based on transaction size)
|
||||
*/
|
||||
class CFeeRate
|
||||
{
|
||||
private:
|
||||
CAmount nSatoshisPerK; // unit is satoshis-per-1,000-bytes
|
||||
public:
|
||||
CFeeRate() : nSatoshisPerK(0) {}
|
||||
explicit CFeeRate(const CAmount& _nSatoshisPerK) : nSatoshisPerK(_nSatoshisPerK) {}
|
||||
CFeeRate(const CAmount& nFeePaid, size_t nSize);
|
||||
CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; }
|
||||
|
||||
CAmount GetFee(size_t size) const; // unit returned is satoshis
|
||||
CAmount GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes
|
||||
|
||||
friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; }
|
||||
friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; }
|
||||
friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; }
|
||||
friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; }
|
||||
friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; }
|
||||
std::string ToString() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(nSatoshisPerK);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BITCOIN_AMOUNT_H
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "base58.h"
|
||||
|
||||
#include "hash.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/** All alphanumeric characters except for "0", "I", "O", and "l" */
|
||||
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
|
||||
{
|
||||
// Skip leading spaces.
|
||||
while (*psz && isspace(*psz))
|
||||
psz++;
|
||||
// Skip and count leading '1's.
|
||||
int zeroes = 0;
|
||||
while (*psz == '1') {
|
||||
zeroes++;
|
||||
psz++;
|
||||
}
|
||||
// Allocate enough space in big-endian base256 representation.
|
||||
std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up.
|
||||
// Process the characters.
|
||||
while (*psz && !isspace(*psz)) {
|
||||
// Decode base58 character
|
||||
const char* ch = strchr(pszBase58, *psz);
|
||||
if (ch == NULL)
|
||||
return false;
|
||||
// Apply "b256 = b256 * 58 + ch".
|
||||
int carry = ch - pszBase58;
|
||||
for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) {
|
||||
carry += 58 * (*it);
|
||||
*it = carry % 256;
|
||||
carry /= 256;
|
||||
}
|
||||
assert(carry == 0);
|
||||
psz++;
|
||||
}
|
||||
// Skip trailing spaces.
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
if (*psz != 0)
|
||||
return false;
|
||||
// Skip leading zeroes in b256.
|
||||
std::vector<unsigned char>::iterator it = b256.begin();
|
||||
while (it != b256.end() && *it == 0)
|
||||
it++;
|
||||
// Copy result into output vector.
|
||||
vch.reserve(zeroes + (b256.end() - it));
|
||||
vch.assign(zeroes, 0x00);
|
||||
while (it != b256.end())
|
||||
vch.push_back(*(it++));
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string DecodeBase58(const char* psz)
|
||||
{
|
||||
std::vector<unsigned char> vch;
|
||||
DecodeBase58(psz, vch);
|
||||
std::stringstream ss;
|
||||
ss << std::hex;
|
||||
|
||||
for (unsigned int i = 0; i < vch.size(); i++) {
|
||||
unsigned char* c = &vch[i];
|
||||
ss << setw(2) << setfill('0') << (int)c[0];
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
|
||||
{
|
||||
// Skip & count leading zeroes.
|
||||
int zeroes = 0;
|
||||
while (pbegin != pend && *pbegin == 0) {
|
||||
pbegin++;
|
||||
zeroes++;
|
||||
}
|
||||
// Allocate enough space in big-endian base58 representation.
|
||||
std::vector<unsigned char> b58((pend - pbegin) * 138 / 100 + 1); // log(256) / log(58), rounded up.
|
||||
// Process the bytes.
|
||||
while (pbegin != pend) {
|
||||
int carry = *pbegin;
|
||||
// Apply "b58 = b58 * 256 + ch".
|
||||
for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); it != b58.rend(); it++) {
|
||||
carry += 256 * (*it);
|
||||
*it = carry % 58;
|
||||
carry /= 58;
|
||||
}
|
||||
assert(carry == 0);
|
||||
pbegin++;
|
||||
}
|
||||
// Skip leading zeroes in base58 result.
|
||||
std::vector<unsigned char>::iterator it = b58.begin();
|
||||
while (it != b58.end() && *it == 0)
|
||||
it++;
|
||||
// Translate the result into a string.
|
||||
std::string str;
|
||||
str.reserve(zeroes + (b58.end() - it));
|
||||
str.assign(zeroes, '1');
|
||||
while (it != b58.end())
|
||||
str += pszBase58[*(it++)];
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string EncodeBase58(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
return EncodeBase58(&vch[0], &vch[0] + vch.size());
|
||||
}
|
||||
|
||||
bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
|
||||
{
|
||||
return DecodeBase58(str.c_str(), vchRet);
|
||||
}
|
||||
|
||||
std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
|
||||
{
|
||||
// add 4-byte hash check to the end
|
||||
std::vector<unsigned char> vch(vchIn);
|
||||
uint256 hash = Hash(vch.begin(), vch.end());
|
||||
vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
|
||||
return EncodeBase58(vch);
|
||||
}
|
||||
|
||||
bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
|
||||
{
|
||||
if (!DecodeBase58(psz, vchRet) ||
|
||||
(vchRet.size() < 4)) {
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
// re-calculate the checksum, insure it matches the included 4-byte checksum
|
||||
uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4);
|
||||
if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) {
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
vchRet.resize(vchRet.size() - 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
|
||||
{
|
||||
return DecodeBase58Check(str.c_str(), vchRet);
|
||||
}
|
||||
|
||||
CBase58Data::CBase58Data()
|
||||
{
|
||||
vchVersion.clear();
|
||||
vchData.clear();
|
||||
}
|
||||
|
||||
void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const void* pdata, size_t nSize)
|
||||
{
|
||||
vchVersion = vchVersionIn;
|
||||
vchData.resize(nSize);
|
||||
if (!vchData.empty())
|
||||
memcpy(&vchData[0], pdata, nSize);
|
||||
}
|
||||
|
||||
void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend)
|
||||
{
|
||||
SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
|
||||
}
|
||||
|
||||
bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
|
||||
{
|
||||
std::vector<unsigned char> vchTemp;
|
||||
bool rc58 = DecodeBase58Check(psz, vchTemp);
|
||||
if ((!rc58) || (vchTemp.size() < nVersionBytes)) {
|
||||
vchData.clear();
|
||||
vchVersion.clear();
|
||||
return false;
|
||||
}
|
||||
vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
|
||||
vchData.resize(vchTemp.size() - nVersionBytes);
|
||||
if (!vchData.empty())
|
||||
memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
|
||||
memory_cleanse(&vchTemp[0], vchData.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBase58Data::SetString(const std::string& str)
|
||||
{
|
||||
return SetString(str.c_str());
|
||||
}
|
||||
|
||||
std::string CBase58Data::ToString() const
|
||||
{
|
||||
std::vector<unsigned char> vch = vchVersion;
|
||||
vch.insert(vch.end(), vchData.begin(), vchData.end());
|
||||
return EncodeBase58Check(vch);
|
||||
}
|
||||
|
||||
int CBase58Data::CompareTo(const CBase58Data& b58) const
|
||||
{
|
||||
if (vchVersion < b58.vchVersion)
|
||||
return -1;
|
||||
if (vchVersion > b58.vchVersion)
|
||||
return 1;
|
||||
if (vchData < b58.vchData)
|
||||
return -1;
|
||||
if (vchData > b58.vchData)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class CBitcoinAddressVisitor : public boost::static_visitor<bool>
|
||||
{
|
||||
private:
|
||||
CBitcoinAddress* addr;
|
||||
|
||||
public:
|
||||
CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {}
|
||||
|
||||
bool operator()(const CKeyID& id) const { return addr->Set(id); }
|
||||
bool operator()(const CScriptID& id) const { return addr->Set(id); }
|
||||
bool operator()(const CNoDestination& no) const { return false; }
|
||||
};
|
||||
|
||||
} // anon namespace
|
||||
|
||||
bool CBitcoinAddress::Set(const CKeyID& id)
|
||||
{
|
||||
SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::Set(const CScriptID& id)
|
||||
{
|
||||
SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::Set(const CTxDestination& dest)
|
||||
{
|
||||
return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::IsValid() const
|
||||
{
|
||||
return IsValid(Params());
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::IsValid(const CChainParams& params) const
|
||||
{
|
||||
bool fCorrectSize = vchData.size() == 20;
|
||||
bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
|
||||
vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
|
||||
return fCorrectSize && fKnownVersion;
|
||||
}
|
||||
|
||||
CTxDestination CBitcoinAddress::Get() const
|
||||
{
|
||||
if (!IsValid())
|
||||
return CNoDestination();
|
||||
uint160 id;
|
||||
memcpy(&id, &vchData[0], 20);
|
||||
if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
|
||||
return CKeyID(id);
|
||||
else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
|
||||
return CScriptID(id);
|
||||
else
|
||||
return CNoDestination();
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const
|
||||
{
|
||||
if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
|
||||
return false;
|
||||
uint160 id;
|
||||
memcpy(&id, &vchData[0], 20);
|
||||
keyID = CKeyID(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::IsScript() const
|
||||
{
|
||||
return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
|
||||
}
|
||||
|
||||
void CBitcoinSecret::SetKey(const CKey& vchSecret)
|
||||
{
|
||||
assert(vchSecret.IsValid());
|
||||
SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
|
||||
if (vchSecret.IsCompressed())
|
||||
vchData.push_back(1);
|
||||
}
|
||||
|
||||
CKey CBitcoinSecret::GetKey()
|
||||
{
|
||||
CKey ret;
|
||||
assert(vchData.size() >= 32);
|
||||
ret.Set(vchData.begin(), vchData.begin() + 32, vchData.size() > 32 && vchData[32] == 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CBitcoinSecret::IsValid() const
|
||||
{
|
||||
bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
|
||||
bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
|
||||
return fExpectedFormat && fCorrectVersion;
|
||||
}
|
||||
|
||||
bool CBitcoinSecret::SetString(const char* pszSecret)
|
||||
{
|
||||
return CBase58Data::SetString(pszSecret) && IsValid();
|
||||
}
|
||||
|
||||
bool CBitcoinSecret::SetString(const std::string& strSecret)
|
||||
{
|
||||
return SetString(strSecret.c_str());
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/**
|
||||
* Why base-58 instead of standard base-64 encoding?
|
||||
* - Don't want 0OIl characters that look the same in some fonts and
|
||||
* could be used to create visually identical looking account numbers.
|
||||
* - A string with non-alphanumeric characters is not as easily accepted as an account number.
|
||||
* - E-mail usually won't line-break if there's no punctuation to break at.
|
||||
* - Double-clicking selects the whole number as one word if it's all alphanumeric.
|
||||
*/
|
||||
#ifndef BITCOIN_BASE58_H
|
||||
#define BITCOIN_BASE58_H
|
||||
|
||||
#include "chainparams.h"
|
||||
#include "key.h"
|
||||
#include "pubkey.h"
|
||||
#include "script/script.h"
|
||||
#include "script/standard.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Encode a byte sequence as a base58-encoded string.
|
||||
* pbegin and pend cannot be NULL, unless both are.
|
||||
*/
|
||||
std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend);
|
||||
|
||||
/**
|
||||
* Encode a byte vector as a base58-encoded string
|
||||
*/
|
||||
std::string EncodeBase58(const std::vector<unsigned char>& vch);
|
||||
|
||||
/**
|
||||
* Decode a base58-encoded string (psz) into a byte vector (vchRet).
|
||||
* return true if decoding is successful.
|
||||
* psz cannot be NULL.
|
||||
*/
|
||||
bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet);
|
||||
|
||||
/**
|
||||
* Decode a base58-encoded string (psz) into a string.
|
||||
* psz cannot be NULL.
|
||||
*/
|
||||
std::string DecodeBase58(const char* psz);
|
||||
|
||||
/**
|
||||
* Decode a base58-encoded string (str) into a byte vector (vchRet).
|
||||
* return true if decoding is successful.
|
||||
*/
|
||||
bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet);
|
||||
|
||||
/**
|
||||
* Encode a byte vector into a base58-encoded string, including checksum
|
||||
*/
|
||||
std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn);
|
||||
|
||||
/**
|
||||
* Decode a base58-encoded string (psz) that includes a checksum into a byte
|
||||
* vector (vchRet), return true if decoding is successful
|
||||
*/
|
||||
inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet);
|
||||
|
||||
/**
|
||||
* Decode a base58-encoded string (str) that includes a checksum into a byte
|
||||
* vector (vchRet), return true if decoding is successful
|
||||
*/
|
||||
inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet);
|
||||
|
||||
/**
|
||||
* Base class for all base58-encoded data
|
||||
*/
|
||||
class CBase58Data
|
||||
{
|
||||
protected:
|
||||
//! the version byte(s)
|
||||
std::vector<unsigned char> vchVersion;
|
||||
|
||||
//! the actually encoded data
|
||||
typedef std::vector<unsigned char, zero_after_free_allocator<unsigned char> > vector_uchar;
|
||||
vector_uchar vchData;
|
||||
|
||||
CBase58Data();
|
||||
void SetData(const std::vector<unsigned char>& vchVersionIn, const void* pdata, size_t nSize);
|
||||
void SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend);
|
||||
|
||||
public:
|
||||
bool SetString(const char* psz, unsigned int nVersionBytes = 1);
|
||||
bool SetString(const std::string& str);
|
||||
std::string ToString() const;
|
||||
int CompareTo(const CBase58Data& b58) const;
|
||||
|
||||
bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
|
||||
bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
|
||||
bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
|
||||
bool operator<(const CBase58Data& b58) const { return CompareTo(b58) < 0; }
|
||||
bool operator>(const CBase58Data& b58) const { return CompareTo(b58) > 0; }
|
||||
};
|
||||
|
||||
/** base58-encoded Agrarian addresses.
|
||||
* Public-key-hash-addresses have version 0 (or 111 testnet).
|
||||
* The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
|
||||
* Script-hash-addresses have version 5 (or 196 testnet).
|
||||
* The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
|
||||
*/
|
||||
class CBitcoinAddress : public CBase58Data
|
||||
{
|
||||
public:
|
||||
bool Set(const CKeyID& id);
|
||||
bool Set(const CScriptID& id);
|
||||
bool Set(const CTxDestination& dest);
|
||||
bool IsValid() const;
|
||||
bool IsValid(const CChainParams& params) const;
|
||||
|
||||
CBitcoinAddress() {}
|
||||
CBitcoinAddress(const CTxDestination& dest) { Set(dest); }
|
||||
CBitcoinAddress(const std::string& strAddress) { SetString(strAddress); }
|
||||
CBitcoinAddress(const char* pszAddress) { SetString(pszAddress); }
|
||||
|
||||
CTxDestination Get() const;
|
||||
bool GetKeyID(CKeyID& keyID) const;
|
||||
bool IsScript() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* A base58-encoded secret key
|
||||
*/
|
||||
class CBitcoinSecret : public CBase58Data
|
||||
{
|
||||
public:
|
||||
void SetKey(const CKey& vchSecret);
|
||||
CKey GetKey();
|
||||
bool IsValid() const;
|
||||
bool SetString(const char* pszSecret);
|
||||
bool SetString(const std::string& strSecret);
|
||||
|
||||
CBitcoinSecret(const CKey& vchSecret) { SetKey(vchSecret); }
|
||||
CBitcoinSecret() {}
|
||||
};
|
||||
|
||||
template <typename K, int Size, CChainParams::Base58Type Type>
|
||||
class CBitcoinExtKeyBase : public CBase58Data
|
||||
{
|
||||
public:
|
||||
void SetKey(const K& key)
|
||||
{
|
||||
unsigned char vch[Size];
|
||||
key.Encode(vch);
|
||||
SetData(Params().Base58Prefix(Type), vch, vch + Size);
|
||||
}
|
||||
|
||||
K GetKey()
|
||||
{
|
||||
K ret;
|
||||
ret.Decode(&vchData[0], &vchData[Size]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CBitcoinExtKeyBase(const K& key)
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
CBitcoinExtKeyBase() {}
|
||||
};
|
||||
|
||||
typedef CBitcoinExtKeyBase<CExtKey, 74, CChainParams::EXT_SECRET_KEY> CBitcoinExtKey;
|
||||
typedef CBitcoinExtKeyBase<CExtPubKey, 74, CChainParams::EXT_PUBLIC_KEY> CBitcoinExtPubKey;
|
||||
|
||||
#endif // BITCOIN_BASE58_H
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "bip38.h"
|
||||
#include "base58.h"
|
||||
#include "hash.h"
|
||||
#include "pubkey.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "random.h"
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <secp256k1.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
/** 39 bytes - 78 characters
|
||||
* 1) Prefix - 2 bytes - 4 chars - strKey[0..3]
|
||||
* 2) Flagbyte - 1 byte - 2 chars - strKey[4..5]
|
||||
* 3) addresshash - 4 bytes - 8 chars - strKey[6..13]
|
||||
* 4) Owner Entropy - 8 bytes - 16 chars - strKey[14..29]
|
||||
* 5) Encrypted Part 1 - 8 bytes - 16 chars - strKey[30..45]
|
||||
* 6) Encrypted Part 2 - 16 bytes - 32 chars - strKey[46..77]
|
||||
*/
|
||||
|
||||
void DecryptAES(uint256 encryptedIn, uint256 decryptionKey, uint256& output)
|
||||
{
|
||||
AES_KEY key;
|
||||
AES_set_decrypt_key(decryptionKey.begin(), 256, &key);
|
||||
AES_decrypt(encryptedIn.begin(), output.begin(), &key);
|
||||
}
|
||||
|
||||
void ComputePreFactor(std::string strPassphrase, std::string strSalt, uint256& prefactor)
|
||||
{
|
||||
//passfactor is the scrypt hash of passphrase and ownersalt (NOTE this needs to handle alt cases too in the future)
|
||||
uint64_t s = uint256(ReverseEndianString(strSalt)).Get64();
|
||||
scrypt_hash(strPassphrase.c_str(), strPassphrase.size(), BEGIN(s), strSalt.size() / 2, BEGIN(prefactor), 16384, 8, 8, 32);
|
||||
}
|
||||
|
||||
void ComputePassfactor(std::string ownersalt, uint256 prefactor, uint256& passfactor)
|
||||
{
|
||||
//concat prefactor and ownersalt
|
||||
uint512 temp(ReverseEndianString(HexStr(prefactor) + ownersalt));
|
||||
Hash(temp.begin(), 40, passfactor.begin()); //40 bytes is the length of prefactor + salt
|
||||
Hash(passfactor.begin(), 32, passfactor.begin());
|
||||
}
|
||||
|
||||
bool ComputePasspoint(uint256 passfactor, CPubKey& passpoint)
|
||||
{
|
||||
size_t clen = 65;
|
||||
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
|
||||
assert(ctx != nullptr);
|
||||
{
|
||||
// Pass in a random blinding seed to the secp256k1 context.
|
||||
std::vector<unsigned char, secure_allocator<unsigned char>> vseed(32);
|
||||
GetRandBytes(vseed.data(), 32);
|
||||
bool ret = secp256k1_context_randomize(ctx, vseed.data());
|
||||
assert(ret);
|
||||
}
|
||||
secp256k1_pubkey pubkey;
|
||||
|
||||
//passpoint is the ec_mult of passfactor on secp256k1
|
||||
if (!secp256k1_ec_pubkey_create(ctx, &pubkey, passfactor.begin())) {
|
||||
secp256k1_context_destroy(ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
secp256k1_ec_pubkey_serialize(ctx, (unsigned char*)passpoint.begin(), &clen, &pubkey, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_context_destroy(ctx);
|
||||
|
||||
if (passpoint.size() != clen)
|
||||
return false;
|
||||
|
||||
if (!passpoint.IsValid())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ComputeSeedBPass(CPubKey passpoint, std::string strAddressHash, std::string strOwnerSalt, uint512& seedBPass)
|
||||
{
|
||||
// Derive decryption key for seedb using scrypt with passpoint, addresshash, and ownerentropy
|
||||
string salt = ReverseEndianString(strAddressHash + strOwnerSalt);
|
||||
uint256 s2(salt);
|
||||
scrypt_hash(BEGIN(passpoint), HexStr(passpoint).size() / 2, BEGIN(s2), salt.size() / 2, BEGIN(seedBPass), 1024, 1, 1, 64);
|
||||
}
|
||||
|
||||
void ComputeFactorB(uint256 seedB, uint256& factorB)
|
||||
{
|
||||
//factorB - a double sha256 hash of seedb
|
||||
Hash(seedB.begin(), 24, factorB.begin()); //seedB is only 24 bytes
|
||||
Hash(factorB.begin(), 32, factorB.begin());
|
||||
}
|
||||
|
||||
std::string AddressToBip38Hash(std::string address)
|
||||
{
|
||||
uint256 addrCheck;
|
||||
Hash((void*)address.c_str(), address.size(), addrCheck.begin());
|
||||
Hash(addrCheck.begin(), 32, addrCheck.begin());
|
||||
|
||||
return HexStr(addrCheck).substr(0, 8);
|
||||
}
|
||||
|
||||
std::string BIP38_Encrypt(std::string strAddress, std::string strPassphrase, uint256 privKey, bool fCompressed)
|
||||
{
|
||||
string strAddressHash = AddressToBip38Hash(strAddress);
|
||||
|
||||
uint512 hashed;
|
||||
uint64_t salt = uint256(ReverseEndianString(strAddressHash)).Get64();
|
||||
scrypt_hash(strPassphrase.c_str(), strPassphrase.size(), BEGIN(salt), strAddressHash.size() / 2, BEGIN(hashed), 16384, 8, 8, 64);
|
||||
|
||||
uint256 derivedHalf1(hashed.ToString().substr(64, 64));
|
||||
uint256 derivedHalf2(hashed.ToString().substr(0, 64));
|
||||
|
||||
//block1 = (pointb[1...16] xor derivedhalf1[0...15])
|
||||
uint256 block1 = uint256((privKey << 128) ^ (derivedHalf1 << 128)) >> 128;
|
||||
|
||||
//encrypt part 1
|
||||
uint512 encrypted1;
|
||||
AES_KEY key;
|
||||
AES_set_encrypt_key(derivedHalf2.begin(), 256, &key);
|
||||
AES_encrypt(block1.begin(), encrypted1.begin(), &key);
|
||||
|
||||
//block2 = (pointb[17...32] xor derivedhalf1[16...31]
|
||||
uint256 p2 = privKey >> 128;
|
||||
uint256 dh12 = derivedHalf1 >> 128;
|
||||
uint256 block2 = uint256(p2 ^ dh12);
|
||||
|
||||
//encrypt part 2
|
||||
uint512 encrypted2;
|
||||
AES_encrypt(block2.begin(), encrypted2.begin(), &key);
|
||||
|
||||
string strPrefix = "0142";
|
||||
strPrefix += (fCompressed ? "E0" : "C0");
|
||||
|
||||
uint512 encryptedKey(ReverseEndianString(strPrefix + strAddressHash));
|
||||
|
||||
//add encrypted1 to the end of encryptedKey
|
||||
encryptedKey = encryptedKey | (encrypted1 << 56);
|
||||
|
||||
//add encrypted2 to the end of encryptedKey
|
||||
encryptedKey = encryptedKey | (encrypted2 << (56 + 128));
|
||||
|
||||
//Base58 checksum is the 4 bytes of dSHA256 hash of the encrypted key
|
||||
uint256 hashChecksum = Hash(encryptedKey.begin(), encryptedKey.begin() + 39);
|
||||
uint512 b58Checksum(hashChecksum.ToString().substr(64 - 8, 8));
|
||||
|
||||
// append the encrypted key with checksum (currently occupies 312 bits)
|
||||
encryptedKey = encryptedKey | (b58Checksum << 312);
|
||||
|
||||
//43 bytes is the total size that we are encoding
|
||||
return EncodeBase58(encryptedKey.begin(), encryptedKey.begin() + 43);
|
||||
}
|
||||
|
||||
bool BIP38_Decrypt(std::string strPassphrase, std::string strEncryptedKey, uint256& privKey, bool& fCompressed)
|
||||
{
|
||||
std::string strKey = DecodeBase58(strEncryptedKey.c_str());
|
||||
|
||||
//incorrect encoding of key, it must be 39 bytes - and another 4 bytes for base58 checksum
|
||||
if (strKey.size() != (78 + 8))
|
||||
return false;
|
||||
|
||||
//invalid prefix
|
||||
if (uint256(ReverseEndianString(strKey.substr(0, 2))) != uint256(0x01))
|
||||
return false;
|
||||
|
||||
uint256 type(ReverseEndianString(strKey.substr(2, 2)));
|
||||
uint256 flag(ReverseEndianString(strKey.substr(4, 2)));
|
||||
std::string strAddressHash = strKey.substr(6, 8);
|
||||
std::string ownersalt = strKey.substr(14, 16);
|
||||
uint256 encryptedPart1(ReverseEndianString(strKey.substr(30, 16)));
|
||||
uint256 encryptedPart2(ReverseEndianString(strKey.substr(46, 32)));
|
||||
|
||||
fCompressed = (flag & uint256(0x20)) != 0;
|
||||
|
||||
//not ec multiplied
|
||||
if (type == uint256(0x42)) {
|
||||
uint512 hashed;
|
||||
encryptedPart1 = uint256(ReverseEndianString(strKey.substr(14, 32)));
|
||||
uint64_t salt = uint256(ReverseEndianString(strAddressHash)).Get64();
|
||||
scrypt_hash(strPassphrase.c_str(), strPassphrase.size(), BEGIN(salt), strAddressHash.size() / 2, BEGIN(hashed), 16384, 8, 8, 64);
|
||||
|
||||
uint256 derivedHalf1(hashed.ToString().substr(64, 64));
|
||||
uint256 derivedHalf2(hashed.ToString().substr(0, 64));
|
||||
|
||||
uint256 decryptedPart1;
|
||||
DecryptAES(encryptedPart1, derivedHalf2, decryptedPart1);
|
||||
|
||||
uint256 decryptedPart2;
|
||||
DecryptAES(encryptedPart2, derivedHalf2, decryptedPart2);
|
||||
|
||||
//combine decrypted parts into 64 bytes
|
||||
uint256 temp1 = decryptedPart2 << 128;
|
||||
temp1 = temp1 | decryptedPart1;
|
||||
|
||||
//xor the decryption with the derived half 1 for the final key
|
||||
privKey = temp1 ^ derivedHalf1;
|
||||
|
||||
return true;
|
||||
} else if (type != uint256(0x43)) //invalid type
|
||||
return false;
|
||||
|
||||
bool fLotSequence = (flag & 0x04) != 0;
|
||||
|
||||
std::string prefactorSalt = ownersalt;
|
||||
if (fLotSequence)
|
||||
prefactorSalt = ownersalt.substr(0, 8);
|
||||
|
||||
uint256 prefactor;
|
||||
ComputePreFactor(strPassphrase, prefactorSalt, prefactor);
|
||||
|
||||
uint256 passfactor;
|
||||
if (fLotSequence)
|
||||
ComputePassfactor(ownersalt, prefactor, passfactor);
|
||||
else
|
||||
passfactor = prefactor;
|
||||
|
||||
CPubKey passpoint;
|
||||
if (!ComputePasspoint(passfactor, passpoint))
|
||||
return false;
|
||||
|
||||
uint512 seedBPass;
|
||||
ComputeSeedBPass(passpoint, strAddressHash, ownersalt, seedBPass);
|
||||
|
||||
//get derived halfs, being mindful for endian switch
|
||||
uint256 derivedHalf1(seedBPass.ToString().substr(64, 64));
|
||||
uint256 derivedHalf2(seedBPass.ToString().substr(0, 64));
|
||||
|
||||
/** Decrypt encryptedpart2 using AES256Decrypt to yield the last 8 bytes of seedb and the last 8 bytes of encryptedpart1. **/
|
||||
uint256 decryptedPart2;
|
||||
DecryptAES(encryptedPart2, derivedHalf2, decryptedPart2);
|
||||
|
||||
//xor decryptedPart2 and 2nd half of derived half 1
|
||||
uint256 x0 = derivedHalf1 >> 128; //drop off the first half (note: endian)
|
||||
uint256 x1 = decryptedPart2 ^ x0;
|
||||
uint256 seedbPart2 = x1 >> 64;
|
||||
|
||||
/** Decrypt encryptedpart1 to yield the remainder of seedb. **/
|
||||
uint256 decryptedPart1;
|
||||
uint256 x2 = x1 & uint256("0xffffffffffffffff"); // set x2 to seedbPart1 (still encrypted)
|
||||
x2 = x2 << 64; //make room to add encryptedPart1 to the front
|
||||
x2 = encryptedPart1 | x2; //combine with encryptedPart1
|
||||
DecryptAES(x2, derivedHalf2, decryptedPart1);
|
||||
|
||||
//decrypted part 1: seedb[0..15] xor derivedhalf1[0..15]
|
||||
uint256 x3 = derivedHalf1 & uint256("0xffffffffffffffffffffffffffffffff");
|
||||
uint256 seedbPart1 = decryptedPart1 ^ x3;
|
||||
uint256 seedB = seedbPart1 | (seedbPart2 << 128);
|
||||
|
||||
uint256 factorB;
|
||||
ComputeFactorB(seedB, factorB);
|
||||
|
||||
//multiply passfactor by factorb mod N to yield the priv key
|
||||
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
|
||||
assert(ctx != nullptr);
|
||||
{
|
||||
// Pass in a random blinding seed to the secp256k1 context.
|
||||
std::vector<unsigned char, secure_allocator<unsigned char>> vseed(32);
|
||||
GetRandBytes(vseed.data(), 32);
|
||||
bool ret = secp256k1_context_randomize(ctx, vseed.data());
|
||||
assert(ret);
|
||||
}
|
||||
privKey = factorB;
|
||||
if (!secp256k1_ec_privkey_tweak_mul(ctx, privKey.begin(), passfactor.begin())) {
|
||||
secp256k1_context_destroy(ctx);
|
||||
return false;
|
||||
}
|
||||
secp256k1_context_destroy(ctx);
|
||||
|
||||
//double check that the address hash matches our final privkey
|
||||
CKey k;
|
||||
k.Set(privKey.begin(), privKey.end(), fCompressed);
|
||||
CPubKey pubkey = k.GetPubKey();
|
||||
string address = CBitcoinAddress(pubkey.GetID()).ToString();
|
||||
|
||||
return strAddressHash == AddressToBip38Hash(address);
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2017 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_BIP38_H
|
||||
#define BITCOIN_BIP38_H
|
||||
|
||||
#include "pubkey.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
/** 39 bytes - 78 characters
|
||||
* 1) Prefix - 2 bytes - 4 chars - strKey[0..3]
|
||||
* 2) Flagbyte - 1 byte - 2 chars - strKey[4..5]
|
||||
* 3) addresshash - 4 bytes - 8 chars - strKey[6..13]
|
||||
* 4) Owner Entropy - 8 bytes - 16 chars - strKey[14..29]
|
||||
* 5) Encrypted Part 1 - 8 bytes - 16 chars - strKey[30..45]
|
||||
* 6) Encrypted Part 2 - 16 bytes - 32 chars - strKey[46..77]
|
||||
*/
|
||||
|
||||
void DecryptAES(uint256 encryptedIn, uint256 decryptionKey, uint256& output);
|
||||
|
||||
void ComputePreFactor(std::string strPassphrase, std::string strSalt, uint256& prefactor);
|
||||
|
||||
void ComputePassfactor(std::string ownersalt, uint256 prefactor, uint256& passfactor);
|
||||
|
||||
bool ComputePasspoint(uint256 passfactor, CPubKey& passpoint);
|
||||
|
||||
void ComputeSeedBPass(CPubKey passpoint, std::string strAddressHash, std::string strOwnerSalt, uint512& seedBPass);
|
||||
|
||||
void ComputeFactorB(uint256 seedB, uint256& factorB);
|
||||
|
||||
std::string BIP38_Encrypt(std::string strAddress, std::string strPassphrase, uint256 privKey, bool fCompressed);
|
||||
bool BIP38_Decrypt(std::string strPassphrase, std::string strEncryptedKey, uint256& privKey, bool& fCompressed);
|
||||
|
||||
std::string AddressToBip38Hash(std::string address);
|
||||
|
||||
#endif // BIP38_H
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2017-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "blocksignature.h"
|
||||
#include "main.h"
|
||||
#include "zagrchain.h"
|
||||
|
||||
bool SignBlockWithKey(CBlock& block, const CKey& key)
|
||||
{
|
||||
if (!key.Sign(block.GetHash(), block.vchBlockSig))
|
||||
return error("%s: failed to sign block hash with key", __func__);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetKeyIDFromUTXO(const CTxOut& txout, CKeyID& keyID)
|
||||
{
|
||||
std::vector<valtype> vSolutions;
|
||||
txnouttype whichType;
|
||||
if (!Solver(txout.scriptPubKey, whichType, vSolutions))
|
||||
return false;
|
||||
if (whichType == TX_PUBKEY) {
|
||||
keyID = CPubKey(vSolutions[0]).GetID();
|
||||
} else if (whichType == TX_PUBKEYHASH) {
|
||||
keyID = CKeyID(uint160(vSolutions[0]));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SignBlock(CBlock& block, const CKeyStore& keystore)
|
||||
{
|
||||
CKeyID keyID;
|
||||
if (block.IsProofOfWork()) {
|
||||
bool fFoundID = false;
|
||||
for (const CTxOut& txout :block.vtx[0].vout) {
|
||||
if (!GetKeyIDFromUTXO(txout, keyID))
|
||||
continue;
|
||||
fFoundID = true;
|
||||
break;
|
||||
}
|
||||
if (!fFoundID)
|
||||
return error("%s: failed to find key for PoW", __func__);
|
||||
} else {
|
||||
if (!GetKeyIDFromUTXO(block.vtx[1].vout[1], keyID))
|
||||
return error("%s: failed to find key for PoS", __func__);
|
||||
}
|
||||
|
||||
CKey key;
|
||||
if (!keystore.GetKey(keyID, key))
|
||||
return error("%s: failed to get key from keystore", __func__);
|
||||
|
||||
return SignBlockWithKey(block, key);
|
||||
}
|
||||
|
||||
bool CheckBlockSignature(const CBlock& block)
|
||||
{
|
||||
if (block.IsProofOfWork())
|
||||
return block.vchBlockSig.empty();
|
||||
|
||||
if (block.vchBlockSig.empty())
|
||||
return error("%s: vchBlockSig is empty!", __func__);
|
||||
|
||||
/** Each block is signed by the private key of the input that is staked. This can be either zAGR or normal UTXO
|
||||
* zAGR: Each zAGR has a keypair associated with it. The serial number is a hash of the public key.
|
||||
* UTXO: The public key that signs must match the public key associated with the first utxo of the coinstake tx.
|
||||
*/
|
||||
CPubKey pubkey;
|
||||
bool fzAGRStake = block.vtx[1].vin[0].IsZerocoinSpend();
|
||||
if (fzAGRStake) {
|
||||
libzerocoin::CoinSpend spend = TxInToZerocoinSpend(block.vtx[1].vin[0]);
|
||||
pubkey = spend.getPubKey();
|
||||
} else {
|
||||
txnouttype whichType;
|
||||
std::vector<valtype> vSolutions;
|
||||
const CTxOut& txout = block.vtx[1].vout[1];
|
||||
if (!Solver(txout.scriptPubKey, whichType, vSolutions))
|
||||
return false;
|
||||
if (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH) {
|
||||
valtype& vchPubKey = vSolutions[0];
|
||||
pubkey = CPubKey(vchPubKey);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pubkey.IsValid())
|
||||
return error("%s: invalid pubkey %s", __func__, HexStr(pubkey));
|
||||
|
||||
return pubkey.Verify(block.GetHash(), block.vchBlockSig);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef Agrarian_BLOCKSIGNATURE_H
|
||||
#define Agrarian_BLOCKSIGNATURE_H
|
||||
|
||||
#include "key.h"
|
||||
#include "primitives/block.h"
|
||||
#include "keystore.h"
|
||||
|
||||
bool SignBlockWithKey(CBlock& block, const CKey& key);
|
||||
bool SignBlock(CBlock& block, const CKeyStore& keystore);
|
||||
bool CheckBlockSignature(const CBlock& block);
|
||||
|
||||
#endif //Agrarian_BLOCKSIGNATURE_H
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
// Copyright (c) 2012-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "bloom.h"
|
||||
|
||||
|
||||
#include "chainparams.h"
|
||||
#include "hash.h"
|
||||
#include "libzerocoin/bignum.h"
|
||||
#include "libzerocoin/CoinSpend.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
#include "script/standard.h"
|
||||
#include "streams.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455
|
||||
#define LN2 0.6931471805599453094172321214581765680755001343602552
|
||||
|
||||
using namespace std;
|
||||
|
||||
CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn, unsigned char nFlagsIn) :
|
||||
/**
|
||||
* The ideal size for a bloom filter with a given number of elements and false positive rate is:
|
||||
* - nElements * log(fp rate) / ln(2)^2
|
||||
* We ignore filter parameters which will create a bloom filter larger than the protocol limits
|
||||
*/
|
||||
vData(min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8),
|
||||
/**
|
||||
* The ideal number of hash functions is filter size * ln(2) / number of elements
|
||||
* Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits
|
||||
* See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas
|
||||
*/
|
||||
isFull(false),
|
||||
isEmpty(false),
|
||||
nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)),
|
||||
nTweak(nTweakIn),
|
||||
nFlags(nFlagsIn)
|
||||
{
|
||||
}
|
||||
|
||||
inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const
|
||||
{
|
||||
// 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values.
|
||||
return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8);
|
||||
}
|
||||
|
||||
void CBloomFilter::setNotFull()
|
||||
{
|
||||
isFull = false;
|
||||
}
|
||||
|
||||
void CBloomFilter::insert(const vector<unsigned char>& vKey)
|
||||
{
|
||||
if (isFull)
|
||||
return;
|
||||
for (unsigned int i = 0; i < nHashFuncs; i++) {
|
||||
unsigned int nIndex = Hash(i, vKey);
|
||||
// Sets bit nIndex of vData
|
||||
vData[nIndex >> 3] |= (1 << (7 & nIndex));
|
||||
}
|
||||
isEmpty = false;
|
||||
}
|
||||
|
||||
void CBloomFilter::insert(const COutPoint& outpoint)
|
||||
{
|
||||
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
stream << outpoint;
|
||||
vector<unsigned char> data(stream.begin(), stream.end());
|
||||
insert(data);
|
||||
}
|
||||
|
||||
void CBloomFilter::insert(const uint256& hash)
|
||||
{
|
||||
vector<unsigned char> data(hash.begin(), hash.end());
|
||||
insert(data);
|
||||
}
|
||||
|
||||
bool CBloomFilter::contains(const vector<unsigned char>& vKey) const
|
||||
{
|
||||
if (isFull) {
|
||||
return true;
|
||||
}
|
||||
if (isEmpty) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned int i = 0; i < nHashFuncs; i++) {
|
||||
unsigned int nIndex = Hash(i, vKey);
|
||||
// Checks bit nIndex of vData
|
||||
if (!(vData[nIndex >> 3] & (1 << (7 & nIndex))))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBloomFilter::contains(const COutPoint& outpoint) const
|
||||
{
|
||||
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
stream << outpoint;
|
||||
vector<unsigned char> data(stream.begin(), stream.end());
|
||||
return contains(data);
|
||||
}
|
||||
|
||||
bool CBloomFilter::contains(const uint256& hash) const
|
||||
{
|
||||
vector<unsigned char> data(hash.begin(), hash.end());
|
||||
return contains(data);
|
||||
}
|
||||
|
||||
void CBloomFilter::clear()
|
||||
{
|
||||
vData.assign(vData.size(), 0);
|
||||
isFull = false;
|
||||
isEmpty = true;
|
||||
}
|
||||
|
||||
bool CBloomFilter::IsWithinSizeConstraints() const
|
||||
{
|
||||
return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this filter will match anything. See {@link org.agrarianj.core.BloomFilter#setMatchAll()}
|
||||
* for when this can be a useful thing to do.
|
||||
*/
|
||||
bool CBloomFilter::MatchesAll() const {
|
||||
for (unsigned char b : vData)
|
||||
if (b != 0xff)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies filter into this. Filter must have the same size, hash function count and nTweak or an
|
||||
* IllegalArgumentException will be thrown.
|
||||
*/
|
||||
bool CBloomFilter::Merge(const CBloomFilter& filter) {
|
||||
if (!this->MatchesAll() && !filter.MatchesAll()) {
|
||||
if(! (filter.vData.size() == this->vData.size() &&
|
||||
filter.nHashFuncs == this->nHashFuncs &&
|
||||
filter.nTweak == this->nTweak)){
|
||||
return false;
|
||||
}
|
||||
for (unsigned int i = 0; i < vData.size(); i++)
|
||||
this->vData[i] |= filter.vData[i];
|
||||
} else {
|
||||
// TODO: Check this.
|
||||
this->vData.clear();
|
||||
this->vData[0] = 0xff;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
|
||||
{
|
||||
bool fFound = false;
|
||||
// Match if the filter contains the hash of tx
|
||||
// for finding tx when they appear in a block
|
||||
if (isFull)
|
||||
return true;
|
||||
if (isEmpty)
|
||||
return false;
|
||||
const uint256& hash = tx.GetHash();
|
||||
if (contains(hash))
|
||||
fFound = true;
|
||||
|
||||
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
||||
const CTxOut& txout = tx.vout[i];
|
||||
// Match if the filter contains any arbitrary script data element in any scriptPubKey in tx
|
||||
// If this matches, also add the specific output that was matched.
|
||||
// This means clients don't have to update the filter themselves when a new relevant tx
|
||||
// is discovered in order to find spending transactions, which avoids round-tripping and race conditions.
|
||||
CScript::const_iterator pc = txout.scriptPubKey.begin();
|
||||
vector<unsigned char> data;
|
||||
while (pc < txout.scriptPubKey.end()) {
|
||||
opcodetype opcode;
|
||||
if (!txout.scriptPubKey.GetOp(pc, opcode, data)){
|
||||
break;
|
||||
}
|
||||
|
||||
if (txout.IsZerocoinMint()){
|
||||
data = vector<unsigned char>(txout.scriptPubKey.begin() + 6, txout.scriptPubKey.begin() + txout.scriptPubKey.size());
|
||||
}
|
||||
|
||||
if (data.size() != 0 && contains(data)) {
|
||||
fFound = true;
|
||||
if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_ALL)
|
||||
insert(COutPoint(hash, i));
|
||||
else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY) {
|
||||
txnouttype type;
|
||||
vector<vector<unsigned char> > vSolutions;
|
||||
if (Solver(txout.scriptPubKey, type, vSolutions) &&
|
||||
(type == TX_PUBKEY || type == TX_MULTISIG))
|
||||
insert(COutPoint(hash, i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fFound)
|
||||
return true;
|
||||
|
||||
for (const CTxIn& txin : tx.vin) {
|
||||
// Match if the filter contains an outpoint tx spends
|
||||
if (contains(txin.prevout))
|
||||
return true;
|
||||
|
||||
// Match if the filter contains any arbitrary script data element in any scriptSig in tx
|
||||
CScript::const_iterator pc = txin.scriptSig.begin();
|
||||
vector<unsigned char> data;
|
||||
while (pc < txin.scriptSig.end()) {
|
||||
opcodetype opcode;
|
||||
if (!txin.scriptSig.GetOp(pc, opcode, data))
|
||||
break;
|
||||
if (txin.IsZerocoinSpend()) {
|
||||
CDataStream s(vector<unsigned char>(txin.scriptSig.begin() + 44, txin.scriptSig.end()),
|
||||
SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
data = libzerocoin::CoinSpend::ParseSerial(s);
|
||||
}
|
||||
if (data.size() != 0 && contains(data)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBloomFilter::UpdateEmptyFull()
|
||||
{
|
||||
bool full = true;
|
||||
bool empty = true;
|
||||
for (unsigned int i = 0; i < vData.size(); i++) {
|
||||
full &= vData[i] == 0xff;
|
||||
empty &= vData[i] == 0;
|
||||
}
|
||||
isFull = full;
|
||||
isEmpty = empty;
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2012-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_BLOOM_H
|
||||
#define BITCOIN_BLOOM_H
|
||||
|
||||
#include "libzerocoin/bignum.h"
|
||||
#include "serialize.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class COutPoint;
|
||||
class CTransaction;
|
||||
class uint256;
|
||||
|
||||
//! 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001%
|
||||
static const unsigned int MAX_BLOOM_FILTER_SIZE = 36000; // bytes
|
||||
static const unsigned int MAX_HASH_FUNCS = 50;
|
||||
|
||||
/**
|
||||
* First two bits of nFlags control how much IsRelevantAndUpdate actually updates
|
||||
* The remaining bits are reserved
|
||||
*/
|
||||
enum bloomflags {
|
||||
BLOOM_UPDATE_NONE = 0,
|
||||
BLOOM_UPDATE_ALL = 1,
|
||||
// Only adds outpoints to the filter if the output is a pay-to-pubkey/pay-to-multisig script
|
||||
BLOOM_UPDATE_P2PUBKEY_ONLY = 2,
|
||||
BLOOM_UPDATE_MASK = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* BloomFilter is a probabilistic filter which SPV clients provide
|
||||
* so that we can filter the transactions we sends them.
|
||||
*
|
||||
* This allows for significantly more efficient transaction and block downloads.
|
||||
*
|
||||
* Because bloom filters are probabilistic, an SPV node can increase the false-
|
||||
* positive rate, making us send them transactions which aren't actually theirs,
|
||||
* allowing clients to trade more bandwidth for more privacy by obfuscating which
|
||||
* keys are owned by them.
|
||||
*/
|
||||
class CBloomFilter
|
||||
{
|
||||
private:
|
||||
std::vector<unsigned char> vData;
|
||||
bool isFull;
|
||||
bool isEmpty;
|
||||
unsigned int nHashFuncs;
|
||||
unsigned int nTweak;
|
||||
unsigned char nFlags;
|
||||
|
||||
unsigned int Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new bloom filter which will provide the given fp rate when filled with the given number of elements
|
||||
* Note that if the given parameters will result in a filter outside the bounds of the protocol limits,
|
||||
* the filter created will be as close to the given parameters as possible within the protocol limits.
|
||||
* This will apply if nFPRate is very low or nElements is unreasonably high.
|
||||
* nTweak is a constant which is added to the seed value passed to the hash function
|
||||
* It should generally always be a random value (and is largely only exposed for unit testing)
|
||||
* nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK)
|
||||
*/
|
||||
CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak, unsigned char nFlagsIn);
|
||||
CBloomFilter() : isFull(true), isEmpty(false), nHashFuncs(0), nTweak(0), nFlags(0) {}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(vData);
|
||||
READWRITE(nHashFuncs);
|
||||
READWRITE(nTweak);
|
||||
READWRITE(nFlags);
|
||||
}
|
||||
|
||||
void setNotFull();
|
||||
|
||||
void insert(const std::vector<unsigned char>& vKey);
|
||||
void insert(const COutPoint& outpoint);
|
||||
void insert(const uint256& hash);
|
||||
|
||||
bool contains(const std::vector<unsigned char>& vKey) const;
|
||||
bool contains(const COutPoint& outpoint) const;
|
||||
bool contains(const uint256& hash) const;
|
||||
|
||||
void clear();
|
||||
|
||||
//! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS
|
||||
//! (catch a filter which was just deserialized which was too big)
|
||||
bool IsWithinSizeConstraints() const;
|
||||
|
||||
bool Merge(const CBloomFilter& filter);
|
||||
bool MatchesAll() const;
|
||||
|
||||
//! Also adds any outputs which match the filter to the filter (to match their spending txes)
|
||||
bool IsRelevantAndUpdate(const CTransaction& tx);
|
||||
|
||||
//! Checks for empty and full filters to avoid wasting cpu
|
||||
void UpdateEmptyFull();
|
||||
};
|
||||
|
||||
#endif // BITCOIN_BLOOM_H
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2016-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "chain.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* CChain implementation
|
||||
*/
|
||||
void CChain::SetTip(CBlockIndex* pindex)
|
||||
{
|
||||
if (pindex == NULL) {
|
||||
vChain.clear();
|
||||
return;
|
||||
}
|
||||
vChain.resize(pindex->nHeight + 1);
|
||||
while (pindex && vChain[pindex->nHeight] != pindex) {
|
||||
vChain[pindex->nHeight] = pindex;
|
||||
pindex = pindex->pprev;
|
||||
}
|
||||
}
|
||||
|
||||
CBlockLocator CChain::GetLocator(const CBlockIndex* pindex) const
|
||||
{
|
||||
int nStep = 1;
|
||||
std::vector<uint256> vHave;
|
||||
vHave.reserve(32);
|
||||
|
||||
if (!pindex)
|
||||
pindex = Tip();
|
||||
while (pindex) {
|
||||
vHave.push_back(pindex->GetBlockHash());
|
||||
// Stop when we have added the genesis block.
|
||||
if (pindex->nHeight == 0)
|
||||
break;
|
||||
// Exponentially larger steps back, plus the genesis block.
|
||||
int nHeight = std::max(pindex->nHeight - nStep, 0);
|
||||
if (Contains(pindex)) {
|
||||
// Use O(1) CChain index if possible.
|
||||
pindex = (*this)[nHeight];
|
||||
} else {
|
||||
// Otherwise, use O(log n) skiplist.
|
||||
pindex = pindex->GetAncestor(nHeight);
|
||||
}
|
||||
if (vHave.size() > 10)
|
||||
nStep *= 2;
|
||||
}
|
||||
|
||||
return CBlockLocator(vHave);
|
||||
}
|
||||
|
||||
const CBlockIndex* CChain::FindFork(const CBlockIndex* pindex) const
|
||||
{
|
||||
if (pindex->nHeight > Height())
|
||||
pindex = pindex->GetAncestor(Height());
|
||||
while (pindex && !Contains(pindex))
|
||||
pindex = pindex->pprev;
|
||||
return pindex;
|
||||
}
|
||||
|
||||
uint256 CBlockIndex::GetBlockTrust() const
|
||||
{
|
||||
uint256 bnTarget;
|
||||
bnTarget.SetCompact(nBits);
|
||||
if (bnTarget <= 0)
|
||||
return 0;
|
||||
|
||||
if (IsProofOfStake()) {
|
||||
// Return trust score as usual
|
||||
return (uint256(1) << 256) / (bnTarget + 1);
|
||||
} else {
|
||||
// Calculate work amount for block
|
||||
uint256 bnPoWTrust = ((~uint256(0) >> 20) / (bnTarget + 1));
|
||||
return bnPoWTrust > 1 ? bnPoWTrust : 1;
|
||||
}
|
||||
}
|
||||
+605
@@ -0,0 +1,605 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2015-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CHAIN_H
|
||||
#define BITCOIN_CHAIN_H
|
||||
|
||||
#include "pow.h"
|
||||
#include "primitives/block.h"
|
||||
#include "tinyformat.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
#include "libzerocoin/Denominations.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
struct CDiskBlockPos {
|
||||
int nFile;
|
||||
unsigned int nPos;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(VARINT(nFile));
|
||||
READWRITE(VARINT(nPos));
|
||||
}
|
||||
|
||||
CDiskBlockPos()
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
CDiskBlockPos(int nFileIn, unsigned int nPosIn)
|
||||
{
|
||||
nFile = nFileIn;
|
||||
nPos = nPosIn;
|
||||
}
|
||||
|
||||
friend bool operator==(const CDiskBlockPos& a, const CDiskBlockPos& b)
|
||||
{
|
||||
return (a.nFile == b.nFile && a.nPos == b.nPos);
|
||||
}
|
||||
|
||||
friend bool operator!=(const CDiskBlockPos& a, const CDiskBlockPos& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
nFile = -1;
|
||||
nPos = 0;
|
||||
}
|
||||
bool IsNull() const { return (nFile == -1); }
|
||||
};
|
||||
|
||||
enum BlockStatus {
|
||||
//! Unused.
|
||||
BLOCK_VALID_UNKNOWN = 0,
|
||||
|
||||
//! Parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future
|
||||
BLOCK_VALID_HEADER = 1,
|
||||
|
||||
//! All parent headers found, difficulty matches, timestamp >= median previous, checkpoint. Implies all parents
|
||||
//! are also at least TREE.
|
||||
BLOCK_VALID_TREE = 2,
|
||||
|
||||
/**
|
||||
* Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids,
|
||||
* sigops, size, merkle root. Implies all parents are at least TREE but not necessarily TRANSACTIONS. When all
|
||||
* parent blocks also have TRANSACTIONS, CBlockIndex::nChainTx will be set.
|
||||
*/
|
||||
BLOCK_VALID_TRANSACTIONS = 3,
|
||||
|
||||
//! Outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30.
|
||||
//! Implies all parents are also at least CHAIN.
|
||||
BLOCK_VALID_CHAIN = 4,
|
||||
|
||||
//! Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
|
||||
BLOCK_VALID_SCRIPTS = 5,
|
||||
|
||||
//! All validity bits.
|
||||
BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS |
|
||||
BLOCK_VALID_CHAIN |
|
||||
BLOCK_VALID_SCRIPTS,
|
||||
|
||||
BLOCK_HAVE_DATA = 8, //! full block available in blk*.dat
|
||||
BLOCK_HAVE_UNDO = 16, //! undo data available in rev*.dat
|
||||
BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO,
|
||||
|
||||
BLOCK_FAILED_VALID = 32, //! stage after last reached validness failed
|
||||
BLOCK_FAILED_CHILD = 64, //! descends from failed block
|
||||
BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD,
|
||||
};
|
||||
|
||||
/** The block chain is a tree shaped structure starting with the
|
||||
* genesis block at the root, with each block potentially having multiple
|
||||
* candidates to be the next block. A blockindex may have multiple pprev pointing
|
||||
* to it, but at most one of them can be part of the currently active branch.
|
||||
*/
|
||||
class CBlockIndex
|
||||
{
|
||||
public:
|
||||
//! pointer to the hash of the block, if any. memory is owned by this CBlockIndex
|
||||
const uint256* phashBlock;
|
||||
|
||||
//! pointer to the index of the predecessor of this block
|
||||
CBlockIndex* pprev;
|
||||
|
||||
//! pointer to the index of the next block
|
||||
CBlockIndex* pnext;
|
||||
|
||||
//! pointer to the index of some further predecessor of this block
|
||||
CBlockIndex* pskip;
|
||||
|
||||
//ppcoin: trust score of block chain
|
||||
uint256 bnChainTrust;
|
||||
|
||||
//! height of the entry in the chain. The genesis block has height 0
|
||||
int nHeight;
|
||||
|
||||
//! Which # file this block is stored in (blk?????.dat)
|
||||
int nFile;
|
||||
|
||||
//! Byte offset within blk?????.dat where this block's data is stored
|
||||
unsigned int nDataPos;
|
||||
|
||||
//! Byte offset within rev?????.dat where this block's undo data is stored
|
||||
unsigned int nUndoPos;
|
||||
|
||||
//! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
|
||||
uint256 nChainWork;
|
||||
|
||||
//! Number of transactions in this block.
|
||||
//! Note: in a potential headers-first mode, this number cannot be relied upon
|
||||
unsigned int nTx;
|
||||
|
||||
//! (memory only) Number of transactions in the chain up to and including this block.
|
||||
//! This value will be non-zero only if and only if transactions for this block and all its parents are available.
|
||||
//! Change to 64-bit type when necessary; won't happen before 2030
|
||||
unsigned int nChainTx;
|
||||
|
||||
//! Verification status of this block. See enum BlockStatus
|
||||
unsigned int nStatus;
|
||||
|
||||
unsigned int nFlags; // ppcoin: block index flags
|
||||
enum {
|
||||
BLOCK_PROOF_OF_STAKE = (1 << 0), // is proof-of-stake block
|
||||
BLOCK_STAKE_ENTROPY = (1 << 1), // entropy bit for stake modifier
|
||||
BLOCK_STAKE_MODIFIER = (1 << 2), // regenerated stake modifier
|
||||
};
|
||||
|
||||
// proof-of-stake specific fields
|
||||
uint256 GetBlockTrust() const;
|
||||
uint64_t nStakeModifier; // hash modifier for proof-of-stake
|
||||
unsigned int nStakeModifierChecksum; // checksum of index; in-memeory only
|
||||
COutPoint prevoutStake;
|
||||
unsigned int nStakeTime;
|
||||
uint256 hashProofOfStake;
|
||||
int64_t nMint;
|
||||
int64_t nMoneySupply;
|
||||
|
||||
//! block header
|
||||
int nVersion;
|
||||
uint256 hashMerkleRoot;
|
||||
unsigned int nTime;
|
||||
unsigned int nBits;
|
||||
unsigned int nNonce;
|
||||
uint256 nAccumulatorCheckpoint;
|
||||
|
||||
//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
|
||||
uint32_t nSequenceId;
|
||||
|
||||
//! zerocoin specific fields
|
||||
std::map<libzerocoin::CoinDenomination, int64_t> mapZerocoinSupply;
|
||||
std::vector<libzerocoin::CoinDenomination> vMintDenominationsInBlock;
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
phashBlock = NULL;
|
||||
pprev = NULL;
|
||||
pskip = NULL;
|
||||
nHeight = 0;
|
||||
nFile = 0;
|
||||
nDataPos = 0;
|
||||
nUndoPos = 0;
|
||||
nChainWork = 0;
|
||||
nTx = 0;
|
||||
nChainTx = 0;
|
||||
nStatus = 0;
|
||||
nSequenceId = 0;
|
||||
|
||||
nMint = 0;
|
||||
nMoneySupply = 0;
|
||||
nFlags = 0;
|
||||
nStakeModifier = 0;
|
||||
nStakeModifierChecksum = 0;
|
||||
prevoutStake.SetNull();
|
||||
nStakeTime = 0;
|
||||
|
||||
nVersion = 0;
|
||||
hashMerkleRoot = uint256();
|
||||
nTime = 0;
|
||||
nBits = 0;
|
||||
nNonce = 0;
|
||||
nAccumulatorCheckpoint = 0;
|
||||
// Start supply of each denomination with 0s
|
||||
for (auto& denom : libzerocoin::zerocoinDenomList) {
|
||||
mapZerocoinSupply.insert(make_pair(denom, 0));
|
||||
}
|
||||
vMintDenominationsInBlock.clear();
|
||||
}
|
||||
|
||||
CBlockIndex()
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
CBlockIndex(const CBlock& block)
|
||||
{
|
||||
SetNull();
|
||||
|
||||
nVersion = block.nVersion;
|
||||
hashMerkleRoot = block.hashMerkleRoot;
|
||||
nTime = block.nTime;
|
||||
nBits = block.nBits;
|
||||
nNonce = block.nNonce;
|
||||
if(block.nVersion > 3)
|
||||
nAccumulatorCheckpoint = block.nAccumulatorCheckpoint;
|
||||
|
||||
//Proof of Stake
|
||||
bnChainTrust = uint256();
|
||||
nMint = 0;
|
||||
nMoneySupply = 0;
|
||||
nFlags = 0;
|
||||
nStakeModifier = 0;
|
||||
nStakeModifierChecksum = 0;
|
||||
hashProofOfStake = uint256();
|
||||
|
||||
if (block.IsProofOfStake()) {
|
||||
SetProofOfStake();
|
||||
prevoutStake = block.vtx[1].vin[0].prevout;
|
||||
nStakeTime = block.nTime;
|
||||
} else {
|
||||
prevoutStake.SetNull();
|
||||
nStakeTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CDiskBlockPos GetBlockPos() const
|
||||
{
|
||||
CDiskBlockPos ret;
|
||||
if (nStatus & BLOCK_HAVE_DATA) {
|
||||
ret.nFile = nFile;
|
||||
ret.nPos = nDataPos;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CDiskBlockPos GetUndoPos() const
|
||||
{
|
||||
CDiskBlockPos ret;
|
||||
if (nStatus & BLOCK_HAVE_UNDO) {
|
||||
ret.nFile = nFile;
|
||||
ret.nPos = nUndoPos;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CBlockHeader GetBlockHeader() const
|
||||
{
|
||||
CBlockHeader block;
|
||||
block.nVersion = nVersion;
|
||||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
block.nAccumulatorCheckpoint = nAccumulatorCheckpoint;
|
||||
return block;
|
||||
}
|
||||
|
||||
int64_t GetZerocoinSupply() const
|
||||
{
|
||||
int64_t nTotal = 0;
|
||||
for (auto& denom : libzerocoin::zerocoinDenomList) {
|
||||
nTotal += GetZcMintsAmount(denom);
|
||||
}
|
||||
return nTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Total of mints added to the specific accumulator.
|
||||
* @param denom
|
||||
* @return
|
||||
*/
|
||||
int64_t GetZcMints(libzerocoin::CoinDenomination denom) const
|
||||
{
|
||||
return mapZerocoinSupply.at(denom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Total available amount in an specific denom.
|
||||
* @param denom
|
||||
* @return
|
||||
*/
|
||||
int64_t GetZcMintsAmount(libzerocoin::CoinDenomination denom) const
|
||||
{
|
||||
return libzerocoin::ZerocoinDenominationToAmount(denom) * GetZcMints(denom);
|
||||
}
|
||||
|
||||
bool MintedDenomination(libzerocoin::CoinDenomination denom) const
|
||||
{
|
||||
return std::find(vMintDenominationsInBlock.begin(), vMintDenominationsInBlock.end(), denom) != vMintDenominationsInBlock.end();
|
||||
}
|
||||
|
||||
uint256 GetBlockHash() const
|
||||
{
|
||||
return *phashBlock;
|
||||
}
|
||||
|
||||
int64_t GetBlockTime() const
|
||||
{
|
||||
return (int64_t)nTime;
|
||||
}
|
||||
|
||||
enum { nMedianTimeSpan = 11 };
|
||||
|
||||
int64_t GetMedianTimePast() const
|
||||
{
|
||||
int64_t pmedian[nMedianTimeSpan];
|
||||
int64_t* pbegin = &pmedian[nMedianTimeSpan];
|
||||
int64_t* pend = &pmedian[nMedianTimeSpan];
|
||||
|
||||
const CBlockIndex* pindex = this;
|
||||
for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
|
||||
*(--pbegin) = pindex->GetBlockTime();
|
||||
|
||||
std::sort(pbegin, pend);
|
||||
return pbegin[(pend - pbegin) / 2];
|
||||
}
|
||||
|
||||
bool IsProofOfWork() const
|
||||
{
|
||||
return !(nFlags & BLOCK_PROOF_OF_STAKE);
|
||||
}
|
||||
|
||||
bool IsProofOfStake() const
|
||||
{
|
||||
return (nFlags & BLOCK_PROOF_OF_STAKE);
|
||||
}
|
||||
|
||||
void SetProofOfStake()
|
||||
{
|
||||
nFlags |= BLOCK_PROOF_OF_STAKE;
|
||||
}
|
||||
|
||||
unsigned int GetStakeEntropyBit() const
|
||||
{
|
||||
unsigned int nEntropyBit = ((GetBlockHash().Get64()) & 1);
|
||||
if (GetBoolArg("-printstakemodifier", false))
|
||||
LogPrintf("GetStakeEntropyBit: nHeight=%u hashBlock=%s nEntropyBit=%u\n", nHeight, GetBlockHash().ToString().c_str(), nEntropyBit);
|
||||
|
||||
return nEntropyBit;
|
||||
}
|
||||
|
||||
bool SetStakeEntropyBit(unsigned int nEntropyBit)
|
||||
{
|
||||
if (nEntropyBit > 1)
|
||||
return false;
|
||||
nFlags |= (nEntropyBit ? BLOCK_STAKE_ENTROPY : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeneratedStakeModifier() const
|
||||
{
|
||||
return (nFlags & BLOCK_STAKE_MODIFIER);
|
||||
}
|
||||
|
||||
void SetStakeModifier(uint64_t nModifier, bool fGeneratedStakeModifier)
|
||||
{
|
||||
nStakeModifier = nModifier;
|
||||
if (fGeneratedStakeModifier)
|
||||
nFlags |= BLOCK_STAKE_MODIFIER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there are nRequired or more blocks of minVersion or above
|
||||
* in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart
|
||||
* and going backwards.
|
||||
*/
|
||||
static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired);
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
|
||||
pprev, nHeight,
|
||||
hashMerkleRoot.ToString(),
|
||||
GetBlockHash().ToString());
|
||||
}
|
||||
|
||||
//! Check whether this block index entry is valid up to the passed validity level.
|
||||
bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const
|
||||
{
|
||||
assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
|
||||
if (nStatus & BLOCK_FAILED_MASK)
|
||||
return false;
|
||||
return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
|
||||
}
|
||||
|
||||
//! Raise the validity level of this block index entry.
|
||||
//! Returns true if the validity was changed.
|
||||
bool RaiseValidity(enum BlockStatus nUpTo)
|
||||
{
|
||||
assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
|
||||
if (nStatus & BLOCK_FAILED_MASK)
|
||||
return false;
|
||||
if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
|
||||
nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! Build the skiplist pointer for this entry.
|
||||
void BuildSkip();
|
||||
|
||||
//! Efficiently find an ancestor of this block.
|
||||
CBlockIndex* GetAncestor(int height);
|
||||
const CBlockIndex* GetAncestor(int height) const;
|
||||
};
|
||||
|
||||
/** Used to marshal pointers into hashes for db storage. */
|
||||
class CDiskBlockIndex : public CBlockIndex
|
||||
{
|
||||
public:
|
||||
uint256 hashPrev;
|
||||
uint256 hashNext;
|
||||
|
||||
CDiskBlockIndex()
|
||||
{
|
||||
hashPrev = uint256();
|
||||
hashNext = uint256();
|
||||
}
|
||||
|
||||
explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
|
||||
{
|
||||
hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(VARINT(nVersion));
|
||||
|
||||
READWRITE(VARINT(nHeight));
|
||||
READWRITE(VARINT(nStatus));
|
||||
READWRITE(VARINT(nTx));
|
||||
if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
|
||||
READWRITE(VARINT(nFile));
|
||||
if (nStatus & BLOCK_HAVE_DATA)
|
||||
READWRITE(VARINT(nDataPos));
|
||||
if (nStatus & BLOCK_HAVE_UNDO)
|
||||
READWRITE(VARINT(nUndoPos));
|
||||
|
||||
|
||||
READWRITE(nMint);
|
||||
READWRITE(nMoneySupply);
|
||||
READWRITE(nFlags);
|
||||
READWRITE(nStakeModifier);
|
||||
if (IsProofOfStake()) {
|
||||
READWRITE(prevoutStake);
|
||||
READWRITE(nStakeTime);
|
||||
} else {
|
||||
const_cast<CDiskBlockIndex*>(this)->prevoutStake.SetNull();
|
||||
const_cast<CDiskBlockIndex*>(this)->nStakeTime = 0;
|
||||
const_cast<CDiskBlockIndex*>(this)->hashProofOfStake = uint256();
|
||||
}
|
||||
|
||||
// block header
|
||||
READWRITE(this->nVersion);
|
||||
READWRITE(hashPrev);
|
||||
READWRITE(hashNext);
|
||||
READWRITE(hashMerkleRoot);
|
||||
READWRITE(nTime);
|
||||
READWRITE(nBits);
|
||||
READWRITE(nNonce);
|
||||
if(this->nVersion > 3) {
|
||||
READWRITE(nAccumulatorCheckpoint);
|
||||
READWRITE(mapZerocoinSupply);
|
||||
READWRITE(vMintDenominationsInBlock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint256 GetBlockHash() const
|
||||
{
|
||||
CBlockHeader block;
|
||||
block.nVersion = nVersion;
|
||||
block.hashPrevBlock = hashPrev;
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
block.nAccumulatorCheckpoint = nAccumulatorCheckpoint;
|
||||
return block.GetHash();
|
||||
}
|
||||
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::string str = "CDiskBlockIndex(";
|
||||
str += CBlockIndex::ToString();
|
||||
str += strprintf("\n hashBlock=%s, hashPrev=%s)",
|
||||
GetBlockHash().ToString(),
|
||||
hashPrev.ToString());
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
/** An in-memory indexed chain of blocks. */
|
||||
class CChain
|
||||
{
|
||||
private:
|
||||
std::vector<CBlockIndex*> vChain;
|
||||
|
||||
public:
|
||||
/** Returns the index entry for the genesis block of this chain, or NULL if none. */
|
||||
CBlockIndex* Genesis() const
|
||||
{
|
||||
return vChain.size() > 0 ? vChain[0] : NULL;
|
||||
}
|
||||
|
||||
/** Returns the index entry for the tip of this chain, or NULL if none. */
|
||||
CBlockIndex* Tip(bool fProofOfStake = false) const
|
||||
{
|
||||
if (vChain.size() < 1)
|
||||
return NULL;
|
||||
|
||||
CBlockIndex* pindex = vChain[vChain.size() - 1];
|
||||
|
||||
if (fProofOfStake) {
|
||||
while (pindex && pindex->pprev && !pindex->IsProofOfStake())
|
||||
pindex = pindex->pprev;
|
||||
}
|
||||
return pindex;
|
||||
}
|
||||
|
||||
/** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */
|
||||
CBlockIndex* operator[](int nHeight) const
|
||||
{
|
||||
if (nHeight < 0 || nHeight >= (int)vChain.size())
|
||||
return NULL;
|
||||
return vChain[nHeight];
|
||||
}
|
||||
|
||||
/** Compare two chains efficiently. */
|
||||
friend bool operator==(const CChain& a, const CChain& b)
|
||||
{
|
||||
return a.vChain.size() == b.vChain.size() &&
|
||||
a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1];
|
||||
}
|
||||
|
||||
/** Efficiently check whether a block is present in this chain. */
|
||||
bool Contains(const CBlockIndex* pindex) const
|
||||
{
|
||||
return (*this)[pindex->nHeight] == pindex;
|
||||
}
|
||||
|
||||
/** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */
|
||||
CBlockIndex* Next(const CBlockIndex* pindex) const
|
||||
{
|
||||
if (Contains(pindex))
|
||||
return (*this)[pindex->nHeight + 1];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */
|
||||
int Height() const
|
||||
{
|
||||
return vChain.size() - 1;
|
||||
}
|
||||
|
||||
/** Set/initialize a chain with a given tip. */
|
||||
void SetTip(CBlockIndex* pindex);
|
||||
|
||||
/** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
|
||||
CBlockLocator GetLocator(const CBlockIndex* pindex = NULL) const;
|
||||
|
||||
/** Find the last common block between this chain and a block index entry. */
|
||||
const CBlockIndex* FindFork(const CBlockIndex* pindex) const;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_CHAIN_H
|
||||
@@ -0,0 +1,484 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2014-2015 The Dash developers
|
||||
// Copyright (c) 2015-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "libzerocoin/Params.h"
|
||||
#include "chainparams.h"
|
||||
#include "random.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::assign;
|
||||
|
||||
struct SeedSpec6 {
|
||||
uint8_t addr[16];
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
#include "chainparamsseeds.h"
|
||||
|
||||
/**
|
||||
* Main network
|
||||
*/
|
||||
|
||||
//! Convert the pnSeeds6 array into usable address objects.
|
||||
static void convertSeed6(std::vector<CAddress>& vSeedsOut, const SeedSpec6* data, unsigned int count)
|
||||
{
|
||||
// It'll only connect to one or two seed nodes because once it connects,
|
||||
// it'll get a pile of addresses with newer timestamps.
|
||||
// Seed nodes are given a random 'last seen time' of between one and two
|
||||
// weeks ago.
|
||||
const int64_t nOneWeek = 7 * 24 * 60 * 60;
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
struct in6_addr ip;
|
||||
memcpy(&ip, data[i].addr, sizeof(ip));
|
||||
CAddress addr(CService(ip, data[i].port));
|
||||
addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
|
||||
vSeedsOut.push_back(addr);
|
||||
}
|
||||
}
|
||||
|
||||
// What makes a good checkpoint block?
|
||||
// + Is surrounded by blocks with reasonable timestamps
|
||||
// (no blocks before with a timestamp after, none after with
|
||||
// timestamp before)
|
||||
// + Contains no strange transactions
|
||||
static Checkpoints::MapCheckpoints mapCheckpoints =
|
||||
boost::assign::map_list_of
|
||||
(0, uint256("000003452250d81f8b07d42e127c92729802e3c48f3c7b9834256fd0fb9a0c2e"));
|
||||
static const Checkpoints::CCheckpointData data = {
|
||||
&mapCheckpoints,
|
||||
1643790201, // * UNIX timestamp of last checkpoint block
|
||||
0, // * total number of transactions between genesis and last checkpoint
|
||||
// (the tx=... number in the SetBestChain debug.log lines)
|
||||
0 // * estimated number of transactions per day after checkpoint
|
||||
};
|
||||
|
||||
static Checkpoints::MapCheckpoints mapCheckpointsTestnet =
|
||||
boost::assign::map_list_of
|
||||
(0, uint256("0x001"));
|
||||
static const Checkpoints::CCheckpointData dataTestnet = {
|
||||
&mapCheckpointsTestnet,
|
||||
1643790201,
|
||||
0,
|
||||
0};
|
||||
|
||||
static Checkpoints::MapCheckpoints mapCheckpointsRegtest =
|
||||
boost::assign::map_list_of(0, uint256("0x001"));
|
||||
static const Checkpoints::CCheckpointData dataRegtest = {
|
||||
&mapCheckpointsRegtest,
|
||||
1643790201,
|
||||
0,
|
||||
0};
|
||||
|
||||
libzerocoin::ZerocoinParams* CChainParams::Zerocoin_Params(bool useModulusV1) const
|
||||
{
|
||||
assert(this);
|
||||
static CBigNum bnHexModulus = 0;
|
||||
if (!bnHexModulus)
|
||||
bnHexModulus.SetHex(zerocoinModulus);
|
||||
static libzerocoin::ZerocoinParams ZCParamsHex = libzerocoin::ZerocoinParams(bnHexModulus);
|
||||
static CBigNum bnDecModulus = 0;
|
||||
if (!bnDecModulus)
|
||||
bnDecModulus.SetDec(zerocoinModulus);
|
||||
static libzerocoin::ZerocoinParams ZCParamsDec = libzerocoin::ZerocoinParams(bnDecModulus);
|
||||
|
||||
if (useModulusV1)
|
||||
return &ZCParamsHex;
|
||||
|
||||
return &ZCParamsDec;
|
||||
}
|
||||
|
||||
class CMainParams : public CChainParams
|
||||
{
|
||||
public:
|
||||
CMainParams()
|
||||
{
|
||||
networkID = CBaseChainParams::MAIN;
|
||||
strNetworkID = "main";
|
||||
/**
|
||||
* The message start string is designed to be unlikely to occur in normal data.
|
||||
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
|
||||
* a large 4-byte int at any alignment.
|
||||
*/
|
||||
pchMessageStart[0] = 0x0b;
|
||||
pchMessageStart[1] = 0x23;
|
||||
pchMessageStart[2] = 0xa0;
|
||||
pchMessageStart[3] = 0xb9;
|
||||
vAlertPubKey = ParseHex("04aa33fe2c682fa60d5ee6fd76d73336c34978408a9c938cb3683f1f26f64793a76665f0045c8066c04f239fda81ea4631631c8f1b8eb835d8b1d417099308c2be");
|
||||
nDefaultPort = 51336;
|
||||
bnProofOfWorkLimit = ~uint256(0) >> 20; // Agrarian starting difficulty is 1 / 2^12
|
||||
nSubsidyHalvingInterval = 210000;
|
||||
nMaxReorganizationDepth = 100;
|
||||
nEnforceBlockUpgradeMajority = 0;
|
||||
nRejectBlockOutdatedMajority = 0;
|
||||
nToCheckBlockUpgradeMajority = 0;
|
||||
nMinerThreads = 0;
|
||||
nTargetTimespan = 10 * 60;
|
||||
nTargetSpacing = 10 * 60;
|
||||
nMaturity = 20;
|
||||
nMasternodeCountDrift = 20;
|
||||
nMaxMoneyOut = 9999999999 * COIN;
|
||||
|
||||
/** Height or Time Based Activations **/
|
||||
nLastPOWBlock = 100000000;
|
||||
nModifierUpdateBlock = 0;
|
||||
nZerocoinStartHeight = 0;
|
||||
nZerocoinStartTime = 1643790201;
|
||||
nBlockEnforceSerialRange = 1; //Enforce serial range starting this block
|
||||
nBlockRecalculateAccumulators = 999999999; //Trigger a recalculation of accumulators
|
||||
nBlockFirstFraudulent = 999999999; //First block that bad serials emerged
|
||||
nBlockLastGoodCheckpoint = 999999999; //Last valid accumulator checkpoint
|
||||
nBlockEnforceInvalidUTXO = 999999999; //Start enforcing the invalid UTXO's
|
||||
nInvalidAmountFiltered = 0; //Amount of invalid coins filtered through exchanges, that should be considered valid
|
||||
nBlockZerocoinV2 = 999999999;
|
||||
nBlockDoubleAccumulated = 999999999;
|
||||
nEnforceNewSporkKey = 1643790201;
|
||||
nRejectOldSporkKey = 1527811200;
|
||||
|
||||
// Public coin spend enforcement
|
||||
nPublicZCSpends = 1;
|
||||
|
||||
// Fake Serial Attack
|
||||
nFakeSerialBlockheightEnd = 0;
|
||||
nSupplyBeforeFakeSerial = 0; // zerocoin supply at block nFakeSerialBlockheightEnd
|
||||
|
||||
/**
|
||||
* Build the genesis block. Note that the output of the genesis coinbase cannot
|
||||
* be spent as it did not originally exist in the database.
|
||||
*
|
||||
* CBlock(hash=00000ffd590b14, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=e0028e, nTime=1390095618, nBits=1e0ffff0, nNonce=28917698, vtx=1)
|
||||
* CTransaction(hash=e0028e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
|
||||
* CTxIn(COutPoint(000000, -1), coinbase 04ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73)
|
||||
* CTxOut(nValue=50.00000000, scriptPubKey=0xA9037BAC7050C479B121CF)
|
||||
* vMerkleTree: e0028e
|
||||
*/
|
||||
const char* pszTimestamp = "CBS 02FEB2022 Pfizer asks FDA to authorize vaccine for kids under 5";
|
||||
CMutableTransaction txNew;
|
||||
txNew.vin.resize(1);
|
||||
txNew.vout.resize(1);
|
||||
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
|
||||
txNew.vout[0].nValue = 50 * COIN;
|
||||
txNew.vout[0].scriptPubKey = CScript() << ParseHex("04fe3d7e5608ebba6d822948eff929c822ad35b5f8ecd00977d0e59ed67da697bd88e0ed8bd58797bde6fe6750236f5dae4cf403af0925c8339f0a91b682254b39") << OP_CHECKSIG;
|
||||
genesis.vtx.push_back(txNew);
|
||||
genesis.hashPrevBlock = 0;
|
||||
genesis.hashMerkleRoot = genesis.BuildMerkleTree();
|
||||
genesis.nVersion = 1;
|
||||
genesis.nTime = 1643790201;
|
||||
genesis.nBits = 0x1e0ffff0;
|
||||
genesis.nNonce = 21936323;
|
||||
|
||||
hashGenesisBlock = genesis.GetHash();
|
||||
assert(hashGenesisBlock == uint256("0x000003452250d81f8b07d42e127c92729802e3c48f3c7b9834256fd0fb9a0c2e"));
|
||||
assert(genesis.hashMerkleRoot == uint256("0x3bb054bb772e1bee1547d4b0e06c0ce34d636ee1daf56b37f1a017ce8136da00"));
|
||||
|
||||
vSeeds.push_back(CDNSSeedData("pacificao.com", "agr1.pacificao.com"));
|
||||
vSeeds.push_back(CDNSSeedData("n2.pacificao.com", "agr2.pacificao.com"));
|
||||
|
||||
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 23);
|
||||
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 24);
|
||||
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1, 151);
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x02)(0x2D)(0x25)(0x33).convert_to_container<std::vector<unsigned char> >();
|
||||
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x02)(0x21)(0x31)(0x2B).convert_to_container<std::vector<unsigned char> >();
|
||||
// BIP44 coin type is from https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
||||
base58Prefixes[EXT_COIN_TYPE] = boost::assign::list_of(0x80)(0x00)(0x00)(0x77).convert_to_container<std::vector<unsigned char> >();
|
||||
|
||||
convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));
|
||||
|
||||
fMiningRequiresPeers = true;
|
||||
fAllowMinDifficultyBlocks = false;
|
||||
fDefaultConsistencyChecks = false;
|
||||
fRequireStandard = true;
|
||||
fMineBlocksOnDemand = false;
|
||||
fSkipProofOfWorkCheck = false;
|
||||
fTestnetToBeDeprecatedFieldRPC = false;
|
||||
fHeadersFirstSyncingActive = false;
|
||||
|
||||
nPoolMaxTransactions = 3;
|
||||
nBudgetCycleBlocks = 4320;
|
||||
strSporkKey = "04f939e9c41b524e82e79080d034fcade7a588a8f02ab28f1047308e45d5a055b7de39a5f0ae4e4249694c4cde65e95cb89d9864eded0047f399f0634622bc571b";
|
||||
strSporkKeyOld = "04B433E6598390C992F4F022F20D3B4CBBE691652EE7C48243B81701CBDB7CC7D7BF0EE09E154E6FCBF2043D65AF4E9E97B89B5DBAF830D83B9B7F469A6C45A717";
|
||||
strObfuscationPoolDummyAddress = "Aef8NvJcvuSzunLfgRUwhLvnCaW2rpgcLK";
|
||||
nStartMasternodePayments = 1643790201;
|
||||
|
||||
/** Zerocoin */
|
||||
zerocoinModulus = "25195908475657893494027183240048398571429282126204032027777137836043662020707595556264018525880784"
|
||||
"4069182906412495150821892985591491761845028084891200728449926873928072877767359714183472702618963750149718246911"
|
||||
"6507761337985909570009733045974880842840179742910064245869181719511874612151517265463228221686998754918242243363"
|
||||
"7259085141865462043576798423387184774447920739934236584823824281198163815010674810451660377306056201619676256133"
|
||||
"8441436038339044149526344321901146575444541784240209246165157233507787077498171257724679629263863563732899121548"
|
||||
"31438167899885040445364023527381951378636564391212010397122822120720357";
|
||||
nMaxZerocoinSpendsPerTransaction = 7; // Assume about 20kb each
|
||||
nMaxZerocoinPublicSpendsPerTransaction = 637; // Assume about 220 bytes each input
|
||||
nMinZerocoinMintFee = 1 * CENT; //high fee required for zerocoin mints
|
||||
nMintRequiredConfirmations = 20; //the maximum amount of confirmations until accumulated in 19
|
||||
nRequiredAccumulation = 1;
|
||||
nDefaultSecurityLevel = 100; //full security level for accumulators
|
||||
nZerocoinHeaderVersion = 4; //Block headers must be this version once zerocoin is active
|
||||
nZerocoinRequiredStakeDepth = 200; //The required confirmations for a zagr to be stakable
|
||||
|
||||
nBudget_Fee_Confirmations = 6; // Number of confirmations for the finalization fee
|
||||
nProposalEstablishmentTime = 60 * 60 * 24; // Proposals must be at least a day old to make it into a budget
|
||||
}
|
||||
|
||||
const Checkpoints::CCheckpointData& Checkpoints() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
};
|
||||
static CMainParams mainParams;
|
||||
|
||||
/**
|
||||
* Testnet (v3)
|
||||
*/
|
||||
class CTestNetParams : public CMainParams
|
||||
{
|
||||
public:
|
||||
CTestNetParams()
|
||||
{
|
||||
networkID = CBaseChainParams::TESTNET;
|
||||
strNetworkID = "test";
|
||||
pchMessageStart[0] = 0x63;
|
||||
pchMessageStart[1] = 0xe3;
|
||||
pchMessageStart[2] = 0xe0;
|
||||
pchMessageStart[3] = 0x0d;
|
||||
vAlertPubKey = ParseHex("047f692cb9b0694eef8509d45aa8b7432c2730a48ae29f531e2732450ba640dda64ba051daca3dedf795a2d89cdcd66c5f187cf47932f8aa81dd64db7adfe8e236");
|
||||
nDefaultPort = 61336;
|
||||
nEnforceBlockUpgradeMajority = 0;
|
||||
nRejectBlockOutdatedMajority = 0;
|
||||
nToCheckBlockUpgradeMajority = 0;
|
||||
nMinerThreads = 0;
|
||||
nTargetTimespan = 10 * 60;
|
||||
nTargetSpacing = 10 * 60;
|
||||
nLastPOWBlock = 200;
|
||||
nMaturity = 15;
|
||||
nMasternodeCountDrift = 4;
|
||||
nModifierUpdateBlock = 0;
|
||||
nMaxMoneyOut = 43199500 * COIN;
|
||||
nZerocoinStartHeight = 0;
|
||||
nZerocoinStartTime = 1643790201;
|
||||
nBlockEnforceSerialRange = 1; //Enforce serial range starting this block
|
||||
nBlockRecalculateAccumulators = 999999999; //Trigger a recalculation of accumulators
|
||||
nBlockFirstFraudulent = 999999999; //First block that bad serials emerged
|
||||
nBlockLastGoodCheckpoint = 999999999; //Last valid accumulator checkpoint
|
||||
nBlockEnforceInvalidUTXO = 999999999; //Start enforcing the invalid UTXO's
|
||||
nInvalidAmountFiltered = 0; //Amount of invalid coins filtered through exchanges, that should be considered valid
|
||||
nBlockZerocoinV2 = 999999999; //!> The block that zerocoin v2 becomes active
|
||||
nEnforceNewSporkKey = 1643790201;
|
||||
nRejectOldSporkKey = 1522454400;
|
||||
|
||||
// Public coin spend enforcement
|
||||
nPublicZCSpends = 1;
|
||||
|
||||
// Fake Serial Attack
|
||||
nFakeSerialBlockheightEnd = -1;
|
||||
nSupplyBeforeFakeSerial = 0;
|
||||
|
||||
//! Modify the testnet genesis block so the timestamp is valid for a later start.
|
||||
genesis.nTime = 1643790201;
|
||||
genesis.nNonce = 21936323;
|
||||
|
||||
hashGenesisBlock = genesis.GetHash();
|
||||
assert(hashGenesisBlock == uint256("0x000003452250d81f8b07d42e127c92729802e3c48f3c7b9834256fd0fb9a0c2e"));
|
||||
|
||||
vFixedSeeds.clear();
|
||||
vSeeds.clear();
|
||||
|
||||
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 38);
|
||||
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 39);
|
||||
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1, 166);
|
||||
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x3a)(0x80)(0x61)(0xa0).convert_to_container<std::vector<unsigned char> >();
|
||||
|
||||
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x3a)(0x80)(0x58)(0x37).convert_to_container<std::vector<unsigned char> >();
|
||||
// Testnet agrarian BIP44 coin type is '1' (All coin's testnet default)
|
||||
base58Prefixes[EXT_COIN_TYPE] = boost::assign::list_of(0x80)(0x00)(0x00)(0x01).convert_to_container<std::vector<unsigned char> >();
|
||||
|
||||
convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));
|
||||
|
||||
fMiningRequiresPeers = true;
|
||||
fAllowMinDifficultyBlocks = true;
|
||||
fDefaultConsistencyChecks = false;
|
||||
fRequireStandard = true;
|
||||
fMineBlocksOnDemand = false;
|
||||
fTestnetToBeDeprecatedFieldRPC = true;
|
||||
|
||||
nPoolMaxTransactions = 2;
|
||||
nBudgetCycleBlocks = 144; //!< Ten cycles per day on testnet
|
||||
strSporkKey = "04ce490c66a62abd3af22be9a561beee84e487dc6b84c22b73928b15f9b305b3785744ad0728588b89808bca7d52f89bf192f36013baf6e57f0428f4c48422fe77";
|
||||
strSporkKeyOld = "04348C2F50F90267E64FACC65BFDC9D0EB147D090872FB97ABAE92E9A36E6CA60983E28E741F8E7277B11A7479B626AC115BA31463AC48178A5075C5A9319D4A38";
|
||||
strObfuscationPoolDummyAddress = "GQ7aNidDjkmcfCrHuVzB67Qeh6RV42cusu";
|
||||
nStartMasternodePayments = 1643790201;
|
||||
nBudget_Fee_Confirmations = 3; // Number of confirmations for the finalization fee. We have to make this very short
|
||||
// here because we only have a 8 block finalization window on testnet
|
||||
|
||||
nProposalEstablishmentTime = 60 * 5; // Proposals must be at least 5 mns old to make it into a test budget
|
||||
}
|
||||
const Checkpoints::CCheckpointData& Checkpoints() const
|
||||
{
|
||||
return dataTestnet;
|
||||
}
|
||||
};
|
||||
static CTestNetParams testNetParams;
|
||||
|
||||
/**
|
||||
* Regression test
|
||||
*/
|
||||
class CRegTestParams : public CTestNetParams
|
||||
{
|
||||
public:
|
||||
CRegTestParams()
|
||||
{
|
||||
networkID = CBaseChainParams::REGTEST;
|
||||
strNetworkID = "regtest";
|
||||
pchMessageStart[0] = 0x6f;
|
||||
pchMessageStart[1] = 0x94;
|
||||
pchMessageStart[2] = 0x98;
|
||||
pchMessageStart[3] = 0xaa;
|
||||
nDefaultPort = 51476;
|
||||
nSubsidyHalvingInterval = 150;
|
||||
nEnforceBlockUpgradeMajority = 0;
|
||||
nRejectBlockOutdatedMajority = 0;
|
||||
nToCheckBlockUpgradeMajority = 0;
|
||||
nMinerThreads = 1;
|
||||
nTargetTimespan = 24 * 60 * 60; // Agrarian: 1 day
|
||||
nTargetSpacing = 1 * 60; // Agrarian: 1 minutes
|
||||
bnProofOfWorkLimit = ~uint256(0) >> 1;
|
||||
nLastPOWBlock = 250;
|
||||
nMaturity = 20;
|
||||
nMasternodeCountDrift = 4;
|
||||
nModifierUpdateBlock = 0; //approx Mon, 17 Apr 2017 04:00:00 GMT
|
||||
nMaxMoneyOut = 43199500 * COIN;
|
||||
nZerocoinStartHeight = 300;
|
||||
nBlockZerocoinV2 = 300;
|
||||
nZerocoinStartTime = 1643790201;
|
||||
nBlockEnforceSerialRange = 1; //Enforce serial range starting this block
|
||||
nBlockRecalculateAccumulators = 999999999; //Trigger a recalculation of accumulators
|
||||
nBlockFirstFraudulent = 999999999; //First block that bad serials emerged
|
||||
nBlockLastGoodCheckpoint = 999999999; //Last valid accumulator checkpoint
|
||||
|
||||
// Public coin spend enforcement
|
||||
nPublicZCSpends = 350;
|
||||
|
||||
// Fake Serial Attack
|
||||
nFakeSerialBlockheightEnd = -1;
|
||||
|
||||
//! Modify the regtest genesis block so the timestamp is valid for a later start.
|
||||
genesis.nTime = 1643790201;
|
||||
genesis.nNonce = 21936323;
|
||||
|
||||
hashGenesisBlock = genesis.GetHash();
|
||||
assert(hashGenesisBlock == uint256("0x000003452250d81f8b07d42e127c92729802e3c48f3c7b9834256fd0fb9a0c2e"));
|
||||
//assert(hashGenesisBlock == uint256("0x17ce7900e21ae0ba9288440bdfcd020bcfb38714717745b4c6a7388990b4764b"));
|
||||
|
||||
vFixedSeeds.clear(); //! Testnet mode doesn't have any fixed seeds.
|
||||
vSeeds.clear(); //! Testnet mode doesn't have any DNS seeds.
|
||||
|
||||
fMiningRequiresPeers = false;
|
||||
fAllowMinDifficultyBlocks = true;
|
||||
fDefaultConsistencyChecks = true;
|
||||
fRequireStandard = false;
|
||||
fMineBlocksOnDemand = true;
|
||||
fSkipProofOfWorkCheck = true;
|
||||
fTestnetToBeDeprecatedFieldRPC = false;
|
||||
}
|
||||
const Checkpoints::CCheckpointData& Checkpoints() const
|
||||
{
|
||||
return dataRegtest;
|
||||
}
|
||||
};
|
||||
static CRegTestParams regTestParams;
|
||||
|
||||
/**
|
||||
* Unit test
|
||||
*/
|
||||
class CUnitTestParams : public CMainParams, public CModifiableParams
|
||||
{
|
||||
public:
|
||||
CUnitTestParams()
|
||||
{
|
||||
networkID = CBaseChainParams::UNITTEST;
|
||||
strNetworkID = "unittest";
|
||||
nDefaultPort = 51478;
|
||||
vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds.
|
||||
vSeeds.clear(); //! Unit test mode doesn't have any DNS seeds.
|
||||
|
||||
fMiningRequiresPeers = false;
|
||||
fDefaultConsistencyChecks = true;
|
||||
fAllowMinDifficultyBlocks = false;
|
||||
fMineBlocksOnDemand = true;
|
||||
}
|
||||
|
||||
const Checkpoints::CCheckpointData& Checkpoints() const
|
||||
{
|
||||
// UnitTest share the same checkpoints as MAIN
|
||||
return data;
|
||||
}
|
||||
|
||||
//! Published setters to allow changing values in unit test cases
|
||||
virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval = anSubsidyHalvingInterval; }
|
||||
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority = anEnforceBlockUpgradeMajority; }
|
||||
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority = anRejectBlockOutdatedMajority; }
|
||||
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority = anToCheckBlockUpgradeMajority; }
|
||||
virtual void setDefaultConsistencyChecks(bool afDefaultConsistencyChecks) { fDefaultConsistencyChecks = afDefaultConsistencyChecks; }
|
||||
virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks = afAllowMinDifficultyBlocks; }
|
||||
virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; }
|
||||
};
|
||||
static CUnitTestParams unitTestParams;
|
||||
|
||||
|
||||
static CChainParams* pCurrentParams = 0;
|
||||
|
||||
CModifiableParams* ModifiableParams()
|
||||
{
|
||||
assert(pCurrentParams);
|
||||
assert(pCurrentParams == &unitTestParams);
|
||||
return (CModifiableParams*)&unitTestParams;
|
||||
}
|
||||
|
||||
const CChainParams& Params()
|
||||
{
|
||||
assert(pCurrentParams);
|
||||
return *pCurrentParams;
|
||||
}
|
||||
|
||||
CChainParams& Params(CBaseChainParams::Network network)
|
||||
{
|
||||
switch (network) {
|
||||
case CBaseChainParams::MAIN:
|
||||
return mainParams;
|
||||
case CBaseChainParams::TESTNET:
|
||||
return testNetParams;
|
||||
case CBaseChainParams::REGTEST:
|
||||
return regTestParams;
|
||||
case CBaseChainParams::UNITTEST:
|
||||
return unitTestParams;
|
||||
default:
|
||||
assert(false && "Unimplemented network");
|
||||
return mainParams;
|
||||
}
|
||||
}
|
||||
|
||||
void SelectParams(CBaseChainParams::Network network)
|
||||
{
|
||||
SelectBaseParams(network);
|
||||
pCurrentParams = &Params(network);
|
||||
}
|
||||
|
||||
bool SelectParamsFromCommandLine()
|
||||
{
|
||||
CBaseChainParams::Network network = NetworkIdFromCommandLine();
|
||||
if (network == CBaseChainParams::MAX_NETWORK_TYPES)
|
||||
return false;
|
||||
|
||||
SelectParams(network);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2014-2015 The Dash developers
|
||||
// Copyright (c) 2015-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CHAINPARAMS_H
|
||||
#define BITCOIN_CHAINPARAMS_H
|
||||
|
||||
#include "chainparamsbase.h"
|
||||
#include "checkpoints.h"
|
||||
#include "primitives/block.h"
|
||||
#include "protocol.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include "libzerocoin/Params.h"
|
||||
#include <vector>
|
||||
|
||||
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
|
||||
|
||||
struct CDNSSeedData {
|
||||
std::string name, host;
|
||||
CDNSSeedData(const std::string& strName, const std::string& strHost) : name(strName), host(strHost) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* CChainParams defines various tweakable parameters of a given instance of the
|
||||
* Agrarian system. There are three: the main network on which people trade goods
|
||||
* and services, the public test network which gets reset from time to time and
|
||||
* a regression test mode which is intended for private networks only. It has
|
||||
* minimal difficulty to ensure that blocks can be found instantly.
|
||||
*/
|
||||
class CChainParams
|
||||
{
|
||||
public:
|
||||
enum Base58Type {
|
||||
PUBKEY_ADDRESS,
|
||||
SCRIPT_ADDRESS,
|
||||
SECRET_KEY, // BIP16
|
||||
EXT_PUBLIC_KEY, // BIP32
|
||||
EXT_SECRET_KEY, // BIP32
|
||||
EXT_COIN_TYPE, // BIP44
|
||||
|
||||
MAX_BASE58_TYPES
|
||||
};
|
||||
|
||||
const uint256& HashGenesisBlock() const { return hashGenesisBlock; }
|
||||
const MessageStartChars& MessageStart() const { return pchMessageStart; }
|
||||
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
|
||||
int GetDefaultPort() const { return nDefaultPort; }
|
||||
const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
|
||||
int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; }
|
||||
/** Used to check majorities for block version upgrade */
|
||||
int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; }
|
||||
int RejectBlockOutdatedMajority() const { return nRejectBlockOutdatedMajority; }
|
||||
int ToCheckBlockUpgradeMajority() const { return nToCheckBlockUpgradeMajority; }
|
||||
int MaxReorganizationDepth() const { return nMaxReorganizationDepth; }
|
||||
|
||||
/** Used if GenerateBitcoins is called with a negative number of threads */
|
||||
int DefaultMinerThreads() const { return nMinerThreads; }
|
||||
const CBlock& GenesisBlock() const { return genesis; }
|
||||
/** Make miner wait to have peers to avoid wasting work */
|
||||
bool MiningRequiresPeers() const { return fMiningRequiresPeers; }
|
||||
/** Headers first syncing is disabled */
|
||||
bool HeadersFirstSyncingActive() const { return fHeadersFirstSyncingActive; };
|
||||
/** Default value for -checkmempool and -checkblockindex argument */
|
||||
bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; }
|
||||
/** Allow mining of a min-difficulty block */
|
||||
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
|
||||
/** Skip proof-of-work check: allow mining of any difficulty block */
|
||||
bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; }
|
||||
/** Make standard checks */
|
||||
bool RequireStandard() const { return fRequireStandard; }
|
||||
int64_t TargetTimespan() const { return nTargetTimespan; }
|
||||
int64_t TargetSpacing() const { return nTargetSpacing; }
|
||||
int64_t Interval() const { return nTargetTimespan / nTargetSpacing; }
|
||||
int COINBASE_MATURITY() const { return nMaturity; }
|
||||
CAmount MaxMoneyOut() const { return nMaxMoneyOut; }
|
||||
/** The masternode count that we will allow the see-saw reward payments to be off by */
|
||||
int MasternodeCountDrift() const { return nMasternodeCountDrift; }
|
||||
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
|
||||
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
|
||||
/** In the future use NetworkIDString() for RPC fields */
|
||||
bool TestnetToBeDeprecatedFieldRPC() const { return fTestnetToBeDeprecatedFieldRPC; }
|
||||
/** Return the BIP70 network string (main, test or regtest) */
|
||||
std::string NetworkIDString() const { return strNetworkID; }
|
||||
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
|
||||
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
|
||||
const std::vector<CAddress>& FixedSeeds() const { return vFixedSeeds; }
|
||||
virtual const Checkpoints::CCheckpointData& Checkpoints() const = 0;
|
||||
int PoolMaxTransactions() const { return nPoolMaxTransactions; }
|
||||
/** Return the number of blocks in a budget cycle */
|
||||
int GetBudgetCycleBlocks() const { return nBudgetCycleBlocks; }
|
||||
int64_t GetProposalEstablishmentTime() const { return nProposalEstablishmentTime; }
|
||||
|
||||
/** Spork key and Masternode Handling **/
|
||||
std::string SporkKey() const { return strSporkKey; }
|
||||
std::string SporkKeyOld() const { return strSporkKeyOld; }
|
||||
int64_t NewSporkStart() const { return nEnforceNewSporkKey; }
|
||||
int64_t RejectOldSporkKey() const { return nRejectOldSporkKey; }
|
||||
std::string ObfuscationPoolDummyAddress() const { return strObfuscationPoolDummyAddress; }
|
||||
int64_t StartMasternodePayments() const { return nStartMasternodePayments; }
|
||||
int64_t Budget_Fee_Confirmations() const { return nBudget_Fee_Confirmations; }
|
||||
|
||||
CBaseChainParams::Network NetworkID() const { return networkID; }
|
||||
|
||||
/** Zerocoin **/
|
||||
std::string Zerocoin_Modulus() const { return zerocoinModulus; }
|
||||
libzerocoin::ZerocoinParams* Zerocoin_Params(bool useModulusV1) const;
|
||||
int Zerocoin_MaxSpendsPerTransaction() const { return nMaxZerocoinSpendsPerTransaction; }
|
||||
int Zerocoin_MaxPublicSpendsPerTransaction() const { return nMaxZerocoinPublicSpendsPerTransaction; }
|
||||
CAmount Zerocoin_MintFee() const { return nMinZerocoinMintFee; }
|
||||
int Zerocoin_MintRequiredConfirmations() const { return nMintRequiredConfirmations; }
|
||||
int Zerocoin_RequiredAccumulation() const { return nRequiredAccumulation; }
|
||||
int Zerocoin_DefaultSpendSecurity() const { return nDefaultSecurityLevel; }
|
||||
int Zerocoin_HeaderVersion() const { return nZerocoinHeaderVersion; }
|
||||
int Zerocoin_RequiredStakeDepth() const { return nZerocoinRequiredStakeDepth; }
|
||||
|
||||
/** Height or Time Based Activations **/
|
||||
int ModifierUpgradeBlock() const { return nModifierUpdateBlock; }
|
||||
int LAST_POW_BLOCK() const { return nLastPOWBlock; }
|
||||
int Zerocoin_StartHeight() const { return nZerocoinStartHeight; }
|
||||
int Zerocoin_Block_EnforceSerialRange() const { return nBlockEnforceSerialRange; }
|
||||
int Zerocoin_Block_RecalculateAccumulators() const { return nBlockRecalculateAccumulators; }
|
||||
int Zerocoin_Block_FirstFraudulent() const { return nBlockFirstFraudulent; }
|
||||
int Zerocoin_Block_LastGoodCheckpoint() const { return nBlockLastGoodCheckpoint; }
|
||||
int Zerocoin_StartTime() const { return nZerocoinStartTime; }
|
||||
int Block_Enforce_Invalid() const { return nBlockEnforceInvalidUTXO; }
|
||||
int Zerocoin_Block_V2_Start() const { return nBlockZerocoinV2; }
|
||||
|
||||
// fake serial attack
|
||||
int Zerocoin_Block_EndFakeSerial() const { return nFakeSerialBlockheightEnd; }
|
||||
CAmount GetSupplyBeforeFakeSerial() const { return nSupplyBeforeFakeSerial; }
|
||||
|
||||
int Zerocoin_Block_Double_Accumulated() const { return nBlockDoubleAccumulated; }
|
||||
CAmount InvalidAmountFiltered() const { return nInvalidAmountFiltered; };
|
||||
|
||||
int Zerocoin_Block_Public_Spend_Enabled() const { return nPublicZCSpends; }
|
||||
|
||||
protected:
|
||||
CChainParams() {}
|
||||
|
||||
uint256 hashGenesisBlock;
|
||||
MessageStartChars pchMessageStart;
|
||||
//! Raw pub key bytes for the broadcast alert signing key.
|
||||
std::vector<unsigned char> vAlertPubKey;
|
||||
int nDefaultPort;
|
||||
uint256 bnProofOfWorkLimit;
|
||||
int nMaxReorganizationDepth;
|
||||
int nSubsidyHalvingInterval;
|
||||
int nEnforceBlockUpgradeMajority;
|
||||
int nRejectBlockOutdatedMajority;
|
||||
int nToCheckBlockUpgradeMajority;
|
||||
int64_t nTargetTimespan;
|
||||
int64_t nTargetSpacing;
|
||||
int nLastPOWBlock;
|
||||
int nMasternodeCountDrift;
|
||||
int nMaturity;
|
||||
int nModifierUpdateBlock;
|
||||
CAmount nMaxMoneyOut;
|
||||
int nMinerThreads;
|
||||
std::vector<CDNSSeedData> vSeeds;
|
||||
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
|
||||
CBaseChainParams::Network networkID;
|
||||
std::string strNetworkID;
|
||||
CBlock genesis;
|
||||
std::vector<CAddress> vFixedSeeds;
|
||||
bool fMiningRequiresPeers;
|
||||
bool fAllowMinDifficultyBlocks;
|
||||
bool fDefaultConsistencyChecks;
|
||||
bool fRequireStandard;
|
||||
bool fMineBlocksOnDemand;
|
||||
bool fSkipProofOfWorkCheck;
|
||||
bool fTestnetToBeDeprecatedFieldRPC;
|
||||
bool fHeadersFirstSyncingActive;
|
||||
int nPoolMaxTransactions;
|
||||
int nBudgetCycleBlocks;
|
||||
std::string strSporkKey;
|
||||
std::string strSporkKeyOld;
|
||||
int64_t nEnforceNewSporkKey;
|
||||
int64_t nRejectOldSporkKey;
|
||||
std::string strObfuscationPoolDummyAddress;
|
||||
int64_t nStartMasternodePayments;
|
||||
std::string zerocoinModulus;
|
||||
int nMaxZerocoinSpendsPerTransaction;
|
||||
int nMaxZerocoinPublicSpendsPerTransaction;
|
||||
CAmount nMinZerocoinMintFee;
|
||||
CAmount nInvalidAmountFiltered;
|
||||
int nMintRequiredConfirmations;
|
||||
int nRequiredAccumulation;
|
||||
int nDefaultSecurityLevel;
|
||||
int nZerocoinHeaderVersion;
|
||||
int64_t nBudget_Fee_Confirmations;
|
||||
int nZerocoinStartHeight;
|
||||
int nZerocoinStartTime;
|
||||
int nZerocoinRequiredStakeDepth;
|
||||
int64_t nProposalEstablishmentTime;
|
||||
|
||||
int nBlockEnforceSerialRange;
|
||||
int nBlockRecalculateAccumulators;
|
||||
int nBlockFirstFraudulent;
|
||||
int nBlockLastGoodCheckpoint;
|
||||
int nBlockEnforceInvalidUTXO;
|
||||
int nBlockZerocoinV2;
|
||||
int nBlockDoubleAccumulated;
|
||||
int nPublicZCSpends;
|
||||
|
||||
// fake serial attack
|
||||
int nFakeSerialBlockheightEnd = 0;
|
||||
CAmount nSupplyBeforeFakeSerial = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Modifiable parameters interface is used by test cases to adapt the parameters in order
|
||||
* to test specific features more easily. Test cases should always restore the previous
|
||||
* values after finalization.
|
||||
*/
|
||||
|
||||
class CModifiableParams
|
||||
{
|
||||
public:
|
||||
//! Published setters to allow changing values in unit test cases
|
||||
virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) = 0;
|
||||
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) = 0;
|
||||
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) = 0;
|
||||
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) = 0;
|
||||
virtual void setDefaultConsistencyChecks(bool aDefaultConsistencyChecks) = 0;
|
||||
virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks) = 0;
|
||||
virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return the currently selected parameters. This won't change after app startup
|
||||
* outside of the unit tests.
|
||||
*/
|
||||
const CChainParams& Params();
|
||||
|
||||
/** Return parameters for the given network. */
|
||||
CChainParams& Params(CBaseChainParams::Network network);
|
||||
|
||||
/** Get modifiable network parameters (UNITTEST only) */
|
||||
CModifiableParams* ModifiableParams();
|
||||
|
||||
/** Sets the params returned by Params() to those for the given network. */
|
||||
void SelectParams(CBaseChainParams::Network network);
|
||||
|
||||
/**
|
||||
* Looks for -regtest or -testnet and then calls SelectParams as appropriate.
|
||||
* Returns false if an invalid combination is given.
|
||||
*/
|
||||
bool SelectParamsFromCommandLine();
|
||||
|
||||
#endif // BITCOIN_CHAINPARAMS_H
|
||||
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2016-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "chainparamsbase.h"
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
/**
|
||||
* Main network
|
||||
*/
|
||||
class CBaseMainParams : public CBaseChainParams
|
||||
{
|
||||
public:
|
||||
CBaseMainParams()
|
||||
{
|
||||
networkID = CBaseChainParams::MAIN;
|
||||
nRPCPort = 51335;
|
||||
}
|
||||
};
|
||||
static CBaseMainParams mainParams;
|
||||
|
||||
/**
|
||||
* Testnet (v3)
|
||||
*/
|
||||
class CBaseTestNetParams : public CBaseMainParams
|
||||
{
|
||||
public:
|
||||
CBaseTestNetParams()
|
||||
{
|
||||
networkID = CBaseChainParams::TESTNET;
|
||||
nRPCPort = 61335;
|
||||
strDataDir = "testnet4";
|
||||
}
|
||||
};
|
||||
static CBaseTestNetParams testNetParams;
|
||||
|
||||
/*
|
||||
* Regression test
|
||||
*/
|
||||
class CBaseRegTestParams : public CBaseTestNetParams
|
||||
{
|
||||
public:
|
||||
CBaseRegTestParams()
|
||||
{
|
||||
networkID = CBaseChainParams::REGTEST;
|
||||
strDataDir = "regtest";
|
||||
}
|
||||
};
|
||||
static CBaseRegTestParams regTestParams;
|
||||
|
||||
/*
|
||||
* Unit test
|
||||
*/
|
||||
class CBaseUnitTestParams : public CBaseMainParams
|
||||
{
|
||||
public:
|
||||
CBaseUnitTestParams()
|
||||
{
|
||||
networkID = CBaseChainParams::UNITTEST;
|
||||
strDataDir = "unittest";
|
||||
}
|
||||
};
|
||||
static CBaseUnitTestParams unitTestParams;
|
||||
|
||||
static CBaseChainParams* pCurrentBaseParams = 0;
|
||||
|
||||
const CBaseChainParams& BaseParams()
|
||||
{
|
||||
assert(pCurrentBaseParams);
|
||||
return *pCurrentBaseParams;
|
||||
}
|
||||
|
||||
void SelectBaseParams(CBaseChainParams::Network network)
|
||||
{
|
||||
switch (network) {
|
||||
case CBaseChainParams::MAIN:
|
||||
pCurrentBaseParams = &mainParams;
|
||||
break;
|
||||
case CBaseChainParams::TESTNET:
|
||||
pCurrentBaseParams = &testNetParams;
|
||||
break;
|
||||
case CBaseChainParams::REGTEST:
|
||||
pCurrentBaseParams = ®TestParams;
|
||||
break;
|
||||
case CBaseChainParams::UNITTEST:
|
||||
pCurrentBaseParams = &unitTestParams;
|
||||
break;
|
||||
default:
|
||||
assert(false && "Unimplemented network");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CBaseChainParams::Network NetworkIdFromCommandLine()
|
||||
{
|
||||
bool fRegTest = GetBoolArg("-regtest", false);
|
||||
bool fTestNet = GetBoolArg("-testnet", false);
|
||||
|
||||
if (fTestNet && fRegTest)
|
||||
return CBaseChainParams::MAX_NETWORK_TYPES;
|
||||
if (fRegTest)
|
||||
return CBaseChainParams::REGTEST;
|
||||
if (fTestNet)
|
||||
return CBaseChainParams::TESTNET;
|
||||
return CBaseChainParams::MAIN;
|
||||
}
|
||||
|
||||
bool SelectBaseParamsFromCommandLine()
|
||||
{
|
||||
CBaseChainParams::Network network = NetworkIdFromCommandLine();
|
||||
if (network == CBaseChainParams::MAX_NETWORK_TYPES)
|
||||
return false;
|
||||
|
||||
SelectBaseParams(network);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AreBaseParamsConfigured()
|
||||
{
|
||||
return pCurrentBaseParams != NULL;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CHAINPARAMSBASE_H
|
||||
#define BITCOIN_CHAINPARAMSBASE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* CBaseChainParams defines the base parameters (shared between agrarian-cli and agrariand)
|
||||
* of a given instance of the Agrarian system.
|
||||
*/
|
||||
class CBaseChainParams
|
||||
{
|
||||
public:
|
||||
enum Network {
|
||||
MAIN,
|
||||
TESTNET,
|
||||
REGTEST,
|
||||
UNITTEST,
|
||||
|
||||
MAX_NETWORK_TYPES
|
||||
};
|
||||
|
||||
const std::string& DataDir() const { return strDataDir; }
|
||||
int RPCPort() const { return nRPCPort; }
|
||||
|
||||
protected:
|
||||
CBaseChainParams() {}
|
||||
|
||||
int nRPCPort;
|
||||
std::string strDataDir;
|
||||
Network networkID;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the currently selected parameters. This won't change after app startup
|
||||
* outside of the unit tests.
|
||||
*/
|
||||
const CBaseChainParams& BaseParams();
|
||||
|
||||
/** Sets the params returned by Params() to those for the given network. */
|
||||
void SelectBaseParams(CBaseChainParams::Network network);
|
||||
|
||||
/**
|
||||
* Looks for -regtest or -testnet and returns the appropriate Network ID.
|
||||
* Returns MAX_NETWORK_TYPES if an invalid combination is given.
|
||||
*/
|
||||
CBaseChainParams::Network NetworkIdFromCommandLine();
|
||||
|
||||
/**
|
||||
* Calls NetworkIdFromCommandLine() and then calls SelectParams as appropriate.
|
||||
* Returns false if an invalid combination is given.
|
||||
*/
|
||||
bool SelectBaseParamsFromCommandLine();
|
||||
|
||||
/**
|
||||
* Return true if SelectBaseParamsFromCommandLine() has been called to select
|
||||
* a network.
|
||||
*/
|
||||
bool AreBaseParamsConfigured();
|
||||
|
||||
#endif // BITCOIN_CHAINPARAMSBASE_H
|
||||
@@ -0,0 +1,263 @@
|
||||
#ifndef BITCOIN_CHAINPARAMSSEEDS_H
|
||||
#define BITCOIN_CHAINPARAMSSEEDS_H
|
||||
/**
|
||||
* List of fixed seed nodes for the bitcoin network
|
||||
* AUTOGENERATED by contrib/seeds/generate-seeds.py
|
||||
*
|
||||
* Each line contains a 16-byte IPv6 address and a port.
|
||||
* IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.
|
||||
*/
|
||||
static SeedSpec6 pnSeed6_main[] = {
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0xee,0x61,0xfd}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0x84,0xa2}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0d,0x5e,0xbc,0x1b}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0x8a,0x10,0x5f}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0x8a,0x25,0xcb}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x2c,0x14,0x8c}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x28,0x75,0xd1,0x49}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x23,0xfb,0x45}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x3a,0x3c,0x9e}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4c,0x14,0x49}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x24,0x27,0x75}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x24,0x28,0xc9}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x2c,0x24,0xe3}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x2b,0xc2}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x0f,0x70,0xef}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x0f,0x7f,0xd9}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x26,0x46,0xf1}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x4d,0xc0,0x09}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x71,0xc4,0x3d}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xb2,0x18,0xf8}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x34,0x57,0x46}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0xbc,0xe5,0xd1}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0x4f,0x99}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x58,0xd2,0x31}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd0,0x25,0x0d}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xee,0x50,0x61}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x54,0x92,0x95}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd1,0xda,0xe0}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xfd,0x0c}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd9,0x3e,0xce}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x2b,0xa4}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x8f,0x19}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd9,0xaa,0xce}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x16,0x6f,0x57}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x2f,0xa3,0x06}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa8,0xb3,0x50}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x2e,0x92}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xe6,0x35,0x1b}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x0c,0x42,0x46}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xa8,0x93,0x48}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xed,0x02,0xbf}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x74,0xca,0x10,0xe4}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xdd,0xa7,0xd4}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xff,0x0c,0x03}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0x0b,0xe8,0x2f}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0x5d,0xe9,0xda}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x1c,0x0f,0x6d}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0x45,0xc5,0x9a}, 51471},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x46,0xe1,0xcf}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x68,0x4a,0x99}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf9,0x29,0x5c}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x66,0x42}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x17,0x6f}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xa2,0xfa,0x44}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xaa,0x70,0xd5}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xb1,0x3b,0x8c}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xb9,0x28,0xcf}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xa9,0x07,0xdb}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xd2,0xda,0x8c}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x63,0x15,0x45}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x63,0x16,0x83}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x63,0x17,0xda}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xe4,0x0c,0x3d}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x90,0x88,0xd7}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x10,0x78,0x4f}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x18,0x60,0x73}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x77,0x15,0x39}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xbd,0x93,0xeb}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xc4,0xd9,0x6b}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x3d,0x69,0xd4}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x79,0x24,0xc8}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x91,0x5b,0x06}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x99,0xdc,0x41}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0xeb,0xb7,0x35}, 51336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xde,0x98,0xc0,0xf2}, 51336},
|
||||
{{0x20,0x01,0x19,0xf0,0x50,0x01,0x24,0x73,0x54,0x00,0x01,0xff,0xfe,0xcf,0x79,0xb7}, 51336},
|
||||
{{0x20,0x01,0x41,0xd0,0x00,0x02,0x9f,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x10,0x33,0xe4,0xff,0xfe,0xb7,0x21,0xcd}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x10,0xa2,0x93,0xff,0xfe,0x6c,0x28,0xe1}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x14,0xb3,0x85,0xff,0xfe,0xb1,0x19,0x23}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x18,0x3a,0xb7,0xff,0xfe,0x7d,0x5d,0x51}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x00,0x18,0x6e,0xff,0xfe,0xd6,0xad,0x45}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x18,0xbe,0x5b,0xff,0xfe,0xa8,0x43,0xfc}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x18,0xfe,0x16,0xff,0xfe,0x53,0x3f,0xbf}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x20,0x67,0x0e,0xff,0xfe,0xda,0x21,0x3b}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x24,0x0b,0xfd,0xff,0xfe,0x59,0x83,0x88}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x24,0xdd,0x4f,0xff,0xfe,0x78,0xdd,0x4c}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x28,0x3f,0x77,0xff,0xfe,0xdd,0xb4,0xae}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x30,0xbc,0x40,0xff,0xfe,0x3f,0xf3,0x33}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x34,0x01,0xb1,0xff,0xfe,0x96,0xc5,0x27}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x34,0x26,0x43,0xff,0xfe,0xb3,0x54,0x9e}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x34,0x37,0xb2,0xff,0xfe,0xb7,0x95,0x0f}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x34,0x91,0x5e,0xff,0xfe,0xca,0x4e,0xf0}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x38,0x30,0x4a,0xff,0xfe,0xce,0x2b,0xa8}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x3c,0x5c,0x9e,0xff,0xfe,0x92,0xac,0xa4}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x40,0x2f,0xda,0xff,0xfe,0x96,0x5b,0x22}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x40,0xc8,0x93,0xff,0xfe,0x46,0x82,0xac}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x04,0x4f,0x27,0xff,0xfe,0x6c,0x29,0xcc}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x48,0xa0,0x24,0xff,0xfe,0x32,0x87,0x8d}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x4c,0xb2,0x81,0xff,0xfe,0x61,0x37,0x29}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x50,0xe9,0x3a,0xff,0xfe,0x7f,0xe7,0xe9}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x54,0x26,0x0e,0xff,0xfe,0xb4,0x36,0x74}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x54,0x55,0x65,0xff,0xfe,0x17,0x09,0x63}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x58,0xdb,0x9b,0xff,0xfe,0x0e,0xbc,0xe5}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x5c,0x13,0x54,0xff,0xfe,0xd5,0x19,0x19}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x5c,0x4b,0x2e,0xff,0xfe,0xcf,0xbf,0xfb}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x5c,0x76,0x74,0xff,0xfe,0x93,0xda,0x00}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x60,0x33,0x2c,0xff,0xfe,0xe2,0x4c,0x15}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x60,0x35,0x33,0xff,0xfe,0x30,0x32,0x34}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x64,0x0f,0xd6,0xff,0xfe,0xa0,0xbf,0x29}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x64,0x30,0x65,0xff,0xfe,0x42,0xad,0xdc}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x64,0x35,0x34,0xff,0xfe,0x37,0x37,0x36}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x64,0x84,0x65,0xff,0xfe,0xbc,0xa0,0xef}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x68,0x05,0xfa,0xff,0xfe,0x3f,0xd4,0x57}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x68,0x98,0x37,0xff,0xfe,0x8a,0xbd,0xd9}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x6c,0x70,0x46,0xff,0xfe,0x67,0x1e,0x72}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x70,0xf9,0xb1,0xff,0xfe,0x1d,0xaf,0x40}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x7c,0x17,0x1f,0xff,0xfe,0x87,0x46,0xed}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x7c,0x36,0xcd,0xff,0xfe,0x07,0x3a,0x17}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x7c,0xe7,0xaa,0xff,0xfe,0xcd,0x73,0xf1}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x08,0x07,0x6c,0xff,0xfe,0xf5,0xdc,0xf1}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x80,0x81,0x08,0xff,0xfe,0xe3,0xb3,0xed}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x80,0x89,0xd7,0xff,0xfe,0x28,0xd8,0xc5}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x80,0xb2,0xef,0xff,0xfe,0x73,0x1f,0x00}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x08,0x10,0x8a,0xff,0xfe,0x44,0xfd,0x7f}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x8c,0x44,0xeb,0xff,0xfe,0xc9,0x30,0x39}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x8c,0x65,0x26,0xff,0xfe,0xa0,0x84,0xca}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x8c,0x8b,0x7f,0xff,0xfe,0x80,0xd3,0xa4}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x8c,0xd4,0x98,0xff,0xfe,0x98,0x3e,0x96}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x08,0xce,0x92,0xff,0xfe,0xf9,0xaf,0x8d}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x08,0xcf,0x32,0xff,0xfe,0x08,0xe3,0xec}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x90,0x20,0x97,0xff,0xfe,0x38,0x30,0x1a}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x90,0x25,0xae,0xff,0xfe,0xb5,0xc7,0x02}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x90,0x5c,0xf3,0xff,0xfe,0x7f,0x1f,0xbb}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x90,0xaa,0xdf,0xff,0xfe,0x2f,0xd5,0x3c}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x94,0x68,0xf2,0xff,0xfe,0xcb,0xe3,0xda}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x94,0x94,0xba,0xff,0xfe,0x79,0x20,0xdd}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x98,0x27,0x57,0xff,0xfe,0xfb,0xb7,0x8f}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x98,0x46,0x5a,0xff,0xfe,0x9e,0xaf,0xce}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x98,0x90,0xdd,0xff,0xfe,0xa1,0xa3,0x2c}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xa0,0x46,0x62,0xff,0xfe,0x28,0x2f,0x6e}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xa0,0x5d,0x64,0xff,0xfe,0xbe,0xf5,0x2a}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xa0,0x86,0x54,0xff,0xfe,0xc5,0xa6,0x03}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xac,0x7e,0x13,0xff,0xfe,0xdf,0xec,0x7c}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xb4,0xb9,0x24,0xff,0xfe,0x6d,0xe9,0x95}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xb8,0x06,0x5e,0xff,0xfe,0x4e,0xc7,0xb3}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xb8,0x23,0xf5,0xff,0xfe,0xf7,0x1d,0x07}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xb8,0xb7,0xfd,0xff,0xfe,0x7a,0xad,0x81}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xb8,0xe3,0x58,0xff,0xfe,0x33,0x41,0xf5}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xbc,0x0d,0xfc,0xff,0xfe,0x6b,0xdf,0x23}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xc0,0x56,0x05,0xff,0xfe,0xa1,0x17,0x25}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xc0,0xd3,0x4b,0xff,0xfe,0x6f,0xe2,0x91}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x0c,0x3c,0x33,0xff,0xfe,0x70,0x28,0xc8}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xc4,0xc2,0x4f,0xff,0xfe,0xe6,0xa0,0x8c}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x0c,0x5b,0x49,0xff,0xfe,0x85,0xe3,0x4b}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xcc,0xce,0xe1,0xff,0xfe,0x21,0x01,0x88}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xcc,0xf5,0x54,0xff,0xfe,0x1a,0x1e,0xcb}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xd4,0x55,0x6f,0xff,0xfe,0xd5,0x9e,0xad}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xd4,0xad,0xe0,0xff,0xfe,0xbc,0x5b,0xf1}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xd4,0xb5,0x48,0xff,0xfe,0x27,0xa7,0x02}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xd4,0xf7,0xef,0xff,0xfe,0xb1,0x75,0x07}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xd8,0x58,0x28,0xff,0xfe,0xe9,0x0a,0xd9}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xe4,0xed,0x2a,0xff,0xfe,0x51,0x6a,0x3b}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xec,0x74,0x92,0xff,0xfe,0x8a,0x5b,0xfb}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xec,0xdb,0x84,0xff,0xfe,0xeb,0xe6,0x59}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xf4,0x73,0x62,0xff,0xfe,0x90,0x4d,0xbe}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xf4,0xad,0x20,0xff,0xfe,0xa4,0xf9,0x95}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0x00,0xf7,0x6a,0xff,0xfe,0xde,0xf6,0x70}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xfc,0x45,0x33,0xff,0xfe,0xc1,0xd9,0x66}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xfc,0xd9,0xd4,0xff,0xfe,0xda,0x5a,0x4e}, 51336},
|
||||
{{0x20,0x01,0x04,0x70,0x1f,0x11,0x01,0xd4,0xfc,0xde,0x9f,0xff,0xfe,0xa7,0x8a,0x4a}, 51336},
|
||||
{{0x20,0x01,0x07,0x70,0x00,0x20,0x49,0x70,0x19,0x99,0x6c,0x63,0x4a,0xe2,0xaa,0x95}, 51336},
|
||||
{{0x24,0x00,0x24,0x11,0xab,0xa1,0x19,0x00,0x20,0x03,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x24,0x01,0xc0,0x80,0x10,0x00,0x4c,0x85,0x54,0x00,0x01,0xff,0x12,0x2b,0xdd,0x01}, 51336},
|
||||
{{0x24,0x01,0xc0,0x80,0x18,0x00,0x4c,0xa5,0x54,0x00,0x01,0xff,0xfe,0xe5,0xfa,0x7d}, 51336},
|
||||
{{0x24,0x03,0x56,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x5f,0x01}, 51336},
|
||||
{{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc1,0x5b,0xec}, 51336},
|
||||
{{0x26,0x02,0xff,0xc5,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x38,0x0d}, 51336},
|
||||
{{0x26,0x02,0xff,0xc5,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3c,0xef}, 51336},
|
||||
{{0x26,0x02,0xff,0xc5,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x22,0xfe}, 51336},
|
||||
{{0x26,0x02,0xff,0xc5,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0xa7}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x01,0x40,0x12,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x01,0x40,0x12,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x80}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x01,0x41,0x11,0x9b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x01,0x92,0x73,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x17}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x01,0x92,0x73,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd4}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x1c,0x0c,0x54,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x1c,0x1c,0x69,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x1c,0x1c,0x7e,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x02,0x11,0x15,0x51,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x02,0x11,0x17,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x02,0x21,0x11,0x42,0xd0,0x0d,0x00,0x00,0xba,0xbe,0xfa,0xce}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x02,0x21,0x11,0x42,0xd0,0x0d,0x00,0x00,0x00,0x00,0xee,0x01}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x0c,0x2c,0x26,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x0c,0x2c,0x5a,0x2e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x2a,0x01,0x04,0xf9,0xc0,0x10,0x21,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x2a,0x01,0x0e,0x0a,0x01,0x65,0x52,0x70,0xdd,0xa8,0xad,0xb7,0xf2,0x6f,0x04,0x69}, 51336},
|
||||
{{0x2a,0x02,0x12,0x0b,0x2c,0x7b,0x7c,0xc0,0x42,0xb1,0xaf,0x0f,0xff,0x19,0x94,0xa2}, 51336},
|
||||
{{0x2a,0x02,0x01,0x68,0xac,0x05,0x00,0x03,0x00,0x00,0x02,0x42,0xac,0x11,0x00,0x05}, 51336},
|
||||
{{0x2a,0x02,0x01,0x68,0xac,0x05,0x00,0x03,0x00,0x00,0x02,0x42,0xac,0x11,0x00,0x06}, 51336},
|
||||
{{0x2a,0x02,0x7b,0x40,0xc2,0x87,0x59,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x2a,0x02,0xc2,0x07,0x20,0x20,0x64,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 51336},
|
||||
{{0x2a,0x0b,0x70,0x80,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x96,0x45}, 51336},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd0,0x22,0xb1,0x3a,0x45,0x60,0x0c,0x73,0x06,0x60}, 9835},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xff,0x89,0x19,0x38,0xec,0x6e,0xc4,0x21,0x32,0x23}, 51336},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xfa,0xe7,0x54,0x9c,0x2b,0xc1,0xdd,0x74,0xe1,0xec}, 9871},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x07,0x9f,0x1b,0x54,0x41,0x49,0xcb,0x79,0x83,0xee}, 9846},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x02,0x25,0x83,0x67,0x00,0x2d,0x5a,0xa4,0x43,0x01}, 9836},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1a,0x3c,0x0f,0xd4,0x0d,0x80,0x0a,0x0f,0xa7,0xca}, 9875},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1b,0x9d,0x75,0x02,0x9f,0x1d,0x46,0x12,0x7a,0x5c}, 9870},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x22,0x32,0x72,0x72,0xed,0x8d,0x32,0xee,0xb4,0x88}, 9865},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x25,0x35,0xc6,0xae,0x57,0xb4,0x86,0x60,0x71,0xf3}, 9975},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2a,0xb8,0x33,0xd1,0x3f,0x22,0xda,0xc0,0x88,0x2b}, 9980},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2b,0x96,0xe9,0x17,0xa2,0xb3,0xa6,0xb9,0x11,0x33}, 9857},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2d,0x55,0xac,0x4e,0x01,0x36,0x24,0x4a,0x56,0xdf}, 9892},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2e,0x0b,0x75,0x0a,0xc7,0x6f,0xec,0x7d,0x2b,0x84}, 9971},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x34,0x83,0x23,0x72,0x3e,0xd2,0x6b,0x17,0x35,0xf2}, 9882},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3e,0x98,0xb9,0x57,0xf0,0x5a,0x26,0x41,0x16,0xa4}, 9918},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3a,0x6d,0x29,0x5c,0xed,0x0b,0x19,0x59,0x28,0x36}, 9843},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3c,0xf1,0x4d,0x47,0xd4,0xfe,0x0f,0xd2,0xa8,0x2d}, 9842},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x42,0x79,0xe2,0xfc,0x71,0x1b,0x54,0xb3,0x28,0xc2}, 9867},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x49,0x06,0x6c,0x34,0x68,0x65,0xc7,0x54,0xaf,0xb3}, 9834},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x51,0xe4,0x59,0xc0,0x91,0x39,0x7d,0xe1,0x9e,0xd2}, 9850},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x55,0x36,0x34,0xa4,0xa4,0x96,0x15,0x94,0x53,0x64}, 9862},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x55,0x65,0x34,0xdf,0xa3,0x13,0x35,0x53,0x23,0xe0}, 9860},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5f,0x8b,0x94,0x16,0x76,0xd7,0x7b,0xf4,0x24,0xe8}, 9997},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x69,0x00,0xe0,0xa0,0x3b,0x38,0xb9,0xf1,0xde}, 51336},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8f,0x4f,0x6a,0x0c,0xbc,0xf5,0x94,0x51,0x74,0x3e}, 51336},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb7,0xb0,0xd1,0x08,0x71,0xcd,0xe9,0x2f,0xeb,0x1c}, 9894}
|
||||
};
|
||||
|
||||
static SeedSpec6 pnSeed6_test[] = {
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x23,0xfb,0x45}, 61336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x59,0x2e,0xc0}, 61336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0xc0,0x6e}, 61336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe0,0xbc}, 61336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x51,0xa6,0x3c}, 61336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0xd4,0x52}, 61336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x23,0x6c,0x6b}, 61336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xc9,0x7d,0x5e}, 61336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x05,0x15,0x1f}, 61336},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x18,0x66,0x01}, 61336},
|
||||
{{0x26,0x02,0xff,0xc5,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3c,0xef}, 61336},
|
||||
{{0x26,0x02,0xff,0xc5,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0xa7}, 61336},
|
||||
{{0x26,0x02,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x72,0x54,0x5d}, 61336},
|
||||
{{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x37,0xc7,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06}, 61336},
|
||||
{{0x2a,0x02,0x7b,0x40,0xc2,0x87,0x59,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 61336},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x17,0x5e,0xab,0xb5,0xf5,0xf9,0xe7,0xb9,0xc0,0x82}, 61336},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2b,0x2b,0xbe,0x13,0xc0,0x7c,0x61,0x6e,0x6b,0xf6}, 61336},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa4,0x77,0x7b,0xc5,0xe3,0xf8,0x3f,0x68,0xa1,0x79}, 61336},
|
||||
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xab,0x47,0x92,0xd9,0xb7,0x3b,0x2d,0x6d,0xaa,0x1f}, 61336}
|
||||
};
|
||||
#endif // BITCOIN_CHAINPARAMSSEEDS_H
|
||||
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2014-2015 The Dash developers
|
||||
// Copyright (c) 2015-2017 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "checkpoints.h"
|
||||
|
||||
#include "chainparams.h"
|
||||
#include "main.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
namespace Checkpoints
|
||||
{
|
||||
/**
|
||||
* How many times we expect transactions after the last checkpoint to
|
||||
* be slower. This number is a compromise, as it can't be accurate for
|
||||
* every system. When reindexing from a fast disk with a slow CPU, it
|
||||
* can be up to 20, while when downloading from a slow network with a
|
||||
* fast multicore CPU, it won't be much higher than 1.
|
||||
*/
|
||||
static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;
|
||||
|
||||
bool fEnabled = true;
|
||||
|
||||
bool CheckBlock(int nHeight, const uint256& hash, bool fMatchesCheckpoint)
|
||||
{
|
||||
if (!fEnabled)
|
||||
return true;
|
||||
|
||||
const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
|
||||
|
||||
MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
|
||||
// If looking for an exact match, then return false
|
||||
if (i == checkpoints.end()) return !fMatchesCheckpoint;
|
||||
return hash == i->second;
|
||||
}
|
||||
|
||||
//! Guess how far we are in the verification process at the given block index
|
||||
double GuessVerificationProgress(CBlockIndex* pindex, bool fSigchecks)
|
||||
{
|
||||
if (pindex == NULL)
|
||||
return 0.0;
|
||||
|
||||
int64_t nNow = time(NULL);
|
||||
|
||||
double fSigcheckVerificationFactor = fSigchecks ? SIGCHECK_VERIFICATION_FACTOR : 1.0;
|
||||
double fWorkBefore = 0.0; // Amount of work done before pindex
|
||||
double fWorkAfter = 0.0; // Amount of work left after pindex (estimated)
|
||||
// Work is defined as: 1.0 per transaction before the last checkpoint, and
|
||||
// fSigcheckVerificationFactor per transaction after.
|
||||
|
||||
const CCheckpointData& data = Params().Checkpoints();
|
||||
|
||||
if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
|
||||
double nCheapBefore = pindex->nChainTx;
|
||||
double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
|
||||
double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint) / 86400.0 * data.fTransactionsPerDay;
|
||||
fWorkBefore = nCheapBefore;
|
||||
fWorkAfter = nCheapAfter + nExpensiveAfter * fSigcheckVerificationFactor;
|
||||
} else {
|
||||
double nCheapBefore = data.nTransactionsLastCheckpoint;
|
||||
double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
|
||||
double nExpensiveAfter = (nNow - pindex->GetBlockTime()) / 86400.0 * data.fTransactionsPerDay;
|
||||
fWorkBefore = nCheapBefore + nExpensiveBefore * fSigcheckVerificationFactor;
|
||||
fWorkAfter = nExpensiveAfter * fSigcheckVerificationFactor;
|
||||
}
|
||||
|
||||
return fWorkBefore / (fWorkBefore + fWorkAfter);
|
||||
}
|
||||
|
||||
int GetTotalBlocksEstimate()
|
||||
{
|
||||
if (!fEnabled)
|
||||
return 0;
|
||||
|
||||
const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
|
||||
|
||||
return checkpoints.rbegin()->first;
|
||||
}
|
||||
|
||||
CBlockIndex* GetLastCheckpoint()
|
||||
{
|
||||
if (!fEnabled)
|
||||
return NULL;
|
||||
|
||||
const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
|
||||
|
||||
BOOST_REVERSE_FOREACH (const MapCheckpoints::value_type& i, checkpoints) {
|
||||
const uint256& hash = i.second;
|
||||
BlockMap::const_iterator t = mapBlockIndex.find(hash);
|
||||
if (t != mapBlockIndex.end())
|
||||
return t->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace Checkpoints
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CHECKPOINTS_H
|
||||
#define BITCOIN_CHECKPOINTS_H
|
||||
|
||||
#include "uint256.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class CBlockIndex;
|
||||
|
||||
/**
|
||||
* Block-chain checkpoints are compiled-in sanity checks.
|
||||
* They are updated every release or three.
|
||||
*/
|
||||
namespace Checkpoints
|
||||
{
|
||||
typedef std::map<int, uint256> MapCheckpoints;
|
||||
|
||||
struct CCheckpointData {
|
||||
const MapCheckpoints* mapCheckpoints;
|
||||
int64_t nTimeLastCheckpoint;
|
||||
int64_t nTransactionsLastCheckpoint;
|
||||
double fTransactionsPerDay;
|
||||
};
|
||||
|
||||
//! Returns true if block passes checkpoint checks
|
||||
bool CheckBlock(int nHeight, const uint256& hash, bool fMatchesCheckpoint = false);
|
||||
|
||||
//! Return conservative estimate of total number of blocks, 0 if unknown
|
||||
int GetTotalBlocksEstimate();
|
||||
|
||||
//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
|
||||
CBlockIndex* GetLastCheckpoint();
|
||||
|
||||
double GuessVerificationProgress(CBlockIndex* pindex, bool fSigchecks = true);
|
||||
|
||||
extern bool fEnabled;
|
||||
|
||||
} //namespace Checkpoints
|
||||
|
||||
#endif // BITCOIN_CHECKPOINTS_H
|
||||
@@ -0,0 +1,213 @@
|
||||
// Copyright (c) 2012-2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CHECKQUEUE_H
|
||||
#define BITCOIN_CHECKQUEUE_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
template <typename T>
|
||||
class CCheckQueueControl;
|
||||
|
||||
/**
|
||||
* Queue for verifications that have to be performed.
|
||||
* The verifications are represented by a type T, which must provide an
|
||||
* operator(), returning a bool.
|
||||
*
|
||||
* One thread (the master) is assumed to push batches of verifications
|
||||
* onto the queue, where they are processed by N-1 worker threads. When
|
||||
* the master is done adding work, it temporarily joins the worker pool
|
||||
* as an N'th worker, until all jobs are done.
|
||||
*/
|
||||
template <typename T>
|
||||
class CCheckQueue
|
||||
{
|
||||
private:
|
||||
//! Mutex to protect the inner state
|
||||
boost::mutex mutex;
|
||||
|
||||
//! Worker threads block on this when out of work
|
||||
boost::condition_variable condWorker;
|
||||
|
||||
//! Master thread blocks on this when out of work
|
||||
boost::condition_variable condMaster;
|
||||
|
||||
//! The queue of elements to be processed.
|
||||
//! As the order of booleans doesn't matter, it is used as a LIFO (stack)
|
||||
std::vector<T> queue;
|
||||
|
||||
//! The number of workers (including the master) that are idle.
|
||||
int nIdle;
|
||||
|
||||
//! The total number of workers (including the master).
|
||||
int nTotal;
|
||||
|
||||
//! The temporary evaluation result.
|
||||
bool fAllOk;
|
||||
|
||||
/**
|
||||
* Number of verifications that haven't completed yet.
|
||||
* This includes elements that are not anymore in queue, but still in
|
||||
* worker's own batches.
|
||||
*/
|
||||
unsigned int nTodo;
|
||||
|
||||
//! Whether we're shutting down.
|
||||
bool fQuit;
|
||||
|
||||
//! The maximum number of elements to be processed in one batch
|
||||
unsigned int nBatchSize;
|
||||
|
||||
/** Internal function that does bulk of the verification work. */
|
||||
bool Loop(bool fMaster = false)
|
||||
{
|
||||
boost::condition_variable& cond = fMaster ? condMaster : condWorker;
|
||||
std::vector<T> vChecks;
|
||||
vChecks.reserve(nBatchSize);
|
||||
unsigned int nNow = 0;
|
||||
bool fOk = true;
|
||||
do {
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mutex);
|
||||
// first do the clean-up of the previous loop run (allowing us to do it in the same critsect)
|
||||
if (nNow) {
|
||||
fAllOk &= fOk;
|
||||
nTodo -= nNow;
|
||||
if (nTodo == 0 && !fMaster)
|
||||
// We processed the last element; inform the master he can exit and return the result
|
||||
condMaster.notify_one();
|
||||
} else {
|
||||
// first iteration
|
||||
nTotal++;
|
||||
}
|
||||
// logically, the do loop starts here
|
||||
while (queue.empty()) {
|
||||
if ((fMaster || fQuit) && nTodo == 0) {
|
||||
nTotal--;
|
||||
bool fRet = fAllOk;
|
||||
// reset the status for new work later
|
||||
if (fMaster)
|
||||
fAllOk = true;
|
||||
// return the current status
|
||||
return fRet;
|
||||
}
|
||||
nIdle++;
|
||||
cond.wait(lock); // wait
|
||||
nIdle--;
|
||||
}
|
||||
// Decide how many work units to process now.
|
||||
// * Do not try to do everything at once, but aim for increasingly smaller batches so
|
||||
// all workers finish approximately simultaneously.
|
||||
// * Try to account for idle jobs which will instantly start helping.
|
||||
// * Don't do batches smaller than 1 (duh), or larger than nBatchSize.
|
||||
nNow = std::max(1U, std::min(nBatchSize, (unsigned int)queue.size() / (nTotal + nIdle + 1)));
|
||||
vChecks.resize(nNow);
|
||||
for (unsigned int i = 0; i < nNow; i++) {
|
||||
// We want the lock on the mutex to be as short as possible, so swap jobs from the global
|
||||
// queue to the local batch vector instead of copying.
|
||||
vChecks[i].swap(queue.back());
|
||||
queue.pop_back();
|
||||
}
|
||||
// Check whether we need to do work at all
|
||||
fOk = fAllOk;
|
||||
}
|
||||
// execute work
|
||||
for (T& check : vChecks)
|
||||
if (fOk)
|
||||
fOk = check();
|
||||
vChecks.clear();
|
||||
} while (true);
|
||||
}
|
||||
|
||||
public:
|
||||
//! Create a new check queue
|
||||
CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {}
|
||||
|
||||
//! Worker thread
|
||||
void Thread()
|
||||
{
|
||||
Loop();
|
||||
}
|
||||
|
||||
//! Wait until execution finishes, and return whether all evaluations where successful.
|
||||
bool Wait()
|
||||
{
|
||||
return Loop(true);
|
||||
}
|
||||
|
||||
//! Add a batch of checks to the queue
|
||||
void Add(std::vector<T>& vChecks)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mutex);
|
||||
for (T& check : vChecks) {
|
||||
queue.push_back(T());
|
||||
check.swap(queue.back());
|
||||
}
|
||||
nTodo += vChecks.size();
|
||||
if (vChecks.size() == 1)
|
||||
condWorker.notify_one();
|
||||
else if (vChecks.size() > 1)
|
||||
condWorker.notify_all();
|
||||
}
|
||||
|
||||
~CCheckQueue()
|
||||
{
|
||||
}
|
||||
|
||||
bool IsIdle()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mutex);
|
||||
return (nTotal == nIdle && nTodo == 0 && fAllOk == true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* RAII-style controller object for a CCheckQueue that guarantees the passed
|
||||
* queue is finished before continuing.
|
||||
*/
|
||||
template <typename T>
|
||||
class CCheckQueueControl
|
||||
{
|
||||
private:
|
||||
CCheckQueue<T>* pqueue;
|
||||
bool fDone;
|
||||
|
||||
public:
|
||||
CCheckQueueControl(CCheckQueue<T>* pqueueIn) : pqueue(pqueueIn), fDone(false)
|
||||
{
|
||||
// passed queue is supposed to be unused, or NULL
|
||||
if (pqueue != NULL) {
|
||||
bool isIdle = pqueue->IsIdle();
|
||||
assert(isIdle);
|
||||
}
|
||||
}
|
||||
|
||||
bool Wait()
|
||||
{
|
||||
if (pqueue == NULL)
|
||||
return true;
|
||||
bool fRet = pqueue->Wait();
|
||||
fDone = true;
|
||||
return fRet;
|
||||
}
|
||||
|
||||
void Add(std::vector<T>& vChecks)
|
||||
{
|
||||
if (pqueue != NULL)
|
||||
pqueue->Add(vChecks);
|
||||
}
|
||||
|
||||
~CCheckQueueControl()
|
||||
{
|
||||
if (!fDone)
|
||||
Wait();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BITCOIN_CHECKQUEUE_H
|
||||
@@ -0,0 +1,112 @@
|
||||
// Copyright (c) 2012-2017 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "clientversion.h"
|
||||
|
||||
#include "tinyformat.h"
|
||||
|
||||
|
||||
/**
|
||||
* Name of client reported in the 'version' message. Report the same name
|
||||
* for both agrariand and agrarian-qt, to make it harder for attackers to
|
||||
* target servers or GUI users specifically.
|
||||
*/
|
||||
const std::string CLIENT_NAME("Agrarian Core");
|
||||
|
||||
/**
|
||||
* Client version number
|
||||
*/
|
||||
#define CLIENT_VERSION_SUFFIX ""
|
||||
|
||||
|
||||
/**
|
||||
* The following part of the code determines the CLIENT_BUILD variable.
|
||||
* Several mechanisms are used for this:
|
||||
* * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
|
||||
* generated by the build environment, possibly containing the output
|
||||
* of git-describe in a macro called BUILD_DESC
|
||||
* * secondly, if this is an exported version of the code, GIT_ARCHIVE will
|
||||
* be defined (automatically using the export-subst git attribute), and
|
||||
* GIT_COMMIT will contain the commit id.
|
||||
* * then, three options exist for determining CLIENT_BUILD:
|
||||
* * if BUILD_DESC is defined, use that literally (output of git-describe)
|
||||
* * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
|
||||
* * otherwise, use v[maj].[min].[rev].[build]-unk
|
||||
* finally CLIENT_VERSION_SUFFIX is added
|
||||
*/
|
||||
|
||||
//! First, include build.h if requested
|
||||
#ifdef HAVE_BUILD_INFO
|
||||
#include "obj/build.h"
|
||||
#endif
|
||||
|
||||
//! git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
|
||||
#define GIT_ARCHIVE 1
|
||||
#ifdef GIT_ARCHIVE
|
||||
#define GIT_COMMIT_ID ""
|
||||
#define GIT_COMMIT_DATE ""
|
||||
#endif
|
||||
|
||||
#define BUILD_DESC_WITH_SUFFIX(maj, min, rev, build, suffix) \
|
||||
"v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-" DO_STRINGIZE(suffix)
|
||||
|
||||
#define BUILD_DESC_FROM_COMMIT(maj, min, rev, build, commit) \
|
||||
"v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit
|
||||
|
||||
#define BUILD_DESC_FROM_UNKNOWN(maj, min, rev, build) \
|
||||
"v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"
|
||||
|
||||
#ifndef BUILD_DESC
|
||||
#ifdef BUILD_SUFFIX
|
||||
#define BUILD_DESC BUILD_DESC_WITH_SUFFIX(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, BUILD_SUFFIX)
|
||||
#elif defined(GIT_COMMIT_ID)
|
||||
#define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
|
||||
#else
|
||||
#define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BUILD_DATE
|
||||
#ifdef GIT_COMMIT_DATE
|
||||
#define BUILD_DATE GIT_COMMIT_DATE
|
||||
#else
|
||||
#define BUILD_DATE __DATE__ ", " __TIME__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
|
||||
const std::string CLIENT_DATE(BUILD_DATE);
|
||||
|
||||
static std::string FormatVersion(int nVersion)
|
||||
{
|
||||
if (nVersion % 100 == 0)
|
||||
return strprintf("%d.%d.%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100);
|
||||
else
|
||||
return strprintf("%d.%d.%d.%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100, nVersion % 100);
|
||||
}
|
||||
|
||||
std::string FormatFullVersion()
|
||||
{
|
||||
return CLIENT_BUILD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki)
|
||||
*/
|
||||
std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "/";
|
||||
ss << name << ":" << FormatVersion(nClientVersion);
|
||||
if (!comments.empty()) {
|
||||
std::vector<std::string>::const_iterator it(comments.begin());
|
||||
ss << "(" << *it;
|
||||
for (++it; it != comments.end(); ++it)
|
||||
ss << "; " << *it;
|
||||
ss << ")";
|
||||
}
|
||||
ss << "/";
|
||||
return ss.str();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2009-2017 The Bitcoin Core developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CLIENTVERSION_H
|
||||
#define BITCOIN_CLIENTVERSION_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/agrarian-config.h"
|
||||
#endif //HAVE_CONFIG_H
|
||||
|
||||
// Check that required client information is defined
|
||||
#if !defined(CLIENT_VERSION_MAJOR) || !defined(CLIENT_VERSION_MINOR) || !defined(CLIENT_VERSION_REVISION) || !defined(CLIENT_VERSION_BUILD) || !defined(CLIENT_VERSION_IS_RELEASE) || !defined(COPYRIGHT_YEAR)
|
||||
#error Client version information missing: version is not defined by agrarian-config.h or in any other way
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Converts the parameter X to a string after macro replacement on X has been performed.
|
||||
* Don't merge these into one macro!
|
||||
*/
|
||||
#define STRINGIZE(X) DO_STRINGIZE(X)
|
||||
#define DO_STRINGIZE(X) #X
|
||||
|
||||
//! Copyright string used in Windows .rc files
|
||||
#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers, 2014-" STRINGIZE(COPYRIGHT_YEAR) " The Dash Core Developers, 2015-" STRINGIZE(COPYRIGHT_YEAR) " The Agrarian Core Developers"
|
||||
|
||||
/**
|
||||
* agrariand-res.rc includes this file, but it cannot cope with real c++ code.
|
||||
* WINDRES_PREPROC is defined to indicate that its pre-processor is running.
|
||||
* Anything other than a define should be guarded below.
|
||||
*/
|
||||
|
||||
#if !defined(WINDRES_PREPROC)
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
static const int CLIENT_VERSION =
|
||||
1000000 * CLIENT_VERSION_MAJOR ///
|
||||
+ 10000 * CLIENT_VERSION_MINOR ///
|
||||
+ 100 * CLIENT_VERSION_REVISION ///
|
||||
+ 1 * CLIENT_VERSION_BUILD;
|
||||
|
||||
extern const std::string CLIENT_NAME;
|
||||
extern const std::string CLIENT_BUILD;
|
||||
extern const std::string CLIENT_DATE;
|
||||
|
||||
|
||||
std::string FormatFullVersion();
|
||||
std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
|
||||
|
||||
#endif // WINDRES_PREPROC
|
||||
|
||||
#endif // BITCOIN_CLIENTVERSION_H
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) 2011-2013 The Bitcoin developers
|
||||
// Copyright (c) 2014-2016 The Dash developers
|
||||
// Copyright (c) 2015-2017 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_COINCONTROL_H
|
||||
#define BITCOIN_COINCONTROL_H
|
||||
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/standard.h"
|
||||
|
||||
/** Coin Control Features. */
|
||||
class CCoinControl
|
||||
{
|
||||
public:
|
||||
CTxDestination destChange;
|
||||
bool useObfuScation;
|
||||
bool useSwiftTX;
|
||||
bool fSplitBlock;
|
||||
int nSplitBlock;
|
||||
//! If false, allows unselected inputs, but requires all selected inputs be used
|
||||
bool fAllowOtherInputs;
|
||||
//! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria
|
||||
bool fAllowWatchOnly;
|
||||
//! Minimum absolute fee (not per kilobyte)
|
||||
CAmount nMinimumTotalFee;
|
||||
|
||||
CCoinControl()
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
destChange = CNoDestination();
|
||||
setSelected.clear();
|
||||
useSwiftTX = false;
|
||||
useObfuScation = false;
|
||||
fAllowOtherInputs = false;
|
||||
fAllowWatchOnly = true;
|
||||
nMinimumTotalFee = 0;
|
||||
fSplitBlock = false;
|
||||
nSplitBlock = 1;
|
||||
}
|
||||
|
||||
bool HasSelected() const
|
||||
{
|
||||
return (setSelected.size() > 0);
|
||||
}
|
||||
|
||||
bool IsSelected(const uint256& hash, unsigned int n) const
|
||||
{
|
||||
COutPoint outpt(hash, n);
|
||||
return (setSelected.count(outpt) > 0);
|
||||
}
|
||||
|
||||
void Select(const COutPoint& output)
|
||||
{
|
||||
setSelected.insert(output);
|
||||
}
|
||||
|
||||
void UnSelect(const COutPoint& output)
|
||||
{
|
||||
setSelected.erase(output);
|
||||
}
|
||||
|
||||
void UnSelectAll()
|
||||
{
|
||||
setSelected.clear();
|
||||
}
|
||||
|
||||
void ListSelected(std::vector<COutPoint>& vOutpoints)
|
||||
{
|
||||
vOutpoints.assign(setSelected.begin(), setSelected.end());
|
||||
}
|
||||
|
||||
unsigned int QuantitySelected()
|
||||
{
|
||||
return setSelected.size();
|
||||
}
|
||||
|
||||
void SetSelection(std::set<COutPoint> setSelected)
|
||||
{
|
||||
this->setSelected.clear();
|
||||
this->setSelected = setSelected;
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<COutPoint> setSelected;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_COINCONTROL_H
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
// Copyright (c) 2012-2014 The Bitcoin developers
|
||||
// Copyright (c) 2015-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "coins.h"
|
||||
|
||||
#include "random.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* calculate number of bytes for the bitmask, and its number of non-zero bytes
|
||||
* each bit in the bitmask represents the availability of one output, but the
|
||||
* availabilities of the first two outputs are encoded separately
|
||||
*/
|
||||
void CCoins::CalcMaskSize(unsigned int& nBytes, unsigned int& nNonzeroBytes) const
|
||||
{
|
||||
unsigned int nLastUsedByte = 0;
|
||||
for (unsigned int b = 0; 2 + b * 8 < vout.size(); b++) {
|
||||
bool fZero = true;
|
||||
for (unsigned int i = 0; i < 8 && 2 + b * 8 + i < vout.size(); i++) {
|
||||
if (!vout[2 + b * 8 + i].IsNull()) {
|
||||
fZero = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!fZero) {
|
||||
nLastUsedByte = b + 1;
|
||||
nNonzeroBytes++;
|
||||
}
|
||||
}
|
||||
nBytes += nLastUsedByte;
|
||||
}
|
||||
|
||||
bool CCoins::Spend(const COutPoint& out, CTxInUndo& undo)
|
||||
{
|
||||
if (out.n >= vout.size())
|
||||
return false;
|
||||
if (vout[out.n].IsNull())
|
||||
return false;
|
||||
undo = CTxInUndo(vout[out.n]);
|
||||
vout[out.n].SetNull();
|
||||
Cleanup();
|
||||
if (vout.size() == 0) {
|
||||
undo.nHeight = nHeight;
|
||||
undo.fCoinBase = fCoinBase;
|
||||
undo.fCoinStake = fCoinStake;
|
||||
undo.nVersion = this->nVersion;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoins::Spend(int nPos)
|
||||
{
|
||||
CTxInUndo undo;
|
||||
COutPoint out(0, nPos);
|
||||
return Spend(out, undo);
|
||||
}
|
||||
|
||||
|
||||
bool CCoinsView::GetCoins(const uint256& txid, CCoins& coins) const { return false; }
|
||||
bool CCoinsView::HaveCoins(const uint256& txid) const { return false; }
|
||||
uint256 CCoinsView::GetBestBlock() const { return uint256(0); }
|
||||
bool CCoinsView::BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock) { return false; }
|
||||
bool CCoinsView::GetStats(CCoinsStats& stats) const { return false; }
|
||||
|
||||
|
||||
CCoinsViewBacked::CCoinsViewBacked(CCoinsView* viewIn) : base(viewIn) {}
|
||||
bool CCoinsViewBacked::GetCoins(const uint256& txid, CCoins& coins) const { return base->GetCoins(txid, coins); }
|
||||
bool CCoinsViewBacked::HaveCoins(const uint256& txid) const { return base->HaveCoins(txid); }
|
||||
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
|
||||
void CCoinsViewBacked::SetBackend(CCoinsView& viewIn) { base = &viewIn; }
|
||||
bool CCoinsViewBacked::BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
|
||||
bool CCoinsViewBacked::GetStats(CCoinsStats& stats) const { return base->GetStats(stats); }
|
||||
|
||||
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
|
||||
|
||||
CCoinsViewCache::CCoinsViewCache(CCoinsView* baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), hashBlock(0) {}
|
||||
|
||||
CCoinsViewCache::~CCoinsViewCache()
|
||||
{
|
||||
assert(!hasModifier);
|
||||
}
|
||||
|
||||
CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256& txid) const
|
||||
{
|
||||
CCoinsMap::iterator it = cacheCoins.find(txid);
|
||||
if (it != cacheCoins.end())
|
||||
return it;
|
||||
CCoins tmp;
|
||||
if (!base->GetCoins(txid, tmp))
|
||||
return cacheCoins.end();
|
||||
CCoinsMap::iterator ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())).first;
|
||||
tmp.swap(ret->second.coins);
|
||||
if (ret->second.coins.IsPruned()) {
|
||||
// The parent only has an empty entry for this txid; we can consider our
|
||||
// version as fresh.
|
||||
ret->second.flags = CCoinsCacheEntry::FRESH;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::GetCoins(const uint256& txid, CCoins& coins) const
|
||||
{
|
||||
CCoinsMap::const_iterator it = FetchCoins(txid);
|
||||
if (it != cacheCoins.end()) {
|
||||
coins = it->second.coins;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256& txid)
|
||||
{
|
||||
assert(!hasModifier);
|
||||
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
|
||||
if (ret.second) {
|
||||
if (!base->GetCoins(txid, ret.first->second.coins)) {
|
||||
// The parent view does not have this entry; mark it as fresh.
|
||||
ret.first->second.coins.Clear();
|
||||
ret.first->second.flags = CCoinsCacheEntry::FRESH;
|
||||
} else if (ret.first->second.coins.IsPruned()) {
|
||||
// The parent view only has a pruned entry for this; mark it as fresh.
|
||||
ret.first->second.flags = CCoinsCacheEntry::FRESH;
|
||||
}
|
||||
}
|
||||
// Assume that whenever ModifyCoins is called, the entry will be modified.
|
||||
ret.first->second.flags |= CCoinsCacheEntry::DIRTY;
|
||||
return CCoinsModifier(*this, ret.first);
|
||||
}
|
||||
|
||||
const CCoins* CCoinsViewCache::AccessCoins(const uint256& txid) const
|
||||
{
|
||||
CCoinsMap::const_iterator it = FetchCoins(txid);
|
||||
if (it == cacheCoins.end()) {
|
||||
return NULL;
|
||||
} else {
|
||||
return &it->second.coins;
|
||||
}
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::HaveCoins(const uint256& txid) const
|
||||
{
|
||||
CCoinsMap::const_iterator it = FetchCoins(txid);
|
||||
// We're using vtx.empty() instead of IsPruned here for performance reasons,
|
||||
// as we only care about the case where a transaction was replaced entirely
|
||||
// in a reorganization (which wipes vout entirely, as opposed to spending
|
||||
// which just cleans individual outputs).
|
||||
return (it != cacheCoins.end() && !it->second.coins.vout.empty());
|
||||
}
|
||||
|
||||
uint256 CCoinsViewCache::GetBestBlock() const
|
||||
{
|
||||
if (hashBlock == uint256(0))
|
||||
hashBlock = base->GetBestBlock();
|
||||
return hashBlock;
|
||||
}
|
||||
|
||||
void CCoinsViewCache::SetBestBlock(const uint256& hashBlockIn)
|
||||
{
|
||||
hashBlock = hashBlockIn;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlockIn)
|
||||
{
|
||||
assert(!hasModifier);
|
||||
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
|
||||
if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
|
||||
CCoinsMap::iterator itUs = cacheCoins.find(it->first);
|
||||
if (itUs == cacheCoins.end()) {
|
||||
if (!it->second.coins.IsPruned()) {
|
||||
// The parent cache does not have an entry, while the child
|
||||
// cache does have (a non-pruned) one. Move the data up, and
|
||||
// mark it as fresh (if the grandparent did have it, we
|
||||
// would have pulled it in at first GetCoins).
|
||||
assert(it->second.flags & CCoinsCacheEntry::FRESH);
|
||||
CCoinsCacheEntry& entry = cacheCoins[it->first];
|
||||
entry.coins.swap(it->second.coins);
|
||||
entry.flags = CCoinsCacheEntry::DIRTY | CCoinsCacheEntry::FRESH;
|
||||
}
|
||||
} else {
|
||||
if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) {
|
||||
// The grandparent does not have an entry, and the child is
|
||||
// modified and being pruned. This means we can just delete
|
||||
// it from the parent.
|
||||
cacheCoins.erase(itUs);
|
||||
} else {
|
||||
// A normal modification.
|
||||
itUs->second.coins.swap(it->second.coins);
|
||||
itUs->second.flags |= CCoinsCacheEntry::DIRTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
CCoinsMap::iterator itOld = it++;
|
||||
mapCoins.erase(itOld);
|
||||
}
|
||||
hashBlock = hashBlockIn;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::Flush()
|
||||
{
|
||||
bool fOk = base->BatchWrite(cacheCoins, hashBlock);
|
||||
cacheCoins.clear();
|
||||
return fOk;
|
||||
}
|
||||
|
||||
unsigned int CCoinsViewCache::GetCacheSize() const
|
||||
{
|
||||
return cacheCoins.size();
|
||||
}
|
||||
|
||||
const CTxOut& CCoinsViewCache::GetOutputFor(const CTxIn& input) const
|
||||
{
|
||||
const CCoins* coins = AccessCoins(input.prevout.hash);
|
||||
assert(coins && coins->IsAvailable(input.prevout.n));
|
||||
return coins->vout[input.prevout.n];
|
||||
}
|
||||
|
||||
CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const
|
||||
{
|
||||
if (tx.IsCoinBase())
|
||||
return 0;
|
||||
|
||||
//todo are there any security precautions to take here?
|
||||
if (tx.HasZerocoinSpendInputs())
|
||||
return tx.GetZerocoinSpent();
|
||||
|
||||
CAmount nResult = 0;
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
||||
nResult += GetOutputFor(tx.vin[i]).nValue;
|
||||
|
||||
return nResult;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
|
||||
{
|
||||
if (!tx.IsCoinBase() && !tx.HasZerocoinSpendInputs()) {
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
||||
const COutPoint& prevout = tx.vin[i].prevout;
|
||||
const CCoins* coins = AccessCoins(prevout.hash);
|
||||
if (!coins || !coins->IsAvailable(prevout.n)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
double CCoinsViewCache::GetPriority(const CTransaction& tx, int nHeight) const
|
||||
{
|
||||
if (tx.IsCoinBase() || tx.IsCoinStake())
|
||||
return 0.0;
|
||||
double dResult = 0.0;
|
||||
for (const CTxIn& txin: tx.vin) {
|
||||
const CCoins* coins = AccessCoins(txin.prevout.hash);
|
||||
assert(coins);
|
||||
if (!coins->IsAvailable(txin.prevout.n)) continue;
|
||||
if (coins->nHeight < nHeight) {
|
||||
dResult += coins->vout[txin.prevout.n].nValue * (nHeight - coins->nHeight);
|
||||
}
|
||||
}
|
||||
return tx.ComputePriority(dResult);
|
||||
}
|
||||
|
||||
CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_)
|
||||
{
|
||||
assert(!cache.hasModifier);
|
||||
cache.hasModifier = true;
|
||||
}
|
||||
|
||||
CCoinsModifier::~CCoinsModifier()
|
||||
{
|
||||
assert(cache.hasModifier);
|
||||
cache.hasModifier = false;
|
||||
it->second.coins.Cleanup();
|
||||
if ((it->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) {
|
||||
cache.cacheCoins.erase(it);
|
||||
}
|
||||
}
|
||||
+484
@@ -0,0 +1,484 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2016-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_COINS_H
|
||||
#define BITCOIN_COINS_H
|
||||
|
||||
#include "compressor.h"
|
||||
#include "script/standard.h"
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
#include "undo.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
/**
|
||||
|
||||
****Note - for Agrarian we added fCoinStake to the 2nd bit. Keep in mind when reading the following and adjust as needed.
|
||||
* Pruned version of CTransaction: only retains metadata and unspent transaction outputs
|
||||
*
|
||||
* Serialized format:
|
||||
* - VARINT(nVersion)
|
||||
* - VARINT(nCode)
|
||||
* - unspentness bitvector, for vout[2] and further; least significant byte first
|
||||
* - the non-spent CTxOuts (via CTxOutCompressor)
|
||||
* - VARINT(nHeight)
|
||||
*
|
||||
* The nCode value consists of:
|
||||
* - bit 1: IsCoinBase()
|
||||
* - bit 2: vout[0] is not spent
|
||||
* - bit 4: vout[1] is not spent
|
||||
* - The higher bits encode N, the number of non-zero bytes in the following bitvector.
|
||||
* - In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at
|
||||
* least one non-spent output).
|
||||
*
|
||||
* Example: 0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e
|
||||
* <><><--------------------------------------------><---->
|
||||
* | \ | /
|
||||
* version code vout[1] height
|
||||
*
|
||||
* - version = 1
|
||||
* - code = 4 (vout[1] is not spent, and 0 non-zero bytes of bitvector follow)
|
||||
* - unspentness bitvector: as 0 non-zero bytes follow, it has length 0
|
||||
* - vout[1]: 835800816115944e077fe7c803cfa57f29b36bf87c1d35
|
||||
* * 8358: compact amount representation for 60000000000 (600 BTC)
|
||||
* * 00: special txout type pay-to-pubkey-hash
|
||||
* * 816115944e077fe7c803cfa57f29b36bf87c1d35: address uint160
|
||||
* - height = 203998
|
||||
*
|
||||
*
|
||||
* Example: 0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b
|
||||
* <><><--><--------------------------------------------------><----------------------------------------------><---->
|
||||
* / \ \ | | /
|
||||
* version code unspentness vout[4] vout[16] height
|
||||
*
|
||||
* - version = 1
|
||||
* - code = 9 (coinbase, neither vout[0] or vout[1] are unspent, 2 (1, +1 because both bit 2 and bit 4 are unset) non-zero bitvector bytes follow)
|
||||
* - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent
|
||||
* - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee
|
||||
* * 86ef97d579: compact amount representation for 234925952 (2.35 BTC)
|
||||
* * 00: special txout type pay-to-pubkey-hash
|
||||
* * 61b01caab50f1b8e9c50a5057eb43c2d9563a4ee: address uint160
|
||||
* - vout[16]: bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4
|
||||
* * bbd123: compact amount representation for 110397 (0.001 BTC)
|
||||
* * 00: special txout type pay-to-pubkey-hash
|
||||
* * 8c988f1a4a4de2161e0f50aac7f17e7f9555caa4: address uint160
|
||||
* - height = 120891
|
||||
*/
|
||||
class CCoins
|
||||
{
|
||||
public:
|
||||
//! whether transaction is a coinbase
|
||||
bool fCoinBase;
|
||||
bool fCoinStake;
|
||||
|
||||
//! unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped
|
||||
std::vector<CTxOut> vout;
|
||||
|
||||
//! at which height this transaction was included in the active block chain
|
||||
int nHeight;
|
||||
|
||||
//! version of the CTransaction; accesses to this value should probably check for nHeight as well,
|
||||
//! as new tx version will probably only be introduced at certain heights
|
||||
int nVersion;
|
||||
|
||||
void FromTx(const CTransaction& tx, int nHeightIn)
|
||||
{
|
||||
fCoinBase = tx.IsCoinBase();
|
||||
fCoinStake = tx.IsCoinStake();
|
||||
vout = tx.vout;
|
||||
nHeight = nHeightIn;
|
||||
nVersion = tx.nVersion;
|
||||
ClearUnspendable();
|
||||
}
|
||||
|
||||
//! construct a CCoins from a CTransaction, at a given height
|
||||
CCoins(const CTransaction& tx, int nHeightIn)
|
||||
{
|
||||
FromTx(tx, nHeightIn);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
fCoinBase = false;
|
||||
fCoinStake = false;
|
||||
std::vector<CTxOut>().swap(vout);
|
||||
nHeight = 0;
|
||||
nVersion = 0;
|
||||
}
|
||||
|
||||
//! empty constructor
|
||||
CCoins() : fCoinBase(false), fCoinStake(false), vout(0), nHeight(0), nVersion(0) {}
|
||||
|
||||
//!remove spent outputs at the end of vout
|
||||
void Cleanup()
|
||||
{
|
||||
while (vout.size() > 0 && vout.back().IsNull())
|
||||
vout.pop_back();
|
||||
if (vout.empty())
|
||||
std::vector<CTxOut>().swap(vout);
|
||||
}
|
||||
|
||||
void ClearUnspendable()
|
||||
{
|
||||
for (CTxOut& txout : vout) {
|
||||
if (txout.scriptPubKey.IsUnspendable())
|
||||
txout.SetNull();
|
||||
}
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
void swap(CCoins& to)
|
||||
{
|
||||
std::swap(to.fCoinBase, fCoinBase);
|
||||
std::swap(to.fCoinStake, fCoinStake);
|
||||
to.vout.swap(vout);
|
||||
std::swap(to.nHeight, nHeight);
|
||||
std::swap(to.nVersion, nVersion);
|
||||
}
|
||||
|
||||
//! equality test
|
||||
friend bool operator==(const CCoins& a, const CCoins& b)
|
||||
{
|
||||
// Empty CCoins objects are always equal.
|
||||
if (a.IsPruned() && b.IsPruned())
|
||||
return true;
|
||||
return a.fCoinBase == b.fCoinBase &&
|
||||
a.fCoinStake == b.fCoinStake &&
|
||||
a.nHeight == b.nHeight &&
|
||||
a.nVersion == b.nVersion &&
|
||||
a.vout == b.vout;
|
||||
}
|
||||
friend bool operator!=(const CCoins& a, const CCoins& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
void CalcMaskSize(unsigned int& nBytes, unsigned int& nNonzeroBytes) const;
|
||||
|
||||
bool IsCoinBase() const
|
||||
{
|
||||
return fCoinBase;
|
||||
}
|
||||
|
||||
bool IsCoinStake() const
|
||||
{
|
||||
return fCoinStake;
|
||||
}
|
||||
|
||||
unsigned int GetSerializeSize(int nType, int nVersion) const
|
||||
{
|
||||
unsigned int nSize = 0;
|
||||
unsigned int nMaskSize = 0, nMaskCode = 0;
|
||||
CalcMaskSize(nMaskSize, nMaskCode);
|
||||
bool fFirst = vout.size() > 0 && !vout[0].IsNull();
|
||||
bool fSecond = vout.size() > 1 && !vout[1].IsNull();
|
||||
assert(fFirst || fSecond || nMaskCode);
|
||||
unsigned int nCode = 8 * (nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fCoinStake ? 2 : 0) + (fFirst ? 4 : 0) + (fSecond ? 8 : 0);
|
||||
// version
|
||||
nSize += ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion);
|
||||
// size of header code
|
||||
nSize += ::GetSerializeSize(VARINT(nCode), nType, nVersion);
|
||||
// spentness bitmask
|
||||
nSize += nMaskSize;
|
||||
// txouts themself
|
||||
for (unsigned int i = 0; i < vout.size(); i++)
|
||||
if (!vout[i].IsNull())
|
||||
nSize += ::GetSerializeSize(CTxOutCompressor(REF(vout[i])), nType, nVersion);
|
||||
// height
|
||||
nSize += ::GetSerializeSize(VARINT(nHeight), nType, nVersion);
|
||||
return nSize;
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
void Serialize(Stream& s, int nType, int nVersion) const
|
||||
{
|
||||
unsigned int nMaskSize = 0, nMaskCode = 0;
|
||||
CalcMaskSize(nMaskSize, nMaskCode);
|
||||
bool fFirst = vout.size() > 0 && !vout[0].IsNull();
|
||||
bool fSecond = vout.size() > 1 && !vout[1].IsNull();
|
||||
assert(fFirst || fSecond || nMaskCode);
|
||||
unsigned int nCode = 16 * (nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fCoinStake ? 2 : 0) + (fFirst ? 4 : 0) + (fSecond ? 8 : 0);
|
||||
// version
|
||||
::Serialize(s, VARINT(this->nVersion), nType, nVersion);
|
||||
// header code
|
||||
::Serialize(s, VARINT(nCode), nType, nVersion);
|
||||
// spentness bitmask
|
||||
for (unsigned int b = 0; b < nMaskSize; b++) {
|
||||
unsigned char chAvail = 0;
|
||||
for (unsigned int i = 0; i < 8 && 2 + b * 8 + i < vout.size(); i++)
|
||||
if (!vout[2 + b * 8 + i].IsNull())
|
||||
chAvail |= (1 << i);
|
||||
::Serialize(s, chAvail, nType, nVersion);
|
||||
}
|
||||
// txouts themself
|
||||
for (unsigned int i = 0; i < vout.size(); i++) {
|
||||
if (!vout[i].IsNull())
|
||||
::Serialize(s, CTxOutCompressor(REF(vout[i])), nType, nVersion);
|
||||
}
|
||||
// coinbase height
|
||||
::Serialize(s, VARINT(nHeight), nType, nVersion);
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s, int nType, int nVersion)
|
||||
{
|
||||
unsigned int nCode = 0;
|
||||
// version
|
||||
::Unserialize(s, VARINT(this->nVersion), nType, nVersion);
|
||||
// header code
|
||||
::Unserialize(s, VARINT(nCode), nType, nVersion);
|
||||
fCoinBase = nCode & 1; //0001 - means coinbase
|
||||
fCoinStake = (nCode & 2) != 0; //0010 coinstake
|
||||
std::vector<bool> vAvail(2, false);
|
||||
vAvail[0] = (nCode & 4) != 0; // 0100
|
||||
vAvail[1] = (nCode & 8) != 0; // 1000
|
||||
unsigned int nMaskCode = (nCode / 16) + ((nCode & 12) != 0 ? 0 : 1);
|
||||
// spentness bitmask
|
||||
while (nMaskCode > 0) {
|
||||
unsigned char chAvail = 0;
|
||||
::Unserialize(s, chAvail, nType, nVersion);
|
||||
for (unsigned int p = 0; p < 8; p++) {
|
||||
bool f = (chAvail & (1 << p)) != 0;
|
||||
vAvail.push_back(f);
|
||||
}
|
||||
if (chAvail != 0)
|
||||
nMaskCode--;
|
||||
}
|
||||
// txouts themself
|
||||
vout.assign(vAvail.size(), CTxOut());
|
||||
for (unsigned int i = 0; i < vAvail.size(); i++) {
|
||||
if (vAvail[i])
|
||||
::Unserialize(s, REF(CTxOutCompressor(vout[i])), nType, nVersion);
|
||||
}
|
||||
// coinbase height
|
||||
::Unserialize(s, VARINT(nHeight), nType, nVersion);
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
//! mark an outpoint spent, and construct undo information
|
||||
bool Spend(const COutPoint& out, CTxInUndo& undo);
|
||||
|
||||
//! mark a vout spent
|
||||
bool Spend(int nPos);
|
||||
|
||||
//! check whether a particular output is still available
|
||||
bool IsAvailable(unsigned int nPos) const
|
||||
{
|
||||
return (nPos < vout.size() && !vout[nPos].IsNull() && !vout[nPos].IsZerocoinMint());
|
||||
}
|
||||
|
||||
//! check whether the entire CCoins is spent
|
||||
//! note that only !IsPruned() CCoins can be serialized
|
||||
bool IsPruned() const
|
||||
{
|
||||
for (const CTxOut& out : vout)
|
||||
if (!out.IsNull())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CCoinsKeyHasher
|
||||
{
|
||||
private:
|
||||
uint256 salt;
|
||||
|
||||
public:
|
||||
CCoinsKeyHasher();
|
||||
|
||||
/**
|
||||
* This *must* return size_t. With Boost 1.46 on 32-bit systems the
|
||||
* unordered_map will behave unpredictably if the custom hasher returns a
|
||||
* uint64_t, resulting in failures when syncing the chain (#4634).
|
||||
*/
|
||||
size_t operator()(const uint256& key) const
|
||||
{
|
||||
return key.GetHash(salt);
|
||||
}
|
||||
};
|
||||
|
||||
struct CCoinsCacheEntry {
|
||||
CCoins coins; // The actual cached data.
|
||||
unsigned char flags;
|
||||
|
||||
enum Flags {
|
||||
DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
|
||||
FRESH = (1 << 1), // The parent view does not have this entry (or it is pruned).
|
||||
};
|
||||
|
||||
CCoinsCacheEntry() : coins(), flags(0) {}
|
||||
};
|
||||
|
||||
typedef boost::unordered_map<uint256, CCoinsCacheEntry, CCoinsKeyHasher> CCoinsMap;
|
||||
|
||||
struct CCoinsStats {
|
||||
int nHeight;
|
||||
uint256 hashBlock;
|
||||
uint64_t nTransactions;
|
||||
uint64_t nTransactionOutputs;
|
||||
uint64_t nSerializedSize;
|
||||
uint256 hashSerialized;
|
||||
CAmount nTotalAmount;
|
||||
|
||||
CCoinsStats() : nHeight(0), hashBlock(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), hashSerialized(0), nTotalAmount(0) {}
|
||||
};
|
||||
|
||||
|
||||
/** Abstract view on the open txout dataset. */
|
||||
class CCoinsView
|
||||
{
|
||||
public:
|
||||
//! Retrieve the CCoins (unspent transaction outputs) for a given txid
|
||||
virtual bool GetCoins(const uint256& txid, CCoins& coins) const;
|
||||
|
||||
//! Just check whether we have data for a given txid.
|
||||
//! This may (but cannot always) return true for fully spent transactions
|
||||
virtual bool HaveCoins(const uint256& txid) const;
|
||||
|
||||
//! Retrieve the block hash whose state this CCoinsView currently represents
|
||||
virtual uint256 GetBestBlock() const;
|
||||
|
||||
//! Do a bulk modification (multiple CCoins changes + BestBlock change).
|
||||
//! The passed mapCoins can be modified.
|
||||
virtual bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock);
|
||||
|
||||
//! Calculate statistics about the unspent transaction output set
|
||||
virtual bool GetStats(CCoinsStats& stats) const;
|
||||
|
||||
//! As we use CCoinsViews polymorphically, have a virtual destructor
|
||||
virtual ~CCoinsView() {}
|
||||
};
|
||||
|
||||
|
||||
/** CCoinsView backed by another CCoinsView */
|
||||
class CCoinsViewBacked : public CCoinsView
|
||||
{
|
||||
protected:
|
||||
CCoinsView* base;
|
||||
|
||||
public:
|
||||
CCoinsViewBacked(CCoinsView* viewIn);
|
||||
bool GetCoins(const uint256& txid, CCoins& coins) const;
|
||||
bool HaveCoins(const uint256& txid) const;
|
||||
uint256 GetBestBlock() const;
|
||||
void SetBackend(CCoinsView& viewIn);
|
||||
bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock);
|
||||
bool GetStats(CCoinsStats& stats) const;
|
||||
};
|
||||
|
||||
class CCoinsViewCache;
|
||||
|
||||
/** Flags for nSequence and nLockTime locks */
|
||||
enum {
|
||||
/* Interpret sequence numbers as relative lock-time constraints. */
|
||||
LOCKTIME_VERIFY_SEQUENCE = (1 << 0),
|
||||
|
||||
/* Use GetMedianTimePast() instead of nTime for end point timestamp. */
|
||||
LOCKTIME_MEDIAN_TIME_PAST = (1 << 1),
|
||||
};
|
||||
|
||||
/** Used as the flags parameter to sequence and nLocktime checks in non-consensus code. */
|
||||
static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE |
|
||||
LOCKTIME_MEDIAN_TIME_PAST;
|
||||
|
||||
/**
|
||||
* A reference to a mutable cache entry. Encapsulating it allows us to run
|
||||
* cleanup code after the modification is finished, and keeping track of
|
||||
* concurrent modifications.
|
||||
*/
|
||||
class CCoinsModifier
|
||||
{
|
||||
private:
|
||||
CCoinsViewCache& cache;
|
||||
CCoinsMap::iterator it;
|
||||
CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_);
|
||||
|
||||
public:
|
||||
CCoins* operator->() { return &it->second.coins; }
|
||||
CCoins& operator*() { return it->second.coins; }
|
||||
~CCoinsModifier();
|
||||
friend class CCoinsViewCache;
|
||||
};
|
||||
|
||||
/** CCoinsView that adds a memory cache for transactions to another CCoinsView */
|
||||
class CCoinsViewCache : public CCoinsViewBacked
|
||||
{
|
||||
protected:
|
||||
/* Whether this cache has an active modifier. */
|
||||
bool hasModifier;
|
||||
|
||||
/**
|
||||
* Make mutable so that we can "fill the cache" even from Get-methods
|
||||
* declared as "const".
|
||||
*/
|
||||
mutable uint256 hashBlock;
|
||||
mutable CCoinsMap cacheCoins;
|
||||
|
||||
public:
|
||||
CCoinsViewCache(CCoinsView* baseIn);
|
||||
~CCoinsViewCache();
|
||||
|
||||
// Standard CCoinsView methods
|
||||
bool GetCoins(const uint256& txid, CCoins& coins) const;
|
||||
bool HaveCoins(const uint256& txid) const;
|
||||
uint256 GetBestBlock() const;
|
||||
void SetBestBlock(const uint256& hashBlock);
|
||||
bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock);
|
||||
|
||||
/**
|
||||
* Return a pointer to CCoins in the cache, or NULL if not found. This is
|
||||
* more efficient than GetCoins. Modifications to other cache entries are
|
||||
* allowed while accessing the returned pointer.
|
||||
*/
|
||||
const CCoins* AccessCoins(const uint256& txid) const;
|
||||
|
||||
/**
|
||||
* Return a modifiable reference to a CCoins. If no entry with the given
|
||||
* txid exists, a new one is created. Simultaneous modifications are not
|
||||
* allowed.
|
||||
*/
|
||||
CCoinsModifier ModifyCoins(const uint256& txid);
|
||||
|
||||
/**
|
||||
* Push the modifications applied to this cache to its base.
|
||||
* Failure to call this method before destruction will cause the changes to be forgotten.
|
||||
* If false is returned, the state of this cache (and its backing view) will be undefined.
|
||||
*/
|
||||
bool Flush();
|
||||
|
||||
//! Calculate the size of the cache (in number of transactions)
|
||||
unsigned int GetCacheSize() const;
|
||||
|
||||
/**
|
||||
* Amount of agrarian coming in to a transaction
|
||||
* Note that lightweight clients may not know anything besides the hash of previous transactions,
|
||||
* so may not be able to calculate this.
|
||||
*
|
||||
* @param[in] tx transaction for which we are checking input total
|
||||
* @return Sum of value of all inputs (scriptSigs)
|
||||
*/
|
||||
CAmount GetValueIn(const CTransaction& tx) const;
|
||||
|
||||
//! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
|
||||
bool HaveInputs(const CTransaction& tx) const;
|
||||
|
||||
//! Return priority of tx at height nHeight
|
||||
double GetPriority(const CTransaction& tx, int nHeight) const;
|
||||
|
||||
const CTxOut& GetOutputFor(const CTxIn& input) const;
|
||||
|
||||
friend class CCoinsModifier;
|
||||
|
||||
private:
|
||||
CCoinsMap::iterator FetchCoins(const uint256& txid);
|
||||
CCoinsMap::const_iterator FetchCoins(const uint256& txid) const;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_COINS_H
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_COMPAT_H
|
||||
#define BITCOIN_COMPAT_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/agrarian-config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#ifdef FD_SETSIZE
|
||||
#undef FD_SETSIZE // prevent redefinition compiler warning
|
||||
#endif
|
||||
#define FD_SETSIZE 1024 // max number of fds in fd_set
|
||||
|
||||
#include <winsock2.h> // Must be included before mswsock.h and windows.h
|
||||
|
||||
#include <mswsock.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <limits.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define MSG_DONTWAIT 0
|
||||
#else
|
||||
typedef u_int SOCKET;
|
||||
#include "errno.h"
|
||||
#define WSAGetLastError() errno
|
||||
#define WSAEINVAL EINVAL
|
||||
#define WSAEALREADY EALREADY
|
||||
#define WSAEWOULDBLOCK EWOULDBLOCK
|
||||
#define WSAEMSGSIZE EMSGSIZE
|
||||
#define WSAEINTR EINTR
|
||||
#define WSAEINPROGRESS EINPROGRESS
|
||||
#define WSAEADDRINUSE EADDRINUSE
|
||||
#define WSAENOTSOCK EBADF
|
||||
#define INVALID_SOCKET (SOCKET)(~0)
|
||||
#define SOCKET_ERROR -1
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef S_IRUSR
|
||||
#define S_IRUSR 0400
|
||||
#define S_IWUSR 0200
|
||||
#endif
|
||||
#else
|
||||
#define MAX_PATH 1024
|
||||
#endif
|
||||
|
||||
// As Solaris does not have the MSG_NOSIGNAL flag for send(2) syscall, it is defined as 0
|
||||
#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
// PRIO_MAX is not defined on Solaris
|
||||
#ifndef PRIO_MAX
|
||||
#define PRIO_MAX 20
|
||||
#endif
|
||||
#define THREAD_PRIORITY_LOWEST PRIO_MAX
|
||||
#define THREAD_PRIORITY_BELOW_NORMAL 2
|
||||
#define THREAD_PRIORITY_NORMAL 0
|
||||
#define THREAD_PRIORITY_ABOVE_NORMAL (-2)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_STRNLEN == 0
|
||||
size_t strnlen( const char *start, size_t max_len);
|
||||
#endif // HAVE_DECL_STRNLEN
|
||||
|
||||
bool static inline IsSelectableSocket(SOCKET s)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return true;
|
||||
#else
|
||||
return (s < FD_SETSIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // BITCOIN_COMPAT_H
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2014-2017 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_COMPAT_BYTESWAP_H
|
||||
#define BITCOIN_COMPAT_BYTESWAP_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config/agrarian-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(HAVE_BYTESWAP_H)
|
||||
#include <byteswap.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
#if !defined(bswap_16)
|
||||
|
||||
// Mac OS X / Darwin features; we include a check for bswap_16 because if it is already defined, protobuf has
|
||||
// defined these macros for us already; if it isn't, we do it ourselves. In either case, we get the exact same
|
||||
// result regardless which path was taken
|
||||
#include <libkern/OSByteOrder.h>
|
||||
#define bswap_16(x) OSSwapInt16(x)
|
||||
#define bswap_32(x) OSSwapInt32(x)
|
||||
#define bswap_64(x) OSSwapInt64(x)
|
||||
|
||||
#endif // !defined(bswap_16)
|
||||
|
||||
#else
|
||||
// Non-Mac OS X / non-Darwin
|
||||
|
||||
#if HAVE_DECL_BSWAP_16 == 0
|
||||
inline uint16_t bswap_16(uint16_t x)
|
||||
{
|
||||
return (x >> 8) | (x << 8);
|
||||
}
|
||||
#endif // HAVE_DECL_BSWAP16 == 0
|
||||
|
||||
#if HAVE_DECL_BSWAP_32 == 0
|
||||
inline uint32_t bswap_32(uint32_t x)
|
||||
{
|
||||
return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
|
||||
((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
|
||||
}
|
||||
#endif // HAVE_DECL_BSWAP32 == 0
|
||||
|
||||
#if HAVE_DECL_BSWAP_64 == 0
|
||||
inline uint64_t bswap_64(uint64_t x)
|
||||
{
|
||||
return (((x & 0xff00000000000000ull) >> 56)
|
||||
| ((x & 0x00ff000000000000ull) >> 40)
|
||||
| ((x & 0x0000ff0000000000ull) >> 24)
|
||||
| ((x & 0x000000ff00000000ull) >> 8)
|
||||
| ((x & 0x00000000ff000000ull) << 8)
|
||||
| ((x & 0x0000000000ff0000ull) << 24)
|
||||
| ((x & 0x000000000000ff00ull) << 40)
|
||||
| ((x & 0x00000000000000ffull) << 56));
|
||||
}
|
||||
#endif // HAVE_DECL_BSWAP64 == 0
|
||||
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
#endif // BITCOIN_COMPAT_BYTESWAP_H
|
||||
@@ -0,0 +1,241 @@
|
||||
// Copyright (c) 2014-2017 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_COMPAT_ENDIAN_H
|
||||
#define BITCOIN_COMPAT_ENDIAN_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config/agrarian-config.h>
|
||||
#endif
|
||||
|
||||
#include <compat/byteswap.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(HAVE_ENDIAN_H)
|
||||
#include <endian.h>
|
||||
#elif defined(HAVE_SYS_ENDIAN_H)
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_CONFIG_H
|
||||
// While not technically a supported configuration, defaulting to defining these
|
||||
// DECLs when we were compiled without autotools makes it easier for other build
|
||||
// systems to build things like libbitcoinconsensus for strange targets.
|
||||
#ifdef htobe16
|
||||
#define HAVE_DECL_HTOBE16 1
|
||||
#endif
|
||||
#ifdef htole16
|
||||
#define HAVE_DECL_HTOLE16 1
|
||||
#endif
|
||||
#ifdef be16toh
|
||||
#define HAVE_DECL_BE16TOH 1
|
||||
#endif
|
||||
#ifdef le16toh
|
||||
#define HAVE_DECL_LE16TOH 1
|
||||
#endif
|
||||
|
||||
#ifdef htobe32
|
||||
#define HAVE_DECL_HTOBE32 1
|
||||
#endif
|
||||
#ifdef htole32
|
||||
#define HAVE_DECL_HTOLE32 1
|
||||
#endif
|
||||
#ifdef be32toh
|
||||
#define HAVE_DECL_BE32TOH 1
|
||||
#endif
|
||||
#ifdef le32toh
|
||||
#define HAVE_DECL_LE32TOH 1
|
||||
#endif
|
||||
|
||||
#ifdef htobe64
|
||||
#define HAVE_DECL_HTOBE64 1
|
||||
#endif
|
||||
#ifdef htole64
|
||||
#define HAVE_DECL_HTOLE64 1
|
||||
#endif
|
||||
#ifdef be64toh
|
||||
#define HAVE_DECL_BE64TOH 1
|
||||
#endif
|
||||
#ifdef le64toh
|
||||
#define HAVE_DECL_LE64TOH 1
|
||||
#endif
|
||||
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#if defined(WORDS_BIGENDIAN)
|
||||
|
||||
#if HAVE_DECL_HTOBE16 == 0
|
||||
inline uint16_t htobe16(uint16_t host_16bits)
|
||||
{
|
||||
return host_16bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE16
|
||||
|
||||
#if HAVE_DECL_HTOLE16 == 0
|
||||
inline uint16_t htole16(uint16_t host_16bits)
|
||||
{
|
||||
return bswap_16(host_16bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE16
|
||||
|
||||
#if HAVE_DECL_BE16TOH == 0
|
||||
inline uint16_t be16toh(uint16_t big_endian_16bits)
|
||||
{
|
||||
return big_endian_16bits;
|
||||
}
|
||||
#endif // HAVE_DECL_BE16TOH
|
||||
|
||||
#if HAVE_DECL_LE16TOH == 0
|
||||
inline uint16_t le16toh(uint16_t little_endian_16bits)
|
||||
{
|
||||
return bswap_16(little_endian_16bits);
|
||||
}
|
||||
#endif // HAVE_DECL_LE16TOH
|
||||
|
||||
#if HAVE_DECL_HTOBE32 == 0
|
||||
inline uint32_t htobe32(uint32_t host_32bits)
|
||||
{
|
||||
return host_32bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE32
|
||||
|
||||
#if HAVE_DECL_HTOLE32 == 0
|
||||
inline uint32_t htole32(uint32_t host_32bits)
|
||||
{
|
||||
return bswap_32(host_32bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE32
|
||||
|
||||
#if HAVE_DECL_BE32TOH == 0
|
||||
inline uint32_t be32toh(uint32_t big_endian_32bits)
|
||||
{
|
||||
return big_endian_32bits;
|
||||
}
|
||||
#endif // HAVE_DECL_BE32TOH
|
||||
|
||||
#if HAVE_DECL_LE32TOH == 0
|
||||
inline uint32_t le32toh(uint32_t little_endian_32bits)
|
||||
{
|
||||
return bswap_32(little_endian_32bits);
|
||||
}
|
||||
#endif // HAVE_DECL_LE32TOH
|
||||
|
||||
#if HAVE_DECL_HTOBE64 == 0
|
||||
inline uint64_t htobe64(uint64_t host_64bits)
|
||||
{
|
||||
return host_64bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE64
|
||||
|
||||
#if HAVE_DECL_HTOLE64 == 0
|
||||
inline uint64_t htole64(uint64_t host_64bits)
|
||||
{
|
||||
return bswap_64(host_64bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE64
|
||||
|
||||
#if HAVE_DECL_BE64TOH == 0
|
||||
inline uint64_t be64toh(uint64_t big_endian_64bits)
|
||||
{
|
||||
return big_endian_64bits;
|
||||
}
|
||||
#endif // HAVE_DECL_BE64TOH
|
||||
|
||||
#if HAVE_DECL_LE64TOH == 0
|
||||
inline uint64_t le64toh(uint64_t little_endian_64bits)
|
||||
{
|
||||
return bswap_64(little_endian_64bits);
|
||||
}
|
||||
#endif // HAVE_DECL_LE64TOH
|
||||
|
||||
#else // WORDS_BIGENDIAN
|
||||
|
||||
#if HAVE_DECL_HTOBE16 == 0
|
||||
inline uint16_t htobe16(uint16_t host_16bits)
|
||||
{
|
||||
return bswap_16(host_16bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE16
|
||||
|
||||
#if HAVE_DECL_HTOLE16 == 0
|
||||
inline uint16_t htole16(uint16_t host_16bits)
|
||||
{
|
||||
return host_16bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE16
|
||||
|
||||
#if HAVE_DECL_BE16TOH == 0
|
||||
inline uint16_t be16toh(uint16_t big_endian_16bits)
|
||||
{
|
||||
return bswap_16(big_endian_16bits);
|
||||
}
|
||||
#endif // HAVE_DECL_BE16TOH
|
||||
|
||||
#if HAVE_DECL_LE16TOH == 0
|
||||
inline uint16_t le16toh(uint16_t little_endian_16bits)
|
||||
{
|
||||
return little_endian_16bits;
|
||||
}
|
||||
#endif // HAVE_DECL_LE16TOH
|
||||
|
||||
#if HAVE_DECL_HTOBE32 == 0
|
||||
inline uint32_t htobe32(uint32_t host_32bits)
|
||||
{
|
||||
return bswap_32(host_32bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE32
|
||||
|
||||
#if HAVE_DECL_HTOLE32 == 0
|
||||
inline uint32_t htole32(uint32_t host_32bits)
|
||||
{
|
||||
return host_32bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE32
|
||||
|
||||
#if HAVE_DECL_BE32TOH == 0
|
||||
inline uint32_t be32toh(uint32_t big_endian_32bits)
|
||||
{
|
||||
return bswap_32(big_endian_32bits);
|
||||
}
|
||||
#endif // HAVE_DECL_BE32TOH
|
||||
|
||||
#if HAVE_DECL_LE32TOH == 0
|
||||
inline uint32_t le32toh(uint32_t little_endian_32bits)
|
||||
{
|
||||
return little_endian_32bits;
|
||||
}
|
||||
#endif // HAVE_DECL_LE32TOH
|
||||
|
||||
#if HAVE_DECL_HTOBE64 == 0
|
||||
inline uint64_t htobe64(uint64_t host_64bits)
|
||||
{
|
||||
return bswap_64(host_64bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE64
|
||||
|
||||
#if HAVE_DECL_HTOLE64 == 0
|
||||
inline uint64_t htole64(uint64_t host_64bits)
|
||||
{
|
||||
return host_64bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE64
|
||||
|
||||
#if HAVE_DECL_BE64TOH == 0
|
||||
inline uint64_t be64toh(uint64_t big_endian_64bits)
|
||||
{
|
||||
return bswap_64(big_endian_64bits);
|
||||
}
|
||||
#endif // HAVE_DECL_BE64TOH
|
||||
|
||||
#if HAVE_DECL_LE64TOH == 0
|
||||
inline uint64_t le64toh(uint64_t little_endian_64bits)
|
||||
{
|
||||
return little_endian_64bits;
|
||||
}
|
||||
#endif // HAVE_DECL_LE64TOH
|
||||
|
||||
#endif // WORDS_BIGENDIAN
|
||||
|
||||
#endif // BITCOIN_COMPAT_ENDIAN_H
|
||||
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) 2009-2017 The Bitcoin Core developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/agrarian-config.h"
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(HAVE_SYS_SELECT_H)
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
// Prior to GLIBC_2.14, memcpy was aliased to memmove.
|
||||
extern "C" void* memmove(void* a, const void* b, size_t c);
|
||||
extern "C" void* memcpy(void* a, const void* b, size_t c)
|
||||
{
|
||||
return memmove(a, b, c);
|
||||
}
|
||||
|
||||
extern "C" void __chk_fail(void) __attribute__((__noreturn__));
|
||||
extern "C" FDELT_TYPE __fdelt_warn(FDELT_TYPE a)
|
||||
{
|
||||
if (a >= FD_SETSIZE)
|
||||
__chk_fail();
|
||||
return a / __NFDBITS;
|
||||
}
|
||||
extern "C" FDELT_TYPE __fdelt_chk(FDELT_TYPE) __attribute__((weak, alias("__fdelt_warn")));
|
||||
|
||||
#if defined(__i386__) || defined(__arm__)
|
||||
|
||||
extern "C" int64_t __udivmoddi4(uint64_t u, uint64_t v, uint64_t* rp);
|
||||
|
||||
extern "C" int64_t __wrap___divmoddi4(int64_t u, int64_t v, int64_t* rp)
|
||||
{
|
||||
int32_t c1 = 0, c2 = 0;
|
||||
int64_t uu = u, vv = v;
|
||||
int64_t w;
|
||||
int64_t r;
|
||||
|
||||
if (uu < 0) {
|
||||
c1 = ~c1, c2 = ~c2, uu = -uu;
|
||||
}
|
||||
if (vv < 0) {
|
||||
c1 = ~c1, vv = -vv;
|
||||
}
|
||||
|
||||
w = __udivmoddi4(uu, vv, (uint64_t*)&r);
|
||||
if (c1)
|
||||
w = -w;
|
||||
if (c2)
|
||||
r = -r;
|
||||
|
||||
*rp = r;
|
||||
return w;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" float log2f_old(float x);
|
||||
#ifdef __i386__
|
||||
__asm(".symver log2f_old,log2f@GLIBC_2.1");
|
||||
#elif defined(__amd64__)
|
||||
__asm(".symver log2f_old,log2f@GLIBC_2.2.5");
|
||||
#elif defined(__arm__)
|
||||
__asm(".symver log2f_old,log2f@GLIBC_2.4");
|
||||
#elif defined(__aarch64__)
|
||||
__asm(".symver log2f_old,log2f@GLIBC_2.17");
|
||||
#elif defined(__riscv)
|
||||
__asm(".symver log2f_old,log2f@GLIBC_2.27");
|
||||
#endif
|
||||
extern "C" float __wrap_log2f(float x)
|
||||
{
|
||||
return log2f_old(x);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2009-2017 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/agrarian-config.h"
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(HAVE_SYS_SELECT_H)
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
extern "C" void* memcpy(void* a, const void* b, size_t c);
|
||||
void* memcpy_int(void* a, const void* b, size_t c)
|
||||
{
|
||||
return memcpy(a, b, c);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// trigger: Use the memcpy_int wrapper which calls our internal memcpy.
|
||||
// A direct call to memcpy may be optimized away by the compiler.
|
||||
// test: Fill an array with a sequence of integers. memcpy to a new empty array.
|
||||
// Verify that the arrays are equal. Use an odd size to decrease the odds of
|
||||
// the call being optimized away.
|
||||
template <unsigned int T>
|
||||
bool sanity_test_memcpy()
|
||||
{
|
||||
unsigned int memcpy_test[T];
|
||||
unsigned int memcpy_verify[T] = {};
|
||||
for (unsigned int i = 0; i != T; ++i)
|
||||
memcpy_test[i] = i;
|
||||
|
||||
memcpy_int(memcpy_verify, memcpy_test, sizeof(memcpy_test));
|
||||
|
||||
for (unsigned int i = 0; i != T; ++i) {
|
||||
if (memcpy_verify[i] != i)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SYS_SELECT_H)
|
||||
// trigger: Call FD_SET to trigger __fdelt_chk. FORTIFY_SOURCE must be defined
|
||||
// as >0 and optimizations must be set to at least -O2.
|
||||
// test: Add a file descriptor to an empty fd_set. Verify that it has been
|
||||
// correctly added.
|
||||
bool sanity_test_fdelt()
|
||||
{
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(0, &fds);
|
||||
return FD_ISSET(0, &fds);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // anon namespace
|
||||
|
||||
bool glibc_sanity_test()
|
||||
{
|
||||
#if defined(HAVE_SYS_SELECT_H)
|
||||
if (!sanity_test_fdelt())
|
||||
return false;
|
||||
#endif
|
||||
return sanity_test_memcpy<1025>();
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2009-2017 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <list>
|
||||
#include <locale>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace
|
||||
{
|
||||
// trigger: use ctype<char>::widen to trigger ctype<char>::_M_widen_init().
|
||||
// test: convert a char from narrow to wide and back. Verify that the result
|
||||
// matches the original.
|
||||
bool sanity_test_widen(char testchar)
|
||||
{
|
||||
const std::ctype<char>& test(std::use_facet<std::ctype<char> >(std::locale()));
|
||||
return test.narrow(test.widen(testchar), 'b') == testchar;
|
||||
}
|
||||
|
||||
// trigger: use list::push_back and list::pop_back to trigger _M_hook and
|
||||
// _M_unhook.
|
||||
// test: Push a sequence of integers into a list. Pop them off and verify that
|
||||
// they match the original sequence.
|
||||
bool sanity_test_list(unsigned int size)
|
||||
{
|
||||
std::list<unsigned int> test;
|
||||
for (unsigned int i = 0; i != size; ++i)
|
||||
test.push_back(i + 1);
|
||||
|
||||
if (test.size() != size)
|
||||
return false;
|
||||
|
||||
while (!test.empty()) {
|
||||
if (test.back() != test.size())
|
||||
return false;
|
||||
test.pop_back();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
// trigger: string::at(x) on an empty string to trigger __throw_out_of_range_fmt.
|
||||
// test: force std::string to throw an out_of_range exception. Verify that
|
||||
// it's caught correctly.
|
||||
bool sanity_test_range_fmt()
|
||||
{
|
||||
std::string test;
|
||||
try {
|
||||
test.at(1);
|
||||
} catch (const std::out_of_range&) {
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool glibcxx_sanity_test()
|
||||
{
|
||||
return sanity_test_widen('a') && sanity_test_list(100) && sanity_test_range_fmt();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_COMPAT_SANITY_H
|
||||
#define BITCOIN_COMPAT_SANITY_H
|
||||
|
||||
bool glibc_sanity_test();
|
||||
bool glibcxx_sanity_test();
|
||||
|
||||
#endif // BITCOIN_COMPAT_SANITY_H
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2009-2017 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/agrarian-config.h"
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#if HAVE_DECL_STRNLEN == 0
|
||||
size_t strnlen( const char *start, size_t max_len)
|
||||
{
|
||||
const char *end = (const char *)memchr(start, '\0', max_len);
|
||||
|
||||
return end ? (size_t)(end - start) : max_len;
|
||||
}
|
||||
#endif // HAVE_DECL_STRNLEN
|
||||
@@ -0,0 +1,181 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "compressor.h"
|
||||
|
||||
#include "hash.h"
|
||||
#include "pubkey.h"
|
||||
#include "script/standard.h"
|
||||
|
||||
bool CScriptCompressor::IsToKeyID(CKeyID& hash) const
|
||||
{
|
||||
if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) {
|
||||
memcpy(&hash, &script[3], 20);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CScriptCompressor::IsToScriptID(CScriptID& hash) const
|
||||
{
|
||||
if (script.size() == 23 && script[0] == OP_HASH160 && script[1] == 20 && script[22] == OP_EQUAL) {
|
||||
memcpy(&hash, &script[2], 20);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CScriptCompressor::IsToPubKey(CPubKey& pubkey) const
|
||||
{
|
||||
if (script.size() == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && (script[1] == 0x02 || script[1] == 0x03)) {
|
||||
pubkey.Set(&script[1], &script[34]);
|
||||
return true;
|
||||
}
|
||||
if (script.size() == 67 && script[0] == 65 && script[66] == OP_CHECKSIG && script[1] == 0x04) {
|
||||
pubkey.Set(&script[1], &script[66]);
|
||||
return pubkey.IsFullyValid(); // if not fully valid, a case that would not be compressible
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CScriptCompressor::Compress(std::vector<unsigned char>& out) const
|
||||
{
|
||||
CKeyID keyID;
|
||||
if (IsToKeyID(keyID)) {
|
||||
out.resize(21);
|
||||
out[0] = 0x00;
|
||||
memcpy(&out[1], &keyID, 20);
|
||||
return true;
|
||||
}
|
||||
CScriptID scriptID;
|
||||
if (IsToScriptID(scriptID)) {
|
||||
out.resize(21);
|
||||
out[0] = 0x01;
|
||||
memcpy(&out[1], &scriptID, 20);
|
||||
return true;
|
||||
}
|
||||
CPubKey pubkey;
|
||||
if (IsToPubKey(pubkey)) {
|
||||
out.resize(33);
|
||||
memcpy(&out[1], &pubkey[1], 32);
|
||||
if (pubkey[0] == 0x02 || pubkey[0] == 0x03) {
|
||||
out[0] = pubkey[0];
|
||||
return true;
|
||||
} else if (pubkey[0] == 0x04) {
|
||||
out[0] = 0x04 | (pubkey[64] & 0x01);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int CScriptCompressor::GetSpecialSize(unsigned int nSize) const
|
||||
{
|
||||
if (nSize == 0 || nSize == 1)
|
||||
return 20;
|
||||
if (nSize == 2 || nSize == 3 || nSize == 4 || nSize == 5)
|
||||
return 32;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector<unsigned char>& in)
|
||||
{
|
||||
switch (nSize) {
|
||||
case 0x00:
|
||||
script.resize(25);
|
||||
script[0] = OP_DUP;
|
||||
script[1] = OP_HASH160;
|
||||
script[2] = 20;
|
||||
memcpy(&script[3], &in[0], 20);
|
||||
script[23] = OP_EQUALVERIFY;
|
||||
script[24] = OP_CHECKSIG;
|
||||
return true;
|
||||
case 0x01:
|
||||
script.resize(23);
|
||||
script[0] = OP_HASH160;
|
||||
script[1] = 20;
|
||||
memcpy(&script[2], &in[0], 20);
|
||||
script[22] = OP_EQUAL;
|
||||
return true;
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
script.resize(35);
|
||||
script[0] = 33;
|
||||
script[1] = nSize;
|
||||
memcpy(&script[2], &in[0], 32);
|
||||
script[34] = OP_CHECKSIG;
|
||||
return true;
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
unsigned char vch[33] = {};
|
||||
vch[0] = nSize - 2;
|
||||
memcpy(&vch[1], &in[0], 32);
|
||||
CPubKey pubkey(&vch[0], &vch[33]);
|
||||
if (!pubkey.Decompress())
|
||||
return false;
|
||||
assert(pubkey.size() == 65);
|
||||
script.resize(67);
|
||||
script[0] = 65;
|
||||
memcpy(&script[1], pubkey.begin(), 65);
|
||||
script[66] = OP_CHECKSIG;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Amount compression:
|
||||
// * If the amount is 0, output 0
|
||||
// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)
|
||||
// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10)
|
||||
// * call the result n
|
||||
// * output 1 + 10*(9*n + d - 1) + e
|
||||
// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
|
||||
// (this is decodable, as d is in [1-9] and e is in [0-9])
|
||||
|
||||
uint64_t CTxOutCompressor::CompressAmount(uint64_t n)
|
||||
{
|
||||
if (n == 0)
|
||||
return 0;
|
||||
int e = 0;
|
||||
while (((n % 10) == 0) && e < 9) {
|
||||
n /= 10;
|
||||
e++;
|
||||
}
|
||||
if (e < 9) {
|
||||
int d = (n % 10);
|
||||
assert(d >= 1 && d <= 9);
|
||||
n /= 10;
|
||||
return 1 + (n * 9 + d - 1) * 10 + e;
|
||||
} else {
|
||||
return 1 + (n - 1) * 10 + 9;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t CTxOutCompressor::DecompressAmount(uint64_t x)
|
||||
{
|
||||
// x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9
|
||||
if (x == 0)
|
||||
return 0;
|
||||
x--;
|
||||
// x = 10*(9*n + d - 1) + e
|
||||
int e = x % 10;
|
||||
x /= 10;
|
||||
uint64_t n = 0;
|
||||
if (e < 9) {
|
||||
// x = 9*n + d - 1
|
||||
int d = (x % 9) + 1;
|
||||
x /= 9;
|
||||
// x = n
|
||||
n = x * 10 + d;
|
||||
} else {
|
||||
n = x + 1;
|
||||
}
|
||||
while (e) {
|
||||
n *= 10;
|
||||
e--;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_COMPRESSOR_H
|
||||
#define BITCOIN_COMPRESSOR_H
|
||||
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
#include "serialize.h"
|
||||
|
||||
class CKeyID;
|
||||
class CPubKey;
|
||||
class CScriptID;
|
||||
|
||||
/** Compact serializer for scripts.
|
||||
*
|
||||
* It detects common cases and encodes them much more efficiently.
|
||||
* 3 special cases are defined:
|
||||
* * Pay to pubkey hash (encoded as 21 bytes)
|
||||
* * Pay to script hash (encoded as 21 bytes)
|
||||
* * Pay to pubkey starting with 0x02, 0x03 or 0x04 (encoded as 33 bytes)
|
||||
*
|
||||
* Other scripts up to 121 bytes require 1 byte + script length. Above
|
||||
* that, scripts up to 16505 bytes require 2 bytes + script length.
|
||||
*/
|
||||
class CScriptCompressor
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* make this static for now (there are only 6 special scripts defined)
|
||||
* this can potentially be extended together with a new nVersion for
|
||||
* transactions, in which case this value becomes dependent on nVersion
|
||||
* and nHeight of the enclosing transaction.
|
||||
*/
|
||||
static const unsigned int nSpecialScripts = 6;
|
||||
|
||||
CScript& script;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* These check for scripts for which a special case with a shorter encoding is defined.
|
||||
* They are implemented separately from the CScript test, as these test for exact byte
|
||||
* sequence correspondences, and are more strict. For example, IsToPubKey also verifies
|
||||
* whether the public key is valid (as invalid ones cannot be represented in compressed
|
||||
* form).
|
||||
*/
|
||||
bool IsToKeyID(CKeyID& hash) const;
|
||||
bool IsToScriptID(CScriptID& hash) const;
|
||||
bool IsToPubKey(CPubKey& pubkey) const;
|
||||
|
||||
bool Compress(std::vector<unsigned char>& out) const;
|
||||
unsigned int GetSpecialSize(unsigned int nSize) const;
|
||||
bool Decompress(unsigned int nSize, const std::vector<unsigned char>& out);
|
||||
|
||||
public:
|
||||
CScriptCompressor(CScript& scriptIn) : script(scriptIn) {}
|
||||
|
||||
unsigned int GetSerializeSize(int nType, int nVersion) const
|
||||
{
|
||||
std::vector<unsigned char> compr;
|
||||
if (Compress(compr))
|
||||
return compr.size();
|
||||
unsigned int nSize = script.size() + nSpecialScripts;
|
||||
return script.size() + VARINT(nSize).GetSerializeSize(nType, nVersion);
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
void Serialize(Stream& s, int nType, int nVersion) const
|
||||
{
|
||||
std::vector<unsigned char> compr;
|
||||
if (Compress(compr)) {
|
||||
s << CFlatData(compr);
|
||||
return;
|
||||
}
|
||||
unsigned int nSize = script.size() + nSpecialScripts;
|
||||
s << VARINT(nSize);
|
||||
s << CFlatData(script);
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s, int nType, int nVersion)
|
||||
{
|
||||
unsigned int nSize = 0;
|
||||
s >> VARINT(nSize);
|
||||
if (nSize < nSpecialScripts) {
|
||||
std::vector<unsigned char> vch(GetSpecialSize(nSize), 0x00);
|
||||
s >> REF(CFlatData(vch));
|
||||
Decompress(nSize, vch);
|
||||
return;
|
||||
}
|
||||
nSize -= nSpecialScripts;
|
||||
script.resize(nSize);
|
||||
s >> REF(CFlatData(script));
|
||||
}
|
||||
};
|
||||
|
||||
/** wrapper for CTxOut that provides a more compact serialization */
|
||||
class CTxOutCompressor
|
||||
{
|
||||
private:
|
||||
CTxOut& txout;
|
||||
|
||||
public:
|
||||
static uint64_t CompressAmount(uint64_t nAmount);
|
||||
static uint64_t DecompressAmount(uint64_t nAmount);
|
||||
|
||||
CTxOutCompressor(CTxOut& txoutIn) : txout(txoutIn) {}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
if (!ser_action.ForRead()) {
|
||||
uint64_t nVal = CompressAmount(txout.nValue);
|
||||
READWRITE(VARINT(nVal));
|
||||
} else {
|
||||
uint64_t nVal = 0;
|
||||
READWRITE(VARINT(nVal));
|
||||
txout.nValue = DecompressAmount(nVal);
|
||||
}
|
||||
CScriptCompressor cscript(REF(txout.scriptPubKey));
|
||||
READWRITE(cscript);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BITCOIN_COMPRESSOR_H
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Copyright (c) 2015-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef Agrarian_CONCURRENTQUEUE_H
|
||||
#define Agrarian_CONCURRENTQUEUE_H
|
||||
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
|
||||
template <typename T>
|
||||
class concurrentqueue
|
||||
{
|
||||
private:
|
||||
std::mutex mutex;
|
||||
std::condition_variable condition;
|
||||
std::deque<T> queue;
|
||||
|
||||
public:
|
||||
void push(T const& value) {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
queue.push_front(value);
|
||||
}
|
||||
this->condition.notify_one();
|
||||
}
|
||||
T pop() {
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
this->condition.wait(lock, [=]{ return !this->queue.empty(); });
|
||||
T rc(std::move(this->queue.back()));
|
||||
this->queue.pop_back();
|
||||
return rc;
|
||||
}
|
||||
|
||||
T popNotWait(){
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
T rc(std::move(this->queue.back()));
|
||||
this->queue.pop_back();
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool hasElements(){
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
return !queue.empty();
|
||||
}
|
||||
};
|
||||
|
||||
#endif //Agrarian_CONCURRENTQUEUE_H
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CORE_IO_H
|
||||
#define BITCOIN_CORE_IO_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class CBlock;
|
||||
class CScript;
|
||||
class CTransaction;
|
||||
class uint256;
|
||||
class UniValue;
|
||||
|
||||
// core_read.cpp
|
||||
extern CScript ParseScript(std::string s);
|
||||
extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
|
||||
extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
|
||||
extern uint256 ParseHashUV(const UniValue& v, const std::string& strName);
|
||||
extern uint256 ParseHashStr(const std::string&, const std::string& strName);
|
||||
extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
|
||||
|
||||
// core_write.cpp
|
||||
extern std::string FormatScript(const CScript& script);
|
||||
extern std::string EncodeHexTx(const CTransaction& tx);
|
||||
extern void ScriptPubKeyToUniv(const CScript& scriptPubKey,
|
||||
UniValue& out,
|
||||
bool fIncludeHex);
|
||||
extern void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry);
|
||||
|
||||
#endif // BITCOIN_CORE_IO_H
|
||||
@@ -0,0 +1,140 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2015-2017 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "core_io.h"
|
||||
|
||||
#include "primitives/block.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
#include "serialize.h"
|
||||
#include "streams.h"
|
||||
#include <univalue.h>
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::algorithm;
|
||||
using namespace std;
|
||||
|
||||
CScript ParseScript(std::string s)
|
||||
{
|
||||
CScript result;
|
||||
|
||||
static map<string, opcodetype> mapOpNames;
|
||||
|
||||
if (mapOpNames.empty()) {
|
||||
for (int op = 0; op <= OP_ZEROCOINSPEND; op++) {
|
||||
// Allow OP_RESERVED to get into mapOpNames
|
||||
if (op < OP_NOP && op != OP_RESERVED)
|
||||
continue;
|
||||
|
||||
const char* name = GetOpName((opcodetype)op);
|
||||
if (strcmp(name, "OP_UNKNOWN") == 0)
|
||||
continue;
|
||||
string strName(name);
|
||||
mapOpNames[strName] = (opcodetype)op;
|
||||
// Convenience: OP_ADD and just ADD are both recognized:
|
||||
replace_first(strName, "OP_", "");
|
||||
mapOpNames[strName] = (opcodetype)op;
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> words;
|
||||
split(words, s, is_any_of(" \t\n"), token_compress_on);
|
||||
|
||||
for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w) {
|
||||
if (w->empty()) {
|
||||
// Empty string, ignore. (boost::split given '' will return one word)
|
||||
} else if (all(*w, is_digit()) ||
|
||||
(starts_with(*w, "-") && all(string(w->begin() + 1, w->end()), is_digit()))) {
|
||||
// Number
|
||||
int64_t n = atoi64(*w);
|
||||
result << n;
|
||||
} else if (starts_with(*w, "0x") && (w->begin() + 2 != w->end()) && IsHex(string(w->begin() + 2, w->end()))) {
|
||||
// Raw hex data, inserted NOT pushed onto stack:
|
||||
std::vector<unsigned char> raw = ParseHex(string(w->begin() + 2, w->end()));
|
||||
result.insert(result.end(), raw.begin(), raw.end());
|
||||
} else if (w->size() >= 2 && starts_with(*w, "'") && ends_with(*w, "'")) {
|
||||
// Single-quoted string, pushed as data. NOTE: this is poor-man's
|
||||
// parsing, spaces/tabs/newlines in single-quoted strings won't work.
|
||||
std::vector<unsigned char> value(w->begin() + 1, w->end() - 1);
|
||||
result << value;
|
||||
} else if (mapOpNames.count(*w)) {
|
||||
// opcode, e.g. OP_ADD or ADD:
|
||||
result << mapOpNames[*w];
|
||||
} else {
|
||||
throw runtime_error("script parse error");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx)
|
||||
{
|
||||
if (!IsHex(strHexTx))
|
||||
return false;
|
||||
|
||||
vector<unsigned char> txData(ParseHex(strHexTx));
|
||||
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
|
||||
try {
|
||||
ssData >> tx;
|
||||
} catch (const std::exception&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk)
|
||||
{
|
||||
if (!IsHex(strHexBlk))
|
||||
return false;
|
||||
|
||||
std::vector<unsigned char> blockData(ParseHex(strHexBlk));
|
||||
CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
|
||||
try {
|
||||
ssBlock >> block;
|
||||
} catch (const std::exception&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint256 ParseHashUV(const UniValue& v, const string& strName)
|
||||
{
|
||||
string strHex;
|
||||
if (v.isStr())
|
||||
strHex = v.getValStr();
|
||||
return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error
|
||||
}
|
||||
|
||||
uint256 ParseHashStr(const std::string& strHex, const std::string& strName)
|
||||
{
|
||||
if (!IsHex(strHex)) // Note: IsHex("") is false
|
||||
throw runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')");
|
||||
|
||||
uint256 result;
|
||||
result.SetHex(strHex);
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<unsigned char> ParseHexUV(const UniValue& v, const string& strName)
|
||||
{
|
||||
string strHex;
|
||||
if (v.isStr())
|
||||
strHex = v.getValStr();
|
||||
if (!IsHex(strHex))
|
||||
throw runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')");
|
||||
return ParseHex(strHex);
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2019 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "core_io.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
#include "script/standard.h"
|
||||
#include "serialize.h"
|
||||
#include "streams.h"
|
||||
#include <univalue.h>
|
||||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
string FormatScript(const CScript& script)
|
||||
{
|
||||
string ret;
|
||||
CScript::const_iterator it = script.begin();
|
||||
opcodetype op;
|
||||
while (it != script.end()) {
|
||||
CScript::const_iterator it2 = it;
|
||||
vector<unsigned char> vch;
|
||||
if (script.GetOp2(it, op, &vch)) {
|
||||
if (op == OP_0) {
|
||||
ret += "0 ";
|
||||
continue;
|
||||
} else if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) {
|
||||
ret += strprintf("%i ", op - OP_1NEGATE - 1);
|
||||
continue;
|
||||
} else if (op >= OP_NOP && op <= OP_CHECKMULTISIGVERIFY) {
|
||||
string str(GetOpName(op));
|
||||
if (str.substr(0, 3) == string("OP_")) {
|
||||
ret += str.substr(3, string::npos) + " ";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (vch.size() > 0) {
|
||||
ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()), HexStr(it - vch.size(), it));
|
||||
} else {
|
||||
ret += strprintf("0x%x", HexStr(it2, it));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ret += strprintf("0x%x ", HexStr(it2, script.end()));
|
||||
break;
|
||||
}
|
||||
return ret.substr(0, ret.size() - 1);
|
||||
}
|
||||
|
||||
string EncodeHexTx(const CTransaction& tx)
|
||||
{
|
||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ssTx << tx;
|
||||
return HexStr(ssTx.begin(), ssTx.end());
|
||||
}
|
||||
|
||||
void ScriptPubKeyToUniv(const CScript& scriptPubKey,
|
||||
UniValue& out,
|
||||
bool fIncludeHex)
|
||||
{
|
||||
txnouttype type;
|
||||
vector<CTxDestination> addresses;
|
||||
int nRequired;
|
||||
|
||||
out.pushKV("asm", scriptPubKey.ToString());
|
||||
if (fIncludeHex)
|
||||
out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
|
||||
|
||||
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
|
||||
out.pushKV("type", GetTxnOutputType(type));
|
||||
return;
|
||||
}
|
||||
|
||||
out.pushKV("reqSigs", nRequired);
|
||||
out.pushKV("type", GetTxnOutputType(type));
|
||||
|
||||
UniValue a(UniValue::VARR);
|
||||
for (const CTxDestination& addr : addresses)
|
||||
a.push_back(CBitcoinAddress(addr).ToString());
|
||||
out.pushKV("addresses", a);
|
||||
}
|
||||
|
||||
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
|
||||
{
|
||||
entry.pushKV("txid", tx.GetHash().GetHex());
|
||||
entry.pushKV("version", tx.nVersion);
|
||||
entry.pushKV("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION));
|
||||
entry.pushKV("locktime", (int64_t)tx.nLockTime);
|
||||
|
||||
UniValue vin(UniValue::VARR);
|
||||
for (const CTxIn& txin : tx.vin) {
|
||||
UniValue in(UniValue::VOBJ);
|
||||
if (tx.IsCoinBase())
|
||||
in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
|
||||
else {
|
||||
in.pushKV("txid", txin.prevout.hash.GetHex());
|
||||
in.pushKV("vout", (int64_t)txin.prevout.n);
|
||||
UniValue o(UniValue::VOBJ);
|
||||
o.pushKV("asm", txin.scriptSig.ToString());
|
||||
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
|
||||
in.pushKV("scriptSig", o);
|
||||
}
|
||||
in.pushKV("sequence", (int64_t)txin.nSequence);
|
||||
vin.push_back(in);
|
||||
}
|
||||
entry.pushKV("vin", vin);
|
||||
|
||||
UniValue vout(UniValue::VARR);
|
||||
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
||||
const CTxOut& txout = tx.vout[i];
|
||||
|
||||
UniValue out(UniValue::VOBJ);
|
||||
|
||||
UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue));
|
||||
out.pushKV("value", outValue);
|
||||
out.pushKV("n", (int64_t)i);
|
||||
|
||||
UniValue o(UniValue::VOBJ);
|
||||
ScriptPubKeyToUniv(txout.scriptPubKey, o, true);
|
||||
out.pushKV("scriptPubKey", o);
|
||||
vout.push_back(out);
|
||||
}
|
||||
entry.pushKV("vout", vout);
|
||||
|
||||
if (hashBlock != 0)
|
||||
entry.pushKV("blockhash", hashBlock.GetHex());
|
||||
|
||||
entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".
|
||||
}
|
||||
+451
@@ -0,0 +1,451 @@
|
||||
// Copyright (c) 2009-2013 The Bitcoin developers
|
||||
// Copyright (c) 2017-2019 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "crypter.h"
|
||||
|
||||
#include "script/script.h"
|
||||
#include "script/standard.h"
|
||||
#include "util.h"
|
||||
#include "init.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
|
||||
{
|
||||
if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
|
||||
return false;
|
||||
|
||||
int i = 0;
|
||||
if (nDerivationMethod == 0)
|
||||
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
|
||||
(unsigned char*)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
|
||||
|
||||
if (i != (int)WALLET_CRYPTO_KEY_SIZE) {
|
||||
memory_cleanse(chKey, sizeof(chKey));
|
||||
memory_cleanse(chIV, sizeof(chIV));
|
||||
return false;
|
||||
}
|
||||
|
||||
fKeySet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV)
|
||||
{
|
||||
if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE)
|
||||
return false;
|
||||
|
||||
memcpy(&chKey[0], &chNewKey[0], sizeof chKey);
|
||||
memcpy(&chIV[0], &chNewIV[0], sizeof chIV);
|
||||
|
||||
fKeySet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char>& vchCiphertext)
|
||||
{
|
||||
if (!fKeySet)
|
||||
return false;
|
||||
|
||||
// max ciphertext len for a n bytes of plaintext is
|
||||
// n + AES_BLOCK_SIZE - 1 bytes
|
||||
int nLen = vchPlaintext.size();
|
||||
int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0;
|
||||
vchCiphertext = std::vector<unsigned char>(nCLen);
|
||||
|
||||
bool fOk = true;
|
||||
|
||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||
if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0;
|
||||
if (fOk) fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0;
|
||||
if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0;
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
if (!fOk) return false;
|
||||
|
||||
vchCiphertext.resize(nCLen + nFLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext)
|
||||
{
|
||||
if (!fKeySet)
|
||||
return false;
|
||||
|
||||
// plaintext will always be equal to or lesser than length of ciphertext
|
||||
int nLen = vchCiphertext.size();
|
||||
int nPLen = nLen, nFLen = 0;
|
||||
|
||||
vchPlaintext = CKeyingMaterial(nPLen);
|
||||
|
||||
bool fOk = true;
|
||||
|
||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||
if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0;
|
||||
if (fOk) fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0;
|
||||
if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0;
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
if (!fOk) return false;
|
||||
|
||||
vchPlaintext.resize(nPLen + nFLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial& vchPlaintext, const uint256& nIV, std::vector<unsigned char>& vchCiphertext)
|
||||
{
|
||||
CCrypter cKeyCrypter;
|
||||
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
|
||||
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
|
||||
if (!cKeyCrypter.SetKey(vMasterKey, chIV))
|
||||
return false;
|
||||
return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext);
|
||||
}
|
||||
|
||||
|
||||
// General secure AES 256 CBC encryption routine
|
||||
bool EncryptAES256(const SecureString& sKey, const SecureString& sPlaintext, const std::string& sIV, std::string& sCiphertext)
|
||||
{
|
||||
// max ciphertext len for a n bytes of plaintext is
|
||||
// n + AES_BLOCK_SIZE - 1 bytes
|
||||
int nLen = sPlaintext.size();
|
||||
int nCLen = nLen + AES_BLOCK_SIZE;
|
||||
int nFLen = 0;
|
||||
|
||||
// Verify key sizes
|
||||
if (sKey.size() != 32 || sIV.size() != AES_BLOCK_SIZE) {
|
||||
LogPrintf("crypter EncryptAES256 - Invalid key or block size: Key: %d sIV:%d\n", sKey.size(), sIV.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prepare output buffer
|
||||
sCiphertext.resize(nCLen);
|
||||
|
||||
// Perform the encryption
|
||||
EVP_CIPHER_CTX* ctx;
|
||||
|
||||
bool fOk = true;
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]);
|
||||
if (fOk) fOk = EVP_EncryptUpdate(ctx, (unsigned char*)&sCiphertext[0], &nCLen, (const unsigned char*)&sPlaintext[0], nLen);
|
||||
if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (unsigned char*)(&sCiphertext[0]) + nCLen, &nFLen);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
if (!fOk) return false;
|
||||
|
||||
sCiphertext.resize(nCLen + nFLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
|
||||
{
|
||||
CCrypter cKeyCrypter;
|
||||
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
|
||||
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
|
||||
if (!cKeyCrypter.SetKey(vMasterKey, chIV))
|
||||
return false;
|
||||
return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
|
||||
}
|
||||
|
||||
bool DecryptAES256(const SecureString& sKey, const std::string& sCiphertext, const std::string& sIV, SecureString& sPlaintext)
|
||||
{
|
||||
// plaintext will always be equal to or lesser than length of ciphertext
|
||||
int nLen = sCiphertext.size();
|
||||
int nPLen = nLen, nFLen = 0;
|
||||
|
||||
// Verify key sizes
|
||||
if (sKey.size() != 32 || sIV.size() != AES_BLOCK_SIZE) {
|
||||
LogPrintf("crypter DecryptAES256 - Invalid key or block size\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
sPlaintext.resize(nPLen);
|
||||
|
||||
EVP_CIPHER_CTX* ctx;
|
||||
|
||||
bool fOk = true;
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]);
|
||||
if (fOk) fOk = EVP_DecryptUpdate(ctx, (unsigned char*)&sPlaintext[0], &nPLen, (const unsigned char*)&sCiphertext[0], nLen);
|
||||
if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (unsigned char*)(&sPlaintext[0]) + nPLen, &nFLen);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
if (!fOk) return false;
|
||||
|
||||
sPlaintext.resize(nPLen + nFLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CCryptoKeyStore::SetCrypted()
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (fUseCrypto)
|
||||
return true;
|
||||
if (!mapKeys.empty())
|
||||
return false;
|
||||
fUseCrypto = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::Lock()
|
||||
{
|
||||
if (!SetCrypted())
|
||||
return false;
|
||||
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
vMasterKey.clear();
|
||||
pwalletMain->zwalletMain->Lock();
|
||||
}
|
||||
|
||||
NotifyStatusChanged(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!SetCrypted())
|
||||
return false;
|
||||
|
||||
bool keyPass = false;
|
||||
bool keyFail = false;
|
||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
||||
for (; mi != mapCryptedKeys.end(); ++mi) {
|
||||
const CPubKey& vchPubKey = (*mi).second.first;
|
||||
const std::vector<unsigned char>& vchCryptedSecret = (*mi).second.second;
|
||||
CKeyingMaterial vchSecret;
|
||||
if (!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) {
|
||||
keyFail = true;
|
||||
break;
|
||||
}
|
||||
if (vchSecret.size() != 32) {
|
||||
keyFail = true;
|
||||
break;
|
||||
}
|
||||
CKey key;
|
||||
key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
|
||||
if (key.GetPubKey() != vchPubKey) {
|
||||
keyFail = true;
|
||||
break;
|
||||
}
|
||||
keyPass = true;
|
||||
if (fDecryptionThoroughlyChecked)
|
||||
break;
|
||||
}
|
||||
if (keyPass && keyFail) {
|
||||
LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.");
|
||||
assert(false);
|
||||
}
|
||||
if (keyFail || !keyPass)
|
||||
return false;
|
||||
vMasterKey = vMasterKeyIn;
|
||||
fDecryptionThoroughlyChecked = true;
|
||||
|
||||
uint256 hashSeed;
|
||||
if (CWalletDB(pwalletMain->strWalletFile).ReadCurrentSeedHash(hashSeed)) {
|
||||
uint256 nSeed;
|
||||
if (!GetDeterministicSeed(hashSeed, nSeed)) {
|
||||
return error("Failed to read zAGR seed from DB. Wallet is probably corrupt.");
|
||||
}
|
||||
pwalletMain->zwalletMain->SetMasterSeed(nSeed, false);
|
||||
} else {
|
||||
// First time this wallet has been unlocked with dzAGR
|
||||
// Borrow random generator from the key class so that we don't have to worry about randomness
|
||||
CKey key;
|
||||
key.MakeNewKey(true);
|
||||
uint256 seed = key.GetPrivKey_256();
|
||||
LogPrintf("%s: first run of zagr wallet detected, new seed generated. Seedhash=%s\n", __func__, Hash(seed.begin(), seed.end()).GetHex());
|
||||
pwalletMain->zwalletMain->SetMasterSeed(seed, true);
|
||||
pwalletMain->zwalletMain->GenerateMintPool();
|
||||
}
|
||||
}
|
||||
|
||||
NotifyStatusChanged(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::AddKeyPubKey(const CKey& key, const CPubKey& pubkey)
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!IsCrypted())
|
||||
return CBasicKeyStore::AddKeyPubKey(key, pubkey);
|
||||
|
||||
if (IsLocked())
|
||||
return false;
|
||||
|
||||
std::vector<unsigned char> vchCryptedSecret;
|
||||
CKeyingMaterial vchSecret(key.begin(), key.end());
|
||||
if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), vchCryptedSecret))
|
||||
return false;
|
||||
|
||||
if (!AddCryptedKey(pubkey, vchCryptedSecret))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CCryptoKeyStore::AddCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret)
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!SetCrypted())
|
||||
return false;
|
||||
|
||||
mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::GetKey(const CKeyID& address, CKey& keyOut) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!IsCrypted())
|
||||
return CBasicKeyStore::GetKey(address, keyOut);
|
||||
|
||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
||||
if (mi != mapCryptedKeys.end()) {
|
||||
const CPubKey& vchPubKey = (*mi).second.first;
|
||||
const std::vector<unsigned char>& vchCryptedSecret = (*mi).second.second;
|
||||
CKeyingMaterial vchSecret;
|
||||
if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||
return false;
|
||||
if (vchSecret.size() != 32)
|
||||
return false;
|
||||
keyOut.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::GetPubKey(const CKeyID& address, CPubKey& vchPubKeyOut) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!IsCrypted())
|
||||
return CKeyStore::GetPubKey(address, vchPubKeyOut);
|
||||
|
||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
||||
if (mi != mapCryptedKeys.end()) {
|
||||
vchPubKeyOut = (*mi).second.first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!mapCryptedKeys.empty() || IsCrypted())
|
||||
return false;
|
||||
|
||||
fUseCrypto = true;
|
||||
for (KeyMap::value_type& mKey : mapKeys) {
|
||||
const CKey& key = mKey.second;
|
||||
CPubKey vchPubKey = key.GetPubKey();
|
||||
CKeyingMaterial vchSecret(key.begin(), key.end());
|
||||
std::vector<unsigned char> vchCryptedSecret;
|
||||
if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret))
|
||||
return false;
|
||||
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
|
||||
return false;
|
||||
}
|
||||
mapKeys.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::AddDeterministicSeed(const uint256& seed)
|
||||
{
|
||||
CWalletDB db(pwalletMain->strWalletFile);
|
||||
string strErr;
|
||||
uint256 hashSeed = Hash(seed.begin(), seed.end());
|
||||
|
||||
if(IsCrypted()) {
|
||||
if (!IsLocked()) { //if we have password
|
||||
|
||||
CKeyingMaterial kmSeed(seed.begin(), seed.end());
|
||||
vector<unsigned char> vchSeedSecret;
|
||||
|
||||
|
||||
//attempt encrypt
|
||||
if (EncryptSecret(vMasterKey, kmSeed, hashSeed, vchSeedSecret)) {
|
||||
//write to wallet with hashSeed as unique key
|
||||
if (db.WriteZAGRSeed(hashSeed, vchSeedSecret)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
strErr = "encrypt seed";
|
||||
}
|
||||
strErr = "save since wallet is locked";
|
||||
} else { //wallet not encrypted
|
||||
if (db.WriteZAGRSeed(hashSeed, ToByteVector(seed))) {
|
||||
return true;
|
||||
}
|
||||
strErr = "save zagrseed to wallet";
|
||||
}
|
||||
//the use case for this is no password set seed, mint dzAGR,
|
||||
|
||||
return error("s%: Failed to %s\n", __func__, strErr);
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::GetDeterministicSeed(const uint256& hashSeed, uint256& seedOut)
|
||||
{
|
||||
|
||||
CWalletDB db(pwalletMain->strWalletFile);
|
||||
string strErr;
|
||||
if (IsCrypted()) {
|
||||
if(!IsLocked()) { //if we have password
|
||||
|
||||
vector<unsigned char> vchCryptedSeed;
|
||||
//read encrypted seed
|
||||
if (db.ReadZAGRSeed(hashSeed, vchCryptedSeed)) {
|
||||
uint256 seedRetrieved = uint256(ReverseEndianString(HexStr(vchCryptedSeed)));
|
||||
//this checks if the hash of the seed we just read matches the hash given, meaning it is not encrypted
|
||||
//the use case for this is when not crypted, seed is set, then password set, the seed not yet crypted in memory
|
||||
if(hashSeed == Hash(seedRetrieved.begin(), seedRetrieved.end())) {
|
||||
seedOut = seedRetrieved;
|
||||
return true;
|
||||
}
|
||||
|
||||
CKeyingMaterial kmSeed;
|
||||
//attempt decrypt
|
||||
if (DecryptSecret(vMasterKey, vchCryptedSeed, hashSeed, kmSeed)) {
|
||||
seedOut = uint256(ReverseEndianString(HexStr(kmSeed)));
|
||||
return true;
|
||||
}
|
||||
strErr = "decrypt seed";
|
||||
} else { strErr = "read seed from wallet"; }
|
||||
} else { strErr = "read seed; wallet is locked"; }
|
||||
} else {
|
||||
vector<unsigned char> vchSeed;
|
||||
// wallet not crypted
|
||||
if (db.ReadZAGRSeed(hashSeed, vchSeed)) {
|
||||
seedOut = uint256(ReverseEndianString(HexStr(vchSeed)));
|
||||
return true;
|
||||
}
|
||||
strErr = "read seed from wallet";
|
||||
}
|
||||
|
||||
return error("%s: Failed to %s\n", __func__, strErr);
|
||||
|
||||
|
||||
// return error("Failed to decrypt deterministic seed %s", IsLocked() ? "Wallet is locked!" : "");
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Copyright (c) 2017-2018 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CRYPTER_H
|
||||
#define BITCOIN_CRYPTER_H
|
||||
|
||||
#include "allocators.h"
|
||||
#include "keystore.h"
|
||||
#include "serialize.h"
|
||||
|
||||
class uint256;
|
||||
|
||||
const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
|
||||
const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
|
||||
|
||||
/**
|
||||
* Private key encryption is done based on a CMasterKey,
|
||||
* which holds a salt and random encryption key.
|
||||
*
|
||||
* CMasterKeys are encrypted using AES-256-CBC using a key
|
||||
* derived using derivation method nDerivationMethod
|
||||
* (0 == EVP_sha512()) and derivation iterations nDeriveIterations.
|
||||
* vchOtherDerivationParameters is provided for alternative algorithms
|
||||
* which may require more parameters (such as scrypt).
|
||||
*
|
||||
* Wallet Private Keys are then encrypted using AES-256-CBC
|
||||
* with the double-sha256 of the public key as the IV, and the
|
||||
* master key's key as the encryption key (see keystore.[ch]).
|
||||
*/
|
||||
|
||||
/** Master key for wallet encryption */
|
||||
class CMasterKey
|
||||
{
|
||||
public:
|
||||
std::vector<unsigned char> vchCryptedKey;
|
||||
std::vector<unsigned char> vchSalt;
|
||||
//! 0 = EVP_sha512()
|
||||
//! 1 = scrypt()
|
||||
unsigned int nDerivationMethod;
|
||||
unsigned int nDeriveIterations;
|
||||
//! Use this for more parameters to key derivation,
|
||||
//! such as the various parameters to scrypt
|
||||
std::vector<unsigned char> vchOtherDerivationParameters;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(vchCryptedKey);
|
||||
READWRITE(vchSalt);
|
||||
READWRITE(nDerivationMethod);
|
||||
READWRITE(nDeriveIterations);
|
||||
READWRITE(vchOtherDerivationParameters);
|
||||
}
|
||||
|
||||
CMasterKey()
|
||||
{
|
||||
// 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
|
||||
// ie slightly lower than the lowest hardware we need bother supporting
|
||||
nDeriveIterations = 25000;
|
||||
nDerivationMethod = 0;
|
||||
vchOtherDerivationParameters = std::vector<unsigned char>(0);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
||||
|
||||
/** Encryption/decryption context with key information */
|
||||
class CCrypter
|
||||
{
|
||||
private:
|
||||
unsigned char chKey[WALLET_CRYPTO_KEY_SIZE];
|
||||
unsigned char chIV[WALLET_CRYPTO_KEY_SIZE];
|
||||
bool fKeySet;
|
||||
|
||||
public:
|
||||
bool SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
|
||||
bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char>& vchCiphertext);
|
||||
bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
|
||||
bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
|
||||
|
||||
void CleanKey()
|
||||
{
|
||||
memory_cleanse(chKey, sizeof(chKey));
|
||||
memory_cleanse(chIV, sizeof(chIV));
|
||||
fKeySet = false;
|
||||
}
|
||||
|
||||
CCrypter()
|
||||
{
|
||||
fKeySet = false;
|
||||
|
||||
// Try to keep the key data out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap)
|
||||
// Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
|
||||
// Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process.
|
||||
LockedPageManager::Instance().LockRange(&chKey[0], sizeof chKey);
|
||||
LockedPageManager::Instance().LockRange(&chIV[0], sizeof chIV);
|
||||
}
|
||||
|
||||
~CCrypter()
|
||||
{
|
||||
CleanKey();
|
||||
|
||||
LockedPageManager::Instance().UnlockRange(&chKey[0], sizeof chKey);
|
||||
LockedPageManager::Instance().UnlockRange(&chIV[0], sizeof chIV);
|
||||
}
|
||||
};
|
||||
|
||||
bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial& vchPlaintext, const uint256& nIV, std::vector<unsigned char>& vchCiphertext);
|
||||
bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
|
||||
|
||||
bool EncryptAES256(const SecureString& sKey, const SecureString& sPlaintext, const std::string& sIV, std::string& sCiphertext);
|
||||
bool DecryptAES256(const SecureString& sKey, const std::string& sCiphertext, const std::string& sIV, SecureString& sPlaintext);
|
||||
|
||||
|
||||
/** Keystore which keeps the private keys encrypted.
|
||||
* It derives from the basic key store, which is used if no encryption is active.
|
||||
*/
|
||||
class CCryptoKeyStore : public CBasicKeyStore
|
||||
{
|
||||
private:
|
||||
CryptedKeyMap mapCryptedKeys;
|
||||
|
||||
CKeyingMaterial vMasterKey;
|
||||
|
||||
//! if fUseCrypto is true, mapKeys must be empty
|
||||
//! if fUseCrypto is false, vMasterKey must be empty
|
||||
bool fUseCrypto;
|
||||
|
||||
//! keeps track of whether Unlock has run a thorough check before
|
||||
bool fDecryptionThoroughlyChecked;
|
||||
|
||||
protected:
|
||||
bool SetCrypted();
|
||||
|
||||
//! will encrypt previously unencrypted keys
|
||||
bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
|
||||
|
||||
bool Unlock(const CKeyingMaterial& vMasterKeyIn);
|
||||
|
||||
public:
|
||||
CCryptoKeyStore() : fUseCrypto(false), fDecryptionThoroughlyChecked(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsCrypted() const
|
||||
{
|
||||
return fUseCrypto;
|
||||
}
|
||||
|
||||
bool IsLocked() const
|
||||
{
|
||||
if (!IsCrypted())
|
||||
return false;
|
||||
bool result;
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
result = vMasterKey.empty();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Lock();
|
||||
|
||||
virtual bool AddCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret);
|
||||
bool AddKeyPubKey(const CKey& key, const CPubKey& pubkey);
|
||||
bool HaveKey(const CKeyID& address) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!IsCrypted())
|
||||
return CBasicKeyStore::HaveKey(address);
|
||||
return mapCryptedKeys.count(address) > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool GetKey(const CKeyID& address, CKey& keyOut) const;
|
||||
bool GetPubKey(const CKeyID& address, CPubKey& vchPubKeyOut) const;
|
||||
void GetKeys(std::set<CKeyID>& setAddress) const
|
||||
{
|
||||
if (!IsCrypted()) {
|
||||
CBasicKeyStore::GetKeys(setAddress);
|
||||
return;
|
||||
}
|
||||
setAddress.clear();
|
||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
||||
while (mi != mapCryptedKeys.end()) {
|
||||
setAddress.insert((*mi).first);
|
||||
mi++;
|
||||
}
|
||||
}
|
||||
|
||||
bool GetDeterministicSeed(const uint256& hashSeed, uint256& seed);
|
||||
bool AddDeterministicSeed(const uint256& seed);
|
||||
|
||||
|
||||
/**
|
||||
* Wallet status (encrypted, locked) changed.
|
||||
* Note: Called without locks held.
|
||||
*/
|
||||
boost::signals2::signal<void(CCryptoKeyStore* wallet)> NotifyStatusChanged;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_CRYPTER_H
|
||||
@@ -0,0 +1,392 @@
|
||||
/* $Id: aes_helper.c 220 2010-06-09 09:21:50Z tp $ */
|
||||
/*
|
||||
* AES tables. This file is not meant to be compiled by itself; it
|
||||
* is included by some hash function implementations. It contains
|
||||
* the precomputed tables and helper macros for evaluating an AES
|
||||
* round, optionally with a final XOR with a subkey.
|
||||
*
|
||||
* By default, this file defines the tables and macros for little-endian
|
||||
* processing (i.e. it is assumed that the input bytes have been read
|
||||
* from memory and assembled with the little-endian convention). If
|
||||
* the 'AES_BIG_ENDIAN' macro is defined (to a non-zero integer value)
|
||||
* when this file is included, then the tables and macros for big-endian
|
||||
* processing are defined instead. The big-endian tables and macros have
|
||||
* names distinct from the little-endian tables and macros, hence it is
|
||||
* possible to have both simultaneously, by including this file twice
|
||||
* (with and without the AES_BIG_ENDIAN macro).
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include "sph_types.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
#if AES_BIG_ENDIAN
|
||||
|
||||
#define AESx(x) ( ((SPH_C32(x) >> 24) & SPH_C32(0x000000FF)) \
|
||||
| ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) \
|
||||
| ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) \
|
||||
| ((SPH_C32(x) << 24) & SPH_C32(0xFF000000)))
|
||||
|
||||
#define AES0 AES0_BE
|
||||
#define AES1 AES1_BE
|
||||
#define AES2 AES2_BE
|
||||
#define AES3 AES3_BE
|
||||
|
||||
#define AES_ROUND_BE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3) do { \
|
||||
(Y0) = AES0[((X0) >> 24) & 0xFF] \
|
||||
^ AES1[((X1) >> 16) & 0xFF] \
|
||||
^ AES2[((X2) >> 8) & 0xFF] \
|
||||
^ AES3[(X3) & 0xFF] ^ (K0); \
|
||||
(Y1) = AES0[((X1) >> 24) & 0xFF] \
|
||||
^ AES1[((X2) >> 16) & 0xFF] \
|
||||
^ AES2[((X3) >> 8) & 0xFF] \
|
||||
^ AES3[(X0) & 0xFF] ^ (K1); \
|
||||
(Y2) = AES0[((X2) >> 24) & 0xFF] \
|
||||
^ AES1[((X3) >> 16) & 0xFF] \
|
||||
^ AES2[((X0) >> 8) & 0xFF] \
|
||||
^ AES3[(X1) & 0xFF] ^ (K2); \
|
||||
(Y3) = AES0[((X3) >> 24) & 0xFF] \
|
||||
^ AES1[((X0) >> 16) & 0xFF] \
|
||||
^ AES2[((X1) >> 8) & 0xFF] \
|
||||
^ AES3[(X2) & 0xFF] ^ (K3); \
|
||||
} while (0)
|
||||
|
||||
#define AES_ROUND_NOKEY_BE(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
|
||||
AES_ROUND_BE(X0, X1, X2, X3, 0, 0, 0, 0, Y0, Y1, Y2, Y3)
|
||||
|
||||
#else
|
||||
|
||||
#define AESx(x) SPH_C32(x)
|
||||
#define AES0 AES0_LE
|
||||
#define AES1 AES1_LE
|
||||
#define AES2 AES2_LE
|
||||
#define AES3 AES3_LE
|
||||
|
||||
#define AES_ROUND_LE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3) do { \
|
||||
(Y0) = AES0[(X0) & 0xFF] \
|
||||
^ AES1[((X1) >> 8) & 0xFF] \
|
||||
^ AES2[((X2) >> 16) & 0xFF] \
|
||||
^ AES3[((X3) >> 24) & 0xFF] ^ (K0); \
|
||||
(Y1) = AES0[(X1) & 0xFF] \
|
||||
^ AES1[((X2) >> 8) & 0xFF] \
|
||||
^ AES2[((X3) >> 16) & 0xFF] \
|
||||
^ AES3[((X0) >> 24) & 0xFF] ^ (K1); \
|
||||
(Y2) = AES0[(X2) & 0xFF] \
|
||||
^ AES1[((X3) >> 8) & 0xFF] \
|
||||
^ AES2[((X0) >> 16) & 0xFF] \
|
||||
^ AES3[((X1) >> 24) & 0xFF] ^ (K2); \
|
||||
(Y3) = AES0[(X3) & 0xFF] \
|
||||
^ AES1[((X0) >> 8) & 0xFF] \
|
||||
^ AES2[((X1) >> 16) & 0xFF] \
|
||||
^ AES3[((X2) >> 24) & 0xFF] ^ (K3); \
|
||||
} while (0)
|
||||
|
||||
#define AES_ROUND_NOKEY_LE(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
|
||||
AES_ROUND_LE(X0, X1, X2, X3, 0, 0, 0, 0, Y0, Y1, Y2, Y3)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The AES*[] tables allow us to perform a fast evaluation of an AES
|
||||
* round; table AESi[] combines SubBytes for a byte at row i, and
|
||||
* MixColumns for the column where that byte goes after ShiftRows.
|
||||
*/
|
||||
|
||||
static const sph_u32 AES0[256] = {
|
||||
AESx(0xA56363C6), AESx(0x847C7CF8), AESx(0x997777EE), AESx(0x8D7B7BF6),
|
||||
AESx(0x0DF2F2FF), AESx(0xBD6B6BD6), AESx(0xB16F6FDE), AESx(0x54C5C591),
|
||||
AESx(0x50303060), AESx(0x03010102), AESx(0xA96767CE), AESx(0x7D2B2B56),
|
||||
AESx(0x19FEFEE7), AESx(0x62D7D7B5), AESx(0xE6ABAB4D), AESx(0x9A7676EC),
|
||||
AESx(0x45CACA8F), AESx(0x9D82821F), AESx(0x40C9C989), AESx(0x877D7DFA),
|
||||
AESx(0x15FAFAEF), AESx(0xEB5959B2), AESx(0xC947478E), AESx(0x0BF0F0FB),
|
||||
AESx(0xECADAD41), AESx(0x67D4D4B3), AESx(0xFDA2A25F), AESx(0xEAAFAF45),
|
||||
AESx(0xBF9C9C23), AESx(0xF7A4A453), AESx(0x967272E4), AESx(0x5BC0C09B),
|
||||
AESx(0xC2B7B775), AESx(0x1CFDFDE1), AESx(0xAE93933D), AESx(0x6A26264C),
|
||||
AESx(0x5A36366C), AESx(0x413F3F7E), AESx(0x02F7F7F5), AESx(0x4FCCCC83),
|
||||
AESx(0x5C343468), AESx(0xF4A5A551), AESx(0x34E5E5D1), AESx(0x08F1F1F9),
|
||||
AESx(0x937171E2), AESx(0x73D8D8AB), AESx(0x53313162), AESx(0x3F15152A),
|
||||
AESx(0x0C040408), AESx(0x52C7C795), AESx(0x65232346), AESx(0x5EC3C39D),
|
||||
AESx(0x28181830), AESx(0xA1969637), AESx(0x0F05050A), AESx(0xB59A9A2F),
|
||||
AESx(0x0907070E), AESx(0x36121224), AESx(0x9B80801B), AESx(0x3DE2E2DF),
|
||||
AESx(0x26EBEBCD), AESx(0x6927274E), AESx(0xCDB2B27F), AESx(0x9F7575EA),
|
||||
AESx(0x1B090912), AESx(0x9E83831D), AESx(0x742C2C58), AESx(0x2E1A1A34),
|
||||
AESx(0x2D1B1B36), AESx(0xB26E6EDC), AESx(0xEE5A5AB4), AESx(0xFBA0A05B),
|
||||
AESx(0xF65252A4), AESx(0x4D3B3B76), AESx(0x61D6D6B7), AESx(0xCEB3B37D),
|
||||
AESx(0x7B292952), AESx(0x3EE3E3DD), AESx(0x712F2F5E), AESx(0x97848413),
|
||||
AESx(0xF55353A6), AESx(0x68D1D1B9), AESx(0x00000000), AESx(0x2CEDEDC1),
|
||||
AESx(0x60202040), AESx(0x1FFCFCE3), AESx(0xC8B1B179), AESx(0xED5B5BB6),
|
||||
AESx(0xBE6A6AD4), AESx(0x46CBCB8D), AESx(0xD9BEBE67), AESx(0x4B393972),
|
||||
AESx(0xDE4A4A94), AESx(0xD44C4C98), AESx(0xE85858B0), AESx(0x4ACFCF85),
|
||||
AESx(0x6BD0D0BB), AESx(0x2AEFEFC5), AESx(0xE5AAAA4F), AESx(0x16FBFBED),
|
||||
AESx(0xC5434386), AESx(0xD74D4D9A), AESx(0x55333366), AESx(0x94858511),
|
||||
AESx(0xCF45458A), AESx(0x10F9F9E9), AESx(0x06020204), AESx(0x817F7FFE),
|
||||
AESx(0xF05050A0), AESx(0x443C3C78), AESx(0xBA9F9F25), AESx(0xE3A8A84B),
|
||||
AESx(0xF35151A2), AESx(0xFEA3A35D), AESx(0xC0404080), AESx(0x8A8F8F05),
|
||||
AESx(0xAD92923F), AESx(0xBC9D9D21), AESx(0x48383870), AESx(0x04F5F5F1),
|
||||
AESx(0xDFBCBC63), AESx(0xC1B6B677), AESx(0x75DADAAF), AESx(0x63212142),
|
||||
AESx(0x30101020), AESx(0x1AFFFFE5), AESx(0x0EF3F3FD), AESx(0x6DD2D2BF),
|
||||
AESx(0x4CCDCD81), AESx(0x140C0C18), AESx(0x35131326), AESx(0x2FECECC3),
|
||||
AESx(0xE15F5FBE), AESx(0xA2979735), AESx(0xCC444488), AESx(0x3917172E),
|
||||
AESx(0x57C4C493), AESx(0xF2A7A755), AESx(0x827E7EFC), AESx(0x473D3D7A),
|
||||
AESx(0xAC6464C8), AESx(0xE75D5DBA), AESx(0x2B191932), AESx(0x957373E6),
|
||||
AESx(0xA06060C0), AESx(0x98818119), AESx(0xD14F4F9E), AESx(0x7FDCDCA3),
|
||||
AESx(0x66222244), AESx(0x7E2A2A54), AESx(0xAB90903B), AESx(0x8388880B),
|
||||
AESx(0xCA46468C), AESx(0x29EEEEC7), AESx(0xD3B8B86B), AESx(0x3C141428),
|
||||
AESx(0x79DEDEA7), AESx(0xE25E5EBC), AESx(0x1D0B0B16), AESx(0x76DBDBAD),
|
||||
AESx(0x3BE0E0DB), AESx(0x56323264), AESx(0x4E3A3A74), AESx(0x1E0A0A14),
|
||||
AESx(0xDB494992), AESx(0x0A06060C), AESx(0x6C242448), AESx(0xE45C5CB8),
|
||||
AESx(0x5DC2C29F), AESx(0x6ED3D3BD), AESx(0xEFACAC43), AESx(0xA66262C4),
|
||||
AESx(0xA8919139), AESx(0xA4959531), AESx(0x37E4E4D3), AESx(0x8B7979F2),
|
||||
AESx(0x32E7E7D5), AESx(0x43C8C88B), AESx(0x5937376E), AESx(0xB76D6DDA),
|
||||
AESx(0x8C8D8D01), AESx(0x64D5D5B1), AESx(0xD24E4E9C), AESx(0xE0A9A949),
|
||||
AESx(0xB46C6CD8), AESx(0xFA5656AC), AESx(0x07F4F4F3), AESx(0x25EAEACF),
|
||||
AESx(0xAF6565CA), AESx(0x8E7A7AF4), AESx(0xE9AEAE47), AESx(0x18080810),
|
||||
AESx(0xD5BABA6F), AESx(0x887878F0), AESx(0x6F25254A), AESx(0x722E2E5C),
|
||||
AESx(0x241C1C38), AESx(0xF1A6A657), AESx(0xC7B4B473), AESx(0x51C6C697),
|
||||
AESx(0x23E8E8CB), AESx(0x7CDDDDA1), AESx(0x9C7474E8), AESx(0x211F1F3E),
|
||||
AESx(0xDD4B4B96), AESx(0xDCBDBD61), AESx(0x868B8B0D), AESx(0x858A8A0F),
|
||||
AESx(0x907070E0), AESx(0x423E3E7C), AESx(0xC4B5B571), AESx(0xAA6666CC),
|
||||
AESx(0xD8484890), AESx(0x05030306), AESx(0x01F6F6F7), AESx(0x120E0E1C),
|
||||
AESx(0xA36161C2), AESx(0x5F35356A), AESx(0xF95757AE), AESx(0xD0B9B969),
|
||||
AESx(0x91868617), AESx(0x58C1C199), AESx(0x271D1D3A), AESx(0xB99E9E27),
|
||||
AESx(0x38E1E1D9), AESx(0x13F8F8EB), AESx(0xB398982B), AESx(0x33111122),
|
||||
AESx(0xBB6969D2), AESx(0x70D9D9A9), AESx(0x898E8E07), AESx(0xA7949433),
|
||||
AESx(0xB69B9B2D), AESx(0x221E1E3C), AESx(0x92878715), AESx(0x20E9E9C9),
|
||||
AESx(0x49CECE87), AESx(0xFF5555AA), AESx(0x78282850), AESx(0x7ADFDFA5),
|
||||
AESx(0x8F8C8C03), AESx(0xF8A1A159), AESx(0x80898909), AESx(0x170D0D1A),
|
||||
AESx(0xDABFBF65), AESx(0x31E6E6D7), AESx(0xC6424284), AESx(0xB86868D0),
|
||||
AESx(0xC3414182), AESx(0xB0999929), AESx(0x772D2D5A), AESx(0x110F0F1E),
|
||||
AESx(0xCBB0B07B), AESx(0xFC5454A8), AESx(0xD6BBBB6D), AESx(0x3A16162C)
|
||||
};
|
||||
|
||||
static const sph_u32 AES1[256] = {
|
||||
AESx(0x6363C6A5), AESx(0x7C7CF884), AESx(0x7777EE99), AESx(0x7B7BF68D),
|
||||
AESx(0xF2F2FF0D), AESx(0x6B6BD6BD), AESx(0x6F6FDEB1), AESx(0xC5C59154),
|
||||
AESx(0x30306050), AESx(0x01010203), AESx(0x6767CEA9), AESx(0x2B2B567D),
|
||||
AESx(0xFEFEE719), AESx(0xD7D7B562), AESx(0xABAB4DE6), AESx(0x7676EC9A),
|
||||
AESx(0xCACA8F45), AESx(0x82821F9D), AESx(0xC9C98940), AESx(0x7D7DFA87),
|
||||
AESx(0xFAFAEF15), AESx(0x5959B2EB), AESx(0x47478EC9), AESx(0xF0F0FB0B),
|
||||
AESx(0xADAD41EC), AESx(0xD4D4B367), AESx(0xA2A25FFD), AESx(0xAFAF45EA),
|
||||
AESx(0x9C9C23BF), AESx(0xA4A453F7), AESx(0x7272E496), AESx(0xC0C09B5B),
|
||||
AESx(0xB7B775C2), AESx(0xFDFDE11C), AESx(0x93933DAE), AESx(0x26264C6A),
|
||||
AESx(0x36366C5A), AESx(0x3F3F7E41), AESx(0xF7F7F502), AESx(0xCCCC834F),
|
||||
AESx(0x3434685C), AESx(0xA5A551F4), AESx(0xE5E5D134), AESx(0xF1F1F908),
|
||||
AESx(0x7171E293), AESx(0xD8D8AB73), AESx(0x31316253), AESx(0x15152A3F),
|
||||
AESx(0x0404080C), AESx(0xC7C79552), AESx(0x23234665), AESx(0xC3C39D5E),
|
||||
AESx(0x18183028), AESx(0x969637A1), AESx(0x05050A0F), AESx(0x9A9A2FB5),
|
||||
AESx(0x07070E09), AESx(0x12122436), AESx(0x80801B9B), AESx(0xE2E2DF3D),
|
||||
AESx(0xEBEBCD26), AESx(0x27274E69), AESx(0xB2B27FCD), AESx(0x7575EA9F),
|
||||
AESx(0x0909121B), AESx(0x83831D9E), AESx(0x2C2C5874), AESx(0x1A1A342E),
|
||||
AESx(0x1B1B362D), AESx(0x6E6EDCB2), AESx(0x5A5AB4EE), AESx(0xA0A05BFB),
|
||||
AESx(0x5252A4F6), AESx(0x3B3B764D), AESx(0xD6D6B761), AESx(0xB3B37DCE),
|
||||
AESx(0x2929527B), AESx(0xE3E3DD3E), AESx(0x2F2F5E71), AESx(0x84841397),
|
||||
AESx(0x5353A6F5), AESx(0xD1D1B968), AESx(0x00000000), AESx(0xEDEDC12C),
|
||||
AESx(0x20204060), AESx(0xFCFCE31F), AESx(0xB1B179C8), AESx(0x5B5BB6ED),
|
||||
AESx(0x6A6AD4BE), AESx(0xCBCB8D46), AESx(0xBEBE67D9), AESx(0x3939724B),
|
||||
AESx(0x4A4A94DE), AESx(0x4C4C98D4), AESx(0x5858B0E8), AESx(0xCFCF854A),
|
||||
AESx(0xD0D0BB6B), AESx(0xEFEFC52A), AESx(0xAAAA4FE5), AESx(0xFBFBED16),
|
||||
AESx(0x434386C5), AESx(0x4D4D9AD7), AESx(0x33336655), AESx(0x85851194),
|
||||
AESx(0x45458ACF), AESx(0xF9F9E910), AESx(0x02020406), AESx(0x7F7FFE81),
|
||||
AESx(0x5050A0F0), AESx(0x3C3C7844), AESx(0x9F9F25BA), AESx(0xA8A84BE3),
|
||||
AESx(0x5151A2F3), AESx(0xA3A35DFE), AESx(0x404080C0), AESx(0x8F8F058A),
|
||||
AESx(0x92923FAD), AESx(0x9D9D21BC), AESx(0x38387048), AESx(0xF5F5F104),
|
||||
AESx(0xBCBC63DF), AESx(0xB6B677C1), AESx(0xDADAAF75), AESx(0x21214263),
|
||||
AESx(0x10102030), AESx(0xFFFFE51A), AESx(0xF3F3FD0E), AESx(0xD2D2BF6D),
|
||||
AESx(0xCDCD814C), AESx(0x0C0C1814), AESx(0x13132635), AESx(0xECECC32F),
|
||||
AESx(0x5F5FBEE1), AESx(0x979735A2), AESx(0x444488CC), AESx(0x17172E39),
|
||||
AESx(0xC4C49357), AESx(0xA7A755F2), AESx(0x7E7EFC82), AESx(0x3D3D7A47),
|
||||
AESx(0x6464C8AC), AESx(0x5D5DBAE7), AESx(0x1919322B), AESx(0x7373E695),
|
||||
AESx(0x6060C0A0), AESx(0x81811998), AESx(0x4F4F9ED1), AESx(0xDCDCA37F),
|
||||
AESx(0x22224466), AESx(0x2A2A547E), AESx(0x90903BAB), AESx(0x88880B83),
|
||||
AESx(0x46468CCA), AESx(0xEEEEC729), AESx(0xB8B86BD3), AESx(0x1414283C),
|
||||
AESx(0xDEDEA779), AESx(0x5E5EBCE2), AESx(0x0B0B161D), AESx(0xDBDBAD76),
|
||||
AESx(0xE0E0DB3B), AESx(0x32326456), AESx(0x3A3A744E), AESx(0x0A0A141E),
|
||||
AESx(0x494992DB), AESx(0x06060C0A), AESx(0x2424486C), AESx(0x5C5CB8E4),
|
||||
AESx(0xC2C29F5D), AESx(0xD3D3BD6E), AESx(0xACAC43EF), AESx(0x6262C4A6),
|
||||
AESx(0x919139A8), AESx(0x959531A4), AESx(0xE4E4D337), AESx(0x7979F28B),
|
||||
AESx(0xE7E7D532), AESx(0xC8C88B43), AESx(0x37376E59), AESx(0x6D6DDAB7),
|
||||
AESx(0x8D8D018C), AESx(0xD5D5B164), AESx(0x4E4E9CD2), AESx(0xA9A949E0),
|
||||
AESx(0x6C6CD8B4), AESx(0x5656ACFA), AESx(0xF4F4F307), AESx(0xEAEACF25),
|
||||
AESx(0x6565CAAF), AESx(0x7A7AF48E), AESx(0xAEAE47E9), AESx(0x08081018),
|
||||
AESx(0xBABA6FD5), AESx(0x7878F088), AESx(0x25254A6F), AESx(0x2E2E5C72),
|
||||
AESx(0x1C1C3824), AESx(0xA6A657F1), AESx(0xB4B473C7), AESx(0xC6C69751),
|
||||
AESx(0xE8E8CB23), AESx(0xDDDDA17C), AESx(0x7474E89C), AESx(0x1F1F3E21),
|
||||
AESx(0x4B4B96DD), AESx(0xBDBD61DC), AESx(0x8B8B0D86), AESx(0x8A8A0F85),
|
||||
AESx(0x7070E090), AESx(0x3E3E7C42), AESx(0xB5B571C4), AESx(0x6666CCAA),
|
||||
AESx(0x484890D8), AESx(0x03030605), AESx(0xF6F6F701), AESx(0x0E0E1C12),
|
||||
AESx(0x6161C2A3), AESx(0x35356A5F), AESx(0x5757AEF9), AESx(0xB9B969D0),
|
||||
AESx(0x86861791), AESx(0xC1C19958), AESx(0x1D1D3A27), AESx(0x9E9E27B9),
|
||||
AESx(0xE1E1D938), AESx(0xF8F8EB13), AESx(0x98982BB3), AESx(0x11112233),
|
||||
AESx(0x6969D2BB), AESx(0xD9D9A970), AESx(0x8E8E0789), AESx(0x949433A7),
|
||||
AESx(0x9B9B2DB6), AESx(0x1E1E3C22), AESx(0x87871592), AESx(0xE9E9C920),
|
||||
AESx(0xCECE8749), AESx(0x5555AAFF), AESx(0x28285078), AESx(0xDFDFA57A),
|
||||
AESx(0x8C8C038F), AESx(0xA1A159F8), AESx(0x89890980), AESx(0x0D0D1A17),
|
||||
AESx(0xBFBF65DA), AESx(0xE6E6D731), AESx(0x424284C6), AESx(0x6868D0B8),
|
||||
AESx(0x414182C3), AESx(0x999929B0), AESx(0x2D2D5A77), AESx(0x0F0F1E11),
|
||||
AESx(0xB0B07BCB), AESx(0x5454A8FC), AESx(0xBBBB6DD6), AESx(0x16162C3A)
|
||||
};
|
||||
|
||||
static const sph_u32 AES2[256] = {
|
||||
AESx(0x63C6A563), AESx(0x7CF8847C), AESx(0x77EE9977), AESx(0x7BF68D7B),
|
||||
AESx(0xF2FF0DF2), AESx(0x6BD6BD6B), AESx(0x6FDEB16F), AESx(0xC59154C5),
|
||||
AESx(0x30605030), AESx(0x01020301), AESx(0x67CEA967), AESx(0x2B567D2B),
|
||||
AESx(0xFEE719FE), AESx(0xD7B562D7), AESx(0xAB4DE6AB), AESx(0x76EC9A76),
|
||||
AESx(0xCA8F45CA), AESx(0x821F9D82), AESx(0xC98940C9), AESx(0x7DFA877D),
|
||||
AESx(0xFAEF15FA), AESx(0x59B2EB59), AESx(0x478EC947), AESx(0xF0FB0BF0),
|
||||
AESx(0xAD41ECAD), AESx(0xD4B367D4), AESx(0xA25FFDA2), AESx(0xAF45EAAF),
|
||||
AESx(0x9C23BF9C), AESx(0xA453F7A4), AESx(0x72E49672), AESx(0xC09B5BC0),
|
||||
AESx(0xB775C2B7), AESx(0xFDE11CFD), AESx(0x933DAE93), AESx(0x264C6A26),
|
||||
AESx(0x366C5A36), AESx(0x3F7E413F), AESx(0xF7F502F7), AESx(0xCC834FCC),
|
||||
AESx(0x34685C34), AESx(0xA551F4A5), AESx(0xE5D134E5), AESx(0xF1F908F1),
|
||||
AESx(0x71E29371), AESx(0xD8AB73D8), AESx(0x31625331), AESx(0x152A3F15),
|
||||
AESx(0x04080C04), AESx(0xC79552C7), AESx(0x23466523), AESx(0xC39D5EC3),
|
||||
AESx(0x18302818), AESx(0x9637A196), AESx(0x050A0F05), AESx(0x9A2FB59A),
|
||||
AESx(0x070E0907), AESx(0x12243612), AESx(0x801B9B80), AESx(0xE2DF3DE2),
|
||||
AESx(0xEBCD26EB), AESx(0x274E6927), AESx(0xB27FCDB2), AESx(0x75EA9F75),
|
||||
AESx(0x09121B09), AESx(0x831D9E83), AESx(0x2C58742C), AESx(0x1A342E1A),
|
||||
AESx(0x1B362D1B), AESx(0x6EDCB26E), AESx(0x5AB4EE5A), AESx(0xA05BFBA0),
|
||||
AESx(0x52A4F652), AESx(0x3B764D3B), AESx(0xD6B761D6), AESx(0xB37DCEB3),
|
||||
AESx(0x29527B29), AESx(0xE3DD3EE3), AESx(0x2F5E712F), AESx(0x84139784),
|
||||
AESx(0x53A6F553), AESx(0xD1B968D1), AESx(0x00000000), AESx(0xEDC12CED),
|
||||
AESx(0x20406020), AESx(0xFCE31FFC), AESx(0xB179C8B1), AESx(0x5BB6ED5B),
|
||||
AESx(0x6AD4BE6A), AESx(0xCB8D46CB), AESx(0xBE67D9BE), AESx(0x39724B39),
|
||||
AESx(0x4A94DE4A), AESx(0x4C98D44C), AESx(0x58B0E858), AESx(0xCF854ACF),
|
||||
AESx(0xD0BB6BD0), AESx(0xEFC52AEF), AESx(0xAA4FE5AA), AESx(0xFBED16FB),
|
||||
AESx(0x4386C543), AESx(0x4D9AD74D), AESx(0x33665533), AESx(0x85119485),
|
||||
AESx(0x458ACF45), AESx(0xF9E910F9), AESx(0x02040602), AESx(0x7FFE817F),
|
||||
AESx(0x50A0F050), AESx(0x3C78443C), AESx(0x9F25BA9F), AESx(0xA84BE3A8),
|
||||
AESx(0x51A2F351), AESx(0xA35DFEA3), AESx(0x4080C040), AESx(0x8F058A8F),
|
||||
AESx(0x923FAD92), AESx(0x9D21BC9D), AESx(0x38704838), AESx(0xF5F104F5),
|
||||
AESx(0xBC63DFBC), AESx(0xB677C1B6), AESx(0xDAAF75DA), AESx(0x21426321),
|
||||
AESx(0x10203010), AESx(0xFFE51AFF), AESx(0xF3FD0EF3), AESx(0xD2BF6DD2),
|
||||
AESx(0xCD814CCD), AESx(0x0C18140C), AESx(0x13263513), AESx(0xECC32FEC),
|
||||
AESx(0x5FBEE15F), AESx(0x9735A297), AESx(0x4488CC44), AESx(0x172E3917),
|
||||
AESx(0xC49357C4), AESx(0xA755F2A7), AESx(0x7EFC827E), AESx(0x3D7A473D),
|
||||
AESx(0x64C8AC64), AESx(0x5DBAE75D), AESx(0x19322B19), AESx(0x73E69573),
|
||||
AESx(0x60C0A060), AESx(0x81199881), AESx(0x4F9ED14F), AESx(0xDCA37FDC),
|
||||
AESx(0x22446622), AESx(0x2A547E2A), AESx(0x903BAB90), AESx(0x880B8388),
|
||||
AESx(0x468CCA46), AESx(0xEEC729EE), AESx(0xB86BD3B8), AESx(0x14283C14),
|
||||
AESx(0xDEA779DE), AESx(0x5EBCE25E), AESx(0x0B161D0B), AESx(0xDBAD76DB),
|
||||
AESx(0xE0DB3BE0), AESx(0x32645632), AESx(0x3A744E3A), AESx(0x0A141E0A),
|
||||
AESx(0x4992DB49), AESx(0x060C0A06), AESx(0x24486C24), AESx(0x5CB8E45C),
|
||||
AESx(0xC29F5DC2), AESx(0xD3BD6ED3), AESx(0xAC43EFAC), AESx(0x62C4A662),
|
||||
AESx(0x9139A891), AESx(0x9531A495), AESx(0xE4D337E4), AESx(0x79F28B79),
|
||||
AESx(0xE7D532E7), AESx(0xC88B43C8), AESx(0x376E5937), AESx(0x6DDAB76D),
|
||||
AESx(0x8D018C8D), AESx(0xD5B164D5), AESx(0x4E9CD24E), AESx(0xA949E0A9),
|
||||
AESx(0x6CD8B46C), AESx(0x56ACFA56), AESx(0xF4F307F4), AESx(0xEACF25EA),
|
||||
AESx(0x65CAAF65), AESx(0x7AF48E7A), AESx(0xAE47E9AE), AESx(0x08101808),
|
||||
AESx(0xBA6FD5BA), AESx(0x78F08878), AESx(0x254A6F25), AESx(0x2E5C722E),
|
||||
AESx(0x1C38241C), AESx(0xA657F1A6), AESx(0xB473C7B4), AESx(0xC69751C6),
|
||||
AESx(0xE8CB23E8), AESx(0xDDA17CDD), AESx(0x74E89C74), AESx(0x1F3E211F),
|
||||
AESx(0x4B96DD4B), AESx(0xBD61DCBD), AESx(0x8B0D868B), AESx(0x8A0F858A),
|
||||
AESx(0x70E09070), AESx(0x3E7C423E), AESx(0xB571C4B5), AESx(0x66CCAA66),
|
||||
AESx(0x4890D848), AESx(0x03060503), AESx(0xF6F701F6), AESx(0x0E1C120E),
|
||||
AESx(0x61C2A361), AESx(0x356A5F35), AESx(0x57AEF957), AESx(0xB969D0B9),
|
||||
AESx(0x86179186), AESx(0xC19958C1), AESx(0x1D3A271D), AESx(0x9E27B99E),
|
||||
AESx(0xE1D938E1), AESx(0xF8EB13F8), AESx(0x982BB398), AESx(0x11223311),
|
||||
AESx(0x69D2BB69), AESx(0xD9A970D9), AESx(0x8E07898E), AESx(0x9433A794),
|
||||
AESx(0x9B2DB69B), AESx(0x1E3C221E), AESx(0x87159287), AESx(0xE9C920E9),
|
||||
AESx(0xCE8749CE), AESx(0x55AAFF55), AESx(0x28507828), AESx(0xDFA57ADF),
|
||||
AESx(0x8C038F8C), AESx(0xA159F8A1), AESx(0x89098089), AESx(0x0D1A170D),
|
||||
AESx(0xBF65DABF), AESx(0xE6D731E6), AESx(0x4284C642), AESx(0x68D0B868),
|
||||
AESx(0x4182C341), AESx(0x9929B099), AESx(0x2D5A772D), AESx(0x0F1E110F),
|
||||
AESx(0xB07BCBB0), AESx(0x54A8FC54), AESx(0xBB6DD6BB), AESx(0x162C3A16)
|
||||
};
|
||||
|
||||
static const sph_u32 AES3[256] = {
|
||||
AESx(0xC6A56363), AESx(0xF8847C7C), AESx(0xEE997777), AESx(0xF68D7B7B),
|
||||
AESx(0xFF0DF2F2), AESx(0xD6BD6B6B), AESx(0xDEB16F6F), AESx(0x9154C5C5),
|
||||
AESx(0x60503030), AESx(0x02030101), AESx(0xCEA96767), AESx(0x567D2B2B),
|
||||
AESx(0xE719FEFE), AESx(0xB562D7D7), AESx(0x4DE6ABAB), AESx(0xEC9A7676),
|
||||
AESx(0x8F45CACA), AESx(0x1F9D8282), AESx(0x8940C9C9), AESx(0xFA877D7D),
|
||||
AESx(0xEF15FAFA), AESx(0xB2EB5959), AESx(0x8EC94747), AESx(0xFB0BF0F0),
|
||||
AESx(0x41ECADAD), AESx(0xB367D4D4), AESx(0x5FFDA2A2), AESx(0x45EAAFAF),
|
||||
AESx(0x23BF9C9C), AESx(0x53F7A4A4), AESx(0xE4967272), AESx(0x9B5BC0C0),
|
||||
AESx(0x75C2B7B7), AESx(0xE11CFDFD), AESx(0x3DAE9393), AESx(0x4C6A2626),
|
||||
AESx(0x6C5A3636), AESx(0x7E413F3F), AESx(0xF502F7F7), AESx(0x834FCCCC),
|
||||
AESx(0x685C3434), AESx(0x51F4A5A5), AESx(0xD134E5E5), AESx(0xF908F1F1),
|
||||
AESx(0xE2937171), AESx(0xAB73D8D8), AESx(0x62533131), AESx(0x2A3F1515),
|
||||
AESx(0x080C0404), AESx(0x9552C7C7), AESx(0x46652323), AESx(0x9D5EC3C3),
|
||||
AESx(0x30281818), AESx(0x37A19696), AESx(0x0A0F0505), AESx(0x2FB59A9A),
|
||||
AESx(0x0E090707), AESx(0x24361212), AESx(0x1B9B8080), AESx(0xDF3DE2E2),
|
||||
AESx(0xCD26EBEB), AESx(0x4E692727), AESx(0x7FCDB2B2), AESx(0xEA9F7575),
|
||||
AESx(0x121B0909), AESx(0x1D9E8383), AESx(0x58742C2C), AESx(0x342E1A1A),
|
||||
AESx(0x362D1B1B), AESx(0xDCB26E6E), AESx(0xB4EE5A5A), AESx(0x5BFBA0A0),
|
||||
AESx(0xA4F65252), AESx(0x764D3B3B), AESx(0xB761D6D6), AESx(0x7DCEB3B3),
|
||||
AESx(0x527B2929), AESx(0xDD3EE3E3), AESx(0x5E712F2F), AESx(0x13978484),
|
||||
AESx(0xA6F55353), AESx(0xB968D1D1), AESx(0x00000000), AESx(0xC12CEDED),
|
||||
AESx(0x40602020), AESx(0xE31FFCFC), AESx(0x79C8B1B1), AESx(0xB6ED5B5B),
|
||||
AESx(0xD4BE6A6A), AESx(0x8D46CBCB), AESx(0x67D9BEBE), AESx(0x724B3939),
|
||||
AESx(0x94DE4A4A), AESx(0x98D44C4C), AESx(0xB0E85858), AESx(0x854ACFCF),
|
||||
AESx(0xBB6BD0D0), AESx(0xC52AEFEF), AESx(0x4FE5AAAA), AESx(0xED16FBFB),
|
||||
AESx(0x86C54343), AESx(0x9AD74D4D), AESx(0x66553333), AESx(0x11948585),
|
||||
AESx(0x8ACF4545), AESx(0xE910F9F9), AESx(0x04060202), AESx(0xFE817F7F),
|
||||
AESx(0xA0F05050), AESx(0x78443C3C), AESx(0x25BA9F9F), AESx(0x4BE3A8A8),
|
||||
AESx(0xA2F35151), AESx(0x5DFEA3A3), AESx(0x80C04040), AESx(0x058A8F8F),
|
||||
AESx(0x3FAD9292), AESx(0x21BC9D9D), AESx(0x70483838), AESx(0xF104F5F5),
|
||||
AESx(0x63DFBCBC), AESx(0x77C1B6B6), AESx(0xAF75DADA), AESx(0x42632121),
|
||||
AESx(0x20301010), AESx(0xE51AFFFF), AESx(0xFD0EF3F3), AESx(0xBF6DD2D2),
|
||||
AESx(0x814CCDCD), AESx(0x18140C0C), AESx(0x26351313), AESx(0xC32FECEC),
|
||||
AESx(0xBEE15F5F), AESx(0x35A29797), AESx(0x88CC4444), AESx(0x2E391717),
|
||||
AESx(0x9357C4C4), AESx(0x55F2A7A7), AESx(0xFC827E7E), AESx(0x7A473D3D),
|
||||
AESx(0xC8AC6464), AESx(0xBAE75D5D), AESx(0x322B1919), AESx(0xE6957373),
|
||||
AESx(0xC0A06060), AESx(0x19988181), AESx(0x9ED14F4F), AESx(0xA37FDCDC),
|
||||
AESx(0x44662222), AESx(0x547E2A2A), AESx(0x3BAB9090), AESx(0x0B838888),
|
||||
AESx(0x8CCA4646), AESx(0xC729EEEE), AESx(0x6BD3B8B8), AESx(0x283C1414),
|
||||
AESx(0xA779DEDE), AESx(0xBCE25E5E), AESx(0x161D0B0B), AESx(0xAD76DBDB),
|
||||
AESx(0xDB3BE0E0), AESx(0x64563232), AESx(0x744E3A3A), AESx(0x141E0A0A),
|
||||
AESx(0x92DB4949), AESx(0x0C0A0606), AESx(0x486C2424), AESx(0xB8E45C5C),
|
||||
AESx(0x9F5DC2C2), AESx(0xBD6ED3D3), AESx(0x43EFACAC), AESx(0xC4A66262),
|
||||
AESx(0x39A89191), AESx(0x31A49595), AESx(0xD337E4E4), AESx(0xF28B7979),
|
||||
AESx(0xD532E7E7), AESx(0x8B43C8C8), AESx(0x6E593737), AESx(0xDAB76D6D),
|
||||
AESx(0x018C8D8D), AESx(0xB164D5D5), AESx(0x9CD24E4E), AESx(0x49E0A9A9),
|
||||
AESx(0xD8B46C6C), AESx(0xACFA5656), AESx(0xF307F4F4), AESx(0xCF25EAEA),
|
||||
AESx(0xCAAF6565), AESx(0xF48E7A7A), AESx(0x47E9AEAE), AESx(0x10180808),
|
||||
AESx(0x6FD5BABA), AESx(0xF0887878), AESx(0x4A6F2525), AESx(0x5C722E2E),
|
||||
AESx(0x38241C1C), AESx(0x57F1A6A6), AESx(0x73C7B4B4), AESx(0x9751C6C6),
|
||||
AESx(0xCB23E8E8), AESx(0xA17CDDDD), AESx(0xE89C7474), AESx(0x3E211F1F),
|
||||
AESx(0x96DD4B4B), AESx(0x61DCBDBD), AESx(0x0D868B8B), AESx(0x0F858A8A),
|
||||
AESx(0xE0907070), AESx(0x7C423E3E), AESx(0x71C4B5B5), AESx(0xCCAA6666),
|
||||
AESx(0x90D84848), AESx(0x06050303), AESx(0xF701F6F6), AESx(0x1C120E0E),
|
||||
AESx(0xC2A36161), AESx(0x6A5F3535), AESx(0xAEF95757), AESx(0x69D0B9B9),
|
||||
AESx(0x17918686), AESx(0x9958C1C1), AESx(0x3A271D1D), AESx(0x27B99E9E),
|
||||
AESx(0xD938E1E1), AESx(0xEB13F8F8), AESx(0x2BB39898), AESx(0x22331111),
|
||||
AESx(0xD2BB6969), AESx(0xA970D9D9), AESx(0x07898E8E), AESx(0x33A79494),
|
||||
AESx(0x2DB69B9B), AESx(0x3C221E1E), AESx(0x15928787), AESx(0xC920E9E9),
|
||||
AESx(0x8749CECE), AESx(0xAAFF5555), AESx(0x50782828), AESx(0xA57ADFDF),
|
||||
AESx(0x038F8C8C), AESx(0x59F8A1A1), AESx(0x09808989), AESx(0x1A170D0D),
|
||||
AESx(0x65DABFBF), AESx(0xD731E6E6), AESx(0x84C64242), AESx(0xD0B86868),
|
||||
AESx(0x82C34141), AESx(0x29B09999), AESx(0x5A772D2D), AESx(0x1E110F0F),
|
||||
AESx(0x7BCBB0B0), AESx(0xA8FC5454), AESx(0x6DD6BBBB), AESx(0x2C3A1616)
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+1120
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,965 @@
|
||||
/* $Id: bmw.c 227 2010-06-16 17:28:38Z tp $ */
|
||||
/*
|
||||
* BMW implementation.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include "sph_bmw.h"
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_BMW
|
||||
#define SPH_SMALL_FOOTPRINT_BMW 1
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4146)
|
||||
#endif
|
||||
|
||||
static const sph_u32 IV224[] = {
|
||||
SPH_C32(0x00010203), SPH_C32(0x04050607),
|
||||
SPH_C32(0x08090A0B), SPH_C32(0x0C0D0E0F),
|
||||
SPH_C32(0x10111213), SPH_C32(0x14151617),
|
||||
SPH_C32(0x18191A1B), SPH_C32(0x1C1D1E1F),
|
||||
SPH_C32(0x20212223), SPH_C32(0x24252627),
|
||||
SPH_C32(0x28292A2B), SPH_C32(0x2C2D2E2F),
|
||||
SPH_C32(0x30313233), SPH_C32(0x34353637),
|
||||
SPH_C32(0x38393A3B), SPH_C32(0x3C3D3E3F)
|
||||
};
|
||||
|
||||
static const sph_u32 IV256[] = {
|
||||
SPH_C32(0x40414243), SPH_C32(0x44454647),
|
||||
SPH_C32(0x48494A4B), SPH_C32(0x4C4D4E4F),
|
||||
SPH_C32(0x50515253), SPH_C32(0x54555657),
|
||||
SPH_C32(0x58595A5B), SPH_C32(0x5C5D5E5F),
|
||||
SPH_C32(0x60616263), SPH_C32(0x64656667),
|
||||
SPH_C32(0x68696A6B), SPH_C32(0x6C6D6E6F),
|
||||
SPH_C32(0x70717273), SPH_C32(0x74757677),
|
||||
SPH_C32(0x78797A7B), SPH_C32(0x7C7D7E7F)
|
||||
};
|
||||
|
||||
#if SPH_64
|
||||
|
||||
static const sph_u64 IV384[] = {
|
||||
SPH_C64(0x0001020304050607), SPH_C64(0x08090A0B0C0D0E0F),
|
||||
SPH_C64(0x1011121314151617), SPH_C64(0x18191A1B1C1D1E1F),
|
||||
SPH_C64(0x2021222324252627), SPH_C64(0x28292A2B2C2D2E2F),
|
||||
SPH_C64(0x3031323334353637), SPH_C64(0x38393A3B3C3D3E3F),
|
||||
SPH_C64(0x4041424344454647), SPH_C64(0x48494A4B4C4D4E4F),
|
||||
SPH_C64(0x5051525354555657), SPH_C64(0x58595A5B5C5D5E5F),
|
||||
SPH_C64(0x6061626364656667), SPH_C64(0x68696A6B6C6D6E6F),
|
||||
SPH_C64(0x7071727374757677), SPH_C64(0x78797A7B7C7D7E7F)
|
||||
};
|
||||
|
||||
static const sph_u64 IV512[] = {
|
||||
SPH_C64(0x8081828384858687), SPH_C64(0x88898A8B8C8D8E8F),
|
||||
SPH_C64(0x9091929394959697), SPH_C64(0x98999A9B9C9D9E9F),
|
||||
SPH_C64(0xA0A1A2A3A4A5A6A7), SPH_C64(0xA8A9AAABACADAEAF),
|
||||
SPH_C64(0xB0B1B2B3B4B5B6B7), SPH_C64(0xB8B9BABBBCBDBEBF),
|
||||
SPH_C64(0xC0C1C2C3C4C5C6C7), SPH_C64(0xC8C9CACBCCCDCECF),
|
||||
SPH_C64(0xD0D1D2D3D4D5D6D7), SPH_C64(0xD8D9DADBDCDDDEDF),
|
||||
SPH_C64(0xE0E1E2E3E4E5E6E7), SPH_C64(0xE8E9EAEBECEDEEEF),
|
||||
SPH_C64(0xF0F1F2F3F4F5F6F7), SPH_C64(0xF8F9FAFBFCFDFEFF)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#define XCAT(x, y) XCAT_(x, y)
|
||||
#define XCAT_(x, y) x ## y
|
||||
|
||||
#define LPAR (
|
||||
|
||||
#define I16_16 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
#define I16_17 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
|
||||
#define I16_18 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
|
||||
#define I16_19 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18
|
||||
#define I16_20 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
|
||||
#define I16_21 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
|
||||
#define I16_22 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
|
||||
#define I16_23 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
|
||||
#define I16_24 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
|
||||
#define I16_25 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
|
||||
#define I16_26 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25
|
||||
#define I16_27 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26
|
||||
#define I16_28 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
|
||||
#define I16_29 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28
|
||||
#define I16_30 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
|
||||
#define I16_31 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
|
||||
|
||||
#define M16_16 0, 1, 3, 4, 7, 10, 11
|
||||
#define M16_17 1, 2, 4, 5, 8, 11, 12
|
||||
#define M16_18 2, 3, 5, 6, 9, 12, 13
|
||||
#define M16_19 3, 4, 6, 7, 10, 13, 14
|
||||
#define M16_20 4, 5, 7, 8, 11, 14, 15
|
||||
#define M16_21 5, 6, 8, 9, 12, 15, 16
|
||||
#define M16_22 6, 7, 9, 10, 13, 0, 1
|
||||
#define M16_23 7, 8, 10, 11, 14, 1, 2
|
||||
#define M16_24 8, 9, 11, 12, 15, 2, 3
|
||||
#define M16_25 9, 10, 12, 13, 0, 3, 4
|
||||
#define M16_26 10, 11, 13, 14, 1, 4, 5
|
||||
#define M16_27 11, 12, 14, 15, 2, 5, 6
|
||||
#define M16_28 12, 13, 15, 16, 3, 6, 7
|
||||
#define M16_29 13, 14, 0, 1, 4, 7, 8
|
||||
#define M16_30 14, 15, 1, 2, 5, 8, 9
|
||||
#define M16_31 15, 16, 2, 3, 6, 9, 10
|
||||
|
||||
#define ss0(x) (((x) >> 1) ^ SPH_T32((x) << 3) \
|
||||
^ SPH_ROTL32(x, 4) ^ SPH_ROTL32(x, 19))
|
||||
#define ss1(x) (((x) >> 1) ^ SPH_T32((x) << 2) \
|
||||
^ SPH_ROTL32(x, 8) ^ SPH_ROTL32(x, 23))
|
||||
#define ss2(x) (((x) >> 2) ^ SPH_T32((x) << 1) \
|
||||
^ SPH_ROTL32(x, 12) ^ SPH_ROTL32(x, 25))
|
||||
#define ss3(x) (((x) >> 2) ^ SPH_T32((x) << 2) \
|
||||
^ SPH_ROTL32(x, 15) ^ SPH_ROTL32(x, 29))
|
||||
#define ss4(x) (((x) >> 1) ^ (x))
|
||||
#define ss5(x) (((x) >> 2) ^ (x))
|
||||
#define rs1(x) SPH_ROTL32(x, 3)
|
||||
#define rs2(x) SPH_ROTL32(x, 7)
|
||||
#define rs3(x) SPH_ROTL32(x, 13)
|
||||
#define rs4(x) SPH_ROTL32(x, 16)
|
||||
#define rs5(x) SPH_ROTL32(x, 19)
|
||||
#define rs6(x) SPH_ROTL32(x, 23)
|
||||
#define rs7(x) SPH_ROTL32(x, 27)
|
||||
|
||||
#define Ks(j) SPH_T32((sph_u32)(j) * SPH_C32(0x05555555))
|
||||
|
||||
#define add_elt_s(mf, hf, j0m, j1m, j3m, j4m, j7m, j10m, j11m, j16) \
|
||||
(SPH_T32(SPH_ROTL32(mf(j0m), j1m) + SPH_ROTL32(mf(j3m), j4m) \
|
||||
- SPH_ROTL32(mf(j10m), j11m) + Ks(j16)) ^ hf(j7m))
|
||||
|
||||
#define expand1s_inner(qf, mf, hf, i16, \
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, \
|
||||
i9, i10, i11, i12, i13, i14, i15, \
|
||||
i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
|
||||
SPH_T32(ss1(qf(i0)) + ss2(qf(i1)) + ss3(qf(i2)) + ss0(qf(i3)) \
|
||||
+ ss1(qf(i4)) + ss2(qf(i5)) + ss3(qf(i6)) + ss0(qf(i7)) \
|
||||
+ ss1(qf(i8)) + ss2(qf(i9)) + ss3(qf(i10)) + ss0(qf(i11)) \
|
||||
+ ss1(qf(i12)) + ss2(qf(i13)) + ss3(qf(i14)) + ss0(qf(i15)) \
|
||||
+ add_elt_s(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
|
||||
|
||||
#define expand1s(qf, mf, hf, i16) \
|
||||
expand1s_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
|
||||
#define expand1s_(qf, mf, hf, i16, ix, iy) \
|
||||
expand1s_inner LPAR qf, mf, hf, i16, ix, iy)
|
||||
|
||||
#define expand2s_inner(qf, mf, hf, i16, \
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, \
|
||||
i9, i10, i11, i12, i13, i14, i15, \
|
||||
i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
|
||||
SPH_T32(qf(i0) + rs1(qf(i1)) + qf(i2) + rs2(qf(i3)) \
|
||||
+ qf(i4) + rs3(qf(i5)) + qf(i6) + rs4(qf(i7)) \
|
||||
+ qf(i8) + rs5(qf(i9)) + qf(i10) + rs6(qf(i11)) \
|
||||
+ qf(i12) + rs7(qf(i13)) + ss4(qf(i14)) + ss5(qf(i15)) \
|
||||
+ add_elt_s(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
|
||||
|
||||
#define expand2s(qf, mf, hf, i16) \
|
||||
expand2s_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
|
||||
#define expand2s_(qf, mf, hf, i16, ix, iy) \
|
||||
expand2s_inner LPAR qf, mf, hf, i16, ix, iy)
|
||||
|
||||
#if SPH_64
|
||||
|
||||
#define sb0(x) (((x) >> 1) ^ SPH_T64((x) << 3) \
|
||||
^ SPH_ROTL64(x, 4) ^ SPH_ROTL64(x, 37))
|
||||
#define sb1(x) (((x) >> 1) ^ SPH_T64((x) << 2) \
|
||||
^ SPH_ROTL64(x, 13) ^ SPH_ROTL64(x, 43))
|
||||
#define sb2(x) (((x) >> 2) ^ SPH_T64((x) << 1) \
|
||||
^ SPH_ROTL64(x, 19) ^ SPH_ROTL64(x, 53))
|
||||
#define sb3(x) (((x) >> 2) ^ SPH_T64((x) << 2) \
|
||||
^ SPH_ROTL64(x, 28) ^ SPH_ROTL64(x, 59))
|
||||
#define sb4(x) (((x) >> 1) ^ (x))
|
||||
#define sb5(x) (((x) >> 2) ^ (x))
|
||||
#define rb1(x) SPH_ROTL64(x, 5)
|
||||
#define rb2(x) SPH_ROTL64(x, 11)
|
||||
#define rb3(x) SPH_ROTL64(x, 27)
|
||||
#define rb4(x) SPH_ROTL64(x, 32)
|
||||
#define rb5(x) SPH_ROTL64(x, 37)
|
||||
#define rb6(x) SPH_ROTL64(x, 43)
|
||||
#define rb7(x) SPH_ROTL64(x, 53)
|
||||
|
||||
#define Kb(j) SPH_T64((sph_u64)(j) * SPH_C64(0x0555555555555555))
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_BMW
|
||||
|
||||
static const sph_u64 Kb_tab[] = {
|
||||
Kb(16), Kb(17), Kb(18), Kb(19), Kb(20), Kb(21), Kb(22), Kb(23),
|
||||
Kb(24), Kb(25), Kb(26), Kb(27), Kb(28), Kb(29), Kb(30), Kb(31)
|
||||
};
|
||||
|
||||
#define rol_off(mf, j, off) \
|
||||
SPH_ROTL64(mf(((j) + (off)) & 15), (((j) + (off)) & 15) + 1)
|
||||
|
||||
#define add_elt_b(mf, hf, j) \
|
||||
(SPH_T64(rol_off(mf, j, 0) + rol_off(mf, j, 3) \
|
||||
- rol_off(mf, j, 10) + Kb_tab[j]) ^ hf(((j) + 7) & 15))
|
||||
|
||||
#define expand1b(qf, mf, hf, i) \
|
||||
SPH_T64(sb1(qf((i) - 16)) + sb2(qf((i) - 15)) \
|
||||
+ sb3(qf((i) - 14)) + sb0(qf((i) - 13)) \
|
||||
+ sb1(qf((i) - 12)) + sb2(qf((i) - 11)) \
|
||||
+ sb3(qf((i) - 10)) + sb0(qf((i) - 9)) \
|
||||
+ sb1(qf((i) - 8)) + sb2(qf((i) - 7)) \
|
||||
+ sb3(qf((i) - 6)) + sb0(qf((i) - 5)) \
|
||||
+ sb1(qf((i) - 4)) + sb2(qf((i) - 3)) \
|
||||
+ sb3(qf((i) - 2)) + sb0(qf((i) - 1)) \
|
||||
+ add_elt_b(mf, hf, (i) - 16))
|
||||
|
||||
#define expand2b(qf, mf, hf, i) \
|
||||
SPH_T64(qf((i) - 16) + rb1(qf((i) - 15)) \
|
||||
+ qf((i) - 14) + rb2(qf((i) - 13)) \
|
||||
+ qf((i) - 12) + rb3(qf((i) - 11)) \
|
||||
+ qf((i) - 10) + rb4(qf((i) - 9)) \
|
||||
+ qf((i) - 8) + rb5(qf((i) - 7)) \
|
||||
+ qf((i) - 6) + rb6(qf((i) - 5)) \
|
||||
+ qf((i) - 4) + rb7(qf((i) - 3)) \
|
||||
+ sb4(qf((i) - 2)) + sb5(qf((i) - 1)) \
|
||||
+ add_elt_b(mf, hf, (i) - 16))
|
||||
|
||||
#else
|
||||
|
||||
#define add_elt_b(mf, hf, j0m, j1m, j3m, j4m, j7m, j10m, j11m, j16) \
|
||||
(SPH_T64(SPH_ROTL64(mf(j0m), j1m) + SPH_ROTL64(mf(j3m), j4m) \
|
||||
- SPH_ROTL64(mf(j10m), j11m) + Kb(j16)) ^ hf(j7m))
|
||||
|
||||
#define expand1b_inner(qf, mf, hf, i16, \
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, \
|
||||
i9, i10, i11, i12, i13, i14, i15, \
|
||||
i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
|
||||
SPH_T64(sb1(qf(i0)) + sb2(qf(i1)) + sb3(qf(i2)) + sb0(qf(i3)) \
|
||||
+ sb1(qf(i4)) + sb2(qf(i5)) + sb3(qf(i6)) + sb0(qf(i7)) \
|
||||
+ sb1(qf(i8)) + sb2(qf(i9)) + sb3(qf(i10)) + sb0(qf(i11)) \
|
||||
+ sb1(qf(i12)) + sb2(qf(i13)) + sb3(qf(i14)) + sb0(qf(i15)) \
|
||||
+ add_elt_b(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
|
||||
|
||||
#define expand1b(qf, mf, hf, i16) \
|
||||
expand1b_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
|
||||
#define expand1b_(qf, mf, hf, i16, ix, iy) \
|
||||
expand1b_inner LPAR qf, mf, hf, i16, ix, iy)
|
||||
|
||||
#define expand2b_inner(qf, mf, hf, i16, \
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, \
|
||||
i9, i10, i11, i12, i13, i14, i15, \
|
||||
i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
|
||||
SPH_T64(qf(i0) + rb1(qf(i1)) + qf(i2) + rb2(qf(i3)) \
|
||||
+ qf(i4) + rb3(qf(i5)) + qf(i6) + rb4(qf(i7)) \
|
||||
+ qf(i8) + rb5(qf(i9)) + qf(i10) + rb6(qf(i11)) \
|
||||
+ qf(i12) + rb7(qf(i13)) + sb4(qf(i14)) + sb5(qf(i15)) \
|
||||
+ add_elt_b(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
|
||||
|
||||
#define expand2b(qf, mf, hf, i16) \
|
||||
expand2b_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
|
||||
#define expand2b_(qf, mf, hf, i16, ix, iy) \
|
||||
expand2b_inner LPAR qf, mf, hf, i16, ix, iy)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define MAKE_W(tt, i0, op01, i1, op12, i2, op23, i3, op34, i4) \
|
||||
tt((M(i0) ^ H(i0)) op01 (M(i1) ^ H(i1)) op12 (M(i2) ^ H(i2)) \
|
||||
op23 (M(i3) ^ H(i3)) op34 (M(i4) ^ H(i4)))
|
||||
|
||||
#define Ws0 MAKE_W(SPH_T32, 5, -, 7, +, 10, +, 13, +, 14)
|
||||
#define Ws1 MAKE_W(SPH_T32, 6, -, 8, +, 11, +, 14, -, 15)
|
||||
#define Ws2 MAKE_W(SPH_T32, 0, +, 7, +, 9, -, 12, +, 15)
|
||||
#define Ws3 MAKE_W(SPH_T32, 0, -, 1, +, 8, -, 10, +, 13)
|
||||
#define Ws4 MAKE_W(SPH_T32, 1, +, 2, +, 9, -, 11, -, 14)
|
||||
#define Ws5 MAKE_W(SPH_T32, 3, -, 2, +, 10, -, 12, +, 15)
|
||||
#define Ws6 MAKE_W(SPH_T32, 4, -, 0, -, 3, -, 11, +, 13)
|
||||
#define Ws7 MAKE_W(SPH_T32, 1, -, 4, -, 5, -, 12, -, 14)
|
||||
#define Ws8 MAKE_W(SPH_T32, 2, -, 5, -, 6, +, 13, -, 15)
|
||||
#define Ws9 MAKE_W(SPH_T32, 0, -, 3, +, 6, -, 7, +, 14)
|
||||
#define Ws10 MAKE_W(SPH_T32, 8, -, 1, -, 4, -, 7, +, 15)
|
||||
#define Ws11 MAKE_W(SPH_T32, 8, -, 0, -, 2, -, 5, +, 9)
|
||||
#define Ws12 MAKE_W(SPH_T32, 1, +, 3, -, 6, -, 9, +, 10)
|
||||
#define Ws13 MAKE_W(SPH_T32, 2, +, 4, +, 7, +, 10, +, 11)
|
||||
#define Ws14 MAKE_W(SPH_T32, 3, -, 5, +, 8, -, 11, -, 12)
|
||||
#define Ws15 MAKE_W(SPH_T32, 12, -, 4, -, 6, -, 9, +, 13)
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_BMW
|
||||
|
||||
#define MAKE_Qas do { \
|
||||
unsigned u; \
|
||||
sph_u32 Ws[16]; \
|
||||
Ws[ 0] = Ws0; \
|
||||
Ws[ 1] = Ws1; \
|
||||
Ws[ 2] = Ws2; \
|
||||
Ws[ 3] = Ws3; \
|
||||
Ws[ 4] = Ws4; \
|
||||
Ws[ 5] = Ws5; \
|
||||
Ws[ 6] = Ws6; \
|
||||
Ws[ 7] = Ws7; \
|
||||
Ws[ 8] = Ws8; \
|
||||
Ws[ 9] = Ws9; \
|
||||
Ws[10] = Ws10; \
|
||||
Ws[11] = Ws11; \
|
||||
Ws[12] = Ws12; \
|
||||
Ws[13] = Ws13; \
|
||||
Ws[14] = Ws14; \
|
||||
Ws[15] = Ws15; \
|
||||
for (u = 0; u < 15; u += 5) { \
|
||||
qt[u + 0] = SPH_T32(ss0(Ws[u + 0]) + H(u + 1)); \
|
||||
qt[u + 1] = SPH_T32(ss1(Ws[u + 1]) + H(u + 2)); \
|
||||
qt[u + 2] = SPH_T32(ss2(Ws[u + 2]) + H(u + 3)); \
|
||||
qt[u + 3] = SPH_T32(ss3(Ws[u + 3]) + H(u + 4)); \
|
||||
qt[u + 4] = SPH_T32(ss4(Ws[u + 4]) + H(u + 5)); \
|
||||
} \
|
||||
qt[15] = SPH_T32(ss0(Ws[15]) + H(0)); \
|
||||
} while (0)
|
||||
|
||||
#define MAKE_Qbs do { \
|
||||
qt[16] = expand1s(Qs, M, H, 16); \
|
||||
qt[17] = expand1s(Qs, M, H, 17); \
|
||||
qt[18] = expand2s(Qs, M, H, 18); \
|
||||
qt[19] = expand2s(Qs, M, H, 19); \
|
||||
qt[20] = expand2s(Qs, M, H, 20); \
|
||||
qt[21] = expand2s(Qs, M, H, 21); \
|
||||
qt[22] = expand2s(Qs, M, H, 22); \
|
||||
qt[23] = expand2s(Qs, M, H, 23); \
|
||||
qt[24] = expand2s(Qs, M, H, 24); \
|
||||
qt[25] = expand2s(Qs, M, H, 25); \
|
||||
qt[26] = expand2s(Qs, M, H, 26); \
|
||||
qt[27] = expand2s(Qs, M, H, 27); \
|
||||
qt[28] = expand2s(Qs, M, H, 28); \
|
||||
qt[29] = expand2s(Qs, M, H, 29); \
|
||||
qt[30] = expand2s(Qs, M, H, 30); \
|
||||
qt[31] = expand2s(Qs, M, H, 31); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define MAKE_Qas do { \
|
||||
qt[ 0] = SPH_T32(ss0(Ws0 ) + H( 1)); \
|
||||
qt[ 1] = SPH_T32(ss1(Ws1 ) + H( 2)); \
|
||||
qt[ 2] = SPH_T32(ss2(Ws2 ) + H( 3)); \
|
||||
qt[ 3] = SPH_T32(ss3(Ws3 ) + H( 4)); \
|
||||
qt[ 4] = SPH_T32(ss4(Ws4 ) + H( 5)); \
|
||||
qt[ 5] = SPH_T32(ss0(Ws5 ) + H( 6)); \
|
||||
qt[ 6] = SPH_T32(ss1(Ws6 ) + H( 7)); \
|
||||
qt[ 7] = SPH_T32(ss2(Ws7 ) + H( 8)); \
|
||||
qt[ 8] = SPH_T32(ss3(Ws8 ) + H( 9)); \
|
||||
qt[ 9] = SPH_T32(ss4(Ws9 ) + H(10)); \
|
||||
qt[10] = SPH_T32(ss0(Ws10) + H(11)); \
|
||||
qt[11] = SPH_T32(ss1(Ws11) + H(12)); \
|
||||
qt[12] = SPH_T32(ss2(Ws12) + H(13)); \
|
||||
qt[13] = SPH_T32(ss3(Ws13) + H(14)); \
|
||||
qt[14] = SPH_T32(ss4(Ws14) + H(15)); \
|
||||
qt[15] = SPH_T32(ss0(Ws15) + H( 0)); \
|
||||
} while (0)
|
||||
|
||||
#define MAKE_Qbs do { \
|
||||
qt[16] = expand1s(Qs, M, H, 16); \
|
||||
qt[17] = expand1s(Qs, M, H, 17); \
|
||||
qt[18] = expand2s(Qs, M, H, 18); \
|
||||
qt[19] = expand2s(Qs, M, H, 19); \
|
||||
qt[20] = expand2s(Qs, M, H, 20); \
|
||||
qt[21] = expand2s(Qs, M, H, 21); \
|
||||
qt[22] = expand2s(Qs, M, H, 22); \
|
||||
qt[23] = expand2s(Qs, M, H, 23); \
|
||||
qt[24] = expand2s(Qs, M, H, 24); \
|
||||
qt[25] = expand2s(Qs, M, H, 25); \
|
||||
qt[26] = expand2s(Qs, M, H, 26); \
|
||||
qt[27] = expand2s(Qs, M, H, 27); \
|
||||
qt[28] = expand2s(Qs, M, H, 28); \
|
||||
qt[29] = expand2s(Qs, M, H, 29); \
|
||||
qt[30] = expand2s(Qs, M, H, 30); \
|
||||
qt[31] = expand2s(Qs, M, H, 31); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define MAKE_Qs do { \
|
||||
MAKE_Qas; \
|
||||
MAKE_Qbs; \
|
||||
} while (0)
|
||||
|
||||
#define Qs(j) (qt[j])
|
||||
|
||||
#if SPH_64
|
||||
|
||||
#define Wb0 MAKE_W(SPH_T64, 5, -, 7, +, 10, +, 13, +, 14)
|
||||
#define Wb1 MAKE_W(SPH_T64, 6, -, 8, +, 11, +, 14, -, 15)
|
||||
#define Wb2 MAKE_W(SPH_T64, 0, +, 7, +, 9, -, 12, +, 15)
|
||||
#define Wb3 MAKE_W(SPH_T64, 0, -, 1, +, 8, -, 10, +, 13)
|
||||
#define Wb4 MAKE_W(SPH_T64, 1, +, 2, +, 9, -, 11, -, 14)
|
||||
#define Wb5 MAKE_W(SPH_T64, 3, -, 2, +, 10, -, 12, +, 15)
|
||||
#define Wb6 MAKE_W(SPH_T64, 4, -, 0, -, 3, -, 11, +, 13)
|
||||
#define Wb7 MAKE_W(SPH_T64, 1, -, 4, -, 5, -, 12, -, 14)
|
||||
#define Wb8 MAKE_W(SPH_T64, 2, -, 5, -, 6, +, 13, -, 15)
|
||||
#define Wb9 MAKE_W(SPH_T64, 0, -, 3, +, 6, -, 7, +, 14)
|
||||
#define Wb10 MAKE_W(SPH_T64, 8, -, 1, -, 4, -, 7, +, 15)
|
||||
#define Wb11 MAKE_W(SPH_T64, 8, -, 0, -, 2, -, 5, +, 9)
|
||||
#define Wb12 MAKE_W(SPH_T64, 1, +, 3, -, 6, -, 9, +, 10)
|
||||
#define Wb13 MAKE_W(SPH_T64, 2, +, 4, +, 7, +, 10, +, 11)
|
||||
#define Wb14 MAKE_W(SPH_T64, 3, -, 5, +, 8, -, 11, -, 12)
|
||||
#define Wb15 MAKE_W(SPH_T64, 12, -, 4, -, 6, -, 9, +, 13)
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_BMW
|
||||
|
||||
#define MAKE_Qab do { \
|
||||
unsigned u; \
|
||||
sph_u64 Wb[16]; \
|
||||
Wb[ 0] = Wb0; \
|
||||
Wb[ 1] = Wb1; \
|
||||
Wb[ 2] = Wb2; \
|
||||
Wb[ 3] = Wb3; \
|
||||
Wb[ 4] = Wb4; \
|
||||
Wb[ 5] = Wb5; \
|
||||
Wb[ 6] = Wb6; \
|
||||
Wb[ 7] = Wb7; \
|
||||
Wb[ 8] = Wb8; \
|
||||
Wb[ 9] = Wb9; \
|
||||
Wb[10] = Wb10; \
|
||||
Wb[11] = Wb11; \
|
||||
Wb[12] = Wb12; \
|
||||
Wb[13] = Wb13; \
|
||||
Wb[14] = Wb14; \
|
||||
Wb[15] = Wb15; \
|
||||
for (u = 0; u < 15; u += 5) { \
|
||||
qt[u + 0] = SPH_T64(sb0(Wb[u + 0]) + H(u + 1)); \
|
||||
qt[u + 1] = SPH_T64(sb1(Wb[u + 1]) + H(u + 2)); \
|
||||
qt[u + 2] = SPH_T64(sb2(Wb[u + 2]) + H(u + 3)); \
|
||||
qt[u + 3] = SPH_T64(sb3(Wb[u + 3]) + H(u + 4)); \
|
||||
qt[u + 4] = SPH_T64(sb4(Wb[u + 4]) + H(u + 5)); \
|
||||
} \
|
||||
qt[15] = SPH_T64(sb0(Wb[15]) + H(0)); \
|
||||
} while (0)
|
||||
|
||||
#define MAKE_Qbb do { \
|
||||
unsigned u; \
|
||||
for (u = 16; u < 18; u ++) \
|
||||
qt[u] = expand1b(Qb, M, H, u); \
|
||||
for (u = 18; u < 32; u ++) \
|
||||
qt[u] = expand2b(Qb, M, H, u); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define MAKE_Qab do { \
|
||||
qt[ 0] = SPH_T64(sb0(Wb0 ) + H( 1)); \
|
||||
qt[ 1] = SPH_T64(sb1(Wb1 ) + H( 2)); \
|
||||
qt[ 2] = SPH_T64(sb2(Wb2 ) + H( 3)); \
|
||||
qt[ 3] = SPH_T64(sb3(Wb3 ) + H( 4)); \
|
||||
qt[ 4] = SPH_T64(sb4(Wb4 ) + H( 5)); \
|
||||
qt[ 5] = SPH_T64(sb0(Wb5 ) + H( 6)); \
|
||||
qt[ 6] = SPH_T64(sb1(Wb6 ) + H( 7)); \
|
||||
qt[ 7] = SPH_T64(sb2(Wb7 ) + H( 8)); \
|
||||
qt[ 8] = SPH_T64(sb3(Wb8 ) + H( 9)); \
|
||||
qt[ 9] = SPH_T64(sb4(Wb9 ) + H(10)); \
|
||||
qt[10] = SPH_T64(sb0(Wb10) + H(11)); \
|
||||
qt[11] = SPH_T64(sb1(Wb11) + H(12)); \
|
||||
qt[12] = SPH_T64(sb2(Wb12) + H(13)); \
|
||||
qt[13] = SPH_T64(sb3(Wb13) + H(14)); \
|
||||
qt[14] = SPH_T64(sb4(Wb14) + H(15)); \
|
||||
qt[15] = SPH_T64(sb0(Wb15) + H( 0)); \
|
||||
} while (0)
|
||||
|
||||
#define MAKE_Qbb do { \
|
||||
qt[16] = expand1b(Qb, M, H, 16); \
|
||||
qt[17] = expand1b(Qb, M, H, 17); \
|
||||
qt[18] = expand2b(Qb, M, H, 18); \
|
||||
qt[19] = expand2b(Qb, M, H, 19); \
|
||||
qt[20] = expand2b(Qb, M, H, 20); \
|
||||
qt[21] = expand2b(Qb, M, H, 21); \
|
||||
qt[22] = expand2b(Qb, M, H, 22); \
|
||||
qt[23] = expand2b(Qb, M, H, 23); \
|
||||
qt[24] = expand2b(Qb, M, H, 24); \
|
||||
qt[25] = expand2b(Qb, M, H, 25); \
|
||||
qt[26] = expand2b(Qb, M, H, 26); \
|
||||
qt[27] = expand2b(Qb, M, H, 27); \
|
||||
qt[28] = expand2b(Qb, M, H, 28); \
|
||||
qt[29] = expand2b(Qb, M, H, 29); \
|
||||
qt[30] = expand2b(Qb, M, H, 30); \
|
||||
qt[31] = expand2b(Qb, M, H, 31); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define MAKE_Qb do { \
|
||||
MAKE_Qab; \
|
||||
MAKE_Qbb; \
|
||||
} while (0)
|
||||
|
||||
#define Qb(j) (qt[j])
|
||||
|
||||
#endif
|
||||
|
||||
#define FOLD(type, mkQ, tt, rol, mf, qf, dhf) do { \
|
||||
type qt[32], xl, xh; \
|
||||
mkQ; \
|
||||
xl = qf(16) ^ qf(17) ^ qf(18) ^ qf(19) \
|
||||
^ qf(20) ^ qf(21) ^ qf(22) ^ qf(23); \
|
||||
xh = xl ^ qf(24) ^ qf(25) ^ qf(26) ^ qf(27) \
|
||||
^ qf(28) ^ qf(29) ^ qf(30) ^ qf(31); \
|
||||
dhf( 0) = tt(((xh << 5) ^ (qf(16) >> 5) ^ mf( 0)) \
|
||||
+ (xl ^ qf(24) ^ qf( 0))); \
|
||||
dhf( 1) = tt(((xh >> 7) ^ (qf(17) << 8) ^ mf( 1)) \
|
||||
+ (xl ^ qf(25) ^ qf( 1))); \
|
||||
dhf( 2) = tt(((xh >> 5) ^ (qf(18) << 5) ^ mf( 2)) \
|
||||
+ (xl ^ qf(26) ^ qf( 2))); \
|
||||
dhf( 3) = tt(((xh >> 1) ^ (qf(19) << 5) ^ mf( 3)) \
|
||||
+ (xl ^ qf(27) ^ qf( 3))); \
|
||||
dhf( 4) = tt(((xh >> 3) ^ (qf(20) << 0) ^ mf( 4)) \
|
||||
+ (xl ^ qf(28) ^ qf( 4))); \
|
||||
dhf( 5) = tt(((xh << 6) ^ (qf(21) >> 6) ^ mf( 5)) \
|
||||
+ (xl ^ qf(29) ^ qf( 5))); \
|
||||
dhf( 6) = tt(((xh >> 4) ^ (qf(22) << 6) ^ mf( 6)) \
|
||||
+ (xl ^ qf(30) ^ qf( 6))); \
|
||||
dhf( 7) = tt(((xh >> 11) ^ (qf(23) << 2) ^ mf( 7)) \
|
||||
+ (xl ^ qf(31) ^ qf( 7))); \
|
||||
dhf( 8) = tt(rol(dhf(4), 9) + (xh ^ qf(24) ^ mf( 8)) \
|
||||
+ ((xl << 8) ^ qf(23) ^ qf( 8))); \
|
||||
dhf( 9) = tt(rol(dhf(5), 10) + (xh ^ qf(25) ^ mf( 9)) \
|
||||
+ ((xl >> 6) ^ qf(16) ^ qf( 9))); \
|
||||
dhf(10) = tt(rol(dhf(6), 11) + (xh ^ qf(26) ^ mf(10)) \
|
||||
+ ((xl << 6) ^ qf(17) ^ qf(10))); \
|
||||
dhf(11) = tt(rol(dhf(7), 12) + (xh ^ qf(27) ^ mf(11)) \
|
||||
+ ((xl << 4) ^ qf(18) ^ qf(11))); \
|
||||
dhf(12) = tt(rol(dhf(0), 13) + (xh ^ qf(28) ^ mf(12)) \
|
||||
+ ((xl >> 3) ^ qf(19) ^ qf(12))); \
|
||||
dhf(13) = tt(rol(dhf(1), 14) + (xh ^ qf(29) ^ mf(13)) \
|
||||
+ ((xl >> 4) ^ qf(20) ^ qf(13))); \
|
||||
dhf(14) = tt(rol(dhf(2), 15) + (xh ^ qf(30) ^ mf(14)) \
|
||||
+ ((xl >> 7) ^ qf(21) ^ qf(14))); \
|
||||
dhf(15) = tt(rol(dhf(3), 16) + (xh ^ qf(31) ^ mf(15)) \
|
||||
+ ((xl >> 2) ^ qf(22) ^ qf(15))); \
|
||||
} while (0)
|
||||
|
||||
#define FOLDs FOLD(sph_u32, MAKE_Qs, SPH_T32, SPH_ROTL32, M, Qs, dH)
|
||||
|
||||
#if SPH_64
|
||||
|
||||
#define FOLDb FOLD(sph_u64, MAKE_Qb, SPH_T64, SPH_ROTL64, M, Qb, dH)
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
compress_small(const unsigned char *data, const sph_u32 h[16], sph_u32 dh[16])
|
||||
{
|
||||
#if SPH_LITTLE_FAST
|
||||
#define M(x) sph_dec32le_aligned(data + 4 * (x))
|
||||
#else
|
||||
sph_u32 mv[16];
|
||||
|
||||
mv[ 0] = sph_dec32le_aligned(data + 0);
|
||||
mv[ 1] = sph_dec32le_aligned(data + 4);
|
||||
mv[ 2] = sph_dec32le_aligned(data + 8);
|
||||
mv[ 3] = sph_dec32le_aligned(data + 12);
|
||||
mv[ 4] = sph_dec32le_aligned(data + 16);
|
||||
mv[ 5] = sph_dec32le_aligned(data + 20);
|
||||
mv[ 6] = sph_dec32le_aligned(data + 24);
|
||||
mv[ 7] = sph_dec32le_aligned(data + 28);
|
||||
mv[ 8] = sph_dec32le_aligned(data + 32);
|
||||
mv[ 9] = sph_dec32le_aligned(data + 36);
|
||||
mv[10] = sph_dec32le_aligned(data + 40);
|
||||
mv[11] = sph_dec32le_aligned(data + 44);
|
||||
mv[12] = sph_dec32le_aligned(data + 48);
|
||||
mv[13] = sph_dec32le_aligned(data + 52);
|
||||
mv[14] = sph_dec32le_aligned(data + 56);
|
||||
mv[15] = sph_dec32le_aligned(data + 60);
|
||||
#define M(x) (mv[x])
|
||||
#endif
|
||||
#define H(x) (h[x])
|
||||
#define dH(x) (dh[x])
|
||||
|
||||
FOLDs;
|
||||
|
||||
#undef M
|
||||
#undef H
|
||||
#undef dH
|
||||
}
|
||||
|
||||
static const sph_u32 final_s[16] = {
|
||||
SPH_C32(0xaaaaaaa0), SPH_C32(0xaaaaaaa1), SPH_C32(0xaaaaaaa2),
|
||||
SPH_C32(0xaaaaaaa3), SPH_C32(0xaaaaaaa4), SPH_C32(0xaaaaaaa5),
|
||||
SPH_C32(0xaaaaaaa6), SPH_C32(0xaaaaaaa7), SPH_C32(0xaaaaaaa8),
|
||||
SPH_C32(0xaaaaaaa9), SPH_C32(0xaaaaaaaa), SPH_C32(0xaaaaaaab),
|
||||
SPH_C32(0xaaaaaaac), SPH_C32(0xaaaaaaad), SPH_C32(0xaaaaaaae),
|
||||
SPH_C32(0xaaaaaaaf)
|
||||
};
|
||||
|
||||
static void
|
||||
bmw32_init(sph_bmw_small_context *sc, const sph_u32 *iv)
|
||||
{
|
||||
memcpy(sc->H, iv, sizeof sc->H);
|
||||
sc->ptr = 0;
|
||||
#if SPH_64
|
||||
sc->bit_count = 0;
|
||||
#else
|
||||
sc->bit_count_high = 0;
|
||||
sc->bit_count_low = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
bmw32(sph_bmw_small_context *sc, const void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
size_t ptr;
|
||||
sph_u32 htmp[16];
|
||||
sph_u32 *h1, *h2;
|
||||
#if !SPH_64
|
||||
sph_u32 tmp;
|
||||
#endif
|
||||
|
||||
#if SPH_64
|
||||
sc->bit_count += (sph_u64)len << 3;
|
||||
#else
|
||||
tmp = sc->bit_count_low;
|
||||
sc->bit_count_low = SPH_T32(tmp + ((sph_u32)len << 3));
|
||||
if (sc->bit_count_low < tmp)
|
||||
sc->bit_count_high ++;
|
||||
sc->bit_count_high += len >> 29;
|
||||
#endif
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
h1 = sc->H;
|
||||
h2 = htmp;
|
||||
while (len > 0) {
|
||||
size_t clen;
|
||||
|
||||
clen = (sizeof sc->buf) - ptr;
|
||||
if (clen > len)
|
||||
clen = len;
|
||||
memcpy(buf + ptr, data, clen);
|
||||
data = (const unsigned char *)data + clen;
|
||||
len -= clen;
|
||||
ptr += clen;
|
||||
if (ptr == sizeof sc->buf) {
|
||||
sph_u32 *ht;
|
||||
|
||||
compress_small(buf, h1, h2);
|
||||
ht = h1;
|
||||
h1 = h2;
|
||||
h2 = ht;
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
sc->ptr = ptr;
|
||||
if (h1 != sc->H)
|
||||
memcpy(sc->H, h1, sizeof sc->H);
|
||||
}
|
||||
|
||||
static void
|
||||
bmw32_close(sph_bmw_small_context *sc, unsigned ub, unsigned n,
|
||||
void *dst, size_t out_size_w32)
|
||||
{
|
||||
unsigned char *buf, *out;
|
||||
size_t ptr, u, v;
|
||||
unsigned z;
|
||||
sph_u32 h1[16], h2[16], *h;
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
z = 0x80 >> n;
|
||||
buf[ptr ++] = ((ub & -z) | z) & 0xFF;
|
||||
h = sc->H;
|
||||
if (ptr > (sizeof sc->buf) - 8) {
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
|
||||
compress_small(buf, h, h1);
|
||||
ptr = 0;
|
||||
h = h1;
|
||||
}
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - 8 - ptr);
|
||||
#if SPH_64
|
||||
sph_enc64le_aligned(buf + (sizeof sc->buf) - 8,
|
||||
SPH_T64(sc->bit_count + n));
|
||||
#else
|
||||
sph_enc32le_aligned(buf + (sizeof sc->buf) - 8,
|
||||
sc->bit_count_low + n);
|
||||
sph_enc32le_aligned(buf + (sizeof sc->buf) - 4,
|
||||
SPH_T32(sc->bit_count_high));
|
||||
#endif
|
||||
compress_small(buf, h, h2);
|
||||
for (u = 0; u < 16; u ++)
|
||||
sph_enc32le_aligned(buf + 4 * u, h2[u]);
|
||||
compress_small(buf, final_s, h1);
|
||||
out = dst;
|
||||
for (u = 0, v = 16 - out_size_w32; u < out_size_w32; u ++, v ++)
|
||||
sph_enc32le(out + 4 * u, h1[v]);
|
||||
}
|
||||
|
||||
#if SPH_64
|
||||
|
||||
static void
|
||||
compress_big(const unsigned char *data, const sph_u64 h[16], sph_u64 dh[16])
|
||||
{
|
||||
#if SPH_LITTLE_FAST
|
||||
#define M(x) sph_dec64le_aligned(data + 8 * (x))
|
||||
#else
|
||||
sph_u64 mv[16];
|
||||
|
||||
mv[ 0] = sph_dec64le_aligned(data + 0);
|
||||
mv[ 1] = sph_dec64le_aligned(data + 8);
|
||||
mv[ 2] = sph_dec64le_aligned(data + 16);
|
||||
mv[ 3] = sph_dec64le_aligned(data + 24);
|
||||
mv[ 4] = sph_dec64le_aligned(data + 32);
|
||||
mv[ 5] = sph_dec64le_aligned(data + 40);
|
||||
mv[ 6] = sph_dec64le_aligned(data + 48);
|
||||
mv[ 7] = sph_dec64le_aligned(data + 56);
|
||||
mv[ 8] = sph_dec64le_aligned(data + 64);
|
||||
mv[ 9] = sph_dec64le_aligned(data + 72);
|
||||
mv[10] = sph_dec64le_aligned(data + 80);
|
||||
mv[11] = sph_dec64le_aligned(data + 88);
|
||||
mv[12] = sph_dec64le_aligned(data + 96);
|
||||
mv[13] = sph_dec64le_aligned(data + 104);
|
||||
mv[14] = sph_dec64le_aligned(data + 112);
|
||||
mv[15] = sph_dec64le_aligned(data + 120);
|
||||
#define M(x) (mv[x])
|
||||
#endif
|
||||
#define H(x) (h[x])
|
||||
#define dH(x) (dh[x])
|
||||
|
||||
FOLDb;
|
||||
|
||||
#undef M
|
||||
#undef H
|
||||
#undef dH
|
||||
}
|
||||
|
||||
static const sph_u64 final_b[16] = {
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa0), SPH_C64(0xaaaaaaaaaaaaaaa1),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa2), SPH_C64(0xaaaaaaaaaaaaaaa3),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa4), SPH_C64(0xaaaaaaaaaaaaaaa5),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa6), SPH_C64(0xaaaaaaaaaaaaaaa7),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa8), SPH_C64(0xaaaaaaaaaaaaaaa9),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaaa), SPH_C64(0xaaaaaaaaaaaaaaab),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaac), SPH_C64(0xaaaaaaaaaaaaaaad),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaae), SPH_C64(0xaaaaaaaaaaaaaaaf)
|
||||
};
|
||||
|
||||
static void
|
||||
bmw64_init(sph_bmw_big_context *sc, const sph_u64 *iv)
|
||||
{
|
||||
memcpy(sc->H, iv, sizeof sc->H);
|
||||
sc->ptr = 0;
|
||||
sc->bit_count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
bmw64(sph_bmw_big_context *sc, const void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
size_t ptr;
|
||||
sph_u64 htmp[16];
|
||||
sph_u64 *h1, *h2;
|
||||
|
||||
sc->bit_count += (sph_u64)len << 3;
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
h1 = sc->H;
|
||||
h2 = htmp;
|
||||
while (len > 0) {
|
||||
size_t clen;
|
||||
|
||||
clen = (sizeof sc->buf) - ptr;
|
||||
if (clen > len)
|
||||
clen = len;
|
||||
memcpy(buf + ptr, data, clen);
|
||||
data = (const unsigned char *)data + clen;
|
||||
len -= clen;
|
||||
ptr += clen;
|
||||
if (ptr == sizeof sc->buf) {
|
||||
sph_u64 *ht;
|
||||
|
||||
compress_big(buf, h1, h2);
|
||||
ht = h1;
|
||||
h1 = h2;
|
||||
h2 = ht;
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
sc->ptr = ptr;
|
||||
if (h1 != sc->H)
|
||||
memcpy(sc->H, h1, sizeof sc->H);
|
||||
}
|
||||
|
||||
static void
|
||||
bmw64_close(sph_bmw_big_context *sc, unsigned ub, unsigned n,
|
||||
void *dst, size_t out_size_w64)
|
||||
{
|
||||
unsigned char *buf, *out;
|
||||
size_t ptr, u, v;
|
||||
unsigned z;
|
||||
sph_u64 h1[16], h2[16], *h;
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
z = 0x80 >> n;
|
||||
buf[ptr ++] = ((ub & -z) | z) & 0xFF;
|
||||
h = sc->H;
|
||||
if (ptr > (sizeof sc->buf) - 8) {
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
|
||||
compress_big(buf, h, h1);
|
||||
ptr = 0;
|
||||
h = h1;
|
||||
}
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - 8 - ptr);
|
||||
sph_enc64le_aligned(buf + (sizeof sc->buf) - 8,
|
||||
SPH_T64(sc->bit_count + n));
|
||||
compress_big(buf, h, h2);
|
||||
for (u = 0; u < 16; u ++)
|
||||
sph_enc64le_aligned(buf + 8 * u, h2[u]);
|
||||
compress_big(buf, final_b, h1);
|
||||
out = dst;
|
||||
for (u = 0, v = 16 - out_size_w64; u < out_size_w64; u ++, v ++)
|
||||
sph_enc64le(out + 8 * u, h1[v]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw224_init(void *cc)
|
||||
{
|
||||
bmw32_init(cc, IV224);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw224(void *cc, const void *data, size_t len)
|
||||
{
|
||||
bmw32(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw224_close(void *cc, void *dst)
|
||||
{
|
||||
sph_bmw224_addbits_and_close(cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
bmw32_close(cc, ub, n, dst, 7);
|
||||
sph_bmw224_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw256_init(void *cc)
|
||||
{
|
||||
bmw32_init(cc, IV256);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw256(void *cc, const void *data, size_t len)
|
||||
{
|
||||
bmw32(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw256_close(void *cc, void *dst)
|
||||
{
|
||||
sph_bmw256_addbits_and_close(cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
bmw32_close(cc, ub, n, dst, 8);
|
||||
sph_bmw256_init(cc);
|
||||
}
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw384_init(void *cc)
|
||||
{
|
||||
bmw64_init(cc, IV384);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw384(void *cc, const void *data, size_t len)
|
||||
{
|
||||
bmw64(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw384_close(void *cc, void *dst)
|
||||
{
|
||||
sph_bmw384_addbits_and_close(cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
bmw64_close(cc, ub, n, dst, 6);
|
||||
sph_bmw384_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw512_init(void *cc)
|
||||
{
|
||||
bmw64_init(cc, IV512);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw512(void *cc, const void *data, size_t len)
|
||||
{
|
||||
bmw64(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw512_close(void *cc, void *dst)
|
||||
{
|
||||
sph_bmw512_addbits_and_close(cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
bmw64_close(cc, ub, n, dst, 8);
|
||||
sph_bmw512_init(cc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,116 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT 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
|
||||
|
||||
#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 // BITCOIN_CRYPTO_COMMON_H
|
||||
@@ -0,0 +1,723 @@
|
||||
/* $Id: cubehash.c 227 2010-06-16 17:28:38Z tp $ */
|
||||
/*
|
||||
* CubeHash implementation.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "sph_cubehash.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_CUBEHASH
|
||||
#define SPH_SMALL_FOOTPRINT_CUBEHASH 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some tests were conducted on an Intel Core2 Q6600 (32-bit and 64-bit
|
||||
* mode), a PowerPC G3, and a MIPS-compatible CPU (Broadcom BCM3302).
|
||||
* It appears that the optimal settings are:
|
||||
* -- full unroll, no state copy on the "big" systems (x86, PowerPC)
|
||||
* -- unroll to 4 or 8, state copy on the "small" system (MIPS)
|
||||
*/
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_CUBEHASH
|
||||
|
||||
#if !defined SPH_CUBEHASH_UNROLL
|
||||
#define SPH_CUBEHASH_UNROLL 4
|
||||
#endif
|
||||
#if !defined SPH_CUBEHASH_NOCOPY
|
||||
#define SPH_CUBEHASH_NOCOPY 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if !defined SPH_CUBEHASH_UNROLL
|
||||
#define SPH_CUBEHASH_UNROLL 0
|
||||
#endif
|
||||
#if !defined SPH_CUBEHASH_NOCOPY
|
||||
#define SPH_CUBEHASH_NOCOPY 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4146)
|
||||
#endif
|
||||
|
||||
static const sph_u32 IV224[] = {
|
||||
SPH_C32(0xB0FC8217), SPH_C32(0x1BEE1A90), SPH_C32(0x829E1A22),
|
||||
SPH_C32(0x6362C342), SPH_C32(0x24D91C30), SPH_C32(0x03A7AA24),
|
||||
SPH_C32(0xA63721C8), SPH_C32(0x85B0E2EF), SPH_C32(0xF35D13F3),
|
||||
SPH_C32(0x41DA807D), SPH_C32(0x21A70CA6), SPH_C32(0x1F4E9774),
|
||||
SPH_C32(0xB3E1C932), SPH_C32(0xEB0A79A8), SPH_C32(0xCDDAAA66),
|
||||
SPH_C32(0xE2F6ECAA), SPH_C32(0x0A713362), SPH_C32(0xAA3080E0),
|
||||
SPH_C32(0xD8F23A32), SPH_C32(0xCEF15E28), SPH_C32(0xDB086314),
|
||||
SPH_C32(0x7F709DF7), SPH_C32(0xACD228A4), SPH_C32(0x704D6ECE),
|
||||
SPH_C32(0xAA3EC95F), SPH_C32(0xE387C214), SPH_C32(0x3A6445FF),
|
||||
SPH_C32(0x9CAB81C3), SPH_C32(0xC73D4B98), SPH_C32(0xD277AEBE),
|
||||
SPH_C32(0xFD20151C), SPH_C32(0x00CB573E)
|
||||
};
|
||||
|
||||
static const sph_u32 IV256[] = {
|
||||
SPH_C32(0xEA2BD4B4), SPH_C32(0xCCD6F29F), SPH_C32(0x63117E71),
|
||||
SPH_C32(0x35481EAE), SPH_C32(0x22512D5B), SPH_C32(0xE5D94E63),
|
||||
SPH_C32(0x7E624131), SPH_C32(0xF4CC12BE), SPH_C32(0xC2D0B696),
|
||||
SPH_C32(0x42AF2070), SPH_C32(0xD0720C35), SPH_C32(0x3361DA8C),
|
||||
SPH_C32(0x28CCECA4), SPH_C32(0x8EF8AD83), SPH_C32(0x4680AC00),
|
||||
SPH_C32(0x40E5FBAB), SPH_C32(0xD89041C3), SPH_C32(0x6107FBD5),
|
||||
SPH_C32(0x6C859D41), SPH_C32(0xF0B26679), SPH_C32(0x09392549),
|
||||
SPH_C32(0x5FA25603), SPH_C32(0x65C892FD), SPH_C32(0x93CB6285),
|
||||
SPH_C32(0x2AF2B5AE), SPH_C32(0x9E4B4E60), SPH_C32(0x774ABFDD),
|
||||
SPH_C32(0x85254725), SPH_C32(0x15815AEB), SPH_C32(0x4AB6AAD6),
|
||||
SPH_C32(0x9CDAF8AF), SPH_C32(0xD6032C0A)
|
||||
};
|
||||
|
||||
static const sph_u32 IV384[] = {
|
||||
SPH_C32(0xE623087E), SPH_C32(0x04C00C87), SPH_C32(0x5EF46453),
|
||||
SPH_C32(0x69524B13), SPH_C32(0x1A05C7A9), SPH_C32(0x3528DF88),
|
||||
SPH_C32(0x6BDD01B5), SPH_C32(0x5057B792), SPH_C32(0x6AA7A922),
|
||||
SPH_C32(0x649C7EEE), SPH_C32(0xF426309F), SPH_C32(0xCB629052),
|
||||
SPH_C32(0xFC8E20ED), SPH_C32(0xB3482BAB), SPH_C32(0xF89E5E7E),
|
||||
SPH_C32(0xD83D4DE4), SPH_C32(0x44BFC10D), SPH_C32(0x5FC1E63D),
|
||||
SPH_C32(0x2104E6CB), SPH_C32(0x17958F7F), SPH_C32(0xDBEAEF70),
|
||||
SPH_C32(0xB4B97E1E), SPH_C32(0x32C195F6), SPH_C32(0x6184A8E4),
|
||||
SPH_C32(0x796C2543), SPH_C32(0x23DE176D), SPH_C32(0xD33BBAEC),
|
||||
SPH_C32(0x0C12E5D2), SPH_C32(0x4EB95A7B), SPH_C32(0x2D18BA01),
|
||||
SPH_C32(0x04EE475F), SPH_C32(0x1FC5F22E)
|
||||
};
|
||||
|
||||
static const sph_u32 IV512[] = {
|
||||
SPH_C32(0x2AEA2A61), SPH_C32(0x50F494D4), SPH_C32(0x2D538B8B),
|
||||
SPH_C32(0x4167D83E), SPH_C32(0x3FEE2313), SPH_C32(0xC701CF8C),
|
||||
SPH_C32(0xCC39968E), SPH_C32(0x50AC5695), SPH_C32(0x4D42C787),
|
||||
SPH_C32(0xA647A8B3), SPH_C32(0x97CF0BEF), SPH_C32(0x825B4537),
|
||||
SPH_C32(0xEEF864D2), SPH_C32(0xF22090C4), SPH_C32(0xD0E5CD33),
|
||||
SPH_C32(0xA23911AE), SPH_C32(0xFCD398D9), SPH_C32(0x148FE485),
|
||||
SPH_C32(0x1B017BEF), SPH_C32(0xB6444532), SPH_C32(0x6A536159),
|
||||
SPH_C32(0x2FF5781C), SPH_C32(0x91FA7934), SPH_C32(0x0DBADEA9),
|
||||
SPH_C32(0xD65C8A2B), SPH_C32(0xA5A70E75), SPH_C32(0xB1C62456),
|
||||
SPH_C32(0xBC796576), SPH_C32(0x1921C8F7), SPH_C32(0xE7989AF1),
|
||||
SPH_C32(0x7795D246), SPH_C32(0xD43E3B44)
|
||||
};
|
||||
|
||||
#define T32 SPH_T32
|
||||
#define ROTL32 SPH_ROTL32
|
||||
|
||||
#if SPH_CUBEHASH_NOCOPY
|
||||
|
||||
#define DECL_STATE
|
||||
#define READ_STATE(cc)
|
||||
#define WRITE_STATE(cc)
|
||||
|
||||
#define x0 ((sc)->state[ 0])
|
||||
#define x1 ((sc)->state[ 1])
|
||||
#define x2 ((sc)->state[ 2])
|
||||
#define x3 ((sc)->state[ 3])
|
||||
#define x4 ((sc)->state[ 4])
|
||||
#define x5 ((sc)->state[ 5])
|
||||
#define x6 ((sc)->state[ 6])
|
||||
#define x7 ((sc)->state[ 7])
|
||||
#define x8 ((sc)->state[ 8])
|
||||
#define x9 ((sc)->state[ 9])
|
||||
#define xa ((sc)->state[10])
|
||||
#define xb ((sc)->state[11])
|
||||
#define xc ((sc)->state[12])
|
||||
#define xd ((sc)->state[13])
|
||||
#define xe ((sc)->state[14])
|
||||
#define xf ((sc)->state[15])
|
||||
#define xg ((sc)->state[16])
|
||||
#define xh ((sc)->state[17])
|
||||
#define xi ((sc)->state[18])
|
||||
#define xj ((sc)->state[19])
|
||||
#define xk ((sc)->state[20])
|
||||
#define xl ((sc)->state[21])
|
||||
#define xm ((sc)->state[22])
|
||||
#define xn ((sc)->state[23])
|
||||
#define xo ((sc)->state[24])
|
||||
#define xp ((sc)->state[25])
|
||||
#define xq ((sc)->state[26])
|
||||
#define xr ((sc)->state[27])
|
||||
#define xs ((sc)->state[28])
|
||||
#define xt ((sc)->state[29])
|
||||
#define xu ((sc)->state[30])
|
||||
#define xv ((sc)->state[31])
|
||||
|
||||
#else
|
||||
|
||||
#define DECL_STATE \
|
||||
sph_u32 x0, x1, x2, x3, x4, x5, x6, x7; \
|
||||
sph_u32 x8, x9, xa, xb, xc, xd, xe, xf; \
|
||||
sph_u32 xg, xh, xi, xj, xk, xl, xm, xn; \
|
||||
sph_u32 xo, xp, xq, xr, xs, xt, xu, xv;
|
||||
|
||||
#define READ_STATE(cc) do { \
|
||||
x0 = (cc)->state[ 0]; \
|
||||
x1 = (cc)->state[ 1]; \
|
||||
x2 = (cc)->state[ 2]; \
|
||||
x3 = (cc)->state[ 3]; \
|
||||
x4 = (cc)->state[ 4]; \
|
||||
x5 = (cc)->state[ 5]; \
|
||||
x6 = (cc)->state[ 6]; \
|
||||
x7 = (cc)->state[ 7]; \
|
||||
x8 = (cc)->state[ 8]; \
|
||||
x9 = (cc)->state[ 9]; \
|
||||
xa = (cc)->state[10]; \
|
||||
xb = (cc)->state[11]; \
|
||||
xc = (cc)->state[12]; \
|
||||
xd = (cc)->state[13]; \
|
||||
xe = (cc)->state[14]; \
|
||||
xf = (cc)->state[15]; \
|
||||
xg = (cc)->state[16]; \
|
||||
xh = (cc)->state[17]; \
|
||||
xi = (cc)->state[18]; \
|
||||
xj = (cc)->state[19]; \
|
||||
xk = (cc)->state[20]; \
|
||||
xl = (cc)->state[21]; \
|
||||
xm = (cc)->state[22]; \
|
||||
xn = (cc)->state[23]; \
|
||||
xo = (cc)->state[24]; \
|
||||
xp = (cc)->state[25]; \
|
||||
xq = (cc)->state[26]; \
|
||||
xr = (cc)->state[27]; \
|
||||
xs = (cc)->state[28]; \
|
||||
xt = (cc)->state[29]; \
|
||||
xu = (cc)->state[30]; \
|
||||
xv = (cc)->state[31]; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_STATE(cc) do { \
|
||||
(cc)->state[ 0] = x0; \
|
||||
(cc)->state[ 1] = x1; \
|
||||
(cc)->state[ 2] = x2; \
|
||||
(cc)->state[ 3] = x3; \
|
||||
(cc)->state[ 4] = x4; \
|
||||
(cc)->state[ 5] = x5; \
|
||||
(cc)->state[ 6] = x6; \
|
||||
(cc)->state[ 7] = x7; \
|
||||
(cc)->state[ 8] = x8; \
|
||||
(cc)->state[ 9] = x9; \
|
||||
(cc)->state[10] = xa; \
|
||||
(cc)->state[11] = xb; \
|
||||
(cc)->state[12] = xc; \
|
||||
(cc)->state[13] = xd; \
|
||||
(cc)->state[14] = xe; \
|
||||
(cc)->state[15] = xf; \
|
||||
(cc)->state[16] = xg; \
|
||||
(cc)->state[17] = xh; \
|
||||
(cc)->state[18] = xi; \
|
||||
(cc)->state[19] = xj; \
|
||||
(cc)->state[20] = xk; \
|
||||
(cc)->state[21] = xl; \
|
||||
(cc)->state[22] = xm; \
|
||||
(cc)->state[23] = xn; \
|
||||
(cc)->state[24] = xo; \
|
||||
(cc)->state[25] = xp; \
|
||||
(cc)->state[26] = xq; \
|
||||
(cc)->state[27] = xr; \
|
||||
(cc)->state[28] = xs; \
|
||||
(cc)->state[29] = xt; \
|
||||
(cc)->state[30] = xu; \
|
||||
(cc)->state[31] = xv; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define INPUT_BLOCK do { \
|
||||
x0 ^= sph_dec32le_aligned(buf + 0); \
|
||||
x1 ^= sph_dec32le_aligned(buf + 4); \
|
||||
x2 ^= sph_dec32le_aligned(buf + 8); \
|
||||
x3 ^= sph_dec32le_aligned(buf + 12); \
|
||||
x4 ^= sph_dec32le_aligned(buf + 16); \
|
||||
x5 ^= sph_dec32le_aligned(buf + 20); \
|
||||
x6 ^= sph_dec32le_aligned(buf + 24); \
|
||||
x7 ^= sph_dec32le_aligned(buf + 28); \
|
||||
} while (0)
|
||||
|
||||
#define ROUND_EVEN do { \
|
||||
xg = T32(x0 + xg); \
|
||||
x0 = ROTL32(x0, 7); \
|
||||
xh = T32(x1 + xh); \
|
||||
x1 = ROTL32(x1, 7); \
|
||||
xi = T32(x2 + xi); \
|
||||
x2 = ROTL32(x2, 7); \
|
||||
xj = T32(x3 + xj); \
|
||||
x3 = ROTL32(x3, 7); \
|
||||
xk = T32(x4 + xk); \
|
||||
x4 = ROTL32(x4, 7); \
|
||||
xl = T32(x5 + xl); \
|
||||
x5 = ROTL32(x5, 7); \
|
||||
xm = T32(x6 + xm); \
|
||||
x6 = ROTL32(x6, 7); \
|
||||
xn = T32(x7 + xn); \
|
||||
x7 = ROTL32(x7, 7); \
|
||||
xo = T32(x8 + xo); \
|
||||
x8 = ROTL32(x8, 7); \
|
||||
xp = T32(x9 + xp); \
|
||||
x9 = ROTL32(x9, 7); \
|
||||
xq = T32(xa + xq); \
|
||||
xa = ROTL32(xa, 7); \
|
||||
xr = T32(xb + xr); \
|
||||
xb = ROTL32(xb, 7); \
|
||||
xs = T32(xc + xs); \
|
||||
xc = ROTL32(xc, 7); \
|
||||
xt = T32(xd + xt); \
|
||||
xd = ROTL32(xd, 7); \
|
||||
xu = T32(xe + xu); \
|
||||
xe = ROTL32(xe, 7); \
|
||||
xv = T32(xf + xv); \
|
||||
xf = ROTL32(xf, 7); \
|
||||
x8 ^= xg; \
|
||||
x9 ^= xh; \
|
||||
xa ^= xi; \
|
||||
xb ^= xj; \
|
||||
xc ^= xk; \
|
||||
xd ^= xl; \
|
||||
xe ^= xm; \
|
||||
xf ^= xn; \
|
||||
x0 ^= xo; \
|
||||
x1 ^= xp; \
|
||||
x2 ^= xq; \
|
||||
x3 ^= xr; \
|
||||
x4 ^= xs; \
|
||||
x5 ^= xt; \
|
||||
x6 ^= xu; \
|
||||
x7 ^= xv; \
|
||||
xi = T32(x8 + xi); \
|
||||
x8 = ROTL32(x8, 11); \
|
||||
xj = T32(x9 + xj); \
|
||||
x9 = ROTL32(x9, 11); \
|
||||
xg = T32(xa + xg); \
|
||||
xa = ROTL32(xa, 11); \
|
||||
xh = T32(xb + xh); \
|
||||
xb = ROTL32(xb, 11); \
|
||||
xm = T32(xc + xm); \
|
||||
xc = ROTL32(xc, 11); \
|
||||
xn = T32(xd + xn); \
|
||||
xd = ROTL32(xd, 11); \
|
||||
xk = T32(xe + xk); \
|
||||
xe = ROTL32(xe, 11); \
|
||||
xl = T32(xf + xl); \
|
||||
xf = ROTL32(xf, 11); \
|
||||
xq = T32(x0 + xq); \
|
||||
x0 = ROTL32(x0, 11); \
|
||||
xr = T32(x1 + xr); \
|
||||
x1 = ROTL32(x1, 11); \
|
||||
xo = T32(x2 + xo); \
|
||||
x2 = ROTL32(x2, 11); \
|
||||
xp = T32(x3 + xp); \
|
||||
x3 = ROTL32(x3, 11); \
|
||||
xu = T32(x4 + xu); \
|
||||
x4 = ROTL32(x4, 11); \
|
||||
xv = T32(x5 + xv); \
|
||||
x5 = ROTL32(x5, 11); \
|
||||
xs = T32(x6 + xs); \
|
||||
x6 = ROTL32(x6, 11); \
|
||||
xt = T32(x7 + xt); \
|
||||
x7 = ROTL32(x7, 11); \
|
||||
xc ^= xi; \
|
||||
xd ^= xj; \
|
||||
xe ^= xg; \
|
||||
xf ^= xh; \
|
||||
x8 ^= xm; \
|
||||
x9 ^= xn; \
|
||||
xa ^= xk; \
|
||||
xb ^= xl; \
|
||||
x4 ^= xq; \
|
||||
x5 ^= xr; \
|
||||
x6 ^= xo; \
|
||||
x7 ^= xp; \
|
||||
x0 ^= xu; \
|
||||
x1 ^= xv; \
|
||||
x2 ^= xs; \
|
||||
x3 ^= xt; \
|
||||
} while (0)
|
||||
|
||||
#define ROUND_ODD do { \
|
||||
xj = T32(xc + xj); \
|
||||
xc = ROTL32(xc, 7); \
|
||||
xi = T32(xd + xi); \
|
||||
xd = ROTL32(xd, 7); \
|
||||
xh = T32(xe + xh); \
|
||||
xe = ROTL32(xe, 7); \
|
||||
xg = T32(xf + xg); \
|
||||
xf = ROTL32(xf, 7); \
|
||||
xn = T32(x8 + xn); \
|
||||
x8 = ROTL32(x8, 7); \
|
||||
xm = T32(x9 + xm); \
|
||||
x9 = ROTL32(x9, 7); \
|
||||
xl = T32(xa + xl); \
|
||||
xa = ROTL32(xa, 7); \
|
||||
xk = T32(xb + xk); \
|
||||
xb = ROTL32(xb, 7); \
|
||||
xr = T32(x4 + xr); \
|
||||
x4 = ROTL32(x4, 7); \
|
||||
xq = T32(x5 + xq); \
|
||||
x5 = ROTL32(x5, 7); \
|
||||
xp = T32(x6 + xp); \
|
||||
x6 = ROTL32(x6, 7); \
|
||||
xo = T32(x7 + xo); \
|
||||
x7 = ROTL32(x7, 7); \
|
||||
xv = T32(x0 + xv); \
|
||||
x0 = ROTL32(x0, 7); \
|
||||
xu = T32(x1 + xu); \
|
||||
x1 = ROTL32(x1, 7); \
|
||||
xt = T32(x2 + xt); \
|
||||
x2 = ROTL32(x2, 7); \
|
||||
xs = T32(x3 + xs); \
|
||||
x3 = ROTL32(x3, 7); \
|
||||
x4 ^= xj; \
|
||||
x5 ^= xi; \
|
||||
x6 ^= xh; \
|
||||
x7 ^= xg; \
|
||||
x0 ^= xn; \
|
||||
x1 ^= xm; \
|
||||
x2 ^= xl; \
|
||||
x3 ^= xk; \
|
||||
xc ^= xr; \
|
||||
xd ^= xq; \
|
||||
xe ^= xp; \
|
||||
xf ^= xo; \
|
||||
x8 ^= xv; \
|
||||
x9 ^= xu; \
|
||||
xa ^= xt; \
|
||||
xb ^= xs; \
|
||||
xh = T32(x4 + xh); \
|
||||
x4 = ROTL32(x4, 11); \
|
||||
xg = T32(x5 + xg); \
|
||||
x5 = ROTL32(x5, 11); \
|
||||
xj = T32(x6 + xj); \
|
||||
x6 = ROTL32(x6, 11); \
|
||||
xi = T32(x7 + xi); \
|
||||
x7 = ROTL32(x7, 11); \
|
||||
xl = T32(x0 + xl); \
|
||||
x0 = ROTL32(x0, 11); \
|
||||
xk = T32(x1 + xk); \
|
||||
x1 = ROTL32(x1, 11); \
|
||||
xn = T32(x2 + xn); \
|
||||
x2 = ROTL32(x2, 11); \
|
||||
xm = T32(x3 + xm); \
|
||||
x3 = ROTL32(x3, 11); \
|
||||
xp = T32(xc + xp); \
|
||||
xc = ROTL32(xc, 11); \
|
||||
xo = T32(xd + xo); \
|
||||
xd = ROTL32(xd, 11); \
|
||||
xr = T32(xe + xr); \
|
||||
xe = ROTL32(xe, 11); \
|
||||
xq = T32(xf + xq); \
|
||||
xf = ROTL32(xf, 11); \
|
||||
xt = T32(x8 + xt); \
|
||||
x8 = ROTL32(x8, 11); \
|
||||
xs = T32(x9 + xs); \
|
||||
x9 = ROTL32(x9, 11); \
|
||||
xv = T32(xa + xv); \
|
||||
xa = ROTL32(xa, 11); \
|
||||
xu = T32(xb + xu); \
|
||||
xb = ROTL32(xb, 11); \
|
||||
x0 ^= xh; \
|
||||
x1 ^= xg; \
|
||||
x2 ^= xj; \
|
||||
x3 ^= xi; \
|
||||
x4 ^= xl; \
|
||||
x5 ^= xk; \
|
||||
x6 ^= xn; \
|
||||
x7 ^= xm; \
|
||||
x8 ^= xp; \
|
||||
x9 ^= xo; \
|
||||
xa ^= xr; \
|
||||
xb ^= xq; \
|
||||
xc ^= xt; \
|
||||
xd ^= xs; \
|
||||
xe ^= xv; \
|
||||
xf ^= xu; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* There is no need to unroll all 16 rounds. The word-swapping permutation
|
||||
* is an involution, so we need to unroll an even number of rounds. On
|
||||
* "big" systems, unrolling 4 rounds yields about 97% of the speed
|
||||
* achieved with full unrolling; and it keeps the code more compact
|
||||
* for small architectures.
|
||||
*/
|
||||
|
||||
#if SPH_CUBEHASH_UNROLL == 2
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
int j; \
|
||||
for (j = 0; j < 8; j ++) { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#elif SPH_CUBEHASH_UNROLL == 4
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
int j; \
|
||||
for (j = 0; j < 4; j ++) { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#elif SPH_CUBEHASH_UNROLL == 8
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
int j; \
|
||||
for (j = 0; j < 2; j ++) { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
cubehash_init(sph_cubehash_context *sc, const sph_u32 *iv)
|
||||
{
|
||||
memcpy(sc->state, iv, sizeof sc->state);
|
||||
sc->ptr = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cubehash_core(sph_cubehash_context *sc, const void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
size_t ptr;
|
||||
DECL_STATE
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
if (len < (sizeof sc->buf) - ptr) {
|
||||
memcpy(buf + ptr, data, len);
|
||||
ptr += len;
|
||||
sc->ptr = ptr;
|
||||
return;
|
||||
}
|
||||
|
||||
READ_STATE(sc);
|
||||
while (len > 0) {
|
||||
size_t clen;
|
||||
|
||||
clen = (sizeof sc->buf) - ptr;
|
||||
if (clen > len)
|
||||
clen = len;
|
||||
memcpy(buf + ptr, data, clen);
|
||||
ptr += clen;
|
||||
data = (const unsigned char *)data + clen;
|
||||
len -= clen;
|
||||
if (ptr == sizeof sc->buf) {
|
||||
INPUT_BLOCK;
|
||||
SIXTEEN_ROUNDS;
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
WRITE_STATE(sc);
|
||||
sc->ptr = ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
cubehash_close(sph_cubehash_context *sc, unsigned ub, unsigned n,
|
||||
void *dst, size_t out_size_w32)
|
||||
{
|
||||
unsigned char *buf, *out;
|
||||
size_t ptr;
|
||||
unsigned z;
|
||||
int i;
|
||||
DECL_STATE
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
z = 0x80 >> n;
|
||||
buf[ptr ++] = ((ub & -z) | z) & 0xFF;
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
|
||||
READ_STATE(sc);
|
||||
INPUT_BLOCK;
|
||||
for (i = 0; i < 11; i ++) {
|
||||
SIXTEEN_ROUNDS;
|
||||
if (i == 0)
|
||||
xv ^= SPH_C32(1);
|
||||
}
|
||||
WRITE_STATE(sc);
|
||||
out = dst;
|
||||
for (z = 0; z < out_size_w32; z ++)
|
||||
sph_enc32le(out + (z << 2), sc->state[z]);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224_init(void *cc)
|
||||
{
|
||||
cubehash_init(cc, IV224);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash224_addbits_and_close(cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close(cc, ub, n, dst, 7);
|
||||
sph_cubehash224_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256_init(void *cc)
|
||||
{
|
||||
cubehash_init(cc, IV256);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash256_addbits_and_close(cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close(cc, ub, n, dst, 8);
|
||||
sph_cubehash256_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384_init(void *cc)
|
||||
{
|
||||
cubehash_init(cc, IV384);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash384_addbits_and_close(cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close(cc, ub, n, dst, 12);
|
||||
sph_cubehash384_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512_init(void *cc)
|
||||
{
|
||||
cubehash_init(cc, IV512);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash512_addbits_and_close(cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close(cc, ub, n, dst, 16);
|
||||
sph_cubehash512_init(cc);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+1031
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "crypto/hmac_sha256.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
CHMAC_SHA256::CHMAC_SHA256(const unsigned char* key, size_t keylen)
|
||||
{
|
||||
unsigned char rkey[64];
|
||||
if (keylen <= 64) {
|
||||
memcpy(rkey, key, keylen);
|
||||
memset(rkey + keylen, 0, 64 - keylen);
|
||||
} else {
|
||||
CSHA256().Write(key, keylen).Finalize(rkey);
|
||||
memset(rkey + 32, 0, 32);
|
||||
}
|
||||
|
||||
for (int n = 0; n < 64; n++)
|
||||
rkey[n] ^= 0x5c;
|
||||
outer.Write(rkey, 64);
|
||||
|
||||
for (int n = 0; n < 64; n++)
|
||||
rkey[n] ^= 0x5c ^ 0x36;
|
||||
inner.Write(rkey, 64);
|
||||
}
|
||||
|
||||
void CHMAC_SHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
unsigned char temp[32];
|
||||
inner.Finalize(temp);
|
||||
outer.Write(temp, 32).Finalize(hash);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CRYPTO_HMAC_SHA256_H
|
||||
#define BITCOIN_CRYPTO_HMAC_SHA256_H
|
||||
|
||||
#include "crypto/sha256.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** A hasher class for HMAC-SHA-256. */
|
||||
class CHMAC_SHA256
|
||||
{
|
||||
private:
|
||||
CSHA256 outer;
|
||||
CSHA256 inner;
|
||||
|
||||
public:
|
||||
static const size_t OUTPUT_SIZE = 32;
|
||||
|
||||
CHMAC_SHA256(const unsigned char* key, size_t keylen);
|
||||
CHMAC_SHA256& Write(const unsigned char* data, size_t len)
|
||||
{
|
||||
inner.Write(data, len);
|
||||
return *this;
|
||||
}
|
||||
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_CRYPTO_HMAC_SHA256_H
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "crypto/hmac_sha512.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CRYPTO_HMAC_SHA512_H
|
||||
#define BITCOIN_CRYPTO_HMAC_SHA512_H
|
||||
|
||||
#include "crypto/sha512.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** 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 // BITCOIN_CRYPTO_HMAC_SHA512_H
|
||||
+1116
File diff suppressed because it is too large
Load Diff
+1824
File diff suppressed because it is too large
Load Diff
+1426
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "crypto/rfc6979_hmac_sha256.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
static const unsigned char zero[1] = {0x00};
|
||||
static const unsigned char one[1] = {0x01};
|
||||
|
||||
RFC6979_HMAC_SHA256::RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen) : retry(false)
|
||||
{
|
||||
memset(V, 0x01, sizeof(V));
|
||||
memset(K, 0x00, sizeof(K));
|
||||
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Write(key, keylen).Write(msg, msglen).Finalize(K);
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(one, sizeof(one)).Write(key, keylen).Write(msg, msglen).Finalize(K);
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
|
||||
}
|
||||
|
||||
RFC6979_HMAC_SHA256::~RFC6979_HMAC_SHA256()
|
||||
{
|
||||
memset(V, 0x01, sizeof(V));
|
||||
memset(K, 0x00, sizeof(K));
|
||||
}
|
||||
|
||||
void RFC6979_HMAC_SHA256::Generate(unsigned char* output, size_t outputlen)
|
||||
{
|
||||
if (retry) {
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Finalize(K);
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
|
||||
}
|
||||
|
||||
while (outputlen > 0) {
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
|
||||
size_t len = std::min(outputlen, sizeof(V));
|
||||
memcpy(output, V, len);
|
||||
output += len;
|
||||
outputlen -= len;
|
||||
}
|
||||
|
||||
retry = true;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_RFC6979_HMAC_SHA256_H
|
||||
#define BITCOIN_RFC6979_HMAC_SHA256_H
|
||||
|
||||
#include "crypto/hmac_sha256.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** The RFC 6979 PRNG using HMAC-SHA256. */
|
||||
class RFC6979_HMAC_SHA256
|
||||
{
|
||||
private:
|
||||
unsigned char V[CHMAC_SHA256::OUTPUT_SIZE];
|
||||
unsigned char K[CHMAC_SHA256::OUTPUT_SIZE];
|
||||
bool retry;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a new RFC6979 PRNG, using the given key and message.
|
||||
* The message is assumed to be already hashed.
|
||||
*/
|
||||
RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen);
|
||||
|
||||
/**
|
||||
* Generate a byte array.
|
||||
*/
|
||||
void Generate(unsigned char* output, size_t outputlen);
|
||||
|
||||
~RFC6979_HMAC_SHA256();
|
||||
};
|
||||
|
||||
#endif // BITCOIN_RFC6979_HMAC_SHA256_H
|
||||
@@ -0,0 +1,292 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT 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;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CRYPTO_RIPEMD160_H
|
||||
#define BITCOIN_CRYPTO_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 // BITCOIN_CRYPTO_RIPEMD160_H
|
||||
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright 2009 Colin Percival, 2011 ArtForz, 2012-2013 pooler
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file was originally written by Colin Percival as part of the Tarsnap
|
||||
* online backup system.
|
||||
*/
|
||||
|
||||
#include "crypto/scrypt.h"
|
||||
#include "uint256.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include <openssl/sha.h>
|
||||
#include <string>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
static inline void be32enc(void *pp, uint32_t x)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
p[3] = x & 0xff;
|
||||
p[2] = (x >> 8) & 0xff;
|
||||
p[1] = (x >> 16) & 0xff;
|
||||
p[0] = (x >> 24) & 0xff;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct HMAC_SHA256Context {
|
||||
SHA256_CTX ictx;
|
||||
SHA256_CTX octx;
|
||||
} HMAC_SHA256_CTX;
|
||||
|
||||
/* Initialize an HMAC-SHA256 operation with the given key. */
|
||||
static void
|
||||
HMAC_SHA256_Init(HMAC_SHA256_CTX *ctx, const void *_K, size_t Klen)
|
||||
{
|
||||
unsigned char pad[64];
|
||||
unsigned char khash[32];
|
||||
const unsigned char *K = (const unsigned char *)_K;
|
||||
size_t i;
|
||||
|
||||
/* If Klen > 64, the key is really SHA256(K). */
|
||||
if (Klen > 64) {
|
||||
SHA256_Init(&ctx->ictx);
|
||||
SHA256_Update(&ctx->ictx, K, Klen);
|
||||
SHA256_Final(khash, &ctx->ictx);
|
||||
K = khash;
|
||||
Klen = 32;
|
||||
}
|
||||
|
||||
/* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
|
||||
SHA256_Init(&ctx->ictx);
|
||||
memset(pad, 0x36, 64);
|
||||
for (i = 0; i < Klen; i++)
|
||||
pad[i] ^= K[i];
|
||||
SHA256_Update(&ctx->ictx, pad, 64);
|
||||
|
||||
/* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
|
||||
SHA256_Init(&ctx->octx);
|
||||
memset(pad, 0x5c, 64);
|
||||
for (i = 0; i < Klen; i++)
|
||||
pad[i] ^= K[i];
|
||||
SHA256_Update(&ctx->octx, pad, 64);
|
||||
|
||||
/* Clean the stack. */
|
||||
memset(khash, 0, 32);
|
||||
}
|
||||
|
||||
/* Add bytes to the HMAC-SHA256 operation. */
|
||||
static void
|
||||
HMAC_SHA256_Update(HMAC_SHA256_CTX *ctx, const void *in, size_t len)
|
||||
{
|
||||
/* Feed data to the inner SHA256 operation. */
|
||||
SHA256_Update(&ctx->ictx, in, len);
|
||||
}
|
||||
|
||||
/* Finish an HMAC-SHA256 operation. */
|
||||
static void
|
||||
HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX *ctx)
|
||||
{
|
||||
unsigned char ihash[32];
|
||||
|
||||
/* Finish the inner SHA256 operation. */
|
||||
SHA256_Final(ihash, &ctx->ictx);
|
||||
|
||||
/* Feed the inner hash to the outer SHA256 operation. */
|
||||
SHA256_Update(&ctx->octx, ihash, 32);
|
||||
|
||||
/* Finish the outer SHA256 operation. */
|
||||
SHA256_Final(digest, &ctx->octx);
|
||||
|
||||
/* Clean the stack. */
|
||||
memset(ihash, 0, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
||||
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
|
||||
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
|
||||
*/
|
||||
void
|
||||
PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt,
|
||||
size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen)
|
||||
{
|
||||
HMAC_SHA256_CTX PShctx, hctx;
|
||||
size_t i;
|
||||
uint8_t ivec[4];
|
||||
uint8_t U[32];
|
||||
uint8_t T[32];
|
||||
uint64_t j;
|
||||
int k;
|
||||
size_t clen;
|
||||
|
||||
/* Compute HMAC state after processing P and S. */
|
||||
HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
|
||||
HMAC_SHA256_Update(&PShctx, salt, saltlen);
|
||||
|
||||
/* Iterate through the blocks. */
|
||||
for (i = 0; i * 32 < dkLen; i++) {
|
||||
/* Generate INT(i + 1). */
|
||||
be32enc(ivec, (uint32_t)(i + 1));
|
||||
|
||||
/* Compute U_1 = PRF(P, S || INT(i)). */
|
||||
memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
|
||||
HMAC_SHA256_Update(&hctx, ivec, 4);
|
||||
HMAC_SHA256_Final(U, &hctx);
|
||||
|
||||
/* T_i = U_1 ... */
|
||||
memcpy(T, U, 32);
|
||||
|
||||
for (j = 2; j <= c; j++) {
|
||||
/* Compute U_j. */
|
||||
HMAC_SHA256_Init(&hctx, passwd, passwdlen);
|
||||
HMAC_SHA256_Update(&hctx, U, 32);
|
||||
HMAC_SHA256_Final(U, &hctx);
|
||||
|
||||
/* ... xor U_j ... */
|
||||
for (k = 0; k < 32; k++)
|
||||
T[k] ^= U[k];
|
||||
}
|
||||
|
||||
/* Copy as many bytes as necessary into buf. */
|
||||
clen = dkLen - i * 32;
|
||||
if (clen > 32)
|
||||
clen = 32;
|
||||
memcpy(&buf[i * 32], T, clen);
|
||||
}
|
||||
|
||||
/* Clean PShctx, since we never called _Final on it. */
|
||||
memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
le32dec_2(const void * pp)
|
||||
{
|
||||
const uint8_t * p = (uint8_t const *)pp;
|
||||
|
||||
return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
|
||||
((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
|
||||
}
|
||||
|
||||
static inline void
|
||||
le32enc_2(void * pp, uint32_t x)
|
||||
{
|
||||
uint8_t * p = (uint8_t *)pp;
|
||||
|
||||
p[0] = x & 0xff;
|
||||
p[1] = (x >> 8) & 0xff;
|
||||
p[2] = (x >> 16) & 0xff;
|
||||
p[3] = (x >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
blkcpy(void * dest, const void * src, size_t len)
|
||||
{
|
||||
size_t * D = (size_t*)dest;
|
||||
const size_t * S = (size_t*)src;
|
||||
size_t L = len / sizeof(size_t);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < L; i++)
|
||||
D[i] = S[i];
|
||||
}
|
||||
|
||||
static void
|
||||
blkxor(void * dest, const void * src, size_t len)
|
||||
{
|
||||
size_t * D = (size_t*)dest;
|
||||
const size_t* S = (size_t*)src;
|
||||
size_t L = len / sizeof(size_t);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < L; i++)
|
||||
D[i] ^= S[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* salsa20_8(B):
|
||||
* Apply the salsa20/8 core to the provided block.
|
||||
*/
|
||||
static void
|
||||
salsa20_8(uint32_t B[16])
|
||||
{
|
||||
uint32_t x[16];
|
||||
size_t i;
|
||||
|
||||
blkcpy(x, B, 64);
|
||||
for (i = 0; i < 8; i += 2) {
|
||||
#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
|
||||
/* Operate on columns. */
|
||||
x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
|
||||
x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
|
||||
|
||||
x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
|
||||
x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
|
||||
|
||||
x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
|
||||
x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
|
||||
|
||||
x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
|
||||
x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
|
||||
|
||||
/* Operate on rows. */
|
||||
x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
|
||||
x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
|
||||
|
||||
x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
|
||||
x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
|
||||
|
||||
x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
|
||||
x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
|
||||
|
||||
x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
|
||||
x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
|
||||
#undef R
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
B[i] += x[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* blockmix_salsa8(Bin, Bout, X, r):
|
||||
* Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
|
||||
* bytes in length; the output Bout must also be the same size. The
|
||||
* temporary space X must be 64 bytes.
|
||||
*/
|
||||
static void
|
||||
blockmix_salsa8(const uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* 1: X <-- B_{2r - 1} */
|
||||
blkcpy(X, &Bin[(2 * r - 1) * 16], 64);
|
||||
|
||||
/* 2: for i = 0 to 2r - 1 do */
|
||||
for (i = 0; i < 2 * r; i += 2) {
|
||||
/* 3: X <-- H(X \xor B_i) */
|
||||
blkxor(X, &Bin[i * 16], 64);
|
||||
salsa20_8(X);
|
||||
|
||||
/* 4: Y_i <-- X */
|
||||
/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
|
||||
blkcpy(&Bout[i * 8], X, 64);
|
||||
|
||||
/* 3: X <-- H(X \xor B_i) */
|
||||
blkxor(X, &Bin[i * 16 + 16], 64);
|
||||
salsa20_8(X);
|
||||
|
||||
/* 4: Y_i <-- X */
|
||||
/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
|
||||
blkcpy(&Bout[i * 8 + r * 16], X, 64);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* integerify(B, r):
|
||||
* Return the result of parsing B_{2r-1} as a little-endian integer.
|
||||
*/
|
||||
static uint64_t
|
||||
integerify(const void * B, size_t r)
|
||||
{
|
||||
const uint32_t * X = (const uint32_t*)((uintptr_t)(B) + (2 * r - 1) * 64);
|
||||
|
||||
return (((uint64_t)(X[1]) << 32) + X[0]);
|
||||
}
|
||||
|
||||
void SMix(uint8_t *B, unsigned int r, unsigned int N, void* _V, void* XY)
|
||||
{
|
||||
//new
|
||||
uint32_t* X = (uint32_t*)XY;
|
||||
uint32_t* Y = (uint32_t*)((uint8_t*)(XY) + 128 * r);
|
||||
uint32_t* Z = (uint32_t*)((uint8_t *)(XY) + 256 * r);
|
||||
uint32_t * V = (uint32_t*)_V;
|
||||
|
||||
uint32_t j, k;
|
||||
|
||||
/* 1: X <-- B */
|
||||
for (k = 0; k < 32 * r; k++)
|
||||
X[k] = le32dec_2(&B[4 * k]);
|
||||
|
||||
/* 2: for i = 0 to N - 1 do */
|
||||
for (unsigned int i = 0; i < N; i += 2)
|
||||
{
|
||||
/* 3: V_i <-- X */
|
||||
blkcpy(&V[i * (32 * r)], X, 128 * r);
|
||||
|
||||
/* 4: X <-- H(X) */
|
||||
blockmix_salsa8(X, Y, Z, r);
|
||||
|
||||
/* 3: V_i <-- X */
|
||||
blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r);
|
||||
|
||||
/* 4: X <-- H(X) */
|
||||
blockmix_salsa8(Y, X, Z, r);
|
||||
}
|
||||
|
||||
/* 6: for i = 0 to N - 1 do */
|
||||
for (unsigned int i = 0; i < N; i += 2)
|
||||
{
|
||||
/* 7: j <-- Integerify(X) mod N */
|
||||
j = integerify(X, r) & (N - 1);
|
||||
|
||||
/* 8: X <-- H(X \xor V_j) */
|
||||
blkxor(X, &V[j * (32 * r)], 128 * r);
|
||||
blockmix_salsa8(X, Y, Z, r);
|
||||
|
||||
/* 7: j <-- Integerify(X) mod N */
|
||||
j = integerify(Y, r) & (N - 1);
|
||||
|
||||
/* 8: X <-- H(X \xor V_j) */
|
||||
blkxor(Y, &V[j * (32 * r)], 128 * r);
|
||||
blockmix_salsa8(Y, X, Z, r);
|
||||
}
|
||||
|
||||
/* 10: B' <-- X */
|
||||
for (k = 0; k < 32 * r; k++)
|
||||
le32enc_2(&B[4 * k], X[k]);
|
||||
}
|
||||
|
||||
void scrypt(const char* pass, unsigned int pLen, const char* salt, unsigned int sLen, char *output, unsigned int N, unsigned int r, unsigned int p, unsigned int dkLen)
|
||||
{
|
||||
//containers
|
||||
void* V0 = malloc(128 * r * N + 63);
|
||||
void* XY0 = malloc(256 * r + 64 + 63);
|
||||
void* B1 = malloc(128 * r * p + 63);
|
||||
uint8_t* B = (uint8_t *)(((uintptr_t)(B1) + 63) & ~ (uintptr_t)(63));
|
||||
uint32_t* V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
|
||||
uint32_t* XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
|
||||
|
||||
PBKDF2_SHA256((const uint8_t *)pass, pLen, (const uint8_t *)salt, sLen, 1, B, p * 128 * r);
|
||||
|
||||
for(unsigned int i = 0; i < p; i++)
|
||||
{
|
||||
SMix(&B[i * 128 * r], r, N, V, XY);
|
||||
}
|
||||
|
||||
PBKDF2_SHA256((const uint8_t *)pass, pLen, B, p * 128 * r, 1, (uint8_t *)output, dkLen);
|
||||
|
||||
free(V0);
|
||||
free(XY0);
|
||||
free(B1);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef SCRYPT_H
|
||||
#define SCRYPT_H
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
void scrypt(const char* pass, unsigned int pLen, const char* salt, unsigned int sLen, char *output, unsigned int N, unsigned int r, unsigned int p, unsigned int dkLen);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,199 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT 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;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CRYPTO_SHA1_H
|
||||
#define BITCOIN_CRYPTO_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 // BITCOIN_CRYPTO_SHA1_H
|
||||
@@ -0,0 +1,189 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "crypto/sha256.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
|
||||
} // 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;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CRYPTO_SHA256_H
|
||||
#define BITCOIN_CRYPTO_SHA256_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();
|
||||
};
|
||||
|
||||
#endif // BITCOIN_CRYPTO_SHA256_H
|
||||
@@ -0,0 +1,207 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "crypto/sha512.h"
|
||||
|
||||
#include "crypto/common.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Internal implementation code.
|
||||
namespace
|
||||
{
|
||||
/// 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-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;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CRYPTO_SHA512_H
|
||||
#define BITCOIN_CRYPTO_SHA512_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** 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();
|
||||
};
|
||||
|
||||
#endif // BITCOIN_CRYPTO_SHA512_H
|
||||
File diff suppressed because it is too large
Load Diff
+1799
File diff suppressed because it is too large
Load Diff
+1254
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,327 @@
|
||||
/* $Id: sph_blake.h 252 2011-06-07 17:55:14Z tp $ */
|
||||
/**
|
||||
* BLAKE interface. BLAKE is a family of functions which differ by their
|
||||
* output size; this implementation defines BLAKE for output sizes 224,
|
||||
* 256, 384 and 512 bits. This implementation conforms to the "third
|
||||
* round" specification.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_blake.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_BLAKE_H__
|
||||
#define SPH_BLAKE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BLAKE-224.
|
||||
*/
|
||||
#define SPH_SIZE_blake224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BLAKE-256.
|
||||
*/
|
||||
#define SPH_SIZE_blake256 256
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BLAKE-384.
|
||||
*/
|
||||
#define SPH_SIZE_blake384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BLAKE-512.
|
||||
*/
|
||||
#define SPH_SIZE_blake512 512
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-224 and BLAKE-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a BLAKE computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running BLAKE
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 H[8];
|
||||
sph_u32 S[4];
|
||||
sph_u32 T0, T1;
|
||||
#endif
|
||||
} sph_blake_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-224 computations. It is
|
||||
* identical to the common <code>sph_blake_small_context</code>.
|
||||
*/
|
||||
typedef sph_blake_small_context sph_blake224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-256 computations. It is
|
||||
* identical to the common <code>sph_blake_small_context</code>.
|
||||
*/
|
||||
typedef sph_blake_small_context sph_blake256_context;
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-384 and BLAKE-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a BLAKE computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running BLAKE
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u64 H[8];
|
||||
sph_u64 S[4];
|
||||
sph_u64 T0, T1;
|
||||
#endif
|
||||
} sph_blake_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-384 computations. It is
|
||||
* identical to the common <code>sph_blake_small_context</code>.
|
||||
*/
|
||||
typedef sph_blake_big_context sph_blake384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-512 computations. It is
|
||||
* identical to the common <code>sph_blake_small_context</code>.
|
||||
*/
|
||||
typedef sph_blake_big_context sph_blake512_context;
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize a BLAKE-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BLAKE-224 context (pointer to a
|
||||
* <code>sph_blake224_context</code>)
|
||||
*/
|
||||
void sph_blake224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BLAKE-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_blake224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BLAKE-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a BLAKE-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BLAKE-256 context (pointer to a
|
||||
* <code>sph_blake256_context</code>)
|
||||
*/
|
||||
void sph_blake256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BLAKE-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_blake256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BLAKE-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* Initialize a BLAKE-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BLAKE-384 context (pointer to a
|
||||
* <code>sph_blake384_context</code>)
|
||||
*/
|
||||
void sph_blake384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BLAKE-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_blake384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BLAKE-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a BLAKE-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BLAKE-512 context (pointer to a
|
||||
* <code>sph_blake512_context</code>)
|
||||
*/
|
||||
void sph_blake512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BLAKE-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_blake512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BLAKE-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,328 @@
|
||||
/* $Id: sph_bmw.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* BMW interface. BMW (aka "Blue Midnight Wish") is a family of
|
||||
* functions which differ by their output size; this implementation
|
||||
* defines BMW for output sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_bmw.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_BMW_H__
|
||||
#define SPH_BMW_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BMW-224.
|
||||
*/
|
||||
#define SPH_SIZE_bmw224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BMW-256.
|
||||
*/
|
||||
#define SPH_SIZE_bmw256 256
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BMW-384.
|
||||
*/
|
||||
#define SPH_SIZE_bmw384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BMW-512.
|
||||
*/
|
||||
#define SPH_SIZE_bmw512 512
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-224 and BMW-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a BMW computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running BMW
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 H[16];
|
||||
#if SPH_64
|
||||
sph_u64 bit_count;
|
||||
#else
|
||||
sph_u32 bit_count_high, bit_count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_bmw_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-224 computations. It is
|
||||
* identical to the common <code>sph_bmw_small_context</code>.
|
||||
*/
|
||||
typedef sph_bmw_small_context sph_bmw224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-256 computations. It is
|
||||
* identical to the common <code>sph_bmw_small_context</code>.
|
||||
*/
|
||||
typedef sph_bmw_small_context sph_bmw256_context;
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-384 and BMW-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a BMW computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running BMW
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u64 H[16];
|
||||
sph_u64 bit_count;
|
||||
#endif
|
||||
} sph_bmw_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-384 computations. It is
|
||||
* identical to the common <code>sph_bmw_small_context</code>.
|
||||
*/
|
||||
typedef sph_bmw_big_context sph_bmw384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-512 computations. It is
|
||||
* identical to the common <code>sph_bmw_small_context</code>.
|
||||
*/
|
||||
typedef sph_bmw_big_context sph_bmw512_context;
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize a BMW-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BMW-224 context (pointer to a
|
||||
* <code>sph_bmw224_context</code>)
|
||||
*/
|
||||
void sph_bmw224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BMW-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_bmw224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BMW-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BMW-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BMW-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a BMW-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BMW-256 context (pointer to a
|
||||
* <code>sph_bmw256_context</code>)
|
||||
*/
|
||||
void sph_bmw256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BMW-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_bmw256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BMW-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BMW-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BMW-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* Initialize a BMW-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BMW-384 context (pointer to a
|
||||
* <code>sph_bmw384_context</code>)
|
||||
*/
|
||||
void sph_bmw384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BMW-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_bmw384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BMW-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BMW-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BMW-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a BMW-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BMW-512 context (pointer to a
|
||||
* <code>sph_bmw512_context</code>)
|
||||
*/
|
||||
void sph_bmw512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BMW-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_bmw512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BMW-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BMW-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BMW-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,292 @@
|
||||
/* $Id: sph_cubehash.h 180 2010-05-08 02:29:25Z tp $ */
|
||||
/**
|
||||
* CubeHash interface. CubeHash is a family of functions which differ by
|
||||
* their output size; this implementation defines CubeHash for output
|
||||
* sizes 224, 256, 384 and 512 bits, with the "standard parameters"
|
||||
* (CubeHash16/32 with the CubeHash specification notations).
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_cubehash.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_CUBEHASH_H__
|
||||
#define SPH_CUBEHASH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-224.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-256.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-384.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-512.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for CubeHash computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* a CubeHash computation has been performed, the context can be reused for
|
||||
* another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running CubeHash computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 state[32];
|
||||
#endif
|
||||
} sph_cubehash_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-224 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash224_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-256 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash256_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-384 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash384_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-512 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash512_context;
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-224 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-224 context (pointer to a
|
||||
* <code>sph_cubehash224_context</code>)
|
||||
*/
|
||||
void sph_cubehash224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-256 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-256 context (pointer to a
|
||||
* <code>sph_cubehash256_context</code>)
|
||||
*/
|
||||
void sph_cubehash256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-384 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-384 context (pointer to a
|
||||
* <code>sph_cubehash384_context</code>)
|
||||
*/
|
||||
void sph_cubehash384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-512 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-512 context (pointer to a
|
||||
* <code>sph_cubehash512_context</code>)
|
||||
*/
|
||||
void sph_cubehash512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,320 @@
|
||||
/* $Id: sph_echo.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* ECHO interface. ECHO is a family of functions which differ by
|
||||
* their output size; this implementation defines ECHO for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_echo.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_ECHO_H__
|
||||
#define SPH_ECHO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-224.
|
||||
*/
|
||||
#define SPH_SIZE_echo224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-256.
|
||||
*/
|
||||
#define SPH_SIZE_echo256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-384.
|
||||
*/
|
||||
#define SPH_SIZE_echo384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-512.
|
||||
*/
|
||||
#define SPH_SIZE_echo512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for ECHO computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an ECHO computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for ECHO-224
|
||||
* and ECHO-256.
|
||||
*
|
||||
* The contents of this structure are private. A running ECHO computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[192]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
sph_u32 Vs[4][4];
|
||||
#if SPH_64
|
||||
sph_u64 Vb[4][2];
|
||||
#endif
|
||||
} u;
|
||||
sph_u32 C0, C1, C2, C3;
|
||||
#endif
|
||||
} sph_echo_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for ECHO computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an ECHO computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for ECHO-384
|
||||
* and ECHO-512.
|
||||
*
|
||||
* The contents of this structure are private. A running ECHO computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
sph_u32 Vs[8][4];
|
||||
#if SPH_64
|
||||
sph_u64 Vb[8][2];
|
||||
#endif
|
||||
} u;
|
||||
sph_u32 C0, C1, C2, C3;
|
||||
#endif
|
||||
} sph_echo_big_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-224 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_echo_small_context sph_echo224_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-256 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_echo_small_context sph_echo256_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-384 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_echo_big_context sph_echo384_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-512 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_echo_big_context sph_echo512_context;
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-224 context (pointer to a
|
||||
* <code>sph_echo224_context</code>)
|
||||
*/
|
||||
void sph_echo224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-256 context (pointer to a
|
||||
* <code>sph_echo256_context</code>)
|
||||
*/
|
||||
void sph_echo256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-384 context (pointer to a
|
||||
* <code>sph_echo384_context</code>)
|
||||
*/
|
||||
void sph_echo384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-512 context (pointer to a
|
||||
* <code>sph_echo512_context</code>)
|
||||
*/
|
||||
void sph_echo512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,329 @@
|
||||
/* $Id: sph_groestl.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* Groestl interface. This code implements Groestl with the recommended
|
||||
* parameters for SHA-3, with outputs of 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_groestl.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_GROESTL_H__
|
||||
#define SPH_GROESTL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Groestl-224.
|
||||
*/
|
||||
#define SPH_SIZE_groestl224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Groestl-256.
|
||||
*/
|
||||
#define SPH_SIZE_groestl256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Groestl-384.
|
||||
*/
|
||||
#define SPH_SIZE_groestl384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Groestl-512.
|
||||
*/
|
||||
#define SPH_SIZE_groestl512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-224 and Groestl-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a Groestl computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Groestl
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
#if SPH_64
|
||||
sph_u64 wide[8];
|
||||
#endif
|
||||
sph_u32 narrow[16];
|
||||
} state;
|
||||
#if SPH_64
|
||||
sph_u64 count;
|
||||
#else
|
||||
sph_u32 count_high, count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_groestl_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-224 computations. It is
|
||||
* identical to the common <code>sph_groestl_small_context</code>.
|
||||
*/
|
||||
typedef sph_groestl_small_context sph_groestl224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-256 computations. It is
|
||||
* identical to the common <code>sph_groestl_small_context</code>.
|
||||
*/
|
||||
typedef sph_groestl_small_context sph_groestl256_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-384 and Groestl-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a Groestl computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Groestl
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
#if SPH_64
|
||||
sph_u64 wide[16];
|
||||
#endif
|
||||
sph_u32 narrow[32];
|
||||
} state;
|
||||
#if SPH_64
|
||||
sph_u64 count;
|
||||
#else
|
||||
sph_u32 count_high, count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_groestl_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-384 computations. It is
|
||||
* identical to the common <code>sph_groestl_small_context</code>.
|
||||
*/
|
||||
typedef sph_groestl_big_context sph_groestl384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-512 computations. It is
|
||||
* identical to the common <code>sph_groestl_small_context</code>.
|
||||
*/
|
||||
typedef sph_groestl_big_context sph_groestl512_context;
|
||||
|
||||
/**
|
||||
* Initialize a Groestl-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Groestl-224 context (pointer to a
|
||||
* <code>sph_groestl224_context</code>)
|
||||
*/
|
||||
void sph_groestl224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Groestl-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_groestl224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Groestl-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Groestl-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Groestl-256 context (pointer to a
|
||||
* <code>sph_groestl256_context</code>)
|
||||
*/
|
||||
void sph_groestl256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Groestl-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_groestl256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Groestl-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Groestl-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Groestl-384 context (pointer to a
|
||||
* <code>sph_groestl384_context</code>)
|
||||
*/
|
||||
void sph_groestl384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Groestl-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_groestl384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Groestl-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Groestl-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Groestl-512 context (pointer to a
|
||||
* <code>sph_groestl512_context</code>)
|
||||
*/
|
||||
void sph_groestl512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Groestl-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_groestl512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Groestl-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,298 @@
|
||||
/* $Id: sph_jh.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* JH interface. JH is a family of functions which differ by
|
||||
* their output size; this implementation defines JH for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_jh.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_JH_H__
|
||||
#define SPH_JH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for JH-224.
|
||||
*/
|
||||
#define SPH_SIZE_jh224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for JH-256.
|
||||
*/
|
||||
#define SPH_SIZE_jh256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for JH-384.
|
||||
*/
|
||||
#define SPH_SIZE_jh384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for JH-512.
|
||||
*/
|
||||
#define SPH_SIZE_jh512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for JH computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* a JH computation has been performed, the context can be reused for
|
||||
* another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running JH computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
#if SPH_64
|
||||
sph_u64 wide[16];
|
||||
#endif
|
||||
sph_u32 narrow[32];
|
||||
} H;
|
||||
#if SPH_64
|
||||
sph_u64 block_count;
|
||||
#else
|
||||
sph_u32 block_count_high, block_count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_jh_context;
|
||||
|
||||
/**
|
||||
* Type for a JH-224 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_jh_context sph_jh224_context;
|
||||
|
||||
/**
|
||||
* Type for a JH-256 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_jh_context sph_jh256_context;
|
||||
|
||||
/**
|
||||
* Type for a JH-384 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_jh_context sph_jh384_context;
|
||||
|
||||
/**
|
||||
* Type for a JH-512 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_jh_context sph_jh512_context;
|
||||
|
||||
/**
|
||||
* Initialize a JH-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the JH-224 context (pointer to a
|
||||
* <code>sph_jh224_context</code>)
|
||||
*/
|
||||
void sph_jh224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the JH-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_jh224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current JH-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the JH-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the JH-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a JH-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the JH-256 context (pointer to a
|
||||
* <code>sph_jh256_context</code>)
|
||||
*/
|
||||
void sph_jh256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the JH-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_jh256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current JH-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the JH-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the JH-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a JH-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the JH-384 context (pointer to a
|
||||
* <code>sph_jh384_context</code>)
|
||||
*/
|
||||
void sph_jh384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the JH-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_jh384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current JH-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the JH-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the JH-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a JH-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the JH-512 context (pointer to a
|
||||
* <code>sph_jh512_context</code>)
|
||||
*/
|
||||
void sph_jh512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the JH-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_jh512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current JH-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the JH-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the JH-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,293 @@
|
||||
/* $Id: sph_keccak.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* Keccak interface. This is the interface for Keccak with the
|
||||
* recommended parameters for SHA-3, with output lengths 224, 256,
|
||||
* 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_keccak.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_KECCAK_H__
|
||||
#define SPH_KECCAK_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Keccak-224.
|
||||
*/
|
||||
#define SPH_SIZE_keccak224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Keccak-256.
|
||||
*/
|
||||
#define SPH_SIZE_keccak256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Keccak-384.
|
||||
*/
|
||||
#define SPH_SIZE_keccak384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Keccak-512.
|
||||
*/
|
||||
#define SPH_SIZE_keccak512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for Keccak computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once a
|
||||
* Keccak computation has been performed, the context can be reused for
|
||||
* another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Keccak computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[144]; /* first field, for alignment */
|
||||
size_t ptr, lim;
|
||||
union {
|
||||
#if SPH_64
|
||||
sph_u64 wide[25];
|
||||
#endif
|
||||
sph_u32 narrow[50];
|
||||
} u;
|
||||
#endif
|
||||
} sph_keccak_context;
|
||||
|
||||
/**
|
||||
* Type for a Keccak-224 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_keccak_context sph_keccak224_context;
|
||||
|
||||
/**
|
||||
* Type for a Keccak-256 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_keccak_context sph_keccak256_context;
|
||||
|
||||
/**
|
||||
* Type for a Keccak-384 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_keccak_context sph_keccak384_context;
|
||||
|
||||
/**
|
||||
* Type for a Keccak-512 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_keccak_context sph_keccak512_context;
|
||||
|
||||
/**
|
||||
* Initialize a Keccak-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Keccak-224 context (pointer to a
|
||||
* <code>sph_keccak224_context</code>)
|
||||
*/
|
||||
void sph_keccak224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Keccak-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_keccak224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Keccak-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Keccak-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Keccak-256 context (pointer to a
|
||||
* <code>sph_keccak256_context</code>)
|
||||
*/
|
||||
void sph_keccak256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Keccak-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_keccak256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Keccak-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Keccak-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Keccak-384 context (pointer to a
|
||||
* <code>sph_keccak384_context</code>)
|
||||
*/
|
||||
void sph_keccak384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Keccak-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_keccak384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Keccak-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Keccak-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Keccak-512 context (pointer to a
|
||||
* <code>sph_keccak512_context</code>)
|
||||
*/
|
||||
void sph_keccak512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Keccak-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_keccak512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Keccak-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,296 @@
|
||||
/* $Id: sph_luffa.h 154 2010-04-26 17:00:24Z tp $ */
|
||||
/**
|
||||
* Luffa interface. Luffa is a family of functions which differ by
|
||||
* their output size; this implementation defines Luffa for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_luffa.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_LUFFA_H__
|
||||
#define SPH_LUFFA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-224.
|
||||
*/
|
||||
#define SPH_SIZE_luffa224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-256.
|
||||
*/
|
||||
#define SPH_SIZE_luffa256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-384.
|
||||
*/
|
||||
#define SPH_SIZE_luffa384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-512.
|
||||
*/
|
||||
#define SPH_SIZE_luffa512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-224 computations: it contains
|
||||
* the intermediate values and some data from the last entered block.
|
||||
* Once a Luffa computation has been performed, the context can be
|
||||
* reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Luffa
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 V[3][8];
|
||||
#endif
|
||||
} sph_luffa224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-256 computations. It is
|
||||
* identical to <code>sph_luffa224_context</code>.
|
||||
*/
|
||||
typedef sph_luffa224_context sph_luffa256_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-384 computations.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 V[4][8];
|
||||
#endif
|
||||
} sph_luffa384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-512 computations.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 V[5][8];
|
||||
#endif
|
||||
} sph_luffa512_context;
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-224 context (pointer to a
|
||||
* <code>sph_luffa224_context</code>)
|
||||
*/
|
||||
void sph_luffa224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-256 context (pointer to a
|
||||
* <code>sph_luffa256_context</code>)
|
||||
*/
|
||||
void sph_luffa256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-384 context (pointer to a
|
||||
* <code>sph_luffa384_context</code>)
|
||||
*/
|
||||
void sph_luffa384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-512 context (pointer to a
|
||||
* <code>sph_luffa512_context</code>)
|
||||
*/
|
||||
void sph_luffa512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,314 @@
|
||||
/* $Id: sph_shavite.h 208 2010-06-02 20:33:00Z tp $ */
|
||||
/**
|
||||
* SHAvite-3 interface. This code implements SHAvite-3 with the
|
||||
* recommended parameters for SHA-3, with outputs of 224, 256, 384 and
|
||||
* 512 bits. In the following, we call the function "SHAvite" (without
|
||||
* the "-3" suffix), thus "SHAvite-224" is "SHAvite-3 with a 224-bit
|
||||
* output".
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_shavite.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_SHAVITE_H__
|
||||
#define SPH_SHAVITE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-224.
|
||||
*/
|
||||
#define SPH_SIZE_shavite224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-256.
|
||||
*/
|
||||
#define SPH_SIZE_shavite256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-384.
|
||||
*/
|
||||
#define SPH_SIZE_shavite384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-512.
|
||||
*/
|
||||
#define SPH_SIZE_shavite512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-224 and SHAvite-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a SHAvite computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running SHAvite
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 h[8];
|
||||
sph_u32 count0, count1;
|
||||
#endif
|
||||
} sph_shavite_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-224 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_small_context sph_shavite224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-256 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_small_context sph_shavite256_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-384 and SHAvite-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a SHAvite computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running SHAvite
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 h[16];
|
||||
sph_u32 count0, count1, count2, count3;
|
||||
#endif
|
||||
} sph_shavite_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-384 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_big_context sph_shavite384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-512 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_big_context sph_shavite512_context;
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-224 context (pointer to a
|
||||
* <code>sph_shavite224_context</code>)
|
||||
*/
|
||||
void sph_shavite224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-256 context (pointer to a
|
||||
* <code>sph_shavite256_context</code>)
|
||||
*/
|
||||
void sph_shavite256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-384 context (pointer to a
|
||||
* <code>sph_shavite384_context</code>)
|
||||
*/
|
||||
void sph_shavite384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-512 context (pointer to a
|
||||
* <code>sph_shavite512_context</code>)
|
||||
*/
|
||||
void sph_shavite512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user