diff --git a/BERN-qt.pro b/BERN-qt.pro new file mode 100644 index 0000000..953c78e --- /dev/null +++ b/BERN-qt.pro @@ -0,0 +1,435 @@ +TEMPLATE = app +TARGET = BERN-qt +VERSION = 1.1.0.0 +INCLUDEPATH += src src/json src/qt +QT += core gui network +DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN USE_IPV6 __NO_SYSTEM_INCLUDES +CONFIG += no_include_pwd +CONFIG += thread static +greaterThan(QT_MAJOR_VERSION, 4): QT += printsupport webkitwidgets +lessThan(QT_MAJOR_VERSION, 5): CONFIG += static +QMAKE_CXXFLAGS = -fpermissive + +greaterThan(QT_MAJOR_VERSION, 4) { + + DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 +} + +# UNCOMMENT THIS SECTION TO BUILD ON WINDOWS +# Change paths if needed, these use the foocoin/deps.git repository locations + + +OBJECTS_DIR = build +MOC_DIR = build +UI_DIR = build + +# use: qmake "RELEASE=1" +contains(RELEASE, 1) { + # Mac: compile for maximum compatibility (10.5, 32-bit) + macx:QMAKE_CXXFLAGS += -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk + + !windows:!macx { + # Linux: static link + LIBS += -Wl,-Bstatic + } +} + +!win32 { +# for extra security against potential buffer overflows: enable GCCs Stack Smashing Protection +QMAKE_CXXFLAGS *= -fstack-protector-all --param ssp-buffer-size=1 +QMAKE_LFLAGS *= -fstack-protector-all --param ssp-buffer-size=1 +# We need to exclude this for Windows cross compile with MinGW 4.2.x, as it will result in a non-working executable! +# This can be enabled for Windows, when we switch to MinGW >= 4.4.x. +} +# for extra security on Windows: enable ASLR and DEP via GCC linker flags +win32:QMAKE_LFLAGS *= -Wl,--dynamicbase -Wl,--nxcompat + +# use: qmake "USE_QRCODE=1" +# libqrencode (http://fukuchi.org/works/qrencode/index.en.html) must be installed for support +contains(USE_QRCODE, 1) { + message(Building with QRCode support) + DEFINES += USE_QRCODE + LIBS += -lqrencode +} + +# use: qmake "USE_UPNP=1" ( enabled by default; default) +# or: qmake "USE_UPNP=0" (disabled by default) +# or: qmake "USE_UPNP=-" (not supported) +# miniupnpc (http://miniupnp.free.fr/files/) must be installed for support +contains(USE_UPNP, -) { + message(Building without UPNP support) +} else { + message(Building with UPNP support) + count(USE_UPNP, 0) { + USE_UPNP=1 + } + DEFINES += USE_UPNP=$$USE_UPNP STATICLIB + INCLUDEPATH += $$MINIUPNPC_INCLUDE_PATH + LIBS += $$join(MINIUPNPC_LIB_PATH,,-L,) -lminiupnpc + win32:LIBS += -liphlpapi +} + + +# use: qmake "USE_DBUS=1" +contains(USE_DBUS, 1) { + message(Building with DBUS (Freedesktop notifications) support) + DEFINES += USE_DBUS + QT += dbus +} + +# use: qmake "USE_IPV6=1" ( enabled by default; default) +# or: qmake "USE_IPV6=0" (disabled by default) +# or: qmake "USE_IPV6=-" (not supported) +contains(USE_IPV6, -) { + message(Building without IPv6 support) +} else { + message(Building with IPv6 support) + count(USE_IPV6, 0) { + USE_IPV6=1 + } + DEFINES += USE_IPV6=$$USE_IPV6 +} + +contains(BITCOIN_NEED_QT_PLUGINS, 1) { + DEFINES += BITCOIN_NEED_QT_PLUGINS + QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs qtaccessiblewidgets +} + + +# regenerate src/build.h +!windows|contains(USE_BUILD_INFO, 1) { + genbuild.depends = FORCE + genbuild.commands = cd $$PWD; /bin/sh share/genbuild.sh $$OUT_PWD/build/build.h + genbuild.target = $$OUT_PWD/build/build.h + PRE_TARGETDEPS += $$OUT_PWD/build/build.h + QMAKE_EXTRA_TARGETS += genbuild + DEFINES += HAVE_BUILD_INFO +} + +QMAKE_CXXFLAGS += -msse2 +QMAKE_CFLAGS += -msse2 +QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter -Wstack-protector + +# Input +DEPENDPATH += src src/json src/qt +HEADERS += src/qt/bitcoingui.h \ + src/qt/transactiontablemodel.h \ + src/qt/addresstablemodel.h \ + src/qt/optionsdialog.h \ + src/qt/coincontroldialog.h \ + src/qt/coincontroltreewidget.h \ + src/qt/sendcoinsdialog.h \ + src/qt/addressbookpage.h \ + src/qt/signverifymessagedialog.h \ + src/qt/aboutdialog.h \ + src/qt/editaddressdialog.h \ + src/qt/bitcoinaddressvalidator.h \ + src/alert.h \ + src/addrman.h \ + src/base58.h \ + src/bignum.h \ + src/checkpoints.h \ + src/compat.h \ + src/coincontrol.h \ + src/sync.h \ + src/util.h \ + src/uint256.h \ + src/kernel.h \ + src/scrypt_mine.h \ + src/pbkdf2.h \ + src/serialize.h \ + src/strlcpy.h \ + src/main.h \ + src/net.h \ + src/key.h \ + src/db.h \ + src/walletdb.h \ + src/script.h \ + src/init.h \ + src/irc.h \ + src/mruset.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_writer.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_utils.h \ + src/json/json_spirit_stream_reader.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_reader.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit.h \ + src/qt/clientmodel.h \ + src/qt/guiutil.h \ + src/qt/transactionrecord.h \ + src/qt/guiconstants.h \ + src/qt/optionsmodel.h \ + src/qt/monitoreddatamapper.h \ + src/qt/transactiondesc.h \ + src/qt/transactiondescdialog.h \ + src/qt/bitcoinamountfield.h \ + src/wallet.h \ + src/keystore.h \ + src/qt/transactionfilterproxy.h \ + src/qt/transactionview.h \ + src/qt/walletmodel.h \ + src/bitcoinrpc.h \ + src/qt/overviewpage.h \ + src/qt/csvmodelwriter.h \ + src/crypter.h \ + src/qt/sendcoinsentry.h \ + src/qt/qvalidatedlineedit.h \ + src/qt/bitcoinunits.h \ + src/qt/qvaluecombobox.h \ + src/qt/askpassphrasedialog.h \ + src/protocol.h \ + src/qt/notificator.h \ + src/qt/qtipcserver.h \ + src/allocators.h \ + src/ui_interface.h \ + src/qt/rpcconsole.h \ + src/version.h \ + src/netbase.h \ + src/clientversion.h \ + src/hashblock.h \ + src/sph_blake.h \ + src/sph_bmw.h \ + src/sph_cubehash.h \ + src/sph_echo.h \ + src/sph_groestl.h \ + src/sph_jh.h \ + src/sph_keccak.h \ + src/sph_luffa.h \ + src/sph_shavite.h \ + src/sph_simd.h \ + src/sph_skein.h \ + src/sph_fugue.h \ + src/sph_hamsi.h \ + src/sph_shabal.h \ + src/sph_types.h \ + src/qt/httpsocket.h \ + src/qt/miningpage.h \ + src/qt/statisticspage.h \ + src/qt/blockbrowser.h \ + + +SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ + src/qt/transactiontablemodel.cpp \ + src/qt/addresstablemodel.cpp \ + src/qt/optionsdialog.cpp \ + src/qt/sendcoinsdialog.cpp \ + src/qt/coincontroldialog.cpp \ + src/qt/coincontroltreewidget.cpp \ + src/qt/addressbookpage.cpp \ + src/qt/signverifymessagedialog.cpp \ + src/qt/aboutdialog.cpp \ + src/qt/editaddressdialog.cpp \ + src/qt/bitcoinaddressvalidator.cpp \ + src/alert.cpp \ + src/version.cpp \ + src/sync.cpp \ + src/util.cpp \ + src/netbase.cpp \ + src/key.cpp \ + src/script.cpp \ + src/main.cpp \ + src/init.cpp \ + src/net.cpp \ + src/irc.cpp \ + src/checkpoints.cpp \ + src/addrman.cpp \ + src/db.cpp \ + src/walletdb.cpp \ + src/qt/clientmodel.cpp \ + src/qt/guiutil.cpp \ + src/qt/transactionrecord.cpp \ + src/qt/optionsmodel.cpp \ + src/qt/monitoreddatamapper.cpp \ + src/qt/transactiondesc.cpp \ + src/qt/transactiondescdialog.cpp \ + src/qt/bitcoinstrings.cpp \ + src/qt/bitcoinamountfield.cpp \ + src/wallet.cpp \ + src/keystore.cpp \ + src/qt/transactionfilterproxy.cpp \ + src/qt/transactionview.cpp \ + src/qt/walletmodel.cpp \ + src/bitcoinrpc.cpp \ + src/rpcdump.cpp \ + src/rpcnet.cpp \ + src/rpcmining.cpp \ + src/rpcwallet.cpp \ + src/rpcblockchain.cpp \ + src/rpcrawtransaction.cpp \ + src/qt/overviewpage.cpp \ + src/qt/csvmodelwriter.cpp \ + src/crypter.cpp \ + src/qt/sendcoinsentry.cpp \ + src/qt/qvalidatedlineedit.cpp \ + src/qt/bitcoinunits.cpp \ + src/qt/qvaluecombobox.cpp \ + src/qt/askpassphrasedialog.cpp \ + src/protocol.cpp \ + src/qt/notificator.cpp \ + src/qt/qtipcserver.cpp \ + src/qt/rpcconsole.cpp \ + src/noui.cpp \ + src/kernel.cpp \ + src/scrypt-x86.S \ + src/scrypt-x86_64.S \ + src/scrypt_mine.cpp \ + src/pbkdf2.cpp \ + src/aes_helper.c \ + src/blake.c \ + src/bmw.c \ + src/cubehash.c \ + src/echo.c \ + src/groestl.c \ + src/jh.c \ + src/keccak.c \ + src/luffa.c \ + src/shavite.c \ + src/simd.c \ + src/skein.c \ + src/fugue.c \ + src/hamsi.c \ + src/shabal.c \ + src/scrypt.cpp \ + src/qt/httpsocket.cpp \ + src/qt/miningpage.cpp \ + src/qt/statisticspage.cpp \ + src/qt/blockbrowser.cpp \ + +RESOURCES += \ + src/qt/bitcoin.qrc + +FORMS += \ + src/qt/forms/coincontroldialog.ui \ + src/qt/forms/sendcoinsdialog.ui \ + src/qt/forms/addressbookpage.ui \ + src/qt/forms/signverifymessagedialog.ui \ + src/qt/forms/aboutdialog.ui \ + src/qt/forms/editaddressdialog.ui \ + src/qt/forms/transactiondescdialog.ui \ + src/qt/forms/overviewpage.ui \ + src/qt/forms/sendcoinsentry.ui \ + src/qt/forms/askpassphrasedialog.ui \ + src/qt/forms/rpcconsole.ui \ + src/qt/forms/optionsdialog.ui \ + src/qt/forms/miningpage.ui \ + src/qt/forms/statisticspage.ui \ + src/qt/forms/blockbrowser.ui + +contains(USE_QRCODE, 1) { +HEADERS += src/qt/qrcodedialog.h +SOURCES += src/qt/qrcodedialog.cpp +FORMS += src/qt/forms/qrcodedialog.ui +} + +contains(BITCOIN_QT_TEST, 1) { +SOURCES += src/qt/test/test_main.cpp \ + src/qt/test/uritests.cpp +HEADERS += src/qt/test/uritests.h +DEPENDPATH += src/qt/test +QT += testlib +TARGET = BERN-qt_test +DEFINES += BITCOIN_QT_TEST +} + +CODECFORTR = UTF-8 + +# for lrelease/lupdate +# also add new translations to src/qt/bitcoin.qrc under translations/ +TRANSLATIONS = $$files(src/qt/locale/bitcoin_*.ts) + +isEmpty(QMAKE_LRELEASE) { + win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\\lrelease.exe + else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease +} +isEmpty(QM_DIR):QM_DIR = $$PWD/src/qt/locale +# automatically build translations, so they can be included in resource file +TSQM.name = lrelease ${QMAKE_FILE_IN} +TSQM.input = TRANSLATIONS +TSQM.output = $$QM_DIR/${QMAKE_FILE_BASE}.qm +TSQM.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +TSQM.CONFIG = no_link +QMAKE_EXTRA_COMPILERS += TSQM + +# "Other files" to show in Qt Creator +OTHER_FILES += \ + doc/*.rst doc/*.txt doc/README README.md res/bitcoin-qt.rc src/test/*.cpp src/test/*.h src/qt/test/*.cpp src/qt/test/*.h + +# platform specific defaults, if not overridden on command line +isEmpty(BOOST_LIB_SUFFIX) { + macx:BOOST_LIB_SUFFIX = -mt + windows:BOOST_LIB_SUFFIX = -mgw44-mt-s-1_50 +} + +isEmpty(BOOST_THREAD_LIB_SUFFIX) { + BOOST_THREAD_LIB_SUFFIX = $$BOOST_LIB_SUFFIX +} + +isEmpty(BDB_LIB_PATH) { + macx:BDB_LIB_PATH = /opt/local/lib/db48 +} + +isEmpty(BDB_LIB_SUFFIX) { + macx:BDB_LIB_SUFFIX = -4.8 +} + +isEmpty(BDB_INCLUDE_PATH) { + macx:BDB_INCLUDE_PATH = /opt/local/include/db48 +} + +isEmpty(BOOST_LIB_PATH) { + macx:BOOST_LIB_PATH = /opt/local/lib +} + +isEmpty(BOOST_INCLUDE_PATH) { + macx:BOOST_INCLUDE_PATH = /opt/local/include +} + +windows:DEFINES += WIN32 WIN32_LEAN_AND_MEAN +windows:RC_FILE = src/qt/res/bitcoin-qt.rc + +windows:!contains(MINGW_THREAD_BUGFIX, 0) { + # At least qmake's win32-g++-cross profile is missing the -lmingwthrd + # thread-safety flag. GCC has -mthreads to enable this, but it doesn't + # work with static linking. -lmingwthrd must come BEFORE -lmingw, so + # it is prepended to QMAKE_LIBS_QT_ENTRY. + # It can be turned off with MINGW_THREAD_BUGFIX=0, just in case it causes + # any problems on some untested qmake profile now or in the future. + DEFINES += _MT + QMAKE_LIBS_QT_ENTRY = -lmingwthrd $$QMAKE_LIBS_QT_ENTRY +} + +!windows:!macx { + DEFINES += LINUX + LIBS += -lrt +} + +macx:HEADERS += src/qt/macdockiconhandler.h +macx:OBJECTIVE_SOURCES += src/qt/macdockiconhandler.mm +macx:LIBS += -framework Foundation -framework ApplicationServices -framework AppKit +macx:DEFINES += MAC_OSX MSG_NOSIGNAL=0 +macx:ICON = src/qt/res/icons/BERN.icns +macx:TARGET = "BERN-qt" +macx:QMAKE_CFLAGS_THREAD += -pthread +macx:QMAKE_LFLAGS_THREAD += -pthread +macx:QMAKE_CXXFLAGS_THREAD += -pthread + +# Set libraries and includes at end, to use platform-defined defaults if not overridden +INCLUDEPATH += $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH $$QRENCODE_INCLUDE_PATH +LIBS += $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,) $$join(QRENCODE_LIB_PATH,,-L,) +LIBS += -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX +# -lgdi32 has to happen after -lcrypto (see #681) +windows:LIBS += -lws2_32 -lshlwapi -lmswsock -lole32 -loleaut32 -luuid -lgdi32 +LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_THREAD_LIB_SUFFIX +windows:LIBS += -lboost_chrono$$BOOST_LIB_SUFFIX + +contains(RELEASE, 1) { + !windows:!macx { + # Linux: turn dynamic linking back on for c/c++ runtime libraries + LIBS += -Wl,-Bdynamic + } +} + +system($$QMAKE_LRELEASE -silent $$_PRO_FILE_) diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..667520e --- /dev/null +++ b/INSTALL @@ -0,0 +1,10 @@ +Building BERN + +See doc/readme-qt.rst for instructions on building BERN QT, +the intended-for-end-users, nice-graphical-interface, reference +implementation of BERNh. + +See doc/build-*.txt for instructions on building BERNd, +the intended-for-services, no-graphical-interface, reference +implementation of BERN. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..00d80ab --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +BERNcash v1.1 +======== + +BERNcash(BERN) (c) copyright 2016 BERN Develper Steven Saxton (berniecoindev@gmail.com) + +X14 PoW/PoS hybrid +RPC PORT: 32016 (testnet 42016) +P2P PORT: 32020 (testnet 42020) + +BERN - http://BERN.cash (BCT thread - https://bitcointalk.org/index.php?topic=1338886.0 ) + +(aka BERNieCoin, BERNcoin) diff --git a/doc/Doxyfile b/doc/Doxyfile new file mode 100644 index 0000000..08d4f8c --- /dev/null +++ b/doc/Doxyfile @@ -0,0 +1,1752 @@ +# Doxyfile 1.7.4 + +# !!! Invoke doxygen from project root using: +# doxygen doc/Doxyfile + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Bitcoin + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.5.0 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "P2P Digital Currency" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = doc/bitcoin_logo_doxygen.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/doc/README b/doc/README new file mode 100644 index 0000000..97e154f --- /dev/null +++ b/doc/README @@ -0,0 +1,50 @@ + +Copyright (c) 2016 BERN Developers + +BERN 1.0.0.0 BETA + +Copyright (c) 2016 BERN Developers +Copyright (c) 2013-2014 SoleCoin Developers +Copyright (c) 2013 NovaCoin Developers +Copyright (c) 2011-2012 Bitcoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +Intro +----- +BERN is a free open source project derived from NovaCoin and subsequelty Bitcoin, with +the goal of providing a long-term energy-efficient x14-based crypto-currency to support +progressive politics. Built on the foundation of Bitcoin and NovaCoin, innovations such as proof-of-stake +help further advance the field of crypto-currency. + +Setup +----- +Unpack the files into a directory and run: + bin/32/BERNd (headless, 32-bit) + bin/64/BERNd (headless, 64-bit) + +The software automatically finds other nodes to connect to. You can +enable Universal Plug and Play (UPnP) with your router/firewall +or forward port 32020 (TCP) to your computer so you can receive +incoming connections. BERN works without incoming connections, +but allowing incoming connections helps the BERN network. + + +Upgrade +------- +All you existing coins/transactions should be intact with the upgrade. +To upgrade first backup wallet +BERNd backupwallet +Then shutdown BERNd by +BERNnd stop +Start up the new BERNd. + + +See the BERN site: + http://BERN.org/ +for help and more information. + diff --git a/doc/README_windows.txt b/doc/README_windows.txt new file mode 100644 index 0000000..649c526 --- /dev/null +++ b/doc/README_windows.txt @@ -0,0 +1,53 @@ + +Copyright (c) 2016 BERN Developers + + +BERN 1.0.0 BETA + +Copyright (c) 2016 BERN Developers +Copyright (c) 2013-2014 SoleCoin Developers +Copyright (c) 2013 NovaCoin Developers +Copyright (c) 2011-2012 Bitcoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +Intro +----- +BERN is a free open source project derived from NovaCoin and subsequelty Bitcoin, with +the goal of providing a long-term energy-efficient x14-based crypto-currency to support +progressive politics. Built on the foundation of Bitcoin and NovaCoin, innovations such as proof-of-stake +help further advance the field of crypto-currency. + +Setup +----- +After completing windows setup then run windows command line (cmd) + cd daemon + BERNd +You would need to create a configuration file BERN.conf in the default +wallet directory. Grant access to BERNd.exe in anti-virus and firewall +applications if necessary. + +The software automatically finds other nodes to connect to. You can +enable Universal Plug and Play (UPnP) with your router/firewall +or forward port 32020 (TCP) to your computer so you can receive +incoming connections. BERN works without incoming connections, +but allowing incoming connections helps the BERN network. + +Upgrade +------- +All you existing coins/transactions should be intact with the upgrade. +To upgrade first backup wallet +BERNd backupwallet +Then shutdown BERNd by +BERNd stop +Start up the new BERNd. + + +See the BERN site: + http://BERN.org/ +for help and more information. + diff --git a/doc/assets-attribution.txt b/doc/assets-attribution.txt new file mode 100644 index 0000000..0b0e377 --- /dev/null +++ b/doc/assets-attribution.txt @@ -0,0 +1,56 @@ +Code: src/strlcpy.h +Author: Todd C. Miller +License: ISC + +Icon: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png, + src/qt/res/src/*.svg +Designer: Wladimir van der Laan +License: MIT + +Icon: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png, + src/qt/res/icons/history.png, src/qt/res/icons/key.png, + src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png, + src/qt/res/icons/receive.png, src/qt/res/icons/send.png, + src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png +Icon Pack: NUVOLA ICON THEME for KDE 3.x +Designer: David Vignoni (david@icon-king.com) + ICON KING - www.icon-king.com +License: LGPL +Site: http://www.icon-king.com/projects/nuvola/ + +Icon: src/qt/res/icons/connect*.png +Icon Pack: Human-O2 +Designer: schollidesign +License: GNU/GPL +Site: http://findicons.com/icon/93743/blocks_gnome_netstatus_0 + +Icon: src/qt/res/icons/transaction*.png +Designer: md2k7 +Site: https://forum.bitcoin.org/index.php?topic=15276.0 +License: You are free to do with these icons as you wish, including selling, + copying, modifying etc. + +Icon: src/qt/res/icons/configure.png, src/qt/res/icons/quit.png, + src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png, + src/qt/res/icons/add.png, src/qt/res/icons/edit.png, + src/qt/res/icons/remove.png (edited) +Designer: http://www.everaldo.com +Icon Pack: Crystal SVG +License: LGPL + +Icon: src/qt/res/icons/bitcoin.png, src/qt/res/icons/toolbar.png +Designer: Bitboy (optimized for 16x16 by Wladimir van der Laan) +License: Public Domain +Site: http://forum.bitcoin.org/?topic=1756.0 + +Icon: scripts/img/reload.xcf (modified),src/qt/res/movies/update_spinner.mng +Icon Pack: Kids +Designer: Everaldo (Everaldo Coelho) +License: GNU/GPL +Site: http://findicons.com/icon/17102/reload?id=17102 + +Image: src/qt/res/images/splash2.jpg (Wallet image) +Designer: Crobbo (forum) +Site: https://bitcointalk.org/index.php?topic=32273.0 +License: Public domain + diff --git a/doc/bitcoin_logo_doxygen.png b/doc/bitcoin_logo_doxygen.png new file mode 100644 index 0000000..5b41b02 Binary files /dev/null and b/doc/bitcoin_logo_doxygen.png differ diff --git a/doc/build-msw.txt b/doc/build-msw.txt new file mode 100644 index 0000000..f4c68ec --- /dev/null +++ b/doc/build-msw.txt @@ -0,0 +1,84 @@ +Copyright (c) 2009-2012 Bitcoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP +software written by Thomas Bernard. + + +See readme-qt.rst for instructions on building BERN QT, the +graphical user interface. + +WINDOWS BUILD NOTES +=================== + +Compilers Supported +------------------- +TODO: What works? +Note: releases are cross-compiled using mingw running on Linux. + + +Dependencies +------------ +Libraries you need to download separately and build: + + default path download +OpenSSL \openssl-1.0.1b-mgw http://www.openssl.org/source/ +Berkeley DB \db-4.8.30.NC-mgw http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost-1.47.0-mgw http://www.boost.org/users/download/ +miniupnpc \miniupnpc-1.6-mgw http://miniupnp.tuxfamily.org/files/ + +Their licenses: +OpenSSL Old BSD license with the problematic advertising requirement +Berkeley DB New BSD license with additional requirement that linked software must be free open source +Boost MIT-like license +miniupnpc New (3-clause) BSD license + +Versions used in this release: +OpenSSL 1.0.1b +Berkeley DB 4.8.30.NC +Boost 1.47.0 +miniupnpc 1.6 + + +OpenSSL +------- +MSYS shell: +un-tar sources with MSYS 'tar xfz' to avoid issue with symlinks (OpenSSL ticket 2377) +change 'MAKE' env. variable from 'C:\MinGW32\bin\mingw32-make.exe' to '/c/MinGW32/bin/mingw32-make.exe' + +cd /c/openssl-1.0.1b-mgw +./config +make + +Berkeley DB +----------- +MSYS shell: +cd /c/db-4.8.30.NC-mgw/build_unix +sh ../dist/configure --enable-mingw --enable-cxx +make + +Boost +----- +DOS prompt: +downloaded boost jam 3.1.18 +cd \boost-1.47.0-mgw +bjam toolset=gcc --build-type=complete stage + +MiniUPnPc +--------- +UPnP support is optional, make with USE_UPNP= to disable it. + +MSYS shell: +cd /c/miniupnpc-1.6-mgw +make -f Makefile.mingw +mkdir miniupnpc +cp *.h miniupnpc/ + +BERN +------- +DOS prompt: +cd \BERN\src +mingw32-make -f makefile.mingw +strip BERNd.exe diff --git a/doc/build-osx.txt b/doc/build-osx.txt new file mode 100644 index 0000000..0ad4044 --- /dev/null +++ b/doc/build-osx.txt @@ -0,0 +1,54 @@ +Copyright (c) 2009-2012 Bitcoin Developers +Distributed under the MIT/X11 software license, see the accompanying file +license.txt or http://www.opensource.org/licenses/mit-license.php. This +product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit (http://www.openssl.org/). This product includes cryptographic +software written by Eric Young (eay@cryptsoft.com) and UPnP software written by +Thomas Bernard. + + +Mac OS X BERNd build instructions +Laszlo Hanyecz +Douglas Huff + + +See readme-qt.rst for instructions on building BERN QT, the +graphical user interface. + +Tested on 10.5 and 10.6 intel. PPC is not supported because it's big-endian. + +All of the commands should be executed in Terminal.app.. it's in +/Applications/Utilities + +You need to install XCode with all the options checked so that the compiler and +everything is available in /usr not just /Developer I think it comes on the DVD +but you can get the current version from http://developer.apple.com + + +1. Clone the github tree to get the source code: + +git clone git@github.com:BERN/BERN.git BERN + +2. Download and install MacPorts from http://www.macports.org/ + +2a. (for 10.7 Lion) + Edit /opt/local/etc/macports/macports.conf and uncomment "build_arch i386" + +3. Install dependencies from MacPorts + +sudo port install boost db48 openssl miniupnpc + +Optionally install qrencode (and set USE_QRCODE=1): +sudo port install qrencode + +4. Now you should be able to build BERNd: + +cd BERN/src +make -f makefile.osx + +Run: + ./BERNd --help # for a list of command-line options. +Run + ./BERNd -daemon # to start the BERN daemon. +Run + ./BERNd help # When the daemon is running, to get a list of RPC commands diff --git a/doc/build-unix.txt b/doc/build-unix.txt new file mode 100644 index 0000000..a1ca54d --- /dev/null +++ b/doc/build-unix.txt @@ -0,0 +1,159 @@ +Copyright (c) 2009-2012 Bitcoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP +software written by Thomas Bernard. + + +UNIX BUILD NOTES +================ + +To Build +-------- + +cd src/ +make -f makefile.unix # Headless BERN + +See readme-qt.rst for instructions on building BERN QT, +the graphical BERN. + +Dependencies +------------ + + Library Purpose Description + ------- ------- ----------- + libssl SSL Support Secure communications + libdb4.8 Berkeley DB Blockchain & wallet storage + libboost Boost C++ Library + miniupnpc UPnP Support Optional firewall-jumping support + libqrencode QRCode generation Optional QRCode generation + +Note that libexecinfo should be installed, if you building under *BSD systems. +This library provides backtrace facility. + +miniupnpc may be used for UPnP port mapping. It can be downloaded from +http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and +turned off by default. Set USE_UPNP to a different value to control this: + USE_UPNP=- No UPnP support - miniupnp not required + USE_UPNP=0 (the default) UPnP support turned off by default at runtime + USE_UPNP=1 UPnP support turned on by default at runtime + +libqrencode may be used for QRCode image generation. It can be downloaded +from http://fukuchi.org/works/qrencode/index.html.en, or installed via +your package manager. Set USE_QRCODE to control this: + USE_QRCODE=0 (the default) No QRCode support - libqrcode not required + USE_QRCODE=1 QRCode support enabled + +Licenses of statically linked libraries: + Berkeley DB New BSD license with additional requirement that linked + software must be free open source + Boost MIT-like license + miniupnpc New (3-clause) BSD license + +Versions used in this release: + GCC 4.3.3 + OpenSSL 0.9.8g + Berkeley DB 4.8.30.NC + Boost 1.37 + miniupnpc 1.6 + +Dependency Build Instructions: Ubuntu & Debian +---------------------------------------------- +sudo apt-get install build-essential +sudo apt-get install libssl-dev +sudo apt-get install libdb4.8-dev +sudo apt-get install libdb4.8++-dev + Boost 1.40+: sudo apt-get install libboost-all-dev + or Boost 1.37: sudo apt-get install libboost1.37-dev +sudo apt-get install libqrencode-dev + +If using Boost 1.37, append -mt to the boost libraries in the makefile. + + +Dependency Build Instructions: Gentoo +------------------------------------- + +Note: If you just want to install BERNd on Gentoo, you can add the BERN + overlay and use your package manager: + layman -a BERN && emerge BERNd + +emerge -av1 --noreplace boost glib openssl sys-libs/db:4.8 + +Take the following steps to build (no UPnP support): + cd ${BERNCASH_DIR}/src + make -f makefile.unix USE_UPNP= BDB_INCLUDE_PATH='/usr/include/db4.8' + strip BERNd + + +Notes +----- +The release is built with GCC and then "strip BERNd" to strip the debug +symbols, which reduces the executable size by about 90%. + + +miniupnpc +--------- +tar -xzvf miniupnpc-1.6.tar.gz +cd miniupnpc-1.6 +make +sudo su +make install + + +Berkeley DB +----------- +You need Berkeley DB 4.8. If you have to build Berkeley DB yourself: +../dist/configure --enable-cxx +make + + +Boost +----- +If you need to build Boost yourself: +sudo su +./bootstrap.sh +./bjam install + + +Security +-------- +To help make your BERN installation more secure by making certain attacks impossible to +exploit even if a vulnerability is found, you can take the following measures: + +* Position Independent Executable + Build position independent code to take advantage of Address Space Layout Randomization + offered by some kernels. An attacker who is able to cause execution of code at an arbitrary + memory location is thwarted if he doesn't know where anything useful is located. + The stack and heap are randomly located by default but this allows the code section to be + randomly located as well. + + On an Amd64 processor where a library was not compiled with -fPIC, this will cause an error + such as: "relocation R_X86_64_32 against `......' can not be used when making a shared object;" + + To build with PIE, use: + make -f makefile.unix ... -e PIE=1 + + To test that you have built PIE executable, install scanelf, part of paxutils, and use: + scanelf -e ./BERN + + The output should contain: + TYPE + ET_DYN + +* Non-executable Stack + If the stack is executable then trivial stack based buffer overflow exploits are possible if + vulnerable buffers are found. By default, BERN should be built with a non-executable stack + but if one of the libraries it uses asks for an executable stack or someone makes a mistake + and uses a compiler extension which requires an executable stack, it will silently build an + executable without the non-executable stack protection. + + To verify that the stack is non-executable after compiling use: + scanelf -e ./BERN + + the output should contain: + STK/REL/PTL + RW- R-- RW- + + The STK RW- means that the stack is readable and writeable but not executable. diff --git a/doc/coding.txt b/doc/coding.txt new file mode 100644 index 0000000..46da661 --- /dev/null +++ b/doc/coding.txt @@ -0,0 +1,99 @@ +Please be consistent with the existing coding style. + +Block style: + +bool Function(char* psz, int n) +{ + // Comment summarising what this section of code does + for (int i = 0; i < n; i++) + { + // When something fails, return early + if (!Something()) + return false; + ... + } + + // Success return is usually at the end + return true; +} + +- ANSI/Allman block style +- 4 space indenting, no tabs +- No extra spaces inside parenthesis; please don't do ( this ) +- No space after function names, one space after if, for and while + +Variable names begin with the type in lowercase, like nSomeVariable. +Please don't put the first word of the variable name in lowercase like +someVariable. + +Common types: +n integer number: short, unsigned short, int, unsigned int, + int64, uint64, sometimes char if used as a number +d double, float +f flag +hash uint256 +p pointer or array, one p for each level of indirection +psz pointer to null terminated string +str string object +v vector or similar list objects +map map or multimap +set set or multiset +bn CBigNum + +------------------------- +Locking/mutex usage notes + +The code is multi-threaded, and uses mutexes and the +CRITICAL_BLOCK/TRY_CRITICAL_BLOCK macros to protect data structures. + +Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main +and then cs_wallet, while thread 2 locks them in the opposite order: +result, deadlock as each waits for the other to release its lock) are +a problem. Compile with -DDEBUG_LOCKORDER to get lock order +inconsistencies reported in the debug.log file. + +Re-architecting the core code so there are better-defined interfaces +between the various components is a goal, with any necessary locking +done by the components (e.g. see the self-contained CKeyStore class +and its cs_KeyStore lock for example). + +------- +Threads + +StartNode : Starts other threads. + +ThreadGetMyExternalIP : Determines outside-the-firewall IP address, +sends addr message to connected peers when it determines it. + +ThreadIRCSeed : Joins IRC bootstrapping channel, watching for new +peers and advertising this node's IP address. + +ThreadSocketHandler : Sends/Receives data from peers on port 8333. + +ThreadMessageHandler : Higher-level message handling (sending and +receiving). + +ThreadOpenConnections : Initiates new connections to peers. + +ThreadTopUpKeyPool : replenishes the keystore's keypool. + +ThreadCleanWalletPassphrase : re-locks an encrypted wallet after user +has unlocked it for a period of time. + +SendingDialogStartTransfer : used by pay-via-ip-address code (obsolete) + +ThreadDelayedRepaint : repaint the gui + +ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used +in 500ms. + +ThreadRPCServer : Remote procedure call handler, listens on port 8332 +for connections and services them. + +ThreadBitcoinMiner : Generates bitcoins + +ThreadMapPort : Universal plug-and-play startup/shutdown + +Shutdown : Does an orderly shutdown of everything + +ExitTimeout : Windows-only, sleeps 5 seconds then exits application diff --git a/doc/readme-qt.rst b/doc/readme-qt.rst new file mode 100644 index 0000000..d2396b3 --- /dev/null +++ b/doc/readme-qt.rst @@ -0,0 +1,159 @@ +BERN-qt: Qt5 GUI for BERN +=============================== + +Build instructions +=================== + +Debian +------- + +First, make sure that the required packages for Qt5 development of your +distribution are installed. + +On recent Ubuntu releases, the `libdb++-dev` package is not in the default +repositories. However it's in the bitcoin repository, which we can add +with: + + apt-add-repository ppa:bitcoin/bitcoin + +Then we need to make sure our build environment is up to date. For Debian and Ubuntu: + +:: + + sudo apt-get install qt5-qmake libqt5-dev libqt5webkit5-dev build-essential libboost-dev libboost-system-dev \ + libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \ + libssl-dev libdb++-dev libminiupnpc-dev libminiupnpc8 + +then execute the following: + +:: + + qmake + make + +Alternatively, install Qt Creator and open the `BERN-qt.pro` file. + +An executable named `BERN-qt` will be built. + + +Windows +-------- + +Windows build instructions: + +- Download the `QT Windows SDK`_ and install it. You don't need the Symbian stuff, just the desktop Qt. + +- Download and extract the `dependencies archive`_ [#]_, or compile openssl, boost and dbcxx yourself. + +- Copy the contents of the folder "deps" to "X:\\QtSDK\\mingw", replace X:\\ with the location where you installed the Qt SDK. Make sure that the contents of "deps\\include" end up in the current "include" directory. + +- Open the .pro file in QT creator and build as normal (ctrl-B) + +.. _`QT Windows SDK`: http://qt.nokia.com/downloads/sdk-windows-cpp +.. _`dependencies archive`: https://download.visucore.com/bitcoin/qtgui_deps_1.zip +.. [#] PGP signature: https://download.visucore.com/bitcoin/qtgui_deps_1.zip.sig (signed with RSA key ID `610945D0`_) +.. _`610945D0`: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x610945D0 + + +Mac OS X +-------- + +- Download and install the `Qt Mac OS X SDK`_. It is recommended to also install Apple's Xcode with UNIX tools. + +- Download and install `MacPorts`_. + +- Execute the following commands in a terminal to get the dependencies: + +:: + + sudo port selfupdate + sudo port install boost db48 miniupnpc + +- Open the .pro file in Qt Creator and build as normal (cmd-B) + +.. _`Qt Mac OS X SDK`: http://qt.nokia.com/downloads/sdk-mac-os-cpp +.. _`MacPorts`: http://www.macports.org/install.php + + +Build configuration options +============================ + +UPNnP port forwarding +--------------------- + +To use UPnP for port forwarding behind a NAT router (recommended, as more connections overall allow for a faster and more stable BERN experience), pass the following argument to qmake: + +:: + + qmake "USE_UPNP=1" + +(in **Qt Creator**, you can find the setting for additional qmake arguments under "Projects" -> "Build Settings" -> "Build Steps", then click "Details" next to **qmake**) + +This requires miniupnpc for UPnP port mapping. It can be downloaded from +http://miniupnp.tuxfamily.org/files/. UPnP support is not compiled in by default. + +Set USE_UPNP to a different value to control this: + ++------------+--------------------------------------------------------------------------+ +| USE_UPNP=- | no UPnP support, miniupnpc not required; | ++------------+--------------------------------------------------------------------------+ +| USE_UPNP=0 | (the default) built with UPnP, support turned off by default at runtime; | ++------------+--------------------------------------------------------------------------+ +| USE_UPNP=1 | build with UPnP support turned on by default at runtime. | ++------------+--------------------------------------------------------------------------+ + +Notification support for recent (k)ubuntu versions +--------------------------------------------------- + +To see desktop notifications on (k)ubuntu versions starting from 10.04, enable usage of the +FreeDesktop notification interface through DBUS using the following qmake option: + +:: + + qmake "USE_DBUS=1" + +Generation of QR codes +----------------------- + +libqrencode may be used to generate QRCode images for payment requests. +It can be downloaded from http://fukuchi.org/works/qrencode/index.html.en, or installed via your package manager. Pass the USE_QRCODE +flag to qmake to control this: + ++--------------+--------------------------------------------------------------------------+ +| USE_QRCODE=0 | (the default) No QRCode support - libarcode not required | ++--------------+--------------------------------------------------------------------------+ +| USE_QRCODE=1 | QRCode support enabled | ++--------------+--------------------------------------------------------------------------+ + + +Berkely DB version warning +========================== + +A warning for people using the *static binary* version of BERN on a Linux/UNIX-ish system (tl;dr: **Berkely DB databases are not forward compatible**). + +The static binary version of BERN is linked against libdb4.8 (see also `this Debian issue`_). + +Now the nasty thing is that databases from 5.X are not compatible with 4.X. + +If the globally installed development package of Berkely DB installed on your system is 5.X, any source you +build yourself will be linked against that. The first time you run with a 5.X version the database will be upgraded, +and 4.X cannot open the new format. This means that you cannot go back to the old statically linked version without +significant hassle! + +.. _`this Debian issue`: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=621425 + +Ubuntu 11.10 warning +==================== + +Ubuntu 11.10 has a package called 'qt-at-spi' installed by default. At the time of writing, having that package +installed causes bitcoin-qt to crash intermittently. The issue has been reported as `launchpad bug 857790`_, but +isn't yet fixed. + +Until the bug is fixed, you can remove the qt-at-spi package to work around the problem, though this will presumably +disable screen reader functionality for Qt apps: + +:: + + sudo apt-get remove qt-at-spi + +.. _`launchpad bug 857790`: https://bugs.launchpad.net/ubuntu/+source/qt-at-spi/+bug/857790 diff --git a/doc/release-process.txt b/doc/release-process.txt new file mode 100644 index 0000000..ed23ef3 --- /dev/null +++ b/doc/release-process.txt @@ -0,0 +1,142 @@ +* update translations (ping tcatm on IRC for now) + +* update (commit) version in sources + bitcoin-qt.pro + src/version.h + share/setup.nsi + doc/README* + +* tag version in git + + git tag -a v0.5.1 + +* write release notes. git shortlog helps a lot: + + git shortlog --no-merges v0.5.0.. + +* perform gitian builds + + * From a directory containing the bitcoin source, gitian-builder and gitian.sigs + export SIGNER=(your gitian key, ie bluematt, sipa, etc) + export VERSION=0.5.1 + cd ./gitian-builder + + * Fetch and build inputs: + mkdir -p inputs; cd inputs/ + wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.6.tar.gz' -O miniupnpc-1.6.tar.gz + wget 'http://www.openssl.org/source/openssl-1.0.1b.tar.gz' + wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' + wget 'http://zlib.net/zlib-1.2.6.tar.gz' + wget 'ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng-1.5.9.tar.gz' + wget 'http://fukuchi.org/works/qrencode/qrencode-3.2.0.tar.bz2' + wget 'http://downloads.sourceforge.net/project/boost/boost/1.47.0/boost_1_47_0.tar.bz2' + wget 'http://download.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.7.4.tar.gz' + cd .. + ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/boost-win32.yml + cp build/out/boost-win32-1.47.0-gitian.zip inputs/ + ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/qt-win32.yml + cp build/out/qt-win32-4.7.4-gitian.zip inputs/ + ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/deps-win32.yml + cp build/out/bitcoin-deps-0.0.3.zip inputs/ + + * Build bitcoind and bitcoin-qt on Linux32, Linux64, and Win32: + ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian.yml + ./bin/gsign --signer $SIGNER --release ${VERSION} --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian.yml + pushd build/out + zip -r bitcoin-${VERSION}-linux-gitian.zip * + mv bitcoin-${VERSION}-linux-gitian.zip ../../ + popd + ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-win32 --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml + pushd build/out + zip -r bitcoin-${VERSION}-win32-gitian.zip * + mv bitcoin-${VERSION}-win32-gitian.zip ../../ + popd + + Build output expected: + 1. linux 32-bit and 64-bit binaries + source (bitcoin-${VERSION}-linux-gitian.zip) + 2. windows 32-bit binary, installer + source (bitcoin-${VERSION}-win32-gitian.zip) + 3. Gitian signatures (in gitian.sigs/${VERSION}[-win32]/(your gitian key)/ + +* repackage gitian builds for release as stand-alone zip/tar/installer exe + + * Linux .tar.gz: + unzip bitcoin-${VERSION}-linux-gitian.zip -d bitcoin-${VERSION}-linux + tar czvf bitcoin-${VERSION}-linux.tar.gz bitcoin-${VERSION}-linux + rm -rf bitcoin-${VERSION}-linux + + * Windows .zip and setup.exe: + unzip bitcoin-${VERSION}-win32-gitian.zip -d bitcoin-${VERSION}-win32 + mv bitcoin-${VERSION}-win32/bitcoin-*-setup.exe . + zip -r bitcoin-${VERSION}-win32.zip bitcoin-${VERSION}-win32 + rm -rf bitcoin-${VERSION}-win32 + +* perform Mac build + See this blog post for how Gavin set up his build environment to build the OSX + release; note that a patched version of macdeployqt is not needed anymore, as + the required functionality and fixes are implemented directly in macdeployqtplus: + http://gavintech.blogspot.com/2011/11/deploying-bitcoin-qt-on-osx.html + Gavin also had trouble with the macports py27-appscript package; he + ended up installing a version that worked with: /usr/bin/easy_install-2.7 appscript + + qmake RELEASE=1 USE_UPNP=1 USE_QRCODE=1 bitcoin-qt.pro + make + export QTDIR=/opt/local/share/qt4 # needed to find translations/qt_*.qm files + T=$(contrib/qt_translations.py $QTDIR/translations src/qt/locale) + python2.7 contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist + + Build output expected: + Bitcoin-Qt.dmg + +* upload builds to SourceForge + +* create SHA256SUMS for builds, and PGP-sign it + +* update bitcoin.org version + +* update forum version + +* update wiki download links + +* update wiki changelog: https://en.bitcoin.it/wiki/Changelog + +* Commit your signature to gitian.sigs: + pushd gitian.sigs + git add ${VERSION}/${SIGNER} + git add ${VERSION}-win32/${SIGNER} + git commit -a + git push # Assuming you can push to the gitian.sigs tree + popd + +------------------------------------------------------------------------- + +* After 3 or more people have gitian-built, repackage gitian-signed zips: + + * From a directory containing bitcoin source, gitian.sigs and gitian zips + export VERSION=0.5.1 + mkdir bitcoin-${VERSION}-linux-gitian + pushd bitcoin-${VERSION}-linux-gitian + unzip ../bitcoin-${VERSION}-linux-gitian.zip + mkdir gitian + cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/ + for signer in $(ls ../gitian.sigs/${VERSION}/); do + cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert + cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig + done + zip -r bitcoin-${VERSION}-linux-gitian.zip * + cp bitcoin-${VERSION}-linux-gitian.zip ../ + popd + mkdir bitcoin-${VERSION}-win32-gitian + pushd bitcoin-${VERSION}-win32-gitian + unzip ../bitcoin-${VERSION}-win32-gitian.zip + mkdir gitian + cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/ + for signer in $(ls ../gitian.sigs/${VERSION}-win32/); do + cp ../gitian.sigs/${VERSION}-win32/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert + cp ../gitian.sigs/${VERSION}-win32/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig + done + zip -r bitcoin-${VERSION}-win32-gitian.zip * + cp bitcoin-${VERSION}-win32-gitian.zip ../ + popd + + * Upload gitian zips to SourceForge diff --git a/doc/translation_process.md b/doc/translation_process.md new file mode 100644 index 0000000..3ddfc0c --- /dev/null +++ b/doc/translation_process.md @@ -0,0 +1,80 @@ +Translations +============ + +The Qt GUI can be easily translated into other languages. Here's how we +handle those translations. + +Files and Folders +----------------- + +### bitcoin-qt.pro + +This file takes care of generating `.qm` files from `.ts` files. It is mostly +automated. + +### src/qt/bitcoin.qrc + +This file must be updated whenever a new translation is added. Please note that +files must end with `.qm`, not `.ts`. + + + locale/bitcoin_en.qm + ... + + +### src/qt/locale/ + +This directory contains all translations. Filenames must adhere to this format: + + bitcoin_xx_YY.ts or bitcoin_xx.ts + +#### Source file + +`src/qt/locale/bitcoin_en.ts` is treated in a special way. It is used as the +source for all other translations. Whenever a string in the code is changed +this file must be updated to reflect those changes. Usually, this can be +accomplished by running `lupdate` (included in the Qt SDK). + +An updated source file should be merged to github and transifex will pick it +up from there. Afterwards the new strings show up as "Remaining" in transifex +and can be translated. + +Syncing with transifex +---------------------- + +We are using http://transifex.net as a frontend for translating the client. + +https://www.transifex.net/projects/p/bitcoin/resource/tx/ + +The "transifex client" (see: http://help.transifex.net/features/client/) +will help with fetching new translations from transifex. Use the following +config to be able to connect with the client. + +### .tx/config + + [main] + host = https://www.transifex.net + + [bitcoin.tx] + file_filter = src/qt/locale/bitcoin_.ts + source_file = src/qt/locale/bitcoin_en.ts + source_lang = en + +### .tx/config (for Windows) + + [main] + host = https://www.transifex.net + + [bitcoin.tx] + file_filter = src\qt\locale\bitcoin_.ts + source_file = src\qt\locale\bitcoin_en.ts + source_lang = en + +It is also possible to directly download new translations one by one from transifex. + +### Fetching new translations + +1. `tx pull -a` +2. update `src/qt/bitcoin.qrc` manually or via + `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/locale/\1.qm<\/file>/'` +3. `git add` new translations from `src/qt/locale/` diff --git a/share/genbuild.sh b/share/genbuild.sh new file mode 100644 index 0000000..d959877 --- /dev/null +++ b/share/genbuild.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +if [ $# -gt 0 ]; then + FILE="$1" + shift + if [ -f "$FILE" ]; then + INFO="$(head -n 1 "$FILE")" + fi +else + echo "Usage: $0 " + exit 1 +fi + +if [ -e "$(which git)" ]; then + # clean 'dirty' status of touched files that haven't been modified + git diff >/dev/null 2>/dev/null + + # get a string like "v0.6.0-66-g59887e8-dirty" + DESC="$(git describe --dirty 2>/dev/null)" + + # get a string like "2012-04-10 16:27:19 +0200" + TIME="$(git log -n 1 --format="%ci")" +fi + +if [ -n "$DESC" ]; then + NEWINFO="#define BUILD_DESC \"$DESC\"" +else + NEWINFO="// No build information available" +fi + +# only update build.h if necessary +if [ "$INFO" != "$NEWINFO" ]; then + echo "$NEWINFO" >"$FILE" + echo "#define BUILD_DATE \"$TIME\"" >>"$FILE" +fi diff --git a/share/pixmaps/addressbook16.bmp b/share/pixmaps/addressbook16.bmp new file mode 100644 index 0000000..c557691 Binary files /dev/null and b/share/pixmaps/addressbook16.bmp differ diff --git a/share/pixmaps/addressbook16mask.bmp b/share/pixmaps/addressbook16mask.bmp new file mode 100644 index 0000000..d3a478d Binary files /dev/null and b/share/pixmaps/addressbook16mask.bmp differ diff --git a/share/pixmaps/addressbook20.bmp b/share/pixmaps/addressbook20.bmp new file mode 100644 index 0000000..2b33b22 Binary files /dev/null and b/share/pixmaps/addressbook20.bmp differ diff --git a/share/pixmaps/addressbook20mask.bmp b/share/pixmaps/addressbook20mask.bmp new file mode 100644 index 0000000..56ce612 Binary files /dev/null and b/share/pixmaps/addressbook20mask.bmp differ diff --git a/share/pixmaps/bitcoin-bc.ico b/share/pixmaps/bitcoin-bc.ico new file mode 100644 index 0000000..88cc240 Binary files /dev/null and b/share/pixmaps/bitcoin-bc.ico differ diff --git a/share/pixmaps/bitcoin.ico b/share/pixmaps/bitcoin.ico new file mode 100644 index 0000000..6192680 Binary files /dev/null and b/share/pixmaps/bitcoin.ico differ diff --git a/share/pixmaps/bitcoin32.xpm b/share/pixmaps/bitcoin32.xpm new file mode 100644 index 0000000..f538a44 --- /dev/null +++ b/share/pixmaps/bitcoin32.xpm @@ -0,0 +1,232 @@ +/* XPM */ +static const char * bitcoin32_xpm[] = { +/* columns rows colors chars-per-pixel */ +"32 32 194 2", +" c #745305", +". c #785704", +"X c #7C5903", +"o c #75560B", +"O c #77590F", +"+ c #7C5C0B", +"@ c #795B12", +"# c #7F631D", +"$ c #825E07", +"% c #825F0B", +"& c #85610A", +"* c #8C660C", +"= c #8E680E", +"- c #916B0F", +"; c #856515", +": c #8B6714", +"> c #8F6A16", +", c #816218", +"< c #88691C", +"1 c #926D12", +"2 c #936F1C", +"3 c #997417", +"4 c #94721E", +"5 c #9B761C", +"6 c #9F781C", +"7 c #A17B1E", +"8 c #826622", +"9 c #916E20", +"0 c #967425", +"q c #9D7420", +"w c #9C7923", +"e c #997728", +"r c #99792C", +"t c #A37D23", +"y c #A37F2C", +"u c #A68125", +"i c #AB8225", +"p c #A5832B", +"a c #AA852C", +"s c #B28A2C", +"d c #A58233", +"f c #AC8734", +"g c #AE8C33", +"h c #AC8C3C", +"j c #B28C33", +"k c #B98E34", +"l c #B28D3D", +"z c #B59136", +"x c #BC9335", +"c c #B3913E", +"v c #BC933A", +"b c #BF9A3D", +"n c #C19235", +"m c #C2953C", +"M c #C39B3C", +"N c #CA9C3D", +"B c #B59343", +"V c #BE9642", +"C c #B69A44", +"Z c #BD9A45", +"A c #B49649", +"S c #BB9A49", +"D c #BB9F52", +"F c #BFA256", +"G c #C49C43", +"H c #CA9D41", +"J c #C59D4A", +"K c #C99E4D", +"L c #C3A144", +"P c #CDA244", +"I c #CFAA47", +"U c #C3A14D", +"Y c #CDA24A", +"T c #CCAB49", +"R c #D2A644", +"E c #D2A54B", +"W c #D6AA4C", +"Q c #DAAE4E", +"! c #DAB04F", +"~ c #C7A656", +"^ c #CDA452", +"/ c #CFAC52", +"( c #C0A65E", +") c #CEA75A", +"_ c #CCAC59", +"` c #D2AB53", +"' c #DCAF52", +"] c #D6AD5A", +"[ c #D9AE5B", +"{ c #DCB556", +"} c #DFB855", +"| c #D6B25F", +" . c #DCB35C", +".. c #DEBE5E", +"X. c #E2B656", +"o. c #E1B55A", +"O. c #E6BC5D", +"+. c #E9BD5E", +"@. c #C3AA63", +"#. c #CCAD62", +"$. c #D4AF62", +"%. c #CDB565", +"&. c #CEB46D", +"*. c #D7B164", +"=. c #DBB362", +"-. c #D6BD64", +";. c #DDBA64", +":. c #D3B66C", +">. c #DFB86B", +",. c #CEB772", +"<. c #D0B771", +"1. c #D4BA73", +"2. c #D9BE77", +"3. c #D6BE79", +"4. c #D8BF7A", +"5. c #E4BB62", +"6. c #E9BF64", +"7. c #E4BC69", +"8. c #E9BF69", +"9. c #E0BB71", +"0. c #E9C05E", +"q. c #D2C279", +"w. c #DBC27C", +"e. c #E2C667", +"r. c #EDC364", +"t. c #E3C16E", +"y. c #ECC46C", +"u. c #EDCC6C", +"i. c #F1C764", +"p. c #F5CA66", +"a. c #F9CD67", +"s. c #F5CC6A", +"d. c #F9CD6B", +"f. c #FBD36F", +"g. c #EDC572", +"h. c #E5CF77", +"j. c #ECCA74", +"k. c #E0C67E", +"l. c #EFCE78", +"z. c #F6CE72", +"x. c #FBCF71", +"c. c #F4CE79", +"v. c #F4D273", +"b. c #FCD473", +"n. c #F4DC75", +"m. c #FEDA74", +"M. c #F6D77C", +"N. c #FBD47A", +"B. c #F1DA7B", +"V. c #FDDA7C", +"C. c #FEE27D", +"Z. c #DDC683", +"A. c #DFC884", +"S. c #E4CA84", +"D. c #E3CC89", +"F. c #E7D183", +"G. c #EFD280", +"H. c #EFDC82", +"J. c #ECD48D", +"K. c #EFDA8C", +"L. c #F9D783", +"P. c #F2DF83", +"I. c #FCDB83", +"U. c #F5DC8F", +"Y. c #FADD8B", +"T. c #EBD593", +"R. c #EFDA99", +"E. c #F3DD93", +"W. c #F3DF9F", +"Q. c #FFE385", +"!. c #FEE986", +"~. c #FDE48C", +"^. c #FEEC8E", +"/. c #ECE199", +"(. c #F6E591", +"). c #FEE494", +"_. c #FEEB93", +"`. c #FEE69A", +"'. c #FFEB9B", +"]. c #FFF197", +"[. c #FFF39B", +"{. c #FEF99B", +"}. c #F6E2A2", +"|. c #F9E5A5", +" X c #F7E9A5", +".X c #FEECA4", +"XX c #FBE7A8", +"oX c #FDEAAB", +"OX c #F7F2AA", +"+X c #FEF2AC", +"@X c #FDF4B4", +"#X c #FFFABA", +"$X c #FFFEC2", +"%X c None", +/* pixels */ +"%X%X%X%X%X%X%X%X%X%X%X%Xp t 6 5 w t w %X%X%X%X%X%X%X%X%X%X%X%X%X", +"%X%X%X%X%X%X%X%X%Xu u x I X.0.s.u.0.W x 7 4 %X%X%X%X%X%X%X%X%X%X", +"%X%X%X%X%X%X%Xy i I i.a.f.m.m.b.f.s.a.s.i.W 7 > %X%X%X%X%X%X%X%X", +"%X%X%X%X%X%Xt M 0.a.m.m.m.m.f.d.p.p.p.f.d.f.i.b 1 < %X%X%X%X%X%X", +"%X%X%X%X%X7 ! d.f.f.m.f.+.W P R I Q 5.v.V.V.z.f.{ 5 + %X%X%X%X%X", +"%X%X%X%Xu X.f.m.m.f.' H s ~ V y _ Z J o.g.L.L.Q.!.e.5 X %X%X%X%X", +"%X%X%Xu X.b.C.m.+.N m n t }.3.> }.w.V 5.y.y.Y.[.^.^.-.1 + %X%X%X", +"%X%Xt P m.N.m.X.v v v k 6 }.1.: /.4.c 7.N.N.v.!.{.{.^.L & %X%X%X", +"%X%Xg Y.Y.V.+.m k a t t : }.1.% }.1.r | l.B.M.b.!.{.^.n.7 X %X%X", +"%Xp -._.'.Y.' Y n D.}.}.|.oXXX|.oX XT.w.F _ j.v.v._.^.C.T & @ %X", +"%Xa (.'.'.9.[ [ K S.}.oXoXoXoXXXoXoXoXoX XD / s.d.v.!.C.v.3 o %X", +"%XU '.'.Y.[ [ [ [ J f <.oXoX( 2 f S J.oXoXT.j r.s.i.C.C.C.z X %X", +"p e.'.'.F. .=.=.=.=.) 1.oXoX@.f . .F oXoX}.a +.i.i.b.C.m.I X O ", +"u w.'.[.j.5.8.7.7.7.] 2.oXoX@.y W c &.oXoXZ.k r.s.i.s.V.m.} = o ", +"u H.[.{.y.8.y.g.8.g.7.2.oXoXA.@.&.D.oXoXT.e G +.O.O.5.V.m.0.- o ", +"u !.].[.r.8.y.g.g.g.7.4.oXoXoXoXoXoXoXoXoX<.y W X.o.o.m.m.0.- o ", +"u B._._.5.5.8.y.g.c.g.w.oXoX,.h A F <..XoXoX1.k ' ' ' V.N.r.- ", +"u u.Q.~.r.6.z.N.V.I.v.k.oXoX@.B | _ c 1.oXoX}.a ' ' O.I.b.O.= o ", +"u ..Q.Q.v.i.s.c.N.L.l.Z.oXoX@.B t.=.S &.oXoXXXy Y R +.N.b.Q % o ", +"t T C.I.I.6.u.z.z.5.S 1.oXoX@.e B h D |.oXoXS.f Y Y 6.d.d.n X O ", +"%Xs m.V.Q.r.r.z.5.<.}.oXoXoXXXW.}.oXoXoXoXW.h G H R a.p.s.7 %X", +"%X7 O.V.V.v.+.r.` 4.oXoXoXoXoXoXoXoXXXR.<.h v N N o.a.p.Q = %X", +"%Xw x v.v.v.r.+. .Z l d e }.Z.r }.3.d l V G n n R a.s.a.s X O %X", +"%X%X6 { v.l.v.+.O.5.=.^ d }.4.9 }.1.f J G m m G d.d.x.Q = %X%X", +"%X%X%Xs u.v.v.v.r.6.o. .l }.4.9 W.4.l ^ ^ J ) c.N.N.y.7 X O %X%X", +"%X%X%X5 z v.v.M.I.g.;. .J 1.#.B 1.#.) 7.$.S..X'.W.Y.j $ %X%X%X", +"%X%X%X%X5 b N.Y.~.).Y.j.5.$.=.=.$.*.2.J.@X$X#X#XoXC $ %X%X%X%X", +"%X%X%X%X%X3 z U.@X+X`.`.`.(.E.E.E.|.@X@X#X#X#X/.j % %X%X%X%X%X", +"%X%X%X%X%X%Xw a q.OX|.).`._.'.'.XX.X.X+X+X X%.w X o %X%X%X%X%X%X", +"%X%X%X%X%X%X%X%Xw a _ j.~.~.).).`.`.`.F._ t & . # %X%X%X%X%X%X%X", +"%X%X%X%X%X%X%X%X%X%X4 3 t z L U Z z t 1 $ . 8 %X%X%X%X%X%X%X%X%X", +"%X%X%X%X%X%X%X%X%X%X%X%X%X< ; & + + , 8 %X%X%X%X%X%X%X%X%X%X%X%X" +}; diff --git a/share/pixmaps/bitcoin80.xpm b/share/pixmaps/bitcoin80.xpm new file mode 100644 index 0000000..c3c816e --- /dev/null +++ b/share/pixmaps/bitcoin80.xpm @@ -0,0 +1,292 @@ +/* XPM */ +static const char * bitcoin80_xpm[] = { +/* columns rows colors chars-per-pixel */ +"80 80 206 2", +" c #725203", +". c #785706", +"X c #7B5907", +"o c #7C5A09", +"O c #7F5F10", +"+ c #815E0B", +"@ c #85620C", +"# c #89650F", +"$ c #856313", +"% c #896614", +"& c #8D6913", +"* c #886718", +"= c #8D6B1B", +"- c #926D14", +"; c #926E1B", +": c #967116", +"> c #997317", +", c #95711E", +"< c #9B7419", +"1 c #9F781B", +"2 c #A27B1D", +"3 c #8F6F22", +"4 c #926F21", +"5 c #947323", +"6 c #9A7623", +"7 c #9D7925", +"8 c #957628", +"9 c #9A7729", +"0 c #9D7B2B", +"q c #9D7F33", +"w c #A47D23", +"e c #A97F27", +"r c #A37E2B", +"t c #9F8030", +"y c #A78021", +"u c #AC8425", +"i c #A5802D", +"p c #AC842B", +"a c #AF8829", +"s c #B2872C", +"d c #B28B2D", +"f c #A68333", +"g c #AA8633", +"h c #AD8A36", +"j c #A4863A", +"k c #A88638", +"l c #A7893B", +"z c #AC8B3B", +"x c #B28732", +"c c #B48C32", +"v c #B98E34", +"b c #B28D3B", +"n c #B88F3C", +"m c #B69033", +"M c #BD9235", +"N c #B4913D", +"B c #BC943A", +"V c #BE993C", +"C c #C19336", +"Z c #C1953B", +"A c #C49A3C", +"S c #C99C3D", +"D c #CDA13F", +"F c #D0A33F", +"G c #A88B40", +"H c #B08F40", +"J c #AE9142", +"K c #AE944C", +"L c #B49443", +"P c #BB9542", +"I c #B49946", +"U c #BD9846", +"Y c #B3964C", +"T c #BB974A", +"R c #B6994A", +"E c #BF9C4A", +"W c #B69B53", +"Q c #B99D53", +"! c #BCA055", +"~ c #BDA25A", +"^ c #C49742", +"/ c #C49C43", +"( c #CB9E42", +") c #C49D4B", +"_ c #C99E4C", +"` c #C29F52", +"' c #C5A244", +"] c #CDA245", +"[ c #C5A34C", +"{ c #CCA34B", +"} c #CCA94D", +"| c #D2A445", +" . c #D1A54B", +".. c #D5AA4E", +"X. c #DBAF4F", +"o. c #C6A352", +"O. c #CBA554", +"+. c #C5AA57", +"@. c #CEAC54", +"#. c #C4A65A", +"$. c #CDA458", +"%. c #C2A85F", +"&. c #CEAA5B", +"*. c #D0A550", +"=. c #D4AB53", +"-. c #DBAE53", +";. c #D0A75B", +":. c #D4AC5A", +">. c #D9AE5C", +",. c #CEB25E", +"<. c #D4B156", +"1. c #DDB156", +"2. c #D4B25C", +"3. c #DCB35D", +"4. c #D7B85C", +"5. c #DCBA5E", +"6. c #E2B355", +"7. c #E2B65B", +"8. c #E4BA5D", +"9. c #EABD5E", +"0. c #C5AA62", +"q. c #CCAE63", +"w. c #C6AE69", +"e. c #D5AF62", +"r. c #CEB167", +"t. c #CCB36C", +"y. c #D5B162", +"u. c #DCB462", +"i. c #D7B964", +"p. c #DCBC64", +"a. c #D2B66B", +"s. c #DCB669", +"d. c #D7BE69", +"f. c #DFB86A", +"g. c #D0B771", +"h. c #D2BA74", +"j. c #D5BE78", +"k. c #E1B766", +"l. c #E4BB63", +"z. c #E9BE63", +"x. c #E3BB6A", +"c. c #E9BF6A", +"v. c #E1BE72", +"b. c #DDC16B", +"n. c #DAC27E", +"m. c #E4C164", +"M. c #ECC264", +"N. c #E4C36B", +"B. c #EBC36C", +"V. c #E7C96F", +"C. c #EECA6E", +"Z. c #F1C564", +"A. c #F1C76A", +"S. c #F5CB6C", +"D. c #FACE6D", +"F. c #F4D06F", +"G. c #FCD06E", +"H. c #E5C371", +"J. c #EDC573", +"K. c #E4CA73", +"L. c #ECCC74", +"P. c #E7CF7A", +"I. c #EBCD7A", +"U. c #F3CD73", +"Y. c #F8CE71", +"T. c #F3CD7A", +"R. c #EDD076", +"E. c #EDD17B", +"W. c #F4D274", +"Q. c #FBD274", +"!. c #FED977", +"~. c #F3D47B", +"^. c #FDD47A", +"/. c #F5DA7C", +"(. c #FDDA7C", +"). c #FFE07F", +"_. c #DBC481", +"`. c #DFC885", +"'. c #E1CA86", +"]. c #EACC80", +"[. c #E4CD8A", +"{. c #EED383", +"}. c #E7D18F", +"|. c #EAD38C", +" X c #F4D680", +".X c #FDD780", +"XX c #F5DA83", +"oX c #FCDC84", +"OX c #F5DB8A", +"+X c #FADE89", +"@X c #EAD492", +"#X c #EED896", +"$X c #EFDA9A", +"%X c #F1DD9D", +"&X c #FDE283", +"*X c #F6E18D", +"=X c #FEE48D", +"-X c #FFE692", +";X c #FFE894", +":X c #FBE799", +">X c #FFEA98", +",X c #F6E2A3", +".J..X.X.X.X(.W.Z.C.&X;X;X;X;X-X-X-X<.u u < 3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3Xu u c oX=X=X=X=X=X=X=Xl.Z C M M C C v v v s w = '.2X2X2X5 $ = 2X2X2X}.5 g ) u./.+X+X=X=X=X&XW.Z.F.=X;X;X;X;X-X-X*XV u y @ X 3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3Xu u u N.-X-X-X-X=X=X=XB.Z M C v v s e e e e w > % `.2X2X2X= + % 2X2X2X}.= r L 4.E.OX+X-X=X=X&X).W.M.R.;X;X;X-X-X-X;XR.u u y 3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3Xu u U -X-X-X-X-X-X=XW.^ C C C x e e r 6 5 4 ; = $ `.2X2X2X= O = 2X2X2X}.O = t Q ,.b.P./.*X=X&X&X).F.M.W.;X;X;X;X&X-X&X} u u O 3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3Xu u u R.-X-X-X-X-X-X=X=.{ ^ Z C x n 2X2X.>.>.=.=._ n b 2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X:XI N +.V./.).).F.F.9.W.;X=X;X-X-X-XR.u u > 3X3X3X3X3X3X3X3X", +"3X3X3X3X3Xu u d =X;X-X-X-X-X-Xx.>.>.>.>.>...^ P 2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X,Xl N 4.R.!.!.!.G.Z.M.&X;X=X=X-X-X-XB a u 3X3X3X3X3X3X3X", +"3X3X3X3X3Xu u @.;X;X-X;X;X;XXX>.:.>.>.>.>.>._ P ` Y Y W _.2X2X2X2X2X2X@XW W ~ 0.t.'..>.>.>.>.>.>.=._ P z r 4 8 2X2X2X2X2X2X_.. $ , 6 1 3 t ~ 1X2X2X2X2X2X2X2Xt B 5.G.!.!.G.G.M.9.&X;X=X-X-X=X/.u u > 3X3X3X3X3X3X3X", +"3X3X3X3Xu u d =X;X;X=X;X;X=X3.>.>.>.e.>.3.3.>.:.*._ P r 9 2X2X2X2X2X1Xn.@ , c B N m h 8 ~ 2X2X2X2X2X2X2XI h <.F.!.G.G.F.M.9.W.;X=X-X-X=X=Xm u y . 3X3X3X3X3X3X", +"3X3X3X3Xu u ' -X-X>X-X-X-X X>.>.>.>.>.>.>.u.u.u.u.3.$.P f 2X2X2X2X2X2X_.$ i / -.<.8.} h 8 1X2X2X2X2X2X2X! i <.S.G.G.G.G.Z.9.Z.=X-X=X-X&X-X} u u X 3X3X3X3X3X3X", +"3X3X3X3Xu u 4.-X-X-X-X-X-XJ.3.>.>.k.k.k.k.k.u.k.u.u.:.U k 2X2X2X2X2X1X_.% f } 8.Z.F.8.U 8 ,X2X2X2X2X2X2XI g } Z.D.G.D.G.D.Z.9.&X-X=X=X=X-Xm.u u @ 3X3X3X3X3X3X", +"3X3X3X3Xu u K.;X-X;X-X>X-Xk.3.k.k.k.k.k.k.k.k.k.k.u.e.U k 2X2X2X2X2X2X_.% f [ 8.F.M.<.b i 2X2X2X2X2X2X2Xt a X.Z.D.D.D.G.G.Z.9./.=X-X=X=X=XR.u u & 3X3X3X3X3X3X", +"3X3X3X3Xu u E.;X-X;X-X-X=Xl.l.x.c.k.x.k.k.x.x.v.x.x.u.) z 2X2X2X2X2X2X_.$ 7 L <.<.} N 6 h.2X2X2X2X2X2X_.: V 1.S.D.D.G.D.S.M.6.W.-X=X-X=X=X&Xu u > X 3X3X3X3X3X", +"3X3X3Xu a u =X;X;X;X;X;XoX7.z.c.c.c.c.c.c.c.c.c.x.k.u.) z 2X2X2X2X2X2Xn.o = i N h i l n.2X2X2X2X2X2X.o.L r [.2X2X2X9 = 8 2X2X2X}.4 r ^ _ *.*._ ) ) ^ ^ ^ O.oX=X-X-X-X-X-X-X<.u u : . 3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3Xy u u i.=X=X=X=X=X-X*X=XW.9.M.A.B.3.5.5.;.U f [.2X2X2Xq 4 8 2X2X2X}.r q _ _ ;.;.*._ _ ` _ e.+X-X-X-X-X-X-X-XR.a u 2 3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3Xu u u K.=X=X=X-X=X=X=X=XXXz.M.8.5.8.u.:.) h }.2X2X2Xj r f 2X2X2X@Xq T _ e.e.u.e.;.$.$.b.-X-X-X=X;X=X;X-X&Xa a u + 3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3Xu u d ~.=X=X=X=X=X-X=X-X+XC.3.5.7.7.2.@.) q.r.q.q.H H L g.r.w.q.T ` e.k.v.k.k.s.s.{.-X-X;X-X;X;X;X;X*XV u u & . 3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X2 u u c XX-X=X=X=X=X-X=X-X-X Xl.7.7.u.2.$.o.[ [ o.O.$.&.&.` ` ` q.s.k.v.k.k.x.{.%X>X>X>X;X>X;X>X>X*XV u u > 3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X2 u u m ~.=X-X-X-X=X-X-X-X-X-X Xc.7.5.u.3.e.y.u.s.f.k.s.e.e.s.s.k.k.k.v. X:X>X>X>X>X>X>X;X>X>X*XV u u < 3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X2 u u d R.-X=X-X=X-X-X-X-X-X-X-X+XI.v.u.s.l.k.k.x.x.x.s.s.s.s.j.].+X>X>X>X>X>X:X>X>X>X>X>XOXV u u 1 3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X2 u u a p.-X-X-X;X;X;X-X-X-X:X-X-X-X-XOX XL.J.J.J.L.I.].OX:X>X-X>X>X-X>X>X>X>X>X>X>X>XK.a a u < 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X2 u u u @.=X;X;X>X;X-X-X>X-X-X-X-X;X-X-X-X-X-X>X>X-X>X-X>X>X>X>X;X>X>X>X-X>X-X-X:X<.u u u > 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X1 u u u m n.>X;X>X>X-X-X-X-X>X-X-X-X;X;X;X-X-X-X-X-X>X-X-X>X-X>X>X-X>X>X>X>XK.B u u u & 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xw u u u / {.>X>X-X-X-X-X-X-X-X-X-X-X;X-X-X;X:X-X-X>X-X:X>X;X;X>X;X;X{.[ u u u w + 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X2 u u u u ) K.-X-X-X-X:X-X-X-X-X-X-X-X-X-X-X-X-X>X-X-X-X-X-X-XE.[ u u u u - . 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X1 u u u u m 2.E.-X+X:X-X-X-X-X-X-X-X-X-X:X-X-X-X;X-XOXi.B u u u u 1 o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X> u u u u u v [ l.I.OX-X-X-X-X-X-X-X-X+XI.f.@.m u u u u u 1 + o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X& 2 u u u u u u u d B V V V V B d u u u u u u u y - . o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X+ - 1 u u u u u u u a u u u u u u u u 2 - o o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xo . X # - > 1 2 2 2 1 2 > - # o . o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xo o . o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", +"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X" +}; diff --git a/share/pixmaps/bitgem32.xpm b/share/pixmaps/bitgem32.xpm new file mode 100644 index 0000000..c77277b --- /dev/null +++ b/share/pixmaps/bitgem32.xpm @@ -0,0 +1,468 @@ +/* XPM */ +static char * BottleCaps32_xpm[] = { +"32 32 433 2", +" c None", +". c #B28F63", +"+ c #C8A274", +"@ c #C69962", +"# c #C59963", +"$ c #C59861", +"% c #C8A478", +"& c #C39760", +"* c #C49863", +"= c #C49963", +"- c #C49862", +"; c #C39862", +"> c #C49A67", +", c #C09F77", +"' c #D5AD79", +") c #E3AB66", +"! c #D38019", +"~ c #D3801B", +"{ c #D3811C", +"] c #D3811B", +"^ c #D07A10", +"/ c #DD9D4E", +"( c #EECB9E", +"_ c #D78D30", +": c #D17D15", +"< c #D17B11", +"[ c #E0A051", +"} c #E0B37D", +"| c #B9966D", +"1 c #C29C6C", +"2 c #D7913A", +"3 c #E1A050", +"4 c #DD9A48", +"5 c #D17A0F", +"6 c #D3801A", +"7 c #D27D14", +"8 c #D48422", +"9 c #ECC28F", +"0 c #F6D7B1", +"a c #E6B271", +"b c #D17A10", +"c c #D88D30", +"d c #E2A65B", +"e c #D98F33", +"f c #CE9F65", +"g c #AF8F67", +"h c #D39B55", +"i c #D57F15", +"j c #D5892A", +"k c #E1A965", +"l c #D68A2D", +"m c #D17E17", +"n c #D3821F", +"o c #D3821E", +"p c #D2811C", +"q c #D07B11", +"r c #E3AF6E", +"s c #F2CFA6", +"t c #F1C999", +"u c #F0CCA0", +"v c #DA9643", +"w c #D07A11", +"x c #D38320", +"y c #D2811D", +"z c #D27F19", +"A c #E1A863", +"B c #DA9541", +"C c #D2790C", +"D c #D69645", +"E c #C3A178", +"F c #CA9E68", +"G c #D88C2E", +"H c #D27E17", +"I c #D07C14", +"J c #DC9D4E", +"K c #DFA359", +"L c #D17D16", +"M c #DA9844", +"N c #F0CEA2", +"O c #F0C897", +"P c #EDC089", +"Q c #F2CEA3", +"R c #E8BC85", +"S c #D2821F", +"T c #D07B12", +"U c #DB9846", +"V c #E0A55C", +"W c #D78622", +"X c #D09C5C", +"Y c #BC976C", +"Z c #D7984B", +"` c #D37F16", +" . c #D2811E", +".. c #D3831F", +"+. c #D9933C", +"@. c #D17C14", +"#. c #D48524", +"$. c #EAC18D", +"%. c #F2CDA1", +"&. c #EEC28C", +"*. c #EEC592", +"=. c #EFC490", +"-. c #F2D1A9", +";. c #DEA156", +">. c #D58829", +",. c #E1AA65", +"'. c #D78E33", +"). c #D17C13", +"!. c #D8933D", +"~. c #C69E6D", +"{. c #CF9D5F", +"]. c #D88621", +"^. c #D2801C", +"/. c #D38422", +"(. c #D9943D", +"_. c #E2AB66", +":. c #E3AD6B", +"<. c #F3D4AE", +"[. c #EEC490", +"}. c #EFC592", +"|. c #EFC593", +"1. c #EEC390", +"2. c #F1CB9D", +"3. c #EEC899", +"4. c #D68B2F", +"5. c #CF790E", +"6. c #DEA053", +"7. c #DEA256", +"8. c #D38321", +"9. c #D28220", +"0. c #D58118", +"a. c #D49C56", +"b. c #B5936A", +"c. c #C09259", +"d. c #D88D31", +"e. c #CF7609", +"f. c #CF780C", +"g. c #DD9D50", +"h. c #D78F35", +"i. c #EDC18B", +"j. c #EEC28D", +"k. c #EDC08A", +"l. c #F2D0A7", +"m. c #E1A862", +"n. c #D5882A", +"o. c #DEA35A", +"p. c #D07C15", +"q. c #CF7910", +"r. c #D07B13", +"s. c #CE770D", +"t. c #D58521", +"u. c #C7975B", +"v. c #B59166", +"w. c #E1B680", +"x. c #DC9740", +"y. c #DB9947", +"z. c #DB9847", +"A. c #D99540", +"B. c #DB9A48", +"C. c #E8BF8A", +"D. c #EECEA4", +"E. c #F5D9B7", +"F. c #F3D1A8", +"G. c #F3D3AB", +"H. c #F3D2AB", +"I. c #F3D3AC", +"J. c #F4D4AE", +"K. c #F5DDC0", +"L. c #EDC38E", +"M. c #E6AB60", +"N. c #DF9841", +"O. c #E19D48", +"P. c #E19D49", +"Q. c #E29D48", +"R. c #E29D49", +"S. c #E39A41", +"T. c #E7B270", +"U. c #C09C72", +"V. c #B38E62", +"W. c #EDD1AD", +"X. c #F1CA9B", +"Y. c #EEC99B", +"Z. c #EFC99B", +"`. c #EFC99A", +" + c #EFC89A", +".+ c #EEC89A", +"++ c #EEC898", +"@+ c #EEC696", +"#+ c #F2D5B1", +"$+ c #ECC89B", +"%+ c #E1A964", +"&+ c #E2AC68", +"*+ c #E3AD6A", +"=+ c #E4AD68", +"-+ c #E9BB83", +";+ c #D1B594", +">+ c #B18349", +",+ c #B38449", +"'+ c #B4864D", +")+ c #B4864E", +"!+ c #B5864D", +"~+ c #B6864D", +"{+ c #B6874E", +"]+ c #B38348", +"^+ c #C1945E", +"/+ c #C7A984", +"(+ c #C8A67D", +"_+ c #F3CFA3", +":+ c #F0C48F", +"<+ c #F0C693", +"[+ c #F0CA9B", +"}+ c #E2AC6A", +"|+ c #CE7507", +"1+ c #CF780D", +"2+ c #CF790F", +"3+ c #CF780E", +"4+ c #D27A0D", +"5+ c #DA953E", +"6+ c #96682F", +"7+ c #764205", +"8+ c #7A4606", +"9+ c #7B4707", +"0+ c #7B4708", +"a+ c #794404", +"b+ c #7B4607", +"c+ c #A37D50", +"d+ c #D7B790", +"e+ c #F5CD9D", +"f+ c #EEC28E", +"g+ c #EEC491", +"h+ c #EEC38F", +"i+ c #F2CFA4", +"j+ c #EBC28F", +"k+ c #D7841F", +"l+ c #DAA665", +"m+ c #8E5E24", +"n+ c #7F4B0B", +"o+ c #865213", +"p+ c #804A08", +"q+ c #A27946", +"r+ c #C2A47E", +"s+ c #B39066", +"t+ c #E6C49B", +"u+ c #F3C894", +"v+ c #F2CCA0", +"w+ c #EDC697", +"x+ c #D5892B", +"y+ c #D17F19", +"z+ c #D3811E", +"A+ c #D6821B", +"B+ c #CA9B61", +"C+ c #895B24", +"D+ c #804A0A", +"E+ c #855112", +"F+ c #845112", +"G+ c #7F4907", +"H+ c #94662F", +"I+ c #B9986F", +"J+ c #C5A57E", +"K+ c #F1C692", +"L+ c #EFC591", +"M+ c #F0C795", +"N+ c #EFC897", +"O+ c #DDA054", +"P+ c #DB8F30", +"Q+ c #B48851", +"R+ c #83531A", +"S+ c #824D0C", +"T+ c #845011", +"U+ c #814B0B", +"V+ c #885518", +"W+ c #B08C61", +"X+ c #D6B790", +"Y+ c #F3CB9A", +"Z+ c #F1CCA0", +"`+ c #D37F18", +" @ c #E1A255", +".@ c #A17138", +"+@ c #7C490A", +"@@ c #834E0E", +"#@ c #814C0C", +"$@ c #A47C4B", +"%@ c #C5A885", +"&@ c #AD8A5E", +"*@ c #E6C49C", +"=@ c #F2C894", +"-@ c #EFC491", +";@ c #EEC38E", +">@ c #E8BA81", +",@ c #D47F16", +"'@ c #D8A15E", +")@ c #966831", +"!@ c #7C4706", +"~@ c #804B0A", +"{@ c #976A33", +"]@ c #BD9D76", +"^@ c #C4A27B", +"/@ c #F0CCA1", +"(@ c #F1C691", +"_@ c #F1CC9F", +":@ c #EBC08D", +"<@ c #D58A2D", +"[@ c #D68219", +"}@ c #C89659", +"|@ c #8F642F", +"1@ c #7F4908", +"2@ c #814C0B", +"3@ c #89571A", +"4@ c #B28F64", +"5@ c #D5B58D", +"6@ c #F4CC9C", +"7@ c #EFC38F", +"8@ c #EEC797", +"9@ c #DC9B4C", +"0@ c #D17E18", +"a@ c #DE9437", +"b@ c #B8884D", +"c@ c #84541A", +"d@ c #824D0D", +"e@ c #834F0F", +"f@ c #A88152", +"g@ c #B08C60", +"h@ c #E3C29B", +"i@ c #F3C995", +"j@ c #F2D0A8", +"k@ c #E0A65E", +"l@ c #E1A152", +"m@ c #A97B42", +"n@ c #855113", +"o@ c #9B703B", +"p@ c #B99970", +"q@ c #C1A078", +"r@ c #EECBA1", +"s@ c #F1C591", +"t@ c #EEC18C", +"u@ c #E5B273", +"v@ c #D37D12", +"w@ c #D59B53", +"x@ c #9D7341", +"y@ c #7D4705", +"z@ c #865314", +"A@ c #814B0A", +"B@ c #8D5D22", +"C@ c #B49268", +"D@ c #D2B38C", +"E@ c #F2CC9C", +"F@ c #F1CA9C", +"G@ c #EABD87", +"H@ c #D17F18", +"I@ c #D1811D", +"J@ c #D8851D", +"K@ c #C89250", +"L@ c #906735", +"M@ c #814B09", +"N@ c #834E0F", +"O@ c #AA8456", +"P@ c #AA875C", +"Q@ c #E2C199", +"R@ c #F3CA97", +"S@ c #DA9743", +"T@ c #D07C16", +"U@ c #DF973C", +"V@ c #BC8C50", +"W@ c #804F13", +"X@ c #844F0F", +"Y@ c #9E7441", +"Z@ c #BD9D77", +"`@ c #C09F78", +" # c #EDCAA0", +".# c #F3D4AF", +"+# c #DD9E4F", +"@# c #DD9A47", +"## c #B08550", +"$# c #7B4504", +"%# c #905F26", +"&# c #B7956D", +"*# c #D1B28C", +"=# c #EFC38D", +"-# c #F3D3AD", +";# c #E2AA65", +"># c #D27B10", +",# c #D39344", +"'# c #A37D4E", +")# c #7B4402", +"!# c #865315", +"~# c #AE895D", +"{# c #E1C19B", +"]# c #F3C996", +"^# c #F0C898", +"/# c #E9BB82", +"(# c #D48627", +"_# c #D7831B", +":# c #CD944D", +"<# c #906530", +"[# c #7D4604", +"}# c #A17948", +"|# c #BB9A72", +"1# c #BF9E75", +"2# c #EDCBA1", +"3# c #EEC99C", +"4# c #D58A2C", +"5# c #DB8C2A", +"6# c #C6965B", +"7# c #7A4504", +"8# c #92642B", +"9# c #B6946B", +"0# c #CFAF89", +"a# c #F2CC9E", +"b# c #F2D3AD", +"c# c #DA9239", +"d# c #D68A2B", +"e# c #B48A57", +"f# c #814E10", +"g# c #DEBF98", +"h# c #F7D6AD", +"i# c #E2A457", +"j# c #D28C36", +"k# c #A07948", +"l# c #BA9A70", +"m# c #EACAA1", +"n# c #F4C58B", +"o# c #CE944D", +"p# c #9E7542", +"q# c #B4936A", +"r# c #D0B28C", +"s# c #F4D4AD", +"t# c #D3A975", +"u# c #AC875B", +"v# c #E5D2BB", +"w# c #E0CAAE", +"x# c #AE895C", +"y# c #BB9D78", +"z# c #C5A989", +" . + @ # # # # # # $ # % & * * = * * - ; > , ", +" ' ) ! ~ { { { { ] ^ / ( _ : { { { { { < [ } | ", +" 1 2 3 4 5 { 6 6 6 7 8 9 0 a b ! 6 6 ] 7 c d e f ", +" g h i j k l m n o p q r s t u v w x o y z A B C D E ", +" F G H I J K L y x ^ M N O P Q R S z x T U V y m W X ", +" Y Z ` .p ..A +.@.m #.$.%.&.*.=.-.;.^ L >.,.'.: x ).!.~. ", +" {.].^.x /.L (._.x ^ :.<.[.}.|.1.2.3.4.5.6.7.L 8.x 9.0.a.b. ", +" c.d.e.I T T T f.g.h.+.u }.i.j.&.j.k.l.m.n.o.p.q.I r.I s.t.u. ", +"v.w.x.y.y.z.U U A.B.C.D.E.F.G.H.H.I.H.J.K.L.M.N.O.P.O.Q.R.S.T.U.", +"V.W.X.Y.Z.`. +.+++@+#+$+%+&+*+*+*+:.:.=+-+;+>+,+'+)+!+~+{+]+^+/+", +" (+_+:+}.}.}.}.}.<+[+}+|+1+2+2+2+2+3+4+5+6+7+8+9+9+0+0+a+b+c+ ", +" d+e+f+*.g+g+g+h+i+j+m y ........o k+l+m+n+o+o+o+o+o+p+q+r+ ", +" s+t+u+1.}.g+g+h+v+w+x+y+o z+y y { A+B+C+D+E+F+E+E+G+H+I+ ", +" J+u K+g+}.L+g+M+N+O+: o o o o 6 P+Q+R+S+F+T+E+U+V+W+ ", +" X+Y+=.g+g+}.=.Z+r w o y o o `+ @.@+@T+T+E+@@#@$@%@ ", +" &@*@=@-@*.}.;@F.>@T o o y o ,@'@)@!@E+E+T+~@{@]@ ", +" ^@/@(@g+L+h+_@:@<@z o o .[@}@|@1@T+E+2@3@4@ ", +" 5@6@7@}.g+L+8@9@r.x o 0@a@b@c@d@E+e@2@f@ ", +" g@h@i@1.}.j.j@k@5.8...).l@m@!@T+n@G+o@p@ ", +" q@r@s@g+t@<.u@@.n 9.v@w@x@y@z@A@B@C@ ", +" D@E@;@1.F@G@4.H@I@J@K@L@M@N@T+O@ ", +" P@Q@R@1.-@Y.S@r.T@U@V@W@X@A@Y@Z@ ", +" `@ #=@j..#+#2+T @###$#2@%#&# ", +" *#X.=#-#;#0@>#,#'#)#!#~# ", +" {#]#^#/#(#_#:#<#[#}#|# ", +" 1#2#=@3#4#5#6#7#8#9# ", +" 0#a#b#c#d#e#f#g@ ", +" g#h#i#j#}#k#l# ", +" ]@m#n#o#p#q# ", +" r#s#t#u# ", +" v#w#x# ", +" y#z# "}; diff --git a/share/pixmaps/bitgem80.xpm b/share/pixmaps/bitgem80.xpm new file mode 100644 index 0000000..1a0bad2 --- /dev/null +++ b/share/pixmaps/bitgem80.xpm @@ -0,0 +1,955 @@ +/* XPM */ +static char * BottleCaps80_xpm[] = { +"81 80 872 2", +" c None", +". c #844E0D", +"+ c #8B5A1E", +"@ c #8A591D", +"# c #8A571A", +"$ c #895517", +"% c #895617", +"& c #895618", +"* c #885414", +"= c #885312", +"- c #885313", +"; c #885210", +"> c #87500D", +", c #824C0D", +"' c #824D0D", +") c #814B0A", +"! c #814A07", +"~ c #814A08", +"{ c #804904", +"] c #804702", +"^ c #7F4600", +"/ c #7E4400", +"( c #7F4400", +"_ c #7D4200", +": c #8B5513", +"< c #824A07", +"[ c #CFB89B", +"} c #FFF8ED", +"| c #FCF0DF", +"1 c #FCF0E0", +"2 c #FDF1E1", +"3 c #FDF2E3", +"4 c #FDF2E2", +"5 c #FDF1E2", +"6 c #FDF3E4", +"7 c #FDF3E6", +"8 c #FDF3E5", +"9 c #FEF4E7", +"0 c #FEF5E9", +"a c #FBEDDB", +"b c #FEF7ED", +"c c #FEF6EC", +"d c #FFF7ED", +"e c #FFF8EF", +"f c #FFF9F0", +"g c #FFFAF2", +"h c #FFFBF3", +"i c #FFFCF5", +"j c #FFFBF4", +"k c #FFFFFF", +"l c #AA8353", +"m c #94652C", +"n c #F2D8B9", +"o c #CD7303", +"p c #D17C13", +"q c #D07C13", +"r c #D17C14", +"s c #D27B11", +"t c #FBF3E9", +"u c #D17A0F", +"v c #D17D15", +"w c #D17D16", +"x c #D17E16", +"y c #D17E17", +"z c #D17C12", +"A c #FBF4EC", +"B c #FDFBF8", +"C c #88510F", +"D c #7F4703", +"E c #F6F3F0", +"F c #D78D32", +"G c #F7EAD8", +"H c #E0A45B", +"I c #D17E18", +"J c #D2811D", +"K c #D3821E", +"L c #D3821D", +"M c #D3811E", +"N c #D2811E", +"O c #D2821E", +"P c #D07A0F", +"Q c #EFD1AB", +"R c #FEFDFA", +"S c #EDCA9E", +"T c #D3811D", +"U c #D2821D", +"V c #D07A10", +"W c #F1D6B4", +"X c #E6B77C", +"Y c #E6B478", +"Z c #CDB9A0", +"` c #884F0B", +" . c #B99C79", +".. c #F4D8B4", +"+. c #D0790F", +"@. c #D78B2D", +"#. c #D0790E", +"$. c #D17D17", +"%. c #DC9B4A", +"&. c #FEFDFB", +"*. c #EDBD84", +"=. c #D78A2D", +"-. c #D2801B", +";. c #D27F19", +">. c #DA953F", +",. c #FCF7F0", +"'. c #D07B12", +"). c #FFFFFA", +"!. c #946327", +"~. c #895514", +"{. c #D27F18", +"]. c #D3821F", +"^. c #D07C14", +"/. c #EBC493", +"(. c #EECDA3", +"_. c #CF780D", +":. c #FDFCFA", +"<. c #F0C99B", +"[. c #EEC490", +"}. c #F2D0A9", +"|. c #F7EAD9", +"1. c #CF7609", +"2. c #CF770A", +"3. c #FDF8F2", +"4. c #DB9641", +"5. c #D17F19", +"6. c #DC9947", +"7. c #EDE8E0", +"8. c #814700", +"9. c #7F4601", +"0. c #E6DDD1", +"a. c #E1A861", +"b. c #D78D31", +"c. c #D27F1A", +"d. c #F0D4B0", +"e. c #F6E1C6", +"f. c #EEC28D", +"g. c #EFC592", +"h. c #EDC18A", +"i. c #FCF5EC", +"j. c #E2AA65", +"k. c #E8BC86", +"l. c #FAE3C6", +"m. c #AE8A5F", +"n. c #8E5918", +"o. c #A67F4E", +"p. c #FDEDD8", +"q. c #CF790F", +"r. c #DD9C4C", +"s. c #FAF2E6", +"t. c #CF770B", +"u. c #D38320", +"v. c #DD9E4D", +"w. c #FEFDFC", +"x. c #EDC089", +"y. c #EEC592", +"z. c #FEFEFC", +"A. c #D2801A", +"B. c #D2811C", +"C. c #D48421", +"D. c #D27E17", +"E. c #D38321", +"F. c #D3811C", +"G. c #834D0C", +"H. c #D58523", +"I. c #CF780C", +"J. c #F4DEC4", +"K. c #E5B476", +"L. c #EFC797", +"M. c #EEC491", +"N. c #EFC591", +"O. c #EEC38E", +"P. c #F7E0C7", +"Q. c #EFD2AD", +"R. c #F6E5D1", +"S. c #E1A964", +"T. c #EBBC82", +"U. c #D1BFA8", +"V. c #834B06", +"W. c #834C09", +"X. c #D1BEA6", +"Y. c #CF790E", +"Z. c #D4821E", +"`. c #F1D7B6", +" + c #F6DFC4", +".+ c #DA943D", +"++ c #DFA45A", +"@+ c #F9EDDD", +"#+ c #FFFBF1", +"$+ c #986A32", +"%+ c #986B33", +"&+ c #E4B071", +"*+ c #F4DFC4", +"=+ c #D2801C", +"-+ c #DFA255", +";+ c #FFFCFA", +">+ c #EDC088", +",+ c #EFC491", +"'+ c #F2CFA5", +")+ c #FAF2E7", +"!+ c #D27E16", +"~+ c #D58828", +"{+ c #DC9740", +"]+ c #F2EFEA", +"^+ c #814904", +"/+ c #804906", +"(+ c #F6F3EF", +"_+ c #DB943D", +":+ c #CF780B", +"<+ c #FBF2E8", +"[+ c #DD9C4B", +"}+ c #D3801B", +"|+ c #EFC693", +"1+ c #EFC593", +"2+ c #EDBF88", +"3+ c #FBF3E8", +"4+ c #E5B374", +"5+ c #EECEA7", +"6+ c #EAC290", +"7+ c #F7DBB9", +"8+ c #B5956D", +"9+ c #89520E", +"0+ c #844C08", +"a+ c #BB9F7B", +"b+ c #F4D6B1", +"c+ c #D88E33", +"d+ c #D0790D", +"e+ c #F1D8B8", +"f+ c #F7E0C5", +"g+ c #EEC38F", +"h+ c #EEC591", +"i+ c #D37F18", +"j+ c #D88D32", +"k+ c #FEFCF8", +"l+ c #844D0B", +"m+ c #EECEA5", +"n+ c #EAC292", +"o+ c #DFA256", +"p+ c #FEFCF9", +"q+ c #F6DFC3", +"r+ c #F0D4B1", +"s+ c #FBF5EC", +"t+ c #DC9A48", +"u+ c #E7B476", +"v+ c #D8CAB8", +"w+ c #804500", +"x+ c #7E4500", +"y+ c #E4DCD1", +"z+ c #E2A861", +"A+ c #D17F18", +"B+ c #D17B11", +"C+ c #D68A2B", +"D+ c #EFC897", +"E+ c #EFC492", +"F+ c #FFFFFE", +"G+ c #DA9540", +"H+ c #F3DDC1", +"I+ c #FFF9EE", +"J+ c #986B34", +"K+ c #8B5310", +"L+ c #A68153", +"M+ c #FEEDD8", +"N+ c #E0A359", +"O+ c #F9EDDF", +"P+ c #F2DABC", +"Q+ c #F6DEC2", +"R+ c #EEC28C", +"S+ c #EEC492", +"T+ c #F1CEA3", +"U+ c #D0770B", +"V+ c #D38019", +"W+ c #DA933D", +"X+ c #F5F4F1", +"Y+ c #7F4602", +"Z+ c #824B08", +"`+ c #D48625", +" @ c #F5E3CD", +".@ c #E2AC69", +"+@ c #E0A55C", +"@@ c #FEFBF8", +"#@ c #EDC18B", +"$@ c #FAEEDF", +"%@ c #E6B87F", +"&@ c #E5B274", +"*@ c #F6D8B4", +"=@ c #B99C78", +"-@ c #89510F", +";@ c #834C0A", +">@ c #D4C3AE", +",@ c #EABC84", +"'@ c #D48320", +")@ c #D28019", +"!@ c #EFC695", +"~@ c #DE9E50", +"{@ c #FAF0E4", +"]@ c #8A5516", +"^@ c #986931", +"/@ c #FFFCF3", +"(@ c #D07B13", +"_@ c #E7BA81", +":@ c #F3DDC2", +"<@ c #F5DCBD", +"[@ c #F4DAB9", +"}@ c #F3DCC0", +"|@ c #D07A11", +"1@ c #E3AD6A", +"2@ c #DFD2C2", +"3@ c #824B07", +"4@ c #814906", +"5@ c #F9F7F4", +"6@ c #D89138", +"7@ c #FDF8F3", +"8@ c #E0A760", +"9@ c #FEFAF5", +"0@ c #FFFDFC", +"a@ c #EBC698", +"b@ c #FFF6E7", +"c@ c #9E723D", +"d@ c #925E1E", +"e@ c #864F0C", +"f@ c #BC9F7B", +"g@ c #F5D6B1", +"h@ c #DA9641", +"i@ c #FCF7EF", +"j@ c #FEFEFE", +"k@ c #EFC694", +"l@ c #F0CA9C", +"m@ c #FBF5ED", +"n@ c #D0780D", +"o@ c #D68929", +"p@ c #D17D13", +"q@ c #D98F34", +"r@ c #FAFAF9", +"s@ c #7E4501", +"t@ c #905F23", +"u@ c #D17D14", +"v@ c #CE7304", +"w@ c #EFCEA5", +"x@ c #E6B679", +"y@ c #F1DABB", +"z@ c #F3D7B4", +"A@ c #EEC18B", +"B@ c #EEC18A", +"C@ c #EDC08A", +"D@ c #F8E9D4", +"E@ c #F5E5CF", +"F@ c #DB9845", +"G@ c #CF760A", +"H@ c #CD7201", +"I@ c #F1CC9E", +"J@ c #BDA07C", +"K@ c #824A06", +"L@ c #854F0D", +"M@ c #D2BB9E", +"N@ c #F9F0E4", +"O@ c #F9F1E6", +"P@ c #F9EFE3", +"Q@ c #F8EEDF", +"R@ c #F8ECDC", +"S@ c #F7EADA", +"T@ c #F6E8D6", +"U@ c #F6E6D3", +"V@ c #F6E7D3", +"W@ c #F6E6D2", +"X@ c #F6E5D0", +"Y@ c #FEFFFF", +"Z@ c #FCF6ED", +"`@ c #FCF6EE", +" # c #FCF5ED", +".# c #FCF5EB", +"+# c #FCF4EB", +"@# c #FCF4EA", +"## c #FCF4E9", +"$# c #FBF4E9", +"%# c #FBF3E7", +"&# c #FBF2E6", +"*# c #FBF1E5", +"=# c #FBF1E4", +"-# c #FBF0E3", +";# c #F2D3AC", +"># c #F4D9B6", +",# c #F4D7B1", +"'# c #F3D6B0", +")# c #F3D4AD", +"!# c #F3D4AC", +"~# c #F2D1A8", +"{# c #F1D1A8", +"]# c #F1CEA2", +"^# c #F0CC9E", +"/# c #F0CB9E", +"(# c #EFC899", +"_# c #F0C999", +":# c #EFC999", +"<# c #EEC694", +"[# c #EEC695", +"}# c #ECC089", +"|# c #A57B49", +"1# c #824C0B", +"2# c #F0C897", +"3# c #EFC796", +"4# c #F0C796", +"5# c #F0C898", +"6# c #F0C99A", +"7# c #F0CA9B", +"8# c #F1CB9E", +"9# c #F8E8D4", +"0# c #E8BE88", +"a# c #D78D33", +"b# c #D9923A", +"c# c #D9933C", +"d# c #D9943E", +"e# c #DA9642", +"f# c #DA9744", +"g# c #DB9846", +"h# c #DA9846", +"i# c #DB9A48", +"j# c #DC9A4A", +"k# c #DC9C4C", +"l# c #DC9D4E", +"m# c #DC9C4D", +"n# c #DD9E50", +"o# c #DD9F52", +"p# c #DD9F51", +"q# c #DDA155", +"r# c #DB9948", +"s# c #FCF1E3", +"t# c #B59064", +"u# c #A88150", +"v# c #A88050", +"w# c #A98353", +"x# c #AA8454", +"y# c #AA8354", +"z# c #AB865A", +"A# c #AB875B", +"B# c #AB895F", +"C# c #AC8A60", +"D# c #AB8960", +"E# c #B18D62", +"F# c #B39067", +"G# c #B3936D", +"H# c #B3946D", +"I# c #B49773", +"J# c #B49772", +"K# c #B39671", +"L# c #BE9F79", +"M# c #97652A", +"N# c #8C5717", +"O# c #9B6E37", +"P# c #F1CEA4", +"Q# c #F4E0C7", +"R# c #D07E17", +"S# c #804805", +"T# c #824D0C", +"U# c #824C0C", +"V# c #814C0C", +"W# c #814C0B", +"X# c #814B0B", +"Y# c #773C00", +"Z# c #EEE4D8", +"`# c #A8804E", +" $ c #C9B193", +".$ c #FCECD7", +"+$ c #D27D15", +"@$ c #D89139", +"#$ c #EAE1D5", +"$$ c #7A4200", +"%$ c #855112", +"&$ c #845011", +"*$ c #855011", +"=$ c #845012", +"-$ c #804A08", +";$ c #C4A884", +">$ c #D6C2A9", +",$ c #7E4602", +"'$ c #F1EDE5", +")$ c #F1CFA6", +"!$ c #FDFAF4", +"~$ c #D78F35", +"{$ c #ECC088", +"]$ c #BDA17E", +"^$ c #814D0D", +"/$ c #966830", +"($ c #FBF8F3", +"_$ c #864E09", +":$ c #946023", +"<$ c #8B591B", +"[$ c #EDC28E", +"}$ c #FBEEDF", +"|$ c #E2AA64", +"1$ c #976932", +"2$ c #865214", +"3$ c #855111", +"4$ c #845111", +"5$ c #845112", +"6$ c #855213", +"7$ c #804907", +"8$ c #97682E", +"9$ c #BA9A74", +"0$ c #FFF6E8", +"a$ c #F4D6B2", +"b$ c #EFD3B1", +"c$ c #F8F2EA", +"d$ c #885413", +"e$ c #7B4400", +"f$ c #DBC8B1", +"g$ c #C0A27D", +"h$ c #7D4501", +"i$ c #E8DED1", +"j$ c #F5D8B5", +"k$ c #FCF6F0", +"l$ c #D68F36", +"m$ c #EDE6DD", +"n$ c #7B4200", +"o$ c #855012", +"p$ c #A8804F", +"q$ c #EFE5DA", +"r$ c #814600", +"s$ c #865111", +"t$ c #FDF9F3", +"u$ c #D68A2C", +"v$ c #E7B372", +"w$ c #C6B095", +"x$ c #7F4A09", +"y$ c #844F10", +"z$ c #875212", +"A$ c #8E5919", +"B$ c #86500E", +"C$ c #FFFFF9", +"D$ c #EDBF87", +"E$ c #DEA156", +"F$ c #FBE6CC", +"G$ c #9A6E39", +"H$ c #865315", +"I$ c #7A4100", +"J$ c #F1E8DC", +"K$ c #AD8657", +"L$ c #7D4502", +"M$ c #D8C7B1", +"N$ c #FAE3C7", +"O$ c #EEC28E", +"P$ c #F5DDBF", +"Q$ c #ECC89A", +"R$ c #FBF7F0", +"S$ c #865213", +"T$ c #865314", +"U$ c #7E4705", +"V$ c #C0A27E", +"W$ c #D8C5AE", +"X$ c #F1CB9D", +"Y$ c #FAF1E4", +"Z$ c #D78F36", +"`$ c #ECE4DA", +" % c #7C4300", +".% c #95652B", +"+% c #FFFEFB", +"@% c #844C07", +"#% c #8C5716", +"$% c #9A6D37", +"%% c #E4AE6A", +"&% c #CDB9A1", +"*% c #7E4603", +"=% c #FDFAF6", +"-% c #9A6C34", +";% c #C8AF91", +">% c #FDEDD9", +",% c #DD9E51", +"'% c #F8DEBD", +")% c #A17847", +"!% c #7B4401", +"~% c #D9C5AE", +"{% c #C2A481", +"]% c #F7F3ED", +"^% c #EEC18C", +"/% c #F7E4CB", +"(% c #E8BC85", +"_% c #CF7608", +":% c #824E0E", +"<% c #F0E8DC", +"[% c #854C07", +"}% c #946021", +"|% c #916125", +"1% c #EDC18C", +"2% c #F1CDA2", +"3% c #F4E3CC", +"4% c #EEE7E0", +"5% c #7F4806", +"6% c #905D1E", +"7% c #87500F", +"8% c #B99973", +"9% c #FFF6E9", +"0% c #D0780C", +"a% c #E1A962", +"b% c #D4C2AC", +"c% c #7B4300", +"d% c #EFE5D8", +"e% c #AE885A", +"f% c #7D4400", +"g% c #E8DED2", +"h% c #F4D7B3", +"i% c #F3D2A9", +"j% c #AC885D", +"k% c #804A09", +"l% c #7F4908", +"m% c #BC9C76", +"n% c #DDCCB7", +"o% c #854B03", +"p% c #85500F", +"q% c #F8E6CF", +"r% c #E6B77E", +"s% c #845010", +"t% c #926125", +"u% c #854D09", +"v% c #864F0D", +"w% c #A98253", +"x% c #FFFEF6", +"y% c #F3D3AC", +"z% c #F2DABB", +"A% c #D5831E", +"B% c #F2EFEB", +"C% c #7E4806", +"D% c #7F4704", +"E% c #FEFBF6", +"F% c #9B6E36", +"G% c #7D4500", +"H% c #D8C7B2", +"I% c #F8E2C5", +"J% c #FDF9F4", +"K% c #E2A860", +"L% c #7D4603", +"M% c #7C4503", +"N% c #D5C0A6", +"O% c #C7AC8B", +"P% c #7E4704", +"Q% c #FBFBF9", +"R% c #F1CA9C", +"S% c #FEFCFA", +"T% c #D6892A", +"U% c #B29068", +"V% c #F4EDE4", +"W% c #9D713B", +"X% c #F9E9D6", +"Y% c #E2AE6C", +"Z% c #FFF3E2", +"`% c #8E5D20", +" & c #834E0F", +".& c #814B08", +"+& c #905D1F", +"@& c #CBB395", +"#& c #FEEED9", +"$& c #D27C13", +"%& c #FBFAF8", +"&& c #7C4502", +"*& c #855113", +"=& c #794000", +"-& c #E9DECE", +";& c #AF8C5F", +">& c #804905", +",& c #F6F2EC", +"'& c #F3D0A6", +")& c #EFC795", +"!& c #F9EFE1", +"~& c #E0A051", +"{& c #D9CBBA", +"]& c #BA9971", +"^& c #E0D0BC", +"/& c #844903", +"(& c #915F24", +"_& c #EDC08B", +":& c #D3801A", +"<& c #EFCA9A", +"[& c #B79872", +"}& c #8E5C1F", +"|& c #885110", +"1& c #B99972", +"2& c #FFF4E6", +"3& c #FAEFE1", +"4& c #DFA359", +"5& c #D07B11", +"6& c #FBEBD6", +"7& c #96672F", +"8& c #FBF8F2", +"9& c #9D7039", +"0& c #E8DFD2", +"a& c #EEC390", +"b& c #F4D9B8", +"c& c #EECDA4", +"d& c #D27D16", +"e& c #FFFEFA", +"f& c #D2BB9F", +"g& c #C9B091", +"h& c #854F0E", +"i& c #F7E9D8", +"j& c #DE9843", +"k& c #DFD5C8", +"l& c #7D4705", +"m& c #834F10", +"n& c #A17743", +"o& c #F8F3EC", +"p& c #834A04", +"q& c #874F0D", +"r& c #A88152", +"s& c #FFFCF4", +"t& c #D38421", +"u& c #B89A75", +"v& c #8E5A1C", +"w& c #7F4702", +"x& c #DCCCB8", +"y& c #F8E1C4", +"z& c #FDF7F0", +"A& c #DA943E", +"B& c #F9E6CE", +"C& c #9D713C", +"D& c #E7DBC9", +"E& c #B49066", +"F& c #824C0A", +"G& c #FDFDFB", +"H& c #F6DFC2", +"I& c #E9C08E", +"J& c #7F4807", +"K& c #B59268", +"L& c #E5D8C7", +"M& c #8D5513", +"N& c #9C703B", +"O& c #F1CDA1", +"P& c #D38422", +"Q& c #D98E31", +"R& c #EAE3DA", +"S& c #834E0E", +"T& c #8D5B1E", +"U& c #87510F", +"V& c #CAB295", +"W& c #FDECD7", +"X& c #FBF5EE", +"Y& c #D3831F", +"Z& c #EDBF85", +"`& c #BFA483", +" * c #FAF5EF", +".* c #A07540", +"+* c #F4F0EA", +"@* c #F3D1A7", +"#* c #D88F36", +"$* c #FBE8CE", +"%* c #9D723D", +"&* c #CEB698", +"** c #CCB598", +"=* c #844902", +"-* c #F8E5CE", +";* c #E6B67A", +">* c #FBF4EB", +",* c #875211", +"'* c #804B0A", +")* c #9F733E", +"!* c #FAF6EF", +"~* c #814802", +"{* c #B89872", +"]* c #F5E2CB", +"^* c #D68B30", +"/* c #F1EBE2", +"(* c #814B09", +"_* c #905F22", +":* c #7E4601", +"<* c #F3D6B2", +"[* c #E7B474", +"}* c #C6AF93", +"|* c #7D4704", +"1* c #E5D8C6", +"2* c #8B5719", +"3* c #EDC390", +"4* c #FEFAF6", +"5* c #FAE3C5", +"6* c #9F7643", +"7* c #804B0B", +"8* c #B18D61", +"9* c #E7DACA", +"0* c #8D5817", +"a* c #A98355", +"b* c #FFFEF7", +"c* c #FBEFE1", +"d* c #E1A760", +"e* c #FAF2E9", +"f* c #8C591B", +"g* c #8A5719", +"h* c #885211", +"i* c #804803", +"j* c #DBCBB7", +"k* c #F8DFC2", +"l* c #F4D5B1", +"m* c #D58A2E", +"n* c #F2ECE5", +"o* c #F9F3EB", +"p* c #A27845", +"q* c #FDFDFC", +"r* c #E3A861", +"s* c #CFBEA7", +"t* c #7D4604", +"u* c #CAB091", +"v* c #D1BCA0", +"w* c #824801", +"x* c #9C6F39", +"y* c #F8DDBA", +"z* c #A17A4A", +"A* c #FEFCF7", +"B* c #804703", +"C* c #814803", +"D* c #FBEAD4", +"E* c #DEA257", +"F* c #926024", +"G* c #F4EFEA", +"H* c #F5DDBE", +"I* c #ECC89C", +"J* c #D58A2C", +"K* c #EFE9E1", +"L* c #E2D3BF", +"M* c #BA9973", +"N* c #916024", +"O* c #D6C6B2", +"P* c #EADFD1", +"Q* c #86500D", +"R* c #BB9B75", +"S* c #FFF7E9", +"T* c #F3D1A6", +"U* c #AD8A60", +"V* c #834F0F", +"W* c #875312", +"X* c #895413", +"Y* c #EAE0D4", +"Z* c #FCF3E9", +"`* c #FFF9ED", +" = c #885619", +".= c #F4EDE3", +"+= c #A47C4A", +"@= c #8A5617", +"#= c #F7E4CA", +"$= c #D4831F", +"%= c #F2EEE8", +"&= c #C8AD8C", +"*= c #D4BFA5", +"== c #844B06", +"-= c #8E5716", +";= c #AB8456", +">= c #F5E4CE", +",= c #DBCDBB", +"'= c #FDFAF5", +")= c #844D0A", +"!= c #814905", +"~= c #F7DFC2", +"{= c #CE7506", +"]= c #EFC898", +"^= c #B69771", +"/= c #926227", +"(= c #FFF3E1", +"_= c #DECCB7", +":= c #BE9F7A", +"<= c #874F0B", +"[= c #9B6E38", +"}= c #FFFFF8", +"|= c #F7E1C8", +"1= c #E6B374", +"2= c #F3EEE6", +"3= c #A77E4D", +"4= c #F0E7DC", +"5= c #7D4300", +"6= c #804600", +"7= c #C9B092", +"8= c #E0CFBA", +"9= c #86510F", +"0= c #F4EEE6", +"a= c #A47B49", +"b= c #D2BCA1", +"c= c #8A5412", +"d= c #B28D61", +"e= c #875110", +" . + @ @ @ @ # $ % % % % & * = = = = = - ; > > > > > > . , ' ' ' ' ' ) ! ! ! ! ! ~ { ] ] ] ] ] ] ^ / ( ( _ : ", +" < [ } | 1 1 1 2 3 4 4 4 4 5 6 7 7 7 7 7 8 9 0 0 0 0 0 0 a b c c c c c d e e e e e e f g g g g g g h i i j k l ", +" m k n o p p q p p p p p p p r r r r r r r r r r r r p s t u v v v v v v w w w w w w w w w w w w w x y w z A B C ", +" D E F G H I J K L J J M K N O L K L K L J K K J O O K P Q R S P T K K O K T K K T K K K U U M U T J U K V W X Y Z ` ", +" C ...+.@.k #.O K T J N J K N J L J J K L N K M J N K $.%.&.*.k =.-.J M N K J K J J J J N J J N O J N U ;.>.,.P '.).!. ", +" ~.k {.].^./.(._.K T O K M K M O U K L K L K O K J O N P :.<.[.}.|.1.].M O K T O K T K K K U U M K T K K 2.3.4.5.O 6.7.8. ", +" 9.0.a.-.J J V &.b.c.J J T T T M J N T M T M J J M J K 2.d.e.f.g.h.i.j.5.J N K M J T M T T M N N M J T K V k.d.V K K V l.m. ", +" n.o.p.q.K K K -.r.s.t.u.J J J K J J L J J K L J K M J w v.w.x.y.g.g.y.z.A.].K K J K J J J J N J J N J J B.C.k D.J J J E.F.k ; ", +" G.k H.E.J K K K I.J.K.y J M N K M N K N J K K N K J u.p w.L.M.g.N.M.O.P.Q.+.K K J K N J N N M J J N O ].t.R.S.I K J K J V T.U.V. ", +" W.X.h.Y.T U U O K K F.k Z.u.K J U J J O J J L O J U K V `. +f.g.M.M.g.g.x.k .+J J J U J J J J J J J J J -.++@+2.K K J O J K t.#+$+ ", +" %+#+t.K J K K K K K y &+*+V T K K M K K K K K K N N =+-+;+>+g.,+M.,+g.M.y.'+)++.J K K K K K K K K K K u.!+k ~+K K K K K N K I {+]+^+ ", +" /+(+_+I K J K K K K L ].:+<+[+N T K N O L K L K L J K }+k |+1+M.M.M.M.g.g.g.2+3+4+I K K K T K K K U U J q 5+6+q K K K U L J K K I.7+8+9+ ", +" 0+a+b+V K J J K K K K L O u.c+w.d+K K N J L J J K L K I.e+f+g+M.,+,+M.,+g.M.g.M.h+k i+B.K J J J J N J K O j+k+p ].J N K J L J M J B.F.k l+ ", +" * k !+J K K K K K K K K K T q.m+n+'.K M O U K L K K I o+p+>+1+g.,+,+M.,+,+,+,+M.f.q+r+_.K K T K K K U K 2.s+t+O J K K K U L K N K T y u+v+w+ ", +" x+y+z+A+L T T J T T K L K T K K B+k C+=+K J N T M T J !+k D+[.M.E+E+M.M.M.E+E+,+,+g.x.F+G+I K M T T M K w 4+H+I.K T T M M N M J J L J J d+I+J+ ", +" K+L+M+t.K O J J J K K K K L J K K v N+O+2.K J L J J K I.P+Q+R+g.h+S+,+M.M.M.g.M.g.M.g.g+T+t U+K J J J N B.Z.k V+J J J J N K J L J M U J K B.W+X+Y+ ", +" Z+k `+J K K N N N K K K K K M K K K I. @.@v K K N K v +@@@2+g.M.h+S+N.N.M.N.g.h+g.M.g.g.#@$@%@V K N N K _.*+&@'.K M L K M K J K N K K O K K #.*@=@-@ ", +" ;@>@,@v K J U J J J U U O U K J K U J -.'@k D.J O J J )@k !@[.g.M.h+E+M.M.M.M.g.,+g.,+g.M.M.g+k K J N J I ~@{@2.K J J U U J K J O J U U J O L ].I k ]@ ", +" ^@/@I.K K J K K K N K K K K K K K K N K (@_@W +.K K I.:@<@f.g.g.M.g.E+g.,+M.,+g.g.g.E+g.g.g.g+[@}@I.K O |@&.b.c.O K M L K K K K K N K K O K T J A+1@2@3@ ", +" 4@5@6@O J K J K K K J K K K K L K K L J J O 2.7@4.A+v 8@9@2+g.N.g.M.y.g.g.M.M.M.g.g.N.N.g.h+g.g.>+0@t+O '.a@S +.K U T J U U K K U L J K K U K J J ].t.b@c@d@ ", +" e@f@g@q J J M J O J J J K K K K L J K T J N J B.h@i@d+A.j@k@g.M.g.g.M.h+M.,+,+M.,+g.M.g.M.g.M.g.M.g.l@m@n@o@k p@J J O J N U U N K J L J M U U K J J N u.q@r@s@ ", +" t@i #.{.v v u@r u@r r r p p p q p p '.'.'.'.'.'.v@w@x@y@z@x.A@A@A@A@A@A@A@A@B@h.h.h.h.h.C@C@C@C@x.x.*.D@Y E@F@G@_._._.Y.Y.Y.#.#.#.+.+.+.P P P V V V |@|@H@I@J@K@", +"L@M@k N@O@O@O@P@P@P@Q@Q@Q@R@R@R@|.S@|.T@T@T@U@V@W@X@W@k Y@Z@`@Z@Z@ #.#.#+#@#@###t $#3+%#%#&#&#&#*#=#*#=#-#k k ;#>#,#'#b+)#!#)#~#{#~#]#]#]#^#/#^#(#_#:#<#<#[#}#k |#", +" 1#B 2#,+[.[.g.g.g.k@k@k@3#4#4#5#5#5#6#6#6#l@7#l@8#6#9#0#a#6@b#b#c#d#d#>.e#e#f#g#h#i#j#j#k#l#m#n#o#p#q#r#s#t#u#v#w#x#y#z#A#A#B#C#D#E#E#E#F#F#F#G#G#H#I#J#K#L#k M#", +" N#O#k C@g.M.M.M.M.M.M.M.M.M.M.M.M.M.[.[.[.[.[.[.[.M.P#Q#1.-.A.A.A.A.A.A.A.A.c.c.c.c.;.c.;.;.;.;.;.;.-.R#s+S#T#T#U#U#U#V#V#V#V#V#V#W#W#W#W#W#W#W#W#W#X#T#Y#Z#`# ", +" /+ $.$R+M.g.M.N.N.h+M.g.g.g.g.g.S+g.g.,+g.M.g.,+g.y.,.+$K O J U K J J J J U J U O U U J U J O J U E.@$#$$$%$&$&$&$*$&$=$=$&$&$%$&$%$=$%$&$&$%$&$&$&$-$;$>$ ", +" ,$'$)$M.g.M.g.g.g.,+g.g.g.g.g.E+g.g.M.S+g.g.M.g.2+!$~$].K N K K N K K K K J K K K O K K K K K K A+{$]$^$%$%$%$%$*$%$=$=$&$%$%$%$%$=$%$%$&$%$&$&$%$/$($_$ ", +" :$<$k [$g.M.N.g.y.M.N.g.g.g.g.g.g.g.M.y.h+g.M.M.f.}$|$J L J K K J O O K U J U K U O K K O K T J t..$1$2$%$%$3$%$*$4$=$5$4$3$%$%$%$5$%$%$4$%$&$6$7$k 8$ ", +" ;@9$0$x.g.h+h+h+,+g.g.g.g.g.,+y.y.M.h+M.y.M.,+g.a$b$'.K N K M J N J J U J U M U K N M N K J K w c$d$%$4$4$&$4$*$4$=$5$4$&$%$4$%$5$%$4$4$%$%$e$f$g$ ", +" h$i$j$f.g.N.N.,+,+,+,+g.g.E+N.,+,+g.,+,+,+,+1+3#k$1.J K O K J O O K K J K M U O K M O K T ].l$m$n$%$%$%$*$%$o$4$o$%$5$*$%$%$5$%$5$%$&$%$X#p$q$r$ ", +" s$k g.M.g.y.M.,+E+E+g.g.E+y.S+M.S+M.S+M.E+g.A@t$u$J J J M J N J T T J T M O J M T N K M =+v$w$x$&$&$&$&$&$&$&$&$&$&$&$&$&$4$&$=$&$%$y$z$k A$ ", +" B$w#C$D$g.h+M.g.g.g.g.g.E+g.g.M.S+M.g.M.,+M.>+&#E$B.J K M J N J J J J J M U O N M N K K +.F$G$H$*$*$*$*$*$&$&$&$&$&$*$%$*$%$&$%$*$%$I$J$K$ ", +" L$M$N$A@g.N.g.g.g.g.g.E+g.g.M.y.h+g.h+N.,+O$P$Q$w K K K N N N N K J K K U K N K N K J d+R$S$T$%$%$%$*$%$o$3$o$%$%$*$%$%$%$%$%$%$U$V$W$ ", +" /+:.X$[.M.g.g.g.g.g.S+g.g.,+g.M.g.,+M.g.S+2#Y$t.K U K J J J J U J U O U U J U J O J Z$`$ %%$&$&$&$&$&$*$&$=$=$&$&$%$&$%$=$&$' .%+%@% ", +" #%$%k x.1+g.g.g.g.g.E+g.g.M.S+g.g.M.g.g.g.f.&.F.B.K K N K K K K J K K K O K K K K -.%%&%e$&$%$%$%$%$%$*$%$=$=$&$%$%$%$%$%$%$*%=%-% ", +" ! ;%>%f.M.g.g.g.g.g.g.g.M.y.h+g.M.g.g.y.x.%#,%c.K K J O O K U J U K U O K K O J q '%)%^$3$%$%$%$3$%$*$4$=$5$4$3$%$%$%$%$!%~%{% ", +" 7$]%P#M.M.g.g.g.,+y.y.M.h+M.y.M.,+y.M.^%/%(%y K M J N J J U J U M U K N M N K _%j 6$%$3$4$4$4$&$4$*$4$=$5$4$&$%$4$&$:%|#<%[% ", +" }%|%k 1%g.g.g.g.E+N.,+,+g.,+,+,+,+,+,+[.2%3%V K K J O O K K J K M U O K M O B.C+4%5%&$3$%$%$%$*$%$o$4$o$%$5$*$%$&$2$. k 6% ", +" 7%8%9%x.g.g.g.E+y.S+M.S+M.S+M.E+S+S+g.f.F+0%J M J N J T T J T M O J M T N ;.a%b%c%&$*$&$&$&$&$&$&$&$&$&$&$&$&$%$n$d%e% ", +" f%g%h%g+g.g.E+g.g.M.S+M.g.M.,+g.M.M.A@`@G+;.M J N J J J J J M U O N M N v i%j%k%*$*$*$*$*$*$*$&$&$&$&$&$*$%$l%m%n%o% ", +" p%k |+M.g.E+g.g.M.y.h+g.h+N.g.M.M.^%q%r%v K N N N N K J K K U K N K K _.#+3$&$*$3$%$%$%$*$%$o$3$o$%$%$%$s%t%k u% ", +" v%w%x%x.g.S+g.g.,+g.M.g.,+M.g.M.M.g+y%z%'.J J J J J U J U O U U J U B.A%B%C%%$&$*$&$&$&$&$&$*$&$=$=$&$&$D%E%F% ", +" G%H%I%f.g.g.g.M.S+g.g.M.g.g.E+E+M.f.J%V K N K K K K J K K K O K K y K%>@L%%$%$%$%$%$%$%$%$*$%$=$=$%$M%N%O% ", +" P%Q%R%[.M.g.M.y.h+g.M.g.g.y.y.g.A@S%T%-.J O O K U J U K U O K K q ]#U%l%%$3$3$%$%$%$3$%$*$4$=$&$^$|#V%r$ ", +" A$W%k 2+g.M.M.h+M.y.M.,+y.M.M.g.f.X%Y%r J N J J U J U M U K N K |@Z%`% &4$&$3$4$4$4$&$4$*$4$=$y$.&k +& ", +" W.@&#&2+g.,+g.,+,+,+,+,+,+,+,+g+..Q.+.J O O K K J K M U O K J $&%&&&%$%$*$3$%$%$%$*$%$o$&$*&=&-&;& ", +" >&,&'&M.M.S+M.S+M.E+S+S+S+,+M.)&!&q K N J T T J T M O J M I ~&{&C%&$4$&$*$&$&$&$&$&$&$%$M%]&^&/& ", +" (&k _&1+M.M.g.M.,+g.M.M.g.g.x.k :&N N J J J J J M U O N V <&[&k%%$*$*$*$*$*$*$*$*$&$6$}&F+|& ", +" B$1&2&h.g.h+g.h+N.g.M.M.g.g.f.3&4&w J N N K J K K U K K 5&6&7&:%%$%$*$3$%$%$%$*$&$S$*%8&9& ", +" D 0&h%a&g.g.,+M.g.M.M.g.g.[.b&c&_.T J J U J U O U U O d&e&n$5$%$&$&$*$&$&$&$&$&$U$f&g& ", +" h&k S+g.M.M.g.g.E+E+g.E+M.l@i&V ].K K K J K K K O c.j&k&l&%$%$%$%$%$%$%$%$%$m&n&o&p& ", +" q&r&s&A@M.M.g.g.y.y.N.g.M.>+@@J t&O K U J U K U J V )&u&V#3$%$%$3$3$%$%$&$%$. k v& ", +" w&x&y&^%g.,+y.M.M.g.g.,+A@z&A&u.J J U J U M U K I.B&C& &4$%$4$&$3$4$4$%$$$D&E& ", +" F&G&6#[.g.,+,+,+,+,+N.[.H&I&v J K K J K M U u.I h 4@&$3$%$%$*$3$%$%$J&K&L&r$ ", +" M&N&k 2+g.S+S+S+,+E+M.M.O&W@n@K T T J T M O P&Q&R&!%%$&$&$4$&$*$%$S&T&k U& ", +" < V&W&C@g.M.M.g.g.M.M.O.X&K Y&J J J J M J I Z&`&V#%$*$%$*$*$*$%$$$ *.* ", +" D +*@*O.M.M.g.g.h+g.>+9@#*t&N K J K K K I.$*%*&$%$3$%$%$&$%$&&&***=* ", +" t@k 1%1+g.g.g.N.g.g+-*;*5.K U J U O ].I >*,*&$%$&$%$&$&$'*)*!*~* ", +" e@{*0$A@g.g.E+M.g.1+T+]*I.T K J K K E.^*/*=&%$%$%$%$%$H$(*k _* ", +" :*0&<*[.M.g.h+N.g.h+i@!+K U J U K -.[*}*'*%$%$3$%$%$|*1*K& ", +" 2*k 3*g.g.h+g.g.2+4*F ].U J U J Y.5*6*6$3$%$4$&$7*8*9*u% ", +" 0*a*b*2+g.N.N.S+f.c*d*J K J K K V e*f**&%$o$%$%$g*k h* ", +" i*j*k*f.g.N.g.g.l*r+'.K J T ].m*n* %%$*$=$%$c%o*p* ", +" < q*_#[.g.g.1+3#,.2.J J J J r*s*C%&$*$%$t*u*v*w* ", +" x*k C@g.g.g.A@J%u$J J K '.y*z**&%$%$:%O#A*B* ", +" C*V&D*#@g.M.>+&#E*J J J 2.z&& H$&$&$(*k F* ", +" x+G*'&g+M.O$H*I*w J J J*K**%%$%$c%L*M* ", +" N*k f.y.E+D+Y$t.O B.+@O*$$&$k%8*P*x+ ", +" Q*R*S*D$g.O.S%:&J w T*U*k%V*W*k X* ", +" < Y**@[.x.Z*m#A.G@`* =2$=&.=+= ", +" @=k [$f.#=k.w $=%=~ U$&=*=== ", +" -=;=s&2+O&>=_.E$,=$$$+'=)= ", +" !=j*~=C@k {=]=^=I$k /= ", +" 3@q*S+Z@F (=S&_=:=<= ", +" [=}=|=1=2=3=4=5= ", +" 6=7=9 $#8=e&9= ", +" Z+0=k k a= ", +" t%k b=^+ ", +" c=d=d$ ", +" e= "}; diff --git a/share/pixmaps/check.ico b/share/pixmaps/check.ico new file mode 100644 index 0000000..0c4e6e8 Binary files /dev/null and b/share/pixmaps/check.ico differ diff --git a/share/pixmaps/favicon.ico b/share/pixmaps/favicon.ico new file mode 100644 index 0000000..b7a55e0 Binary files /dev/null and b/share/pixmaps/favicon.ico differ diff --git a/share/pixmaps/nsis-header.bmp b/share/pixmaps/nsis-header.bmp new file mode 100644 index 0000000..5eb10ae Binary files /dev/null and b/share/pixmaps/nsis-header.bmp differ diff --git a/share/pixmaps/nsis-wizard.bmp b/share/pixmaps/nsis-wizard.bmp new file mode 100644 index 0000000..330de6b Binary files /dev/null and b/share/pixmaps/nsis-wizard.bmp differ diff --git a/share/pixmaps/send16.bmp b/share/pixmaps/send16.bmp new file mode 100644 index 0000000..676b5c4 Binary files /dev/null and b/share/pixmaps/send16.bmp differ diff --git a/share/pixmaps/send16mask.bmp b/share/pixmaps/send16mask.bmp new file mode 100644 index 0000000..06c747f Binary files /dev/null and b/share/pixmaps/send16mask.bmp differ diff --git a/share/pixmaps/send16masknoshadow.bmp b/share/pixmaps/send16masknoshadow.bmp new file mode 100644 index 0000000..faf24e0 Binary files /dev/null and b/share/pixmaps/send16masknoshadow.bmp differ diff --git a/share/pixmaps/send20.bmp b/share/pixmaps/send20.bmp new file mode 100644 index 0000000..2b90422 Binary files /dev/null and b/share/pixmaps/send20.bmp differ diff --git a/share/pixmaps/send20mask.bmp b/share/pixmaps/send20mask.bmp new file mode 100644 index 0000000..f124d0d Binary files /dev/null and b/share/pixmaps/send20mask.bmp differ diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py new file mode 100644 index 0000000..771f28a --- /dev/null +++ b/share/qt/extract_strings_qt.py @@ -0,0 +1,70 @@ +#!/usr/bin/python +''' +Extract _("...") strings for translation and convert to Qt4 stringdefs so that +they can be picked up by Qt linguist. +''' +from subprocess import Popen, PIPE +import glob + +OUT_CPP="src/qt/bitcoinstrings.cpp" +EMPTY=['""'] + +def parse_po(text): + """ + Parse 'po' format produced by xgettext. + Return a list of (msgid,msgstr) tuples. + """ + messages = [] + msgid = [] + msgstr = [] + in_msgid = False + in_msgstr = False + + for line in text.split('\n'): + line = line.rstrip('\r') + if line.startswith('msgid '): + if in_msgstr: + messages.append((msgid, msgstr)) + in_msgstr = False + # message start + in_msgid = True + + msgid = [line[6:]] + elif line.startswith('msgstr '): + in_msgid = False + in_msgstr = True + msgstr = [line[7:]] + elif line.startswith('"'): + if in_msgid: + msgid.append(line) + if in_msgstr: + msgstr.append(line) + + if in_msgstr: + messages.append((msgid, msgstr)) + + return messages + +files = glob.glob('src/*.cpp') + glob.glob('src/*.h') + +# xgettext -n --keyword=_ $FILES +child = Popen(['xgettext','--output=-','-n','--keyword=_'] + files, stdout=PIPE) +(out, err) = child.communicate() + +messages = parse_po(out) + +f = open(OUT_CPP, 'w') +f.write("""#include +// Automatically generated by extract_strings.py +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif +""") +f.write('static const char UNUSED *bitcoin_strings[] = {') +for (msgid, msgstr) in messages: + if msgid != EMPTY: + f.write('QT_TRANSLATE_NOOP("bitcoin-core", %s),\n' % ('\n'.join(msgid))) +f.write('};') +f.close() diff --git a/share/qt/img/reload.xcf b/share/qt/img/reload.xcf new file mode 100644 index 0000000..dc8be62 Binary files /dev/null and b/share/qt/img/reload.xcf differ diff --git a/share/qt/make_spinner.py b/share/qt/make_spinner.py new file mode 100644 index 0000000..136aff3 --- /dev/null +++ b/share/qt/make_spinner.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# W.J. van der Laan, 2011 +# Make spinning .mng animation from a .png +# Requires imagemagick 6.7+ +from __future__ import division +from os import path +from PIL import Image +from subprocess import Popen + +SRC='img/reload_scaled.png' +DST='../../src/qt/res/movies/update_spinner.mng' +TMPDIR='/tmp' +TMPNAME='tmp-%03i.png' +NUMFRAMES=35 +FRAMERATE=10.0 +CONVERT='convert' +CLOCKWISE=True +DSIZE=(16,16) + +im_src = Image.open(SRC) + +if CLOCKWISE: + im_src = im_src.transpose(Image.FLIP_LEFT_RIGHT) + +def frame_to_filename(frame): + return path.join(TMPDIR, TMPNAME % frame) + +frame_files = [] +for frame in xrange(NUMFRAMES): + rotation = (frame + 0.5) / NUMFRAMES * 360.0 + if CLOCKWISE: + rotation = -rotation + im_new = im_src.rotate(rotation, Image.BICUBIC) + im_new.thumbnail(DSIZE, Image.ANTIALIAS) + outfile = frame_to_filename(frame) + im_new.save(outfile, 'png') + frame_files.append(outfile) + +p = Popen([CONVERT, "-delay", str(FRAMERATE), "-dispose", "2"] + frame_files + [DST]) +p.communicate() + + + diff --git a/share/qt/make_windows_icon.sh b/share/qt/make_windows_icon.sh new file mode 100644 index 0000000..fde9829 --- /dev/null +++ b/share/qt/make_windows_icon.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# create multiresolution windows icon +ICON_DST=../../src/qt/res/icons/SoleCoin.ico + +convert ../../src/qt/res/icons/SoleCoin-16.png ../../src/qt/res/icons/SoleCoin-32.png ../../src/qt/res/icons/SoleCoin-48.png ${ICON_DST} diff --git a/share/setup.nsi b/share/setup.nsi new file mode 100644 index 0000000..2cc647f --- /dev/null +++ b/share/setup.nsi @@ -0,0 +1,164 @@ +Name BottleCaps + +RequestExecutionLevel highest +SetCompressor /SOLID lzma + +# General Symbol Definitions +!define REGKEY "SOFTWARE\$(^Name)" +!define VERSION 0.3.0 +!define COMPANY "BottleCaps project" +!define URL http:// + +# MUI Symbol Definitions +!define MUI_ICON "../share/pixmaps/BottleCaps.ico" +!define MUI_WELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp" +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_RIGHT +!define MUI_HEADERIMAGE_BITMAP "../share/pixmaps/nsis-header.bmp" +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM +!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup +!define MUI_STARTMENUPAGE_DEFAULTFOLDER BottleCaps +!define MUI_FINISHPAGE_RUN $INSTDIR\BottleCaps-qt.exe +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp" +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +# Included files +!include Sections.nsh +!include MUI2.nsh + +# Variables +Var StartMenuGroup + +# Installer pages +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +# Installer languages +!insertmacro MUI_LANGUAGE English + +# Installer attributes +OutFile BottleCaps-0.3.0-win32-setup.exe +InstallDir $PROGRAMFILES\BottleCaps +CRCCheck on +XPStyle on +BrandingText " " +ShowInstDetails show +VIProductVersion 0.3.0.0 +VIAddVersionKey ProductName BottleCaps +VIAddVersionKey ProductVersion "${VERSION}" +VIAddVersionKey CompanyName "${COMPANY}" +VIAddVersionKey CompanyWebsite "${URL}" +VIAddVersionKey FileVersion "${VERSION}" +VIAddVersionKey FileDescription "" +VIAddVersionKey LegalCopyright "" +InstallDirRegKey HKCU "${REGKEY}" Path +ShowUninstDetails show + +# Installer sections +Section -Main SEC0000 + SetOutPath $INSTDIR + SetOverwrite on + File ../release/BottleCaps-qt.exe + File /oname=license.txt ../COPYING + File /oname=readme.txt ../doc/README_windows.txt + SetOutPath $INSTDIR\daemon + File ../src/BottleCapsd.exe + SetOutPath $INSTDIR\src + File /r /x *.exe /x *.o ../src\*.* + SetOutPath $INSTDIR + WriteRegStr HKCU "${REGKEY}\Components" Main 1 + + # Remove old wxwidgets-based-BottleCaps executable and locales: + Delete /REBOOTOK $INSTDIR\BottleCaps.exe + RMDir /r /REBOOTOK $INSTDIR\locale +SectionEnd + +Section -post SEC0001 + WriteRegStr HKCU "${REGKEY}" Path $INSTDIR + SetOutPath $INSTDIR + WriteUninstaller $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + CreateDirectory $SMPROGRAMS\$StartMenuGroup + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\BottleCaps.lnk" $INSTDIR\BottleCaps-qt.exe + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall BottleCaps.lnk" $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_END + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 + + # BottleCaps: URI handling disabled for 0.6.0 + WriteRegStr HKCR "BottleCaps" "URL Protocol" "" + WriteRegStr HKCR "BottleCaps" "" "URL:BottleCaps" + WriteRegStr HKCR "BottleCaps\DefaultIcon" "" $INSTDIR\BottleCaps-qt.exe + WriteRegStr HKCR "BottleCaps\shell\open\command" "" '"$INSTDIR\BottleCaps-qt.exe" "$$1"' +SectionEnd + +# Macro for selecting uninstaller sections +!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID + Push $R0 + ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}" + StrCmp $R0 1 0 next${UNSECTION_ID} + !insertmacro SelectSection "${UNSECTION_ID}" + GoTo done${UNSECTION_ID} +next${UNSECTION_ID}: + !insertmacro UnselectSection "${UNSECTION_ID}" +done${UNSECTION_ID}: + Pop $R0 +!macroend + +# Uninstaller sections +Section /o -un.Main UNSEC0000 + Delete /REBOOTOK $INSTDIR\BottleCaps-qt.exe + Delete /REBOOTOK $INSTDIR\license.txt + Delete /REBOOTOK $INSTDIR\readme.txt + RMDir /r /REBOOTOK $INSTDIR\daemon + RMDir /r /REBOOTOK $INSTDIR\src + DeleteRegValue HKCU "${REGKEY}\Components" Main +SectionEnd + +Section -un.post UNSEC0001 + DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall BottleCaps.lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\BottleCaps.lnk" + Delete /REBOOTOK "$SMSTARTUP\BottleCaps.lnk" + Delete /REBOOTOK $INSTDIR\uninstall.exe + Delete /REBOOTOK $INSTDIR\debug.log + Delete /REBOOTOK $INSTDIR\db.log + DeleteRegValue HKCU "${REGKEY}" StartMenuGroup + DeleteRegValue HKCU "${REGKEY}" Path + DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components" + DeleteRegKey /IfEmpty HKCU "${REGKEY}" + DeleteRegKey HKCR "BottleCaps" + RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup + RmDir /REBOOTOK $INSTDIR + Push $R0 + StrCpy $R0 $StartMenuGroup 1 + StrCmp $R0 ">" no_smgroup +no_smgroup: + Pop $R0 +SectionEnd + +# Installer functions +Function .onInit + InitPluginsDir +FunctionEnd + +# Uninstaller functions +Function un.onInit + ReadRegStr $INSTDIR HKCU "${REGKEY}" Path + !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup + !insertmacro SELECT_UNSECTION Main ${UNSEC0000} +FunctionEnd diff --git a/share/ui.rc b/share/ui.rc new file mode 100644 index 0000000..431d8fd --- /dev/null +++ b/share/ui.rc @@ -0,0 +1,15 @@ +BottleCaps ICON "pixmaps/BottleCaps.ico" + +#include "wx/msw/wx.rc" + +check ICON "pixmaps/check.ico" +send16 BITMAP "pixmaps/send16.bmp" +send16mask BITMAP "pixmaps/send16mask.bmp" +send16masknoshadow BITMAP "pixmaps/send16masknoshadow.bmp" +send20 BITMAP "pixmaps/send20.bmp" +send20mask BITMAP "pixmaps/send20mask.bmp" +addressbook16 BITMAP "pixmaps/addressbook16.bmp" +addressbook16mask BITMAP "pixmaps/addressbook16mask.bmp" +addressbook20 BITMAP "pixmaps/addressbook20.bmp" +addressbook20mask BITMAP "pixmaps/addressbook20mask.bmp" +favicon ICON "pixmaps/favicon.ico" diff --git a/src/addrman.cpp b/src/addrman.cpp new file mode 100644 index 0000000..4428cd1 --- /dev/null +++ b/src/addrman.cpp @@ -0,0 +1,527 @@ +// Copyright (c) 2012 Pieter Wuille +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "addrman.h" + +using namespace std; + +int CAddrInfo::GetTriedBucket(const std::vector &nKey) const +{ + CDataStream ss1(SER_GETHASH, 0); + std::vector vchKey = GetKey(); + ss1 << nKey << vchKey; + uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64(); + + CDataStream ss2(SER_GETHASH, 0); + std::vector vchGroupKey = GetGroup(); + ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); + uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64(); + return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; +} + +int CAddrInfo::GetNewBucket(const std::vector &nKey, const CNetAddr& src) const +{ + CDataStream ss1(SER_GETHASH, 0); + std::vector vchGroupKey = GetGroup(); + std::vector vchSourceGroupKey = src.GetGroup(); + ss1 << nKey << vchGroupKey << vchSourceGroupKey; + uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64(); + + CDataStream ss2(SER_GETHASH, 0); + ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); + uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64(); + return hash2 % ADDRMAN_NEW_BUCKET_COUNT; +} + +bool CAddrInfo::IsTerrible(int64 nNow) const +{ + if (nLastTry && nLastTry >= nNow-60) // never remove things tried 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*86400) // not seen in over a month + return true; + + if (nLastSuccess==0 && nAttempts>=ADDRMAN_RETRIES) // tried three times and never a success + return true; + + if (nNow-nLastSuccess > ADDRMAN_MIN_FAIL_DAYS*86400 && nAttempts>=ADDRMAN_MAX_FAILURES) // 10 successive failures in the last week + return true; + + return false; +} + +double CAddrInfo::GetChance(int64 nNow) const +{ + double fChance = 1.0; + + int64 nSinceLastSeen = nNow - nTime; + int64 nSinceLastTry = nNow - nLastTry; + + if (nSinceLastSeen < 0) nSinceLastSeen = 0; + if (nSinceLastTry < 0) nSinceLastTry = 0; + + fChance *= 600.0 / (600.0 + nSinceLastSeen); + + // deprioritize very recent attempts away + if (nSinceLastTry < 60*10) + fChance *= 0.01; + + // deprioritize 50% after each failed attempt + for (int n=0; n::iterator it = mapAddr.find(addr); + if (it == mapAddr.end()) + return NULL; + if (pnId) + *pnId = (*it).second; + std::map::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; +} + +int CAddrMan::SelectTried(int nKBucket) +{ + std::vector &vTried = vvTried[nKBucket]; + + // random shuffle the first few elements (using the entire list) + // find the least recently tried among them + int64 nOldest = -1; + int nOldestPos = -1; + for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++) + { + int nPos = GetRandInt(vTried.size() - i) + i; + int nTemp = vTried[nPos]; + vTried[nPos] = vTried[i]; + vTried[i] = nTemp; + assert(nOldest == -1 || mapInfo.count(nTemp) == 1); + if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) { + nOldest = nTemp; + nOldestPos = nPos; + } + } + + return nOldestPos; +} + +int CAddrMan::ShrinkNew(int nUBucket) +{ + assert(nUBucket >= 0 && (unsigned int)nUBucket < vvNew.size()); + std::set &vNew = vvNew[nUBucket]; + + // first look for deletable items + for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) + { + assert(mapInfo.count(*it)); + CAddrInfo &info = mapInfo[*it]; + if (info.IsTerrible()) + { + if (--info.nRefCount == 0) + { + SwapRandom(info.nRandomPos, vRandom.size()-1); + vRandom.pop_back(); + mapAddr.erase(info); + mapInfo.erase(*it); + nNew--; + } + vNew.erase(it); + return 0; + } + } + + // otherwise, select four randomly, and pick the oldest of those to replace + int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())}; + int nI = 0; + int nOldest = -1; + for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) + { + if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3]) + { + assert(nOldest == -1 || mapInfo.count(*it) == 1); + if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime) + nOldest = *it; + } + nI++; + } + assert(mapInfo.count(nOldest) == 1); + CAddrInfo &info = mapInfo[nOldest]; + if (--info.nRefCount == 0) + { + SwapRandom(info.nRandomPos, vRandom.size()-1); + vRandom.pop_back(); + mapAddr.erase(info); + mapInfo.erase(nOldest); + nNew--; + } + vNew.erase(nOldest); + + return 1; +} + +void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) +{ + assert(vvNew[nOrigin].count(nId) == 1); + + // remove the entry from all new buckets + for (std::vector >::iterator it = vvNew.begin(); it != vvNew.end(); it++) + { + if ((*it).erase(nId)) + info.nRefCount--; + } + nNew--; + + assert(info.nRefCount == 0); + + // what tried bucket to move the entry to + int nKBucket = info.GetTriedBucket(nKey); + std::vector &vTried = vvTried[nKBucket]; + + // first check whether there is place to just add it + if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) + { + vTried.push_back(nId); + nTried++; + info.fInTried = true; + return; + } + + // otherwise, find an item to evict + int nPos = SelectTried(nKBucket); + + // find which new bucket it belongs to + assert(mapInfo.count(vTried[nPos]) == 1); + int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey); + std::set &vNew = vvNew[nUBucket]; + + // remove the to-be-replaced tried entry from the tried set + CAddrInfo& infoOld = mapInfo[vTried[nPos]]; + infoOld.fInTried = false; + infoOld.nRefCount = 1; + // do not update nTried, as we are going to move something else there immediately + + // check whether there is place in that one, + if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) + { + // if so, move it back there + vNew.insert(vTried[nPos]); + } else { + // otherwise, move it to the new bucket nId came from (there is certainly place there) + vvNew[nOrigin].insert(vTried[nPos]); + } + nNew++; + + vTried[nPos] = nId; + // we just overwrote an entry in vTried; no need to update nTried + info.fInTried = true; + return; +} + +void CAddrMan::Good_(const CService &addr, int64 nTime) +{ +// printf("Good: addr=%s\n", addr.ToString().c_str()); + + 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.nTime = nTime; + info.nAttempts = 0; + + // 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 = GetRandInt(vvNew.size()); + int nUBucket = -1; + for (unsigned int n = 0; n < vvNew.size(); n++) + { + int nB = (n+nRnd) % vvNew.size(); + std::set &vNew = vvNew[nB]; + if (vNew.count(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; + + printf("Moving %s to tried\n", addr.ToString().c_str()); + + // move nId to the tried tables + MakeTried(info, nId, nUBucket); +} + +bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64 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 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); + if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty)) + pinfo->nTime = max((int64)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; nnRefCount; n++) + nFactor *= 2; + if (nFactor > 1 && (GetRandInt(nFactor) != 0)) + return false; + } else { + pinfo = Create(addr, source, &nId); + pinfo->nTime = max((int64)0, (int64)pinfo->nTime - nTimePenalty); +// printf("Added %s [nTime=%fhr]\n", pinfo->ToString().c_str(), (GetAdjustedTime() - pinfo->nTime) / 3600.0); + nNew++; + fNew = true; + } + + int nUBucket = pinfo->GetNewBucket(nKey, source); + std::set &vNew = vvNew[nUBucket]; + if (!vNew.count(nId)) + { + pinfo->nRefCount++; + if (vNew.size() == ADDRMAN_NEW_BUCKET_SIZE) + ShrinkNew(nUBucket); + vvNew[nUBucket].insert(nId); + } + return fNew; +} + +void CAddrMan::Attempt_(const CService &addr, int64 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++; +} + +CAddress CAddrMan::Select_(int nUnkBias) +{ + if (size() == 0) + return CAddress(); + + double nCorTried = sqrt(nTried) * (100.0 - nUnkBias); + double nCorNew = sqrt(nNew) * nUnkBias; + if ((nCorTried + nCorNew)*GetRandInt(1<<30)/(1<<30) < nCorTried) + { + // use a tried node + double fChanceFactor = 1.0; + while(1) + { + int nKBucket = GetRandInt(vvTried.size()); + std::vector &vTried = vvTried[nKBucket]; + if (vTried.size() == 0) continue; + int nPos = GetRandInt(vTried.size()); + assert(mapInfo.count(vTried[nPos]) == 1); + CAddrInfo &info = mapInfo[vTried[nPos]]; + if (GetRandInt(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 = GetRandInt(vvNew.size()); + std::set &vNew = vvNew[nUBucket]; + if (vNew.size() == 0) continue; + int nPos = GetRandInt(vNew.size()); + std::set::iterator it = vNew.begin(); + while (nPos--) + it++; + assert(mapInfo.count(*it) == 1); + CAddrInfo &info = mapInfo[*it]; + if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30)) + return info; + fChanceFactor *= 1.2; + } + } +} + +#ifdef DEBUG_ADDRMAN +int CAddrMan::Check_() +{ + std::set setTried; + std::map mapNew; + + if (vRandom.size() != nTried + nNew) return -7; + + for (std::map::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 &vTried = vvTried[n]; + for (std::vector::iterator it = vTried.begin(); it != vTried.end(); it++) + { + if (!setTried.count(*it)) return -11; + setTried.erase(*it); + } + } + + for (int n=0; n &vNew = vvNew[n]; + for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) + { + if (!mapNew.count(*it)) return -12; + if (--mapNew[*it] == 0) + mapNew.erase(*it); + } + } + + if (setTried.size()) return -13; + if (mapNew.size()) return -15; + + return 0; +} +#endif + +void CAddrMan::GetAddr_(std::vector &vAddr) +{ + int nNodes = ADDRMAN_GETADDR_MAX_PCT*vRandom.size()/100; + if (nNodes > ADDRMAN_GETADDR_MAX) + nNodes = ADDRMAN_GETADDR_MAX; + + // perform a random shuffle over the first nNodes elements of vRandom (selecting from all) + for (int n = 0; n nUpdateInterval) + info.nTime = nTime; +} diff --git a/src/addrman.h b/src/addrman.h new file mode 100644 index 0000000..7af6afd --- /dev/null +++ b/src/addrman.h @@ -0,0 +1,503 @@ +// Copyright (c) 2012 Pieter Wuille +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef _BITCOIN_ADDRMAN +#define _BITCOIN_ADDRMAN 1 + +#include "netbase.h" +#include "protocol.h" +#include "util.h" +#include "sync.h" + + +#include +#include + +#include + + +/** Extended statistics about a CAddress */ +class CAddrInfo : public CAddress +{ +private: + // where knowledge about this address first came from + CNetAddr source; + + // last successful connection by us + int64 nLastSuccess; + + // last try whatsoever by us: + // int64 CAddress::nLastTry + + // 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: + + IMPLEMENT_SERIALIZE( + CAddress* pthis = (CAddress*)(this); + READWRITE(*pthis); + 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 std::vector &nKey) const; + + // Calculate in which "new" bucket this entry belongs, given a certain source + int GetNewBucket(const std::vector &nKey, const CNetAddr& src) const; + + // Calculate in which "new" bucket this entry belongs, using its default source + int GetNewBucket(const std::vector &nKey) const + { + return GetNewBucket(nKey, source); + } + + // Determine whether the statistics about this entry are bad enough so that it can just be deleted + bool IsTerrible(int64 nNow = GetAdjustedTime()) const; + + // Calculate the relative chance this entry should be given when selecting nodes to connect to + double GetChance(int64 nNow = GetAdjustedTime()) const; + +}; + +// Stochastic address manager +// +// Design goals: +// * Only keep a limited number of addresses around, so that addr.dat and memory requirements do not grow without bound. +// * Keep the address tables in-memory, and asynchronously dump the entire to able in addr.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 256 "new" buckets. +// * Based on the address range (/16 for IPv4) of source of the information, 32 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 4 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 64 "tried" buckets. +// * Each address range selects at random 4 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 64 + +// maximum allowed number of entries in buckets for tried addresses +#define ADDRMAN_TRIED_BUCKET_SIZE 64 + +// total number of buckets for new addresses +#define ADDRMAN_NEW_BUCKET_COUNT 256 + +// maximum allowed number of entries in buckets for new addresses +#define ADDRMAN_NEW_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 4 + +// over how many buckets entries with new addresses originating from a single group are spread +#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 32 + +// in how many buckets for entries with new addresses a single address may occur +#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4 + +// how many entries in a bucket with tried addresses are inspected, when selecting one to replace +#define ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT 4 + +// 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; + + // secret key to randomize bucket select with + std::vector nKey; + + // last used nId + int nIdCount; + + // table with information about all nIds + std::map mapInfo; + + // find an nId based on its network address + std::map mapAddr; + + // randomly-ordered vector of all nIds + std::vector vRandom; + + // number of "tried" entries + int nTried; + + // list of "tried" buckets + std::vector > vvTried; + + // number of (unique) "new" entries + int nNew; + + // list of "new" buckets + std::vector > vvNew; + +protected: + + // Find an entry. + CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL); + + // find an entry, creating it if necessary. + // nTime and nServices of found node is 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); + + // Return position in given bucket to replace. + int SelectTried(int nKBucket); + + // Remove an element from a "new" bucket. + // This is the only place where actual deletes occur. + // They are never deleted while in the "tried" table, only possibly evicted back to the "new" table. + int ShrinkNew(int nUBucket); + + // Move an entry from the "new" table(s) to the "tried" table + // @pre vvUnkown[nOrigin].count(nId) != 0 + void MakeTried(CAddrInfo& info, int nId, int nOrigin); + + // Mark an entry "good", possibly moving it from "new" to "tried". + void Good_(const CService &addr, int64 nTime); + + // Add an entry to the "new" table. + bool Add_(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty); + + // Mark an entry as attempted to connect. + void Attempt_(const CService &addr, int64 nTime); + + // Select an address to connect to. + // nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100) + CAddress Select_(int nUnkBias); + +#ifdef DEBUG_ADDRMAN + // Perform consistency check. Returns an error code or zero. + int Check_(); +#endif + + // Select several addresses at once. + void GetAddr_(std::vector &vAddr); + + // Mark an entry as currently-connected-to. + void Connected_(const CService &addr, int64 nTime); + +public: + + IMPLEMENT_SERIALIZE + (({ + // serialized format: + // * version byte (currently 0) + // * nKey + // * nNew + // * nTried + // * number of "new" buckets + // * all nNew addrinfos in vvNew + // * all nTried addrinfos in vvTried + // * for each bucket: + // * number of elements + // * for each element: index + // + // 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. + { + LOCK(cs); + unsigned char nVersion = 0; + READWRITE(nVersion); + READWRITE(nKey); + READWRITE(nNew); + READWRITE(nTried); + + CAddrMan *am = const_cast(this); + if (fWrite) + { + int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT; + READWRITE(nUBuckets); + std::map mapUnkIds; + int nIds = 0; + for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) + { + if (nIds == nNew) break; // this means nNew was wrong, oh ow + mapUnkIds[(*it).first] = nIds; + CAddrInfo &info = (*it).second; + if (info.nRefCount) + { + READWRITE(info); + nIds++; + } + } + nIds = 0; + for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) + { + if (nIds == nTried) break; // this means nTried was wrong, oh ow + CAddrInfo &info = (*it).second; + if (info.fInTried) + { + READWRITE(info); + nIds++; + } + } + for (std::vector >::iterator it = am->vvNew.begin(); it != am->vvNew.end(); it++) + { + const std::set &vNew = (*it); + int nSize = vNew.size(); + READWRITE(nSize); + for (std::set::iterator it2 = vNew.begin(); it2 != vNew.end(); it2++) + { + int nIndex = mapUnkIds[*it2]; + READWRITE(nIndex); + } + } + } else { + int nUBuckets = 0; + READWRITE(nUBuckets); + am->nIdCount = 0; + am->mapInfo.clear(); + am->mapAddr.clear(); + am->vRandom.clear(); + am->vvTried = std::vector >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)); + am->vvNew = std::vector >(ADDRMAN_NEW_BUCKET_COUNT, std::set()); + for (int n = 0; n < am->nNew; n++) + { + CAddrInfo &info = am->mapInfo[n]; + READWRITE(info); + am->mapAddr[info] = n; + info.nRandomPos = vRandom.size(); + am->vRandom.push_back(n); + if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) + { + am->vvNew[info.GetNewBucket(am->nKey)].insert(n); + info.nRefCount++; + } + } + am->nIdCount = am->nNew; + int nLost = 0; + for (int n = 0; n < am->nTried; n++) + { + CAddrInfo info; + READWRITE(info); + std::vector &vTried = am->vvTried[info.GetTriedBucket(am->nKey)]; + if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) + { + info.nRandomPos = vRandom.size(); + info.fInTried = true; + am->vRandom.push_back(am->nIdCount); + am->mapInfo[am->nIdCount] = info; + am->mapAddr[info] = am->nIdCount; + vTried.push_back(am->nIdCount); + am->nIdCount++; + } else { + nLost++; + } + } + am->nTried -= nLost; + for (int b = 0; b < nUBuckets; b++) + { + std::set &vNew = am->vvNew[b]; + int nSize = 0; + READWRITE(nSize); + for (int n = 0; n < nSize; n++) + { + int nIndex = 0; + READWRITE(nIndex); + CAddrInfo &info = am->mapInfo[nIndex]; + if (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + { + info.nRefCount++; + vNew.insert(nIndex); + } + } + } + } + } + });) + + CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set()) + { + nKey.resize(32); + RAND_bytes(&nKey[0], 32); + + nIdCount = 0; + nTried = 0; + nNew = 0; + } + + // 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_())) + printf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err); + } +#endif + } + + // Add a single address. + bool Add(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty = 0) + { + bool fRet = false; + { + LOCK(cs); + Check(); + fRet |= Add_(addr, source, nTimePenalty); + Check(); + } + if (fRet) + printf("Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort().c_str(), source.ToString().c_str(), nTried, nNew); + return fRet; + } + + // Add multiple addresses. + bool Add(const std::vector &vAddr, const CNetAddr& source, int64 nTimePenalty = 0) + { + int nAdd = 0; + { + LOCK(cs); + Check(); + for (std::vector::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) + nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0; + Check(); + } + if (nAdd) + printf("Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString().c_str(), nTried, nNew); + return nAdd > 0; + } + + // Mark an entry as accessible. + void Good(const CService &addr, int64 nTime = GetAdjustedTime()) + { + { + LOCK(cs); + Check(); + Good_(addr, nTime); + Check(); + } + } + + // Mark an entry as connection attempted to. + void Attempt(const CService &addr, int64 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). + CAddress Select(int nUnkBias = 50) + { + CAddress addrRet; + { + LOCK(cs); + Check(); + addrRet = Select_(nUnkBias); + Check(); + } + return addrRet; + } + + // Return a bunch of addresses, selected at random. + std::vector GetAddr() + { + Check(); + std::vector vAddr; + { + LOCK(cs); + GetAddr_(vAddr); + } + Check(); + return vAddr; + } + + // Mark an entry as currently-connected-to. + void Connected(const CService &addr, int64 nTime = GetAdjustedTime()) + { + { + LOCK(cs); + Check(); + Connected_(addr, nTime); + Check(); + } + } +}; + +#endif diff --git a/src/aes_helper.c b/src/aes_helper.c new file mode 100644 index 0000000..75b7cc6 --- /dev/null +++ b/src/aes_helper.c @@ -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 + */ + +#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 diff --git a/src/alert.cpp b/src/alert.cpp new file mode 100644 index 0000000..5c99cfc --- /dev/null +++ b/src/alert.cpp @@ -0,0 +1,244 @@ +// +// Alert system +// + +#include +#include + +#include "alert.h" +#include "key.h" +#include "net.h" +#include "sync.h" +#include "ui_interface.h" + +using namespace std; + +map mapAlerts; +CCriticalSection cs_mapAlerts; + +static const char* pszMainKey = ""; + +// TestNet alerts pubKey +static const char* pszTestKey = ""; + +// TestNet alerts private key +// "" + +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; + BOOST_FOREACH(int n, setCancel) + strSetCancel += strprintf("%d ", n); + std::string strSetSubVer; + BOOST_FOREACH(std::string str, setSubVer) + strSetSubVer += "\"" + str + "\" "; + return strprintf( + "CAlert(\n" + " nVersion = %d\n" + " nRelayUntil = %"PRI64d"\n" + " nExpiration = %"PRI64d"\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.c_str(), + nMinVer, + nMaxVer, + strSetSubVer.c_str(), + nPriority, + strComment.c_str(), + strStatusBar.c_str()); +} + +void CUnsignedAlert::print() const +{ + printf("%s", ToString().c_str()); +} + +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())); +} + +bool CAlert::RelayTo(CNode* pnode) const +{ + if (!IsInEffect()) + 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 +{ + CKey key; + if (!key.SetPubKey(ParseHex(fTestNet ? pszTestKey : pszMainKey))) + return error("CAlert::CheckSignature() : SetPubKey failed"); + 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::iterator mi = mapAlerts.find(hash); + if(mi != mapAlerts.end()) + retval = mi->second; + } + return retval; +} + +bool CAlert::ProcessAlert() +{ + 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::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::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();) + { + const CAlert& alert = (*mi).second; + if (Cancels(alert)) + { + printf("cancelling alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mapAlerts.erase(mi++); + } + else if (!alert.IsInEffect()) + { + printf("expiring alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mapAlerts.erase(mi++); + } + else + mi++; + } + + // Check if this alert has been cancelled + BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + { + const CAlert& alert = item.second; + if (alert.Cancels(*this)) + { + printf("alert already cancelled by %d\n", alert.nID); + return false; + } + } + + // Add to mapAlerts + mapAlerts.insert(make_pair(GetHash(), *this)); + // Notify UI if it applies to me + if(AppliesToMe()) + uiInterface.NotifyAlertChanged(GetHash(), CT_NEW); + } + + printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe()); + return true; +} diff --git a/src/alert.h b/src/alert.h new file mode 100644 index 0000000..7949c76 --- /dev/null +++ b/src/alert.h @@ -0,0 +1,102 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 _BITCOINALERT_H_ +#define _BITCOINALERT_H_ 1 + +#include +#include + +#include "uint256.h" +#include "util.h" + +class CNode; + +/** 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 nRelayUntil; // when newer nodes stop relaying to newer nodes + int64 nExpiration; + int nID; + int nCancel; + std::set setCancel; + int nMinVer; // lowest version inclusive + int nMaxVer; // highest version inclusive + std::set setSubVer; // empty matches all + int nPriority; + + // Actions + std::string strComment; + std::string strStatusBar; + std::string strReserved; + + IMPLEMENT_SERIALIZE + ( + 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(strComment); + READWRITE(strStatusBar); + READWRITE(strReserved); + ) + + void SetNull(); + + std::string ToString() const; + void print() const; +}; + +/** An alert is a combination of a serialized CUnsignedAlert and a signature. */ +class CAlert : public CUnsignedAlert +{ +public: + std::vector vchMsg; + std::vector vchSig; + + CAlert() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + 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(); + + /* + * Get copy of (active) alert object by hash. Returns a null alert if it is not found. + */ + static CAlert getAlertByHash(const uint256 &hash); +}; + +#endif diff --git a/src/allocators.h b/src/allocators.h new file mode 100644 index 0000000..99afa10 --- /dev/null +++ b/src/allocators.h @@ -0,0 +1,257 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 +#include +#include +#include + +#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 +// 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 +#include // for PAGESIZE +#include // for sysconf +#endif + +/** + * 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 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); + } + + // 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(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(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(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(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 Histogram; + Histogram histogram; +}; + +/** 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; +} + +/** + * 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) + { +#ifdef WIN32 + return VirtualLock(const_cast(addr), len); +#else + return mlock(addr, len) == 0; +#endif + } + /** Unlock memory pages. + * addr and len must be a multiple of the system page size + */ + bool Unlock(const void *addr, size_t len) + { +#ifdef WIN32 + return VirtualUnlock(const_cast(addr), len); +#else + return munlock(addr, len) == 0; +#endif + } +}; + +/** + * Singleton class to keep track of locked (ie, non-swappable) memory pages, for use in + * std::allocator templates. + */ +class LockedPageManager: public LockedPageManagerBase +{ +public: + static LockedPageManager instance; // instantiated in util.cpp +private: + LockedPageManager(): + LockedPageManagerBase(GetSystemPageSize()) + {} +}; + +// +// Allocator that locks its contents from being paged +// out of memory and clears its contents before deletion. +// +template +struct secure_allocator : public std::allocator +{ + // MSVC8 default copy constructor is broken + typedef std::allocator 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 + secure_allocator(const secure_allocator& a) throw() : base(a) {} + ~secure_allocator() throw() {} + template struct rebind + { typedef secure_allocator<_Other> other; }; + + T* allocate(std::size_t n, const void *hint = 0) + { + T *p; + p = std::allocator::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) + { + memset(p, 0, sizeof(T) * n); + LockedPageManager::instance.UnlockRange(p, sizeof(T) * n); + } + std::allocator::deallocate(p, n); + } +}; + + +// +// Allocator that clears its contents before deletion. +// +template +struct zero_after_free_allocator : public std::allocator +{ + // MSVC8 default copy constructor is broken + typedef std::allocator 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 + zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} + ~zero_after_free_allocator() throw() {} + template struct rebind + { typedef zero_after_free_allocator<_Other> other; }; + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) + memset(p, 0, sizeof(T) * n); + std::allocator::deallocate(p, n); + } +}; + +// This is exactly like std::string, but with a custom allocator. +typedef std::basic_string, secure_allocator > SecureString; + +#endif diff --git a/src/base58.h b/src/base58.h new file mode 100644 index 0000000..0319110 --- /dev/null +++ b/src/base58.h @@ -0,0 +1,460 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin Developers +// Distributed under the MIT/X11 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 +#include +#include "bignum.h" +#include "key.h" +#include "script.h" + +static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +// Encode a byte sequence as a base58-encoded string +inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) +{ + CAutoBN_CTX pctx; + CBigNum bn58 = 58; + CBigNum bn0 = 0; + + // Convert big endian data to little endian + // Extra zero at the end make sure bignum will interpret as a positive number + std::vector vchTmp(pend-pbegin+1, 0); + reverse_copy(pbegin, pend, vchTmp.begin()); + + // Convert little endian data to bignum + CBigNum bn; + bn.setvch(vchTmp); + + // Convert bignum to std::string + std::string str; + // Expected size increase from base58 conversion is approximately 137% + // use 138% to be safe + str.reserve((pend - pbegin) * 138 / 100 + 1); + CBigNum dv; + CBigNum rem; + while (bn > bn0) + { + if (!BN_div(&dv, &rem, &bn, &bn58, pctx)) + throw bignum_error("EncodeBase58 : BN_div failed"); + bn = dv; + unsigned int c = rem.getulong(); + str += pszBase58[c]; + } + + // Leading zeroes encoded as base58 zeros + for (const unsigned char* p = pbegin; p < pend && *p == 0; p++) + str += pszBase58[0]; + + // Convert little endian std::string to big endian + reverse(str.begin(), str.end()); + return str; +} + +// Encode a byte vector as a base58-encoded string +inline std::string EncodeBase58(const std::vector& vch) +{ + return EncodeBase58(&vch[0], &vch[0] + vch.size()); +} + +// Decode a base58-encoded string psz into byte vector vchRet +// returns true if decoding is successful +inline bool DecodeBase58(const char* psz, std::vector& vchRet) +{ + CAutoBN_CTX pctx; + vchRet.clear(); + CBigNum bn58 = 58; + CBigNum bn = 0; + CBigNum bnChar; + while (isspace(*psz)) + psz++; + + // Convert big endian string to bignum + for (const char* p = psz; *p; p++) + { + const char* p1 = strchr(pszBase58, *p); + if (p1 == NULL) + { + while (isspace(*p)) + p++; + if (*p != '\0') + return false; + break; + } + bnChar.setulong(p1 - pszBase58); + if (!BN_mul(&bn, &bn, &bn58, pctx)) + throw bignum_error("DecodeBase58 : BN_mul failed"); + bn += bnChar; + } + + // Get bignum as little endian data + std::vector vchTmp = bn.getvch(); + + // Trim off sign byte if present + if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) + vchTmp.erase(vchTmp.end()-1); + + // Restore leading zeros + int nLeadingZeros = 0; + for (const char* p = psz; *p == pszBase58[0]; p++) + nLeadingZeros++; + vchRet.assign(nLeadingZeros + vchTmp.size(), 0); + + // Convert little endian data to big endian + reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); + return true; +} + +// Decode a base58-encoded string str into byte vector vchRet +// returns true if decoding is successful +inline bool DecodeBase58(const std::string& str, std::vector& vchRet) +{ + return DecodeBase58(str.c_str(), vchRet); +} + + + + +// Encode a byte vector to a base58-encoded string, including checksum +inline std::string EncodeBase58Check(const std::vector& vchIn) +{ + // add 4-byte hash check to the end + std::vector vch(vchIn); + uint256 hash = Hash(vch.begin(), vch.end()); + vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); + return EncodeBase58(vch); +} + +// Decode a base58-encoded string psz that includes a checksum, into byte vector vchRet +// returns true if decoding is successful +inline bool DecodeBase58Check(const char* psz, std::vector& vchRet) +{ + if (!DecodeBase58(psz, vchRet)) + return false; + if (vchRet.size() < 4) + { + vchRet.clear(); + return false; + } + 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; +} + +// Decode a base58-encoded string str that includes a checksum, into byte vector vchRet +// returns true if decoding is successful +inline bool DecodeBase58Check(const std::string& str, std::vector& vchRet) +{ + return DecodeBase58Check(str.c_str(), vchRet); +} + + + + + +/** Base class for all base58-encoded data */ +class CBase58Data +{ +protected: + // the version byte + unsigned char nVersion; + + // the actually encoded data + std::vector vchData; + + CBase58Data() + { + nVersion = 0; + vchData.clear(); + } + + ~CBase58Data() + { + // zero the memory, as it may contain sensitive data + if (!vchData.empty()) + memset(&vchData[0], 0, vchData.size()); + } + + void SetData(int nVersionIn, const void* pdata, size_t nSize) + { + nVersion = nVersionIn; + vchData.resize(nSize); + if (!vchData.empty()) + memcpy(&vchData[0], pdata, nSize); + } + + void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend) + { + SetData(nVersionIn, (void*)pbegin, pend - pbegin); + } + +public: + bool SetString(const char* psz) + { + std::vector vchTemp; + DecodeBase58Check(psz, vchTemp); + if (vchTemp.empty()) + { + vchData.clear(); + nVersion = 0; + return false; + } + nVersion = vchTemp[0]; + vchData.resize(vchTemp.size() - 1); + if (!vchData.empty()) + memcpy(&vchData[0], &vchTemp[1], vchData.size()); + memset(&vchTemp[0], 0, vchTemp.size()); + return true; + } + + bool SetString(const std::string& str) + { + return SetString(str.c_str()); + } + + std::string ToString() const + { + std::vector vch(1, nVersion); + vch.insert(vch.end(), vchData.begin(), vchData.end()); + return EncodeBase58Check(vch); + } + + int CompareTo(const CBase58Data& b58) const + { + if (nVersion < b58.nVersion) return -1; + if (nVersion > b58.nVersion) return 1; + if (vchData < b58.vchData) return -1; + if (vchData > b58.vchData) return 1; + return 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; } + bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; } +}; + +/** base58-encoded Bitcoin 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; +class CBitcoinAddressVisitor : public boost::static_visitor +{ +private: + CBitcoinAddress *addr; +public: + CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { } + bool operator()(const CKeyID &id) const; + bool operator()(const CScriptID &id) const; + bool operator()(const CNoDestination &no) const; +}; + +class CBitcoinAddress : public CBase58Data +{ +public: + enum + { + PUBKEY_ADDRESS = 25, // BERN: address begin with 'B' + SCRIPT_ADDRESS = 85, + PUBKEY_ADDRESS_TEST = 86, // BERN testnet: address begin with 'b' + SCRIPT_ADDRESS_TEST = 196, + }; + + bool Set(const CKeyID &id) { + SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &id, 20); + return true; + } + + bool Set(const CScriptID &id) { + SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &id, 20); + return true; + } + + bool Set(const CTxDestination &dest) + { + return boost::apply_visitor(CBitcoinAddressVisitor(this), dest); + } + + bool IsValid() const + { + unsigned int nExpectedSize = 20; + bool fExpectTestNet = false; + switch(nVersion) + { + case PUBKEY_ADDRESS: + nExpectedSize = 20; // Hash of public key + fExpectTestNet = false; + break; + case SCRIPT_ADDRESS: + nExpectedSize = 20; // Hash of CScript + fExpectTestNet = false; + break; + + case PUBKEY_ADDRESS_TEST: + nExpectedSize = 20; + fExpectTestNet = true; + break; + case SCRIPT_ADDRESS_TEST: + nExpectedSize = 20; + fExpectTestNet = true; + break; + + default: + return false; + } + return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize; + } + + CBitcoinAddress() + { + } + + CBitcoinAddress(const CTxDestination &dest) + { + Set(dest); + } + + CBitcoinAddress(const std::string& strAddress) + { + SetString(strAddress); + } + + CBitcoinAddress(const char* pszAddress) + { + SetString(pszAddress); + } + + CTxDestination Get() const { + if (!IsValid()) + return CNoDestination(); + switch (nVersion) { + case PUBKEY_ADDRESS: + case PUBKEY_ADDRESS_TEST: { + uint160 id; + memcpy(&id, &vchData[0], 20); + return CKeyID(id); + } + case SCRIPT_ADDRESS: + case SCRIPT_ADDRESS_TEST: { + uint160 id; + memcpy(&id, &vchData[0], 20); + return CScriptID(id); + } + } + return CNoDestination(); + } + + bool GetKeyID(CKeyID &keyID) const { + if (!IsValid()) + return false; + switch (nVersion) { + case PUBKEY_ADDRESS: + case PUBKEY_ADDRESS_TEST: { + uint160 id; + memcpy(&id, &vchData[0], 20); + keyID = CKeyID(id); + return true; + } + default: return false; + } + } + + bool IsScript() const { + if (!IsValid()) + return false; + switch (nVersion) { + case SCRIPT_ADDRESS: + case SCRIPT_ADDRESS_TEST: { + return true; + } + default: return false; + } + } +}; + +bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { return addr->Set(id); } +bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); } +bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; } + +/** A base58-encoded secret key */ +class CBitcoinSecret : public CBase58Data +{ +public: + void SetSecret(const CSecret& vchSecret, bool fCompressed) + { + assert(vchSecret.size() == 32); + SetData(128 + (fTestNet ? CBitcoinAddress::PUBKEY_ADDRESS_TEST : CBitcoinAddress::PUBKEY_ADDRESS), &vchSecret[0], vchSecret.size()); + if (fCompressed) + vchData.push_back(1); + } + + CSecret GetSecret(bool &fCompressedOut) + { + CSecret vchSecret; + vchSecret.resize(32); + memcpy(&vchSecret[0], &vchData[0], 32); + fCompressedOut = vchData.size() == 33; + return vchSecret; + } + + bool IsValid() const + { + bool fExpectTestNet = false; + switch(nVersion) + { + case (128 + CBitcoinAddress::PUBKEY_ADDRESS): + break; + + case (128 + CBitcoinAddress::PUBKEY_ADDRESS_TEST): + fExpectTestNet = true; + break; + + default: + return false; + } + return fExpectTestNet == fTestNet && (vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1)); + } + + bool SetString(const char* pszSecret) + { + return CBase58Data::SetString(pszSecret) && IsValid(); + } + + bool SetString(const std::string& strSecret) + { + return SetString(strSecret.c_str()); + } + + CBitcoinSecret(const CSecret& vchSecret, bool fCompressed) + { + SetSecret(vchSecret, fCompressed); + } + + CBitcoinSecret() + { + } +}; + +#endif diff --git a/src/bignum.h b/src/bignum.h new file mode 100644 index 0000000..c214275 --- /dev/null +++ b/src/bignum.h @@ -0,0 +1,564 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_BIGNUM_H +#define BITCOIN_BIGNUM_H + +#include +#include +#include + +#include "util.h" // for uint64 + +/** Errors thrown by the bignum class */ +class bignum_error : public std::runtime_error +{ +public: + explicit bignum_error(const std::string& str) : std::runtime_error(str) {} +}; + + +/** RAII encapsulated BN_CTX (OpenSSL bignum context) */ +class CAutoBN_CTX +{ +protected: + BN_CTX* pctx; + BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; } + +public: + CAutoBN_CTX() + { + pctx = BN_CTX_new(); + if (pctx == NULL) + throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL"); + } + + ~CAutoBN_CTX() + { + if (pctx != NULL) + BN_CTX_free(pctx); + } + + operator BN_CTX*() { return pctx; } + BN_CTX& operator*() { return *pctx; } + BN_CTX** operator&() { return &pctx; } + bool operator!() { return (pctx == NULL); } +}; + + +/** C++ wrapper for BIGNUM (OpenSSL bignum) */ +class CBigNum : public BIGNUM +{ +public: + CBigNum() + { + BN_init(this); + } + + CBigNum(const CBigNum& b) + { + BN_init(this); + if (!BN_copy(this, &b)) + { + BN_clear_free(this); + throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed"); + } + } + + CBigNum& operator=(const CBigNum& b) + { + if (!BN_copy(this, &b)) + throw bignum_error("CBigNum::operator= : BN_copy failed"); + return (*this); + } + + ~CBigNum() + { + BN_clear_free(this); + } + + //CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'. + CBigNum(signed char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int64 n) { BN_init(this); setint64(n); } + CBigNum(unsigned char n) { BN_init(this); setulong(n); } + CBigNum(unsigned short n) { BN_init(this); setulong(n); } + CBigNum(unsigned int n) { BN_init(this); setulong(n); } + CBigNum(unsigned long n) { BN_init(this); setulong(n); } + CBigNum(uint64 n) { BN_init(this); setuint64(n); } + explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); } + + explicit CBigNum(const std::vector& vch) + { + BN_init(this); + setvch(vch); + } + + void setulong(unsigned long n) + { + if (!BN_set_word(this, n)) + throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed"); + } + + unsigned long getulong() const + { + return BN_get_word(this); + } + + unsigned int getuint() const + { + return BN_get_word(this); + } + + int getint() const + { + unsigned long n = BN_get_word(this); + if (!BN_is_negative(this)) + return (n > (unsigned long)std::numeric_limits::max() ? std::numeric_limits::max() : n); + else + return (n > (unsigned long)std::numeric_limits::max() ? std::numeric_limits::min() : -(int)n); + } + + void setint64(int64 sn) + { + unsigned char pch[sizeof(sn) + 6]; + unsigned char* p = pch + 4; + bool fNegative; + uint64 n; + + if (sn < (int64)0) + { + // Since the minimum signed integer cannot be represented as positive so long as its type is signed, and it's not well-defined what happens if you make it unsigned before negating it, we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate + n = -(sn + 1); + ++n; + fNegative = true; + } else { + n = sn; + fNegative = false; + } + + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = (fNegative ? 0x80 : 0); + else if (fNegative) + c |= 0x80; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + uint64 getuint64() + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return 0; + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + if (vch.size() > 4) + vch[4] &= 0x7f; + uint64 n = 0; + for (unsigned int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--) + ((unsigned char*)&n)[i] = vch[j]; + return n; + } + + void setuint64(uint64 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + void setuint256(uint256 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + unsigned char* pbegin = (unsigned char*)&n; + unsigned char* psrc = pbegin + sizeof(n); + while (psrc != pbegin) + { + unsigned char c = *(--psrc); + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize >> 0) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + uint256 getuint256() + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return 0; + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + if (vch.size() > 4) + vch[4] &= 0x7f; + uint256 n = 0; + for (unsigned int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--) + ((unsigned char*)&n)[i] = vch[j]; + return n; + } + + + void setvch(const std::vector& vch) + { + std::vector vch2(vch.size() + 4); + unsigned int nSize = vch.size(); + // BIGNUM's byte stream format expects 4 bytes of + // big endian size data info at the front + vch2[0] = (nSize >> 24) & 0xff; + vch2[1] = (nSize >> 16) & 0xff; + vch2[2] = (nSize >> 8) & 0xff; + vch2[3] = (nSize >> 0) & 0xff; + // swap data to big endian + reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4); + BN_mpi2bn(&vch2[0], vch2.size(), this); + } + + std::vector getvch() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize <= 4) + return std::vector(); + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + vch.erase(vch.begin(), vch.begin() + 4); + reverse(vch.begin(), vch.end()); + return vch; + } + + CBigNum& SetCompact(unsigned int nCompact) + { + unsigned int nSize = nCompact >> 24; + std::vector vch(4 + nSize); + vch[3] = nSize; + if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff; + if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff; + if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff; + BN_mpi2bn(&vch[0], vch.size(), this); + return *this; + } + + unsigned int GetCompact() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + std::vector vch(nSize); + nSize -= 4; + BN_bn2mpi(this, &vch[0]); + unsigned int nCompact = nSize << 24; + if (nSize >= 1) nCompact |= (vch[4] << 16); + if (nSize >= 2) nCompact |= (vch[5] << 8); + if (nSize >= 3) nCompact |= (vch[6] << 0); + return nCompact; + } + + void SetHex(const std::string& str) + { + // skip 0x + const char* psz = str.c_str(); + while (isspace(*psz)) + psz++; + bool fNegative = false; + if (*psz == '-') + { + fNegative = true; + psz++; + } + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + while (isspace(*psz)) + psz++; + + // hex string to bignum + static const signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + *this = 0; + while (isxdigit(*psz)) + { + *this <<= 4; + int n = phexdigit[(unsigned char)*psz++]; + *this += n; + } + if (fNegative) + *this = 0 - *this; + } + + std::string ToString(int nBase=10) const + { + CAutoBN_CTX pctx; + CBigNum bnBase = nBase; + CBigNum bn0 = 0; + std::string str; + CBigNum bn = *this; + BN_set_negative(&bn, false); + CBigNum dv; + CBigNum rem; + if (BN_cmp(&bn, &bn0) == 0) + return "0"; + while (BN_cmp(&bn, &bn0) > 0) + { + if (!BN_div(&dv, &rem, &bn, &bnBase, pctx)) + throw bignum_error("CBigNum::ToString() : BN_div failed"); + bn = dv; + unsigned int c = rem.getulong(); + str += "0123456789abcdef"[c]; + } + if (BN_is_negative(this)) + str += "-"; + reverse(str.begin(), str.end()); + return str; + } + + std::string GetHex() const + { + return ToString(16); + } + + unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const + { + return ::GetSerializeSize(getvch(), nType, nVersion); + } + + template + void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const + { + ::Serialize(s, getvch(), nType, nVersion); + } + + template + void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) + { + std::vector vch; + ::Unserialize(s, vch, nType, nVersion); + setvch(vch); + } + + + bool operator!() const + { + return BN_is_zero(this); + } + + CBigNum& operator+=(const CBigNum& b) + { + if (!BN_add(this, this, &b)) + throw bignum_error("CBigNum::operator+= : BN_add failed"); + return *this; + } + + CBigNum& operator-=(const CBigNum& b) + { + *this = *this - b; + return *this; + } + + CBigNum& operator*=(const CBigNum& b) + { + CAutoBN_CTX pctx; + if (!BN_mul(this, this, &b, pctx)) + throw bignum_error("CBigNum::operator*= : BN_mul failed"); + return *this; + } + + CBigNum& operator/=(const CBigNum& b) + { + *this = *this / b; + return *this; + } + + CBigNum& operator%=(const CBigNum& b) + { + *this = *this % b; + return *this; + } + + CBigNum& operator<<=(unsigned int shift) + { + if (!BN_lshift(this, this, shift)) + throw bignum_error("CBigNum:operator<<= : BN_lshift failed"); + return *this; + } + + CBigNum& operator>>=(unsigned int shift) + { + // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number + // if built on ubuntu 9.04 or 9.10, probably depends on version of OpenSSL + CBigNum a = 1; + a <<= shift; + if (BN_cmp(&a, this) > 0) + { + *this = 0; + return *this; + } + + if (!BN_rshift(this, this, shift)) + throw bignum_error("CBigNum:operator>>= : BN_rshift failed"); + return *this; + } + + + CBigNum& operator++() + { + // prefix operator + if (!BN_add(this, this, BN_value_one())) + throw bignum_error("CBigNum::operator++ : BN_add failed"); + return *this; + } + + const CBigNum operator++(int) + { + // postfix operator + const CBigNum ret = *this; + ++(*this); + return ret; + } + + CBigNum& operator--() + { + // prefix operator + CBigNum r; + if (!BN_sub(&r, this, BN_value_one())) + throw bignum_error("CBigNum::operator-- : BN_sub failed"); + *this = r; + return *this; + } + + const CBigNum operator--(int) + { + // postfix operator + const CBigNum ret = *this; + --(*this); + return ret; + } + + + friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b); +}; + + + +inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_add(&r, &a, &b)) + throw bignum_error("CBigNum::operator+ : BN_add failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_sub(&r, &a, &b)) + throw bignum_error("CBigNum::operator- : BN_sub failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a) +{ + CBigNum r(a); + BN_set_negative(&r, !BN_is_negative(&r)); + return r; +} + +inline const CBigNum operator*(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mul(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator* : BN_mul failed"); + return r; +} + +inline const CBigNum operator/(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_div(&r, NULL, &a, &b, pctx)) + throw bignum_error("CBigNum::operator/ : BN_div failed"); + return r; +} + +inline const CBigNum operator%(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mod(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator% : BN_div failed"); + return r; +} + +inline const CBigNum operator<<(const CBigNum& a, unsigned int shift) +{ + CBigNum r; + if (!BN_lshift(&r, &a, shift)) + throw bignum_error("CBigNum:operator<< : BN_lshift failed"); + return r; +} + +inline const CBigNum operator>>(const CBigNum& a, unsigned int shift) +{ + CBigNum r = a; + r >>= shift; + return r; +} + +inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); } +inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); } +inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); } +inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); } +inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); } +inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); } + +#endif diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp new file mode 100644 index 0000000..f6b3e8e --- /dev/null +++ b/src/bitcoinrpc.cpp @@ -0,0 +1,1292 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "init.h" +#include "util.h" +#include "sync.h" +#include "ui_interface.h" +#include "base58.h" +#include "bitcoinrpc.h" +#include "db.h" + +#undef printf +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define printf OutputDebugStringF + +using namespace std; +using namespace boost; +using namespace boost::asio; +using namespace json_spirit; + +void ThreadRPCServer2(void* parg); + +static std::string strRPCUserColonPass; + +const Object emptyobj; + +void ThreadRPCServer3(void* parg); + +static inline unsigned short GetDefaultRPCPort() +{ + return GetBoolArg("-testnet", false) ? 42016 : 32016; +} + +Object JSONRPCError(int code, const string& message) +{ + Object error; + error.push_back(Pair("code", code)); + error.push_back(Pair("message", message)); + return error; +} + +void RPCTypeCheck(const Array& params, + const list& typesExpected, + bool fAllowNull) +{ + unsigned int i = 0; + BOOST_FOREACH(Value_type t, typesExpected) + { + if (params.size() <= i) + break; + + const Value& v = params[i]; + if (!((v.type() == t) || (fAllowNull && (v.type() == null_type)))) + { + string err = strprintf("Expected type %s, got %s", + Value_type_name[t], Value_type_name[v.type()]); + throw JSONRPCError(RPC_TYPE_ERROR, err); + } + i++; + } +} + +void RPCTypeCheck(const Object& o, + const map& typesExpected, + bool fAllowNull) +{ + BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) + { + const Value& v = find_value(o, t.first); + if (!fAllowNull && v.type() == null_type) + throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first.c_str())); + + if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type)))) + { + string err = strprintf("Expected type %s for %s, got %s", + Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]); + throw JSONRPCError(RPC_TYPE_ERROR, err); + } + } +} + +int64 AmountFromValue(const Value& value) +{ + double dAmount = value.get_real(); + if (dAmount <= 0.0 || dAmount > MAX_MONEY) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); + int64 nAmount = roundint64(dAmount * COIN); + if (!MoneyRange(nAmount)) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); + return nAmount; +} + +Value ValueFromAmount(int64 amount) +{ + return (double)amount / (double)COIN; +} + +std::string HexBits(unsigned int nBits) +{ + union { + int32_t nBits; + char cBits[4]; + } uBits; + uBits.nBits = htonl((int32_t)nBits); + return HexStr(BEGIN(uBits.cBits), END(uBits.cBits)); +} + + + +/// +/// Note: This interface may still be subject to change. +/// + +string CRPCTable::help(string strCommand) const +{ + string strRet; + set setDone; + for (map::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi) + { + const CRPCCommand *pcmd = mi->second; + string strMethod = mi->first; + // We already filter duplicates, but these deprecated screw up the sort order + if (strMethod.find("label") != string::npos) + continue; + if (strCommand != "" && strMethod != strCommand) + continue; + try + { + Array params; + rpcfn_type pfn = pcmd->actor; + if (setDone.insert(pfn).second) + (*pfn)(params, true); + } + catch (std::exception& e) + { + // Help text is returned in an exception + string strHelp = string(e.what()); + if (strCommand == "") + if (strHelp.find('\n') != string::npos) + strHelp = strHelp.substr(0, strHelp.find('\n')); + strRet += strHelp + "\n"; + } + } + if (strRet == "") + strRet = strprintf("help: unknown command: %s\n", strCommand.c_str()); + strRet = strRet.substr(0,strRet.size()-1); + return strRet; +} + +Value help(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "help [command]\n" + "List commands, or get help for a command."); + + string strCommand; + if (params.size() > 0) + strCommand = params[0].get_str(); + + return tableRPC.help(strCommand); +} + + +Value stop(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "stop \n" + " is true or false to detach the database or not for this stop only\n" + "Stop BERN server (and possibly override the detachdb config value)."); + // Shutdown will take long enough that the response should get back + if (params.size() > 0) + bitdb.SetDetach(params[0].get_bool()); + StartShutdown(); + return "BERN server stopping"; +} + + + +// +// Call Table +// + + +static const CRPCCommand vRPCCommands[] = +{ // name function safemd unlocked + // ------------------------ ----------------------- ------ -------- + { "help", &help, true, true }, + { "stop", &stop, true, true }, + { "getblockcount", &getblockcount, true, false }, + { "getconnectioncount", &getconnectioncount, true, false }, + { "getpeerinfo", &getpeerinfo, true, false }, + { "getdifficulty", &getdifficulty, true, false }, + { "getgenerate", &getgenerate, true, false }, + { "setgenerate", &setgenerate, true, false }, + { "gethashespersec", &gethashespersec, true, false }, + { "getinfo", &getinfo, true, false }, + { "getmininginfo", &getmininginfo, true, false }, + { "getnewaddress", &getnewaddress, true, false }, + { "getnewpubkey", &getnewpubkey, true, false }, + { "getaccountaddress", &getaccountaddress, true, false }, + { "setaccount", &setaccount, true, false }, + { "getaccount", &getaccount, false, false }, + { "getaddressesbyaccount", &getaddressesbyaccount, true, false }, + { "sendtoaddress", &sendtoaddress, false, false }, + { "getreceivedbyaddress", &getreceivedbyaddress, false, false }, + { "getreceivedbyaccount", &getreceivedbyaccount, false, false }, + { "listreceivedbyaddress", &listreceivedbyaddress, false, false }, + { "listreceivedbyaccount", &listreceivedbyaccount, false, false }, + { "backupwallet", &backupwallet, true, false }, + { "keypoolrefill", &keypoolrefill, true, false }, + { "walletpassphrase", &walletpassphrase, true, false }, + { "walletpassphrasechange", &walletpassphrasechange, false, false }, + { "walletlock", &walletlock, true, false }, + { "encryptwallet", &encryptwallet, false, false }, + { "validateaddress", &validateaddress, true, false }, + { "validatepubkey", &validatepubkey, true, false }, + { "getbalance", &getbalance, false, false }, + { "move", &movecmd, false, false }, + { "sendfrom", &sendfrom, false, false }, + { "sendmany", &sendmany, false, false }, + { "addmultisigaddress", &addmultisigaddress, false, false }, + { "getrawmempool", &getrawmempool, true, false }, + { "getblock", &getblock, false, false }, + { "getblockbynumber", &getblockbynumber, false, false }, + { "getblockhash", &getblockhash, false, false }, + { "gettransaction", &gettransaction, false, false }, + { "listtransactions", &listtransactions, false, false }, + { "listaddressgroupings", &listaddressgroupings, false, false }, + { "signmessage", &signmessage, false, false }, + { "verifymessage", &verifymessage, false, false }, + { "getwork", &getwork, true, false }, + { "getworkex", &getworkex, true, false }, + { "listaccounts", &listaccounts, false, false }, + { "settxfee", &settxfee, false, false }, + { "getblocktemplate", &getblocktemplate, true, false }, + { "submitblock", &submitblock, false, false }, + { "listsinceblock", &listsinceblock, false, false }, + { "dumpprivkey", &dumpprivkey, false, false }, + { "importprivkey", &importprivkey, false, false }, + { "listunspent", &listunspent, false, false }, + { "getrawtransaction", &getrawtransaction, false, false }, + { "createrawtransaction", &createrawtransaction, false, false }, + { "decoderawtransaction", &decoderawtransaction, false, false }, + { "signrawtransaction", &signrawtransaction, false, false }, + { "sendrawtransaction", &sendrawtransaction, false, false }, + { "getcheckpoint", &getcheckpoint, true, false }, + { "reservebalance", &reservebalance, false, true}, + { "checkwallet", &checkwallet, false, true}, + { "repairwallet", &repairwallet, false, true}, + { "resendtx", &resendtx, false, true}, + { "makekeypair", &makekeypair, false, true}, + { "sendalert", &sendalert, false, false}, +}; + +CRPCTable::CRPCTable() +{ + unsigned int vcidx; + for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++) + { + const CRPCCommand *pcmd; + + pcmd = &vRPCCommands[vcidx]; + mapCommands[pcmd->name] = pcmd; + } +} + +const CRPCCommand *CRPCTable::operator[](string name) const +{ + map::const_iterator it = mapCommands.find(name); + if (it == mapCommands.end()) + return NULL; + return (*it).second; +} + +// +// HTTP protocol +// +// This ain't Apache. We're just using HTTP header for the length field +// and to be compatible with other JSON-RPC implementations. +// + +string HTTPPost(const string& strMsg, const map& mapRequestHeaders) +{ + ostringstream s; + s << "POST / HTTP/1.1\r\n" + << "User-Agent: BERN-json-rpc/" << FormatFullVersion() << "\r\n" + << "Host: 127.0.0.1\r\n" + << "Content-Type: application/json\r\n" + << "Content-Length: " << strMsg.size() << "\r\n" + << "Connection: close\r\n" + << "Accept: application/json\r\n"; + BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders) + s << item.first << ": " << item.second << "\r\n"; + s << "\r\n" << strMsg; + + return s.str(); +} + +string rfc1123Time() +{ + char buffer[64]; + time_t now; + time(&now); + struct tm* now_gmt = gmtime(&now); + string locale(setlocale(LC_TIME, NULL)); + setlocale(LC_TIME, "C"); // we want POSIX (aka "C") weekday/month strings + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt); + setlocale(LC_TIME, locale.c_str()); + return string(buffer); +} + +static string HTTPReply(int nStatus, const string& strMsg, bool keepalive) +{ + if (nStatus == HTTP_UNAUTHORIZED) + return strprintf("HTTP/1.0 401 Authorization Required\r\n" + "Date: %s\r\n" + "Server: BERN-json-rpc/%s\r\n" + "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 296\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "Error\r\n" + "\r\n" + "\r\n" + "

401 Unauthorized.

\r\n" + "\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str()); + const char *cStatus; + if (nStatus == HTTP_OK) cStatus = "OK"; + else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request"; + else if (nStatus == HTTP_FORBIDDEN) cStatus = "Forbidden"; + else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found"; + else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error"; + else cStatus = ""; + return strprintf( + "HTTP/1.1 %d %s\r\n" + "Date: %s\r\n" + "Connection: %s\r\n" + "Content-Length: %"PRIszu"\r\n" + "Content-Type: application/json\r\n" + "Server: BERN-json-rpc/%s\r\n" + "\r\n" + "%s", + nStatus, + cStatus, + rfc1123Time().c_str(), + keepalive ? "keep-alive" : "close", + strMsg.size(), + FormatFullVersion().c_str(), + strMsg.c_str()); +} + +int ReadHTTPStatus(std::basic_istream& stream, int &proto) +{ + string str; + getline(stream, str); + vector vWords; + boost::split(vWords, str, boost::is_any_of(" ")); + if (vWords.size() < 2) + return HTTP_INTERNAL_SERVER_ERROR; + proto = 0; + const char *ver = strstr(str.c_str(), "HTTP/1."); + if (ver != NULL) + proto = atoi(ver+7); + return atoi(vWords[1].c_str()); +} + +int ReadHTTPHeader(std::basic_istream& stream, map& mapHeadersRet) +{ + int nLen = 0; + while (true) + { + string str; + std::getline(stream, str); + if (str.empty() || str == "\r") + break; + string::size_type nColon = str.find(":"); + if (nColon != string::npos) + { + string strHeader = str.substr(0, nColon); + boost::trim(strHeader); + boost::to_lower(strHeader); + string strValue = str.substr(nColon+1); + boost::trim(strValue); + mapHeadersRet[strHeader] = strValue; + if (strHeader == "content-length") + nLen = atoi(strValue.c_str()); + } + } + return nLen; +} + +int ReadHTTP(std::basic_istream& stream, map& mapHeadersRet, string& strMessageRet) +{ + mapHeadersRet.clear(); + strMessageRet = ""; + + // Read status + int nProto = 0; + int nStatus = ReadHTTPStatus(stream, nProto); + + // Read header + int nLen = ReadHTTPHeader(stream, mapHeadersRet); + if (nLen < 0 || nLen > (int)MAX_SIZE) + return HTTP_INTERNAL_SERVER_ERROR; + + // Read message + if (nLen > 0) + { + vector vch(nLen); + stream.read(&vch[0], nLen); + strMessageRet = string(vch.begin(), vch.end()); + } + + string sConHdr = mapHeadersRet["connection"]; + + if ((sConHdr != "close") && (sConHdr != "keep-alive")) + { + if (nProto >= 1) + mapHeadersRet["connection"] = "keep-alive"; + else + mapHeadersRet["connection"] = "close"; + } + + return nStatus; +} + +bool HTTPAuthorized(map& mapHeaders) +{ + string strAuth = mapHeaders["authorization"]; + if (strAuth.substr(0,6) != "Basic ") + return false; + string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); + string strUserPass = DecodeBase64(strUserPass64); + return strUserPass == strRPCUserColonPass; +} + +// +// JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility, +// but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were +// unspecified (HTTP errors and contents of 'error'). +// +// 1.0 spec: http://json-rpc.org/wiki/specification +// 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http +// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx +// + +string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) +{ + Object request; + request.push_back(Pair("method", strMethod)); + request.push_back(Pair("params", params)); + request.push_back(Pair("id", id)); + return write_string(Value(request), false) + "\n"; +} + +Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) +{ + Object reply; + if (error.type() != null_type) + reply.push_back(Pair("result", Value::null)); + else + reply.push_back(Pair("result", result)); + reply.push_back(Pair("error", error)); + reply.push_back(Pair("id", id)); + return reply; +} + +string JSONRPCReply(const Value& result, const Value& error, const Value& id) +{ + Object reply = JSONRPCReplyObj(result, error, id); + return write_string(Value(reply), false) + "\n"; +} + +void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) +{ + // Send error reply from json-rpc error object + int nStatus = HTTP_INTERNAL_SERVER_ERROR; + int code = find_value(objError, "code").get_int(); + if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; + else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND; + string strReply = JSONRPCReply(Value::null, objError, id); + stream << HTTPReply(nStatus, strReply, false) << std::flush; +} + +bool ClientAllowed(const boost::asio::ip::address& address) +{ + // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses + if (address.is_v6() + && (address.to_v6().is_v4_compatible() + || address.to_v6().is_v4_mapped())) + return ClientAllowed(address.to_v6().to_v4()); + + std::string ipv4addr = address.to_string(); + + if (address == asio::ip::address_v4::loopback() + || address == asio::ip::address_v6::loopback() + || (address.is_v4() + // Check whether IPv4 addresses match 127.0.0.0/8 (loopback subnet) + && (address.to_v4().to_ulong() & 0xff000000) == 0x7f000000)) + return true; + + const string strAddress = address.to_string(); + const vector& vAllow = mapMultiArgs["-rpcallowip"]; + BOOST_FOREACH(string strAllow, vAllow) + if (WildcardMatch(strAddress, strAllow)) + return true; + return false; +} + +// +// IOStream device that speaks SSL but can also speak non-SSL +// +template +class SSLIOStreamDevice : public iostreams::device { +public: + SSLIOStreamDevice(asio::ssl::stream &streamIn, bool fUseSSLIn) : stream(streamIn) + { + fUseSSL = fUseSSLIn; + fNeedHandshake = fUseSSLIn; + } + + void handshake(ssl::stream_base::handshake_type role) + { + if (!fNeedHandshake) return; + fNeedHandshake = false; + stream.handshake(role); + } + std::streamsize read(char* s, std::streamsize n) + { + handshake(ssl::stream_base::server); // HTTPS servers read first + if (fUseSSL) return stream.read_some(asio::buffer(s, n)); + return stream.next_layer().read_some(asio::buffer(s, n)); + } + std::streamsize write(const char* s, std::streamsize n) + { + handshake(ssl::stream_base::client); // HTTPS clients write first + if (fUseSSL) return asio::write(stream, asio::buffer(s, n)); + return asio::write(stream.next_layer(), asio::buffer(s, n)); + } + bool connect(const std::string& server, const std::string& port) + { + ip::tcp::resolver resolver(stream.get_io_service()); + ip::tcp::resolver::query query(server.c_str(), port.c_str()); + ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); + ip::tcp::resolver::iterator end; + boost::system::error_code error = asio::error::host_not_found; + while (error && endpoint_iterator != end) + { + stream.lowest_layer().close(); + stream.lowest_layer().connect(*endpoint_iterator++, error); + } + if (error) + return false; + return true; + } + +private: + bool fNeedHandshake; + bool fUseSSL; + asio::ssl::stream& stream; +}; + +class AcceptedConnection +{ +public: + virtual ~AcceptedConnection() {} + + virtual std::iostream& stream() = 0; + virtual std::string peer_address_to_string() const = 0; + virtual void close() = 0; +}; + +template +class AcceptedConnectionImpl : public AcceptedConnection +{ +public: + AcceptedConnectionImpl( + asio::io_service& io_service, + ssl::context &context, + bool fUseSSL) : + sslStream(io_service, context), + _d(sslStream, fUseSSL), + _stream(_d) + { + } + + virtual std::iostream& stream() + { + return _stream; + } + + virtual std::string peer_address_to_string() const + { + return peer.address().to_string(); + } + + virtual void close() + { + _stream.close(); + } + + typename Protocol::endpoint peer; + asio::ssl::stream sslStream; + +private: + SSLIOStreamDevice _d; + iostreams::stream< SSLIOStreamDevice > _stream; +}; + +void ThreadRPCServer(void* parg) +{ + // Make this thread recognisable as the RPC listener + RenameThread("bitcoin-rpclist"); + + try + { + vnThreadsRunning[THREAD_RPCLISTENER]++; + ThreadRPCServer2(parg); + vnThreadsRunning[THREAD_RPCLISTENER]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_RPCLISTENER]--; + PrintException(&e, "ThreadRPCServer()"); + } catch (...) { + vnThreadsRunning[THREAD_RPCLISTENER]--; + PrintException(NULL, "ThreadRPCServer()"); + } + printf("ThreadRPCServer exited\n"); +} + +// Forward declaration required for RPCListen +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + bool fUseSSL, + AcceptedConnection* conn, + const boost::system::error_code& error); + +/** + * Sets up I/O resources to accept and handle a new connection. + */ +template +static void RPCListen(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + const bool fUseSSL) +{ + // Accept connection + AcceptedConnectionImpl* conn = new AcceptedConnectionImpl(acceptor->get_io_service(), context, fUseSSL); + + acceptor->async_accept( + conn->sslStream.lowest_layer(), + conn->peer, + boost::bind(&RPCAcceptHandler, + acceptor, + boost::ref(context), + fUseSSL, + conn, + boost::asio::placeholders::error)); +} + +/** + * Accept and handle incoming connection. + */ +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + const bool fUseSSL, + AcceptedConnection* conn, + const boost::system::error_code& error) +{ + vnThreadsRunning[THREAD_RPCLISTENER]++; + + // Immediately start accepting new connections, except when we're cancelled or our socket is closed. + if (error != asio::error::operation_aborted + && acceptor->is_open()) + RPCListen(acceptor, context, fUseSSL); + + AcceptedConnectionImpl* tcp_conn = dynamic_cast< AcceptedConnectionImpl* >(conn); + + // TODO: Actually handle errors + if (error) + { + delete conn; + } + + // Restrict callers by IP. It is important to + // do this before starting client thread, to filter out + // certain DoS and misbehaving clients. + else if (tcp_conn + && !ClientAllowed(tcp_conn->peer.address())) + { + // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake. + if (!fUseSSL) + conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush; + delete conn; + } + + // start HTTP client thread + else if (!NewThread(ThreadRPCServer3, conn)) { + printf("Failed to create RPC server client thread\n"); + delete conn; + } + + vnThreadsRunning[THREAD_RPCLISTENER]--; +} + +void ThreadRPCServer2(void* parg) +{ + printf("ThreadRPCServer started\n"); + + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + if (mapArgs["-rpcpassword"] == "") + { + unsigned char rand_pwd[32]; + RAND_bytes(rand_pwd, 32); + string strWhatAmI = "To use BERNd"; + if (mapArgs.count("-server")) + strWhatAmI = strprintf(_("To use the %s option"), "\"-server\""); + else if (mapArgs.count("-daemon")) + strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\""); + uiInterface.ThreadSafeMessageBox(strprintf( + _("%s, you must set a rpcpassword in the configuration file:\n %s\n" + "It is recommended you use the following random password:\n" + "rpcuser=bitcoinrpc\n" + "rpcpassword=%s\n" + "(you do not need to remember this password)\n" + "If the file does not exist, create it with owner-readable-only file permissions.\n"), + strWhatAmI.c_str(), + GetConfigFile().string().c_str(), + EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()), + _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); + StartShutdown(); + return; + } + + const bool fUseSSL = GetBoolArg("-rpcssl"); + + asio::io_service io_service; + + ssl::context context(io_service, ssl::context::sslv23); + if (fUseSSL) + { + context.set_options(ssl::context::no_sslv2); + + filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); + if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile; + if (filesystem::exists(pathCertFile)) context.use_certificate_chain_file(pathCertFile.string()); + else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str()); + + filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); + if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile; + if (filesystem::exists(pathPKFile)) context.use_private_key_file(pathPKFile.string(), ssl::context::pem); + else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str()); + + string strCiphers = GetArg("-rpcsslciphers", "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH"); + SSL_CTX_set_cipher_list(context.impl(), strCiphers.c_str()); + } + + // Try a dual IPv6/IPv4 socket, falling back to separate IPv4 and IPv6 sockets + const bool loopback = !mapArgs.count("-rpcallowip"); + asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any(); + ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", GetDefaultRPCPort())); + boost::system::error_code v6_only_error; + boost::shared_ptr acceptor(new ip::tcp::acceptor(io_service)); + + boost::signals2::signal StopRequests; + + bool fListening = false; + std::string strerr; + try + { + acceptor->open(endpoint.protocol()); + acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + + // Try making the socket dual IPv6/IPv4 (if listening on the "any" address) + acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error); + + acceptor->bind(endpoint); + acceptor->listen(socket_base::max_connections); + + RPCListen(acceptor, context, fUseSSL); + // Cancel outstanding listen-requests for this acceptor when shutting down + StopRequests.connect(signals2::slot( + static_cast(&ip::tcp::acceptor::close), acceptor.get()) + .track(acceptor)); + + fListening = true; + } + catch(boost::system::system_error &e) + { + strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s"), endpoint.port(), e.what()); + } + + try { + // If dual IPv6/IPv4 failed (or we're opening loopback interfaces only), open IPv4 separately + if (!fListening || loopback || v6_only_error) + { + bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any(); + endpoint.address(bindAddress); + + acceptor.reset(new ip::tcp::acceptor(io_service)); + acceptor->open(endpoint.protocol()); + acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + acceptor->bind(endpoint); + acceptor->listen(socket_base::max_connections); + + RPCListen(acceptor, context, fUseSSL); + // Cancel outstanding listen-requests for this acceptor when shutting down + StopRequests.connect(signals2::slot( + static_cast(&ip::tcp::acceptor::close), acceptor.get()) + .track(acceptor)); + + fListening = true; + } + } + catch(boost::system::system_error &e) + { + strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv4: %s"), endpoint.port(), e.what()); + } + + if (!fListening) { + uiInterface.ThreadSafeMessageBox(strerr, _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); + StartShutdown(); + return; + } + + vnThreadsRunning[THREAD_RPCLISTENER]--; + while (!fShutdown) + io_service.run_one(); + vnThreadsRunning[THREAD_RPCLISTENER]++; + StopRequests(); +} + +class JSONRequest +{ +public: + Value id; + string strMethod; + Array params; + + JSONRequest() { id = Value::null; } + void parse(const Value& valRequest); +}; + +void JSONRequest::parse(const Value& valRequest) +{ + // Parse request + if (valRequest.type() != obj_type) + throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object"); + const Object& request = valRequest.get_obj(); + + // Parse id now so errors from here on will have the id + id = find_value(request, "id"); + + // Parse method + Value valMethod = find_value(request, "method"); + if (valMethod.type() == null_type) + throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); + if (valMethod.type() != str_type) + throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string"); + strMethod = valMethod.get_str(); + if (strMethod != "getwork" && strMethod != "getblocktemplate") + printf("ThreadRPCServer method=%s\n", strMethod.c_str()); + + // Parse params + Value valParams = find_value(request, "params"); + if (valParams.type() == array_type) + params = valParams.get_array(); + else if (valParams.type() == null_type) + params = Array(); + else + throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); +} + +static Object JSONRPCExecOne(const Value& req) +{ + Object rpc_result; + + JSONRequest jreq; + try { + jreq.parse(req); + + Value result = tableRPC.execute(jreq.strMethod, jreq.params); + rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id); + } + catch (Object& objError) + { + rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); + } + catch (std::exception& e) + { + rpc_result = JSONRPCReplyObj(Value::null, + JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); + } + + return rpc_result; +} + +static string JSONRPCExecBatch(const Array& vReq) +{ + Array ret; + for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) + ret.push_back(JSONRPCExecOne(vReq[reqIdx])); + + return write_string(Value(ret), false) + "\n"; +} + +static CCriticalSection cs_THREAD_RPCHANDLER; + +void ThreadRPCServer3(void* parg) +{ + // Make this thread recognisable as the RPC handler + RenameThread("bitcoin-rpchand"); + + { + LOCK(cs_THREAD_RPCHANDLER); + vnThreadsRunning[THREAD_RPCHANDLER]++; + } + AcceptedConnection *conn = (AcceptedConnection *) parg; + + bool fRun = true; + while (true) { + if (fShutdown || !fRun) + { + conn->close(); + delete conn; + { + LOCK(cs_THREAD_RPCHANDLER); + --vnThreadsRunning[THREAD_RPCHANDLER]; + } + return; + } + map mapHeaders; + string strRequest; + + ReadHTTP(conn->stream(), mapHeaders, strRequest); + + // Check authorization + if (mapHeaders.count("authorization") == 0) + { + conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; + break; + } + if (!HTTPAuthorized(mapHeaders)) + { + printf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string().c_str()); + /* Deter brute-forcing short passwords. + If this results in a DOS the user really + shouldn't have their RPC port exposed.*/ + if (mapArgs["-rpcpassword"].size() < 20) + Sleep(250); + + conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; + break; + } + if (mapHeaders["connection"] == "close") + fRun = false; + + JSONRequest jreq; + try + { + // Parse request + Value valRequest; + if (!read_string(strRequest, valRequest)) + throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); + + string strReply; + + // singleton request + if (valRequest.type() == obj_type) { + jreq.parse(valRequest); + + Value result = tableRPC.execute(jreq.strMethod, jreq.params); + + // Send reply + strReply = JSONRPCReply(result, Value::null, jreq.id); + + // array of requests + } else if (valRequest.type() == array_type) + strReply = JSONRPCExecBatch(valRequest.get_array()); + else + throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); + + conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush; + } + catch (Object& objError) + { + ErrorReply(conn->stream(), objError, jreq.id); + break; + } + catch (std::exception& e) + { + ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); + break; + } + } + + delete conn; + { + LOCK(cs_THREAD_RPCHANDLER); + vnThreadsRunning[THREAD_RPCHANDLER]--; + } +} + +json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const +{ + // Find method + const CRPCCommand *pcmd = tableRPC[strMethod]; + if (!pcmd) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); + + // Observe safe mode + string strWarning = GetWarnings("rpc"); + if (strWarning != "" && !GetBoolArg("-disablesafemode") && + !pcmd->okSafeMode) + throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); + + try + { + // Execute + Value result; + { + if (pcmd->unlocked) + result = pcmd->actor(params, false); + else { + LOCK2(cs_main, pwalletMain->cs_wallet); + result = pcmd->actor(params, false); + } + } + return result; + } + catch (std::exception& e) + { + throw JSONRPCError(RPC_MISC_ERROR, e.what()); + } +} + + +Object CallRPC(const string& strMethod, const Array& params) +{ + if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "") + throw runtime_error(strprintf( + _("You must set rpcpassword= in the configuration file:\n%s\n" + "If the file does not exist, create it with owner-readable-only file permissions."), + GetConfigFile().string().c_str())); + + // Connect to localhost + bool fUseSSL = GetBoolArg("-rpcssl"); + asio::io_service io_service; + ssl::context context(io_service, ssl::context::sslv23); + context.set_options(ssl::context::no_sslv2); + asio::ssl::stream sslStream(io_service, context); + SSLIOStreamDevice d(sslStream, fUseSSL); + iostreams::stream< SSLIOStreamDevice > stream(d); + if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(GetDefaultRPCPort())))) + throw runtime_error("couldn't connect to server"); + + // HTTP basic authentication + string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); + map mapRequestHeaders; + mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64; + + // Send request + string strRequest = JSONRPCRequest(strMethod, params, 1); + string strPost = HTTPPost(strRequest, mapRequestHeaders); + stream << strPost << std::flush; + + // Receive reply + map mapHeaders; + string strReply; + int nStatus = ReadHTTP(stream, mapHeaders, strReply); + if (nStatus == HTTP_UNAUTHORIZED) + throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); + else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR) + throw runtime_error(strprintf("server returned HTTP error %d", nStatus)); + else if (strReply.empty()) + throw runtime_error("no response from server"); + + // Parse reply + Value valReply; + if (!read_string(strReply, valReply)) + throw runtime_error("couldn't parse reply from server"); + const Object& reply = valReply.get_obj(); + if (reply.empty()) + throw runtime_error("expected reply to have result, error and id properties"); + + return reply; +} + + + + +template +void ConvertTo(Value& value, bool fAllowNull=false) +{ + if (fAllowNull && value.type() == null_type) + return; + if (value.type() == str_type) + { + // reinterpret string as unquoted json value + Value value2; + string strJSON = value.get_str(); + if (!read_string(strJSON, value2)) + throw runtime_error(string("Error parsing JSON:")+strJSON); + ConvertTo(value2, fAllowNull); + value = value2; + } + else + { + value = value.get_value(); + } +} + +// Convert strings to command-specific RPC representation +Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams) +{ + Array params; + BOOST_FOREACH(const std::string ¶m, strParams) + params.push_back(param); + + int n = params.size(); + + // + // Special case non-string parameter types + // + if (strMethod == "stop" && n > 0) ConvertTo(params[0]); + if (strMethod == "setgenerate" && n > 0) ConvertTo(params[0]); + if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "settxfee" && n > 0) ConvertTo(params[0]); + if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo(params[1]); + if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo(params[0]); + if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo(params[0]); + if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo(params[1]); + if (strMethod == "getbalance" && n > 1) ConvertTo(params[1]); + if (strMethod == "getblock" && n > 1) ConvertTo(params[1]); + if (strMethod == "getblockbynumber" && n > 0) ConvertTo(params[0]); + if (strMethod == "getblockbynumber" && n > 1) ConvertTo(params[1]); + if (strMethod == "getblockhash" && n > 0) ConvertTo(params[0]); + if (strMethod == "move" && n > 2) ConvertTo(params[2]); + if (strMethod == "move" && n > 3) ConvertTo(params[3]); + if (strMethod == "sendfrom" && n > 2) ConvertTo(params[2]); + if (strMethod == "sendfrom" && n > 3) ConvertTo(params[3]); + if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); + if (strMethod == "listtransactions" && n > 2) ConvertTo(params[2]); + if (strMethod == "listaccounts" && n > 0) ConvertTo(params[0]); + if (strMethod == "walletpassphrase" && n > 1) ConvertTo(params[1]); + if (strMethod == "walletpassphrase" && n > 2) ConvertTo(params[2]); + if (strMethod == "getblocktemplate" && n > 0) ConvertTo(params[0]); + if (strMethod == "listsinceblock" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendmany" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendmany" && n > 2) ConvertTo(params[2]); + if (strMethod == "reservebalance" && n > 0) ConvertTo(params[0]); + if (strMethod == "reservebalance" && n > 1) ConvertTo(params[1]); + if (strMethod == "addmultisigaddress" && n > 0) ConvertTo(params[0]); + if (strMethod == "addmultisigaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "listunspent" && n > 0) ConvertTo(params[0]); + if (strMethod == "listunspent" && n > 1) ConvertTo(params[1]); + if (strMethod == "listunspent" && n > 2) ConvertTo(params[2]); + if (strMethod == "getrawtransaction" && n > 1) ConvertTo(params[1]); + if (strMethod == "createrawtransaction" && n > 0) ConvertTo(params[0]); + if (strMethod == "createrawtransaction" && n > 1) ConvertTo(params[1]); + if (strMethod == "signrawtransaction" && n > 1) ConvertTo(params[1], true); + if (strMethod == "signrawtransaction" && n > 2) ConvertTo(params[2], true); + + return params; +} + +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 strParams(&argv[2], &argv[argc]); + Array params = RPCConvertValues(strMethod, strParams); + + // Execute + Object reply = CallRPC(strMethod, params); + + // Parse reply + const Value& result = find_value(reply, "result"); + const Value& error = find_value(reply, "error"); + + if (error.type() != null_type) + { + // Error + strPrint = "error: " + write_string(error, false); + int code = find_value(error.get_obj(), "code").get_int(); + nRet = abs(code); + } + else + { + // Result + if (result.type() == null_type) + strPrint = ""; + else if (result.type() == str_type) + strPrint = result.get_str(); + else + strPrint = write_string(result, true); + } + } + catch (std::exception& e) + { + strPrint = string("error: ") + e.what(); + nRet = 87; + } + catch (...) + { + PrintException(NULL, "CommandLineRPC()"); + } + + if (strPrint != "") + { + fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str()); + } + return nRet; +} + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ +#ifdef _MSC_VER + // Turn off Microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif + setbuf(stdin, NULL); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + try + { + if (argc >= 2 && string(argv[1]) == "-server") + { + printf("server ready\n"); + ThreadRPCServer(NULL); + } + else + { + return CommandLineRPC(argc, argv); + } + } + catch (std::exception& e) { + PrintException(&e, "main()"); + } catch (...) { + PrintException(NULL, "main()"); + } + return 0; +} +#endif + +const CRPCTable tableRPC; diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h new file mode 100644 index 0000000..d6a5a5b --- /dev/null +++ b/src/bitcoinrpc.h @@ -0,0 +1,209 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 _BITCOINRPC_H_ +#define _BITCOINRPC_H_ 1 + +#include +#include +#include + +class CBlockIndex; + +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" + +#include "util.h" +#include "checkpoints.h" + +// HTTP status codes +enum HTTPStatusCode +{ + HTTP_OK = 200, + HTTP_BAD_REQUEST = 400, + HTTP_UNAUTHORIZED = 401, + HTTP_FORBIDDEN = 403, + HTTP_NOT_FOUND = 404, + HTTP_INTERNAL_SERVER_ERROR = 500, +}; + +// Bitcoin RPC error codes +enum RPCErrorCode +{ + // Standard JSON-RPC 2.0 errors + RPC_INVALID_REQUEST = -32600, + RPC_METHOD_NOT_FOUND = -32601, + RPC_INVALID_PARAMS = -32602, + RPC_INTERNAL_ERROR = -32603, + RPC_PARSE_ERROR = -32700, + + // General application defined errors + RPC_MISC_ERROR = -1, // std::exception thrown in command handling + RPC_FORBIDDEN_BY_SAFE_MODE = -2, // Server is in safe mode, and command is not allowed in safe mode + RPC_TYPE_ERROR = -3, // Unexpected type was passed as parameter + RPC_INVALID_ADDRESS_OR_KEY = -5, // Invalid address or key + RPC_OUT_OF_MEMORY = -7, // Ran out of memory during operation + RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter + RPC_DATABASE_ERROR = -20, // Database error + RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format + + // P2P client errors + RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected + RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, // Still downloading initial blocks + + // Wallet errors + RPC_WALLET_ERROR = -4, // Unspecified problem with wallet (key not found etc.) + RPC_WALLET_INSUFFICIENT_FUNDS = -6, // Not enough funds in wallet or account + RPC_WALLET_INVALID_ACCOUNT_NAME = -11, // Invalid account name + RPC_WALLET_KEYPOOL_RAN_OUT = -12, // Keypool ran out, call keypoolrefill first + RPC_WALLET_UNLOCK_NEEDED = -13, // Enter the wallet passphrase with walletpassphrase first + RPC_WALLET_PASSPHRASE_INCORRECT = -14, // The wallet passphrase entered was incorrect + RPC_WALLET_WRONG_ENC_STATE = -15, // Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) + RPC_WALLET_ENCRYPTION_FAILED = -16, // Failed to encrypt the wallet + RPC_WALLET_ALREADY_UNLOCKED = -17, // Wallet is already unlocked +}; + +json_spirit::Object JSONRPCError(int code, const std::string& message); + +void ThreadRPCServer(void* parg); +int CommandLineRPC(int argc, char *argv[]); + +/** Convert parameter values for RPC call from strings to command-specific JSON objects. */ +json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams); + +/* + Type-check arguments; throws JSONRPCError if wrong type given. Does not check that + the right number of arguments are passed, just that any passed are the correct type. + Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); +*/ +void RPCTypeCheck(const json_spirit::Array& params, + const std::list& typesExpected, bool fAllowNull=false); +/* + Check for expected keys/value types in an Object. + Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); +*/ +void RPCTypeCheck(const json_spirit::Object& o, + const std::map& typesExpected, bool fAllowNull=false); + +typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp); + +class CRPCCommand +{ +public: + std::string name; + rpcfn_type actor; + bool okSafeMode; + bool unlocked; +}; + +/** + * Bitcoin RPC command dispatcher. + */ +class CRPCTable +{ +private: + std::map mapCommands; +public: + CRPCTable(); + const CRPCCommand* operator[](std::string name) const; + std::string help(std::string name) const; + + /** + * Execute a method. + * @param method Method to execute + * @param params Array of arguments (JSON objects) + * @returns Result of the call. + * @throws an exception (json_spirit::Value) when an error happens. + */ + json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const; +}; + +extern const CRPCTable tableRPC; + +extern int64 nWalletUnlockTime; +extern int64 AmountFromValue(const json_spirit::Value& value); +extern json_spirit::Value ValueFromAmount(int64 amount); +extern double GetDifficulty(const CBlockIndex* blockindex = NULL); + +extern double GetPoWMHashPS(); +extern double GetPoSKernelPS(); + +extern std::string HexBits(unsigned int nBits); +extern std::string HelpRequiringPassphrase(); +extern void EnsureWalletIsUnlocked(); + + +extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp +extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp +extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendalert(const json_spirit::Array& params, bool fHelp); + +extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp +extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getworkex(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp); + +extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp +extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value reservebalance(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value checkwallet(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value repairwallet(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value resendtx(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value makekeypair(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value validatepubkey(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getnewpubkey(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); + +extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp +extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp); + +extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp +extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblockbynumber(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getcheckpoint(const json_spirit::Array& params, bool fHelp); + +#endif diff --git a/src/blake.c b/src/blake.c new file mode 100644 index 0000000..0650b9c --- /dev/null +++ b/src/blake.c @@ -0,0 +1,1120 @@ +/* $Id: blake.c 252 2011-06-07 17:55:14Z tp $ */ +/* + * BLAKE 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 + */ + +#include +#include +#include + +#include "sph_blake.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_BLAKE +#define SPH_SMALL_FOOTPRINT_BLAKE 1 +#endif + +#if SPH_SMALL_FOOTPRINT_BLAKE +#define SPH_COMPACT_BLAKE_32 1 +#endif + +#if SPH_64 && (SPH_SMALL_FOOTPRINT_BLAKE || !SPH_64_TRUE) +#define SPH_COMPACT_BLAKE_64 1 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +static const sph_u32 IV224[8] = { + SPH_C32(0xC1059ED8), SPH_C32(0x367CD507), + SPH_C32(0x3070DD17), SPH_C32(0xF70E5939), + SPH_C32(0xFFC00B31), SPH_C32(0x68581511), + SPH_C32(0x64F98FA7), SPH_C32(0xBEFA4FA4) +}; + +static const sph_u32 IV256[8] = { + SPH_C32(0x6A09E667), SPH_C32(0xBB67AE85), + SPH_C32(0x3C6EF372), SPH_C32(0xA54FF53A), + SPH_C32(0x510E527F), SPH_C32(0x9B05688C), + SPH_C32(0x1F83D9AB), SPH_C32(0x5BE0CD19) +}; + +#if SPH_64 + +static const sph_u64 IV384[8] = { + SPH_C64(0xCBBB9D5DC1059ED8), SPH_C64(0x629A292A367CD507), + SPH_C64(0x9159015A3070DD17), SPH_C64(0x152FECD8F70E5939), + SPH_C64(0x67332667FFC00B31), SPH_C64(0x8EB44A8768581511), + SPH_C64(0xDB0C2E0D64F98FA7), SPH_C64(0x47B5481DBEFA4FA4) +}; + +static const sph_u64 IV512[8] = { + SPH_C64(0x6A09E667F3BCC908), SPH_C64(0xBB67AE8584CAA73B), + SPH_C64(0x3C6EF372FE94F82B), SPH_C64(0xA54FF53A5F1D36F1), + SPH_C64(0x510E527FADE682D1), SPH_C64(0x9B05688C2B3E6C1F), + SPH_C64(0x1F83D9ABFB41BD6B), SPH_C64(0x5BE0CD19137E2179) +}; + +#endif + +#if SPH_COMPACT_BLAKE_32 || SPH_COMPACT_BLAKE_64 + +static const unsigned sigma[16][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } +}; + +/* + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 14 10 4 8 9 15 13 6 1 12 0 2 11 7 5 3 + 11 8 12 0 5 2 15 13 10 14 3 6 7 1 9 4 + 7 9 3 1 13 12 11 14 2 6 5 10 4 0 15 8 + 9 0 5 7 2 4 10 15 14 1 11 12 6 8 3 13 + 2 12 6 10 0 11 8 3 4 13 7 5 15 14 1 9 + 12 5 1 15 14 13 4 10 0 7 6 3 9 2 8 11 + 13 11 7 14 12 1 3 9 5 0 15 4 8 6 2 10 + 6 15 14 9 11 3 0 8 12 2 13 7 1 4 10 5 + 10 2 8 4 7 6 1 5 15 11 9 14 3 12 13 0 +*/ +#endif + +#define Z00 0 +#define Z01 1 +#define Z02 2 +#define Z03 3 +#define Z04 4 +#define Z05 5 +#define Z06 6 +#define Z07 7 +#define Z08 8 +#define Z09 9 +#define Z0A A +#define Z0B B +#define Z0C C +#define Z0D D +#define Z0E E +#define Z0F F + +#define Z10 E +#define Z11 A +#define Z12 4 +#define Z13 8 +#define Z14 9 +#define Z15 F +#define Z16 D +#define Z17 6 +#define Z18 1 +#define Z19 C +#define Z1A 0 +#define Z1B 2 +#define Z1C B +#define Z1D 7 +#define Z1E 5 +#define Z1F 3 + +#define Z20 B +#define Z21 8 +#define Z22 C +#define Z23 0 +#define Z24 5 +#define Z25 2 +#define Z26 F +#define Z27 D +#define Z28 A +#define Z29 E +#define Z2A 3 +#define Z2B 6 +#define Z2C 7 +#define Z2D 1 +#define Z2E 9 +#define Z2F 4 + +#define Z30 7 +#define Z31 9 +#define Z32 3 +#define Z33 1 +#define Z34 D +#define Z35 C +#define Z36 B +#define Z37 E +#define Z38 2 +#define Z39 6 +#define Z3A 5 +#define Z3B A +#define Z3C 4 +#define Z3D 0 +#define Z3E F +#define Z3F 8 + +#define Z40 9 +#define Z41 0 +#define Z42 5 +#define Z43 7 +#define Z44 2 +#define Z45 4 +#define Z46 A +#define Z47 F +#define Z48 E +#define Z49 1 +#define Z4A B +#define Z4B C +#define Z4C 6 +#define Z4D 8 +#define Z4E 3 +#define Z4F D + +#define Z50 2 +#define Z51 C +#define Z52 6 +#define Z53 A +#define Z54 0 +#define Z55 B +#define Z56 8 +#define Z57 3 +#define Z58 4 +#define Z59 D +#define Z5A 7 +#define Z5B 5 +#define Z5C F +#define Z5D E +#define Z5E 1 +#define Z5F 9 + +#define Z60 C +#define Z61 5 +#define Z62 1 +#define Z63 F +#define Z64 E +#define Z65 D +#define Z66 4 +#define Z67 A +#define Z68 0 +#define Z69 7 +#define Z6A 6 +#define Z6B 3 +#define Z6C 9 +#define Z6D 2 +#define Z6E 8 +#define Z6F B + +#define Z70 D +#define Z71 B +#define Z72 7 +#define Z73 E +#define Z74 C +#define Z75 1 +#define Z76 3 +#define Z77 9 +#define Z78 5 +#define Z79 0 +#define Z7A F +#define Z7B 4 +#define Z7C 8 +#define Z7D 6 +#define Z7E 2 +#define Z7F A + +#define Z80 6 +#define Z81 F +#define Z82 E +#define Z83 9 +#define Z84 B +#define Z85 3 +#define Z86 0 +#define Z87 8 +#define Z88 C +#define Z89 2 +#define Z8A D +#define Z8B 7 +#define Z8C 1 +#define Z8D 4 +#define Z8E A +#define Z8F 5 + +#define Z90 A +#define Z91 2 +#define Z92 8 +#define Z93 4 +#define Z94 7 +#define Z95 6 +#define Z96 1 +#define Z97 5 +#define Z98 F +#define Z99 B +#define Z9A 9 +#define Z9B E +#define Z9C 3 +#define Z9D C +#define Z9E D +#define Z9F 0 + +#define Mx(r, i) Mx_(Z ## r ## i) +#define Mx_(n) Mx__(n) +#define Mx__(n) M ## n + +#define CSx(r, i) CSx_(Z ## r ## i) +#define CSx_(n) CSx__(n) +#define CSx__(n) CS ## n + +#define CS0 SPH_C32(0x243F6A88) +#define CS1 SPH_C32(0x85A308D3) +#define CS2 SPH_C32(0x13198A2E) +#define CS3 SPH_C32(0x03707344) +#define CS4 SPH_C32(0xA4093822) +#define CS5 SPH_C32(0x299F31D0) +#define CS6 SPH_C32(0x082EFA98) +#define CS7 SPH_C32(0xEC4E6C89) +#define CS8 SPH_C32(0x452821E6) +#define CS9 SPH_C32(0x38D01377) +#define CSA SPH_C32(0xBE5466CF) +#define CSB SPH_C32(0x34E90C6C) +#define CSC SPH_C32(0xC0AC29B7) +#define CSD SPH_C32(0xC97C50DD) +#define CSE SPH_C32(0x3F84D5B5) +#define CSF SPH_C32(0xB5470917) + +#if SPH_COMPACT_BLAKE_32 + +static const sph_u32 CS[16] = { + SPH_C32(0x243F6A88), SPH_C32(0x85A308D3), + SPH_C32(0x13198A2E), SPH_C32(0x03707344), + SPH_C32(0xA4093822), SPH_C32(0x299F31D0), + SPH_C32(0x082EFA98), SPH_C32(0xEC4E6C89), + SPH_C32(0x452821E6), SPH_C32(0x38D01377), + SPH_C32(0xBE5466CF), SPH_C32(0x34E90C6C), + SPH_C32(0xC0AC29B7), SPH_C32(0xC97C50DD), + SPH_C32(0x3F84D5B5), SPH_C32(0xB5470917) +}; + +#endif + +#if SPH_64 + +#define CBx(r, i) CBx_(Z ## r ## i) +#define CBx_(n) CBx__(n) +#define CBx__(n) CB ## n + +#define CB0 SPH_C64(0x243F6A8885A308D3) +#define CB1 SPH_C64(0x13198A2E03707344) +#define CB2 SPH_C64(0xA4093822299F31D0) +#define CB3 SPH_C64(0x082EFA98EC4E6C89) +#define CB4 SPH_C64(0x452821E638D01377) +#define CB5 SPH_C64(0xBE5466CF34E90C6C) +#define CB6 SPH_C64(0xC0AC29B7C97C50DD) +#define CB7 SPH_C64(0x3F84D5B5B5470917) +#define CB8 SPH_C64(0x9216D5D98979FB1B) +#define CB9 SPH_C64(0xD1310BA698DFB5AC) +#define CBA SPH_C64(0x2FFD72DBD01ADFB7) +#define CBB SPH_C64(0xB8E1AFED6A267E96) +#define CBC SPH_C64(0xBA7C9045F12C7F99) +#define CBD SPH_C64(0x24A19947B3916CF7) +#define CBE SPH_C64(0x0801F2E2858EFC16) +#define CBF SPH_C64(0x636920D871574E69) + +#if SPH_COMPACT_BLAKE_64 + +static const sph_u64 CB[16] = { + SPH_C64(0x243F6A8885A308D3), SPH_C64(0x13198A2E03707344), + SPH_C64(0xA4093822299F31D0), SPH_C64(0x082EFA98EC4E6C89), + SPH_C64(0x452821E638D01377), SPH_C64(0xBE5466CF34E90C6C), + SPH_C64(0xC0AC29B7C97C50DD), SPH_C64(0x3F84D5B5B5470917), + SPH_C64(0x9216D5D98979FB1B), SPH_C64(0xD1310BA698DFB5AC), + SPH_C64(0x2FFD72DBD01ADFB7), SPH_C64(0xB8E1AFED6A267E96), + SPH_C64(0xBA7C9045F12C7F99), SPH_C64(0x24A19947B3916CF7), + SPH_C64(0x0801F2E2858EFC16), SPH_C64(0x636920D871574E69) +}; + +#endif + +#endif + +#define GS(m0, m1, c0, c1, a, b, c, d) do { \ + a = SPH_T32(a + b + (m0 ^ c1)); \ + d = SPH_ROTR32(d ^ a, 16); \ + c = SPH_T32(c + d); \ + b = SPH_ROTR32(b ^ c, 12); \ + a = SPH_T32(a + b + (m1 ^ c0)); \ + d = SPH_ROTR32(d ^ a, 8); \ + c = SPH_T32(c + d); \ + b = SPH_ROTR32(b ^ c, 7); \ + } while (0) + +#if SPH_COMPACT_BLAKE_32 + +#define ROUND_S(r) do { \ + GS(M[sigma[r][0x0]], M[sigma[r][0x1]], \ + CS[sigma[r][0x0]], CS[sigma[r][0x1]], V0, V4, V8, VC); \ + GS(M[sigma[r][0x2]], M[sigma[r][0x3]], \ + CS[sigma[r][0x2]], CS[sigma[r][0x3]], V1, V5, V9, VD); \ + GS(M[sigma[r][0x4]], M[sigma[r][0x5]], \ + CS[sigma[r][0x4]], CS[sigma[r][0x5]], V2, V6, VA, VE); \ + GS(M[sigma[r][0x6]], M[sigma[r][0x7]], \ + CS[sigma[r][0x6]], CS[sigma[r][0x7]], V3, V7, VB, VF); \ + GS(M[sigma[r][0x8]], M[sigma[r][0x9]], \ + CS[sigma[r][0x8]], CS[sigma[r][0x9]], V0, V5, VA, VF); \ + GS(M[sigma[r][0xA]], M[sigma[r][0xB]], \ + CS[sigma[r][0xA]], CS[sigma[r][0xB]], V1, V6, VB, VC); \ + GS(M[sigma[r][0xC]], M[sigma[r][0xD]], \ + CS[sigma[r][0xC]], CS[sigma[r][0xD]], V2, V7, V8, VD); \ + GS(M[sigma[r][0xE]], M[sigma[r][0xF]], \ + CS[sigma[r][0xE]], CS[sigma[r][0xF]], V3, V4, V9, VE); \ + } while (0) + +#else + +#define ROUND_S(r) do { \ + GS(Mx(r, 0), Mx(r, 1), CSx(r, 0), CSx(r, 1), V0, V4, V8, VC); \ + GS(Mx(r, 2), Mx(r, 3), CSx(r, 2), CSx(r, 3), V1, V5, V9, VD); \ + GS(Mx(r, 4), Mx(r, 5), CSx(r, 4), CSx(r, 5), V2, V6, VA, VE); \ + GS(Mx(r, 6), Mx(r, 7), CSx(r, 6), CSx(r, 7), V3, V7, VB, VF); \ + GS(Mx(r, 8), Mx(r, 9), CSx(r, 8), CSx(r, 9), V0, V5, VA, VF); \ + GS(Mx(r, A), Mx(r, B), CSx(r, A), CSx(r, B), V1, V6, VB, VC); \ + GS(Mx(r, C), Mx(r, D), CSx(r, C), CSx(r, D), V2, V7, V8, VD); \ + GS(Mx(r, E), Mx(r, F), CSx(r, E), CSx(r, F), V3, V4, V9, VE); \ + } while (0) + +#endif + +#if SPH_64 + +#define GB(m0, m1, c0, c1, a, b, c, d) do { \ + a = SPH_T64(a + b + (m0 ^ c1)); \ + d = SPH_ROTR64(d ^ a, 32); \ + c = SPH_T64(c + d); \ + b = SPH_ROTR64(b ^ c, 25); \ + a = SPH_T64(a + b + (m1 ^ c0)); \ + d = SPH_ROTR64(d ^ a, 16); \ + c = SPH_T64(c + d); \ + b = SPH_ROTR64(b ^ c, 11); \ + } while (0) + +#if SPH_COMPACT_BLAKE_64 + +#define ROUND_B(r) do { \ + GB(M[sigma[r][0x0]], M[sigma[r][0x1]], \ + CB[sigma[r][0x0]], CB[sigma[r][0x1]], V0, V4, V8, VC); \ + GB(M[sigma[r][0x2]], M[sigma[r][0x3]], \ + CB[sigma[r][0x2]], CB[sigma[r][0x3]], V1, V5, V9, VD); \ + GB(M[sigma[r][0x4]], M[sigma[r][0x5]], \ + CB[sigma[r][0x4]], CB[sigma[r][0x5]], V2, V6, VA, VE); \ + GB(M[sigma[r][0x6]], M[sigma[r][0x7]], \ + CB[sigma[r][0x6]], CB[sigma[r][0x7]], V3, V7, VB, VF); \ + GB(M[sigma[r][0x8]], M[sigma[r][0x9]], \ + CB[sigma[r][0x8]], CB[sigma[r][0x9]], V0, V5, VA, VF); \ + GB(M[sigma[r][0xA]], M[sigma[r][0xB]], \ + CB[sigma[r][0xA]], CB[sigma[r][0xB]], V1, V6, VB, VC); \ + GB(M[sigma[r][0xC]], M[sigma[r][0xD]], \ + CB[sigma[r][0xC]], CB[sigma[r][0xD]], V2, V7, V8, VD); \ + GB(M[sigma[r][0xE]], M[sigma[r][0xF]], \ + CB[sigma[r][0xE]], CB[sigma[r][0xF]], V3, V4, V9, VE); \ + } while (0) + +#else + +#define ROUND_B(r) do { \ + GB(Mx(r, 0), Mx(r, 1), CBx(r, 0), CBx(r, 1), V0, V4, V8, VC); \ + GB(Mx(r, 2), Mx(r, 3), CBx(r, 2), CBx(r, 3), V1, V5, V9, VD); \ + GB(Mx(r, 4), Mx(r, 5), CBx(r, 4), CBx(r, 5), V2, V6, VA, VE); \ + GB(Mx(r, 6), Mx(r, 7), CBx(r, 6), CBx(r, 7), V3, V7, VB, VF); \ + GB(Mx(r, 8), Mx(r, 9), CBx(r, 8), CBx(r, 9), V0, V5, VA, VF); \ + GB(Mx(r, A), Mx(r, B), CBx(r, A), CBx(r, B), V1, V6, VB, VC); \ + GB(Mx(r, C), Mx(r, D), CBx(r, C), CBx(r, D), V2, V7, V8, VD); \ + GB(Mx(r, E), Mx(r, F), CBx(r, E), CBx(r, F), V3, V4, V9, VE); \ + } while (0) + +#endif + +#endif + +#define DECL_STATE32 \ + sph_u32 H0, H1, H2, H3, H4, H5, H6, H7; \ + sph_u32 S0, S1, S2, S3, T0, T1; + +#define READ_STATE32(state) do { \ + H0 = (state)->H[0]; \ + H1 = (state)->H[1]; \ + H2 = (state)->H[2]; \ + H3 = (state)->H[3]; \ + H4 = (state)->H[4]; \ + H5 = (state)->H[5]; \ + H6 = (state)->H[6]; \ + H7 = (state)->H[7]; \ + S0 = (state)->S[0]; \ + S1 = (state)->S[1]; \ + S2 = (state)->S[2]; \ + S3 = (state)->S[3]; \ + T0 = (state)->T0; \ + T1 = (state)->T1; \ + } while (0) + +#define WRITE_STATE32(state) do { \ + (state)->H[0] = H0; \ + (state)->H[1] = H1; \ + (state)->H[2] = H2; \ + (state)->H[3] = H3; \ + (state)->H[4] = H4; \ + (state)->H[5] = H5; \ + (state)->H[6] = H6; \ + (state)->H[7] = H7; \ + (state)->S[0] = S0; \ + (state)->S[1] = S1; \ + (state)->S[2] = S2; \ + (state)->S[3] = S3; \ + (state)->T0 = T0; \ + (state)->T1 = T1; \ + } while (0) + +#if SPH_COMPACT_BLAKE_32 + +#define COMPRESS32 do { \ + sph_u32 M[16]; \ + sph_u32 V0, V1, V2, V3, V4, V5, V6, V7; \ + sph_u32 V8, V9, VA, VB, VC, VD, VE, VF; \ + unsigned r; \ + V0 = H0; \ + V1 = H1; \ + V2 = H2; \ + V3 = H3; \ + V4 = H4; \ + V5 = H5; \ + V6 = H6; \ + V7 = H7; \ + V8 = S0 ^ CS0; \ + V9 = S1 ^ CS1; \ + VA = S2 ^ CS2; \ + VB = S3 ^ CS3; \ + VC = T0 ^ CS4; \ + VD = T0 ^ CS5; \ + VE = T1 ^ CS6; \ + VF = T1 ^ CS7; \ + M[0x0] = sph_dec32be_aligned(buf + 0); \ + M[0x1] = sph_dec32be_aligned(buf + 4); \ + M[0x2] = sph_dec32be_aligned(buf + 8); \ + M[0x3] = sph_dec32be_aligned(buf + 12); \ + M[0x4] = sph_dec32be_aligned(buf + 16); \ + M[0x5] = sph_dec32be_aligned(buf + 20); \ + M[0x6] = sph_dec32be_aligned(buf + 24); \ + M[0x7] = sph_dec32be_aligned(buf + 28); \ + M[0x8] = sph_dec32be_aligned(buf + 32); \ + M[0x9] = sph_dec32be_aligned(buf + 36); \ + M[0xA] = sph_dec32be_aligned(buf + 40); \ + M[0xB] = sph_dec32be_aligned(buf + 44); \ + M[0xC] = sph_dec32be_aligned(buf + 48); \ + M[0xD] = sph_dec32be_aligned(buf + 52); \ + M[0xE] = sph_dec32be_aligned(buf + 56); \ + M[0xF] = sph_dec32be_aligned(buf + 60); \ + for (r = 0; r < 14; r ++) \ + ROUND_S(r); \ + H0 ^= S0 ^ V0 ^ V8; \ + H1 ^= S1 ^ V1 ^ V9; \ + H2 ^= S2 ^ V2 ^ VA; \ + H3 ^= S3 ^ V3 ^ VB; \ + H4 ^= S0 ^ V4 ^ VC; \ + H5 ^= S1 ^ V5 ^ VD; \ + H6 ^= S2 ^ V6 ^ VE; \ + H7 ^= S3 ^ V7 ^ VF; \ + } while (0) + +#else + +#define COMPRESS32 do { \ + sph_u32 M0, M1, M2, M3, M4, M5, M6, M7; \ + sph_u32 M8, M9, MA, MB, MC, MD, ME, MF; \ + sph_u32 V0, V1, V2, V3, V4, V5, V6, V7; \ + sph_u32 V8, V9, VA, VB, VC, VD, VE, VF; \ + V0 = H0; \ + V1 = H1; \ + V2 = H2; \ + V3 = H3; \ + V4 = H4; \ + V5 = H5; \ + V6 = H6; \ + V7 = H7; \ + V8 = S0 ^ CS0; \ + V9 = S1 ^ CS1; \ + VA = S2 ^ CS2; \ + VB = S3 ^ CS3; \ + VC = T0 ^ CS4; \ + VD = T0 ^ CS5; \ + VE = T1 ^ CS6; \ + VF = T1 ^ CS7; \ + M0 = sph_dec32be_aligned(buf + 0); \ + M1 = sph_dec32be_aligned(buf + 4); \ + M2 = sph_dec32be_aligned(buf + 8); \ + M3 = sph_dec32be_aligned(buf + 12); \ + M4 = sph_dec32be_aligned(buf + 16); \ + M5 = sph_dec32be_aligned(buf + 20); \ + M6 = sph_dec32be_aligned(buf + 24); \ + M7 = sph_dec32be_aligned(buf + 28); \ + M8 = sph_dec32be_aligned(buf + 32); \ + M9 = sph_dec32be_aligned(buf + 36); \ + MA = sph_dec32be_aligned(buf + 40); \ + MB = sph_dec32be_aligned(buf + 44); \ + MC = sph_dec32be_aligned(buf + 48); \ + MD = sph_dec32be_aligned(buf + 52); \ + ME = sph_dec32be_aligned(buf + 56); \ + MF = sph_dec32be_aligned(buf + 60); \ + ROUND_S(0); \ + ROUND_S(1); \ + ROUND_S(2); \ + ROUND_S(3); \ + ROUND_S(4); \ + ROUND_S(5); \ + ROUND_S(6); \ + ROUND_S(7); \ + ROUND_S(8); \ + ROUND_S(9); \ + ROUND_S(0); \ + ROUND_S(1); \ + ROUND_S(2); \ + ROUND_S(3); \ + H0 ^= S0 ^ V0 ^ V8; \ + H1 ^= S1 ^ V1 ^ V9; \ + H2 ^= S2 ^ V2 ^ VA; \ + H3 ^= S3 ^ V3 ^ VB; \ + H4 ^= S0 ^ V4 ^ VC; \ + H5 ^= S1 ^ V5 ^ VD; \ + H6 ^= S2 ^ V6 ^ VE; \ + H7 ^= S3 ^ V7 ^ VF; \ + } while (0) + +#endif + +#if SPH_64 + +#define DECL_STATE64 \ + sph_u64 H0, H1, H2, H3, H4, H5, H6, H7; \ + sph_u64 S0, S1, S2, S3, T0, T1; + +#define READ_STATE64(state) do { \ + H0 = (state)->H[0]; \ + H1 = (state)->H[1]; \ + H2 = (state)->H[2]; \ + H3 = (state)->H[3]; \ + H4 = (state)->H[4]; \ + H5 = (state)->H[5]; \ + H6 = (state)->H[6]; \ + H7 = (state)->H[7]; \ + S0 = (state)->S[0]; \ + S1 = (state)->S[1]; \ + S2 = (state)->S[2]; \ + S3 = (state)->S[3]; \ + T0 = (state)->T0; \ + T1 = (state)->T1; \ + } while (0) + +#define WRITE_STATE64(state) do { \ + (state)->H[0] = H0; \ + (state)->H[1] = H1; \ + (state)->H[2] = H2; \ + (state)->H[3] = H3; \ + (state)->H[4] = H4; \ + (state)->H[5] = H5; \ + (state)->H[6] = H6; \ + (state)->H[7] = H7; \ + (state)->S[0] = S0; \ + (state)->S[1] = S1; \ + (state)->S[2] = S2; \ + (state)->S[3] = S3; \ + (state)->T0 = T0; \ + (state)->T1 = T1; \ + } while (0) + +#if SPH_COMPACT_BLAKE_64 + +#define COMPRESS64 do { \ + sph_u64 M[16]; \ + sph_u64 V0, V1, V2, V3, V4, V5, V6, V7; \ + sph_u64 V8, V9, VA, VB, VC, VD, VE, VF; \ + unsigned r; \ + V0 = H0; \ + V1 = H1; \ + V2 = H2; \ + V3 = H3; \ + V4 = H4; \ + V5 = H5; \ + V6 = H6; \ + V7 = H7; \ + V8 = S0 ^ CB0; \ + V9 = S1 ^ CB1; \ + VA = S2 ^ CB2; \ + VB = S3 ^ CB3; \ + VC = T0 ^ CB4; \ + VD = T0 ^ CB5; \ + VE = T1 ^ CB6; \ + VF = T1 ^ CB7; \ + M[0x0] = sph_dec64be_aligned(buf + 0); \ + M[0x1] = sph_dec64be_aligned(buf + 8); \ + M[0x2] = sph_dec64be_aligned(buf + 16); \ + M[0x3] = sph_dec64be_aligned(buf + 24); \ + M[0x4] = sph_dec64be_aligned(buf + 32); \ + M[0x5] = sph_dec64be_aligned(buf + 40); \ + M[0x6] = sph_dec64be_aligned(buf + 48); \ + M[0x7] = sph_dec64be_aligned(buf + 56); \ + M[0x8] = sph_dec64be_aligned(buf + 64); \ + M[0x9] = sph_dec64be_aligned(buf + 72); \ + M[0xA] = sph_dec64be_aligned(buf + 80); \ + M[0xB] = sph_dec64be_aligned(buf + 88); \ + M[0xC] = sph_dec64be_aligned(buf + 96); \ + M[0xD] = sph_dec64be_aligned(buf + 104); \ + M[0xE] = sph_dec64be_aligned(buf + 112); \ + M[0xF] = sph_dec64be_aligned(buf + 120); \ + for (r = 0; r < 16; r ++) \ + ROUND_B(r); \ + H0 ^= S0 ^ V0 ^ V8; \ + H1 ^= S1 ^ V1 ^ V9; \ + H2 ^= S2 ^ V2 ^ VA; \ + H3 ^= S3 ^ V3 ^ VB; \ + H4 ^= S0 ^ V4 ^ VC; \ + H5 ^= S1 ^ V5 ^ VD; \ + H6 ^= S2 ^ V6 ^ VE; \ + H7 ^= S3 ^ V7 ^ VF; \ + } while (0) + +#else + +#define COMPRESS64 do { \ + sph_u64 M0, M1, M2, M3, M4, M5, M6, M7; \ + sph_u64 M8, M9, MA, MB, MC, MD, ME, MF; \ + sph_u64 V0, V1, V2, V3, V4, V5, V6, V7; \ + sph_u64 V8, V9, VA, VB, VC, VD, VE, VF; \ + V0 = H0; \ + V1 = H1; \ + V2 = H2; \ + V3 = H3; \ + V4 = H4; \ + V5 = H5; \ + V6 = H6; \ + V7 = H7; \ + V8 = S0 ^ CB0; \ + V9 = S1 ^ CB1; \ + VA = S2 ^ CB2; \ + VB = S3 ^ CB3; \ + VC = T0 ^ CB4; \ + VD = T0 ^ CB5; \ + VE = T1 ^ CB6; \ + VF = T1 ^ CB7; \ + M0 = sph_dec64be_aligned(buf + 0); \ + M1 = sph_dec64be_aligned(buf + 8); \ + M2 = sph_dec64be_aligned(buf + 16); \ + M3 = sph_dec64be_aligned(buf + 24); \ + M4 = sph_dec64be_aligned(buf + 32); \ + M5 = sph_dec64be_aligned(buf + 40); \ + M6 = sph_dec64be_aligned(buf + 48); \ + M7 = sph_dec64be_aligned(buf + 56); \ + M8 = sph_dec64be_aligned(buf + 64); \ + M9 = sph_dec64be_aligned(buf + 72); \ + MA = sph_dec64be_aligned(buf + 80); \ + MB = sph_dec64be_aligned(buf + 88); \ + MC = sph_dec64be_aligned(buf + 96); \ + MD = sph_dec64be_aligned(buf + 104); \ + ME = sph_dec64be_aligned(buf + 112); \ + MF = sph_dec64be_aligned(buf + 120); \ + ROUND_B(0); \ + ROUND_B(1); \ + ROUND_B(2); \ + ROUND_B(3); \ + ROUND_B(4); \ + ROUND_B(5); \ + ROUND_B(6); \ + ROUND_B(7); \ + ROUND_B(8); \ + ROUND_B(9); \ + ROUND_B(0); \ + ROUND_B(1); \ + ROUND_B(2); \ + ROUND_B(3); \ + ROUND_B(4); \ + ROUND_B(5); \ + H0 ^= S0 ^ V0 ^ V8; \ + H1 ^= S1 ^ V1 ^ V9; \ + H2 ^= S2 ^ V2 ^ VA; \ + H3 ^= S3 ^ V3 ^ VB; \ + H4 ^= S0 ^ V4 ^ VC; \ + H5 ^= S1 ^ V5 ^ VD; \ + H6 ^= S2 ^ V6 ^ VE; \ + H7 ^= S3 ^ V7 ^ VF; \ + } while (0) + +#endif + +#endif + +static const sph_u32 salt_zero_small[4] = { 0, 0, 0, 0 }; + +static void +blake32_init(sph_blake_small_context *sc, + const sph_u32 *iv, const sph_u32 *salt) +{ + memcpy(sc->H, iv, 8 * sizeof(sph_u32)); + memcpy(sc->S, salt, 4 * sizeof(sph_u32)); + sc->T0 = sc->T1 = 0; + sc->ptr = 0; +} + +static void +blake32(sph_blake_small_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE32 + + buf = sc->buf; + ptr = sc->ptr; + if (len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + READ_STATE32(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) { + if ((T0 = SPH_T32(T0 + 512)) < 512) + T1 = SPH_T32(T1 + 1); + COMPRESS32; + ptr = 0; + } + } + WRITE_STATE32(sc); + sc->ptr = ptr; +} + +static void +blake32_close(sph_blake_small_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_size_w32) +{ + union { + unsigned char buf[64]; + sph_u32 dummy; + } u; + size_t ptr, k; + unsigned bit_len; + unsigned z; + sph_u32 th, tl; + unsigned char *out; + + ptr = sc->ptr; + bit_len = ((unsigned)ptr << 3) + n; + z = 0x80 >> n; + u.buf[ptr] = ((ub & -z) | z) & 0xFF; + tl = sc->T0 + bit_len; + th = sc->T1; + if (ptr == 0 && n == 0) { + sc->T0 = SPH_C32(0xFFFFFE00); + sc->T1 = SPH_C32(0xFFFFFFFF); + } else if (sc->T0 == 0) { + sc->T0 = SPH_C32(0xFFFFFE00) + bit_len; + sc->T1 = SPH_T32(sc->T1 - 1); + } else { + sc->T0 -= 512 - bit_len; + } + if (bit_len <= 446) { + memset(u.buf + ptr + 1, 0, 55 - ptr); + if (out_size_w32 == 8) + u.buf[55] |= 1; + sph_enc32be_aligned(u.buf + 56, th); + sph_enc32be_aligned(u.buf + 60, tl); + blake32(sc, u.buf + ptr, 64 - ptr); + } else { + memset(u.buf + ptr + 1, 0, 63 - ptr); + blake32(sc, u.buf + ptr, 64 - ptr); + sc->T0 = SPH_C32(0xFFFFFE00); + sc->T1 = SPH_C32(0xFFFFFFFF); + memset(u.buf, 0, 56); + if (out_size_w32 == 8) + u.buf[55] = 1; + sph_enc32be_aligned(u.buf + 56, th); + sph_enc32be_aligned(u.buf + 60, tl); + blake32(sc, u.buf, 64); + } + out = dst; + for (k = 0; k < out_size_w32; k ++) + sph_enc32be(out + (k << 2), sc->H[k]); +} + +#if SPH_64 + +static const sph_u64 salt_zero_big[4] = { 0, 0, 0, 0 }; + +static void +blake64_init(sph_blake_big_context *sc, + const sph_u64 *iv, const sph_u64 *salt) +{ + memcpy(sc->H, iv, 8 * sizeof(sph_u64)); + memcpy(sc->S, salt, 4 * sizeof(sph_u64)); + sc->T0 = sc->T1 = 0; + sc->ptr = 0; +} + +static void +blake64(sph_blake_big_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE64 + + buf = sc->buf; + ptr = sc->ptr; + if (len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + READ_STATE64(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) { + if ((T0 = SPH_T64(T0 + 1024)) < 1024) + T1 = SPH_T64(T1 + 1); + COMPRESS64; + ptr = 0; + } + } + WRITE_STATE64(sc); + sc->ptr = ptr; +} + +static void +blake64_close(sph_blake_big_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_size_w64) +{ + union { + unsigned char buf[128]; + sph_u64 dummy; + } u; + size_t ptr, k; + unsigned bit_len; + unsigned z; + sph_u64 th, tl; + unsigned char *out; + + ptr = sc->ptr; + bit_len = ((unsigned)ptr << 3) + n; + z = 0x80 >> n; + u.buf[ptr] = ((ub & -z) | z) & 0xFF; + tl = sc->T0 + bit_len; + th = sc->T1; + if (ptr == 0 && n == 0) { + sc->T0 = SPH_C64(0xFFFFFFFFFFFFFC00); + sc->T1 = SPH_C64(0xFFFFFFFFFFFFFFFF); + } else if (sc->T0 == 0) { + sc->T0 = SPH_C64(0xFFFFFFFFFFFFFC00) + bit_len; + sc->T1 = SPH_T64(sc->T1 - 1); + } else { + sc->T0 -= 1024 - bit_len; + } + if (bit_len <= 894) { + memset(u.buf + ptr + 1, 0, 111 - ptr); + if (out_size_w64 == 8) + u.buf[111] |= 1; + sph_enc64be_aligned(u.buf + 112, th); + sph_enc64be_aligned(u.buf + 120, tl); + blake64(sc, u.buf + ptr, 128 - ptr); + } else { + memset(u.buf + ptr + 1, 0, 127 - ptr); + blake64(sc, u.buf + ptr, 128 - ptr); + sc->T0 = SPH_C64(0xFFFFFFFFFFFFFC00); + sc->T1 = SPH_C64(0xFFFFFFFFFFFFFFFF); + memset(u.buf, 0, 112); + if (out_size_w64 == 8) + u.buf[111] = 1; + sph_enc64be_aligned(u.buf + 112, th); + sph_enc64be_aligned(u.buf + 120, tl); + blake64(sc, u.buf, 128); + } + out = dst; + for (k = 0; k < out_size_w64; k ++) + sph_enc64be(out + (k << 3), sc->H[k]); +} + +#endif + +/* see sph_blake.h */ +void +sph_blake224_init(void *cc) +{ + blake32_init(cc, IV224, salt_zero_small); +} + +/* see sph_blake.h */ +void +sph_blake224(void *cc, const void *data, size_t len) +{ + blake32(cc, data, len); +} + +/* see sph_blake.h */ +void +sph_blake224_close(void *cc, void *dst) +{ + sph_blake224_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_blake.h */ +void +sph_blake224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + blake32_close(cc, ub, n, dst, 7); + sph_blake224_init(cc); +} + +/* see sph_blake.h */ +void +sph_blake256_init(void *cc) +{ + blake32_init(cc, IV256, salt_zero_small); +} + +/* see sph_blake.h */ +void +sph_blake256(void *cc, const void *data, size_t len) +{ + blake32(cc, data, len); +} + +/* see sph_blake.h */ +void +sph_blake256_close(void *cc, void *dst) +{ + sph_blake256_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_blake.h */ +void +sph_blake256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + blake32_close(cc, ub, n, dst, 8); + sph_blake256_init(cc); +} + +#if SPH_64 + +/* see sph_blake.h */ +void +sph_blake384_init(void *cc) +{ + blake64_init(cc, IV384, salt_zero_big); +} + +/* see sph_blake.h */ +void +sph_blake384(void *cc, const void *data, size_t len) +{ + blake64(cc, data, len); +} + +/* see sph_blake.h */ +void +sph_blake384_close(void *cc, void *dst) +{ + sph_blake384_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_blake.h */ +void +sph_blake384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + blake64_close(cc, ub, n, dst, 6); + sph_blake384_init(cc); +} + +/* see sph_blake.h */ +void +sph_blake512_init(void *cc) +{ + blake64_init(cc, IV512, salt_zero_big); +} + +/* see sph_blake.h */ +void +sph_blake512(void *cc, const void *data, size_t len) +{ + blake64(cc, data, len); +} + +/* see sph_blake.h */ +void +sph_blake512_close(void *cc, void *dst) +{ + sph_blake512_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_blake.h */ +void +sph_blake512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + blake64_close(cc, ub, n, dst, 8); + sph_blake512_init(cc); +} + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/src/bmw.c b/src/bmw.c new file mode 100644 index 0000000..b89a881 --- /dev/null +++ b/src/bmw.c @@ -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 + */ + +#include +#include +#include + +#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 diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp new file mode 100644 index 0000000..ef6eea5 --- /dev/null +++ b/src/checkpoints.cpp @@ -0,0 +1,443 @@ +// Copyright (c) 2009-2012 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 // for 'map_list_of()' +#include + +#include "checkpoints.h" + +#include "db.h" +#include "main.h" +#include "uint256.h" + +namespace Checkpoints +{ + typedef std::map MapCheckpoints; + + // + // 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 MapCheckpoints mapCheckpoints = + boost::assign::map_list_of + ( 0, hashGenesisBlockOfficial ) + ( 10002, uint256("0x00000000ac0c0b0e623f420f43fa7d4e024c70cdd6cef8ed3bcafec94d4f3bf7")) + ( 25005, uint256("0x0000000049d5446d88868977d67ef7ac25a4ef945c9f24ba2fcba17a35b3f35a")) + ( 50012, uint256("0x000000005a90fdce82e6093a0db04d267385799c5b0670b0b8d3c09a808d57c5")) + ( 75003, uint256("0x0000000068509ed3e47cf74b7f92bcd732dd4c9461a9520c18da3cd0f9257049")) + ( 100000, uint256("0x0000000007b889e033e959968271781833fab49d764492b7f00cd8cf6648b82b")) + ( 125004, uint256("0x0000000015669b8a67da27948f300595ebe5cd3b00c6b35f863a2455481eb83c")) + ( 150000, uint256("0x000000000350df6e9f670a8612136931fcff5dd7ee8f3f1b33b0fd7ee4c093d6")) + ; + + static MapCheckpoints mapCheckpointsTestnet = + boost::assign::map_list_of + ( 0, hashGenesisBlockTestNet ) + + ; + + bool CheckHardened(int nHeight, const uint256& hash) + { + MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints); + + MapCheckpoints::const_iterator i = checkpoints.find(nHeight); + if (i == checkpoints.end()) return true; + return hash == i->second; + } + + int GetTotalBlocksEstimate() + { + MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints); + + return checkpoints.rbegin()->first; + } + + CBlockIndex* GetLastCheckpoint(const std::map& mapBlockIndex) + { + MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints); + + BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints) + { + const uint256& hash = i.second; + std::map::const_iterator t = mapBlockIndex.find(hash); + if (t != mapBlockIndex.end()) + return t->second; + } + return NULL; + } + + // ppcoin: synchronized checkpoint (centrally broadcasted) + uint256 hashSyncCheckpoint = 0; + uint256 hashPendingCheckpoint = 0; + CSyncCheckpoint checkpointMessage; + CSyncCheckpoint checkpointMessagePending; + uint256 hashInvalidCheckpoint = 0; + CCriticalSection cs_hashSyncCheckpoint; + + // ppcoin: get last synchronized checkpoint + CBlockIndex* GetLastSyncCheckpoint() + { + LOCK(cs_hashSyncCheckpoint); + if (!mapBlockIndex.count(hashSyncCheckpoint)) + error("GetSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString().c_str()); + else + return mapBlockIndex[hashSyncCheckpoint]; + return NULL; + } + + // ppcoin: only descendant of current sync-checkpoint is allowed + bool ValidateSyncCheckpoint(uint256 hashCheckpoint) + { + if (!mapBlockIndex.count(hashSyncCheckpoint)) + return error("ValidateSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString().c_str()); + if (!mapBlockIndex.count(hashCheckpoint)) + return error("ValidateSyncCheckpoint: block index missing for received sync-checkpoint %s", hashCheckpoint.ToString().c_str()); + + CBlockIndex* pindexSyncCheckpoint = mapBlockIndex[hashSyncCheckpoint]; + CBlockIndex* pindexCheckpointRecv = mapBlockIndex[hashCheckpoint]; + + if (pindexCheckpointRecv->nHeight <= pindexSyncCheckpoint->nHeight) + { + // Received an older checkpoint, trace back from current checkpoint + // to the same height of the received checkpoint to verify + // that current checkpoint should be a descendant block + CBlockIndex* pindex = pindexSyncCheckpoint; + while (pindex->nHeight > pindexCheckpointRecv->nHeight) + if (!(pindex = pindex->pprev)) + return error("ValidateSyncCheckpoint: pprev1 null - block index structure failure"); + if (pindex->GetBlockHash() != hashCheckpoint) + { + hashInvalidCheckpoint = hashCheckpoint; + return error("ValidateSyncCheckpoint: new sync-checkpoint %s is conflicting with current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str()); + } + return false; // ignore older checkpoint + } + + // Received checkpoint should be a descendant block of the current + // checkpoint. Trace back to the same height of current checkpoint + // to verify. + CBlockIndex* pindex = pindexCheckpointRecv; + while (pindex->nHeight > pindexSyncCheckpoint->nHeight) + if (!(pindex = pindex->pprev)) + return error("ValidateSyncCheckpoint: pprev2 null - block index structure failure"); + if (pindex->GetBlockHash() != hashSyncCheckpoint) + { + hashInvalidCheckpoint = hashCheckpoint; + return error("ValidateSyncCheckpoint: new sync-checkpoint %s is not a descendant of current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str()); + } + return true; + } + + bool WriteSyncCheckpoint(const uint256& hashCheckpoint) + { + CTxDB txdb; + txdb.TxnBegin(); + if (!txdb.WriteSyncCheckpoint(hashCheckpoint)) + { + txdb.TxnAbort(); + return error("WriteSyncCheckpoint(): failed to write to db sync checkpoint %s", hashCheckpoint.ToString().c_str()); + } + if (!txdb.TxnCommit()) + return error("WriteSyncCheckpoint(): failed to commit to db sync checkpoint %s", hashCheckpoint.ToString().c_str()); + txdb.Close(); + + Checkpoints::hashSyncCheckpoint = hashCheckpoint; + return true; + } + + bool AcceptPendingSyncCheckpoint() + { + LOCK(cs_hashSyncCheckpoint); + if (hashPendingCheckpoint != 0 && mapBlockIndex.count(hashPendingCheckpoint)) + { + if (!ValidateSyncCheckpoint(hashPendingCheckpoint)) + { + hashPendingCheckpoint = 0; + checkpointMessagePending.SetNull(); + return false; + } + + CTxDB txdb; + CBlockIndex* pindexCheckpoint = mapBlockIndex[hashPendingCheckpoint]; + if (!pindexCheckpoint->IsInMainChain()) + { + CBlock block; + if (!block.ReadFromDisk(pindexCheckpoint)) + return error("AcceptPendingSyncCheckpoint: ReadFromDisk failed for sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); + if (!block.SetBestChain(txdb, pindexCheckpoint)) + { + hashInvalidCheckpoint = hashPendingCheckpoint; + return error("AcceptPendingSyncCheckpoint: SetBestChain failed for sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); + } + } + txdb.Close(); + + if (!WriteSyncCheckpoint(hashPendingCheckpoint)) + return error("AcceptPendingSyncCheckpoint(): failed to write sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); + hashPendingCheckpoint = 0; + checkpointMessage = checkpointMessagePending; + checkpointMessagePending.SetNull(); + printf("AcceptPendingSyncCheckpoint : sync-checkpoint at %s\n", hashSyncCheckpoint.ToString().c_str()); + // relay the checkpoint + if (!checkpointMessage.IsNull()) + { + BOOST_FOREACH(CNode* pnode, vNodes) + checkpointMessage.RelayTo(pnode); + } + return true; + } + return false; + } + + // Automatically select a suitable sync-checkpoint + uint256 AutoSelectSyncCheckpoint() + { + // Proof-of-work blocks are immediately checkpointed + // to defend against 51% attack which rejects other miners block + + // Select the last proof-of-work block + const CBlockIndex *pindex = GetLastBlockIndex(pindexBest, false); + // Search forward for a block within max span and maturity window + while (pindex->pnext && (pindex->GetBlockTime() + CHECKPOINT_MAX_SPAN <= pindexBest->GetBlockTime() || pindex->nHeight + std::min(6, nCoinbaseMaturity - 20) <= pindexBest->nHeight)) + pindex = pindex->pnext; + return pindex->GetBlockHash(); + } + + // Check against synchronized checkpoint + bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev) + { + if (fTestNet) return true; // Testnet has no checkpoints + int nHeight = pindexPrev->nHeight + 1; + + LOCK(cs_hashSyncCheckpoint); + // sync-checkpoint should always be accepted block + assert(mapBlockIndex.count(hashSyncCheckpoint)); + const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint]; + + if (nHeight > pindexSync->nHeight) + { + // trace back to same height as sync-checkpoint + const CBlockIndex* pindex = pindexPrev; + while (pindex->nHeight > pindexSync->nHeight) + if (!(pindex = pindex->pprev)) + return error("CheckSync: pprev null - block index structure failure"); + if (pindex->nHeight < pindexSync->nHeight || pindex->GetBlockHash() != hashSyncCheckpoint) + return false; // only descendant of sync-checkpoint can pass check + } + if (nHeight == pindexSync->nHeight && hashBlock != hashSyncCheckpoint) + return false; // same height with sync-checkpoint + if (nHeight < pindexSync->nHeight && !mapBlockIndex.count(hashBlock)) + return false; // lower height than sync-checkpoint + return true; + } + + bool WantedByPendingSyncCheckpoint(uint256 hashBlock) + { + LOCK(cs_hashSyncCheckpoint); + if (hashPendingCheckpoint == 0) + return false; + if (hashBlock == hashPendingCheckpoint) + return true; + if (mapOrphanBlocks.count(hashPendingCheckpoint) + && hashBlock == WantedByOrphan(mapOrphanBlocks[hashPendingCheckpoint])) + return true; + return false; + } + + // ppcoin: reset synchronized checkpoint to last hardened checkpoint + bool ResetSyncCheckpoint() + { + LOCK(cs_hashSyncCheckpoint); + const uint256& hash = mapCheckpoints.rbegin()->second; + if (mapBlockIndex.count(hash) && !mapBlockIndex[hash]->IsInMainChain()) + { + // checkpoint block accepted but not yet in main chain + printf("ResetSyncCheckpoint: SetBestChain to hardened checkpoint %s\n", hash.ToString().c_str()); + CTxDB txdb; + CBlock block; + if (!block.ReadFromDisk(mapBlockIndex[hash])) + return error("ResetSyncCheckpoint: ReadFromDisk failed for hardened checkpoint %s", hash.ToString().c_str()); + if (!block.SetBestChain(txdb, mapBlockIndex[hash])) + { + return error("ResetSyncCheckpoint: SetBestChain failed for hardened checkpoint %s", hash.ToString().c_str()); + } + txdb.Close(); + } + else if(!mapBlockIndex.count(hash)) + { + // checkpoint block not yet accepted + hashPendingCheckpoint = hash; + checkpointMessagePending.SetNull(); + printf("ResetSyncCheckpoint: pending for sync-checkpoint %s\n", hashPendingCheckpoint.ToString().c_str()); + } + + BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints) + { + const uint256& hash = i.second; + if (mapBlockIndex.count(hash) && mapBlockIndex[hash]->IsInMainChain()) + { + if (!WriteSyncCheckpoint(hash)) + return error("ResetSyncCheckpoint: failed to write sync checkpoint %s", hash.ToString().c_str()); + printf("ResetSyncCheckpoint: sync-checkpoint reset to %s\n", hashSyncCheckpoint.ToString().c_str()); + return true; + } + } + + return false; + } + + void AskForPendingSyncCheckpoint(CNode* pfrom) + { + LOCK(cs_hashSyncCheckpoint); + if (pfrom && hashPendingCheckpoint != 0 && (!mapBlockIndex.count(hashPendingCheckpoint)) && (!mapOrphanBlocks.count(hashPendingCheckpoint))) + pfrom->AskFor(CInv(MSG_BLOCK, hashPendingCheckpoint)); + } + + bool SetCheckpointPrivKey(std::string strPrivKey) + { + // Test signing a sync-checkpoint with genesis block + CSyncCheckpoint checkpoint; + checkpoint.hashCheckpoint = !fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet; + CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); + sMsg << (CUnsignedSyncCheckpoint)checkpoint; + checkpoint.vchMsg = std::vector(sMsg.begin(), sMsg.end()); + + std::vector vchPrivKey = ParseHex(strPrivKey); + CKey key; + key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash + if (!key.Sign(Hash(checkpoint.vchMsg.begin(), checkpoint.vchMsg.end()), checkpoint.vchSig)) + return false; + + // Test signing successful, proceed + CSyncCheckpoint::strMasterPrivKey = strPrivKey; + return true; + } + + bool SendSyncCheckpoint(uint256 hashCheckpoint) + { + CSyncCheckpoint checkpoint; + checkpoint.hashCheckpoint = hashCheckpoint; + CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); + sMsg << (CUnsignedSyncCheckpoint)checkpoint; + checkpoint.vchMsg = std::vector(sMsg.begin(), sMsg.end()); + + if (CSyncCheckpoint::strMasterPrivKey.empty()) + return error("SendSyncCheckpoint: Checkpoint master key unavailable."); + std::vector vchPrivKey = ParseHex(CSyncCheckpoint::strMasterPrivKey); + CKey key; + key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash + if (!key.Sign(Hash(checkpoint.vchMsg.begin(), checkpoint.vchMsg.end()), checkpoint.vchSig)) + return error("SendSyncCheckpoint: Unable to sign checkpoint, check private key?"); + + if(!checkpoint.ProcessSyncCheckpoint(NULL)) + { + printf("WARNING: SendSyncCheckpoint: Failed to process checkpoint.\n"); + return false; + } + + // Relay checkpoint + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + checkpoint.RelayTo(pnode); + } + return true; + } + + // Is the sync-checkpoint outside maturity window? + bool IsMatureSyncCheckpoint() + { + LOCK(cs_hashSyncCheckpoint); + // sync-checkpoint should always be accepted block + assert(mapBlockIndex.count(hashSyncCheckpoint)); + const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint]; + return (nBestHeight >= pindexSync->nHeight + nCoinbaseMaturity || + pindexSync->GetBlockTime() + nStakeMinAge < GetAdjustedTime()); + } + + // Is the sync-checkpoint too old? + bool IsSyncCheckpointTooOld(unsigned int nSeconds) + { + LOCK(cs_hashSyncCheckpoint); + // sync-checkpoint should always be accepted block + assert(mapBlockIndex.count(hashSyncCheckpoint)); + const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint]; + return (pindexSync->GetBlockTime() + nSeconds < GetAdjustedTime()); + } +} + +// ppcoin: sync-checkpoint master key +const std::string CSyncCheckpoint::strMasterPubKey = "040e63063d0f339b15c4809944d6fa3b18cbd440534d07a847ac995adcf48ae98fc3c96957df64453e3f460d11a9ed4c96959b0c2c0d0a1d6701f78b6211e49595"; + +std::string CSyncCheckpoint::strMasterPrivKey = ""; + +// ppcoin: verify signature of sync-checkpoint message +bool CSyncCheckpoint::CheckSignature() +{ + CKey key; + if (!key.SetPubKey(ParseHex(CSyncCheckpoint::strMasterPubKey))) + return error("CSyncCheckpoint::CheckSignature() : SetPubKey failed"); + if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) + return error("CSyncCheckpoint::CheckSignature() : verify signature failed"); + + // Now unserialize the data + CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); + sMsg >> *(CUnsignedSyncCheckpoint*)this; + return true; +} + +// ppcoin: process synchronized checkpoint +bool CSyncCheckpoint::ProcessSyncCheckpoint(CNode* pfrom) +{ + if (!CheckSignature()) + return false; + + LOCK(Checkpoints::cs_hashSyncCheckpoint); + if (!mapBlockIndex.count(hashCheckpoint)) + { + // We haven't received the checkpoint chain, keep the checkpoint as pending + Checkpoints::hashPendingCheckpoint = hashCheckpoint; + Checkpoints::checkpointMessagePending = *this; + printf("ProcessSyncCheckpoint: pending for sync-checkpoint %s\n", hashCheckpoint.ToString().c_str()); + // Ask this guy to fill in what we're missing + if (pfrom) + { + pfrom->PushGetBlocks(pindexBest, hashCheckpoint); + // ask directly as well in case rejected earlier by duplicate + // proof-of-stake because getblocks may not get it this time + pfrom->AskFor(CInv(MSG_BLOCK, mapOrphanBlocks.count(hashCheckpoint)? WantedByOrphan(mapOrphanBlocks[hashCheckpoint]) : hashCheckpoint)); + } + return false; + } + + if (!Checkpoints::ValidateSyncCheckpoint(hashCheckpoint)) + return false; + + CTxDB txdb; + CBlockIndex* pindexCheckpoint = mapBlockIndex[hashCheckpoint]; + if (!pindexCheckpoint->IsInMainChain()) + { + // checkpoint chain received but not yet main chain + CBlock block; + if (!block.ReadFromDisk(pindexCheckpoint)) + return error("ProcessSyncCheckpoint: ReadFromDisk failed for sync checkpoint %s", hashCheckpoint.ToString().c_str()); + if (!block.SetBestChain(txdb, pindexCheckpoint)) + { + Checkpoints::hashInvalidCheckpoint = hashCheckpoint; + return error("ProcessSyncCheckpoint: SetBestChain failed for sync checkpoint %s", hashCheckpoint.ToString().c_str()); + } + } + txdb.Close(); + + if (!Checkpoints::WriteSyncCheckpoint(hashCheckpoint)) + return error("ProcessSyncCheckpoint(): failed to write sync checkpoint %s", hashCheckpoint.ToString().c_str()); + Checkpoints::checkpointMessage = *this; + Checkpoints::hashPendingCheckpoint = 0; + Checkpoints::checkpointMessagePending.SetNull(); + printf("ProcessSyncCheckpoint: sync-checkpoint at %s\n", hashCheckpoint.ToString().c_str()); + return true; +} diff --git a/src/checkpoints.h b/src/checkpoints.h new file mode 100644 index 0000000..4f5db11 --- /dev/null +++ b/src/checkpoints.h @@ -0,0 +1,140 @@ +// Copyright (c) 2009-2012 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_CHECKPOINT_H +#define BITCOIN_CHECKPOINT_H + +#include +#include "net.h" +#include "util.h" + +#define CHECKPOINT_MAX_SPAN (60 * 60 * 4) // max 4 hours before latest block + +class uint256; +class CBlockIndex; +class CSyncCheckpoint; + +/** Block-chain checkpoints are compiled-in sanity checks. + * They are updated every release or three. + */ +namespace Checkpoints +{ + // Returns true if block passes checkpoint checks + bool CheckHardened(int nHeight, const uint256& hash); + + // Return conservative estimate of total number of blocks, 0 if unknown + int GetTotalBlocksEstimate(); + + // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint + CBlockIndex* GetLastCheckpoint(const std::map& mapBlockIndex); + + extern uint256 hashSyncCheckpoint; + extern CSyncCheckpoint checkpointMessage; + extern uint256 hashInvalidCheckpoint; + extern CCriticalSection cs_hashSyncCheckpoint; + + CBlockIndex* GetLastSyncCheckpoint(); + bool WriteSyncCheckpoint(const uint256& hashCheckpoint); + bool AcceptPendingSyncCheckpoint(); + uint256 AutoSelectSyncCheckpoint(); + bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev); + bool WantedByPendingSyncCheckpoint(uint256 hashBlock); + bool ResetSyncCheckpoint(); + void AskForPendingSyncCheckpoint(CNode* pfrom); + bool SetCheckpointPrivKey(std::string strPrivKey); + bool SendSyncCheckpoint(uint256 hashCheckpoint); + bool IsMatureSyncCheckpoint(); + bool IsSyncCheckpointTooOld(unsigned int nSeconds); +} + +// ppcoin: synchronized checkpoint +class CUnsignedSyncCheckpoint +{ +public: + int nVersion; + uint256 hashCheckpoint; // checkpoint block + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(hashCheckpoint); + ) + + void SetNull() + { + nVersion = 1; + hashCheckpoint = 0; + } + + std::string ToString() const + { + return strprintf( + "CSyncCheckpoint(\n" + " nVersion = %d\n" + " hashCheckpoint = %s\n" + ")\n", + nVersion, + hashCheckpoint.ToString().c_str()); + } + + void print() const + { + printf("%s", ToString().c_str()); + } +}; + +class CSyncCheckpoint : public CUnsignedSyncCheckpoint +{ +public: + static const std::string strMasterPubKey; + static std::string strMasterPrivKey; + + std::vector vchMsg; + std::vector vchSig; + + CSyncCheckpoint() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(vchMsg); + READWRITE(vchSig); + ) + + void SetNull() + { + CUnsignedSyncCheckpoint::SetNull(); + vchMsg.clear(); + vchSig.clear(); + } + + bool IsNull() const + { + return (hashCheckpoint == 0); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool RelayTo(CNode* pnode) const + { + // returns true if wasn't already sent + if (pnode->hashCheckpointKnown != hashCheckpoint) + { + pnode->hashCheckpointKnown = hashCheckpoint; + pnode->PushMessage("checkpoint", *this); + return true; + } + return false; + } + + bool CheckSignature(); + bool ProcessSyncCheckpoint(CNode* pfrom); +}; + +#endif diff --git a/src/clientversion.h b/src/clientversion.h new file mode 100644 index 0000000..6de17d2 --- /dev/null +++ b/src/clientversion.h @@ -0,0 +1,19 @@ +#ifndef CLIENTVERSION_H +#define CLIENTVERSION_H + +// +// client versioning +// + +// These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it +#define CLIENT_VERSION_MAJOR 1 +#define CLIENT_VERSION_MINOR 1 +#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_BUILD 0 + +// 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 + +#endif // CLIENTVERSION_H diff --git a/src/coincontrol.h b/src/coincontrol.h new file mode 100644 index 0000000..236b586 --- /dev/null +++ b/src/coincontrol.h @@ -0,0 +1,57 @@ +#ifndef COINCONTROL_H +#define COINCONTROL_H + +/** Coin Control Features. */ +class CCoinControl +{ +public: + CTxDestination destChange; + + CCoinControl() + { + SetNull(); + } + + void SetNull() + { + destChange = CNoDestination(); + setSelected.clear(); + } + + 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(COutPoint& output) + { + setSelected.insert(output); + } + + void UnSelect(COutPoint& output) + { + setSelected.erase(output); + } + + void UnSelectAll() + { + setSelected.clear(); + } + + void ListSelected(std::vector& vOutpoints) + { + vOutpoints.assign(setSelected.begin(), setSelected.end()); + } + +private: + std::set setSelected; + +}; + +#endif // COINCONTROL_H diff --git a/src/compat.h b/src/compat.h new file mode 100644 index 0000000..79ebb93 --- /dev/null +++ b/src/compat.h @@ -0,0 +1,63 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_COMPAT_H +#define _BITCOIN_COMPAT_H 1 + +#ifdef WIN32 +#define _WIN32_WINNT 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +typedef u_int SOCKET; +#ifdef WIN32 +#define MSG_NOSIGNAL 0 +#define MSG_DONTWAIT 0 +typedef int socklen_t; +#else +#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 + +inline int myclosesocket(SOCKET& hSocket) +{ + if (hSocket == INVALID_SOCKET) + return WSAENOTSOCK; +#ifdef WIN32 + int ret = closesocket(hSocket); +#else + int ret = close(hSocket); +#endif + hSocket = INVALID_SOCKET; + return ret; +} +#define closesocket(s) myclosesocket(s) + + +#endif diff --git a/src/crypter.cpp b/src/crypter.cpp new file mode 100644 index 0000000..181b8fa --- /dev/null +++ b/src/crypter.cpp @@ -0,0 +1,121 @@ +// Copyright (c) 2009-2012 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 +#include +#include +#include +#ifdef WIN32 +#include +#endif + +#include "crypter.h" + +bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector& 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) + { + memset(&chKey, 0, sizeof chKey); + memset(&chIV, 0, sizeof chIV); + return false; + } + + fKeySet = true; + return true; +} + +bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector& 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 &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 (nCLen); + + EVP_CIPHER_CTX ctx; + + bool fOk = true; + + EVP_CIPHER_CTX_init(&ctx); + if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); + if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen); + if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen); + EVP_CIPHER_CTX_cleanup(&ctx); + + if (!fOk) return false; + + vchCiphertext.resize(nCLen + nFLen); + return true; +} + +bool CCrypter::Decrypt(const std::vector& 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); + + EVP_CIPHER_CTX ctx; + + bool fOk = true; + + EVP_CIPHER_CTX_init(&ctx); + if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); + if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen); + if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen); + EVP_CIPHER_CTX_cleanup(&ctx); + + if (!fOk) return false; + + vchPlaintext.resize(nPLen + nFLen); + return true; +} + + +bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext) +{ + CCrypter cKeyCrypter; + std::vector chIV(WALLET_CRYPTO_KEY_SIZE); + memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); + if(!cKeyCrypter.SetKey(vMasterKey, chIV)) + return false; + return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext); +} + +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext) +{ + CCrypter cKeyCrypter; + std::vector 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)); +} diff --git a/src/crypter.h b/src/crypter.h new file mode 100644 index 0000000..04538a3 --- /dev/null +++ b/src/crypter.h @@ -0,0 +1,107 @@ +// Copyright (c) 2009-2012 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 __CRYPTER_H__ +#define __CRYPTER_H__ + +#include "allocators.h" /* for SecureString */ +#include "key.h" +#include "serialize.h" + +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 vchCryptedKey; + std::vector 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 vchOtherDerivationParameters; + + IMPLEMENT_SERIALIZE + ( + 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(0); + } +}; + +typedef std::vector > 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& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod); + bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector &vchCiphertext); + bool Decrypt(const std::vector& vchCiphertext, CKeyingMaterial& vchPlaintext); + bool SetKey(const CKeyingMaterial& chNewKey, const std::vector& chNewIV); + + void CleanKey() + { + memset(&chKey, 0, sizeof chKey); + memset(&chIV, 0, 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(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext); +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector &vchCiphertext, const uint256& nIV, CSecret &vchPlaintext); + +#endif diff --git a/src/cubehash.c b/src/cubehash.c new file mode 100644 index 0000000..9322fe1 --- /dev/null +++ b/src/cubehash.c @@ -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 + */ + +#include +#include +#include + +#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 diff --git a/src/db.cpp b/src/db.cpp new file mode 100644 index 0000000..43ba3b5 --- /dev/null +++ b/src/db.cpp @@ -0,0 +1,976 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "db.h" +#include "net.h" +#include "checkpoints.h" +#include "util.h" +#include "main.h" +#include "kernel.h" +#include +#include +#include + +#ifndef WIN32 +#include "sys/stat.h" +#endif + +using namespace std; +using namespace boost; + + +unsigned int nWalletDBUpdated; + + + +// +// CDB +// + +CDBEnv bitdb; + +void CDBEnv::EnvShutdown() +{ + if (!fDbEnvInit) + return; + + fDbEnvInit = false; + int ret = dbenv.close(0); + if (ret != 0) + printf("EnvShutdown exception: %s (%d)\n", DbEnv::strerror(ret), ret); + if (!fMockDb) + DbEnv(0).remove(strPath.c_str(), 0); +} + +CDBEnv::CDBEnv() : dbenv(DB_CXX_NO_EXCEPTIONS) +{ + fDbEnvInit = false; + fMockDb = false; +} + +CDBEnv::~CDBEnv() +{ + EnvShutdown(); +} + +void CDBEnv::Close() +{ + EnvShutdown(); +} + +bool CDBEnv::Open(boost::filesystem::path pathEnv_) +{ + if (fDbEnvInit) + return true; + + if (fShutdown) + return false; + + pathEnv = pathEnv_; + filesystem::path pathDataDir = pathEnv; + strPath = pathDataDir.string(); + filesystem::path pathLogDir = pathDataDir / "database"; + filesystem::create_directory(pathLogDir); + filesystem::path pathErrorFile = pathDataDir / "db.log"; + printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str()); + + unsigned int nEnvFlags = 0; + if (GetBoolArg("-privdb", true)) + nEnvFlags |= DB_PRIVATE; + + int nDbCache = GetArg("-dbcache", 25); + dbenv.set_lg_dir(pathLogDir.string().c_str()); + dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1); + dbenv.set_lg_bsize(1048576); + dbenv.set_lg_max(10485760); + dbenv.set_lk_max_locks(10000); + dbenv.set_lk_max_objects(10000); + dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug + dbenv.set_flags(DB_AUTO_COMMIT, 1); + dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1); +// dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); + int ret = dbenv.open(strPath.c_str(), + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_RECOVER | + nEnvFlags, + S_IRUSR | S_IWUSR); + if (ret != 0) + return error("CDB() : error %s (%d) opening database environment", DbEnv::strerror(ret), ret); + + fDbEnvInit = true; + fMockDb = false; + return true; +} + +void CDBEnv::MakeMock() +{ + if (fDbEnvInit) + throw runtime_error("CDBEnv::MakeMock(): already initialized"); + + if (fShutdown) + throw runtime_error("CDBEnv::MakeMock(): during shutdown"); + + printf("CDBEnv::MakeMock()\n"); + + dbenv.set_cachesize(1, 0, 1); + dbenv.set_lg_bsize(10485760*4); + dbenv.set_lg_max(10485760); + dbenv.set_lk_max_locks(10000); + dbenv.set_lk_max_objects(10000); + dbenv.set_flags(DB_AUTO_COMMIT, 1); +// dbenv.log_set_config(DB_LOG_IN_MEMORY, 1); + int ret = dbenv.open(NULL, + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_PRIVATE, + S_IRUSR | S_IWUSR); + if (ret > 0) + throw runtime_error(strprintf("CDBEnv::MakeMock(): error %d opening database environment", ret)); + + fDbEnvInit = true; + fMockDb = true; +} + +CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)) +{ + LOCK(cs_db); + assert(mapFileUseCount.count(strFile) == 0); + + Db db(&dbenv, 0); + int result = db.verify(strFile.c_str(), NULL, NULL, 0); + if (result == 0) + return VERIFY_OK; + else if (recoverFunc == NULL) + return RECOVER_FAIL; + + // Try to recover: + bool fRecovered = (*recoverFunc)(*this, strFile); + return (fRecovered ? RECOVER_OK : RECOVER_FAIL); +} + +bool CDBEnv::Salvage(std::string strFile, bool fAggressive, + std::vector& vResult) +{ + LOCK(cs_db); + assert(mapFileUseCount.count(strFile) == 0); + + u_int32_t flags = DB_SALVAGE; + if (fAggressive) flags |= DB_AGGRESSIVE; + + stringstream strDump; + + Db db(&dbenv, 0); + int result = db.verify(strFile.c_str(), NULL, &strDump, flags); + if (result != 0) + { + printf("ERROR: db salvage failed\n"); + return false; + } + + // Format of bdb dump is ascii lines: + // header lines... + // HEADER=END + // hexadecimal key + // hexadecimal value + // ... repeated + // DATA=END + + string strLine; + while (!strDump.eof() && strLine != "HEADER=END") + getline(strDump, strLine); // Skip past header + + std::string keyHex, valueHex; + while (!strDump.eof() && keyHex != "DATA=END") + { + getline(strDump, keyHex); + if (keyHex != "DATA_END") + { + getline(strDump, valueHex); + vResult.push_back(make_pair(ParseHex(keyHex),ParseHex(valueHex))); + } + } + + return (result == 0); +} + + +void CDBEnv::CheckpointLSN(std::string strFile) +{ + dbenv.txn_checkpoint(0, 0, 0); + if (fMockDb) + return; + dbenv.lsn_reset(strFile.c_str(), 0); +} + + +CDB::CDB(const char *pszFile, const char* pszMode) : + pdb(NULL), activeTxn(NULL) +{ + int ret; + if (pszFile == NULL) + return; + + fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); + bool fCreate = strchr(pszMode, 'c'); + unsigned int nFlags = DB_THREAD; + if (fCreate) + nFlags |= DB_CREATE; + + { + LOCK(bitdb.cs_db); + if (!bitdb.Open(GetDataDir())) + throw runtime_error("env open failed"); + + strFile = pszFile; + ++bitdb.mapFileUseCount[strFile]; + pdb = bitdb.mapDb[strFile]; + if (pdb == NULL || pszFile[0] == '\0') + { + pdb = new Db(&bitdb.dbenv, 0); + + bool fMockDb = bitdb.IsMock(); + if (fMockDb) + { + DbMpoolFile*mpf = pdb->get_mpf(); + ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); + if (ret != 0) + throw runtime_error(strprintf("CDB() : failed to configure for no temp file backing for database %s", pszFile)); + } + + ret = pdb->open(NULL, // Txn pointer + fMockDb ? NULL : pszFile, // Filename + "main", // Logical db name + DB_BTREE, // Database type + nFlags, // Flags + 0); + + if (ret != 0) + { + delete pdb; + pdb = NULL; + --bitdb.mapFileUseCount[strFile]; + strFile = ""; + throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret)); + } + + if (fCreate && !Exists(string("version"))) + { + bool fTmp = fReadOnly; + fReadOnly = false; + WriteVersion(CLIENT_VERSION); + fReadOnly = fTmp; + } + + bitdb.mapDb[strFile] = pdb; + } + } +} + +static bool IsChainFile(std::string strFile) +{ + if (strFile == "blkindex.dat") + return true; + + return false; +} + +void CDB::Close() +{ + if (!pdb) + return; + if (activeTxn) + activeTxn->abort(); + activeTxn = NULL; + pdb = NULL; + + // Flush database activity from memory pool to disk log + unsigned int nMinutes = 0; + if (fReadOnly) + nMinutes = 1; + if (IsChainFile(strFile)) + nMinutes = 2; + if (IsChainFile(strFile) && IsInitialBlockDownload()) + nMinutes = 5; + + bitdb.dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0); + + { + LOCK(bitdb.cs_db); + --bitdb.mapFileUseCount[strFile]; + } +} + +void CDBEnv::CloseDb(const string& strFile) +{ + { + LOCK(cs_db); + if (mapDb[strFile] != NULL) + { + // Close the database handle + Db* pdb = mapDb[strFile]; + pdb->close(0); + delete pdb; + mapDb[strFile] = NULL; + } + } +} + +bool CDBEnv::RemoveDb(const string& strFile) +{ + this->CloseDb(strFile); + + LOCK(cs_db); + int rc = dbenv.dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT); + return (rc == 0); +} + +bool CDB::Rewrite(const string& strFile, const char* pszSkip) +{ + while (!fShutdown) + { + { + LOCK(bitdb.cs_db); + if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) + { + // Flush log data to the dat file + bitdb.CloseDb(strFile); + bitdb.CheckpointLSN(strFile); + bitdb.mapFileUseCount.erase(strFile); + + bool fSuccess = true; + printf("Rewriting %s...\n", strFile.c_str()); + string strFileRes = strFile + ".rewrite"; + { // surround usage of db with extra {} + CDB db(strFile.c_str(), "r"); + Db* pdbCopy = new Db(&bitdb.dbenv, 0); + + int ret = pdbCopy->open(NULL, // Txn pointer + strFileRes.c_str(), // Filename + "main", // Logical db name + DB_BTREE, // Database type + DB_CREATE, // Flags + 0); + if (ret > 0) + { + printf("Cannot create database file %s\n", strFileRes.c_str()); + fSuccess = false; + } + + Dbc* pcursor = db.GetCursor(); + if (pcursor) + while (fSuccess) + { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); + if (ret == DB_NOTFOUND) + { + pcursor->close(); + break; + } + else if (ret != 0) + { + pcursor->close(); + fSuccess = false; + break; + } + if (pszSkip && + strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) + continue; + if (strncmp(&ssKey[0], "\x07version", 8) == 0) + { + // Update version: + ssValue.clear(); + ssValue << CLIENT_VERSION; + } + Dbt datKey(&ssKey[0], ssKey.size()); + Dbt datValue(&ssValue[0], ssValue.size()); + int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE); + if (ret2 > 0) + fSuccess = false; + } + if (fSuccess) + { + db.Close(); + bitdb.CloseDb(strFile); + if (pdbCopy->close(0)) + fSuccess = false; + delete pdbCopy; + } + } + if (fSuccess) + { + Db dbA(&bitdb.dbenv, 0); + if (dbA.remove(strFile.c_str(), NULL, 0)) + fSuccess = false; + Db dbB(&bitdb.dbenv, 0); + if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) + fSuccess = false; + } + if (!fSuccess) + printf("Rewriting of %s FAILED!\n", strFileRes.c_str()); + return fSuccess; + } + } + Sleep(100); + } + return false; +} + + +void CDBEnv::Flush(bool fShutdown) +{ + int64 nStart = GetTimeMillis(); + // Flush log data to the actual data file + // on all files that are not in use + printf("Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); + if (!fDbEnvInit) + return; + { + LOCK(cs_db); + map::iterator mi = mapFileUseCount.begin(); + while (mi != mapFileUseCount.end()) + { + string strFile = (*mi).first; + int nRefCount = (*mi).second; + printf("%s refcount=%d\n", strFile.c_str(), nRefCount); + if (nRefCount == 0) + { + // Move log data to the dat file + CloseDb(strFile); + printf("%s checkpoint\n", strFile.c_str()); + dbenv.txn_checkpoint(0, 0, 0); + if (!IsChainFile(strFile) || fDetachDB) { + printf("%s detach\n", strFile.c_str()); + if (!fMockDb) + dbenv.lsn_reset(strFile.c_str(), 0); + } + printf("%s closed\n", strFile.c_str()); + mapFileUseCount.erase(mi++); + } + else + mi++; + } + printf("DBFlush(%s)%s ended %15"PRI64d"ms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started", GetTimeMillis() - nStart); + if (fShutdown) + { + char** listp; + if (mapFileUseCount.empty()) + { + dbenv.log_archive(&listp, DB_ARCH_REMOVE); + Close(); + } + } + } +} + + + + + + +// +// CTxDB +// + +bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex) +{ + assert(!fClient); + txindex.SetNull(); + return Read(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex) +{ + assert(!fClient); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight) +{ + assert(!fClient); + + // Add to tx index + uint256 hash = tx.GetHash(); + CTxIndex txindex(pos, tx.vout.size()); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::EraseTxIndex(const CTransaction& tx) +{ + assert(!fClient); + uint256 hash = tx.GetHash(); + + return Erase(make_pair(string("tx"), hash)); +} + +bool CTxDB::ContainsTx(uint256 hash) +{ + assert(!fClient); + return Exists(make_pair(string("tx"), hash)); +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex) +{ + assert(!fClient); + tx.SetNull(); + if (!ReadTxIndex(hash, txindex)) + return false; + return (tx.ReadFromDisk(txindex.pos)); +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex) +{ + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) +{ + return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex); +} + +bool CTxDB::ReadHashBestChain(uint256& hashBestChain) +{ + return Read(string("hashBestChain"), hashBestChain); +} + +bool CTxDB::WriteHashBestChain(uint256 hashBestChain) +{ + return Write(string("hashBestChain"), hashBestChain); +} + +bool CTxDB::ReadBestInvalidTrust(CBigNum& bnBestInvalidTrust) +{ + return Read(string("bnBestInvalidTrust"), bnBestInvalidTrust); +} + +bool CTxDB::WriteBestInvalidTrust(CBigNum bnBestInvalidTrust) +{ + return Write(string("bnBestInvalidTrust"), bnBestInvalidTrust); +} + +bool CTxDB::ReadSyncCheckpoint(uint256& hashCheckpoint) +{ + return Read(string("hashSyncCheckpoint"), hashCheckpoint); +} + +bool CTxDB::WriteSyncCheckpoint(uint256 hashCheckpoint) +{ + return Write(string("hashSyncCheckpoint"), hashCheckpoint); +} + +bool CTxDB::ReadCheckpointPubKey(string& strPubKey) +{ + return Read(string("strCheckpointPubKey"), strPubKey); +} + +bool CTxDB::WriteCheckpointPubKey(const string& strPubKey) +{ + return Write(string("strCheckpointPubKey"), strPubKey); +} + +CBlockIndex static * InsertBlockIndex(uint256 hash) +{ + if (hash == 0) + return NULL; + + // Return existing + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + return (*mi).second; + + // Create new + CBlockIndex* pindexNew = new CBlockIndex(); + if (!pindexNew) + throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); + mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + + return pindexNew; +} + +bool CTxDB::LoadBlockIndex() +{ + if (!LoadBlockIndexGuts()) + return false; + + if (fRequestShutdown) + return true; + + // Calculate bnChainTrust + vector > vSortedByHeight; + vSortedByHeight.reserve(mapBlockIndex.size()); + BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) + { + CBlockIndex* pindex = item.second; + vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); + } + sort(vSortedByHeight.begin(), vSortedByHeight.end()); + BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) + { + CBlockIndex* pindex = item.second; + pindex->bnChainTrust = (pindex->pprev ? pindex->pprev->bnChainTrust : 0) + pindex->GetBlockTrust(); + // ppcoin: calculate stake modifier checksum + pindex->nStakeModifierChecksum = GetStakeModifierChecksum(pindex); + if (!CheckStakeModifierCheckpoints(pindex->nHeight, pindex->nStakeModifierChecksum)) + return error("CTxDB::LoadBlockIndex() : Failed stake modifier checkpoint height=%d, modifier=0x%016"PRI64x, pindex->nHeight, pindex->nStakeModifier); + } + + // Load hashBestChain pointer to end of best chain + if (!ReadHashBestChain(hashBestChain)) + { + if (pindexGenesisBlock == NULL) + return true; + return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded"); + } + if (!mapBlockIndex.count(hashBestChain)) + return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index"); + pindexBest = mapBlockIndex[hashBestChain]; + nBestHeight = pindexBest->nHeight; + bnBestChainTrust = pindexBest->bnChainTrust; + printf("LoadBlockIndex(): hashBestChain=%s height=%d trust=%s date=%s\n", + hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(), + DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); + + // ppcoin: load hashSyncCheckpoint + if (!ReadSyncCheckpoint(Checkpoints::hashSyncCheckpoint)) + return error("CTxDB::LoadBlockIndex() : hashSyncCheckpoint not loaded"); + printf("LoadBlockIndex(): synchronized checkpoint %s\n", Checkpoints::hashSyncCheckpoint.ToString().c_str()); + + // Load bnBestInvalidTrust, OK if it doesn't exist + ReadBestInvalidTrust(bnBestInvalidTrust); + + // Verify blocks in the best chain + int nCheckLevel = GetArg("-checklevel", 1); + int nCheckDepth = GetArg( "-checkblocks", 2500); + if (nCheckDepth == 0) + nCheckDepth = 1000000000; // suffices until the year 19000 + if (nCheckDepth > nBestHeight) + nCheckDepth = nBestHeight; + printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); + CBlockIndex* pindexFork = NULL; + map, CBlockIndex*> mapBlockPos; + for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) + { + if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) + break; + CBlock block; + if (!block.ReadFromDisk(pindex)) + return error("LoadBlockIndex() : block.ReadFromDisk failed"); + // check level 1: verify block validity + if (nCheckLevel>0 && !block.CheckBlock()) + { + printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); + pindexFork = pindex->pprev; + } + // check level 2: verify transaction index validity + if (nCheckLevel>1) + { + pair pos = make_pair(pindex->nFile, pindex->nBlockPos); + mapBlockPos[pos] = pindex; + BOOST_FOREACH(const CTransaction &tx, block.vtx) + { + uint256 hashTx = tx.GetHash(); + CTxIndex txindex; + if (ReadTxIndex(hashTx, txindex)) + { + // check level 3: checker transaction hashes + if (nCheckLevel>2 || pindex->nFile != txindex.pos.nFile || pindex->nBlockPos != txindex.pos.nBlockPos) + { + // either an error or a duplicate transaction + CTransaction txFound; + if (!txFound.ReadFromDisk(txindex.pos)) + { + printf("LoadBlockIndex() : *** cannot read mislocated transaction %s\n", hashTx.ToString().c_str()); + pindexFork = pindex->pprev; + } + else + if (txFound.GetHash() != hashTx) // not a duplicate tx + { + printf("LoadBlockIndex(): *** invalid tx position for %s\n", hashTx.ToString().c_str()); + pindexFork = pindex->pprev; + } + } + // check level 4: check whether spent txouts were spent within the main chain + unsigned int nOutput = 0; + if (nCheckLevel>3) + { + BOOST_FOREACH(const CDiskTxPos &txpos, txindex.vSpent) + { + if (!txpos.IsNull()) + { + pair posFind = make_pair(txpos.nFile, txpos.nBlockPos); + if (!mapBlockPos.count(posFind)) + { + printf("LoadBlockIndex(): *** found bad spend at %d, hashBlock=%s, hashTx=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), hashTx.ToString().c_str()); + pindexFork = pindex->pprev; + } + // check level 6: check whether spent txouts were spent by a valid transaction that consume them + if (nCheckLevel>5) + { + CTransaction txSpend; + if (!txSpend.ReadFromDisk(txpos)) + { + printf("LoadBlockIndex(): *** cannot read spending transaction of %s:%i from disk\n", hashTx.ToString().c_str(), nOutput); + pindexFork = pindex->pprev; + } + else if (!txSpend.CheckTransaction()) + { + printf("LoadBlockIndex(): *** spending transaction of %s:%i is invalid\n", hashTx.ToString().c_str(), nOutput); + pindexFork = pindex->pprev; + } + else + { + bool fFound = false; + BOOST_FOREACH(const CTxIn &txin, txSpend.vin) + if (txin.prevout.hash == hashTx && txin.prevout.n == nOutput) + fFound = true; + if (!fFound) + { + printf("LoadBlockIndex(): *** spending transaction of %s:%i does not spend it\n", hashTx.ToString().c_str(), nOutput); + pindexFork = pindex->pprev; + } + } + } + } + nOutput++; + } + } + } + // check level 5: check whether all prevouts are marked spent + if (nCheckLevel>4) + { + BOOST_FOREACH(const CTxIn &txin, tx.vin) + { + CTxIndex txindex; + if (ReadTxIndex(txin.prevout.hash, txindex)) + if (txindex.vSpent.size()-1 < txin.prevout.n || txindex.vSpent[txin.prevout.n].IsNull()) + { + printf("LoadBlockIndex(): *** found unspent prevout %s:%i in %s\n", txin.prevout.hash.ToString().c_str(), txin.prevout.n, hashTx.ToString().c_str()); + pindexFork = pindex->pprev; + } + } + } + } + } + } + if (pindexFork && !fRequestShutdown) + { + // Reorg back to the fork + printf("LoadBlockIndex() : *** moving best chain pointer back to block %d\n", pindexFork->nHeight); + CBlock block; + if (!block.ReadFromDisk(pindexFork)) + return error("LoadBlockIndex() : block.ReadFromDisk failed"); + CTxDB txdb; + block.SetBestChain(txdb, pindexFork); + } + + return true; +} + + + +bool CTxDB::LoadBlockIndexGuts() +{ + // Get database cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + // Load mapBlockIndex + unsigned int fFlags = DB_SET_RANGE; + while(true) + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + if (fFlags == DB_SET_RANGE) + ssKey << make_pair(string("blockindex"), uint256(0)); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + + try { + string strType; + ssKey >> strType; + if (strType == "blockindex" && !fRequestShutdown) + { + CDiskBlockIndex diskindex; + ssValue >> diskindex; + + // Construct block index object + CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); + pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); + pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); + pindexNew->nFile = diskindex.nFile; + pindexNew->nBlockPos = diskindex.nBlockPos; + pindexNew->nHeight = diskindex.nHeight; + pindexNew->nMint = diskindex.nMint; + pindexNew->nMoneySupply = diskindex.nMoneySupply; + pindexNew->nFlags = diskindex.nFlags; + pindexNew->nStakeModifier = diskindex.nStakeModifier; + pindexNew->prevoutStake = diskindex.prevoutStake; + pindexNew->nStakeTime = diskindex.nStakeTime; + pindexNew->hashProofOfStake = diskindex.hashProofOfStake; + pindexNew->nVersion = diskindex.nVersion; + pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; + pindexNew->nTime = diskindex.nTime; + pindexNew->nBits = diskindex.nBits; + pindexNew->nNonce = diskindex.nNonce; + + // Watch for genesis block + if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) + pindexGenesisBlock = pindexNew; + + if (!pindexNew->CheckIndex()) + return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); + + // ppcoin: build setStakeSeen + if (pindexNew->IsProofOfStake()) + setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); + } + else + { + break; // if shutdown requested or finished loading block index + } + } // try + catch (std::exception &e) { + return error("%s() : deserialize error", __PRETTY_FUNCTION__); + } + } + pcursor->close(); + + return true; +} + + + + + +// +// CAddrDB +// + + +CAddrDB::CAddrDB() +{ + pathAddr = GetDataDir() / "peers.dat"; +} + +bool CAddrDB::Write(const CAddrMan& addr) +{ + // Generate random temporary filename + unsigned short randv = 0; + RAND_bytes((unsigned char *)&randv, sizeof(randv)); + std::string tmpfn = strprintf("peers.dat.%04x", randv); + + // serialize addresses, checksum data up to that point, then append csum + CDataStream ssPeers(SER_DISK, CLIENT_VERSION); + ssPeers << FLATDATA(pchMessageStart); + ssPeers << addr; + uint256 hash = Hash(ssPeers.begin(), ssPeers.end()); + ssPeers << hash; + + // open temp output file, and associate with CAutoFile + boost::filesystem::path pathTmp = GetDataDir() / tmpfn; + FILE *file = fopen(pathTmp.string().c_str(), "wb"); + CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION); + if (!fileout) + return error("CAddrman::Write() : open failed"); + + // Write and commit header, data + try { + fileout << ssPeers; + } + catch (std::exception &e) { + return error("CAddrman::Write() : I/O error"); + } + FileCommit(fileout); + fileout.fclose(); + + // replace existing peers.dat, if any, with new peers.dat.XXXX + if (!RenameOver(pathTmp, pathAddr)) + return error("CAddrman::Write() : Rename-into-place failed"); + + return true; +} + +bool CAddrDB::Read(CAddrMan& addr) +{ + // open input file, and associate with CAutoFile + FILE *file = fopen(pathAddr.string().c_str(), "rb"); + CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); + if (!filein) + return error("CAddrman::Read() : open failed"); + + // use file size to size memory buffer + int fileSize = GetFilesize(filein); + int dataSize = fileSize - sizeof(uint256); + vector vchData; + vchData.resize(dataSize); + uint256 hashIn; + + // read data and checksum from file + try { + filein.read((char *)&vchData[0], dataSize); + filein >> hashIn; + } + catch (std::exception &e) { + return error("CAddrman::Read() 2 : I/O error or stream data corrupted"); + } + filein.fclose(); + + CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION); + + // verify stored checksum matches input data + uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); + if (hashIn != hashTmp) + return error("CAddrman::Read() : checksum mismatch; data corrupted"); + + unsigned char pchMsgTmp[4]; + try { + // de-serialize file header (pchMessageStart magic number) and + ssPeers >> FLATDATA(pchMsgTmp); + + // verify the network matches ours + if (memcmp(pchMsgTmp, pchMessageStart, sizeof(pchMsgTmp))) + return error("CAddrman::Read() : invalid network magic number"); + + // de-serialize address data into one CAddrMan object + ssPeers >> addr; + } + catch (std::exception &e) { + return error("CAddrman::Read() : I/O error or stream data corrupted"); + } + + return true; +} + diff --git a/src/db.h b/src/db.h new file mode 100644 index 0000000..eeb3a0b --- /dev/null +++ b/src/db.h @@ -0,0 +1,366 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_DB_H +#define BITCOIN_DB_H + +#include "main.h" + +#include +#include +#include + +#include + +class CAddress; +class CAddrMan; +class CBlockLocator; +class CDiskBlockIndex; +class CDiskTxPos; +class CMasterKey; +class COutPoint; +class CTxIndex; +class CWallet; +class CWalletTx; + +extern unsigned int nWalletDBUpdated; + +void ThreadFlushWalletDB(void* parg); +bool BackupWallet(const CWallet& wallet, const std::string& strDest); + + +class CDBEnv +{ +private: + bool fDetachDB; + bool fDbEnvInit; + bool fMockDb; + boost::filesystem::path pathEnv; + std::string strPath; + + void EnvShutdown(); + +public: + mutable CCriticalSection cs_db; + DbEnv dbenv; + std::map mapFileUseCount; + std::map mapDb; + + CDBEnv(); + ~CDBEnv(); + void MakeMock(); + bool IsMock() { return fMockDb; }; + + /* + * Verify that database file strFile is OK. If it is not, + * call the callback to try to recover. + * This must be called BEFORE strFile is opened. + * Returns true if strFile is OK. + */ + enum VerifyResult { VERIFY_OK, RECOVER_OK, RECOVER_FAIL }; + VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)); + /* + * Salvage data from a file that Verify says is bad. + * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation). + * Appends binary key/value pairs to vResult, returns true if successful. + * NOTE: reads the entire database into memory, so cannot be used + * for huge databases. + */ + typedef std::pair, std::vector > KeyValPair; + bool Salvage(std::string strFile, bool fAggressive, std::vector& vResult); + + bool Open(boost::filesystem::path pathEnv_); + void Close(); + void Flush(bool fShutdown); + void CheckpointLSN(std::string strFile); + void SetDetach(bool fDetachDB_) { fDetachDB = fDetachDB_; } + bool GetDetach() { return fDetachDB; } + + void CloseDb(const std::string& strFile); + bool RemoveDb(const std::string& strFile); + + DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC) + { + DbTxn* ptxn = NULL; + int ret = dbenv.txn_begin(NULL, &ptxn, flags); + if (!ptxn || ret != 0) + return NULL; + return ptxn; + } +}; + +extern CDBEnv bitdb; + + +/** RAII class that provides access to a Berkeley database */ +class CDB +{ +protected: + Db* pdb; + std::string strFile; + DbTxn *activeTxn; + bool fReadOnly; + + explicit CDB(const char* pszFile, const char* pszMode="r+"); + ~CDB() { Close(); } +public: + void Close(); +private: + CDB(const CDB&); + void operator=(const CDB&); + +protected: + template + bool Read(const K& key, T& value) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Read + Dbt datValue; + datValue.set_flags(DB_DBT_MALLOC); + int ret = pdb->get(activeTxn, &datKey, &datValue, 0); + memset(datKey.get_data(), 0, datKey.get_size()); + if (datValue.get_data() == NULL) + return false; + + // Unserialize value + try { + CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); + ssValue >> value; + } + catch (std::exception &e) { + return false; + } + + // Clear and free memory + memset(datValue.get_data(), 0, datValue.get_size()); + free(datValue.get_data()); + return (ret == 0); + } + + template + bool Write(const K& key, const T& value, bool fOverwrite=true) + { + if (!pdb) + return false; + if (fReadOnly) + assert(!"Write called on database in read-only mode"); + + // Key + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Value + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + ssValue.reserve(10000); + ssValue << value; + Dbt datValue(&ssValue[0], ssValue.size()); + + // Write + int ret = pdb->put(activeTxn, &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); + + // Clear memory in case it was a private key + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + return (ret == 0); + } + + template + bool Erase(const K& key) + { + if (!pdb) + return false; + if (fReadOnly) + assert(!"Erase called on database in read-only mode"); + + // Key + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Erase + int ret = pdb->del(activeTxn, &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0 || ret == DB_NOTFOUND); + } + + template + bool Exists(const K& key) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Exists + int ret = pdb->exists(activeTxn, &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0); + } + + Dbc* GetCursor() + { + if (!pdb) + return NULL; + Dbc* pcursor = NULL; + int ret = pdb->cursor(NULL, &pcursor, 0); + if (ret != 0) + return NULL; + return pcursor; + } + + int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT) + { + // Read at cursor + Dbt datKey; + if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) + { + datKey.set_data(&ssKey[0]); + datKey.set_size(ssKey.size()); + } + Dbt datValue; + if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) + { + datValue.set_data(&ssValue[0]); + datValue.set_size(ssValue.size()); + } + datKey.set_flags(DB_DBT_MALLOC); + datValue.set_flags(DB_DBT_MALLOC); + int ret = pcursor->get(&datKey, &datValue, fFlags); + if (ret != 0) + return ret; + else if (datKey.get_data() == NULL || datValue.get_data() == NULL) + return 99999; + + // Convert to streams + ssKey.SetType(SER_DISK); + ssKey.clear(); + ssKey.write((char*)datKey.get_data(), datKey.get_size()); + ssValue.SetType(SER_DISK); + ssValue.clear(); + ssValue.write((char*)datValue.get_data(), datValue.get_size()); + + // Clear and free memory + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + free(datKey.get_data()); + free(datValue.get_data()); + return 0; + } + +public: + bool TxnBegin() + { + if (!pdb || activeTxn) + return false; + DbTxn* ptxn = bitdb.TxnBegin(); + if (!ptxn) + return false; + activeTxn = ptxn; + return true; + } + + bool TxnCommit() + { + if (!pdb || !activeTxn) + return false; + int ret = activeTxn->commit(0); + activeTxn = NULL; + return (ret == 0); + } + + bool TxnAbort() + { + if (!pdb || !activeTxn) + return false; + int ret = activeTxn->abort(); + activeTxn = NULL; + return (ret == 0); + } + + bool ReadVersion(int& nVersion) + { + nVersion = 0; + return Read(std::string("version"), nVersion); + } + + bool WriteVersion(int nVersion) + { + return Write(std::string("version"), nVersion); + } + + bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL); +}; + + + + + + + +/** Access to the transaction database (blkindex.dat) */ +class CTxDB : public CDB +{ +public: + CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { } +private: + CTxDB(const CTxDB&); + void operator=(const CTxDB&); +public: + bool ReadTxIndex(uint256 hash, CTxIndex& txindex); + bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); + bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight); + bool EraseTxIndex(const CTransaction& tx); + bool ContainsTx(uint256 hash); + bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(uint256 hash, CTransaction& tx); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); + bool WriteBlockIndex(const CDiskBlockIndex& blockindex); + bool ReadHashBestChain(uint256& hashBestChain); + bool WriteHashBestChain(uint256 hashBestChain); + bool ReadBestInvalidTrust(CBigNum& bnBestInvalidTrust); + bool WriteBestInvalidTrust(CBigNum bnBestInvalidTrust); + bool ReadSyncCheckpoint(uint256& hashCheckpoint); + bool WriteSyncCheckpoint(uint256 hashCheckpoint); + bool ReadCheckpointPubKey(std::string& strPubKey); + bool WriteCheckpointPubKey(const std::string& strPubKey); + bool LoadBlockIndex(); +private: + bool LoadBlockIndexGuts(); +}; + + + + +/** Access to the (IP) address database (peers.dat) */ +class CAddrDB +{ +private: + boost::filesystem::path pathAddr; +public: + CAddrDB(); + bool Write(const CAddrMan& addr); + bool Read(CAddrMan& addr); +}; + +#endif // BITCOIN_DB_H diff --git a/src/echo.c b/src/echo.c new file mode 100644 index 0000000..667e3f3 --- /dev/null +++ b/src/echo.c @@ -0,0 +1,1031 @@ +/* $Id: echo.c 227 2010-06-16 17:28:38Z tp $ */ +/* + * ECHO 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 + */ + +#include +#include +#include + +#include "sph_echo.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_ECHO +#define SPH_SMALL_FOOTPRINT_ECHO 1 +#endif + +/* + * Some measures tend to show that the 64-bit implementation offers + * better performance only on a "64-bit architectures", those which have + * actual 64-bit registers. + */ +#if !defined SPH_ECHO_64 && SPH_64_TRUE +#define SPH_ECHO_64 1 +#endif + +/* + * We can use a 64-bit implementation only if a 64-bit type is available. + */ +#if !SPH_64 +#undef SPH_ECHO_64 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +#define T32 SPH_T32 +#define C32 SPH_C32 +#if SPH_64 +#define C64 SPH_C64 +#endif + +#define AES_BIG_ENDIAN 0 +#include "aes_helper.c" + +#if SPH_ECHO_64 + +#define DECL_STATE_SMALL \ + sph_u64 W[16][2]; + +#define DECL_STATE_BIG \ + sph_u64 W[16][2]; + +#define INPUT_BLOCK_SMALL(sc) do { \ + unsigned u; \ + memcpy(W, sc->u.Vb, 8 * sizeof(sph_u64)); \ + for (u = 0; u < 12; u ++) { \ + W[u + 4][0] = sph_dec64le_aligned( \ + sc->buf + 16 * u); \ + W[u + 4][1] = sph_dec64le_aligned( \ + sc->buf + 16 * u + 8); \ + } \ + } while (0) + +#define INPUT_BLOCK_BIG(sc) do { \ + unsigned u; \ + memcpy(W, sc->u.Vb, 16 * sizeof(sph_u64)); \ + for (u = 0; u < 8; u ++) { \ + W[u + 8][0] = sph_dec64le_aligned( \ + sc->buf + 16 * u); \ + W[u + 8][1] = sph_dec64le_aligned( \ + sc->buf + 16 * u + 8); \ + } \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_ECHO + +static void +aes_2rounds_all(sph_u64 W[16][2], + sph_u32 *pK0, sph_u32 *pK1, sph_u32 *pK2, sph_u32 *pK3) +{ + int n; + sph_u32 K0 = *pK0; + sph_u32 K1 = *pK1; + sph_u32 K2 = *pK2; + sph_u32 K3 = *pK3; + + for (n = 0; n < 16; n ++) { + sph_u64 Wl = W[n][0]; + sph_u64 Wh = W[n][1]; + sph_u32 X0 = (sph_u32)Wl; + sph_u32 X1 = (sph_u32)(Wl >> 32); + sph_u32 X2 = (sph_u32)Wh; + sph_u32 X3 = (sph_u32)(Wh >> 32); + sph_u32 Y0, Y1, Y2, Y3; \ + AES_ROUND_LE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3); + AES_ROUND_NOKEY_LE(Y0, Y1, Y2, Y3, X0, X1, X2, X3); + W[n][0] = (sph_u64)X0 | ((sph_u64)X1 << 32); + W[n][1] = (sph_u64)X2 | ((sph_u64)X3 << 32); + if ((K0 = T32(K0 + 1)) == 0) { + if ((K1 = T32(K1 + 1)) == 0) + if ((K2 = T32(K2 + 1)) == 0) + K3 = T32(K3 + 1); + } + } + *pK0 = K0; + *pK1 = K1; + *pK2 = K2; + *pK3 = K3; +} + +#define BIG_SUB_WORDS do { \ + aes_2rounds_all(W, &K0, &K1, &K2, &K3); \ + } while (0) + +#else + +#define AES_2ROUNDS(X) do { \ + sph_u32 X0 = (sph_u32)(X[0]); \ + sph_u32 X1 = (sph_u32)(X[0] >> 32); \ + sph_u32 X2 = (sph_u32)(X[1]); \ + sph_u32 X3 = (sph_u32)(X[1] >> 32); \ + sph_u32 Y0, Y1, Y2, Y3; \ + AES_ROUND_LE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3); \ + AES_ROUND_NOKEY_LE(Y0, Y1, Y2, Y3, X0, X1, X2, X3); \ + X[0] = (sph_u64)X0 | ((sph_u64)X1 << 32); \ + X[1] = (sph_u64)X2 | ((sph_u64)X3 << 32); \ + if ((K0 = T32(K0 + 1)) == 0) { \ + if ((K1 = T32(K1 + 1)) == 0) \ + if ((K2 = T32(K2 + 1)) == 0) \ + K3 = T32(K3 + 1); \ + } \ + } while (0) + +#define BIG_SUB_WORDS do { \ + AES_2ROUNDS(W[ 0]); \ + AES_2ROUNDS(W[ 1]); \ + AES_2ROUNDS(W[ 2]); \ + AES_2ROUNDS(W[ 3]); \ + AES_2ROUNDS(W[ 4]); \ + AES_2ROUNDS(W[ 5]); \ + AES_2ROUNDS(W[ 6]); \ + AES_2ROUNDS(W[ 7]); \ + AES_2ROUNDS(W[ 8]); \ + AES_2ROUNDS(W[ 9]); \ + AES_2ROUNDS(W[10]); \ + AES_2ROUNDS(W[11]); \ + AES_2ROUNDS(W[12]); \ + AES_2ROUNDS(W[13]); \ + AES_2ROUNDS(W[14]); \ + AES_2ROUNDS(W[15]); \ + } while (0) + +#endif + +#define SHIFT_ROW1(a, b, c, d) do { \ + sph_u64 tmp; \ + tmp = W[a][0]; \ + W[a][0] = W[b][0]; \ + W[b][0] = W[c][0]; \ + W[c][0] = W[d][0]; \ + W[d][0] = tmp; \ + tmp = W[a][1]; \ + W[a][1] = W[b][1]; \ + W[b][1] = W[c][1]; \ + W[c][1] = W[d][1]; \ + W[d][1] = tmp; \ + } while (0) + +#define SHIFT_ROW2(a, b, c, d) do { \ + sph_u64 tmp; \ + tmp = W[a][0]; \ + W[a][0] = W[c][0]; \ + W[c][0] = tmp; \ + tmp = W[b][0]; \ + W[b][0] = W[d][0]; \ + W[d][0] = tmp; \ + tmp = W[a][1]; \ + W[a][1] = W[c][1]; \ + W[c][1] = tmp; \ + tmp = W[b][1]; \ + W[b][1] = W[d][1]; \ + W[d][1] = tmp; \ + } while (0) + +#define SHIFT_ROW3(a, b, c, d) SHIFT_ROW1(d, c, b, a) + +#define BIG_SHIFT_ROWS do { \ + SHIFT_ROW1(1, 5, 9, 13); \ + SHIFT_ROW2(2, 6, 10, 14); \ + SHIFT_ROW3(3, 7, 11, 15); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_ECHO + +static void +mix_column(sph_u64 W[16][2], int ia, int ib, int ic, int id) +{ + int n; + + for (n = 0; n < 2; n ++) { + sph_u64 a = W[ia][n]; + sph_u64 b = W[ib][n]; + sph_u64 c = W[ic][n]; + sph_u64 d = W[id][n]; + sph_u64 ab = a ^ b; + sph_u64 bc = b ^ c; + sph_u64 cd = c ^ d; + sph_u64 abx = ((ab & C64(0x8080808080808080)) >> 7) * 27U + ^ ((ab & C64(0x7F7F7F7F7F7F7F7F)) << 1); + sph_u64 bcx = ((bc & C64(0x8080808080808080)) >> 7) * 27U + ^ ((bc & C64(0x7F7F7F7F7F7F7F7F)) << 1); + sph_u64 cdx = ((cd & C64(0x8080808080808080)) >> 7) * 27U + ^ ((cd & C64(0x7F7F7F7F7F7F7F7F)) << 1); + W[ia][n] = abx ^ bc ^ d; + W[ib][n] = bcx ^ a ^ cd; + W[ic][n] = cdx ^ ab ^ d; + W[id][n] = abx ^ bcx ^ cdx ^ ab ^ c; + } +} + +#define MIX_COLUMN(a, b, c, d) mix_column(W, a, b, c, d) + +#else + +#define MIX_COLUMN1(ia, ib, ic, id, n) do { \ + sph_u64 a = W[ia][n]; \ + sph_u64 b = W[ib][n]; \ + sph_u64 c = W[ic][n]; \ + sph_u64 d = W[id][n]; \ + sph_u64 ab = a ^ b; \ + sph_u64 bc = b ^ c; \ + sph_u64 cd = c ^ d; \ + sph_u64 abx = ((ab & C64(0x8080808080808080)) >> 7) * 27U \ + ^ ((ab & C64(0x7F7F7F7F7F7F7F7F)) << 1); \ + sph_u64 bcx = ((bc & C64(0x8080808080808080)) >> 7) * 27U \ + ^ ((bc & C64(0x7F7F7F7F7F7F7F7F)) << 1); \ + sph_u64 cdx = ((cd & C64(0x8080808080808080)) >> 7) * 27U \ + ^ ((cd & C64(0x7F7F7F7F7F7F7F7F)) << 1); \ + W[ia][n] = abx ^ bc ^ d; \ + W[ib][n] = bcx ^ a ^ cd; \ + W[ic][n] = cdx ^ ab ^ d; \ + W[id][n] = abx ^ bcx ^ cdx ^ ab ^ c; \ + } while (0) + +#define MIX_COLUMN(a, b, c, d) do { \ + MIX_COLUMN1(a, b, c, d, 0); \ + MIX_COLUMN1(a, b, c, d, 1); \ + } while (0) + +#endif + +#define BIG_MIX_COLUMNS do { \ + MIX_COLUMN(0, 1, 2, 3); \ + MIX_COLUMN(4, 5, 6, 7); \ + MIX_COLUMN(8, 9, 10, 11); \ + MIX_COLUMN(12, 13, 14, 15); \ + } while (0) + +#define BIG_ROUND do { \ + BIG_SUB_WORDS; \ + BIG_SHIFT_ROWS; \ + BIG_MIX_COLUMNS; \ + } while (0) + +#define FINAL_SMALL do { \ + unsigned u; \ + sph_u64 *VV = &sc->u.Vb[0][0]; \ + sph_u64 *WW = &W[0][0]; \ + for (u = 0; u < 8; u ++) { \ + VV[u] ^= sph_dec64le_aligned(sc->buf + (u * 8)) \ + ^ sph_dec64le_aligned(sc->buf + (u * 8) + 64) \ + ^ sph_dec64le_aligned(sc->buf + (u * 8) + 128) \ + ^ WW[u] ^ WW[u + 8] \ + ^ WW[u + 16] ^ WW[u + 24]; \ + } \ + } while (0) + +#define FINAL_BIG do { \ + unsigned u; \ + sph_u64 *VV = &sc->u.Vb[0][0]; \ + sph_u64 *WW = &W[0][0]; \ + for (u = 0; u < 16; u ++) { \ + VV[u] ^= sph_dec64le_aligned(sc->buf + (u * 8)) \ + ^ WW[u] ^ WW[u + 16]; \ + } \ + } while (0) + +#define COMPRESS_SMALL(sc) do { \ + sph_u32 K0 = sc->C0; \ + sph_u32 K1 = sc->C1; \ + sph_u32 K2 = sc->C2; \ + sph_u32 K3 = sc->C3; \ + unsigned u; \ + INPUT_BLOCK_SMALL(sc); \ + for (u = 0; u < 8; u ++) { \ + BIG_ROUND; \ + } \ + FINAL_SMALL; \ + } while (0) + +#define COMPRESS_BIG(sc) do { \ + sph_u32 K0 = sc->C0; \ + sph_u32 K1 = sc->C1; \ + sph_u32 K2 = sc->C2; \ + sph_u32 K3 = sc->C3; \ + unsigned u; \ + INPUT_BLOCK_BIG(sc); \ + for (u = 0; u < 10; u ++) { \ + BIG_ROUND; \ + } \ + FINAL_BIG; \ + } while (0) + +#else + +#define DECL_STATE_SMALL \ + sph_u32 W[16][4]; + +#define DECL_STATE_BIG \ + sph_u32 W[16][4]; + +#define INPUT_BLOCK_SMALL(sc) do { \ + unsigned u; \ + memcpy(W, sc->u.Vs, 16 * sizeof(sph_u32)); \ + for (u = 0; u < 12; u ++) { \ + W[u + 4][0] = sph_dec32le_aligned( \ + sc->buf + 16 * u); \ + W[u + 4][1] = sph_dec32le_aligned( \ + sc->buf + 16 * u + 4); \ + W[u + 4][2] = sph_dec32le_aligned( \ + sc->buf + 16 * u + 8); \ + W[u + 4][3] = sph_dec32le_aligned( \ + sc->buf + 16 * u + 12); \ + } \ + } while (0) + +#define INPUT_BLOCK_BIG(sc) do { \ + unsigned u; \ + memcpy(W, sc->u.Vs, 32 * sizeof(sph_u32)); \ + for (u = 0; u < 8; u ++) { \ + W[u + 8][0] = sph_dec32le_aligned( \ + sc->buf + 16 * u); \ + W[u + 8][1] = sph_dec32le_aligned( \ + sc->buf + 16 * u + 4); \ + W[u + 8][2] = sph_dec32le_aligned( \ + sc->buf + 16 * u + 8); \ + W[u + 8][3] = sph_dec32le_aligned( \ + sc->buf + 16 * u + 12); \ + } \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_ECHO + +static void +aes_2rounds_all(sph_u32 W[16][4], + sph_u32 *pK0, sph_u32 *pK1, sph_u32 *pK2, sph_u32 *pK3) +{ + int n; + sph_u32 K0 = *pK0; + sph_u32 K1 = *pK1; + sph_u32 K2 = *pK2; + sph_u32 K3 = *pK3; + + for (n = 0; n < 16; n ++) { + sph_u32 *X = W[n]; + sph_u32 Y0, Y1, Y2, Y3; + AES_ROUND_LE(X[0], X[1], X[2], X[3], + K0, K1, K2, K3, Y0, Y1, Y2, Y3); + AES_ROUND_NOKEY_LE(Y0, Y1, Y2, Y3, X[0], X[1], X[2], X[3]); + if ((K0 = T32(K0 + 1)) == 0) { + if ((K1 = T32(K1 + 1)) == 0) + if ((K2 = T32(K2 + 1)) == 0) + K3 = T32(K3 + 1); + } + } + *pK0 = K0; + *pK1 = K1; + *pK2 = K2; + *pK3 = K3; +} + +#define BIG_SUB_WORDS do { \ + aes_2rounds_all(W, &K0, &K1, &K2, &K3); \ + } while (0) + +#else + +#define AES_2ROUNDS(X) do { \ + sph_u32 Y0, Y1, Y2, Y3; \ + AES_ROUND_LE(X[0], X[1], X[2], X[3], \ + K0, K1, K2, K3, Y0, Y1, Y2, Y3); \ + AES_ROUND_NOKEY_LE(Y0, Y1, Y2, Y3, X[0], X[1], X[2], X[3]); \ + if ((K0 = T32(K0 + 1)) == 0) { \ + if ((K1 = T32(K1 + 1)) == 0) \ + if ((K2 = T32(K2 + 1)) == 0) \ + K3 = T32(K3 + 1); \ + } \ + } while (0) + +#define BIG_SUB_WORDS do { \ + AES_2ROUNDS(W[ 0]); \ + AES_2ROUNDS(W[ 1]); \ + AES_2ROUNDS(W[ 2]); \ + AES_2ROUNDS(W[ 3]); \ + AES_2ROUNDS(W[ 4]); \ + AES_2ROUNDS(W[ 5]); \ + AES_2ROUNDS(W[ 6]); \ + AES_2ROUNDS(W[ 7]); \ + AES_2ROUNDS(W[ 8]); \ + AES_2ROUNDS(W[ 9]); \ + AES_2ROUNDS(W[10]); \ + AES_2ROUNDS(W[11]); \ + AES_2ROUNDS(W[12]); \ + AES_2ROUNDS(W[13]); \ + AES_2ROUNDS(W[14]); \ + AES_2ROUNDS(W[15]); \ + } while (0) + +#endif + +#define SHIFT_ROW1(a, b, c, d) do { \ + sph_u32 tmp; \ + tmp = W[a][0]; \ + W[a][0] = W[b][0]; \ + W[b][0] = W[c][0]; \ + W[c][0] = W[d][0]; \ + W[d][0] = tmp; \ + tmp = W[a][1]; \ + W[a][1] = W[b][1]; \ + W[b][1] = W[c][1]; \ + W[c][1] = W[d][1]; \ + W[d][1] = tmp; \ + tmp = W[a][2]; \ + W[a][2] = W[b][2]; \ + W[b][2] = W[c][2]; \ + W[c][2] = W[d][2]; \ + W[d][2] = tmp; \ + tmp = W[a][3]; \ + W[a][3] = W[b][3]; \ + W[b][3] = W[c][3]; \ + W[c][3] = W[d][3]; \ + W[d][3] = tmp; \ + } while (0) + +#define SHIFT_ROW2(a, b, c, d) do { \ + sph_u32 tmp; \ + tmp = W[a][0]; \ + W[a][0] = W[c][0]; \ + W[c][0] = tmp; \ + tmp = W[b][0]; \ + W[b][0] = W[d][0]; \ + W[d][0] = tmp; \ + tmp = W[a][1]; \ + W[a][1] = W[c][1]; \ + W[c][1] = tmp; \ + tmp = W[b][1]; \ + W[b][1] = W[d][1]; \ + W[d][1] = tmp; \ + tmp = W[a][2]; \ + W[a][2] = W[c][2]; \ + W[c][2] = tmp; \ + tmp = W[b][2]; \ + W[b][2] = W[d][2]; \ + W[d][2] = tmp; \ + tmp = W[a][3]; \ + W[a][3] = W[c][3]; \ + W[c][3] = tmp; \ + tmp = W[b][3]; \ + W[b][3] = W[d][3]; \ + W[d][3] = tmp; \ + } while (0) + +#define SHIFT_ROW3(a, b, c, d) SHIFT_ROW1(d, c, b, a) + +#define BIG_SHIFT_ROWS do { \ + SHIFT_ROW1(1, 5, 9, 13); \ + SHIFT_ROW2(2, 6, 10, 14); \ + SHIFT_ROW3(3, 7, 11, 15); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_ECHO + +static void +mix_column(sph_u32 W[16][4], int ia, int ib, int ic, int id) +{ + int n; + + for (n = 0; n < 4; n ++) { + sph_u32 a = W[ia][n]; + sph_u32 b = W[ib][n]; + sph_u32 c = W[ic][n]; + sph_u32 d = W[id][n]; + sph_u32 ab = a ^ b; + sph_u32 bc = b ^ c; + sph_u32 cd = c ^ d; + sph_u32 abx = ((ab & C32(0x80808080)) >> 7) * 27U + ^ ((ab & C32(0x7F7F7F7F)) << 1); + sph_u32 bcx = ((bc & C32(0x80808080)) >> 7) * 27U + ^ ((bc & C32(0x7F7F7F7F)) << 1); + sph_u32 cdx = ((cd & C32(0x80808080)) >> 7) * 27U + ^ ((cd & C32(0x7F7F7F7F)) << 1); + W[ia][n] = abx ^ bc ^ d; + W[ib][n] = bcx ^ a ^ cd; + W[ic][n] = cdx ^ ab ^ d; + W[id][n] = abx ^ bcx ^ cdx ^ ab ^ c; + } +} + +#define MIX_COLUMN(a, b, c, d) mix_column(W, a, b, c, d) + +#else + +#define MIX_COLUMN1(ia, ib, ic, id, n) do { \ + sph_u32 a = W[ia][n]; \ + sph_u32 b = W[ib][n]; \ + sph_u32 c = W[ic][n]; \ + sph_u32 d = W[id][n]; \ + sph_u32 ab = a ^ b; \ + sph_u32 bc = b ^ c; \ + sph_u32 cd = c ^ d; \ + sph_u32 abx = ((ab & C32(0x80808080)) >> 7) * 27U \ + ^ ((ab & C32(0x7F7F7F7F)) << 1); \ + sph_u32 bcx = ((bc & C32(0x80808080)) >> 7) * 27U \ + ^ ((bc & C32(0x7F7F7F7F)) << 1); \ + sph_u32 cdx = ((cd & C32(0x80808080)) >> 7) * 27U \ + ^ ((cd & C32(0x7F7F7F7F)) << 1); \ + W[ia][n] = abx ^ bc ^ d; \ + W[ib][n] = bcx ^ a ^ cd; \ + W[ic][n] = cdx ^ ab ^ d; \ + W[id][n] = abx ^ bcx ^ cdx ^ ab ^ c; \ + } while (0) + +#define MIX_COLUMN(a, b, c, d) do { \ + MIX_COLUMN1(a, b, c, d, 0); \ + MIX_COLUMN1(a, b, c, d, 1); \ + MIX_COLUMN1(a, b, c, d, 2); \ + MIX_COLUMN1(a, b, c, d, 3); \ + } while (0) + +#endif + +#define BIG_MIX_COLUMNS do { \ + MIX_COLUMN(0, 1, 2, 3); \ + MIX_COLUMN(4, 5, 6, 7); \ + MIX_COLUMN(8, 9, 10, 11); \ + MIX_COLUMN(12, 13, 14, 15); \ + } while (0) + +#define BIG_ROUND do { \ + BIG_SUB_WORDS; \ + BIG_SHIFT_ROWS; \ + BIG_MIX_COLUMNS; \ + } while (0) + +#define FINAL_SMALL do { \ + unsigned u; \ + sph_u32 *VV = &sc->u.Vs[0][0]; \ + sph_u32 *WW = &W[0][0]; \ + for (u = 0; u < 16; u ++) { \ + VV[u] ^= sph_dec32le_aligned(sc->buf + (u * 4)) \ + ^ sph_dec32le_aligned(sc->buf + (u * 4) + 64) \ + ^ sph_dec32le_aligned(sc->buf + (u * 4) + 128) \ + ^ WW[u] ^ WW[u + 16] \ + ^ WW[u + 32] ^ WW[u + 48]; \ + } \ + } while (0) + +#define FINAL_BIG do { \ + unsigned u; \ + sph_u32 *VV = &sc->u.Vs[0][0]; \ + sph_u32 *WW = &W[0][0]; \ + for (u = 0; u < 32; u ++) { \ + VV[u] ^= sph_dec32le_aligned(sc->buf + (u * 4)) \ + ^ WW[u] ^ WW[u + 32]; \ + } \ + } while (0) + +#define COMPRESS_SMALL(sc) do { \ + sph_u32 K0 = sc->C0; \ + sph_u32 K1 = sc->C1; \ + sph_u32 K2 = sc->C2; \ + sph_u32 K3 = sc->C3; \ + unsigned u; \ + INPUT_BLOCK_SMALL(sc); \ + for (u = 0; u < 8; u ++) { \ + BIG_ROUND; \ + } \ + FINAL_SMALL; \ + } while (0) + +#define COMPRESS_BIG(sc) do { \ + sph_u32 K0 = sc->C0; \ + sph_u32 K1 = sc->C1; \ + sph_u32 K2 = sc->C2; \ + sph_u32 K3 = sc->C3; \ + unsigned u; \ + INPUT_BLOCK_BIG(sc); \ + for (u = 0; u < 10; u ++) { \ + BIG_ROUND; \ + } \ + FINAL_BIG; \ + } while (0) + +#endif + +#define INCR_COUNTER(sc, val) do { \ + sc->C0 = T32(sc->C0 + (sph_u32)(val)); \ + if (sc->C0 < (sph_u32)(val)) { \ + if ((sc->C1 = T32(sc->C1 + 1)) == 0) \ + if ((sc->C2 = T32(sc->C2 + 1)) == 0) \ + sc->C3 = T32(sc->C3 + 1); \ + } \ + } while (0) + +static void +echo_small_init(sph_echo_small_context *sc, unsigned out_len) +{ +#if SPH_ECHO_64 + sc->u.Vb[0][0] = (sph_u64)out_len; + sc->u.Vb[0][1] = 0; + sc->u.Vb[1][0] = (sph_u64)out_len; + sc->u.Vb[1][1] = 0; + sc->u.Vb[2][0] = (sph_u64)out_len; + sc->u.Vb[2][1] = 0; + sc->u.Vb[3][0] = (sph_u64)out_len; + sc->u.Vb[3][1] = 0; +#else + sc->u.Vs[0][0] = (sph_u32)out_len; + sc->u.Vs[0][1] = sc->u.Vs[0][2] = sc->u.Vs[0][3] = 0; + sc->u.Vs[1][0] = (sph_u32)out_len; + sc->u.Vs[1][1] = sc->u.Vs[1][2] = sc->u.Vs[1][3] = 0; + sc->u.Vs[2][0] = (sph_u32)out_len; + sc->u.Vs[2][1] = sc->u.Vs[2][2] = sc->u.Vs[2][3] = 0; + sc->u.Vs[3][0] = (sph_u32)out_len; + sc->u.Vs[3][1] = sc->u.Vs[3][2] = sc->u.Vs[3][3] = 0; +#endif + sc->ptr = 0; + sc->C0 = sc->C1 = sc->C2 = sc->C3 = 0; +} + +static void +echo_big_init(sph_echo_big_context *sc, unsigned out_len) +{ +#if SPH_ECHO_64 + sc->u.Vb[0][0] = (sph_u64)out_len; + sc->u.Vb[0][1] = 0; + sc->u.Vb[1][0] = (sph_u64)out_len; + sc->u.Vb[1][1] = 0; + sc->u.Vb[2][0] = (sph_u64)out_len; + sc->u.Vb[2][1] = 0; + sc->u.Vb[3][0] = (sph_u64)out_len; + sc->u.Vb[3][1] = 0; + sc->u.Vb[4][0] = (sph_u64)out_len; + sc->u.Vb[4][1] = 0; + sc->u.Vb[5][0] = (sph_u64)out_len; + sc->u.Vb[5][1] = 0; + sc->u.Vb[6][0] = (sph_u64)out_len; + sc->u.Vb[6][1] = 0; + sc->u.Vb[7][0] = (sph_u64)out_len; + sc->u.Vb[7][1] = 0; +#else + sc->u.Vs[0][0] = (sph_u32)out_len; + sc->u.Vs[0][1] = sc->u.Vs[0][2] = sc->u.Vs[0][3] = 0; + sc->u.Vs[1][0] = (sph_u32)out_len; + sc->u.Vs[1][1] = sc->u.Vs[1][2] = sc->u.Vs[1][3] = 0; + sc->u.Vs[2][0] = (sph_u32)out_len; + sc->u.Vs[2][1] = sc->u.Vs[2][2] = sc->u.Vs[2][3] = 0; + sc->u.Vs[3][0] = (sph_u32)out_len; + sc->u.Vs[3][1] = sc->u.Vs[3][2] = sc->u.Vs[3][3] = 0; + sc->u.Vs[4][0] = (sph_u32)out_len; + sc->u.Vs[4][1] = sc->u.Vs[4][2] = sc->u.Vs[4][3] = 0; + sc->u.Vs[5][0] = (sph_u32)out_len; + sc->u.Vs[5][1] = sc->u.Vs[5][2] = sc->u.Vs[5][3] = 0; + sc->u.Vs[6][0] = (sph_u32)out_len; + sc->u.Vs[6][1] = sc->u.Vs[6][2] = sc->u.Vs[6][3] = 0; + sc->u.Vs[7][0] = (sph_u32)out_len; + sc->u.Vs[7][1] = sc->u.Vs[7][2] = sc->u.Vs[7][3] = 0; +#endif + sc->ptr = 0; + sc->C0 = sc->C1 = sc->C2 = sc->C3 = 0; +} + +static void +echo_small_compress(sph_echo_small_context *sc) +{ + DECL_STATE_SMALL + + COMPRESS_SMALL(sc); +} + +static void +echo_big_compress(sph_echo_big_context *sc) +{ + DECL_STATE_BIG + + COMPRESS_BIG(sc); +} + +static void +echo_small_core(sph_echo_small_context *sc, + const unsigned char *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + + buf = sc->buf; + ptr = sc->ptr; + if (len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - ptr; + if (clen > len) + clen = len; + memcpy(buf + ptr, data, clen); + ptr += clen; + data += clen; + len -= clen; + if (ptr == sizeof sc->buf) { + INCR_COUNTER(sc, 1536); + echo_small_compress(sc); + ptr = 0; + } + } + sc->ptr = ptr; +} + +static void +echo_big_core(sph_echo_big_context *sc, + const unsigned char *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + + buf = sc->buf; + ptr = sc->ptr; + if (len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - ptr; + if (clen > len) + clen = len; + memcpy(buf + ptr, data, clen); + ptr += clen; + data += clen; + len -= clen; + if (ptr == sizeof sc->buf) { + INCR_COUNTER(sc, 1024); + echo_big_compress(sc); + ptr = 0; + } + } + sc->ptr = ptr; +} + +static void +echo_small_close(sph_echo_small_context *sc, unsigned ub, unsigned n, + void *dst, unsigned out_size_w32) +{ + unsigned char *buf; + size_t ptr; + unsigned z; + unsigned elen; + union { + unsigned char tmp[32]; + sph_u32 dummy; +#if SPH_ECHO_64 + sph_u64 dummy2; +#endif + } u; +#if SPH_ECHO_64 + sph_u64 *VV; +#else + sph_u32 *VV; +#endif + unsigned k; + + buf = sc->buf; + ptr = sc->ptr; + elen = ((unsigned)ptr << 3) + n; + INCR_COUNTER(sc, elen); + sph_enc32le_aligned(u.tmp, sc->C0); + sph_enc32le_aligned(u.tmp + 4, sc->C1); + sph_enc32le_aligned(u.tmp + 8, sc->C2); + sph_enc32le_aligned(u.tmp + 12, sc->C3); + /* + * If elen is zero, then this block actually contains no message + * bit, only the first padding bit. + */ + if (elen == 0) { + sc->C0 = sc->C1 = sc->C2 = sc->C3 = 0; + } + z = 0x80 >> n; + buf[ptr ++] = ((ub & -z) | z) & 0xFF; + memset(buf + ptr, 0, (sizeof sc->buf) - ptr); + if (ptr > ((sizeof sc->buf) - 18)) { + echo_small_compress(sc); + sc->C0 = sc->C1 = sc->C2 = sc->C3 = 0; + memset(buf, 0, sizeof sc->buf); + } + sph_enc16le(buf + (sizeof sc->buf) - 18, out_size_w32 << 5); + memcpy(buf + (sizeof sc->buf) - 16, u.tmp, 16); + echo_small_compress(sc); +#if SPH_ECHO_64 + for (VV = &sc->u.Vb[0][0], k = 0; k < ((out_size_w32 + 1) >> 1); k ++) + sph_enc64le_aligned(u.tmp + (k << 3), VV[k]); +#else + for (VV = &sc->u.Vs[0][0], k = 0; k < out_size_w32; k ++) + sph_enc32le_aligned(u.tmp + (k << 2), VV[k]); +#endif + memcpy(dst, u.tmp, out_size_w32 << 2); + echo_small_init(sc, out_size_w32 << 5); +} + +static void +echo_big_close(sph_echo_big_context *sc, unsigned ub, unsigned n, + void *dst, unsigned out_size_w32) +{ + unsigned char *buf; + size_t ptr; + unsigned z; + unsigned elen; + union { + unsigned char tmp[64]; + sph_u32 dummy; +#if SPH_ECHO_64 + sph_u64 dummy2; +#endif + } u; +#if SPH_ECHO_64 + sph_u64 *VV; +#else + sph_u32 *VV; +#endif + unsigned k; + + buf = sc->buf; + ptr = sc->ptr; + elen = ((unsigned)ptr << 3) + n; + INCR_COUNTER(sc, elen); + sph_enc32le_aligned(u.tmp, sc->C0); + sph_enc32le_aligned(u.tmp + 4, sc->C1); + sph_enc32le_aligned(u.tmp + 8, sc->C2); + sph_enc32le_aligned(u.tmp + 12, sc->C3); + /* + * If elen is zero, then this block actually contains no message + * bit, only the first padding bit. + */ + if (elen == 0) { + sc->C0 = sc->C1 = sc->C2 = sc->C3 = 0; + } + z = 0x80 >> n; + buf[ptr ++] = ((ub & -z) | z) & 0xFF; + memset(buf + ptr, 0, (sizeof sc->buf) - ptr); + if (ptr > ((sizeof sc->buf) - 18)) { + echo_big_compress(sc); + sc->C0 = sc->C1 = sc->C2 = sc->C3 = 0; + memset(buf, 0, sizeof sc->buf); + } + sph_enc16le(buf + (sizeof sc->buf) - 18, out_size_w32 << 5); + memcpy(buf + (sizeof sc->buf) - 16, u.tmp, 16); + echo_big_compress(sc); +#if SPH_ECHO_64 + for (VV = &sc->u.Vb[0][0], k = 0; k < ((out_size_w32 + 1) >> 1); k ++) + sph_enc64le_aligned(u.tmp + (k << 3), VV[k]); +#else + for (VV = &sc->u.Vs[0][0], k = 0; k < out_size_w32; k ++) + sph_enc32le_aligned(u.tmp + (k << 2), VV[k]); +#endif + memcpy(dst, u.tmp, out_size_w32 << 2); + echo_big_init(sc, out_size_w32 << 5); +} + +/* see sph_echo.h */ +void +sph_echo224_init(void *cc) +{ + echo_small_init(cc, 224); +} + +/* see sph_echo.h */ +void +sph_echo224(void *cc, const void *data, size_t len) +{ + echo_small_core(cc, data, len); +} + +/* see sph_echo.h */ +void +sph_echo224_close(void *cc, void *dst) +{ + echo_small_close(cc, 0, 0, dst, 7); +} + +/* see sph_echo.h */ +void +sph_echo224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + echo_small_close(cc, ub, n, dst, 7); +} + +/* see sph_echo.h */ +void +sph_echo256_init(void *cc) +{ + echo_small_init(cc, 256); +} + +/* see sph_echo.h */ +void +sph_echo256(void *cc, const void *data, size_t len) +{ + echo_small_core(cc, data, len); +} + +/* see sph_echo.h */ +void +sph_echo256_close(void *cc, void *dst) +{ + echo_small_close(cc, 0, 0, dst, 8); +} + +/* see sph_echo.h */ +void +sph_echo256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + echo_small_close(cc, ub, n, dst, 8); +} + +/* see sph_echo.h */ +void +sph_echo384_init(void *cc) +{ + echo_big_init(cc, 384); +} + +/* see sph_echo.h */ +void +sph_echo384(void *cc, const void *data, size_t len) +{ + echo_big_core(cc, data, len); +} + +/* see sph_echo.h */ +void +sph_echo384_close(void *cc, void *dst) +{ + echo_big_close(cc, 0, 0, dst, 12); +} + +/* see sph_echo.h */ +void +sph_echo384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + echo_big_close(cc, ub, n, dst, 12); +} + +/* see sph_echo.h */ +void +sph_echo512_init(void *cc) +{ + echo_big_init(cc, 512); +} + +/* see sph_echo.h */ +void +sph_echo512(void *cc, const void *data, size_t len) +{ + echo_big_core(cc, data, len); +} + +/* see sph_echo.h */ +void +sph_echo512_close(void *cc, void *dst) +{ + echo_big_close(cc, 0, 0, dst, 16); +} + +/* see sph_echo.h */ +void +sph_echo512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + echo_big_close(cc, ub, n, dst, 16); +} +#ifdef __cplusplus +} +#endif diff --git a/src/fugue.c b/src/fugue.c new file mode 100644 index 0000000..85767c9 --- /dev/null +++ b/src/fugue.c @@ -0,0 +1,1208 @@ +#include +#include + +#include "sph_fugue.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +static const sph_u32 IV224[] = { + SPH_C32(0xf4c9120d), SPH_C32(0x6286f757), SPH_C32(0xee39e01c), + SPH_C32(0xe074e3cb), SPH_C32(0xa1127c62), SPH_C32(0x9a43d215), + SPH_C32(0xbd8d679a) +}; + +static const sph_u32 IV256[] = { + SPH_C32(0xe952bdde), SPH_C32(0x6671135f), SPH_C32(0xe0d4f668), + SPH_C32(0xd2b0b594), SPH_C32(0xf96c621d), SPH_C32(0xfbf929de), + SPH_C32(0x9149e899), SPH_C32(0x34f8c248) +}; + +static const sph_u32 IV384[] = { + SPH_C32(0xaa61ec0d), SPH_C32(0x31252e1f), SPH_C32(0xa01db4c7), + SPH_C32(0x00600985), SPH_C32(0x215ef44a), SPH_C32(0x741b5e9c), + SPH_C32(0xfa693e9a), SPH_C32(0x473eb040), SPH_C32(0xe502ae8a), + SPH_C32(0xa99c25e0), SPH_C32(0xbc95517c), SPH_C32(0x5c1095a1) +}; + +static const sph_u32 IV512[] = { + SPH_C32(0x8807a57e), SPH_C32(0xe616af75), SPH_C32(0xc5d3e4db), + SPH_C32(0xac9ab027), SPH_C32(0xd915f117), SPH_C32(0xb6eecc54), + SPH_C32(0x06e8020b), SPH_C32(0x4a92efd1), SPH_C32(0xaac6e2c9), + SPH_C32(0xddb21398), SPH_C32(0xcae65838), SPH_C32(0x437f203f), + SPH_C32(0x25ea78e7), SPH_C32(0x951fddd6), SPH_C32(0xda6ed11d), + SPH_C32(0xe13e3567) +}; + +static const sph_u32 mixtab0[] = { + SPH_C32(0x63633297), SPH_C32(0x7c7c6feb), SPH_C32(0x77775ec7), + SPH_C32(0x7b7b7af7), SPH_C32(0xf2f2e8e5), SPH_C32(0x6b6b0ab7), + SPH_C32(0x6f6f16a7), SPH_C32(0xc5c56d39), SPH_C32(0x303090c0), + SPH_C32(0x01010704), SPH_C32(0x67672e87), SPH_C32(0x2b2bd1ac), + SPH_C32(0xfefeccd5), SPH_C32(0xd7d71371), SPH_C32(0xabab7c9a), + SPH_C32(0x767659c3), SPH_C32(0xcaca4005), SPH_C32(0x8282a33e), + SPH_C32(0xc9c94909), SPH_C32(0x7d7d68ef), SPH_C32(0xfafad0c5), + SPH_C32(0x5959947f), SPH_C32(0x4747ce07), SPH_C32(0xf0f0e6ed), + SPH_C32(0xadad6e82), SPH_C32(0xd4d41a7d), SPH_C32(0xa2a243be), + SPH_C32(0xafaf608a), SPH_C32(0x9c9cf946), SPH_C32(0xa4a451a6), + SPH_C32(0x727245d3), SPH_C32(0xc0c0762d), SPH_C32(0xb7b728ea), + SPH_C32(0xfdfdc5d9), SPH_C32(0x9393d47a), SPH_C32(0x2626f298), + SPH_C32(0x363682d8), SPH_C32(0x3f3fbdfc), SPH_C32(0xf7f7f3f1), + SPH_C32(0xcccc521d), SPH_C32(0x34348cd0), SPH_C32(0xa5a556a2), + SPH_C32(0xe5e58db9), SPH_C32(0xf1f1e1e9), SPH_C32(0x71714cdf), + SPH_C32(0xd8d83e4d), SPH_C32(0x313197c4), SPH_C32(0x15156b54), + SPH_C32(0x04041c10), SPH_C32(0xc7c76331), SPH_C32(0x2323e98c), + SPH_C32(0xc3c37f21), SPH_C32(0x18184860), SPH_C32(0x9696cf6e), + SPH_C32(0x05051b14), SPH_C32(0x9a9aeb5e), SPH_C32(0x0707151c), + SPH_C32(0x12127e48), SPH_C32(0x8080ad36), SPH_C32(0xe2e298a5), + SPH_C32(0xebeba781), SPH_C32(0x2727f59c), SPH_C32(0xb2b233fe), + SPH_C32(0x757550cf), SPH_C32(0x09093f24), SPH_C32(0x8383a43a), + SPH_C32(0x2c2cc4b0), SPH_C32(0x1a1a4668), SPH_C32(0x1b1b416c), + SPH_C32(0x6e6e11a3), SPH_C32(0x5a5a9d73), SPH_C32(0xa0a04db6), + SPH_C32(0x5252a553), SPH_C32(0x3b3ba1ec), SPH_C32(0xd6d61475), + SPH_C32(0xb3b334fa), SPH_C32(0x2929dfa4), SPH_C32(0xe3e39fa1), + SPH_C32(0x2f2fcdbc), SPH_C32(0x8484b126), SPH_C32(0x5353a257), + SPH_C32(0xd1d10169), SPH_C32(0x00000000), SPH_C32(0xededb599), + SPH_C32(0x2020e080), SPH_C32(0xfcfcc2dd), SPH_C32(0xb1b13af2), + SPH_C32(0x5b5b9a77), SPH_C32(0x6a6a0db3), SPH_C32(0xcbcb4701), + SPH_C32(0xbebe17ce), SPH_C32(0x3939afe4), SPH_C32(0x4a4aed33), + SPH_C32(0x4c4cff2b), SPH_C32(0x5858937b), SPH_C32(0xcfcf5b11), + SPH_C32(0xd0d0066d), SPH_C32(0xefefbb91), SPH_C32(0xaaaa7b9e), + SPH_C32(0xfbfbd7c1), SPH_C32(0x4343d217), SPH_C32(0x4d4df82f), + SPH_C32(0x333399cc), SPH_C32(0x8585b622), SPH_C32(0x4545c00f), + SPH_C32(0xf9f9d9c9), SPH_C32(0x02020e08), SPH_C32(0x7f7f66e7), + SPH_C32(0x5050ab5b), SPH_C32(0x3c3cb4f0), SPH_C32(0x9f9ff04a), + SPH_C32(0xa8a87596), SPH_C32(0x5151ac5f), SPH_C32(0xa3a344ba), + SPH_C32(0x4040db1b), SPH_C32(0x8f8f800a), SPH_C32(0x9292d37e), + SPH_C32(0x9d9dfe42), SPH_C32(0x3838a8e0), SPH_C32(0xf5f5fdf9), + SPH_C32(0xbcbc19c6), SPH_C32(0xb6b62fee), SPH_C32(0xdada3045), + SPH_C32(0x2121e784), SPH_C32(0x10107040), SPH_C32(0xffffcbd1), + SPH_C32(0xf3f3efe1), SPH_C32(0xd2d20865), SPH_C32(0xcdcd5519), + SPH_C32(0x0c0c2430), SPH_C32(0x1313794c), SPH_C32(0xececb29d), + SPH_C32(0x5f5f8667), SPH_C32(0x9797c86a), SPH_C32(0x4444c70b), + SPH_C32(0x1717655c), SPH_C32(0xc4c46a3d), SPH_C32(0xa7a758aa), + SPH_C32(0x7e7e61e3), SPH_C32(0x3d3db3f4), SPH_C32(0x6464278b), + SPH_C32(0x5d5d886f), SPH_C32(0x19194f64), SPH_C32(0x737342d7), + SPH_C32(0x60603b9b), SPH_C32(0x8181aa32), SPH_C32(0x4f4ff627), + SPH_C32(0xdcdc225d), SPH_C32(0x2222ee88), SPH_C32(0x2a2ad6a8), + SPH_C32(0x9090dd76), SPH_C32(0x88889516), SPH_C32(0x4646c903), + SPH_C32(0xeeeebc95), SPH_C32(0xb8b805d6), SPH_C32(0x14146c50), + SPH_C32(0xdede2c55), SPH_C32(0x5e5e8163), SPH_C32(0x0b0b312c), + SPH_C32(0xdbdb3741), SPH_C32(0xe0e096ad), SPH_C32(0x32329ec8), + SPH_C32(0x3a3aa6e8), SPH_C32(0x0a0a3628), SPH_C32(0x4949e43f), + SPH_C32(0x06061218), SPH_C32(0x2424fc90), SPH_C32(0x5c5c8f6b), + SPH_C32(0xc2c27825), SPH_C32(0xd3d30f61), SPH_C32(0xacac6986), + SPH_C32(0x62623593), SPH_C32(0x9191da72), SPH_C32(0x9595c662), + SPH_C32(0xe4e48abd), SPH_C32(0x797974ff), SPH_C32(0xe7e783b1), + SPH_C32(0xc8c84e0d), SPH_C32(0x373785dc), SPH_C32(0x6d6d18af), + SPH_C32(0x8d8d8e02), SPH_C32(0xd5d51d79), SPH_C32(0x4e4ef123), + SPH_C32(0xa9a97292), SPH_C32(0x6c6c1fab), SPH_C32(0x5656b943), + SPH_C32(0xf4f4fafd), SPH_C32(0xeaeaa085), SPH_C32(0x6565208f), + SPH_C32(0x7a7a7df3), SPH_C32(0xaeae678e), SPH_C32(0x08083820), + SPH_C32(0xbaba0bde), SPH_C32(0x787873fb), SPH_C32(0x2525fb94), + SPH_C32(0x2e2ecab8), SPH_C32(0x1c1c5470), SPH_C32(0xa6a65fae), + SPH_C32(0xb4b421e6), SPH_C32(0xc6c66435), SPH_C32(0xe8e8ae8d), + SPH_C32(0xdddd2559), SPH_C32(0x747457cb), SPH_C32(0x1f1f5d7c), + SPH_C32(0x4b4bea37), SPH_C32(0xbdbd1ec2), SPH_C32(0x8b8b9c1a), + SPH_C32(0x8a8a9b1e), SPH_C32(0x70704bdb), SPH_C32(0x3e3ebaf8), + SPH_C32(0xb5b526e2), SPH_C32(0x66662983), SPH_C32(0x4848e33b), + SPH_C32(0x0303090c), SPH_C32(0xf6f6f4f5), SPH_C32(0x0e0e2a38), + SPH_C32(0x61613c9f), SPH_C32(0x35358bd4), SPH_C32(0x5757be47), + SPH_C32(0xb9b902d2), SPH_C32(0x8686bf2e), SPH_C32(0xc1c17129), + SPH_C32(0x1d1d5374), SPH_C32(0x9e9ef74e), SPH_C32(0xe1e191a9), + SPH_C32(0xf8f8decd), SPH_C32(0x9898e556), SPH_C32(0x11117744), + SPH_C32(0x696904bf), SPH_C32(0xd9d93949), SPH_C32(0x8e8e870e), + SPH_C32(0x9494c166), SPH_C32(0x9b9bec5a), SPH_C32(0x1e1e5a78), + SPH_C32(0x8787b82a), SPH_C32(0xe9e9a989), SPH_C32(0xcece5c15), + SPH_C32(0x5555b04f), SPH_C32(0x2828d8a0), SPH_C32(0xdfdf2b51), + SPH_C32(0x8c8c8906), SPH_C32(0xa1a14ab2), SPH_C32(0x89899212), + SPH_C32(0x0d0d2334), SPH_C32(0xbfbf10ca), SPH_C32(0xe6e684b5), + SPH_C32(0x4242d513), SPH_C32(0x686803bb), SPH_C32(0x4141dc1f), + SPH_C32(0x9999e252), SPH_C32(0x2d2dc3b4), SPH_C32(0x0f0f2d3c), + SPH_C32(0xb0b03df6), SPH_C32(0x5454b74b), SPH_C32(0xbbbb0cda), + SPH_C32(0x16166258) +}; + +static const sph_u32 mixtab1[] = { + SPH_C32(0x97636332), SPH_C32(0xeb7c7c6f), SPH_C32(0xc777775e), + SPH_C32(0xf77b7b7a), SPH_C32(0xe5f2f2e8), SPH_C32(0xb76b6b0a), + SPH_C32(0xa76f6f16), SPH_C32(0x39c5c56d), SPH_C32(0xc0303090), + SPH_C32(0x04010107), SPH_C32(0x8767672e), SPH_C32(0xac2b2bd1), + SPH_C32(0xd5fefecc), SPH_C32(0x71d7d713), SPH_C32(0x9aabab7c), + SPH_C32(0xc3767659), SPH_C32(0x05caca40), SPH_C32(0x3e8282a3), + SPH_C32(0x09c9c949), SPH_C32(0xef7d7d68), SPH_C32(0xc5fafad0), + SPH_C32(0x7f595994), SPH_C32(0x074747ce), SPH_C32(0xedf0f0e6), + SPH_C32(0x82adad6e), SPH_C32(0x7dd4d41a), SPH_C32(0xbea2a243), + SPH_C32(0x8aafaf60), SPH_C32(0x469c9cf9), SPH_C32(0xa6a4a451), + SPH_C32(0xd3727245), SPH_C32(0x2dc0c076), SPH_C32(0xeab7b728), + SPH_C32(0xd9fdfdc5), SPH_C32(0x7a9393d4), SPH_C32(0x982626f2), + SPH_C32(0xd8363682), SPH_C32(0xfc3f3fbd), SPH_C32(0xf1f7f7f3), + SPH_C32(0x1dcccc52), SPH_C32(0xd034348c), SPH_C32(0xa2a5a556), + SPH_C32(0xb9e5e58d), SPH_C32(0xe9f1f1e1), SPH_C32(0xdf71714c), + SPH_C32(0x4dd8d83e), SPH_C32(0xc4313197), SPH_C32(0x5415156b), + SPH_C32(0x1004041c), SPH_C32(0x31c7c763), SPH_C32(0x8c2323e9), + SPH_C32(0x21c3c37f), SPH_C32(0x60181848), SPH_C32(0x6e9696cf), + SPH_C32(0x1405051b), SPH_C32(0x5e9a9aeb), SPH_C32(0x1c070715), + SPH_C32(0x4812127e), SPH_C32(0x368080ad), SPH_C32(0xa5e2e298), + SPH_C32(0x81ebeba7), SPH_C32(0x9c2727f5), SPH_C32(0xfeb2b233), + SPH_C32(0xcf757550), SPH_C32(0x2409093f), SPH_C32(0x3a8383a4), + SPH_C32(0xb02c2cc4), SPH_C32(0x681a1a46), SPH_C32(0x6c1b1b41), + SPH_C32(0xa36e6e11), SPH_C32(0x735a5a9d), SPH_C32(0xb6a0a04d), + SPH_C32(0x535252a5), SPH_C32(0xec3b3ba1), SPH_C32(0x75d6d614), + SPH_C32(0xfab3b334), SPH_C32(0xa42929df), SPH_C32(0xa1e3e39f), + SPH_C32(0xbc2f2fcd), SPH_C32(0x268484b1), SPH_C32(0x575353a2), + SPH_C32(0x69d1d101), SPH_C32(0x00000000), SPH_C32(0x99ededb5), + SPH_C32(0x802020e0), SPH_C32(0xddfcfcc2), SPH_C32(0xf2b1b13a), + SPH_C32(0x775b5b9a), SPH_C32(0xb36a6a0d), SPH_C32(0x01cbcb47), + SPH_C32(0xcebebe17), SPH_C32(0xe43939af), SPH_C32(0x334a4aed), + SPH_C32(0x2b4c4cff), SPH_C32(0x7b585893), SPH_C32(0x11cfcf5b), + SPH_C32(0x6dd0d006), SPH_C32(0x91efefbb), SPH_C32(0x9eaaaa7b), + SPH_C32(0xc1fbfbd7), SPH_C32(0x174343d2), SPH_C32(0x2f4d4df8), + SPH_C32(0xcc333399), SPH_C32(0x228585b6), SPH_C32(0x0f4545c0), + SPH_C32(0xc9f9f9d9), SPH_C32(0x0802020e), SPH_C32(0xe77f7f66), + SPH_C32(0x5b5050ab), SPH_C32(0xf03c3cb4), SPH_C32(0x4a9f9ff0), + SPH_C32(0x96a8a875), SPH_C32(0x5f5151ac), SPH_C32(0xbaa3a344), + SPH_C32(0x1b4040db), SPH_C32(0x0a8f8f80), SPH_C32(0x7e9292d3), + SPH_C32(0x429d9dfe), SPH_C32(0xe03838a8), SPH_C32(0xf9f5f5fd), + SPH_C32(0xc6bcbc19), SPH_C32(0xeeb6b62f), SPH_C32(0x45dada30), + SPH_C32(0x842121e7), SPH_C32(0x40101070), SPH_C32(0xd1ffffcb), + SPH_C32(0xe1f3f3ef), SPH_C32(0x65d2d208), SPH_C32(0x19cdcd55), + SPH_C32(0x300c0c24), SPH_C32(0x4c131379), SPH_C32(0x9dececb2), + SPH_C32(0x675f5f86), SPH_C32(0x6a9797c8), SPH_C32(0x0b4444c7), + SPH_C32(0x5c171765), SPH_C32(0x3dc4c46a), SPH_C32(0xaaa7a758), + SPH_C32(0xe37e7e61), SPH_C32(0xf43d3db3), SPH_C32(0x8b646427), + SPH_C32(0x6f5d5d88), SPH_C32(0x6419194f), SPH_C32(0xd7737342), + SPH_C32(0x9b60603b), SPH_C32(0x328181aa), SPH_C32(0x274f4ff6), + SPH_C32(0x5ddcdc22), SPH_C32(0x882222ee), SPH_C32(0xa82a2ad6), + SPH_C32(0x769090dd), SPH_C32(0x16888895), SPH_C32(0x034646c9), + SPH_C32(0x95eeeebc), SPH_C32(0xd6b8b805), SPH_C32(0x5014146c), + SPH_C32(0x55dede2c), SPH_C32(0x635e5e81), SPH_C32(0x2c0b0b31), + SPH_C32(0x41dbdb37), SPH_C32(0xade0e096), SPH_C32(0xc832329e), + SPH_C32(0xe83a3aa6), SPH_C32(0x280a0a36), SPH_C32(0x3f4949e4), + SPH_C32(0x18060612), SPH_C32(0x902424fc), SPH_C32(0x6b5c5c8f), + SPH_C32(0x25c2c278), SPH_C32(0x61d3d30f), SPH_C32(0x86acac69), + SPH_C32(0x93626235), SPH_C32(0x729191da), SPH_C32(0x629595c6), + SPH_C32(0xbde4e48a), SPH_C32(0xff797974), SPH_C32(0xb1e7e783), + SPH_C32(0x0dc8c84e), SPH_C32(0xdc373785), SPH_C32(0xaf6d6d18), + SPH_C32(0x028d8d8e), SPH_C32(0x79d5d51d), SPH_C32(0x234e4ef1), + SPH_C32(0x92a9a972), SPH_C32(0xab6c6c1f), SPH_C32(0x435656b9), + SPH_C32(0xfdf4f4fa), SPH_C32(0x85eaeaa0), SPH_C32(0x8f656520), + SPH_C32(0xf37a7a7d), SPH_C32(0x8eaeae67), SPH_C32(0x20080838), + SPH_C32(0xdebaba0b), SPH_C32(0xfb787873), SPH_C32(0x942525fb), + SPH_C32(0xb82e2eca), SPH_C32(0x701c1c54), SPH_C32(0xaea6a65f), + SPH_C32(0xe6b4b421), SPH_C32(0x35c6c664), SPH_C32(0x8de8e8ae), + SPH_C32(0x59dddd25), SPH_C32(0xcb747457), SPH_C32(0x7c1f1f5d), + SPH_C32(0x374b4bea), SPH_C32(0xc2bdbd1e), SPH_C32(0x1a8b8b9c), + SPH_C32(0x1e8a8a9b), SPH_C32(0xdb70704b), SPH_C32(0xf83e3eba), + SPH_C32(0xe2b5b526), SPH_C32(0x83666629), SPH_C32(0x3b4848e3), + SPH_C32(0x0c030309), SPH_C32(0xf5f6f6f4), SPH_C32(0x380e0e2a), + SPH_C32(0x9f61613c), SPH_C32(0xd435358b), SPH_C32(0x475757be), + SPH_C32(0xd2b9b902), SPH_C32(0x2e8686bf), SPH_C32(0x29c1c171), + SPH_C32(0x741d1d53), SPH_C32(0x4e9e9ef7), SPH_C32(0xa9e1e191), + SPH_C32(0xcdf8f8de), SPH_C32(0x569898e5), SPH_C32(0x44111177), + SPH_C32(0xbf696904), SPH_C32(0x49d9d939), SPH_C32(0x0e8e8e87), + SPH_C32(0x669494c1), SPH_C32(0x5a9b9bec), SPH_C32(0x781e1e5a), + SPH_C32(0x2a8787b8), SPH_C32(0x89e9e9a9), SPH_C32(0x15cece5c), + SPH_C32(0x4f5555b0), SPH_C32(0xa02828d8), SPH_C32(0x51dfdf2b), + SPH_C32(0x068c8c89), SPH_C32(0xb2a1a14a), SPH_C32(0x12898992), + SPH_C32(0x340d0d23), SPH_C32(0xcabfbf10), SPH_C32(0xb5e6e684), + SPH_C32(0x134242d5), SPH_C32(0xbb686803), SPH_C32(0x1f4141dc), + SPH_C32(0x529999e2), SPH_C32(0xb42d2dc3), SPH_C32(0x3c0f0f2d), + SPH_C32(0xf6b0b03d), SPH_C32(0x4b5454b7), SPH_C32(0xdabbbb0c), + SPH_C32(0x58161662) +}; + +static const sph_u32 mixtab2[] = { + SPH_C32(0x32976363), SPH_C32(0x6feb7c7c), SPH_C32(0x5ec77777), + SPH_C32(0x7af77b7b), SPH_C32(0xe8e5f2f2), SPH_C32(0x0ab76b6b), + SPH_C32(0x16a76f6f), SPH_C32(0x6d39c5c5), SPH_C32(0x90c03030), + SPH_C32(0x07040101), SPH_C32(0x2e876767), SPH_C32(0xd1ac2b2b), + SPH_C32(0xccd5fefe), SPH_C32(0x1371d7d7), SPH_C32(0x7c9aabab), + SPH_C32(0x59c37676), SPH_C32(0x4005caca), SPH_C32(0xa33e8282), + SPH_C32(0x4909c9c9), SPH_C32(0x68ef7d7d), SPH_C32(0xd0c5fafa), + SPH_C32(0x947f5959), SPH_C32(0xce074747), SPH_C32(0xe6edf0f0), + SPH_C32(0x6e82adad), SPH_C32(0x1a7dd4d4), SPH_C32(0x43bea2a2), + SPH_C32(0x608aafaf), SPH_C32(0xf9469c9c), SPH_C32(0x51a6a4a4), + SPH_C32(0x45d37272), SPH_C32(0x762dc0c0), SPH_C32(0x28eab7b7), + SPH_C32(0xc5d9fdfd), SPH_C32(0xd47a9393), SPH_C32(0xf2982626), + SPH_C32(0x82d83636), SPH_C32(0xbdfc3f3f), SPH_C32(0xf3f1f7f7), + SPH_C32(0x521dcccc), SPH_C32(0x8cd03434), SPH_C32(0x56a2a5a5), + SPH_C32(0x8db9e5e5), SPH_C32(0xe1e9f1f1), SPH_C32(0x4cdf7171), + SPH_C32(0x3e4dd8d8), SPH_C32(0x97c43131), SPH_C32(0x6b541515), + SPH_C32(0x1c100404), SPH_C32(0x6331c7c7), SPH_C32(0xe98c2323), + SPH_C32(0x7f21c3c3), SPH_C32(0x48601818), SPH_C32(0xcf6e9696), + SPH_C32(0x1b140505), SPH_C32(0xeb5e9a9a), SPH_C32(0x151c0707), + SPH_C32(0x7e481212), SPH_C32(0xad368080), SPH_C32(0x98a5e2e2), + SPH_C32(0xa781ebeb), SPH_C32(0xf59c2727), SPH_C32(0x33feb2b2), + SPH_C32(0x50cf7575), SPH_C32(0x3f240909), SPH_C32(0xa43a8383), + SPH_C32(0xc4b02c2c), SPH_C32(0x46681a1a), SPH_C32(0x416c1b1b), + SPH_C32(0x11a36e6e), SPH_C32(0x9d735a5a), SPH_C32(0x4db6a0a0), + SPH_C32(0xa5535252), SPH_C32(0xa1ec3b3b), SPH_C32(0x1475d6d6), + SPH_C32(0x34fab3b3), SPH_C32(0xdfa42929), SPH_C32(0x9fa1e3e3), + SPH_C32(0xcdbc2f2f), SPH_C32(0xb1268484), SPH_C32(0xa2575353), + SPH_C32(0x0169d1d1), SPH_C32(0x00000000), SPH_C32(0xb599eded), + SPH_C32(0xe0802020), SPH_C32(0xc2ddfcfc), SPH_C32(0x3af2b1b1), + SPH_C32(0x9a775b5b), SPH_C32(0x0db36a6a), SPH_C32(0x4701cbcb), + SPH_C32(0x17cebebe), SPH_C32(0xafe43939), SPH_C32(0xed334a4a), + SPH_C32(0xff2b4c4c), SPH_C32(0x937b5858), SPH_C32(0x5b11cfcf), + SPH_C32(0x066dd0d0), SPH_C32(0xbb91efef), SPH_C32(0x7b9eaaaa), + SPH_C32(0xd7c1fbfb), SPH_C32(0xd2174343), SPH_C32(0xf82f4d4d), + SPH_C32(0x99cc3333), SPH_C32(0xb6228585), SPH_C32(0xc00f4545), + SPH_C32(0xd9c9f9f9), SPH_C32(0x0e080202), SPH_C32(0x66e77f7f), + SPH_C32(0xab5b5050), SPH_C32(0xb4f03c3c), SPH_C32(0xf04a9f9f), + SPH_C32(0x7596a8a8), SPH_C32(0xac5f5151), SPH_C32(0x44baa3a3), + SPH_C32(0xdb1b4040), SPH_C32(0x800a8f8f), SPH_C32(0xd37e9292), + SPH_C32(0xfe429d9d), SPH_C32(0xa8e03838), SPH_C32(0xfdf9f5f5), + SPH_C32(0x19c6bcbc), SPH_C32(0x2feeb6b6), SPH_C32(0x3045dada), + SPH_C32(0xe7842121), SPH_C32(0x70401010), SPH_C32(0xcbd1ffff), + SPH_C32(0xefe1f3f3), SPH_C32(0x0865d2d2), SPH_C32(0x5519cdcd), + SPH_C32(0x24300c0c), SPH_C32(0x794c1313), SPH_C32(0xb29decec), + SPH_C32(0x86675f5f), SPH_C32(0xc86a9797), SPH_C32(0xc70b4444), + SPH_C32(0x655c1717), SPH_C32(0x6a3dc4c4), SPH_C32(0x58aaa7a7), + SPH_C32(0x61e37e7e), SPH_C32(0xb3f43d3d), SPH_C32(0x278b6464), + SPH_C32(0x886f5d5d), SPH_C32(0x4f641919), SPH_C32(0x42d77373), + SPH_C32(0x3b9b6060), SPH_C32(0xaa328181), SPH_C32(0xf6274f4f), + SPH_C32(0x225ddcdc), SPH_C32(0xee882222), SPH_C32(0xd6a82a2a), + SPH_C32(0xdd769090), SPH_C32(0x95168888), SPH_C32(0xc9034646), + SPH_C32(0xbc95eeee), SPH_C32(0x05d6b8b8), SPH_C32(0x6c501414), + SPH_C32(0x2c55dede), SPH_C32(0x81635e5e), SPH_C32(0x312c0b0b), + SPH_C32(0x3741dbdb), SPH_C32(0x96ade0e0), SPH_C32(0x9ec83232), + SPH_C32(0xa6e83a3a), SPH_C32(0x36280a0a), SPH_C32(0xe43f4949), + SPH_C32(0x12180606), SPH_C32(0xfc902424), SPH_C32(0x8f6b5c5c), + SPH_C32(0x7825c2c2), SPH_C32(0x0f61d3d3), SPH_C32(0x6986acac), + SPH_C32(0x35936262), SPH_C32(0xda729191), SPH_C32(0xc6629595), + SPH_C32(0x8abde4e4), SPH_C32(0x74ff7979), SPH_C32(0x83b1e7e7), + SPH_C32(0x4e0dc8c8), SPH_C32(0x85dc3737), SPH_C32(0x18af6d6d), + SPH_C32(0x8e028d8d), SPH_C32(0x1d79d5d5), SPH_C32(0xf1234e4e), + SPH_C32(0x7292a9a9), SPH_C32(0x1fab6c6c), SPH_C32(0xb9435656), + SPH_C32(0xfafdf4f4), SPH_C32(0xa085eaea), SPH_C32(0x208f6565), + SPH_C32(0x7df37a7a), SPH_C32(0x678eaeae), SPH_C32(0x38200808), + SPH_C32(0x0bdebaba), SPH_C32(0x73fb7878), SPH_C32(0xfb942525), + SPH_C32(0xcab82e2e), SPH_C32(0x54701c1c), SPH_C32(0x5faea6a6), + SPH_C32(0x21e6b4b4), SPH_C32(0x6435c6c6), SPH_C32(0xae8de8e8), + SPH_C32(0x2559dddd), SPH_C32(0x57cb7474), SPH_C32(0x5d7c1f1f), + SPH_C32(0xea374b4b), SPH_C32(0x1ec2bdbd), SPH_C32(0x9c1a8b8b), + SPH_C32(0x9b1e8a8a), SPH_C32(0x4bdb7070), SPH_C32(0xbaf83e3e), + SPH_C32(0x26e2b5b5), SPH_C32(0x29836666), SPH_C32(0xe33b4848), + SPH_C32(0x090c0303), SPH_C32(0xf4f5f6f6), SPH_C32(0x2a380e0e), + SPH_C32(0x3c9f6161), SPH_C32(0x8bd43535), SPH_C32(0xbe475757), + SPH_C32(0x02d2b9b9), SPH_C32(0xbf2e8686), SPH_C32(0x7129c1c1), + SPH_C32(0x53741d1d), SPH_C32(0xf74e9e9e), SPH_C32(0x91a9e1e1), + SPH_C32(0xdecdf8f8), SPH_C32(0xe5569898), SPH_C32(0x77441111), + SPH_C32(0x04bf6969), SPH_C32(0x3949d9d9), SPH_C32(0x870e8e8e), + SPH_C32(0xc1669494), SPH_C32(0xec5a9b9b), SPH_C32(0x5a781e1e), + SPH_C32(0xb82a8787), SPH_C32(0xa989e9e9), SPH_C32(0x5c15cece), + SPH_C32(0xb04f5555), SPH_C32(0xd8a02828), SPH_C32(0x2b51dfdf), + SPH_C32(0x89068c8c), SPH_C32(0x4ab2a1a1), SPH_C32(0x92128989), + SPH_C32(0x23340d0d), SPH_C32(0x10cabfbf), SPH_C32(0x84b5e6e6), + SPH_C32(0xd5134242), SPH_C32(0x03bb6868), SPH_C32(0xdc1f4141), + SPH_C32(0xe2529999), SPH_C32(0xc3b42d2d), SPH_C32(0x2d3c0f0f), + SPH_C32(0x3df6b0b0), SPH_C32(0xb74b5454), SPH_C32(0x0cdabbbb), + SPH_C32(0x62581616) +}; + +static const sph_u32 mixtab3[] = { + SPH_C32(0x63329763), SPH_C32(0x7c6feb7c), SPH_C32(0x775ec777), + SPH_C32(0x7b7af77b), SPH_C32(0xf2e8e5f2), SPH_C32(0x6b0ab76b), + SPH_C32(0x6f16a76f), SPH_C32(0xc56d39c5), SPH_C32(0x3090c030), + SPH_C32(0x01070401), SPH_C32(0x672e8767), SPH_C32(0x2bd1ac2b), + SPH_C32(0xfeccd5fe), SPH_C32(0xd71371d7), SPH_C32(0xab7c9aab), + SPH_C32(0x7659c376), SPH_C32(0xca4005ca), SPH_C32(0x82a33e82), + SPH_C32(0xc94909c9), SPH_C32(0x7d68ef7d), SPH_C32(0xfad0c5fa), + SPH_C32(0x59947f59), SPH_C32(0x47ce0747), SPH_C32(0xf0e6edf0), + SPH_C32(0xad6e82ad), SPH_C32(0xd41a7dd4), SPH_C32(0xa243bea2), + SPH_C32(0xaf608aaf), SPH_C32(0x9cf9469c), SPH_C32(0xa451a6a4), + SPH_C32(0x7245d372), SPH_C32(0xc0762dc0), SPH_C32(0xb728eab7), + SPH_C32(0xfdc5d9fd), SPH_C32(0x93d47a93), SPH_C32(0x26f29826), + SPH_C32(0x3682d836), SPH_C32(0x3fbdfc3f), SPH_C32(0xf7f3f1f7), + SPH_C32(0xcc521dcc), SPH_C32(0x348cd034), SPH_C32(0xa556a2a5), + SPH_C32(0xe58db9e5), SPH_C32(0xf1e1e9f1), SPH_C32(0x714cdf71), + SPH_C32(0xd83e4dd8), SPH_C32(0x3197c431), SPH_C32(0x156b5415), + SPH_C32(0x041c1004), SPH_C32(0xc76331c7), SPH_C32(0x23e98c23), + SPH_C32(0xc37f21c3), SPH_C32(0x18486018), SPH_C32(0x96cf6e96), + SPH_C32(0x051b1405), SPH_C32(0x9aeb5e9a), SPH_C32(0x07151c07), + SPH_C32(0x127e4812), SPH_C32(0x80ad3680), SPH_C32(0xe298a5e2), + SPH_C32(0xeba781eb), SPH_C32(0x27f59c27), SPH_C32(0xb233feb2), + SPH_C32(0x7550cf75), SPH_C32(0x093f2409), SPH_C32(0x83a43a83), + SPH_C32(0x2cc4b02c), SPH_C32(0x1a46681a), SPH_C32(0x1b416c1b), + SPH_C32(0x6e11a36e), SPH_C32(0x5a9d735a), SPH_C32(0xa04db6a0), + SPH_C32(0x52a55352), SPH_C32(0x3ba1ec3b), SPH_C32(0xd61475d6), + SPH_C32(0xb334fab3), SPH_C32(0x29dfa429), SPH_C32(0xe39fa1e3), + SPH_C32(0x2fcdbc2f), SPH_C32(0x84b12684), SPH_C32(0x53a25753), + SPH_C32(0xd10169d1), SPH_C32(0x00000000), SPH_C32(0xedb599ed), + SPH_C32(0x20e08020), SPH_C32(0xfcc2ddfc), SPH_C32(0xb13af2b1), + SPH_C32(0x5b9a775b), SPH_C32(0x6a0db36a), SPH_C32(0xcb4701cb), + SPH_C32(0xbe17cebe), SPH_C32(0x39afe439), SPH_C32(0x4aed334a), + SPH_C32(0x4cff2b4c), SPH_C32(0x58937b58), SPH_C32(0xcf5b11cf), + SPH_C32(0xd0066dd0), SPH_C32(0xefbb91ef), SPH_C32(0xaa7b9eaa), + SPH_C32(0xfbd7c1fb), SPH_C32(0x43d21743), SPH_C32(0x4df82f4d), + SPH_C32(0x3399cc33), SPH_C32(0x85b62285), SPH_C32(0x45c00f45), + SPH_C32(0xf9d9c9f9), SPH_C32(0x020e0802), SPH_C32(0x7f66e77f), + SPH_C32(0x50ab5b50), SPH_C32(0x3cb4f03c), SPH_C32(0x9ff04a9f), + SPH_C32(0xa87596a8), SPH_C32(0x51ac5f51), SPH_C32(0xa344baa3), + SPH_C32(0x40db1b40), SPH_C32(0x8f800a8f), SPH_C32(0x92d37e92), + SPH_C32(0x9dfe429d), SPH_C32(0x38a8e038), SPH_C32(0xf5fdf9f5), + SPH_C32(0xbc19c6bc), SPH_C32(0xb62feeb6), SPH_C32(0xda3045da), + SPH_C32(0x21e78421), SPH_C32(0x10704010), SPH_C32(0xffcbd1ff), + SPH_C32(0xf3efe1f3), SPH_C32(0xd20865d2), SPH_C32(0xcd5519cd), + SPH_C32(0x0c24300c), SPH_C32(0x13794c13), SPH_C32(0xecb29dec), + SPH_C32(0x5f86675f), SPH_C32(0x97c86a97), SPH_C32(0x44c70b44), + SPH_C32(0x17655c17), SPH_C32(0xc46a3dc4), SPH_C32(0xa758aaa7), + SPH_C32(0x7e61e37e), SPH_C32(0x3db3f43d), SPH_C32(0x64278b64), + SPH_C32(0x5d886f5d), SPH_C32(0x194f6419), SPH_C32(0x7342d773), + SPH_C32(0x603b9b60), SPH_C32(0x81aa3281), SPH_C32(0x4ff6274f), + SPH_C32(0xdc225ddc), SPH_C32(0x22ee8822), SPH_C32(0x2ad6a82a), + SPH_C32(0x90dd7690), SPH_C32(0x88951688), SPH_C32(0x46c90346), + SPH_C32(0xeebc95ee), SPH_C32(0xb805d6b8), SPH_C32(0x146c5014), + SPH_C32(0xde2c55de), SPH_C32(0x5e81635e), SPH_C32(0x0b312c0b), + SPH_C32(0xdb3741db), SPH_C32(0xe096ade0), SPH_C32(0x329ec832), + SPH_C32(0x3aa6e83a), SPH_C32(0x0a36280a), SPH_C32(0x49e43f49), + SPH_C32(0x06121806), SPH_C32(0x24fc9024), SPH_C32(0x5c8f6b5c), + SPH_C32(0xc27825c2), SPH_C32(0xd30f61d3), SPH_C32(0xac6986ac), + SPH_C32(0x62359362), SPH_C32(0x91da7291), SPH_C32(0x95c66295), + SPH_C32(0xe48abde4), SPH_C32(0x7974ff79), SPH_C32(0xe783b1e7), + SPH_C32(0xc84e0dc8), SPH_C32(0x3785dc37), SPH_C32(0x6d18af6d), + SPH_C32(0x8d8e028d), SPH_C32(0xd51d79d5), SPH_C32(0x4ef1234e), + SPH_C32(0xa97292a9), SPH_C32(0x6c1fab6c), SPH_C32(0x56b94356), + SPH_C32(0xf4fafdf4), SPH_C32(0xeaa085ea), SPH_C32(0x65208f65), + SPH_C32(0x7a7df37a), SPH_C32(0xae678eae), SPH_C32(0x08382008), + SPH_C32(0xba0bdeba), SPH_C32(0x7873fb78), SPH_C32(0x25fb9425), + SPH_C32(0x2ecab82e), SPH_C32(0x1c54701c), SPH_C32(0xa65faea6), + SPH_C32(0xb421e6b4), SPH_C32(0xc66435c6), SPH_C32(0xe8ae8de8), + SPH_C32(0xdd2559dd), SPH_C32(0x7457cb74), SPH_C32(0x1f5d7c1f), + SPH_C32(0x4bea374b), SPH_C32(0xbd1ec2bd), SPH_C32(0x8b9c1a8b), + SPH_C32(0x8a9b1e8a), SPH_C32(0x704bdb70), SPH_C32(0x3ebaf83e), + SPH_C32(0xb526e2b5), SPH_C32(0x66298366), SPH_C32(0x48e33b48), + SPH_C32(0x03090c03), SPH_C32(0xf6f4f5f6), SPH_C32(0x0e2a380e), + SPH_C32(0x613c9f61), SPH_C32(0x358bd435), SPH_C32(0x57be4757), + SPH_C32(0xb902d2b9), SPH_C32(0x86bf2e86), SPH_C32(0xc17129c1), + SPH_C32(0x1d53741d), SPH_C32(0x9ef74e9e), SPH_C32(0xe191a9e1), + SPH_C32(0xf8decdf8), SPH_C32(0x98e55698), SPH_C32(0x11774411), + SPH_C32(0x6904bf69), SPH_C32(0xd93949d9), SPH_C32(0x8e870e8e), + SPH_C32(0x94c16694), SPH_C32(0x9bec5a9b), SPH_C32(0x1e5a781e), + SPH_C32(0x87b82a87), SPH_C32(0xe9a989e9), SPH_C32(0xce5c15ce), + SPH_C32(0x55b04f55), SPH_C32(0x28d8a028), SPH_C32(0xdf2b51df), + SPH_C32(0x8c89068c), SPH_C32(0xa14ab2a1), SPH_C32(0x89921289), + SPH_C32(0x0d23340d), SPH_C32(0xbf10cabf), SPH_C32(0xe684b5e6), + SPH_C32(0x42d51342), SPH_C32(0x6803bb68), SPH_C32(0x41dc1f41), + SPH_C32(0x99e25299), SPH_C32(0x2dc3b42d), SPH_C32(0x0f2d3c0f), + SPH_C32(0xb03df6b0), SPH_C32(0x54b74b54), SPH_C32(0xbb0cdabb), + SPH_C32(0x16625816) +}; + +#define TIX2(q, x00, x01, x08, x10, x24) do { \ + x10 ^= x00; \ + x00 = (q); \ + x08 ^= x00; \ + x01 ^= x24; \ + } while (0) + +#define TIX3(q, x00, x01, x04, x08, x16, x27, x30) do { \ + x16 ^= x00; \ + x00 = (q); \ + x08 ^= x00; \ + x01 ^= x27; \ + x04 ^= x30; \ + } while (0) + +#define TIX4(q, x00, x01, x04, x07, x08, x22, x24, x27, x30) do { \ + x22 ^= x00; \ + x00 = (q); \ + x08 ^= x00; \ + x01 ^= x24; \ + x04 ^= x27; \ + x07 ^= x30; \ + } while (0) + +#define CMIX30(x00, x01, x02, x04, x05, x06, x15, x16, x17) do { \ + x00 ^= x04; \ + x01 ^= x05; \ + x02 ^= x06; \ + x15 ^= x04; \ + x16 ^= x05; \ + x17 ^= x06; \ + } while (0) + +#define CMIX36(x00, x01, x02, x04, x05, x06, x18, x19, x20) do { \ + x00 ^= x04; \ + x01 ^= x05; \ + x02 ^= x06; \ + x18 ^= x04; \ + x19 ^= x05; \ + x20 ^= x06; \ + } while (0) + +#define SMIX(x0, x1, x2, x3) do { \ + sph_u32 c0 = 0; \ + sph_u32 c1 = 0; \ + sph_u32 c2 = 0; \ + sph_u32 c3 = 0; \ + sph_u32 r0 = 0; \ + sph_u32 r1 = 0; \ + sph_u32 r2 = 0; \ + sph_u32 r3 = 0; \ + sph_u32 tmp; \ + tmp = mixtab0[x0 >> 24]; \ + c0 ^= tmp; \ + tmp = mixtab1[(x0 >> 16) & 0xFF]; \ + c0 ^= tmp; \ + r1 ^= tmp; \ + tmp = mixtab2[(x0 >> 8) & 0xFF]; \ + c0 ^= tmp; \ + r2 ^= tmp; \ + tmp = mixtab3[x0 & 0xFF]; \ + c0 ^= tmp; \ + r3 ^= tmp; \ + tmp = mixtab0[x1 >> 24]; \ + c1 ^= tmp; \ + r0 ^= tmp; \ + tmp = mixtab1[(x1 >> 16) & 0xFF]; \ + c1 ^= tmp; \ + tmp = mixtab2[(x1 >> 8) & 0xFF]; \ + c1 ^= tmp; \ + r2 ^= tmp; \ + tmp = mixtab3[x1 & 0xFF]; \ + c1 ^= tmp; \ + r3 ^= tmp; \ + tmp = mixtab0[x2 >> 24]; \ + c2 ^= tmp; \ + r0 ^= tmp; \ + tmp = mixtab1[(x2 >> 16) & 0xFF]; \ + c2 ^= tmp; \ + r1 ^= tmp; \ + tmp = mixtab2[(x2 >> 8) & 0xFF]; \ + c2 ^= tmp; \ + tmp = mixtab3[x2 & 0xFF]; \ + c2 ^= tmp; \ + r3 ^= tmp; \ + tmp = mixtab0[x3 >> 24]; \ + c3 ^= tmp; \ + r0 ^= tmp; \ + tmp = mixtab1[(x3 >> 16) & 0xFF]; \ + c3 ^= tmp; \ + r1 ^= tmp; \ + tmp = mixtab2[(x3 >> 8) & 0xFF]; \ + c3 ^= tmp; \ + r2 ^= tmp; \ + tmp = mixtab3[x3 & 0xFF]; \ + c3 ^= tmp; \ + x0 = ((c0 ^ r0) & SPH_C32(0xFF000000)) \ + | ((c1 ^ r1) & SPH_C32(0x00FF0000)) \ + | ((c2 ^ r2) & SPH_C32(0x0000FF00)) \ + | ((c3 ^ r3) & SPH_C32(0x000000FF)); \ + x1 = ((c1 ^ (r0 << 8)) & SPH_C32(0xFF000000)) \ + | ((c2 ^ (r1 << 8)) & SPH_C32(0x00FF0000)) \ + | ((c3 ^ (r2 << 8)) & SPH_C32(0x0000FF00)) \ + | ((c0 ^ (r3 >> 24)) & SPH_C32(0x000000FF)); \ + x2 = ((c2 ^ (r0 << 16)) & SPH_C32(0xFF000000)) \ + | ((c3 ^ (r1 << 16)) & SPH_C32(0x00FF0000)) \ + | ((c0 ^ (r2 >> 16)) & SPH_C32(0x0000FF00)) \ + | ((c1 ^ (r3 >> 16)) & SPH_C32(0x000000FF)); \ + x3 = ((c3 ^ (r0 << 24)) & SPH_C32(0xFF000000)) \ + | ((c0 ^ (r1 >> 8)) & SPH_C32(0x00FF0000)) \ + | ((c1 ^ (r2 >> 8)) & SPH_C32(0x0000FF00)) \ + | ((c2 ^ (r3 >> 8)) & SPH_C32(0x000000FF)); \ + /* */ \ + } while (0) + +#if SPH_FUGUE_NOCOPY + +#define DECL_STATE_SMALL +#define READ_STATE_SMALL(state) +#define WRITE_STATE_SMALL(state) +#define DECL_STATE_BIG +#define READ_STATE_BIG(state) +#define WRITE_STATE_BIG(state) + +#define S00 ((sc)->S[ 0]) +#define S01 ((sc)->S[ 1]) +#define S02 ((sc)->S[ 2]) +#define S03 ((sc)->S[ 3]) +#define S04 ((sc)->S[ 4]) +#define S05 ((sc)->S[ 5]) +#define S06 ((sc)->S[ 6]) +#define S07 ((sc)->S[ 7]) +#define S08 ((sc)->S[ 8]) +#define S09 ((sc)->S[ 9]) +#define S10 ((sc)->S[10]) +#define S11 ((sc)->S[11]) +#define S12 ((sc)->S[12]) +#define S13 ((sc)->S[13]) +#define S14 ((sc)->S[14]) +#define S15 ((sc)->S[15]) +#define S16 ((sc)->S[16]) +#define S17 ((sc)->S[17]) +#define S18 ((sc)->S[18]) +#define S19 ((sc)->S[19]) +#define S20 ((sc)->S[20]) +#define S21 ((sc)->S[21]) +#define S22 ((sc)->S[22]) +#define S23 ((sc)->S[23]) +#define S24 ((sc)->S[24]) +#define S25 ((sc)->S[25]) +#define S26 ((sc)->S[26]) +#define S27 ((sc)->S[27]) +#define S28 ((sc)->S[28]) +#define S29 ((sc)->S[29]) +#define S30 ((sc)->S[30]) +#define S31 ((sc)->S[31]) +#define S32 ((sc)->S[32]) +#define S33 ((sc)->S[33]) +#define S34 ((sc)->S[34]) +#define S35 ((sc)->S[35]) + +#else + +#define DECL_STATE_SMALL \ + sph_u32 S00, S01, S02, S03, S04, S05, S06, S07, S08, S09; \ + sph_u32 S10, S11, S12, S13, S14, S15, S16, S17, S18, S19; \ + sph_u32 S20, S21, S22, S23, S24, S25, S26, S27, S28, S29; + +#define DECL_STATE_BIG \ + DECL_STATE_SMALL \ + sph_u32 S30, S31, S32, S33, S34, S35; + +#define READ_STATE_SMALL(state) do { \ + S00 = (state)->S[ 0]; \ + S01 = (state)->S[ 1]; \ + S02 = (state)->S[ 2]; \ + S03 = (state)->S[ 3]; \ + S04 = (state)->S[ 4]; \ + S05 = (state)->S[ 5]; \ + S06 = (state)->S[ 6]; \ + S07 = (state)->S[ 7]; \ + S08 = (state)->S[ 8]; \ + S09 = (state)->S[ 9]; \ + S10 = (state)->S[10]; \ + S11 = (state)->S[11]; \ + S12 = (state)->S[12]; \ + S13 = (state)->S[13]; \ + S14 = (state)->S[14]; \ + S15 = (state)->S[15]; \ + S16 = (state)->S[16]; \ + S17 = (state)->S[17]; \ + S18 = (state)->S[18]; \ + S19 = (state)->S[19]; \ + S20 = (state)->S[20]; \ + S21 = (state)->S[21]; \ + S22 = (state)->S[22]; \ + S23 = (state)->S[23]; \ + S24 = (state)->S[24]; \ + S25 = (state)->S[25]; \ + S26 = (state)->S[26]; \ + S27 = (state)->S[27]; \ + S28 = (state)->S[28]; \ + S29 = (state)->S[29]; \ + } while (0) + +#define READ_STATE_BIG(state) do { \ + READ_STATE_SMALL(state); \ + S30 = (state)->S[30]; \ + S31 = (state)->S[31]; \ + S32 = (state)->S[32]; \ + S33 = (state)->S[33]; \ + S34 = (state)->S[34]; \ + S35 = (state)->S[35]; \ + } while (0) + +#define WRITE_STATE_SMALL(state) do { \ + (state)->S[ 0] = S00; \ + (state)->S[ 1] = S01; \ + (state)->S[ 2] = S02; \ + (state)->S[ 3] = S03; \ + (state)->S[ 4] = S04; \ + (state)->S[ 5] = S05; \ + (state)->S[ 6] = S06; \ + (state)->S[ 7] = S07; \ + (state)->S[ 8] = S08; \ + (state)->S[ 9] = S09; \ + (state)->S[10] = S10; \ + (state)->S[11] = S11; \ + (state)->S[12] = S12; \ + (state)->S[13] = S13; \ + (state)->S[14] = S14; \ + (state)->S[15] = S15; \ + (state)->S[16] = S16; \ + (state)->S[17] = S17; \ + (state)->S[18] = S18; \ + (state)->S[19] = S19; \ + (state)->S[20] = S20; \ + (state)->S[21] = S21; \ + (state)->S[22] = S22; \ + (state)->S[23] = S23; \ + (state)->S[24] = S24; \ + (state)->S[25] = S25; \ + (state)->S[26] = S26; \ + (state)->S[27] = S27; \ + (state)->S[28] = S28; \ + (state)->S[29] = S29; \ + } while (0) + +#define WRITE_STATE_BIG(state) do { \ + WRITE_STATE_SMALL(state); \ + (state)->S[30] = S30; \ + (state)->S[31] = S31; \ + (state)->S[32] = S32; \ + (state)->S[33] = S33; \ + (state)->S[34] = S34; \ + (state)->S[35] = S35; \ + } while (0) + +#endif + +static void +fugue_init(sph_fugue_context *sc, size_t z_len, + const sph_u32 *iv, size_t iv_len) +{ + size_t u; + + for (u = 0; u < z_len; u ++) + sc->S[u] = 0; + memcpy(&sc->S[z_len], iv, iv_len * sizeof *iv); + sc->partial = 0; + sc->partial_len = 0; + sc->round_shift = 0; +#if SPH_64 + sc->bit_count = 0; +#else + sc->bit_count_high = 0; + sc->bit_count_low = 0; +#endif +} + +#if SPH_64 + +#define INCR_COUNTER do { \ + sc->bit_count += (sph_u64)len << 3; \ + } while (0) + +#else + +#define INCR_COUNTER do { \ + sph_u32 tmp = SPH_T32((sph_u32)len << 3); \ + sc->bit_count_low = SPH_T32(sc->bit_count_low + tmp); \ + if (sc->bit_count_low < tmp) \ + sc->bit_count_high ++; \ + sc->bit_count_high = SPH_T32(sc->bit_count_high \ + + ((sph_u32)len >> 29)); \ + } while (0) + +#endif + +#define CORE_ENTRY \ + sph_u32 p; \ + unsigned plen, rshift; \ + INCR_COUNTER; \ + p = sc->partial; \ + plen = sc->partial_len; \ + if (plen < 4) { \ + unsigned count = 4 - plen; \ + if (len < count) \ + count = len; \ + plen += count; \ + while (count -- > 0) { \ + p = (p << 8) | *(const unsigned char *)data; \ + data = (const unsigned char *)data + 1; \ + len --; \ + } \ + if (len == 0) { \ + sc->partial = p; \ + sc->partial_len = plen; \ + return; \ + } \ + } + +#define CORE_EXIT \ + p = 0; \ + sc->partial_len = (unsigned)len; \ + while (len -- > 0) { \ + p = (p << 8) | *(const unsigned char *)data; \ + data = (const unsigned char *)data + 1; \ + } \ + sc->partial = p; \ + sc->round_shift = rshift; + +/* + * Not in a do..while: the 'break' must exit the outer loop. + */ +#define NEXT(rc) \ + if (len <= 4) { \ + rshift = (rc); \ + break; \ + } \ + p = sph_dec32be(data); \ + data = (const unsigned char *)data + 4; \ + len -= 4 + +static void +fugue2_core(sph_fugue_context *sc, const void *data, size_t len) +{ + DECL_STATE_SMALL + CORE_ENTRY + READ_STATE_SMALL(sc); + rshift = sc->round_shift; + switch (rshift) { + for (;;) { + sph_u32 q; + + case 0: + q = p; + TIX2(q, S00, S01, S08, S10, S24); + CMIX30(S27, S28, S29, S01, S02, S03, S12, S13, S14); + SMIX(S27, S28, S29, S00); + CMIX30(S24, S25, S26, S28, S29, S00, S09, S10, S11); + SMIX(S24, S25, S26, S27); + NEXT(1); + /* fall through */ + case 1: + q = p; + TIX2(q, S24, S25, S02, S04, S18); + CMIX30(S21, S22, S23, S25, S26, S27, S06, S07, S08); + SMIX(S21, S22, S23, S24); + CMIX30(S18, S19, S20, S22, S23, S24, S03, S04, S05); + SMIX(S18, S19, S20, S21); + NEXT(2); + /* fall through */ + case 2: + q = p; + TIX2(q, S18, S19, S26, S28, S12); + CMIX30(S15, S16, S17, S19, S20, S21, S00, S01, S02); + SMIX(S15, S16, S17, S18); + CMIX30(S12, S13, S14, S16, S17, S18, S27, S28, S29); + SMIX(S12, S13, S14, S15); + NEXT(3); + /* fall through */ + case 3: + q = p; + TIX2(q, S12, S13, S20, S22, S06); + CMIX30(S09, S10, S11, S13, S14, S15, S24, S25, S26); + SMIX(S09, S10, S11, S12); + CMIX30(S06, S07, S08, S10, S11, S12, S21, S22, S23); + SMIX(S06, S07, S08, S09); + NEXT(4); + /* fall through */ + case 4: + q = p; + TIX2(q, S06, S07, S14, S16, S00); + CMIX30(S03, S04, S05, S07, S08, S09, S18, S19, S20); + SMIX(S03, S04, S05, S06); + CMIX30(S00, S01, S02, S04, S05, S06, S15, S16, S17); + SMIX(S00, S01, S02, S03); + NEXT(0); + } + } + CORE_EXIT + WRITE_STATE_SMALL(sc); +} + +static void +fugue3_core(sph_fugue_context *sc, const void *data, size_t len) +{ + DECL_STATE_BIG + CORE_ENTRY + READ_STATE_BIG(sc); + rshift = sc->round_shift; + switch (rshift) { + for (;;) { + sph_u32 q; + + case 0: + q = p; + TIX3(q, S00, S01, S04, S08, S16, S27, S30); + CMIX36(S33, S34, S35, S01, S02, S03, S15, S16, S17); + SMIX(S33, S34, S35, S00); + CMIX36(S30, S31, S32, S34, S35, S00, S12, S13, S14); + SMIX(S30, S31, S32, S33); + CMIX36(S27, S28, S29, S31, S32, S33, S09, S10, S11); + SMIX(S27, S28, S29, S30); + NEXT(1); + /* fall through */ + case 1: + q = p; + TIX3(q, S27, S28, S31, S35, S07, S18, S21); + CMIX36(S24, S25, S26, S28, S29, S30, S06, S07, S08); + SMIX(S24, S25, S26, S27); + CMIX36(S21, S22, S23, S25, S26, S27, S03, S04, S05); + SMIX(S21, S22, S23, S24); + CMIX36(S18, S19, S20, S22, S23, S24, S00, S01, S02); + SMIX(S18, S19, S20, S21); + NEXT(2); + /* fall through */ + case 2: + q = p; + TIX3(q, S18, S19, S22, S26, S34, S09, S12); + CMIX36(S15, S16, S17, S19, S20, S21, S33, S34, S35); + SMIX(S15, S16, S17, S18); + CMIX36(S12, S13, S14, S16, S17, S18, S30, S31, S32); + SMIX(S12, S13, S14, S15); + CMIX36(S09, S10, S11, S13, S14, S15, S27, S28, S29); + SMIX(S09, S10, S11, S12); + NEXT(3); + /* fall through */ + case 3: + q = p; + TIX3(q, S09, S10, S13, S17, S25, S00, S03); + CMIX36(S06, S07, S08, S10, S11, S12, S24, S25, S26); + SMIX(S06, S07, S08, S09); + CMIX36(S03, S04, S05, S07, S08, S09, S21, S22, S23); + SMIX(S03, S04, S05, S06); + CMIX36(S00, S01, S02, S04, S05, S06, S18, S19, S20); + SMIX(S00, S01, S02, S03); + NEXT(0); + } + } + CORE_EXIT + WRITE_STATE_BIG(sc); +} + +static void +fugue4_core(sph_fugue_context *sc, const void *data, size_t len) +{ + DECL_STATE_BIG + CORE_ENTRY + READ_STATE_BIG(sc); + rshift = sc->round_shift; + switch (rshift) { + for (;;) { + sph_u32 q; + + case 0: + q = p; + TIX4(q, S00, S01, S04, S07, S08, S22, S24, S27, S30); + CMIX36(S33, S34, S35, S01, S02, S03, S15, S16, S17); + SMIX(S33, S34, S35, S00); + CMIX36(S30, S31, S32, S34, S35, S00, S12, S13, S14); + SMIX(S30, S31, S32, S33); + CMIX36(S27, S28, S29, S31, S32, S33, S09, S10, S11); + SMIX(S27, S28, S29, S30); + CMIX36(S24, S25, S26, S28, S29, S30, S06, S07, S08); + SMIX(S24, S25, S26, S27); + NEXT(1); + /* fall through */ + case 1: + q = p; + TIX4(q, S24, S25, S28, S31, S32, S10, S12, S15, S18); + CMIX36(S21, S22, S23, S25, S26, S27, S03, S04, S05); + SMIX(S21, S22, S23, S24); + CMIX36(S18, S19, S20, S22, S23, S24, S00, S01, S02); + SMIX(S18, S19, S20, S21); + CMIX36(S15, S16, S17, S19, S20, S21, S33, S34, S35); + SMIX(S15, S16, S17, S18); + CMIX36(S12, S13, S14, S16, S17, S18, S30, S31, S32); + SMIX(S12, S13, S14, S15); + NEXT(2); + /* fall through */ + case 2: + q = p; + TIX4(q, S12, S13, S16, S19, S20, S34, S00, S03, S06); + CMIX36(S09, S10, S11, S13, S14, S15, S27, S28, S29); + SMIX(S09, S10, S11, S12); + CMIX36(S06, S07, S08, S10, S11, S12, S24, S25, S26); + SMIX(S06, S07, S08, S09); + CMIX36(S03, S04, S05, S07, S08, S09, S21, S22, S23); + SMIX(S03, S04, S05, S06); + CMIX36(S00, S01, S02, S04, S05, S06, S18, S19, S20); + SMIX(S00, S01, S02, S03); + NEXT(0); + } + } + CORE_EXIT + WRITE_STATE_BIG(sc); +} + +#if SPH_64 + +#define WRITE_COUNTER do { \ + sph_enc64be(buf + 4, sc->bit_count + n); \ + } while (0) + +#else + +#define WRITE_COUNTER do { \ + sph_enc32be(buf + 4, sc->bit_count_high); \ + sph_enc32be(buf + 8, sc->bit_count_low + n); \ + } while (0) + +#endif + +#define CLOSE_ENTRY(s, rcm, core) \ + unsigned char buf[16]; \ + unsigned plen, rms; \ + unsigned char *out; \ + sph_u32 S[s]; \ + plen = sc->partial_len; \ + WRITE_COUNTER; \ + if (plen == 0 && n == 0) { \ + plen = 4; \ + } else if (plen < 4 || n != 0) { \ + unsigned u; \ + \ + if (plen == 4) \ + plen = 0; \ + buf[plen] = ub & ~(0xFFU >> n); \ + for (u = plen + 1; u < 4; u ++) \ + buf[u] = 0; \ + } \ + core(sc, buf + plen, (sizeof buf) - plen); \ + rms = sc->round_shift * (rcm); \ + memcpy(S, sc->S + (s) - rms, rms * sizeof(sph_u32)); \ + memcpy(S + rms, sc->S, ((s) - rms) * sizeof(sph_u32)); + +#define ROR(n, s) do { \ + sph_u32 tmp[n]; \ + memcpy(tmp, S + ((s) - (n)), (n) * sizeof(sph_u32)); \ + memmove(S + (n), S, ((s) - (n)) * sizeof(sph_u32)); \ + memcpy(S, tmp, (n) * sizeof(sph_u32)); \ + } while (0) + +static void +fugue2_close(sph_fugue_context *sc, unsigned ub, unsigned n, + void *dst, size_t out_size_w32) +{ + int i; + + CLOSE_ENTRY(30, 6, fugue2_core) + for (i = 0; i < 10; i ++) { + ROR(3, 30); + CMIX30(S[0], S[1], S[2], S[4], S[5], S[6], S[15], S[16], S[17]); + SMIX(S[0], S[1], S[2], S[3]); + } + for (i = 0; i < 13; i ++) { + S[4] ^= S[0]; + S[15] ^= S[0]; + ROR(15, 30); + SMIX(S[0], S[1], S[2], S[3]); + S[4] ^= S[0]; + S[16] ^= S[0]; + ROR(14, 30); + SMIX(S[0], S[1], S[2], S[3]); + } + S[4] ^= S[0]; + S[15] ^= S[0]; + out = dst; + sph_enc32be(out + 0, S[ 1]); + sph_enc32be(out + 4, S[ 2]); + sph_enc32be(out + 8, S[ 3]); + sph_enc32be(out + 12, S[ 4]); + sph_enc32be(out + 16, S[15]); + sph_enc32be(out + 20, S[16]); + sph_enc32be(out + 24, S[17]); + if (out_size_w32 == 8) { + sph_enc32be(out + 28, S[18]); + sph_fugue256_init(sc); + } else { + sph_fugue224_init(sc); + } +} + +static void +fugue3_close(sph_fugue_context *sc, unsigned ub, unsigned n, void *dst) +{ + int i; + + CLOSE_ENTRY(36, 9, fugue3_core) + for (i = 0; i < 18; i ++) { + ROR(3, 36); + CMIX36(S[0], S[1], S[2], S[4], S[5], S[6], S[18], S[19], S[20]); + SMIX(S[0], S[1], S[2], S[3]); + } + for (i = 0; i < 13; i ++) { + S[4] ^= S[0]; + S[12] ^= S[0]; + S[24] ^= S[0]; + ROR(12, 36); + SMIX(S[0], S[1], S[2], S[3]); + S[4] ^= S[0]; + S[13] ^= S[0]; + S[24] ^= S[0]; + ROR(12, 36); + SMIX(S[0], S[1], S[2], S[3]); + S[4] ^= S[0]; + S[13] ^= S[0]; + S[25] ^= S[0]; + ROR(11, 36); + SMIX(S[0], S[1], S[2], S[3]); + } + S[4] ^= S[0]; + S[12] ^= S[0]; + S[24] ^= S[0]; + out = dst; + sph_enc32be(out + 0, S[ 1]); + sph_enc32be(out + 4, S[ 2]); + sph_enc32be(out + 8, S[ 3]); + sph_enc32be(out + 12, S[ 4]); + sph_enc32be(out + 16, S[12]); + sph_enc32be(out + 20, S[13]); + sph_enc32be(out + 24, S[14]); + sph_enc32be(out + 28, S[15]); + sph_enc32be(out + 32, S[24]); + sph_enc32be(out + 36, S[25]); + sph_enc32be(out + 40, S[26]); + sph_enc32be(out + 44, S[27]); + sph_fugue384_init(sc); +} + +static void +fugue4_close(sph_fugue_context *sc, unsigned ub, unsigned n, void *dst) +{ + int i; + + CLOSE_ENTRY(36, 12, fugue4_core) + for (i = 0; i < 32; i ++) { + ROR(3, 36); + CMIX36(S[0], S[1], S[2], S[4], S[5], S[6], S[18], S[19], S[20]); + SMIX(S[0], S[1], S[2], S[3]); + } + for (i = 0; i < 13; i ++) { + S[4] ^= S[0]; + S[9] ^= S[0]; + S[18] ^= S[0]; + S[27] ^= S[0]; + ROR(9, 36); + SMIX(S[0], S[1], S[2], S[3]); + S[4] ^= S[0]; + S[10] ^= S[0]; + S[18] ^= S[0]; + S[27] ^= S[0]; + ROR(9, 36); + SMIX(S[0], S[1], S[2], S[3]); + S[4] ^= S[0]; + S[10] ^= S[0]; + S[19] ^= S[0]; + S[27] ^= S[0]; + ROR(9, 36); + SMIX(S[0], S[1], S[2], S[3]); + S[4] ^= S[0]; + S[10] ^= S[0]; + S[19] ^= S[0]; + S[28] ^= S[0]; + ROR(8, 36); + SMIX(S[0], S[1], S[2], S[3]); + } + S[4] ^= S[0]; + S[9] ^= S[0]; + S[18] ^= S[0]; + S[27] ^= S[0]; + out = dst; + sph_enc32be(out + 0, S[ 1]); + sph_enc32be(out + 4, S[ 2]); + sph_enc32be(out + 8, S[ 3]); + sph_enc32be(out + 12, S[ 4]); + sph_enc32be(out + 16, S[ 9]); + sph_enc32be(out + 20, S[10]); + sph_enc32be(out + 24, S[11]); + sph_enc32be(out + 28, S[12]); + sph_enc32be(out + 32, S[18]); + sph_enc32be(out + 36, S[19]); + sph_enc32be(out + 40, S[20]); + sph_enc32be(out + 44, S[21]); + sph_enc32be(out + 48, S[27]); + sph_enc32be(out + 52, S[28]); + sph_enc32be(out + 56, S[29]); + sph_enc32be(out + 60, S[30]); + sph_fugue512_init(sc); +} + +void +sph_fugue224_init(void *cc) +{ + fugue_init(cc, 23, IV224, 7); +} + +void +sph_fugue224(void *cc, const void *data, size_t len) +{ + fugue2_core(cc, data, len); +} + +void +sph_fugue224_close(void *cc, void *dst) +{ + fugue2_close(cc, 0, 0, dst, 7); +} + +void +sph_fugue224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + fugue2_close(cc, ub, n, dst, 7); +} + +void +sph_fugue256_init(void *cc) +{ + fugue_init(cc, 22, IV256, 8); +} + +void +sph_fugue256(void *cc, const void *data, size_t len) +{ + fugue2_core(cc, data, len); +} + +void +sph_fugue256_close(void *cc, void *dst) +{ + fugue2_close(cc, 0, 0, dst, 8); +} + +void +sph_fugue256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + fugue2_close(cc, ub, n, dst, 8); +} + +void +sph_fugue384_init(void *cc) +{ + fugue_init(cc, 24, IV384, 12); +} + +void +sph_fugue384(void *cc, const void *data, size_t len) +{ + fugue3_core(cc, data, len); +} + +void +sph_fugue384_close(void *cc, void *dst) +{ + fugue3_close(cc, 0, 0, dst); +} + +void +sph_fugue384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + fugue3_close(cc, ub, n, dst); +} + +void +sph_fugue512_init(void *cc) +{ + fugue_init(cc, 20, IV512, 16); +} + +void +sph_fugue512(void *cc, const void *data, size_t len) +{ + fugue4_core(cc, data, len); +} + +void +sph_fugue512_close(void *cc, void *dst) +{ + fugue4_close(cc, 0, 0, dst); +} + +void +sph_fugue512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + fugue4_close(cc, ub, n, dst); +} +#ifdef __cplusplus +} +#endif diff --git a/src/groestl.c b/src/groestl.c new file mode 100644 index 0000000..928bc41 --- /dev/null +++ b/src/groestl.c @@ -0,0 +1,3123 @@ +/* $Id: groestl.c 260 2011-07-21 01:02:38Z tp $ */ +/* + * Groestl 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 + */ + +#include +#include + +#include "sph_groestl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_GROESTL +#define SPH_SMALL_FOOTPRINT_GROESTL 1 +#endif + +/* + * Apparently, the 32-bit-only version is not faster than the 64-bit + * version unless using the "small footprint" code on a 32-bit machine. + */ +#if !defined SPH_GROESTL_64 +#if SPH_SMALL_FOOTPRINT_GROESTL && !SPH_64_TRUE +#define SPH_GROESTL_64 0 +#else +#define SPH_GROESTL_64 1 +#endif +#endif + +#if !SPH_64 +#undef SPH_GROESTL_64 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +/* + * The internal representation may use either big-endian or + * little-endian. Using the platform default representation speeds up + * encoding and decoding between bytes and the matrix columns. + */ + +#undef USE_LE +#if SPH_GROESTL_LITTLE_ENDIAN +#define USE_LE 1 +#elif SPH_GROESTL_BIG_ENDIAN +#define USE_LE 0 +#elif SPH_LITTLE_ENDIAN +#define USE_LE 1 +#endif + +#if USE_LE + +#define C32e(x) ((SPH_C32(x) >> 24) \ + | ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) \ + | ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) \ + | ((SPH_C32(x) << 24) & SPH_C32(0xFF000000))) +#define dec32e_aligned sph_dec32le_aligned +#define enc32e sph_enc32le +#define B32_0(x) ((x) & 0xFF) +#define B32_1(x) (((x) >> 8) & 0xFF) +#define B32_2(x) (((x) >> 16) & 0xFF) +#define B32_3(x) ((x) >> 24) + +#define R32u(u, d) SPH_T32(((u) << 16) | ((d) >> 16)) +#define R32d(u, d) SPH_T32(((u) >> 16) | ((d) << 16)) + +#define PC32up(j, r) ((sph_u32)((j) + (r))) +#define PC32dn(j, r) 0 +#define QC32up(j, r) SPH_C32(0xFFFFFFFF) +#define QC32dn(j, r) (((sph_u32)(r) << 24) ^ SPH_T32(~((sph_u32)(j) << 24))) + +#if SPH_64 +#define C64e(x) ((SPH_C64(x) >> 56) \ + | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \ + | ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) \ + | ((SPH_C64(x) >> 8) & SPH_C64(0x00000000FF000000)) \ + | ((SPH_C64(x) << 8) & SPH_C64(0x000000FF00000000)) \ + | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \ + | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \ + | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000))) +#define dec64e_aligned sph_dec64le_aligned +#define enc64e sph_enc64le +#define B64_0(x) ((x) & 0xFF) +#define B64_1(x) (((x) >> 8) & 0xFF) +#define B64_2(x) (((x) >> 16) & 0xFF) +#define B64_3(x) (((x) >> 24) & 0xFF) +#define B64_4(x) (((x) >> 32) & 0xFF) +#define B64_5(x) (((x) >> 40) & 0xFF) +#define B64_6(x) (((x) >> 48) & 0xFF) +#define B64_7(x) ((x) >> 56) +#define R64 SPH_ROTL64 +#define PC64(j, r) ((sph_u64)((j) + (r))) +#define QC64(j, r) (((sph_u64)(r) << 56) ^ SPH_T64(~((sph_u64)(j) << 56))) +#endif + +#else + +#define C32e(x) SPH_C32(x) +#define dec32e_aligned sph_dec32be_aligned +#define enc32e sph_enc32be +#define B32_0(x) ((x) >> 24) +#define B32_1(x) (((x) >> 16) & 0xFF) +#define B32_2(x) (((x) >> 8) & 0xFF) +#define B32_3(x) ((x) & 0xFF) + +#define R32u(u, d) SPH_T32(((u) >> 16) | ((d) << 16)) +#define R32d(u, d) SPH_T32(((u) << 16) | ((d) >> 16)) + +#define PC32up(j, r) ((sph_u32)((j) + (r)) << 24) +#define PC32dn(j, r) 0 +#define QC32up(j, r) SPH_C32(0xFFFFFFFF) +#define QC32dn(j, r) ((sph_u32)(r) ^ SPH_T32(~(sph_u32)(j))) + +#if SPH_64 +#define C64e(x) SPH_C64(x) +#define dec64e_aligned sph_dec64be_aligned +#define enc64e sph_enc64be +#define B64_0(x) ((x) >> 56) +#define B64_1(x) (((x) >> 48) & 0xFF) +#define B64_2(x) (((x) >> 40) & 0xFF) +#define B64_3(x) (((x) >> 32) & 0xFF) +#define B64_4(x) (((x) >> 24) & 0xFF) +#define B64_5(x) (((x) >> 16) & 0xFF) +#define B64_6(x) (((x) >> 8) & 0xFF) +#define B64_7(x) ((x) & 0xFF) +#define R64 SPH_ROTR64 +#define PC64(j, r) ((sph_u64)((j) + (r)) << 56) +#define QC64(j, r) ((sph_u64)(r) ^ SPH_T64(~(sph_u64)(j))) +#endif + +#endif + +#if SPH_GROESTL_64 + +static const sph_u64 T0[] = { + C64e(0xc632f4a5f497a5c6), C64e(0xf86f978497eb84f8), + C64e(0xee5eb099b0c799ee), C64e(0xf67a8c8d8cf78df6), + C64e(0xffe8170d17e50dff), C64e(0xd60adcbddcb7bdd6), + C64e(0xde16c8b1c8a7b1de), C64e(0x916dfc54fc395491), + C64e(0x6090f050f0c05060), C64e(0x0207050305040302), + C64e(0xce2ee0a9e087a9ce), C64e(0x56d1877d87ac7d56), + C64e(0xe7cc2b192bd519e7), C64e(0xb513a662a67162b5), + C64e(0x4d7c31e6319ae64d), C64e(0xec59b59ab5c39aec), + C64e(0x8f40cf45cf05458f), C64e(0x1fa3bc9dbc3e9d1f), + C64e(0x8949c040c0094089), C64e(0xfa68928792ef87fa), + C64e(0xefd03f153fc515ef), C64e(0xb29426eb267febb2), + C64e(0x8ece40c94007c98e), C64e(0xfbe61d0b1ded0bfb), + C64e(0x416e2fec2f82ec41), C64e(0xb31aa967a97d67b3), + C64e(0x5f431cfd1cbefd5f), C64e(0x456025ea258aea45), + C64e(0x23f9dabfda46bf23), C64e(0x535102f702a6f753), + C64e(0xe445a196a1d396e4), C64e(0x9b76ed5bed2d5b9b), + C64e(0x75285dc25deac275), C64e(0xe1c5241c24d91ce1), + C64e(0x3dd4e9aee97aae3d), C64e(0x4cf2be6abe986a4c), + C64e(0x6c82ee5aeed85a6c), C64e(0x7ebdc341c3fc417e), + C64e(0xf5f3060206f102f5), C64e(0x8352d14fd11d4f83), + C64e(0x688ce45ce4d05c68), C64e(0x515607f407a2f451), + C64e(0xd18d5c345cb934d1), C64e(0xf9e1180818e908f9), + C64e(0xe24cae93aedf93e2), C64e(0xab3e9573954d73ab), + C64e(0x6297f553f5c45362), C64e(0x2a6b413f41543f2a), + C64e(0x081c140c14100c08), C64e(0x9563f652f6315295), + C64e(0x46e9af65af8c6546), C64e(0x9d7fe25ee2215e9d), + C64e(0x3048782878602830), C64e(0x37cff8a1f86ea137), + C64e(0x0a1b110f11140f0a), C64e(0x2febc4b5c45eb52f), + C64e(0x0e151b091b1c090e), C64e(0x247e5a365a483624), + C64e(0x1badb69bb6369b1b), C64e(0xdf98473d47a53ddf), + C64e(0xcda76a266a8126cd), C64e(0x4ef5bb69bb9c694e), + C64e(0x7f334ccd4cfecd7f), C64e(0xea50ba9fbacf9fea), + C64e(0x123f2d1b2d241b12), C64e(0x1da4b99eb93a9e1d), + C64e(0x58c49c749cb07458), C64e(0x3446722e72682e34), + C64e(0x3641772d776c2d36), C64e(0xdc11cdb2cda3b2dc), + C64e(0xb49d29ee2973eeb4), C64e(0x5b4d16fb16b6fb5b), + C64e(0xa4a501f60153f6a4), C64e(0x76a1d74dd7ec4d76), + C64e(0xb714a361a37561b7), C64e(0x7d3449ce49face7d), + C64e(0x52df8d7b8da47b52), C64e(0xdd9f423e42a13edd), + C64e(0x5ecd937193bc715e), C64e(0x13b1a297a2269713), + C64e(0xa6a204f50457f5a6), C64e(0xb901b868b86968b9), + C64e(0x0000000000000000), C64e(0xc1b5742c74992cc1), + C64e(0x40e0a060a0806040), C64e(0xe3c2211f21dd1fe3), + C64e(0x793a43c843f2c879), C64e(0xb69a2ced2c77edb6), + C64e(0xd40dd9bed9b3bed4), C64e(0x8d47ca46ca01468d), + C64e(0x671770d970ced967), C64e(0x72afdd4bdde44b72), + C64e(0x94ed79de7933de94), C64e(0x98ff67d4672bd498), + C64e(0xb09323e8237be8b0), C64e(0x855bde4ade114a85), + C64e(0xbb06bd6bbd6d6bbb), C64e(0xc5bb7e2a7e912ac5), + C64e(0x4f7b34e5349ee54f), C64e(0xedd73a163ac116ed), + C64e(0x86d254c55417c586), C64e(0x9af862d7622fd79a), + C64e(0x6699ff55ffcc5566), C64e(0x11b6a794a7229411), + C64e(0x8ac04acf4a0fcf8a), C64e(0xe9d9301030c910e9), + C64e(0x040e0a060a080604), C64e(0xfe66988198e781fe), + C64e(0xa0ab0bf00b5bf0a0), C64e(0x78b4cc44ccf04478), + C64e(0x25f0d5bad54aba25), C64e(0x4b753ee33e96e34b), + C64e(0xa2ac0ef30e5ff3a2), C64e(0x5d4419fe19bafe5d), + C64e(0x80db5bc05b1bc080), C64e(0x0580858a850a8a05), + C64e(0x3fd3ecadec7ead3f), C64e(0x21fedfbcdf42bc21), + C64e(0x70a8d848d8e04870), C64e(0xf1fd0c040cf904f1), + C64e(0x63197adf7ac6df63), C64e(0x772f58c158eec177), + C64e(0xaf309f759f4575af), C64e(0x42e7a563a5846342), + C64e(0x2070503050403020), C64e(0xe5cb2e1a2ed11ae5), + C64e(0xfdef120e12e10efd), C64e(0xbf08b76db7656dbf), + C64e(0x8155d44cd4194c81), C64e(0x18243c143c301418), + C64e(0x26795f355f4c3526), C64e(0xc3b2712f719d2fc3), + C64e(0xbe8638e13867e1be), C64e(0x35c8fda2fd6aa235), + C64e(0x88c74fcc4f0bcc88), C64e(0x2e654b394b5c392e), + C64e(0x936af957f93d5793), C64e(0x55580df20daaf255), + C64e(0xfc619d829de382fc), C64e(0x7ab3c947c9f4477a), + C64e(0xc827efacef8bacc8), C64e(0xba8832e7326fe7ba), + C64e(0x324f7d2b7d642b32), C64e(0xe642a495a4d795e6), + C64e(0xc03bfba0fb9ba0c0), C64e(0x19aab398b3329819), + C64e(0x9ef668d16827d19e), C64e(0xa322817f815d7fa3), + C64e(0x44eeaa66aa886644), C64e(0x54d6827e82a87e54), + C64e(0x3bdde6abe676ab3b), C64e(0x0b959e839e16830b), + C64e(0x8cc945ca4503ca8c), C64e(0xc7bc7b297b9529c7), + C64e(0x6b056ed36ed6d36b), C64e(0x286c443c44503c28), + C64e(0xa72c8b798b5579a7), C64e(0xbc813de23d63e2bc), + C64e(0x1631271d272c1d16), C64e(0xad379a769a4176ad), + C64e(0xdb964d3b4dad3bdb), C64e(0x649efa56fac85664), + C64e(0x74a6d24ed2e84e74), C64e(0x1436221e22281e14), + C64e(0x92e476db763fdb92), C64e(0x0c121e0a1e180a0c), + C64e(0x48fcb46cb4906c48), C64e(0xb88f37e4376be4b8), + C64e(0x9f78e75de7255d9f), C64e(0xbd0fb26eb2616ebd), + C64e(0x43692aef2a86ef43), C64e(0xc435f1a6f193a6c4), + C64e(0x39dae3a8e372a839), C64e(0x31c6f7a4f762a431), + C64e(0xd38a593759bd37d3), C64e(0xf274868b86ff8bf2), + C64e(0xd583563256b132d5), C64e(0x8b4ec543c50d438b), + C64e(0x6e85eb59ebdc596e), C64e(0xda18c2b7c2afb7da), + C64e(0x018e8f8c8f028c01), C64e(0xb11dac64ac7964b1), + C64e(0x9cf16dd26d23d29c), C64e(0x49723be03b92e049), + C64e(0xd81fc7b4c7abb4d8), C64e(0xacb915fa1543faac), + C64e(0xf3fa090709fd07f3), C64e(0xcfa06f256f8525cf), + C64e(0xca20eaafea8fafca), C64e(0xf47d898e89f38ef4), + C64e(0x476720e9208ee947), C64e(0x1038281828201810), + C64e(0x6f0b64d564ded56f), C64e(0xf073838883fb88f0), + C64e(0x4afbb16fb1946f4a), C64e(0x5cca967296b8725c), + C64e(0x38546c246c702438), C64e(0x575f08f108aef157), + C64e(0x732152c752e6c773), C64e(0x9764f351f3355197), + C64e(0xcbae6523658d23cb), C64e(0xa125847c84597ca1), + C64e(0xe857bf9cbfcb9ce8), C64e(0x3e5d6321637c213e), + C64e(0x96ea7cdd7c37dd96), C64e(0x611e7fdc7fc2dc61), + C64e(0x0d9c9186911a860d), C64e(0x0f9b9485941e850f), + C64e(0xe04bab90abdb90e0), C64e(0x7cbac642c6f8427c), + C64e(0x712657c457e2c471), C64e(0xcc29e5aae583aacc), + C64e(0x90e373d8733bd890), C64e(0x06090f050f0c0506), + C64e(0xf7f4030103f501f7), C64e(0x1c2a36123638121c), + C64e(0xc23cfea3fe9fa3c2), C64e(0x6a8be15fe1d45f6a), + C64e(0xaebe10f91047f9ae), C64e(0x69026bd06bd2d069), + C64e(0x17bfa891a82e9117), C64e(0x9971e858e8295899), + C64e(0x3a5369276974273a), C64e(0x27f7d0b9d04eb927), + C64e(0xd991483848a938d9), C64e(0xebde351335cd13eb), + C64e(0x2be5ceb3ce56b32b), C64e(0x2277553355443322), + C64e(0xd204d6bbd6bfbbd2), C64e(0xa9399070904970a9), + C64e(0x07878089800e8907), C64e(0x33c1f2a7f266a733), + C64e(0x2decc1b6c15ab62d), C64e(0x3c5a66226678223c), + C64e(0x15b8ad92ad2a9215), C64e(0xc9a96020608920c9), + C64e(0x875cdb49db154987), C64e(0xaab01aff1a4fffaa), + C64e(0x50d8887888a07850), C64e(0xa52b8e7a8e517aa5), + C64e(0x03898a8f8a068f03), C64e(0x594a13f813b2f859), + C64e(0x09929b809b128009), C64e(0x1a2339173934171a), + C64e(0x651075da75cada65), C64e(0xd784533153b531d7), + C64e(0x84d551c65113c684), C64e(0xd003d3b8d3bbb8d0), + C64e(0x82dc5ec35e1fc382), C64e(0x29e2cbb0cb52b029), + C64e(0x5ac3997799b4775a), C64e(0x1e2d3311333c111e), + C64e(0x7b3d46cb46f6cb7b), C64e(0xa8b71ffc1f4bfca8), + C64e(0x6d0c61d661dad66d), C64e(0x2c624e3a4e583a2c) +}; + +#if !SPH_SMALL_FOOTPRINT_GROESTL + +static const sph_u64 T1[] = { + C64e(0xc6c632f4a5f497a5), C64e(0xf8f86f978497eb84), + C64e(0xeeee5eb099b0c799), C64e(0xf6f67a8c8d8cf78d), + C64e(0xffffe8170d17e50d), C64e(0xd6d60adcbddcb7bd), + C64e(0xdede16c8b1c8a7b1), C64e(0x91916dfc54fc3954), + C64e(0x606090f050f0c050), C64e(0x0202070503050403), + C64e(0xcece2ee0a9e087a9), C64e(0x5656d1877d87ac7d), + C64e(0xe7e7cc2b192bd519), C64e(0xb5b513a662a67162), + C64e(0x4d4d7c31e6319ae6), C64e(0xecec59b59ab5c39a), + C64e(0x8f8f40cf45cf0545), C64e(0x1f1fa3bc9dbc3e9d), + C64e(0x898949c040c00940), C64e(0xfafa68928792ef87), + C64e(0xefefd03f153fc515), C64e(0xb2b29426eb267feb), + C64e(0x8e8ece40c94007c9), C64e(0xfbfbe61d0b1ded0b), + C64e(0x41416e2fec2f82ec), C64e(0xb3b31aa967a97d67), + C64e(0x5f5f431cfd1cbefd), C64e(0x45456025ea258aea), + C64e(0x2323f9dabfda46bf), C64e(0x53535102f702a6f7), + C64e(0xe4e445a196a1d396), C64e(0x9b9b76ed5bed2d5b), + C64e(0x7575285dc25deac2), C64e(0xe1e1c5241c24d91c), + C64e(0x3d3dd4e9aee97aae), C64e(0x4c4cf2be6abe986a), + C64e(0x6c6c82ee5aeed85a), C64e(0x7e7ebdc341c3fc41), + C64e(0xf5f5f3060206f102), C64e(0x838352d14fd11d4f), + C64e(0x68688ce45ce4d05c), C64e(0x51515607f407a2f4), + C64e(0xd1d18d5c345cb934), C64e(0xf9f9e1180818e908), + C64e(0xe2e24cae93aedf93), C64e(0xabab3e9573954d73), + C64e(0x626297f553f5c453), C64e(0x2a2a6b413f41543f), + C64e(0x08081c140c14100c), C64e(0x959563f652f63152), + C64e(0x4646e9af65af8c65), C64e(0x9d9d7fe25ee2215e), + C64e(0x3030487828786028), C64e(0x3737cff8a1f86ea1), + C64e(0x0a0a1b110f11140f), C64e(0x2f2febc4b5c45eb5), + C64e(0x0e0e151b091b1c09), C64e(0x24247e5a365a4836), + C64e(0x1b1badb69bb6369b), C64e(0xdfdf98473d47a53d), + C64e(0xcdcda76a266a8126), C64e(0x4e4ef5bb69bb9c69), + C64e(0x7f7f334ccd4cfecd), C64e(0xeaea50ba9fbacf9f), + C64e(0x12123f2d1b2d241b), C64e(0x1d1da4b99eb93a9e), + C64e(0x5858c49c749cb074), C64e(0x343446722e72682e), + C64e(0x363641772d776c2d), C64e(0xdcdc11cdb2cda3b2), + C64e(0xb4b49d29ee2973ee), C64e(0x5b5b4d16fb16b6fb), + C64e(0xa4a4a501f60153f6), C64e(0x7676a1d74dd7ec4d), + C64e(0xb7b714a361a37561), C64e(0x7d7d3449ce49face), + C64e(0x5252df8d7b8da47b), C64e(0xdddd9f423e42a13e), + C64e(0x5e5ecd937193bc71), C64e(0x1313b1a297a22697), + C64e(0xa6a6a204f50457f5), C64e(0xb9b901b868b86968), + C64e(0x0000000000000000), C64e(0xc1c1b5742c74992c), + C64e(0x4040e0a060a08060), C64e(0xe3e3c2211f21dd1f), + C64e(0x79793a43c843f2c8), C64e(0xb6b69a2ced2c77ed), + C64e(0xd4d40dd9bed9b3be), C64e(0x8d8d47ca46ca0146), + C64e(0x67671770d970ced9), C64e(0x7272afdd4bdde44b), + C64e(0x9494ed79de7933de), C64e(0x9898ff67d4672bd4), + C64e(0xb0b09323e8237be8), C64e(0x85855bde4ade114a), + C64e(0xbbbb06bd6bbd6d6b), C64e(0xc5c5bb7e2a7e912a), + C64e(0x4f4f7b34e5349ee5), C64e(0xededd73a163ac116), + C64e(0x8686d254c55417c5), C64e(0x9a9af862d7622fd7), + C64e(0x666699ff55ffcc55), C64e(0x1111b6a794a72294), + C64e(0x8a8ac04acf4a0fcf), C64e(0xe9e9d9301030c910), + C64e(0x04040e0a060a0806), C64e(0xfefe66988198e781), + C64e(0xa0a0ab0bf00b5bf0), C64e(0x7878b4cc44ccf044), + C64e(0x2525f0d5bad54aba), C64e(0x4b4b753ee33e96e3), + C64e(0xa2a2ac0ef30e5ff3), C64e(0x5d5d4419fe19bafe), + C64e(0x8080db5bc05b1bc0), C64e(0x050580858a850a8a), + C64e(0x3f3fd3ecadec7ead), C64e(0x2121fedfbcdf42bc), + C64e(0x7070a8d848d8e048), C64e(0xf1f1fd0c040cf904), + C64e(0x6363197adf7ac6df), C64e(0x77772f58c158eec1), + C64e(0xafaf309f759f4575), C64e(0x4242e7a563a58463), + C64e(0x2020705030504030), C64e(0xe5e5cb2e1a2ed11a), + C64e(0xfdfdef120e12e10e), C64e(0xbfbf08b76db7656d), + C64e(0x818155d44cd4194c), C64e(0x1818243c143c3014), + C64e(0x2626795f355f4c35), C64e(0xc3c3b2712f719d2f), + C64e(0xbebe8638e13867e1), C64e(0x3535c8fda2fd6aa2), + C64e(0x8888c74fcc4f0bcc), C64e(0x2e2e654b394b5c39), + C64e(0x93936af957f93d57), C64e(0x5555580df20daaf2), + C64e(0xfcfc619d829de382), C64e(0x7a7ab3c947c9f447), + C64e(0xc8c827efacef8bac), C64e(0xbaba8832e7326fe7), + C64e(0x32324f7d2b7d642b), C64e(0xe6e642a495a4d795), + C64e(0xc0c03bfba0fb9ba0), C64e(0x1919aab398b33298), + C64e(0x9e9ef668d16827d1), C64e(0xa3a322817f815d7f), + C64e(0x4444eeaa66aa8866), C64e(0x5454d6827e82a87e), + C64e(0x3b3bdde6abe676ab), C64e(0x0b0b959e839e1683), + C64e(0x8c8cc945ca4503ca), C64e(0xc7c7bc7b297b9529), + C64e(0x6b6b056ed36ed6d3), C64e(0x28286c443c44503c), + C64e(0xa7a72c8b798b5579), C64e(0xbcbc813de23d63e2), + C64e(0x161631271d272c1d), C64e(0xadad379a769a4176), + C64e(0xdbdb964d3b4dad3b), C64e(0x64649efa56fac856), + C64e(0x7474a6d24ed2e84e), C64e(0x141436221e22281e), + C64e(0x9292e476db763fdb), C64e(0x0c0c121e0a1e180a), + C64e(0x4848fcb46cb4906c), C64e(0xb8b88f37e4376be4), + C64e(0x9f9f78e75de7255d), C64e(0xbdbd0fb26eb2616e), + C64e(0x4343692aef2a86ef), C64e(0xc4c435f1a6f193a6), + C64e(0x3939dae3a8e372a8), C64e(0x3131c6f7a4f762a4), + C64e(0xd3d38a593759bd37), C64e(0xf2f274868b86ff8b), + C64e(0xd5d583563256b132), C64e(0x8b8b4ec543c50d43), + C64e(0x6e6e85eb59ebdc59), C64e(0xdada18c2b7c2afb7), + C64e(0x01018e8f8c8f028c), C64e(0xb1b11dac64ac7964), + C64e(0x9c9cf16dd26d23d2), C64e(0x4949723be03b92e0), + C64e(0xd8d81fc7b4c7abb4), C64e(0xacacb915fa1543fa), + C64e(0xf3f3fa090709fd07), C64e(0xcfcfa06f256f8525), + C64e(0xcaca20eaafea8faf), C64e(0xf4f47d898e89f38e), + C64e(0x47476720e9208ee9), C64e(0x1010382818282018), + C64e(0x6f6f0b64d564ded5), C64e(0xf0f073838883fb88), + C64e(0x4a4afbb16fb1946f), C64e(0x5c5cca967296b872), + C64e(0x3838546c246c7024), C64e(0x57575f08f108aef1), + C64e(0x73732152c752e6c7), C64e(0x979764f351f33551), + C64e(0xcbcbae6523658d23), C64e(0xa1a125847c84597c), + C64e(0xe8e857bf9cbfcb9c), C64e(0x3e3e5d6321637c21), + C64e(0x9696ea7cdd7c37dd), C64e(0x61611e7fdc7fc2dc), + C64e(0x0d0d9c9186911a86), C64e(0x0f0f9b9485941e85), + C64e(0xe0e04bab90abdb90), C64e(0x7c7cbac642c6f842), + C64e(0x71712657c457e2c4), C64e(0xcccc29e5aae583aa), + C64e(0x9090e373d8733bd8), C64e(0x0606090f050f0c05), + C64e(0xf7f7f4030103f501), C64e(0x1c1c2a3612363812), + C64e(0xc2c23cfea3fe9fa3), C64e(0x6a6a8be15fe1d45f), + C64e(0xaeaebe10f91047f9), C64e(0x6969026bd06bd2d0), + C64e(0x1717bfa891a82e91), C64e(0x999971e858e82958), + C64e(0x3a3a536927697427), C64e(0x2727f7d0b9d04eb9), + C64e(0xd9d991483848a938), C64e(0xebebde351335cd13), + C64e(0x2b2be5ceb3ce56b3), C64e(0x2222775533554433), + C64e(0xd2d204d6bbd6bfbb), C64e(0xa9a9399070904970), + C64e(0x0707878089800e89), C64e(0x3333c1f2a7f266a7), + C64e(0x2d2decc1b6c15ab6), C64e(0x3c3c5a6622667822), + C64e(0x1515b8ad92ad2a92), C64e(0xc9c9a96020608920), + C64e(0x87875cdb49db1549), C64e(0xaaaab01aff1a4fff), + C64e(0x5050d8887888a078), C64e(0xa5a52b8e7a8e517a), + C64e(0x0303898a8f8a068f), C64e(0x59594a13f813b2f8), + C64e(0x0909929b809b1280), C64e(0x1a1a233917393417), + C64e(0x65651075da75cada), C64e(0xd7d784533153b531), + C64e(0x8484d551c65113c6), C64e(0xd0d003d3b8d3bbb8), + C64e(0x8282dc5ec35e1fc3), C64e(0x2929e2cbb0cb52b0), + C64e(0x5a5ac3997799b477), C64e(0x1e1e2d3311333c11), + C64e(0x7b7b3d46cb46f6cb), C64e(0xa8a8b71ffc1f4bfc), + C64e(0x6d6d0c61d661dad6), C64e(0x2c2c624e3a4e583a) +}; + +static const sph_u64 T2[] = { + C64e(0xa5c6c632f4a5f497), C64e(0x84f8f86f978497eb), + C64e(0x99eeee5eb099b0c7), C64e(0x8df6f67a8c8d8cf7), + C64e(0x0dffffe8170d17e5), C64e(0xbdd6d60adcbddcb7), + C64e(0xb1dede16c8b1c8a7), C64e(0x5491916dfc54fc39), + C64e(0x50606090f050f0c0), C64e(0x0302020705030504), + C64e(0xa9cece2ee0a9e087), C64e(0x7d5656d1877d87ac), + C64e(0x19e7e7cc2b192bd5), C64e(0x62b5b513a662a671), + C64e(0xe64d4d7c31e6319a), C64e(0x9aecec59b59ab5c3), + C64e(0x458f8f40cf45cf05), C64e(0x9d1f1fa3bc9dbc3e), + C64e(0x40898949c040c009), C64e(0x87fafa68928792ef), + C64e(0x15efefd03f153fc5), C64e(0xebb2b29426eb267f), + C64e(0xc98e8ece40c94007), C64e(0x0bfbfbe61d0b1ded), + C64e(0xec41416e2fec2f82), C64e(0x67b3b31aa967a97d), + C64e(0xfd5f5f431cfd1cbe), C64e(0xea45456025ea258a), + C64e(0xbf2323f9dabfda46), C64e(0xf753535102f702a6), + C64e(0x96e4e445a196a1d3), C64e(0x5b9b9b76ed5bed2d), + C64e(0xc27575285dc25dea), C64e(0x1ce1e1c5241c24d9), + C64e(0xae3d3dd4e9aee97a), C64e(0x6a4c4cf2be6abe98), + C64e(0x5a6c6c82ee5aeed8), C64e(0x417e7ebdc341c3fc), + C64e(0x02f5f5f3060206f1), C64e(0x4f838352d14fd11d), + C64e(0x5c68688ce45ce4d0), C64e(0xf451515607f407a2), + C64e(0x34d1d18d5c345cb9), C64e(0x08f9f9e1180818e9), + C64e(0x93e2e24cae93aedf), C64e(0x73abab3e9573954d), + C64e(0x53626297f553f5c4), C64e(0x3f2a2a6b413f4154), + C64e(0x0c08081c140c1410), C64e(0x52959563f652f631), + C64e(0x654646e9af65af8c), C64e(0x5e9d9d7fe25ee221), + C64e(0x2830304878287860), C64e(0xa13737cff8a1f86e), + C64e(0x0f0a0a1b110f1114), C64e(0xb52f2febc4b5c45e), + C64e(0x090e0e151b091b1c), C64e(0x3624247e5a365a48), + C64e(0x9b1b1badb69bb636), C64e(0x3ddfdf98473d47a5), + C64e(0x26cdcda76a266a81), C64e(0x694e4ef5bb69bb9c), + C64e(0xcd7f7f334ccd4cfe), C64e(0x9feaea50ba9fbacf), + C64e(0x1b12123f2d1b2d24), C64e(0x9e1d1da4b99eb93a), + C64e(0x745858c49c749cb0), C64e(0x2e343446722e7268), + C64e(0x2d363641772d776c), C64e(0xb2dcdc11cdb2cda3), + C64e(0xeeb4b49d29ee2973), C64e(0xfb5b5b4d16fb16b6), + C64e(0xf6a4a4a501f60153), C64e(0x4d7676a1d74dd7ec), + C64e(0x61b7b714a361a375), C64e(0xce7d7d3449ce49fa), + C64e(0x7b5252df8d7b8da4), C64e(0x3edddd9f423e42a1), + C64e(0x715e5ecd937193bc), C64e(0x971313b1a297a226), + C64e(0xf5a6a6a204f50457), C64e(0x68b9b901b868b869), + C64e(0x0000000000000000), C64e(0x2cc1c1b5742c7499), + C64e(0x604040e0a060a080), C64e(0x1fe3e3c2211f21dd), + C64e(0xc879793a43c843f2), C64e(0xedb6b69a2ced2c77), + C64e(0xbed4d40dd9bed9b3), C64e(0x468d8d47ca46ca01), + C64e(0xd967671770d970ce), C64e(0x4b7272afdd4bdde4), + C64e(0xde9494ed79de7933), C64e(0xd49898ff67d4672b), + C64e(0xe8b0b09323e8237b), C64e(0x4a85855bde4ade11), + C64e(0x6bbbbb06bd6bbd6d), C64e(0x2ac5c5bb7e2a7e91), + C64e(0xe54f4f7b34e5349e), C64e(0x16ededd73a163ac1), + C64e(0xc58686d254c55417), C64e(0xd79a9af862d7622f), + C64e(0x55666699ff55ffcc), C64e(0x941111b6a794a722), + C64e(0xcf8a8ac04acf4a0f), C64e(0x10e9e9d9301030c9), + C64e(0x0604040e0a060a08), C64e(0x81fefe66988198e7), + C64e(0xf0a0a0ab0bf00b5b), C64e(0x447878b4cc44ccf0), + C64e(0xba2525f0d5bad54a), C64e(0xe34b4b753ee33e96), + C64e(0xf3a2a2ac0ef30e5f), C64e(0xfe5d5d4419fe19ba), + C64e(0xc08080db5bc05b1b), C64e(0x8a050580858a850a), + C64e(0xad3f3fd3ecadec7e), C64e(0xbc2121fedfbcdf42), + C64e(0x487070a8d848d8e0), C64e(0x04f1f1fd0c040cf9), + C64e(0xdf6363197adf7ac6), C64e(0xc177772f58c158ee), + C64e(0x75afaf309f759f45), C64e(0x634242e7a563a584), + C64e(0x3020207050305040), C64e(0x1ae5e5cb2e1a2ed1), + C64e(0x0efdfdef120e12e1), C64e(0x6dbfbf08b76db765), + C64e(0x4c818155d44cd419), C64e(0x141818243c143c30), + C64e(0x352626795f355f4c), C64e(0x2fc3c3b2712f719d), + C64e(0xe1bebe8638e13867), C64e(0xa23535c8fda2fd6a), + C64e(0xcc8888c74fcc4f0b), C64e(0x392e2e654b394b5c), + C64e(0x5793936af957f93d), C64e(0xf25555580df20daa), + C64e(0x82fcfc619d829de3), C64e(0x477a7ab3c947c9f4), + C64e(0xacc8c827efacef8b), C64e(0xe7baba8832e7326f), + C64e(0x2b32324f7d2b7d64), C64e(0x95e6e642a495a4d7), + C64e(0xa0c0c03bfba0fb9b), C64e(0x981919aab398b332), + C64e(0xd19e9ef668d16827), C64e(0x7fa3a322817f815d), + C64e(0x664444eeaa66aa88), C64e(0x7e5454d6827e82a8), + C64e(0xab3b3bdde6abe676), C64e(0x830b0b959e839e16), + C64e(0xca8c8cc945ca4503), C64e(0x29c7c7bc7b297b95), + C64e(0xd36b6b056ed36ed6), C64e(0x3c28286c443c4450), + C64e(0x79a7a72c8b798b55), C64e(0xe2bcbc813de23d63), + C64e(0x1d161631271d272c), C64e(0x76adad379a769a41), + C64e(0x3bdbdb964d3b4dad), C64e(0x5664649efa56fac8), + C64e(0x4e7474a6d24ed2e8), C64e(0x1e141436221e2228), + C64e(0xdb9292e476db763f), C64e(0x0a0c0c121e0a1e18), + C64e(0x6c4848fcb46cb490), C64e(0xe4b8b88f37e4376b), + C64e(0x5d9f9f78e75de725), C64e(0x6ebdbd0fb26eb261), + C64e(0xef4343692aef2a86), C64e(0xa6c4c435f1a6f193), + C64e(0xa83939dae3a8e372), C64e(0xa43131c6f7a4f762), + C64e(0x37d3d38a593759bd), C64e(0x8bf2f274868b86ff), + C64e(0x32d5d583563256b1), C64e(0x438b8b4ec543c50d), + C64e(0x596e6e85eb59ebdc), C64e(0xb7dada18c2b7c2af), + C64e(0x8c01018e8f8c8f02), C64e(0x64b1b11dac64ac79), + C64e(0xd29c9cf16dd26d23), C64e(0xe04949723be03b92), + C64e(0xb4d8d81fc7b4c7ab), C64e(0xfaacacb915fa1543), + C64e(0x07f3f3fa090709fd), C64e(0x25cfcfa06f256f85), + C64e(0xafcaca20eaafea8f), C64e(0x8ef4f47d898e89f3), + C64e(0xe947476720e9208e), C64e(0x1810103828182820), + C64e(0xd56f6f0b64d564de), C64e(0x88f0f073838883fb), + C64e(0x6f4a4afbb16fb194), C64e(0x725c5cca967296b8), + C64e(0x243838546c246c70), C64e(0xf157575f08f108ae), + C64e(0xc773732152c752e6), C64e(0x51979764f351f335), + C64e(0x23cbcbae6523658d), C64e(0x7ca1a125847c8459), + C64e(0x9ce8e857bf9cbfcb), C64e(0x213e3e5d6321637c), + C64e(0xdd9696ea7cdd7c37), C64e(0xdc61611e7fdc7fc2), + C64e(0x860d0d9c9186911a), C64e(0x850f0f9b9485941e), + C64e(0x90e0e04bab90abdb), C64e(0x427c7cbac642c6f8), + C64e(0xc471712657c457e2), C64e(0xaacccc29e5aae583), + C64e(0xd89090e373d8733b), C64e(0x050606090f050f0c), + C64e(0x01f7f7f4030103f5), C64e(0x121c1c2a36123638), + C64e(0xa3c2c23cfea3fe9f), C64e(0x5f6a6a8be15fe1d4), + C64e(0xf9aeaebe10f91047), C64e(0xd06969026bd06bd2), + C64e(0x911717bfa891a82e), C64e(0x58999971e858e829), + C64e(0x273a3a5369276974), C64e(0xb92727f7d0b9d04e), + C64e(0x38d9d991483848a9), C64e(0x13ebebde351335cd), + C64e(0xb32b2be5ceb3ce56), C64e(0x3322227755335544), + C64e(0xbbd2d204d6bbd6bf), C64e(0x70a9a93990709049), + C64e(0x890707878089800e), C64e(0xa73333c1f2a7f266), + C64e(0xb62d2decc1b6c15a), C64e(0x223c3c5a66226678), + C64e(0x921515b8ad92ad2a), C64e(0x20c9c9a960206089), + C64e(0x4987875cdb49db15), C64e(0xffaaaab01aff1a4f), + C64e(0x785050d8887888a0), C64e(0x7aa5a52b8e7a8e51), + C64e(0x8f0303898a8f8a06), C64e(0xf859594a13f813b2), + C64e(0x800909929b809b12), C64e(0x171a1a2339173934), + C64e(0xda65651075da75ca), C64e(0x31d7d784533153b5), + C64e(0xc68484d551c65113), C64e(0xb8d0d003d3b8d3bb), + C64e(0xc38282dc5ec35e1f), C64e(0xb02929e2cbb0cb52), + C64e(0x775a5ac3997799b4), C64e(0x111e1e2d3311333c), + C64e(0xcb7b7b3d46cb46f6), C64e(0xfca8a8b71ffc1f4b), + C64e(0xd66d6d0c61d661da), C64e(0x3a2c2c624e3a4e58) +}; + +static const sph_u64 T3[] = { + C64e(0x97a5c6c632f4a5f4), C64e(0xeb84f8f86f978497), + C64e(0xc799eeee5eb099b0), C64e(0xf78df6f67a8c8d8c), + C64e(0xe50dffffe8170d17), C64e(0xb7bdd6d60adcbddc), + C64e(0xa7b1dede16c8b1c8), C64e(0x395491916dfc54fc), + C64e(0xc050606090f050f0), C64e(0x0403020207050305), + C64e(0x87a9cece2ee0a9e0), C64e(0xac7d5656d1877d87), + C64e(0xd519e7e7cc2b192b), C64e(0x7162b5b513a662a6), + C64e(0x9ae64d4d7c31e631), C64e(0xc39aecec59b59ab5), + C64e(0x05458f8f40cf45cf), C64e(0x3e9d1f1fa3bc9dbc), + C64e(0x0940898949c040c0), C64e(0xef87fafa68928792), + C64e(0xc515efefd03f153f), C64e(0x7febb2b29426eb26), + C64e(0x07c98e8ece40c940), C64e(0xed0bfbfbe61d0b1d), + C64e(0x82ec41416e2fec2f), C64e(0x7d67b3b31aa967a9), + C64e(0xbefd5f5f431cfd1c), C64e(0x8aea45456025ea25), + C64e(0x46bf2323f9dabfda), C64e(0xa6f753535102f702), + C64e(0xd396e4e445a196a1), C64e(0x2d5b9b9b76ed5bed), + C64e(0xeac27575285dc25d), C64e(0xd91ce1e1c5241c24), + C64e(0x7aae3d3dd4e9aee9), C64e(0x986a4c4cf2be6abe), + C64e(0xd85a6c6c82ee5aee), C64e(0xfc417e7ebdc341c3), + C64e(0xf102f5f5f3060206), C64e(0x1d4f838352d14fd1), + C64e(0xd05c68688ce45ce4), C64e(0xa2f451515607f407), + C64e(0xb934d1d18d5c345c), C64e(0xe908f9f9e1180818), + C64e(0xdf93e2e24cae93ae), C64e(0x4d73abab3e957395), + C64e(0xc453626297f553f5), C64e(0x543f2a2a6b413f41), + C64e(0x100c08081c140c14), C64e(0x3152959563f652f6), + C64e(0x8c654646e9af65af), C64e(0x215e9d9d7fe25ee2), + C64e(0x6028303048782878), C64e(0x6ea13737cff8a1f8), + C64e(0x140f0a0a1b110f11), C64e(0x5eb52f2febc4b5c4), + C64e(0x1c090e0e151b091b), C64e(0x483624247e5a365a), + C64e(0x369b1b1badb69bb6), C64e(0xa53ddfdf98473d47), + C64e(0x8126cdcda76a266a), C64e(0x9c694e4ef5bb69bb), + C64e(0xfecd7f7f334ccd4c), C64e(0xcf9feaea50ba9fba), + C64e(0x241b12123f2d1b2d), C64e(0x3a9e1d1da4b99eb9), + C64e(0xb0745858c49c749c), C64e(0x682e343446722e72), + C64e(0x6c2d363641772d77), C64e(0xa3b2dcdc11cdb2cd), + C64e(0x73eeb4b49d29ee29), C64e(0xb6fb5b5b4d16fb16), + C64e(0x53f6a4a4a501f601), C64e(0xec4d7676a1d74dd7), + C64e(0x7561b7b714a361a3), C64e(0xface7d7d3449ce49), + C64e(0xa47b5252df8d7b8d), C64e(0xa13edddd9f423e42), + C64e(0xbc715e5ecd937193), C64e(0x26971313b1a297a2), + C64e(0x57f5a6a6a204f504), C64e(0x6968b9b901b868b8), + C64e(0x0000000000000000), C64e(0x992cc1c1b5742c74), + C64e(0x80604040e0a060a0), C64e(0xdd1fe3e3c2211f21), + C64e(0xf2c879793a43c843), C64e(0x77edb6b69a2ced2c), + C64e(0xb3bed4d40dd9bed9), C64e(0x01468d8d47ca46ca), + C64e(0xced967671770d970), C64e(0xe44b7272afdd4bdd), + C64e(0x33de9494ed79de79), C64e(0x2bd49898ff67d467), + C64e(0x7be8b0b09323e823), C64e(0x114a85855bde4ade), + C64e(0x6d6bbbbb06bd6bbd), C64e(0x912ac5c5bb7e2a7e), + C64e(0x9ee54f4f7b34e534), C64e(0xc116ededd73a163a), + C64e(0x17c58686d254c554), C64e(0x2fd79a9af862d762), + C64e(0xcc55666699ff55ff), C64e(0x22941111b6a794a7), + C64e(0x0fcf8a8ac04acf4a), C64e(0xc910e9e9d9301030), + C64e(0x080604040e0a060a), C64e(0xe781fefe66988198), + C64e(0x5bf0a0a0ab0bf00b), C64e(0xf0447878b4cc44cc), + C64e(0x4aba2525f0d5bad5), C64e(0x96e34b4b753ee33e), + C64e(0x5ff3a2a2ac0ef30e), C64e(0xbafe5d5d4419fe19), + C64e(0x1bc08080db5bc05b), C64e(0x0a8a050580858a85), + C64e(0x7ead3f3fd3ecadec), C64e(0x42bc2121fedfbcdf), + C64e(0xe0487070a8d848d8), C64e(0xf904f1f1fd0c040c), + C64e(0xc6df6363197adf7a), C64e(0xeec177772f58c158), + C64e(0x4575afaf309f759f), C64e(0x84634242e7a563a5), + C64e(0x4030202070503050), C64e(0xd11ae5e5cb2e1a2e), + C64e(0xe10efdfdef120e12), C64e(0x656dbfbf08b76db7), + C64e(0x194c818155d44cd4), C64e(0x30141818243c143c), + C64e(0x4c352626795f355f), C64e(0x9d2fc3c3b2712f71), + C64e(0x67e1bebe8638e138), C64e(0x6aa23535c8fda2fd), + C64e(0x0bcc8888c74fcc4f), C64e(0x5c392e2e654b394b), + C64e(0x3d5793936af957f9), C64e(0xaaf25555580df20d), + C64e(0xe382fcfc619d829d), C64e(0xf4477a7ab3c947c9), + C64e(0x8bacc8c827efacef), C64e(0x6fe7baba8832e732), + C64e(0x642b32324f7d2b7d), C64e(0xd795e6e642a495a4), + C64e(0x9ba0c0c03bfba0fb), C64e(0x32981919aab398b3), + C64e(0x27d19e9ef668d168), C64e(0x5d7fa3a322817f81), + C64e(0x88664444eeaa66aa), C64e(0xa87e5454d6827e82), + C64e(0x76ab3b3bdde6abe6), C64e(0x16830b0b959e839e), + C64e(0x03ca8c8cc945ca45), C64e(0x9529c7c7bc7b297b), + C64e(0xd6d36b6b056ed36e), C64e(0x503c28286c443c44), + C64e(0x5579a7a72c8b798b), C64e(0x63e2bcbc813de23d), + C64e(0x2c1d161631271d27), C64e(0x4176adad379a769a), + C64e(0xad3bdbdb964d3b4d), C64e(0xc85664649efa56fa), + C64e(0xe84e7474a6d24ed2), C64e(0x281e141436221e22), + C64e(0x3fdb9292e476db76), C64e(0x180a0c0c121e0a1e), + C64e(0x906c4848fcb46cb4), C64e(0x6be4b8b88f37e437), + C64e(0x255d9f9f78e75de7), C64e(0x616ebdbd0fb26eb2), + C64e(0x86ef4343692aef2a), C64e(0x93a6c4c435f1a6f1), + C64e(0x72a83939dae3a8e3), C64e(0x62a43131c6f7a4f7), + C64e(0xbd37d3d38a593759), C64e(0xff8bf2f274868b86), + C64e(0xb132d5d583563256), C64e(0x0d438b8b4ec543c5), + C64e(0xdc596e6e85eb59eb), C64e(0xafb7dada18c2b7c2), + C64e(0x028c01018e8f8c8f), C64e(0x7964b1b11dac64ac), + C64e(0x23d29c9cf16dd26d), C64e(0x92e04949723be03b), + C64e(0xabb4d8d81fc7b4c7), C64e(0x43faacacb915fa15), + C64e(0xfd07f3f3fa090709), C64e(0x8525cfcfa06f256f), + C64e(0x8fafcaca20eaafea), C64e(0xf38ef4f47d898e89), + C64e(0x8ee947476720e920), C64e(0x2018101038281828), + C64e(0xded56f6f0b64d564), C64e(0xfb88f0f073838883), + C64e(0x946f4a4afbb16fb1), C64e(0xb8725c5cca967296), + C64e(0x70243838546c246c), C64e(0xaef157575f08f108), + C64e(0xe6c773732152c752), C64e(0x3551979764f351f3), + C64e(0x8d23cbcbae652365), C64e(0x597ca1a125847c84), + C64e(0xcb9ce8e857bf9cbf), C64e(0x7c213e3e5d632163), + C64e(0x37dd9696ea7cdd7c), C64e(0xc2dc61611e7fdc7f), + C64e(0x1a860d0d9c918691), C64e(0x1e850f0f9b948594), + C64e(0xdb90e0e04bab90ab), C64e(0xf8427c7cbac642c6), + C64e(0xe2c471712657c457), C64e(0x83aacccc29e5aae5), + C64e(0x3bd89090e373d873), C64e(0x0c050606090f050f), + C64e(0xf501f7f7f4030103), C64e(0x38121c1c2a361236), + C64e(0x9fa3c2c23cfea3fe), C64e(0xd45f6a6a8be15fe1), + C64e(0x47f9aeaebe10f910), C64e(0xd2d06969026bd06b), + C64e(0x2e911717bfa891a8), C64e(0x2958999971e858e8), + C64e(0x74273a3a53692769), C64e(0x4eb92727f7d0b9d0), + C64e(0xa938d9d991483848), C64e(0xcd13ebebde351335), + C64e(0x56b32b2be5ceb3ce), C64e(0x4433222277553355), + C64e(0xbfbbd2d204d6bbd6), C64e(0x4970a9a939907090), + C64e(0x0e89070787808980), C64e(0x66a73333c1f2a7f2), + C64e(0x5ab62d2decc1b6c1), C64e(0x78223c3c5a662266), + C64e(0x2a921515b8ad92ad), C64e(0x8920c9c9a9602060), + C64e(0x154987875cdb49db), C64e(0x4fffaaaab01aff1a), + C64e(0xa0785050d8887888), C64e(0x517aa5a52b8e7a8e), + C64e(0x068f0303898a8f8a), C64e(0xb2f859594a13f813), + C64e(0x12800909929b809b), C64e(0x34171a1a23391739), + C64e(0xcada65651075da75), C64e(0xb531d7d784533153), + C64e(0x13c68484d551c651), C64e(0xbbb8d0d003d3b8d3), + C64e(0x1fc38282dc5ec35e), C64e(0x52b02929e2cbb0cb), + C64e(0xb4775a5ac3997799), C64e(0x3c111e1e2d331133), + C64e(0xf6cb7b7b3d46cb46), C64e(0x4bfca8a8b71ffc1f), + C64e(0xdad66d6d0c61d661), C64e(0x583a2c2c624e3a4e) +}; + +#endif + +static const sph_u64 T4[] = { + C64e(0xf497a5c6c632f4a5), C64e(0x97eb84f8f86f9784), + C64e(0xb0c799eeee5eb099), C64e(0x8cf78df6f67a8c8d), + C64e(0x17e50dffffe8170d), C64e(0xdcb7bdd6d60adcbd), + C64e(0xc8a7b1dede16c8b1), C64e(0xfc395491916dfc54), + C64e(0xf0c050606090f050), C64e(0x0504030202070503), + C64e(0xe087a9cece2ee0a9), C64e(0x87ac7d5656d1877d), + C64e(0x2bd519e7e7cc2b19), C64e(0xa67162b5b513a662), + C64e(0x319ae64d4d7c31e6), C64e(0xb5c39aecec59b59a), + C64e(0xcf05458f8f40cf45), C64e(0xbc3e9d1f1fa3bc9d), + C64e(0xc00940898949c040), C64e(0x92ef87fafa689287), + C64e(0x3fc515efefd03f15), C64e(0x267febb2b29426eb), + C64e(0x4007c98e8ece40c9), C64e(0x1ded0bfbfbe61d0b), + C64e(0x2f82ec41416e2fec), C64e(0xa97d67b3b31aa967), + C64e(0x1cbefd5f5f431cfd), C64e(0x258aea45456025ea), + C64e(0xda46bf2323f9dabf), C64e(0x02a6f753535102f7), + C64e(0xa1d396e4e445a196), C64e(0xed2d5b9b9b76ed5b), + C64e(0x5deac27575285dc2), C64e(0x24d91ce1e1c5241c), + C64e(0xe97aae3d3dd4e9ae), C64e(0xbe986a4c4cf2be6a), + C64e(0xeed85a6c6c82ee5a), C64e(0xc3fc417e7ebdc341), + C64e(0x06f102f5f5f30602), C64e(0xd11d4f838352d14f), + C64e(0xe4d05c68688ce45c), C64e(0x07a2f451515607f4), + C64e(0x5cb934d1d18d5c34), C64e(0x18e908f9f9e11808), + C64e(0xaedf93e2e24cae93), C64e(0x954d73abab3e9573), + C64e(0xf5c453626297f553), C64e(0x41543f2a2a6b413f), + C64e(0x14100c08081c140c), C64e(0xf63152959563f652), + C64e(0xaf8c654646e9af65), C64e(0xe2215e9d9d7fe25e), + C64e(0x7860283030487828), C64e(0xf86ea13737cff8a1), + C64e(0x11140f0a0a1b110f), C64e(0xc45eb52f2febc4b5), + C64e(0x1b1c090e0e151b09), C64e(0x5a483624247e5a36), + C64e(0xb6369b1b1badb69b), C64e(0x47a53ddfdf98473d), + C64e(0x6a8126cdcda76a26), C64e(0xbb9c694e4ef5bb69), + C64e(0x4cfecd7f7f334ccd), C64e(0xbacf9feaea50ba9f), + C64e(0x2d241b12123f2d1b), C64e(0xb93a9e1d1da4b99e), + C64e(0x9cb0745858c49c74), C64e(0x72682e343446722e), + C64e(0x776c2d363641772d), C64e(0xcda3b2dcdc11cdb2), + C64e(0x2973eeb4b49d29ee), C64e(0x16b6fb5b5b4d16fb), + C64e(0x0153f6a4a4a501f6), C64e(0xd7ec4d7676a1d74d), + C64e(0xa37561b7b714a361), C64e(0x49face7d7d3449ce), + C64e(0x8da47b5252df8d7b), C64e(0x42a13edddd9f423e), + C64e(0x93bc715e5ecd9371), C64e(0xa226971313b1a297), + C64e(0x0457f5a6a6a204f5), C64e(0xb86968b9b901b868), + C64e(0x0000000000000000), C64e(0x74992cc1c1b5742c), + C64e(0xa080604040e0a060), C64e(0x21dd1fe3e3c2211f), + C64e(0x43f2c879793a43c8), C64e(0x2c77edb6b69a2ced), + C64e(0xd9b3bed4d40dd9be), C64e(0xca01468d8d47ca46), + C64e(0x70ced967671770d9), C64e(0xdde44b7272afdd4b), + C64e(0x7933de9494ed79de), C64e(0x672bd49898ff67d4), + C64e(0x237be8b0b09323e8), C64e(0xde114a85855bde4a), + C64e(0xbd6d6bbbbb06bd6b), C64e(0x7e912ac5c5bb7e2a), + C64e(0x349ee54f4f7b34e5), C64e(0x3ac116ededd73a16), + C64e(0x5417c58686d254c5), C64e(0x622fd79a9af862d7), + C64e(0xffcc55666699ff55), C64e(0xa722941111b6a794), + C64e(0x4a0fcf8a8ac04acf), C64e(0x30c910e9e9d93010), + C64e(0x0a080604040e0a06), C64e(0x98e781fefe669881), + C64e(0x0b5bf0a0a0ab0bf0), C64e(0xccf0447878b4cc44), + C64e(0xd54aba2525f0d5ba), C64e(0x3e96e34b4b753ee3), + C64e(0x0e5ff3a2a2ac0ef3), C64e(0x19bafe5d5d4419fe), + C64e(0x5b1bc08080db5bc0), C64e(0x850a8a050580858a), + C64e(0xec7ead3f3fd3ecad), C64e(0xdf42bc2121fedfbc), + C64e(0xd8e0487070a8d848), C64e(0x0cf904f1f1fd0c04), + C64e(0x7ac6df6363197adf), C64e(0x58eec177772f58c1), + C64e(0x9f4575afaf309f75), C64e(0xa584634242e7a563), + C64e(0x5040302020705030), C64e(0x2ed11ae5e5cb2e1a), + C64e(0x12e10efdfdef120e), C64e(0xb7656dbfbf08b76d), + C64e(0xd4194c818155d44c), C64e(0x3c30141818243c14), + C64e(0x5f4c352626795f35), C64e(0x719d2fc3c3b2712f), + C64e(0x3867e1bebe8638e1), C64e(0xfd6aa23535c8fda2), + C64e(0x4f0bcc8888c74fcc), C64e(0x4b5c392e2e654b39), + C64e(0xf93d5793936af957), C64e(0x0daaf25555580df2), + C64e(0x9de382fcfc619d82), C64e(0xc9f4477a7ab3c947), + C64e(0xef8bacc8c827efac), C64e(0x326fe7baba8832e7), + C64e(0x7d642b32324f7d2b), C64e(0xa4d795e6e642a495), + C64e(0xfb9ba0c0c03bfba0), C64e(0xb332981919aab398), + C64e(0x6827d19e9ef668d1), C64e(0x815d7fa3a322817f), + C64e(0xaa88664444eeaa66), C64e(0x82a87e5454d6827e), + C64e(0xe676ab3b3bdde6ab), C64e(0x9e16830b0b959e83), + C64e(0x4503ca8c8cc945ca), C64e(0x7b9529c7c7bc7b29), + C64e(0x6ed6d36b6b056ed3), C64e(0x44503c28286c443c), + C64e(0x8b5579a7a72c8b79), C64e(0x3d63e2bcbc813de2), + C64e(0x272c1d161631271d), C64e(0x9a4176adad379a76), + C64e(0x4dad3bdbdb964d3b), C64e(0xfac85664649efa56), + C64e(0xd2e84e7474a6d24e), C64e(0x22281e141436221e), + C64e(0x763fdb9292e476db), C64e(0x1e180a0c0c121e0a), + C64e(0xb4906c4848fcb46c), C64e(0x376be4b8b88f37e4), + C64e(0xe7255d9f9f78e75d), C64e(0xb2616ebdbd0fb26e), + C64e(0x2a86ef4343692aef), C64e(0xf193a6c4c435f1a6), + C64e(0xe372a83939dae3a8), C64e(0xf762a43131c6f7a4), + C64e(0x59bd37d3d38a5937), C64e(0x86ff8bf2f274868b), + C64e(0x56b132d5d5835632), C64e(0xc50d438b8b4ec543), + C64e(0xebdc596e6e85eb59), C64e(0xc2afb7dada18c2b7), + C64e(0x8f028c01018e8f8c), C64e(0xac7964b1b11dac64), + C64e(0x6d23d29c9cf16dd2), C64e(0x3b92e04949723be0), + C64e(0xc7abb4d8d81fc7b4), C64e(0x1543faacacb915fa), + C64e(0x09fd07f3f3fa0907), C64e(0x6f8525cfcfa06f25), + C64e(0xea8fafcaca20eaaf), C64e(0x89f38ef4f47d898e), + C64e(0x208ee947476720e9), C64e(0x2820181010382818), + C64e(0x64ded56f6f0b64d5), C64e(0x83fb88f0f0738388), + C64e(0xb1946f4a4afbb16f), C64e(0x96b8725c5cca9672), + C64e(0x6c70243838546c24), C64e(0x08aef157575f08f1), + C64e(0x52e6c773732152c7), C64e(0xf33551979764f351), + C64e(0x658d23cbcbae6523), C64e(0x84597ca1a125847c), + C64e(0xbfcb9ce8e857bf9c), C64e(0x637c213e3e5d6321), + C64e(0x7c37dd9696ea7cdd), C64e(0x7fc2dc61611e7fdc), + C64e(0x911a860d0d9c9186), C64e(0x941e850f0f9b9485), + C64e(0xabdb90e0e04bab90), C64e(0xc6f8427c7cbac642), + C64e(0x57e2c471712657c4), C64e(0xe583aacccc29e5aa), + C64e(0x733bd89090e373d8), C64e(0x0f0c050606090f05), + C64e(0x03f501f7f7f40301), C64e(0x3638121c1c2a3612), + C64e(0xfe9fa3c2c23cfea3), C64e(0xe1d45f6a6a8be15f), + C64e(0x1047f9aeaebe10f9), C64e(0x6bd2d06969026bd0), + C64e(0xa82e911717bfa891), C64e(0xe82958999971e858), + C64e(0x6974273a3a536927), C64e(0xd04eb92727f7d0b9), + C64e(0x48a938d9d9914838), C64e(0x35cd13ebebde3513), + C64e(0xce56b32b2be5ceb3), C64e(0x5544332222775533), + C64e(0xd6bfbbd2d204d6bb), C64e(0x904970a9a9399070), + C64e(0x800e890707878089), C64e(0xf266a73333c1f2a7), + C64e(0xc15ab62d2decc1b6), C64e(0x6678223c3c5a6622), + C64e(0xad2a921515b8ad92), C64e(0x608920c9c9a96020), + C64e(0xdb154987875cdb49), C64e(0x1a4fffaaaab01aff), + C64e(0x88a0785050d88878), C64e(0x8e517aa5a52b8e7a), + C64e(0x8a068f0303898a8f), C64e(0x13b2f859594a13f8), + C64e(0x9b12800909929b80), C64e(0x3934171a1a233917), + C64e(0x75cada65651075da), C64e(0x53b531d7d7845331), + C64e(0x5113c68484d551c6), C64e(0xd3bbb8d0d003d3b8), + C64e(0x5e1fc38282dc5ec3), C64e(0xcb52b02929e2cbb0), + C64e(0x99b4775a5ac39977), C64e(0x333c111e1e2d3311), + C64e(0x46f6cb7b7b3d46cb), C64e(0x1f4bfca8a8b71ffc), + C64e(0x61dad66d6d0c61d6), C64e(0x4e583a2c2c624e3a) +}; + +#if !SPH_SMALL_FOOTPRINT_GROESTL + +static const sph_u64 T5[] = { + C64e(0xa5f497a5c6c632f4), C64e(0x8497eb84f8f86f97), + C64e(0x99b0c799eeee5eb0), C64e(0x8d8cf78df6f67a8c), + C64e(0x0d17e50dffffe817), C64e(0xbddcb7bdd6d60adc), + C64e(0xb1c8a7b1dede16c8), C64e(0x54fc395491916dfc), + C64e(0x50f0c050606090f0), C64e(0x0305040302020705), + C64e(0xa9e087a9cece2ee0), C64e(0x7d87ac7d5656d187), + C64e(0x192bd519e7e7cc2b), C64e(0x62a67162b5b513a6), + C64e(0xe6319ae64d4d7c31), C64e(0x9ab5c39aecec59b5), + C64e(0x45cf05458f8f40cf), C64e(0x9dbc3e9d1f1fa3bc), + C64e(0x40c00940898949c0), C64e(0x8792ef87fafa6892), + C64e(0x153fc515efefd03f), C64e(0xeb267febb2b29426), + C64e(0xc94007c98e8ece40), C64e(0x0b1ded0bfbfbe61d), + C64e(0xec2f82ec41416e2f), C64e(0x67a97d67b3b31aa9), + C64e(0xfd1cbefd5f5f431c), C64e(0xea258aea45456025), + C64e(0xbfda46bf2323f9da), C64e(0xf702a6f753535102), + C64e(0x96a1d396e4e445a1), C64e(0x5bed2d5b9b9b76ed), + C64e(0xc25deac27575285d), C64e(0x1c24d91ce1e1c524), + C64e(0xaee97aae3d3dd4e9), C64e(0x6abe986a4c4cf2be), + C64e(0x5aeed85a6c6c82ee), C64e(0x41c3fc417e7ebdc3), + C64e(0x0206f102f5f5f306), C64e(0x4fd11d4f838352d1), + C64e(0x5ce4d05c68688ce4), C64e(0xf407a2f451515607), + C64e(0x345cb934d1d18d5c), C64e(0x0818e908f9f9e118), + C64e(0x93aedf93e2e24cae), C64e(0x73954d73abab3e95), + C64e(0x53f5c453626297f5), C64e(0x3f41543f2a2a6b41), + C64e(0x0c14100c08081c14), C64e(0x52f63152959563f6), + C64e(0x65af8c654646e9af), C64e(0x5ee2215e9d9d7fe2), + C64e(0x2878602830304878), C64e(0xa1f86ea13737cff8), + C64e(0x0f11140f0a0a1b11), C64e(0xb5c45eb52f2febc4), + C64e(0x091b1c090e0e151b), C64e(0x365a483624247e5a), + C64e(0x9bb6369b1b1badb6), C64e(0x3d47a53ddfdf9847), + C64e(0x266a8126cdcda76a), C64e(0x69bb9c694e4ef5bb), + C64e(0xcd4cfecd7f7f334c), C64e(0x9fbacf9feaea50ba), + C64e(0x1b2d241b12123f2d), C64e(0x9eb93a9e1d1da4b9), + C64e(0x749cb0745858c49c), C64e(0x2e72682e34344672), + C64e(0x2d776c2d36364177), C64e(0xb2cda3b2dcdc11cd), + C64e(0xee2973eeb4b49d29), C64e(0xfb16b6fb5b5b4d16), + C64e(0xf60153f6a4a4a501), C64e(0x4dd7ec4d7676a1d7), + C64e(0x61a37561b7b714a3), C64e(0xce49face7d7d3449), + C64e(0x7b8da47b5252df8d), C64e(0x3e42a13edddd9f42), + C64e(0x7193bc715e5ecd93), C64e(0x97a226971313b1a2), + C64e(0xf50457f5a6a6a204), C64e(0x68b86968b9b901b8), + C64e(0x0000000000000000), C64e(0x2c74992cc1c1b574), + C64e(0x60a080604040e0a0), C64e(0x1f21dd1fe3e3c221), + C64e(0xc843f2c879793a43), C64e(0xed2c77edb6b69a2c), + C64e(0xbed9b3bed4d40dd9), C64e(0x46ca01468d8d47ca), + C64e(0xd970ced967671770), C64e(0x4bdde44b7272afdd), + C64e(0xde7933de9494ed79), C64e(0xd4672bd49898ff67), + C64e(0xe8237be8b0b09323), C64e(0x4ade114a85855bde), + C64e(0x6bbd6d6bbbbb06bd), C64e(0x2a7e912ac5c5bb7e), + C64e(0xe5349ee54f4f7b34), C64e(0x163ac116ededd73a), + C64e(0xc55417c58686d254), C64e(0xd7622fd79a9af862), + C64e(0x55ffcc55666699ff), C64e(0x94a722941111b6a7), + C64e(0xcf4a0fcf8a8ac04a), C64e(0x1030c910e9e9d930), + C64e(0x060a080604040e0a), C64e(0x8198e781fefe6698), + C64e(0xf00b5bf0a0a0ab0b), C64e(0x44ccf0447878b4cc), + C64e(0xbad54aba2525f0d5), C64e(0xe33e96e34b4b753e), + C64e(0xf30e5ff3a2a2ac0e), C64e(0xfe19bafe5d5d4419), + C64e(0xc05b1bc08080db5b), C64e(0x8a850a8a05058085), + C64e(0xadec7ead3f3fd3ec), C64e(0xbcdf42bc2121fedf), + C64e(0x48d8e0487070a8d8), C64e(0x040cf904f1f1fd0c), + C64e(0xdf7ac6df6363197a), C64e(0xc158eec177772f58), + C64e(0x759f4575afaf309f), C64e(0x63a584634242e7a5), + C64e(0x3050403020207050), C64e(0x1a2ed11ae5e5cb2e), + C64e(0x0e12e10efdfdef12), C64e(0x6db7656dbfbf08b7), + C64e(0x4cd4194c818155d4), C64e(0x143c30141818243c), + C64e(0x355f4c352626795f), C64e(0x2f719d2fc3c3b271), + C64e(0xe13867e1bebe8638), C64e(0xa2fd6aa23535c8fd), + C64e(0xcc4f0bcc8888c74f), C64e(0x394b5c392e2e654b), + C64e(0x57f93d5793936af9), C64e(0xf20daaf25555580d), + C64e(0x829de382fcfc619d), C64e(0x47c9f4477a7ab3c9), + C64e(0xacef8bacc8c827ef), C64e(0xe7326fe7baba8832), + C64e(0x2b7d642b32324f7d), C64e(0x95a4d795e6e642a4), + C64e(0xa0fb9ba0c0c03bfb), C64e(0x98b332981919aab3), + C64e(0xd16827d19e9ef668), C64e(0x7f815d7fa3a32281), + C64e(0x66aa88664444eeaa), C64e(0x7e82a87e5454d682), + C64e(0xabe676ab3b3bdde6), C64e(0x839e16830b0b959e), + C64e(0xca4503ca8c8cc945), C64e(0x297b9529c7c7bc7b), + C64e(0xd36ed6d36b6b056e), C64e(0x3c44503c28286c44), + C64e(0x798b5579a7a72c8b), C64e(0xe23d63e2bcbc813d), + C64e(0x1d272c1d16163127), C64e(0x769a4176adad379a), + C64e(0x3b4dad3bdbdb964d), C64e(0x56fac85664649efa), + C64e(0x4ed2e84e7474a6d2), C64e(0x1e22281e14143622), + C64e(0xdb763fdb9292e476), C64e(0x0a1e180a0c0c121e), + C64e(0x6cb4906c4848fcb4), C64e(0xe4376be4b8b88f37), + C64e(0x5de7255d9f9f78e7), C64e(0x6eb2616ebdbd0fb2), + C64e(0xef2a86ef4343692a), C64e(0xa6f193a6c4c435f1), + C64e(0xa8e372a83939dae3), C64e(0xa4f762a43131c6f7), + C64e(0x3759bd37d3d38a59), C64e(0x8b86ff8bf2f27486), + C64e(0x3256b132d5d58356), C64e(0x43c50d438b8b4ec5), + C64e(0x59ebdc596e6e85eb), C64e(0xb7c2afb7dada18c2), + C64e(0x8c8f028c01018e8f), C64e(0x64ac7964b1b11dac), + C64e(0xd26d23d29c9cf16d), C64e(0xe03b92e04949723b), + C64e(0xb4c7abb4d8d81fc7), C64e(0xfa1543faacacb915), + C64e(0x0709fd07f3f3fa09), C64e(0x256f8525cfcfa06f), + C64e(0xafea8fafcaca20ea), C64e(0x8e89f38ef4f47d89), + C64e(0xe9208ee947476720), C64e(0x1828201810103828), + C64e(0xd564ded56f6f0b64), C64e(0x8883fb88f0f07383), + C64e(0x6fb1946f4a4afbb1), C64e(0x7296b8725c5cca96), + C64e(0x246c70243838546c), C64e(0xf108aef157575f08), + C64e(0xc752e6c773732152), C64e(0x51f33551979764f3), + C64e(0x23658d23cbcbae65), C64e(0x7c84597ca1a12584), + C64e(0x9cbfcb9ce8e857bf), C64e(0x21637c213e3e5d63), + C64e(0xdd7c37dd9696ea7c), C64e(0xdc7fc2dc61611e7f), + C64e(0x86911a860d0d9c91), C64e(0x85941e850f0f9b94), + C64e(0x90abdb90e0e04bab), C64e(0x42c6f8427c7cbac6), + C64e(0xc457e2c471712657), C64e(0xaae583aacccc29e5), + C64e(0xd8733bd89090e373), C64e(0x050f0c050606090f), + C64e(0x0103f501f7f7f403), C64e(0x123638121c1c2a36), + C64e(0xa3fe9fa3c2c23cfe), C64e(0x5fe1d45f6a6a8be1), + C64e(0xf91047f9aeaebe10), C64e(0xd06bd2d06969026b), + C64e(0x91a82e911717bfa8), C64e(0x58e82958999971e8), + C64e(0x276974273a3a5369), C64e(0xb9d04eb92727f7d0), + C64e(0x3848a938d9d99148), C64e(0x1335cd13ebebde35), + C64e(0xb3ce56b32b2be5ce), C64e(0x3355443322227755), + C64e(0xbbd6bfbbd2d204d6), C64e(0x70904970a9a93990), + C64e(0x89800e8907078780), C64e(0xa7f266a73333c1f2), + C64e(0xb6c15ab62d2decc1), C64e(0x226678223c3c5a66), + C64e(0x92ad2a921515b8ad), C64e(0x20608920c9c9a960), + C64e(0x49db154987875cdb), C64e(0xff1a4fffaaaab01a), + C64e(0x7888a0785050d888), C64e(0x7a8e517aa5a52b8e), + C64e(0x8f8a068f0303898a), C64e(0xf813b2f859594a13), + C64e(0x809b12800909929b), C64e(0x173934171a1a2339), + C64e(0xda75cada65651075), C64e(0x3153b531d7d78453), + C64e(0xc65113c68484d551), C64e(0xb8d3bbb8d0d003d3), + C64e(0xc35e1fc38282dc5e), C64e(0xb0cb52b02929e2cb), + C64e(0x7799b4775a5ac399), C64e(0x11333c111e1e2d33), + C64e(0xcb46f6cb7b7b3d46), C64e(0xfc1f4bfca8a8b71f), + C64e(0xd661dad66d6d0c61), C64e(0x3a4e583a2c2c624e) +}; + +static const sph_u64 T6[] = { + C64e(0xf4a5f497a5c6c632), C64e(0x978497eb84f8f86f), + C64e(0xb099b0c799eeee5e), C64e(0x8c8d8cf78df6f67a), + C64e(0x170d17e50dffffe8), C64e(0xdcbddcb7bdd6d60a), + C64e(0xc8b1c8a7b1dede16), C64e(0xfc54fc395491916d), + C64e(0xf050f0c050606090), C64e(0x0503050403020207), + C64e(0xe0a9e087a9cece2e), C64e(0x877d87ac7d5656d1), + C64e(0x2b192bd519e7e7cc), C64e(0xa662a67162b5b513), + C64e(0x31e6319ae64d4d7c), C64e(0xb59ab5c39aecec59), + C64e(0xcf45cf05458f8f40), C64e(0xbc9dbc3e9d1f1fa3), + C64e(0xc040c00940898949), C64e(0x928792ef87fafa68), + C64e(0x3f153fc515efefd0), C64e(0x26eb267febb2b294), + C64e(0x40c94007c98e8ece), C64e(0x1d0b1ded0bfbfbe6), + C64e(0x2fec2f82ec41416e), C64e(0xa967a97d67b3b31a), + C64e(0x1cfd1cbefd5f5f43), C64e(0x25ea258aea454560), + C64e(0xdabfda46bf2323f9), C64e(0x02f702a6f7535351), + C64e(0xa196a1d396e4e445), C64e(0xed5bed2d5b9b9b76), + C64e(0x5dc25deac2757528), C64e(0x241c24d91ce1e1c5), + C64e(0xe9aee97aae3d3dd4), C64e(0xbe6abe986a4c4cf2), + C64e(0xee5aeed85a6c6c82), C64e(0xc341c3fc417e7ebd), + C64e(0x060206f102f5f5f3), C64e(0xd14fd11d4f838352), + C64e(0xe45ce4d05c68688c), C64e(0x07f407a2f4515156), + C64e(0x5c345cb934d1d18d), C64e(0x180818e908f9f9e1), + C64e(0xae93aedf93e2e24c), C64e(0x9573954d73abab3e), + C64e(0xf553f5c453626297), C64e(0x413f41543f2a2a6b), + C64e(0x140c14100c08081c), C64e(0xf652f63152959563), + C64e(0xaf65af8c654646e9), C64e(0xe25ee2215e9d9d7f), + C64e(0x7828786028303048), C64e(0xf8a1f86ea13737cf), + C64e(0x110f11140f0a0a1b), C64e(0xc4b5c45eb52f2feb), + C64e(0x1b091b1c090e0e15), C64e(0x5a365a483624247e), + C64e(0xb69bb6369b1b1bad), C64e(0x473d47a53ddfdf98), + C64e(0x6a266a8126cdcda7), C64e(0xbb69bb9c694e4ef5), + C64e(0x4ccd4cfecd7f7f33), C64e(0xba9fbacf9feaea50), + C64e(0x2d1b2d241b12123f), C64e(0xb99eb93a9e1d1da4), + C64e(0x9c749cb0745858c4), C64e(0x722e72682e343446), + C64e(0x772d776c2d363641), C64e(0xcdb2cda3b2dcdc11), + C64e(0x29ee2973eeb4b49d), C64e(0x16fb16b6fb5b5b4d), + C64e(0x01f60153f6a4a4a5), C64e(0xd74dd7ec4d7676a1), + C64e(0xa361a37561b7b714), C64e(0x49ce49face7d7d34), + C64e(0x8d7b8da47b5252df), C64e(0x423e42a13edddd9f), + C64e(0x937193bc715e5ecd), C64e(0xa297a226971313b1), + C64e(0x04f50457f5a6a6a2), C64e(0xb868b86968b9b901), + C64e(0x0000000000000000), C64e(0x742c74992cc1c1b5), + C64e(0xa060a080604040e0), C64e(0x211f21dd1fe3e3c2), + C64e(0x43c843f2c879793a), C64e(0x2ced2c77edb6b69a), + C64e(0xd9bed9b3bed4d40d), C64e(0xca46ca01468d8d47), + C64e(0x70d970ced9676717), C64e(0xdd4bdde44b7272af), + C64e(0x79de7933de9494ed), C64e(0x67d4672bd49898ff), + C64e(0x23e8237be8b0b093), C64e(0xde4ade114a85855b), + C64e(0xbd6bbd6d6bbbbb06), C64e(0x7e2a7e912ac5c5bb), + C64e(0x34e5349ee54f4f7b), C64e(0x3a163ac116ededd7), + C64e(0x54c55417c58686d2), C64e(0x62d7622fd79a9af8), + C64e(0xff55ffcc55666699), C64e(0xa794a722941111b6), + C64e(0x4acf4a0fcf8a8ac0), C64e(0x301030c910e9e9d9), + C64e(0x0a060a080604040e), C64e(0x988198e781fefe66), + C64e(0x0bf00b5bf0a0a0ab), C64e(0xcc44ccf0447878b4), + C64e(0xd5bad54aba2525f0), C64e(0x3ee33e96e34b4b75), + C64e(0x0ef30e5ff3a2a2ac), C64e(0x19fe19bafe5d5d44), + C64e(0x5bc05b1bc08080db), C64e(0x858a850a8a050580), + C64e(0xecadec7ead3f3fd3), C64e(0xdfbcdf42bc2121fe), + C64e(0xd848d8e0487070a8), C64e(0x0c040cf904f1f1fd), + C64e(0x7adf7ac6df636319), C64e(0x58c158eec177772f), + C64e(0x9f759f4575afaf30), C64e(0xa563a584634242e7), + C64e(0x5030504030202070), C64e(0x2e1a2ed11ae5e5cb), + C64e(0x120e12e10efdfdef), C64e(0xb76db7656dbfbf08), + C64e(0xd44cd4194c818155), C64e(0x3c143c3014181824), + C64e(0x5f355f4c35262679), C64e(0x712f719d2fc3c3b2), + C64e(0x38e13867e1bebe86), C64e(0xfda2fd6aa23535c8), + C64e(0x4fcc4f0bcc8888c7), C64e(0x4b394b5c392e2e65), + C64e(0xf957f93d5793936a), C64e(0x0df20daaf2555558), + C64e(0x9d829de382fcfc61), C64e(0xc947c9f4477a7ab3), + C64e(0xefacef8bacc8c827), C64e(0x32e7326fe7baba88), + C64e(0x7d2b7d642b32324f), C64e(0xa495a4d795e6e642), + C64e(0xfba0fb9ba0c0c03b), C64e(0xb398b332981919aa), + C64e(0x68d16827d19e9ef6), C64e(0x817f815d7fa3a322), + C64e(0xaa66aa88664444ee), C64e(0x827e82a87e5454d6), + C64e(0xe6abe676ab3b3bdd), C64e(0x9e839e16830b0b95), + C64e(0x45ca4503ca8c8cc9), C64e(0x7b297b9529c7c7bc), + C64e(0x6ed36ed6d36b6b05), C64e(0x443c44503c28286c), + C64e(0x8b798b5579a7a72c), C64e(0x3de23d63e2bcbc81), + C64e(0x271d272c1d161631), C64e(0x9a769a4176adad37), + C64e(0x4d3b4dad3bdbdb96), C64e(0xfa56fac85664649e), + C64e(0xd24ed2e84e7474a6), C64e(0x221e22281e141436), + C64e(0x76db763fdb9292e4), C64e(0x1e0a1e180a0c0c12), + C64e(0xb46cb4906c4848fc), C64e(0x37e4376be4b8b88f), + C64e(0xe75de7255d9f9f78), C64e(0xb26eb2616ebdbd0f), + C64e(0x2aef2a86ef434369), C64e(0xf1a6f193a6c4c435), + C64e(0xe3a8e372a83939da), C64e(0xf7a4f762a43131c6), + C64e(0x593759bd37d3d38a), C64e(0x868b86ff8bf2f274), + C64e(0x563256b132d5d583), C64e(0xc543c50d438b8b4e), + C64e(0xeb59ebdc596e6e85), C64e(0xc2b7c2afb7dada18), + C64e(0x8f8c8f028c01018e), C64e(0xac64ac7964b1b11d), + C64e(0x6dd26d23d29c9cf1), C64e(0x3be03b92e0494972), + C64e(0xc7b4c7abb4d8d81f), C64e(0x15fa1543faacacb9), + C64e(0x090709fd07f3f3fa), C64e(0x6f256f8525cfcfa0), + C64e(0xeaafea8fafcaca20), C64e(0x898e89f38ef4f47d), + C64e(0x20e9208ee9474767), C64e(0x2818282018101038), + C64e(0x64d564ded56f6f0b), C64e(0x838883fb88f0f073), + C64e(0xb16fb1946f4a4afb), C64e(0x967296b8725c5cca), + C64e(0x6c246c7024383854), C64e(0x08f108aef157575f), + C64e(0x52c752e6c7737321), C64e(0xf351f33551979764), + C64e(0x6523658d23cbcbae), C64e(0x847c84597ca1a125), + C64e(0xbf9cbfcb9ce8e857), C64e(0x6321637c213e3e5d), + C64e(0x7cdd7c37dd9696ea), C64e(0x7fdc7fc2dc61611e), + C64e(0x9186911a860d0d9c), C64e(0x9485941e850f0f9b), + C64e(0xab90abdb90e0e04b), C64e(0xc642c6f8427c7cba), + C64e(0x57c457e2c4717126), C64e(0xe5aae583aacccc29), + C64e(0x73d8733bd89090e3), C64e(0x0f050f0c05060609), + C64e(0x030103f501f7f7f4), C64e(0x36123638121c1c2a), + C64e(0xfea3fe9fa3c2c23c), C64e(0xe15fe1d45f6a6a8b), + C64e(0x10f91047f9aeaebe), C64e(0x6bd06bd2d0696902), + C64e(0xa891a82e911717bf), C64e(0xe858e82958999971), + C64e(0x69276974273a3a53), C64e(0xd0b9d04eb92727f7), + C64e(0x483848a938d9d991), C64e(0x351335cd13ebebde), + C64e(0xceb3ce56b32b2be5), C64e(0x5533554433222277), + C64e(0xd6bbd6bfbbd2d204), C64e(0x9070904970a9a939), + C64e(0x8089800e89070787), C64e(0xf2a7f266a73333c1), + C64e(0xc1b6c15ab62d2dec), C64e(0x66226678223c3c5a), + C64e(0xad92ad2a921515b8), C64e(0x6020608920c9c9a9), + C64e(0xdb49db154987875c), C64e(0x1aff1a4fffaaaab0), + C64e(0x887888a0785050d8), C64e(0x8e7a8e517aa5a52b), + C64e(0x8a8f8a068f030389), C64e(0x13f813b2f859594a), + C64e(0x9b809b1280090992), C64e(0x39173934171a1a23), + C64e(0x75da75cada656510), C64e(0x533153b531d7d784), + C64e(0x51c65113c68484d5), C64e(0xd3b8d3bbb8d0d003), + C64e(0x5ec35e1fc38282dc), C64e(0xcbb0cb52b02929e2), + C64e(0x997799b4775a5ac3), C64e(0x3311333c111e1e2d), + C64e(0x46cb46f6cb7b7b3d), C64e(0x1ffc1f4bfca8a8b7), + C64e(0x61d661dad66d6d0c), C64e(0x4e3a4e583a2c2c62) +}; + +static const sph_u64 T7[] = { + C64e(0x32f4a5f497a5c6c6), C64e(0x6f978497eb84f8f8), + C64e(0x5eb099b0c799eeee), C64e(0x7a8c8d8cf78df6f6), + C64e(0xe8170d17e50dffff), C64e(0x0adcbddcb7bdd6d6), + C64e(0x16c8b1c8a7b1dede), C64e(0x6dfc54fc39549191), + C64e(0x90f050f0c0506060), C64e(0x0705030504030202), + C64e(0x2ee0a9e087a9cece), C64e(0xd1877d87ac7d5656), + C64e(0xcc2b192bd519e7e7), C64e(0x13a662a67162b5b5), + C64e(0x7c31e6319ae64d4d), C64e(0x59b59ab5c39aecec), + C64e(0x40cf45cf05458f8f), C64e(0xa3bc9dbc3e9d1f1f), + C64e(0x49c040c009408989), C64e(0x68928792ef87fafa), + C64e(0xd03f153fc515efef), C64e(0x9426eb267febb2b2), + C64e(0xce40c94007c98e8e), C64e(0xe61d0b1ded0bfbfb), + C64e(0x6e2fec2f82ec4141), C64e(0x1aa967a97d67b3b3), + C64e(0x431cfd1cbefd5f5f), C64e(0x6025ea258aea4545), + C64e(0xf9dabfda46bf2323), C64e(0x5102f702a6f75353), + C64e(0x45a196a1d396e4e4), C64e(0x76ed5bed2d5b9b9b), + C64e(0x285dc25deac27575), C64e(0xc5241c24d91ce1e1), + C64e(0xd4e9aee97aae3d3d), C64e(0xf2be6abe986a4c4c), + C64e(0x82ee5aeed85a6c6c), C64e(0xbdc341c3fc417e7e), + C64e(0xf3060206f102f5f5), C64e(0x52d14fd11d4f8383), + C64e(0x8ce45ce4d05c6868), C64e(0x5607f407a2f45151), + C64e(0x8d5c345cb934d1d1), C64e(0xe1180818e908f9f9), + C64e(0x4cae93aedf93e2e2), C64e(0x3e9573954d73abab), + C64e(0x97f553f5c4536262), C64e(0x6b413f41543f2a2a), + C64e(0x1c140c14100c0808), C64e(0x63f652f631529595), + C64e(0xe9af65af8c654646), C64e(0x7fe25ee2215e9d9d), + C64e(0x4878287860283030), C64e(0xcff8a1f86ea13737), + C64e(0x1b110f11140f0a0a), C64e(0xebc4b5c45eb52f2f), + C64e(0x151b091b1c090e0e), C64e(0x7e5a365a48362424), + C64e(0xadb69bb6369b1b1b), C64e(0x98473d47a53ddfdf), + C64e(0xa76a266a8126cdcd), C64e(0xf5bb69bb9c694e4e), + C64e(0x334ccd4cfecd7f7f), C64e(0x50ba9fbacf9feaea), + C64e(0x3f2d1b2d241b1212), C64e(0xa4b99eb93a9e1d1d), + C64e(0xc49c749cb0745858), C64e(0x46722e72682e3434), + C64e(0x41772d776c2d3636), C64e(0x11cdb2cda3b2dcdc), + C64e(0x9d29ee2973eeb4b4), C64e(0x4d16fb16b6fb5b5b), + C64e(0xa501f60153f6a4a4), C64e(0xa1d74dd7ec4d7676), + C64e(0x14a361a37561b7b7), C64e(0x3449ce49face7d7d), + C64e(0xdf8d7b8da47b5252), C64e(0x9f423e42a13edddd), + C64e(0xcd937193bc715e5e), C64e(0xb1a297a226971313), + C64e(0xa204f50457f5a6a6), C64e(0x01b868b86968b9b9), + C64e(0x0000000000000000), C64e(0xb5742c74992cc1c1), + C64e(0xe0a060a080604040), C64e(0xc2211f21dd1fe3e3), + C64e(0x3a43c843f2c87979), C64e(0x9a2ced2c77edb6b6), + C64e(0x0dd9bed9b3bed4d4), C64e(0x47ca46ca01468d8d), + C64e(0x1770d970ced96767), C64e(0xafdd4bdde44b7272), + C64e(0xed79de7933de9494), C64e(0xff67d4672bd49898), + C64e(0x9323e8237be8b0b0), C64e(0x5bde4ade114a8585), + C64e(0x06bd6bbd6d6bbbbb), C64e(0xbb7e2a7e912ac5c5), + C64e(0x7b34e5349ee54f4f), C64e(0xd73a163ac116eded), + C64e(0xd254c55417c58686), C64e(0xf862d7622fd79a9a), + C64e(0x99ff55ffcc556666), C64e(0xb6a794a722941111), + C64e(0xc04acf4a0fcf8a8a), C64e(0xd9301030c910e9e9), + C64e(0x0e0a060a08060404), C64e(0x66988198e781fefe), + C64e(0xab0bf00b5bf0a0a0), C64e(0xb4cc44ccf0447878), + C64e(0xf0d5bad54aba2525), C64e(0x753ee33e96e34b4b), + C64e(0xac0ef30e5ff3a2a2), C64e(0x4419fe19bafe5d5d), + C64e(0xdb5bc05b1bc08080), C64e(0x80858a850a8a0505), + C64e(0xd3ecadec7ead3f3f), C64e(0xfedfbcdf42bc2121), + C64e(0xa8d848d8e0487070), C64e(0xfd0c040cf904f1f1), + C64e(0x197adf7ac6df6363), C64e(0x2f58c158eec17777), + C64e(0x309f759f4575afaf), C64e(0xe7a563a584634242), + C64e(0x7050305040302020), C64e(0xcb2e1a2ed11ae5e5), + C64e(0xef120e12e10efdfd), C64e(0x08b76db7656dbfbf), + C64e(0x55d44cd4194c8181), C64e(0x243c143c30141818), + C64e(0x795f355f4c352626), C64e(0xb2712f719d2fc3c3), + C64e(0x8638e13867e1bebe), C64e(0xc8fda2fd6aa23535), + C64e(0xc74fcc4f0bcc8888), C64e(0x654b394b5c392e2e), + C64e(0x6af957f93d579393), C64e(0x580df20daaf25555), + C64e(0x619d829de382fcfc), C64e(0xb3c947c9f4477a7a), + C64e(0x27efacef8bacc8c8), C64e(0x8832e7326fe7baba), + C64e(0x4f7d2b7d642b3232), C64e(0x42a495a4d795e6e6), + C64e(0x3bfba0fb9ba0c0c0), C64e(0xaab398b332981919), + C64e(0xf668d16827d19e9e), C64e(0x22817f815d7fa3a3), + C64e(0xeeaa66aa88664444), C64e(0xd6827e82a87e5454), + C64e(0xdde6abe676ab3b3b), C64e(0x959e839e16830b0b), + C64e(0xc945ca4503ca8c8c), C64e(0xbc7b297b9529c7c7), + C64e(0x056ed36ed6d36b6b), C64e(0x6c443c44503c2828), + C64e(0x2c8b798b5579a7a7), C64e(0x813de23d63e2bcbc), + C64e(0x31271d272c1d1616), C64e(0x379a769a4176adad), + C64e(0x964d3b4dad3bdbdb), C64e(0x9efa56fac8566464), + C64e(0xa6d24ed2e84e7474), C64e(0x36221e22281e1414), + C64e(0xe476db763fdb9292), C64e(0x121e0a1e180a0c0c), + C64e(0xfcb46cb4906c4848), C64e(0x8f37e4376be4b8b8), + C64e(0x78e75de7255d9f9f), C64e(0x0fb26eb2616ebdbd), + C64e(0x692aef2a86ef4343), C64e(0x35f1a6f193a6c4c4), + C64e(0xdae3a8e372a83939), C64e(0xc6f7a4f762a43131), + C64e(0x8a593759bd37d3d3), C64e(0x74868b86ff8bf2f2), + C64e(0x83563256b132d5d5), C64e(0x4ec543c50d438b8b), + C64e(0x85eb59ebdc596e6e), C64e(0x18c2b7c2afb7dada), + C64e(0x8e8f8c8f028c0101), C64e(0x1dac64ac7964b1b1), + C64e(0xf16dd26d23d29c9c), C64e(0x723be03b92e04949), + C64e(0x1fc7b4c7abb4d8d8), C64e(0xb915fa1543faacac), + C64e(0xfa090709fd07f3f3), C64e(0xa06f256f8525cfcf), + C64e(0x20eaafea8fafcaca), C64e(0x7d898e89f38ef4f4), + C64e(0x6720e9208ee94747), C64e(0x3828182820181010), + C64e(0x0b64d564ded56f6f), C64e(0x73838883fb88f0f0), + C64e(0xfbb16fb1946f4a4a), C64e(0xca967296b8725c5c), + C64e(0x546c246c70243838), C64e(0x5f08f108aef15757), + C64e(0x2152c752e6c77373), C64e(0x64f351f335519797), + C64e(0xae6523658d23cbcb), C64e(0x25847c84597ca1a1), + C64e(0x57bf9cbfcb9ce8e8), C64e(0x5d6321637c213e3e), + C64e(0xea7cdd7c37dd9696), C64e(0x1e7fdc7fc2dc6161), + C64e(0x9c9186911a860d0d), C64e(0x9b9485941e850f0f), + C64e(0x4bab90abdb90e0e0), C64e(0xbac642c6f8427c7c), + C64e(0x2657c457e2c47171), C64e(0x29e5aae583aacccc), + C64e(0xe373d8733bd89090), C64e(0x090f050f0c050606), + C64e(0xf4030103f501f7f7), C64e(0x2a36123638121c1c), + C64e(0x3cfea3fe9fa3c2c2), C64e(0x8be15fe1d45f6a6a), + C64e(0xbe10f91047f9aeae), C64e(0x026bd06bd2d06969), + C64e(0xbfa891a82e911717), C64e(0x71e858e829589999), + C64e(0x5369276974273a3a), C64e(0xf7d0b9d04eb92727), + C64e(0x91483848a938d9d9), C64e(0xde351335cd13ebeb), + C64e(0xe5ceb3ce56b32b2b), C64e(0x7755335544332222), + C64e(0x04d6bbd6bfbbd2d2), C64e(0x399070904970a9a9), + C64e(0x878089800e890707), C64e(0xc1f2a7f266a73333), + C64e(0xecc1b6c15ab62d2d), C64e(0x5a66226678223c3c), + C64e(0xb8ad92ad2a921515), C64e(0xa96020608920c9c9), + C64e(0x5cdb49db15498787), C64e(0xb01aff1a4fffaaaa), + C64e(0xd8887888a0785050), C64e(0x2b8e7a8e517aa5a5), + C64e(0x898a8f8a068f0303), C64e(0x4a13f813b2f85959), + C64e(0x929b809b12800909), C64e(0x2339173934171a1a), + C64e(0x1075da75cada6565), C64e(0x84533153b531d7d7), + C64e(0xd551c65113c68484), C64e(0x03d3b8d3bbb8d0d0), + C64e(0xdc5ec35e1fc38282), C64e(0xe2cbb0cb52b02929), + C64e(0xc3997799b4775a5a), C64e(0x2d3311333c111e1e), + C64e(0x3d46cb46f6cb7b7b), C64e(0xb71ffc1f4bfca8a8), + C64e(0x0c61d661dad66d6d), C64e(0x624e3a4e583a2c2c) +}; + +#endif + +#define DECL_STATE_SMALL \ + sph_u64 H[8]; + +#define READ_STATE_SMALL(sc) do { \ + memcpy(H, (sc)->state.wide, sizeof H); \ + } while (0) + +#define WRITE_STATE_SMALL(sc) do { \ + memcpy((sc)->state.wide, H, sizeof H); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ R64(T0[B64_1(a[b1])], 8) \ + ^ R64(T0[B64_2(a[b2])], 16) \ + ^ R64(T0[B64_3(a[b3])], 24) \ + ^ T4[B64_4(a[b4])] \ + ^ R64(T4[B64_5(a[b5])], 8) \ + ^ R64(T4[B64_6(a[b6])], 16) \ + ^ R64(T4[B64_7(a[b7])], 24); \ + } while (0) + +#else + +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ T1[B64_1(a[b1])] \ + ^ T2[B64_2(a[b2])] \ + ^ T3[B64_3(a[b3])] \ + ^ T4[B64_4(a[b4])] \ + ^ T5[B64_5(a[b5])] \ + ^ T6[B64_6(a[b6])] \ + ^ T7[B64_7(a[b7])]; \ + } while (0) + +#endif + +#define ROUND_SMALL_P(a, r) do { \ + sph_u64 t[8]; \ + a[0] ^= PC64(0x00, r); \ + a[1] ^= PC64(0x10, r); \ + a[2] ^= PC64(0x20, r); \ + a[3] ^= PC64(0x30, r); \ + a[4] ^= PC64(0x40, r); \ + a[5] ^= PC64(0x50, r); \ + a[6] ^= PC64(0x60, r); \ + a[7] ^= PC64(0x70, r); \ + RSTT(0, a, 0, 1, 2, 3, 4, 5, 6, 7); \ + RSTT(1, a, 1, 2, 3, 4, 5, 6, 7, 0); \ + RSTT(2, a, 2, 3, 4, 5, 6, 7, 0, 1); \ + RSTT(3, a, 3, 4, 5, 6, 7, 0, 1, 2); \ + RSTT(4, a, 4, 5, 6, 7, 0, 1, 2, 3); \ + RSTT(5, a, 5, 6, 7, 0, 1, 2, 3, 4); \ + RSTT(6, a, 6, 7, 0, 1, 2, 3, 4, 5); \ + RSTT(7, a, 7, 0, 1, 2, 3, 4, 5, 6); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#define ROUND_SMALL_Q(a, r) do { \ + sph_u64 t[8]; \ + a[0] ^= QC64(0x00, r); \ + a[1] ^= QC64(0x10, r); \ + a[2] ^= QC64(0x20, r); \ + a[3] ^= QC64(0x30, r); \ + a[4] ^= QC64(0x40, r); \ + a[5] ^= QC64(0x50, r); \ + a[6] ^= QC64(0x60, r); \ + a[7] ^= QC64(0x70, r); \ + RSTT(0, a, 1, 3, 5, 7, 0, 2, 4, 6); \ + RSTT(1, a, 2, 4, 6, 0, 1, 3, 5, 7); \ + RSTT(2, a, 3, 5, 7, 1, 2, 4, 6, 0); \ + RSTT(3, a, 4, 6, 0, 2, 3, 5, 7, 1); \ + RSTT(4, a, 5, 7, 1, 3, 4, 6, 0, 2); \ + RSTT(5, a, 6, 0, 2, 4, 5, 7, 1, 3); \ + RSTT(6, a, 7, 1, 3, 5, 6, 0, 2, 4); \ + RSTT(7, a, 0, 2, 4, 6, 7, 1, 3, 5); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_P(a, r); \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_Q(a, r); \ + } while (0) + +#else + +/* + * Apparently, unrolling more than that confuses GCC, resulting in + * lower performance, even though L1 cache would be no problem. + */ +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_P(a, r + 0); \ + ROUND_SMALL_P(a, r + 1); \ + } \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_Q(a, r + 0); \ + ROUND_SMALL_Q(a, r + 1); \ + } \ + } while (0) + +#endif + +#define COMPRESS_SMALL do { \ + sph_u64 g[8], m[8]; \ + size_t u; \ + for (u = 0; u < 8; u ++) { \ + m[u] = dec64e_aligned(buf + (u << 3)); \ + g[u] = m[u] ^ H[u]; \ + } \ + PERM_SMALL_P(g); \ + PERM_SMALL_Q(m); \ + for (u = 0; u < 8; u ++) \ + H[u] ^= g[u] ^ m[u]; \ + } while (0) + +#define FINAL_SMALL do { \ + sph_u64 x[8]; \ + size_t u; \ + memcpy(x, H, sizeof x); \ + PERM_SMALL_P(x); \ + for (u = 0; u < 8; u ++) \ + H[u] ^= x[u]; \ + } while (0) + +#define DECL_STATE_BIG \ + sph_u64 H[16]; + +#define READ_STATE_BIG(sc) do { \ + memcpy(H, (sc)->state.wide, sizeof H); \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + memcpy((sc)->state.wide, H, sizeof H); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define RBTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ R64(T0[B64_1(a[b1])], 8) \ + ^ R64(T0[B64_2(a[b2])], 16) \ + ^ R64(T0[B64_3(a[b3])], 24) \ + ^ T4[B64_4(a[b4])] \ + ^ R64(T4[B64_5(a[b5])], 8) \ + ^ R64(T4[B64_6(a[b6])], 16) \ + ^ R64(T4[B64_7(a[b7])], 24); \ + } while (0) + +#else + +#define RBTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ T1[B64_1(a[b1])] \ + ^ T2[B64_2(a[b2])] \ + ^ T3[B64_3(a[b3])] \ + ^ T4[B64_4(a[b4])] \ + ^ T5[B64_5(a[b5])] \ + ^ T6[B64_6(a[b6])] \ + ^ T7[B64_7(a[b7])]; \ + } while (0) + +#endif + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define ROUND_BIG_P(a, r) do { \ + sph_u64 t[16]; \ + size_t u; \ + a[0x0] ^= PC64(0x00, r); \ + a[0x1] ^= PC64(0x10, r); \ + a[0x2] ^= PC64(0x20, r); \ + a[0x3] ^= PC64(0x30, r); \ + a[0x4] ^= PC64(0x40, r); \ + a[0x5] ^= PC64(0x50, r); \ + a[0x6] ^= PC64(0x60, r); \ + a[0x7] ^= PC64(0x70, r); \ + a[0x8] ^= PC64(0x80, r); \ + a[0x9] ^= PC64(0x90, r); \ + a[0xA] ^= PC64(0xA0, r); \ + a[0xB] ^= PC64(0xB0, r); \ + a[0xC] ^= PC64(0xC0, r); \ + a[0xD] ^= PC64(0xD0, r); \ + a[0xE] ^= PC64(0xE0, r); \ + a[0xF] ^= PC64(0xF0, r); \ + for (u = 0; u < 16; u += 4) { \ + RBTT(u + 0, a, u + 0, (u + 1) & 0xF, \ + (u + 2) & 0xF, (u + 3) & 0xF, (u + 4) & 0xF, \ + (u + 5) & 0xF, (u + 6) & 0xF, (u + 11) & 0xF); \ + RBTT(u + 1, a, u + 1, (u + 2) & 0xF, \ + (u + 3) & 0xF, (u + 4) & 0xF, (u + 5) & 0xF, \ + (u + 6) & 0xF, (u + 7) & 0xF, (u + 12) & 0xF); \ + RBTT(u + 2, a, u + 2, (u + 3) & 0xF, \ + (u + 4) & 0xF, (u + 5) & 0xF, (u + 6) & 0xF, \ + (u + 7) & 0xF, (u + 8) & 0xF, (u + 13) & 0xF); \ + RBTT(u + 3, a, u + 3, (u + 4) & 0xF, \ + (u + 5) & 0xF, (u + 6) & 0xF, (u + 7) & 0xF, \ + (u + 8) & 0xF, (u + 9) & 0xF, (u + 14) & 0xF); \ + } \ + memcpy(a, t, sizeof t); \ + } while (0) + +#define ROUND_BIG_Q(a, r) do { \ + sph_u64 t[16]; \ + size_t u; \ + a[0x0] ^= QC64(0x00, r); \ + a[0x1] ^= QC64(0x10, r); \ + a[0x2] ^= QC64(0x20, r); \ + a[0x3] ^= QC64(0x30, r); \ + a[0x4] ^= QC64(0x40, r); \ + a[0x5] ^= QC64(0x50, r); \ + a[0x6] ^= QC64(0x60, r); \ + a[0x7] ^= QC64(0x70, r); \ + a[0x8] ^= QC64(0x80, r); \ + a[0x9] ^= QC64(0x90, r); \ + a[0xA] ^= QC64(0xA0, r); \ + a[0xB] ^= QC64(0xB0, r); \ + a[0xC] ^= QC64(0xC0, r); \ + a[0xD] ^= QC64(0xD0, r); \ + a[0xE] ^= QC64(0xE0, r); \ + a[0xF] ^= QC64(0xF0, r); \ + for (u = 0; u < 16; u += 4) { \ + RBTT(u + 0, a, (u + 1) & 0xF, (u + 3) & 0xF, \ + (u + 5) & 0xF, (u + 11) & 0xF, (u + 0) & 0xF, \ + (u + 2) & 0xF, (u + 4) & 0xF, (u + 6) & 0xF); \ + RBTT(u + 1, a, (u + 2) & 0xF, (u + 4) & 0xF, \ + (u + 6) & 0xF, (u + 12) & 0xF, (u + 1) & 0xF, \ + (u + 3) & 0xF, (u + 5) & 0xF, (u + 7) & 0xF); \ + RBTT(u + 2, a, (u + 3) & 0xF, (u + 5) & 0xF, \ + (u + 7) & 0xF, (u + 13) & 0xF, (u + 2) & 0xF, \ + (u + 4) & 0xF, (u + 6) & 0xF, (u + 8) & 0xF); \ + RBTT(u + 3, a, (u + 4) & 0xF, (u + 6) & 0xF, \ + (u + 8) & 0xF, (u + 14) & 0xF, (u + 3) & 0xF, \ + (u + 5) & 0xF, (u + 7) & 0xF, (u + 9) & 0xF); \ + } \ + memcpy(a, t, sizeof t); \ + } while (0) + +#else + +#define ROUND_BIG_P(a, r) do { \ + sph_u64 t[16]; \ + a[0x0] ^= PC64(0x00, r); \ + a[0x1] ^= PC64(0x10, r); \ + a[0x2] ^= PC64(0x20, r); \ + a[0x3] ^= PC64(0x30, r); \ + a[0x4] ^= PC64(0x40, r); \ + a[0x5] ^= PC64(0x50, r); \ + a[0x6] ^= PC64(0x60, r); \ + a[0x7] ^= PC64(0x70, r); \ + a[0x8] ^= PC64(0x80, r); \ + a[0x9] ^= PC64(0x90, r); \ + a[0xA] ^= PC64(0xA0, r); \ + a[0xB] ^= PC64(0xB0, r); \ + a[0xC] ^= PC64(0xC0, r); \ + a[0xD] ^= PC64(0xD0, r); \ + a[0xE] ^= PC64(0xE0, r); \ + a[0xF] ^= PC64(0xF0, r); \ + RBTT(0x0, a, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xB); \ + RBTT(0x1, a, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xC); \ + RBTT(0x2, a, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xD); \ + RBTT(0x3, a, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xE); \ + RBTT(0x4, a, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xF); \ + RBTT(0x5, a, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0x0); \ + RBTT(0x6, a, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x1); \ + RBTT(0x7, a, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0x2); \ + RBTT(0x8, a, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0x3); \ + RBTT(0x9, a, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x4); \ + RBTT(0xA, a, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x5); \ + RBTT(0xB, a, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x6); \ + RBTT(0xC, a, 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x7); \ + RBTT(0xD, a, 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x8); \ + RBTT(0xE, a, 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9); \ + RBTT(0xF, a, 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xA); \ + a[0x0] = t[0x0]; \ + a[0x1] = t[0x1]; \ + a[0x2] = t[0x2]; \ + a[0x3] = t[0x3]; \ + a[0x4] = t[0x4]; \ + a[0x5] = t[0x5]; \ + a[0x6] = t[0x6]; \ + a[0x7] = t[0x7]; \ + a[0x8] = t[0x8]; \ + a[0x9] = t[0x9]; \ + a[0xA] = t[0xA]; \ + a[0xB] = t[0xB]; \ + a[0xC] = t[0xC]; \ + a[0xD] = t[0xD]; \ + a[0xE] = t[0xE]; \ + a[0xF] = t[0xF]; \ + } while (0) + +#define ROUND_BIG_Q(a, r) do { \ + sph_u64 t[16]; \ + a[0x0] ^= QC64(0x00, r); \ + a[0x1] ^= QC64(0x10, r); \ + a[0x2] ^= QC64(0x20, r); \ + a[0x3] ^= QC64(0x30, r); \ + a[0x4] ^= QC64(0x40, r); \ + a[0x5] ^= QC64(0x50, r); \ + a[0x6] ^= QC64(0x60, r); \ + a[0x7] ^= QC64(0x70, r); \ + a[0x8] ^= QC64(0x80, r); \ + a[0x9] ^= QC64(0x90, r); \ + a[0xA] ^= QC64(0xA0, r); \ + a[0xB] ^= QC64(0xB0, r); \ + a[0xC] ^= QC64(0xC0, r); \ + a[0xD] ^= QC64(0xD0, r); \ + a[0xE] ^= QC64(0xE0, r); \ + a[0xF] ^= QC64(0xF0, r); \ + RBTT(0x0, a, 0x1, 0x3, 0x5, 0xB, 0x0, 0x2, 0x4, 0x6); \ + RBTT(0x1, a, 0x2, 0x4, 0x6, 0xC, 0x1, 0x3, 0x5, 0x7); \ + RBTT(0x2, a, 0x3, 0x5, 0x7, 0xD, 0x2, 0x4, 0x6, 0x8); \ + RBTT(0x3, a, 0x4, 0x6, 0x8, 0xE, 0x3, 0x5, 0x7, 0x9); \ + RBTT(0x4, a, 0x5, 0x7, 0x9, 0xF, 0x4, 0x6, 0x8, 0xA); \ + RBTT(0x5, a, 0x6, 0x8, 0xA, 0x0, 0x5, 0x7, 0x9, 0xB); \ + RBTT(0x6, a, 0x7, 0x9, 0xB, 0x1, 0x6, 0x8, 0xA, 0xC); \ + RBTT(0x7, a, 0x8, 0xA, 0xC, 0x2, 0x7, 0x9, 0xB, 0xD); \ + RBTT(0x8, a, 0x9, 0xB, 0xD, 0x3, 0x8, 0xA, 0xC, 0xE); \ + RBTT(0x9, a, 0xA, 0xC, 0xE, 0x4, 0x9, 0xB, 0xD, 0xF); \ + RBTT(0xA, a, 0xB, 0xD, 0xF, 0x5, 0xA, 0xC, 0xE, 0x0); \ + RBTT(0xB, a, 0xC, 0xE, 0x0, 0x6, 0xB, 0xD, 0xF, 0x1); \ + RBTT(0xC, a, 0xD, 0xF, 0x1, 0x7, 0xC, 0xE, 0x0, 0x2); \ + RBTT(0xD, a, 0xE, 0x0, 0x2, 0x8, 0xD, 0xF, 0x1, 0x3); \ + RBTT(0xE, a, 0xF, 0x1, 0x3, 0x9, 0xE, 0x0, 0x2, 0x4); \ + RBTT(0xF, a, 0x0, 0x2, 0x4, 0xA, 0xF, 0x1, 0x3, 0x5); \ + a[0x0] = t[0x0]; \ + a[0x1] = t[0x1]; \ + a[0x2] = t[0x2]; \ + a[0x3] = t[0x3]; \ + a[0x4] = t[0x4]; \ + a[0x5] = t[0x5]; \ + a[0x6] = t[0x6]; \ + a[0x7] = t[0x7]; \ + a[0x8] = t[0x8]; \ + a[0x9] = t[0x9]; \ + a[0xA] = t[0xA]; \ + a[0xB] = t[0xB]; \ + a[0xC] = t[0xC]; \ + a[0xD] = t[0xD]; \ + a[0xE] = t[0xE]; \ + a[0xF] = t[0xF]; \ + } while (0) + +#endif + +#define PERM_BIG_P(a) do { \ + int r; \ + for (r = 0; r < 14; r += 2) { \ + ROUND_BIG_P(a, r + 0); \ + ROUND_BIG_P(a, r + 1); \ + } \ + } while (0) + +#define PERM_BIG_Q(a) do { \ + int r; \ + for (r = 0; r < 14; r += 2) { \ + ROUND_BIG_Q(a, r + 0); \ + ROUND_BIG_Q(a, r + 1); \ + } \ + } while (0) + +/* obsolete +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define COMPRESS_BIG do { \ + sph_u64 g[16], m[16], *ya; \ + const sph_u64 *yc; \ + size_t u; \ + int i; \ + for (u = 0; u < 16; u ++) { \ + m[u] = dec64e_aligned(buf + (u << 3)); \ + g[u] = m[u] ^ H[u]; \ + } \ + ya = g; \ + yc = CP; \ + for (i = 0; i < 2; i ++) { \ + PERM_BIG(ya, yc); \ + ya = m; \ + yc = CQ; \ + } \ + for (u = 0; u < 16; u ++) { \ + H[u] ^= g[u] ^ m[u]; \ + } \ + } while (0) + +#else +*/ + +#define COMPRESS_BIG do { \ + sph_u64 g[16], m[16]; \ + size_t u; \ + for (u = 0; u < 16; u ++) { \ + m[u] = dec64e_aligned(buf + (u << 3)); \ + g[u] = m[u] ^ H[u]; \ + } \ + PERM_BIG_P(g); \ + PERM_BIG_Q(m); \ + for (u = 0; u < 16; u ++) { \ + H[u] ^= g[u] ^ m[u]; \ + } \ + } while (0) + +/* obsolete +#endif +*/ + +#define FINAL_BIG do { \ + sph_u64 x[16]; \ + size_t u; \ + memcpy(x, H, sizeof x); \ + PERM_BIG_P(x); \ + for (u = 0; u < 16; u ++) \ + H[u] ^= x[u]; \ + } while (0) + +#else + +static const sph_u32 T0up[] = { + C32e(0xc632f4a5), C32e(0xf86f9784), C32e(0xee5eb099), C32e(0xf67a8c8d), + C32e(0xffe8170d), C32e(0xd60adcbd), C32e(0xde16c8b1), C32e(0x916dfc54), + C32e(0x6090f050), C32e(0x02070503), C32e(0xce2ee0a9), C32e(0x56d1877d), + C32e(0xe7cc2b19), C32e(0xb513a662), C32e(0x4d7c31e6), C32e(0xec59b59a), + C32e(0x8f40cf45), C32e(0x1fa3bc9d), C32e(0x8949c040), C32e(0xfa689287), + C32e(0xefd03f15), C32e(0xb29426eb), C32e(0x8ece40c9), C32e(0xfbe61d0b), + C32e(0x416e2fec), C32e(0xb31aa967), C32e(0x5f431cfd), C32e(0x456025ea), + C32e(0x23f9dabf), C32e(0x535102f7), C32e(0xe445a196), C32e(0x9b76ed5b), + C32e(0x75285dc2), C32e(0xe1c5241c), C32e(0x3dd4e9ae), C32e(0x4cf2be6a), + C32e(0x6c82ee5a), C32e(0x7ebdc341), C32e(0xf5f30602), C32e(0x8352d14f), + C32e(0x688ce45c), C32e(0x515607f4), C32e(0xd18d5c34), C32e(0xf9e11808), + C32e(0xe24cae93), C32e(0xab3e9573), C32e(0x6297f553), C32e(0x2a6b413f), + C32e(0x081c140c), C32e(0x9563f652), C32e(0x46e9af65), C32e(0x9d7fe25e), + C32e(0x30487828), C32e(0x37cff8a1), C32e(0x0a1b110f), C32e(0x2febc4b5), + C32e(0x0e151b09), C32e(0x247e5a36), C32e(0x1badb69b), C32e(0xdf98473d), + C32e(0xcda76a26), C32e(0x4ef5bb69), C32e(0x7f334ccd), C32e(0xea50ba9f), + C32e(0x123f2d1b), C32e(0x1da4b99e), C32e(0x58c49c74), C32e(0x3446722e), + C32e(0x3641772d), C32e(0xdc11cdb2), C32e(0xb49d29ee), C32e(0x5b4d16fb), + C32e(0xa4a501f6), C32e(0x76a1d74d), C32e(0xb714a361), C32e(0x7d3449ce), + C32e(0x52df8d7b), C32e(0xdd9f423e), C32e(0x5ecd9371), C32e(0x13b1a297), + C32e(0xa6a204f5), C32e(0xb901b868), C32e(0x00000000), C32e(0xc1b5742c), + C32e(0x40e0a060), C32e(0xe3c2211f), C32e(0x793a43c8), C32e(0xb69a2ced), + C32e(0xd40dd9be), C32e(0x8d47ca46), C32e(0x671770d9), C32e(0x72afdd4b), + C32e(0x94ed79de), C32e(0x98ff67d4), C32e(0xb09323e8), C32e(0x855bde4a), + C32e(0xbb06bd6b), C32e(0xc5bb7e2a), C32e(0x4f7b34e5), C32e(0xedd73a16), + C32e(0x86d254c5), C32e(0x9af862d7), C32e(0x6699ff55), C32e(0x11b6a794), + C32e(0x8ac04acf), C32e(0xe9d93010), C32e(0x040e0a06), C32e(0xfe669881), + C32e(0xa0ab0bf0), C32e(0x78b4cc44), C32e(0x25f0d5ba), C32e(0x4b753ee3), + C32e(0xa2ac0ef3), C32e(0x5d4419fe), C32e(0x80db5bc0), C32e(0x0580858a), + C32e(0x3fd3ecad), C32e(0x21fedfbc), C32e(0x70a8d848), C32e(0xf1fd0c04), + C32e(0x63197adf), C32e(0x772f58c1), C32e(0xaf309f75), C32e(0x42e7a563), + C32e(0x20705030), C32e(0xe5cb2e1a), C32e(0xfdef120e), C32e(0xbf08b76d), + C32e(0x8155d44c), C32e(0x18243c14), C32e(0x26795f35), C32e(0xc3b2712f), + C32e(0xbe8638e1), C32e(0x35c8fda2), C32e(0x88c74fcc), C32e(0x2e654b39), + C32e(0x936af957), C32e(0x55580df2), C32e(0xfc619d82), C32e(0x7ab3c947), + C32e(0xc827efac), C32e(0xba8832e7), C32e(0x324f7d2b), C32e(0xe642a495), + C32e(0xc03bfba0), C32e(0x19aab398), C32e(0x9ef668d1), C32e(0xa322817f), + C32e(0x44eeaa66), C32e(0x54d6827e), C32e(0x3bdde6ab), C32e(0x0b959e83), + C32e(0x8cc945ca), C32e(0xc7bc7b29), C32e(0x6b056ed3), C32e(0x286c443c), + C32e(0xa72c8b79), C32e(0xbc813de2), C32e(0x1631271d), C32e(0xad379a76), + C32e(0xdb964d3b), C32e(0x649efa56), C32e(0x74a6d24e), C32e(0x1436221e), + C32e(0x92e476db), C32e(0x0c121e0a), C32e(0x48fcb46c), C32e(0xb88f37e4), + C32e(0x9f78e75d), C32e(0xbd0fb26e), C32e(0x43692aef), C32e(0xc435f1a6), + C32e(0x39dae3a8), C32e(0x31c6f7a4), C32e(0xd38a5937), C32e(0xf274868b), + C32e(0xd5835632), C32e(0x8b4ec543), C32e(0x6e85eb59), C32e(0xda18c2b7), + C32e(0x018e8f8c), C32e(0xb11dac64), C32e(0x9cf16dd2), C32e(0x49723be0), + C32e(0xd81fc7b4), C32e(0xacb915fa), C32e(0xf3fa0907), C32e(0xcfa06f25), + C32e(0xca20eaaf), C32e(0xf47d898e), C32e(0x476720e9), C32e(0x10382818), + C32e(0x6f0b64d5), C32e(0xf0738388), C32e(0x4afbb16f), C32e(0x5cca9672), + C32e(0x38546c24), C32e(0x575f08f1), C32e(0x732152c7), C32e(0x9764f351), + C32e(0xcbae6523), C32e(0xa125847c), C32e(0xe857bf9c), C32e(0x3e5d6321), + C32e(0x96ea7cdd), C32e(0x611e7fdc), C32e(0x0d9c9186), C32e(0x0f9b9485), + C32e(0xe04bab90), C32e(0x7cbac642), C32e(0x712657c4), C32e(0xcc29e5aa), + C32e(0x90e373d8), C32e(0x06090f05), C32e(0xf7f40301), C32e(0x1c2a3612), + C32e(0xc23cfea3), C32e(0x6a8be15f), C32e(0xaebe10f9), C32e(0x69026bd0), + C32e(0x17bfa891), C32e(0x9971e858), C32e(0x3a536927), C32e(0x27f7d0b9), + C32e(0xd9914838), C32e(0xebde3513), C32e(0x2be5ceb3), C32e(0x22775533), + C32e(0xd204d6bb), C32e(0xa9399070), C32e(0x07878089), C32e(0x33c1f2a7), + C32e(0x2decc1b6), C32e(0x3c5a6622), C32e(0x15b8ad92), C32e(0xc9a96020), + C32e(0x875cdb49), C32e(0xaab01aff), C32e(0x50d88878), C32e(0xa52b8e7a), + C32e(0x03898a8f), C32e(0x594a13f8), C32e(0x09929b80), C32e(0x1a233917), + C32e(0x651075da), C32e(0xd7845331), C32e(0x84d551c6), C32e(0xd003d3b8), + C32e(0x82dc5ec3), C32e(0x29e2cbb0), C32e(0x5ac39977), C32e(0x1e2d3311), + C32e(0x7b3d46cb), C32e(0xa8b71ffc), C32e(0x6d0c61d6), C32e(0x2c624e3a) +}; + +static const sph_u32 T0dn[] = { + C32e(0xf497a5c6), C32e(0x97eb84f8), C32e(0xb0c799ee), C32e(0x8cf78df6), + C32e(0x17e50dff), C32e(0xdcb7bdd6), C32e(0xc8a7b1de), C32e(0xfc395491), + C32e(0xf0c05060), C32e(0x05040302), C32e(0xe087a9ce), C32e(0x87ac7d56), + C32e(0x2bd519e7), C32e(0xa67162b5), C32e(0x319ae64d), C32e(0xb5c39aec), + C32e(0xcf05458f), C32e(0xbc3e9d1f), C32e(0xc0094089), C32e(0x92ef87fa), + C32e(0x3fc515ef), C32e(0x267febb2), C32e(0x4007c98e), C32e(0x1ded0bfb), + C32e(0x2f82ec41), C32e(0xa97d67b3), C32e(0x1cbefd5f), C32e(0x258aea45), + C32e(0xda46bf23), C32e(0x02a6f753), C32e(0xa1d396e4), C32e(0xed2d5b9b), + C32e(0x5deac275), C32e(0x24d91ce1), C32e(0xe97aae3d), C32e(0xbe986a4c), + C32e(0xeed85a6c), C32e(0xc3fc417e), C32e(0x06f102f5), C32e(0xd11d4f83), + C32e(0xe4d05c68), C32e(0x07a2f451), C32e(0x5cb934d1), C32e(0x18e908f9), + C32e(0xaedf93e2), C32e(0x954d73ab), C32e(0xf5c45362), C32e(0x41543f2a), + C32e(0x14100c08), C32e(0xf6315295), C32e(0xaf8c6546), C32e(0xe2215e9d), + C32e(0x78602830), C32e(0xf86ea137), C32e(0x11140f0a), C32e(0xc45eb52f), + C32e(0x1b1c090e), C32e(0x5a483624), C32e(0xb6369b1b), C32e(0x47a53ddf), + C32e(0x6a8126cd), C32e(0xbb9c694e), C32e(0x4cfecd7f), C32e(0xbacf9fea), + C32e(0x2d241b12), C32e(0xb93a9e1d), C32e(0x9cb07458), C32e(0x72682e34), + C32e(0x776c2d36), C32e(0xcda3b2dc), C32e(0x2973eeb4), C32e(0x16b6fb5b), + C32e(0x0153f6a4), C32e(0xd7ec4d76), C32e(0xa37561b7), C32e(0x49face7d), + C32e(0x8da47b52), C32e(0x42a13edd), C32e(0x93bc715e), C32e(0xa2269713), + C32e(0x0457f5a6), C32e(0xb86968b9), C32e(0x00000000), C32e(0x74992cc1), + C32e(0xa0806040), C32e(0x21dd1fe3), C32e(0x43f2c879), C32e(0x2c77edb6), + C32e(0xd9b3bed4), C32e(0xca01468d), C32e(0x70ced967), C32e(0xdde44b72), + C32e(0x7933de94), C32e(0x672bd498), C32e(0x237be8b0), C32e(0xde114a85), + C32e(0xbd6d6bbb), C32e(0x7e912ac5), C32e(0x349ee54f), C32e(0x3ac116ed), + C32e(0x5417c586), C32e(0x622fd79a), C32e(0xffcc5566), C32e(0xa7229411), + C32e(0x4a0fcf8a), C32e(0x30c910e9), C32e(0x0a080604), C32e(0x98e781fe), + C32e(0x0b5bf0a0), C32e(0xccf04478), C32e(0xd54aba25), C32e(0x3e96e34b), + C32e(0x0e5ff3a2), C32e(0x19bafe5d), C32e(0x5b1bc080), C32e(0x850a8a05), + C32e(0xec7ead3f), C32e(0xdf42bc21), C32e(0xd8e04870), C32e(0x0cf904f1), + C32e(0x7ac6df63), C32e(0x58eec177), C32e(0x9f4575af), C32e(0xa5846342), + C32e(0x50403020), C32e(0x2ed11ae5), C32e(0x12e10efd), C32e(0xb7656dbf), + C32e(0xd4194c81), C32e(0x3c301418), C32e(0x5f4c3526), C32e(0x719d2fc3), + C32e(0x3867e1be), C32e(0xfd6aa235), C32e(0x4f0bcc88), C32e(0x4b5c392e), + C32e(0xf93d5793), C32e(0x0daaf255), C32e(0x9de382fc), C32e(0xc9f4477a), + C32e(0xef8bacc8), C32e(0x326fe7ba), C32e(0x7d642b32), C32e(0xa4d795e6), + C32e(0xfb9ba0c0), C32e(0xb3329819), C32e(0x6827d19e), C32e(0x815d7fa3), + C32e(0xaa886644), C32e(0x82a87e54), C32e(0xe676ab3b), C32e(0x9e16830b), + C32e(0x4503ca8c), C32e(0x7b9529c7), C32e(0x6ed6d36b), C32e(0x44503c28), + C32e(0x8b5579a7), C32e(0x3d63e2bc), C32e(0x272c1d16), C32e(0x9a4176ad), + C32e(0x4dad3bdb), C32e(0xfac85664), C32e(0xd2e84e74), C32e(0x22281e14), + C32e(0x763fdb92), C32e(0x1e180a0c), C32e(0xb4906c48), C32e(0x376be4b8), + C32e(0xe7255d9f), C32e(0xb2616ebd), C32e(0x2a86ef43), C32e(0xf193a6c4), + C32e(0xe372a839), C32e(0xf762a431), C32e(0x59bd37d3), C32e(0x86ff8bf2), + C32e(0x56b132d5), C32e(0xc50d438b), C32e(0xebdc596e), C32e(0xc2afb7da), + C32e(0x8f028c01), C32e(0xac7964b1), C32e(0x6d23d29c), C32e(0x3b92e049), + C32e(0xc7abb4d8), C32e(0x1543faac), C32e(0x09fd07f3), C32e(0x6f8525cf), + C32e(0xea8fafca), C32e(0x89f38ef4), C32e(0x208ee947), C32e(0x28201810), + C32e(0x64ded56f), C32e(0x83fb88f0), C32e(0xb1946f4a), C32e(0x96b8725c), + C32e(0x6c702438), C32e(0x08aef157), C32e(0x52e6c773), C32e(0xf3355197), + C32e(0x658d23cb), C32e(0x84597ca1), C32e(0xbfcb9ce8), C32e(0x637c213e), + C32e(0x7c37dd96), C32e(0x7fc2dc61), C32e(0x911a860d), C32e(0x941e850f), + C32e(0xabdb90e0), C32e(0xc6f8427c), C32e(0x57e2c471), C32e(0xe583aacc), + C32e(0x733bd890), C32e(0x0f0c0506), C32e(0x03f501f7), C32e(0x3638121c), + C32e(0xfe9fa3c2), C32e(0xe1d45f6a), C32e(0x1047f9ae), C32e(0x6bd2d069), + C32e(0xa82e9117), C32e(0xe8295899), C32e(0x6974273a), C32e(0xd04eb927), + C32e(0x48a938d9), C32e(0x35cd13eb), C32e(0xce56b32b), C32e(0x55443322), + C32e(0xd6bfbbd2), C32e(0x904970a9), C32e(0x800e8907), C32e(0xf266a733), + C32e(0xc15ab62d), C32e(0x6678223c), C32e(0xad2a9215), C32e(0x608920c9), + C32e(0xdb154987), C32e(0x1a4fffaa), C32e(0x88a07850), C32e(0x8e517aa5), + C32e(0x8a068f03), C32e(0x13b2f859), C32e(0x9b128009), C32e(0x3934171a), + C32e(0x75cada65), C32e(0x53b531d7), C32e(0x5113c684), C32e(0xd3bbb8d0), + C32e(0x5e1fc382), C32e(0xcb52b029), C32e(0x99b4775a), C32e(0x333c111e), + C32e(0x46f6cb7b), C32e(0x1f4bfca8), C32e(0x61dad66d), C32e(0x4e583a2c) +}; + +static const sph_u32 T1up[] = { + C32e(0xc6c632f4), C32e(0xf8f86f97), C32e(0xeeee5eb0), C32e(0xf6f67a8c), + C32e(0xffffe817), C32e(0xd6d60adc), C32e(0xdede16c8), C32e(0x91916dfc), + C32e(0x606090f0), C32e(0x02020705), C32e(0xcece2ee0), C32e(0x5656d187), + C32e(0xe7e7cc2b), C32e(0xb5b513a6), C32e(0x4d4d7c31), C32e(0xecec59b5), + C32e(0x8f8f40cf), C32e(0x1f1fa3bc), C32e(0x898949c0), C32e(0xfafa6892), + C32e(0xefefd03f), C32e(0xb2b29426), C32e(0x8e8ece40), C32e(0xfbfbe61d), + C32e(0x41416e2f), C32e(0xb3b31aa9), C32e(0x5f5f431c), C32e(0x45456025), + C32e(0x2323f9da), C32e(0x53535102), C32e(0xe4e445a1), C32e(0x9b9b76ed), + C32e(0x7575285d), C32e(0xe1e1c524), C32e(0x3d3dd4e9), C32e(0x4c4cf2be), + C32e(0x6c6c82ee), C32e(0x7e7ebdc3), C32e(0xf5f5f306), C32e(0x838352d1), + C32e(0x68688ce4), C32e(0x51515607), C32e(0xd1d18d5c), C32e(0xf9f9e118), + C32e(0xe2e24cae), C32e(0xabab3e95), C32e(0x626297f5), C32e(0x2a2a6b41), + C32e(0x08081c14), C32e(0x959563f6), C32e(0x4646e9af), C32e(0x9d9d7fe2), + C32e(0x30304878), C32e(0x3737cff8), C32e(0x0a0a1b11), C32e(0x2f2febc4), + C32e(0x0e0e151b), C32e(0x24247e5a), C32e(0x1b1badb6), C32e(0xdfdf9847), + C32e(0xcdcda76a), C32e(0x4e4ef5bb), C32e(0x7f7f334c), C32e(0xeaea50ba), + C32e(0x12123f2d), C32e(0x1d1da4b9), C32e(0x5858c49c), C32e(0x34344672), + C32e(0x36364177), C32e(0xdcdc11cd), C32e(0xb4b49d29), C32e(0x5b5b4d16), + C32e(0xa4a4a501), C32e(0x7676a1d7), C32e(0xb7b714a3), C32e(0x7d7d3449), + C32e(0x5252df8d), C32e(0xdddd9f42), C32e(0x5e5ecd93), C32e(0x1313b1a2), + C32e(0xa6a6a204), C32e(0xb9b901b8), C32e(0x00000000), C32e(0xc1c1b574), + C32e(0x4040e0a0), C32e(0xe3e3c221), C32e(0x79793a43), C32e(0xb6b69a2c), + C32e(0xd4d40dd9), C32e(0x8d8d47ca), C32e(0x67671770), C32e(0x7272afdd), + C32e(0x9494ed79), C32e(0x9898ff67), C32e(0xb0b09323), C32e(0x85855bde), + C32e(0xbbbb06bd), C32e(0xc5c5bb7e), C32e(0x4f4f7b34), C32e(0xededd73a), + C32e(0x8686d254), C32e(0x9a9af862), C32e(0x666699ff), C32e(0x1111b6a7), + C32e(0x8a8ac04a), C32e(0xe9e9d930), C32e(0x04040e0a), C32e(0xfefe6698), + C32e(0xa0a0ab0b), C32e(0x7878b4cc), C32e(0x2525f0d5), C32e(0x4b4b753e), + C32e(0xa2a2ac0e), C32e(0x5d5d4419), C32e(0x8080db5b), C32e(0x05058085), + C32e(0x3f3fd3ec), C32e(0x2121fedf), C32e(0x7070a8d8), C32e(0xf1f1fd0c), + C32e(0x6363197a), C32e(0x77772f58), C32e(0xafaf309f), C32e(0x4242e7a5), + C32e(0x20207050), C32e(0xe5e5cb2e), C32e(0xfdfdef12), C32e(0xbfbf08b7), + C32e(0x818155d4), C32e(0x1818243c), C32e(0x2626795f), C32e(0xc3c3b271), + C32e(0xbebe8638), C32e(0x3535c8fd), C32e(0x8888c74f), C32e(0x2e2e654b), + C32e(0x93936af9), C32e(0x5555580d), C32e(0xfcfc619d), C32e(0x7a7ab3c9), + C32e(0xc8c827ef), C32e(0xbaba8832), C32e(0x32324f7d), C32e(0xe6e642a4), + C32e(0xc0c03bfb), C32e(0x1919aab3), C32e(0x9e9ef668), C32e(0xa3a32281), + C32e(0x4444eeaa), C32e(0x5454d682), C32e(0x3b3bdde6), C32e(0x0b0b959e), + C32e(0x8c8cc945), C32e(0xc7c7bc7b), C32e(0x6b6b056e), C32e(0x28286c44), + C32e(0xa7a72c8b), C32e(0xbcbc813d), C32e(0x16163127), C32e(0xadad379a), + C32e(0xdbdb964d), C32e(0x64649efa), C32e(0x7474a6d2), C32e(0x14143622), + C32e(0x9292e476), C32e(0x0c0c121e), C32e(0x4848fcb4), C32e(0xb8b88f37), + C32e(0x9f9f78e7), C32e(0xbdbd0fb2), C32e(0x4343692a), C32e(0xc4c435f1), + C32e(0x3939dae3), C32e(0x3131c6f7), C32e(0xd3d38a59), C32e(0xf2f27486), + C32e(0xd5d58356), C32e(0x8b8b4ec5), C32e(0x6e6e85eb), C32e(0xdada18c2), + C32e(0x01018e8f), C32e(0xb1b11dac), C32e(0x9c9cf16d), C32e(0x4949723b), + C32e(0xd8d81fc7), C32e(0xacacb915), C32e(0xf3f3fa09), C32e(0xcfcfa06f), + C32e(0xcaca20ea), C32e(0xf4f47d89), C32e(0x47476720), C32e(0x10103828), + C32e(0x6f6f0b64), C32e(0xf0f07383), C32e(0x4a4afbb1), C32e(0x5c5cca96), + C32e(0x3838546c), C32e(0x57575f08), C32e(0x73732152), C32e(0x979764f3), + C32e(0xcbcbae65), C32e(0xa1a12584), C32e(0xe8e857bf), C32e(0x3e3e5d63), + C32e(0x9696ea7c), C32e(0x61611e7f), C32e(0x0d0d9c91), C32e(0x0f0f9b94), + C32e(0xe0e04bab), C32e(0x7c7cbac6), C32e(0x71712657), C32e(0xcccc29e5), + C32e(0x9090e373), C32e(0x0606090f), C32e(0xf7f7f403), C32e(0x1c1c2a36), + C32e(0xc2c23cfe), C32e(0x6a6a8be1), C32e(0xaeaebe10), C32e(0x6969026b), + C32e(0x1717bfa8), C32e(0x999971e8), C32e(0x3a3a5369), C32e(0x2727f7d0), + C32e(0xd9d99148), C32e(0xebebde35), C32e(0x2b2be5ce), C32e(0x22227755), + C32e(0xd2d204d6), C32e(0xa9a93990), C32e(0x07078780), C32e(0x3333c1f2), + C32e(0x2d2decc1), C32e(0x3c3c5a66), C32e(0x1515b8ad), C32e(0xc9c9a960), + C32e(0x87875cdb), C32e(0xaaaab01a), C32e(0x5050d888), C32e(0xa5a52b8e), + C32e(0x0303898a), C32e(0x59594a13), C32e(0x0909929b), C32e(0x1a1a2339), + C32e(0x65651075), C32e(0xd7d78453), C32e(0x8484d551), C32e(0xd0d003d3), + C32e(0x8282dc5e), C32e(0x2929e2cb), C32e(0x5a5ac399), C32e(0x1e1e2d33), + C32e(0x7b7b3d46), C32e(0xa8a8b71f), C32e(0x6d6d0c61), C32e(0x2c2c624e) +}; + +static const sph_u32 T1dn[] = { + C32e(0xa5f497a5), C32e(0x8497eb84), C32e(0x99b0c799), C32e(0x8d8cf78d), + C32e(0x0d17e50d), C32e(0xbddcb7bd), C32e(0xb1c8a7b1), C32e(0x54fc3954), + C32e(0x50f0c050), C32e(0x03050403), C32e(0xa9e087a9), C32e(0x7d87ac7d), + C32e(0x192bd519), C32e(0x62a67162), C32e(0xe6319ae6), C32e(0x9ab5c39a), + C32e(0x45cf0545), C32e(0x9dbc3e9d), C32e(0x40c00940), C32e(0x8792ef87), + C32e(0x153fc515), C32e(0xeb267feb), C32e(0xc94007c9), C32e(0x0b1ded0b), + C32e(0xec2f82ec), C32e(0x67a97d67), C32e(0xfd1cbefd), C32e(0xea258aea), + C32e(0xbfda46bf), C32e(0xf702a6f7), C32e(0x96a1d396), C32e(0x5bed2d5b), + C32e(0xc25deac2), C32e(0x1c24d91c), C32e(0xaee97aae), C32e(0x6abe986a), + C32e(0x5aeed85a), C32e(0x41c3fc41), C32e(0x0206f102), C32e(0x4fd11d4f), + C32e(0x5ce4d05c), C32e(0xf407a2f4), C32e(0x345cb934), C32e(0x0818e908), + C32e(0x93aedf93), C32e(0x73954d73), C32e(0x53f5c453), C32e(0x3f41543f), + C32e(0x0c14100c), C32e(0x52f63152), C32e(0x65af8c65), C32e(0x5ee2215e), + C32e(0x28786028), C32e(0xa1f86ea1), C32e(0x0f11140f), C32e(0xb5c45eb5), + C32e(0x091b1c09), C32e(0x365a4836), C32e(0x9bb6369b), C32e(0x3d47a53d), + C32e(0x266a8126), C32e(0x69bb9c69), C32e(0xcd4cfecd), C32e(0x9fbacf9f), + C32e(0x1b2d241b), C32e(0x9eb93a9e), C32e(0x749cb074), C32e(0x2e72682e), + C32e(0x2d776c2d), C32e(0xb2cda3b2), C32e(0xee2973ee), C32e(0xfb16b6fb), + C32e(0xf60153f6), C32e(0x4dd7ec4d), C32e(0x61a37561), C32e(0xce49face), + C32e(0x7b8da47b), C32e(0x3e42a13e), C32e(0x7193bc71), C32e(0x97a22697), + C32e(0xf50457f5), C32e(0x68b86968), C32e(0x00000000), C32e(0x2c74992c), + C32e(0x60a08060), C32e(0x1f21dd1f), C32e(0xc843f2c8), C32e(0xed2c77ed), + C32e(0xbed9b3be), C32e(0x46ca0146), C32e(0xd970ced9), C32e(0x4bdde44b), + C32e(0xde7933de), C32e(0xd4672bd4), C32e(0xe8237be8), C32e(0x4ade114a), + C32e(0x6bbd6d6b), C32e(0x2a7e912a), C32e(0xe5349ee5), C32e(0x163ac116), + C32e(0xc55417c5), C32e(0xd7622fd7), C32e(0x55ffcc55), C32e(0x94a72294), + C32e(0xcf4a0fcf), C32e(0x1030c910), C32e(0x060a0806), C32e(0x8198e781), + C32e(0xf00b5bf0), C32e(0x44ccf044), C32e(0xbad54aba), C32e(0xe33e96e3), + C32e(0xf30e5ff3), C32e(0xfe19bafe), C32e(0xc05b1bc0), C32e(0x8a850a8a), + C32e(0xadec7ead), C32e(0xbcdf42bc), C32e(0x48d8e048), C32e(0x040cf904), + C32e(0xdf7ac6df), C32e(0xc158eec1), C32e(0x759f4575), C32e(0x63a58463), + C32e(0x30504030), C32e(0x1a2ed11a), C32e(0x0e12e10e), C32e(0x6db7656d), + C32e(0x4cd4194c), C32e(0x143c3014), C32e(0x355f4c35), C32e(0x2f719d2f), + C32e(0xe13867e1), C32e(0xa2fd6aa2), C32e(0xcc4f0bcc), C32e(0x394b5c39), + C32e(0x57f93d57), C32e(0xf20daaf2), C32e(0x829de382), C32e(0x47c9f447), + C32e(0xacef8bac), C32e(0xe7326fe7), C32e(0x2b7d642b), C32e(0x95a4d795), + C32e(0xa0fb9ba0), C32e(0x98b33298), C32e(0xd16827d1), C32e(0x7f815d7f), + C32e(0x66aa8866), C32e(0x7e82a87e), C32e(0xabe676ab), C32e(0x839e1683), + C32e(0xca4503ca), C32e(0x297b9529), C32e(0xd36ed6d3), C32e(0x3c44503c), + C32e(0x798b5579), C32e(0xe23d63e2), C32e(0x1d272c1d), C32e(0x769a4176), + C32e(0x3b4dad3b), C32e(0x56fac856), C32e(0x4ed2e84e), C32e(0x1e22281e), + C32e(0xdb763fdb), C32e(0x0a1e180a), C32e(0x6cb4906c), C32e(0xe4376be4), + C32e(0x5de7255d), C32e(0x6eb2616e), C32e(0xef2a86ef), C32e(0xa6f193a6), + C32e(0xa8e372a8), C32e(0xa4f762a4), C32e(0x3759bd37), C32e(0x8b86ff8b), + C32e(0x3256b132), C32e(0x43c50d43), C32e(0x59ebdc59), C32e(0xb7c2afb7), + C32e(0x8c8f028c), C32e(0x64ac7964), C32e(0xd26d23d2), C32e(0xe03b92e0), + C32e(0xb4c7abb4), C32e(0xfa1543fa), C32e(0x0709fd07), C32e(0x256f8525), + C32e(0xafea8faf), C32e(0x8e89f38e), C32e(0xe9208ee9), C32e(0x18282018), + C32e(0xd564ded5), C32e(0x8883fb88), C32e(0x6fb1946f), C32e(0x7296b872), + C32e(0x246c7024), C32e(0xf108aef1), C32e(0xc752e6c7), C32e(0x51f33551), + C32e(0x23658d23), C32e(0x7c84597c), C32e(0x9cbfcb9c), C32e(0x21637c21), + C32e(0xdd7c37dd), C32e(0xdc7fc2dc), C32e(0x86911a86), C32e(0x85941e85), + C32e(0x90abdb90), C32e(0x42c6f842), C32e(0xc457e2c4), C32e(0xaae583aa), + C32e(0xd8733bd8), C32e(0x050f0c05), C32e(0x0103f501), C32e(0x12363812), + C32e(0xa3fe9fa3), C32e(0x5fe1d45f), C32e(0xf91047f9), C32e(0xd06bd2d0), + C32e(0x91a82e91), C32e(0x58e82958), C32e(0x27697427), C32e(0xb9d04eb9), + C32e(0x3848a938), C32e(0x1335cd13), C32e(0xb3ce56b3), C32e(0x33554433), + C32e(0xbbd6bfbb), C32e(0x70904970), C32e(0x89800e89), C32e(0xa7f266a7), + C32e(0xb6c15ab6), C32e(0x22667822), C32e(0x92ad2a92), C32e(0x20608920), + C32e(0x49db1549), C32e(0xff1a4fff), C32e(0x7888a078), C32e(0x7a8e517a), + C32e(0x8f8a068f), C32e(0xf813b2f8), C32e(0x809b1280), C32e(0x17393417), + C32e(0xda75cada), C32e(0x3153b531), C32e(0xc65113c6), C32e(0xb8d3bbb8), + C32e(0xc35e1fc3), C32e(0xb0cb52b0), C32e(0x7799b477), C32e(0x11333c11), + C32e(0xcb46f6cb), C32e(0xfc1f4bfc), C32e(0xd661dad6), C32e(0x3a4e583a) +}; + +static const sph_u32 T2up[] = { + C32e(0xa5c6c632), C32e(0x84f8f86f), C32e(0x99eeee5e), C32e(0x8df6f67a), + C32e(0x0dffffe8), C32e(0xbdd6d60a), C32e(0xb1dede16), C32e(0x5491916d), + C32e(0x50606090), C32e(0x03020207), C32e(0xa9cece2e), C32e(0x7d5656d1), + C32e(0x19e7e7cc), C32e(0x62b5b513), C32e(0xe64d4d7c), C32e(0x9aecec59), + C32e(0x458f8f40), C32e(0x9d1f1fa3), C32e(0x40898949), C32e(0x87fafa68), + C32e(0x15efefd0), C32e(0xebb2b294), C32e(0xc98e8ece), C32e(0x0bfbfbe6), + C32e(0xec41416e), C32e(0x67b3b31a), C32e(0xfd5f5f43), C32e(0xea454560), + C32e(0xbf2323f9), C32e(0xf7535351), C32e(0x96e4e445), C32e(0x5b9b9b76), + C32e(0xc2757528), C32e(0x1ce1e1c5), C32e(0xae3d3dd4), C32e(0x6a4c4cf2), + C32e(0x5a6c6c82), C32e(0x417e7ebd), C32e(0x02f5f5f3), C32e(0x4f838352), + C32e(0x5c68688c), C32e(0xf4515156), C32e(0x34d1d18d), C32e(0x08f9f9e1), + C32e(0x93e2e24c), C32e(0x73abab3e), C32e(0x53626297), C32e(0x3f2a2a6b), + C32e(0x0c08081c), C32e(0x52959563), C32e(0x654646e9), C32e(0x5e9d9d7f), + C32e(0x28303048), C32e(0xa13737cf), C32e(0x0f0a0a1b), C32e(0xb52f2feb), + C32e(0x090e0e15), C32e(0x3624247e), C32e(0x9b1b1bad), C32e(0x3ddfdf98), + C32e(0x26cdcda7), C32e(0x694e4ef5), C32e(0xcd7f7f33), C32e(0x9feaea50), + C32e(0x1b12123f), C32e(0x9e1d1da4), C32e(0x745858c4), C32e(0x2e343446), + C32e(0x2d363641), C32e(0xb2dcdc11), C32e(0xeeb4b49d), C32e(0xfb5b5b4d), + C32e(0xf6a4a4a5), C32e(0x4d7676a1), C32e(0x61b7b714), C32e(0xce7d7d34), + C32e(0x7b5252df), C32e(0x3edddd9f), C32e(0x715e5ecd), C32e(0x971313b1), + C32e(0xf5a6a6a2), C32e(0x68b9b901), C32e(0x00000000), C32e(0x2cc1c1b5), + C32e(0x604040e0), C32e(0x1fe3e3c2), C32e(0xc879793a), C32e(0xedb6b69a), + C32e(0xbed4d40d), C32e(0x468d8d47), C32e(0xd9676717), C32e(0x4b7272af), + C32e(0xde9494ed), C32e(0xd49898ff), C32e(0xe8b0b093), C32e(0x4a85855b), + C32e(0x6bbbbb06), C32e(0x2ac5c5bb), C32e(0xe54f4f7b), C32e(0x16ededd7), + C32e(0xc58686d2), C32e(0xd79a9af8), C32e(0x55666699), C32e(0x941111b6), + C32e(0xcf8a8ac0), C32e(0x10e9e9d9), C32e(0x0604040e), C32e(0x81fefe66), + C32e(0xf0a0a0ab), C32e(0x447878b4), C32e(0xba2525f0), C32e(0xe34b4b75), + C32e(0xf3a2a2ac), C32e(0xfe5d5d44), C32e(0xc08080db), C32e(0x8a050580), + C32e(0xad3f3fd3), C32e(0xbc2121fe), C32e(0x487070a8), C32e(0x04f1f1fd), + C32e(0xdf636319), C32e(0xc177772f), C32e(0x75afaf30), C32e(0x634242e7), + C32e(0x30202070), C32e(0x1ae5e5cb), C32e(0x0efdfdef), C32e(0x6dbfbf08), + C32e(0x4c818155), C32e(0x14181824), C32e(0x35262679), C32e(0x2fc3c3b2), + C32e(0xe1bebe86), C32e(0xa23535c8), C32e(0xcc8888c7), C32e(0x392e2e65), + C32e(0x5793936a), C32e(0xf2555558), C32e(0x82fcfc61), C32e(0x477a7ab3), + C32e(0xacc8c827), C32e(0xe7baba88), C32e(0x2b32324f), C32e(0x95e6e642), + C32e(0xa0c0c03b), C32e(0x981919aa), C32e(0xd19e9ef6), C32e(0x7fa3a322), + C32e(0x664444ee), C32e(0x7e5454d6), C32e(0xab3b3bdd), C32e(0x830b0b95), + C32e(0xca8c8cc9), C32e(0x29c7c7bc), C32e(0xd36b6b05), C32e(0x3c28286c), + C32e(0x79a7a72c), C32e(0xe2bcbc81), C32e(0x1d161631), C32e(0x76adad37), + C32e(0x3bdbdb96), C32e(0x5664649e), C32e(0x4e7474a6), C32e(0x1e141436), + C32e(0xdb9292e4), C32e(0x0a0c0c12), C32e(0x6c4848fc), C32e(0xe4b8b88f), + C32e(0x5d9f9f78), C32e(0x6ebdbd0f), C32e(0xef434369), C32e(0xa6c4c435), + C32e(0xa83939da), C32e(0xa43131c6), C32e(0x37d3d38a), C32e(0x8bf2f274), + C32e(0x32d5d583), C32e(0x438b8b4e), C32e(0x596e6e85), C32e(0xb7dada18), + C32e(0x8c01018e), C32e(0x64b1b11d), C32e(0xd29c9cf1), C32e(0xe0494972), + C32e(0xb4d8d81f), C32e(0xfaacacb9), C32e(0x07f3f3fa), C32e(0x25cfcfa0), + C32e(0xafcaca20), C32e(0x8ef4f47d), C32e(0xe9474767), C32e(0x18101038), + C32e(0xd56f6f0b), C32e(0x88f0f073), C32e(0x6f4a4afb), C32e(0x725c5cca), + C32e(0x24383854), C32e(0xf157575f), C32e(0xc7737321), C32e(0x51979764), + C32e(0x23cbcbae), C32e(0x7ca1a125), C32e(0x9ce8e857), C32e(0x213e3e5d), + C32e(0xdd9696ea), C32e(0xdc61611e), C32e(0x860d0d9c), C32e(0x850f0f9b), + C32e(0x90e0e04b), C32e(0x427c7cba), C32e(0xc4717126), C32e(0xaacccc29), + C32e(0xd89090e3), C32e(0x05060609), C32e(0x01f7f7f4), C32e(0x121c1c2a), + C32e(0xa3c2c23c), C32e(0x5f6a6a8b), C32e(0xf9aeaebe), C32e(0xd0696902), + C32e(0x911717bf), C32e(0x58999971), C32e(0x273a3a53), C32e(0xb92727f7), + C32e(0x38d9d991), C32e(0x13ebebde), C32e(0xb32b2be5), C32e(0x33222277), + C32e(0xbbd2d204), C32e(0x70a9a939), C32e(0x89070787), C32e(0xa73333c1), + C32e(0xb62d2dec), C32e(0x223c3c5a), C32e(0x921515b8), C32e(0x20c9c9a9), + C32e(0x4987875c), C32e(0xffaaaab0), C32e(0x785050d8), C32e(0x7aa5a52b), + C32e(0x8f030389), C32e(0xf859594a), C32e(0x80090992), C32e(0x171a1a23), + C32e(0xda656510), C32e(0x31d7d784), C32e(0xc68484d5), C32e(0xb8d0d003), + C32e(0xc38282dc), C32e(0xb02929e2), C32e(0x775a5ac3), C32e(0x111e1e2d), + C32e(0xcb7b7b3d), C32e(0xfca8a8b7), C32e(0xd66d6d0c), C32e(0x3a2c2c62) +}; + +static const sph_u32 T2dn[] = { + C32e(0xf4a5f497), C32e(0x978497eb), C32e(0xb099b0c7), C32e(0x8c8d8cf7), + C32e(0x170d17e5), C32e(0xdcbddcb7), C32e(0xc8b1c8a7), C32e(0xfc54fc39), + C32e(0xf050f0c0), C32e(0x05030504), C32e(0xe0a9e087), C32e(0x877d87ac), + C32e(0x2b192bd5), C32e(0xa662a671), C32e(0x31e6319a), C32e(0xb59ab5c3), + C32e(0xcf45cf05), C32e(0xbc9dbc3e), C32e(0xc040c009), C32e(0x928792ef), + C32e(0x3f153fc5), C32e(0x26eb267f), C32e(0x40c94007), C32e(0x1d0b1ded), + C32e(0x2fec2f82), C32e(0xa967a97d), C32e(0x1cfd1cbe), C32e(0x25ea258a), + C32e(0xdabfda46), C32e(0x02f702a6), C32e(0xa196a1d3), C32e(0xed5bed2d), + C32e(0x5dc25dea), C32e(0x241c24d9), C32e(0xe9aee97a), C32e(0xbe6abe98), + C32e(0xee5aeed8), C32e(0xc341c3fc), C32e(0x060206f1), C32e(0xd14fd11d), + C32e(0xe45ce4d0), C32e(0x07f407a2), C32e(0x5c345cb9), C32e(0x180818e9), + C32e(0xae93aedf), C32e(0x9573954d), C32e(0xf553f5c4), C32e(0x413f4154), + C32e(0x140c1410), C32e(0xf652f631), C32e(0xaf65af8c), C32e(0xe25ee221), + C32e(0x78287860), C32e(0xf8a1f86e), C32e(0x110f1114), C32e(0xc4b5c45e), + C32e(0x1b091b1c), C32e(0x5a365a48), C32e(0xb69bb636), C32e(0x473d47a5), + C32e(0x6a266a81), C32e(0xbb69bb9c), C32e(0x4ccd4cfe), C32e(0xba9fbacf), + C32e(0x2d1b2d24), C32e(0xb99eb93a), C32e(0x9c749cb0), C32e(0x722e7268), + C32e(0x772d776c), C32e(0xcdb2cda3), C32e(0x29ee2973), C32e(0x16fb16b6), + C32e(0x01f60153), C32e(0xd74dd7ec), C32e(0xa361a375), C32e(0x49ce49fa), + C32e(0x8d7b8da4), C32e(0x423e42a1), C32e(0x937193bc), C32e(0xa297a226), + C32e(0x04f50457), C32e(0xb868b869), C32e(0x00000000), C32e(0x742c7499), + C32e(0xa060a080), C32e(0x211f21dd), C32e(0x43c843f2), C32e(0x2ced2c77), + C32e(0xd9bed9b3), C32e(0xca46ca01), C32e(0x70d970ce), C32e(0xdd4bdde4), + C32e(0x79de7933), C32e(0x67d4672b), C32e(0x23e8237b), C32e(0xde4ade11), + C32e(0xbd6bbd6d), C32e(0x7e2a7e91), C32e(0x34e5349e), C32e(0x3a163ac1), + C32e(0x54c55417), C32e(0x62d7622f), C32e(0xff55ffcc), C32e(0xa794a722), + C32e(0x4acf4a0f), C32e(0x301030c9), C32e(0x0a060a08), C32e(0x988198e7), + C32e(0x0bf00b5b), C32e(0xcc44ccf0), C32e(0xd5bad54a), C32e(0x3ee33e96), + C32e(0x0ef30e5f), C32e(0x19fe19ba), C32e(0x5bc05b1b), C32e(0x858a850a), + C32e(0xecadec7e), C32e(0xdfbcdf42), C32e(0xd848d8e0), C32e(0x0c040cf9), + C32e(0x7adf7ac6), C32e(0x58c158ee), C32e(0x9f759f45), C32e(0xa563a584), + C32e(0x50305040), C32e(0x2e1a2ed1), C32e(0x120e12e1), C32e(0xb76db765), + C32e(0xd44cd419), C32e(0x3c143c30), C32e(0x5f355f4c), C32e(0x712f719d), + C32e(0x38e13867), C32e(0xfda2fd6a), C32e(0x4fcc4f0b), C32e(0x4b394b5c), + C32e(0xf957f93d), C32e(0x0df20daa), C32e(0x9d829de3), C32e(0xc947c9f4), + C32e(0xefacef8b), C32e(0x32e7326f), C32e(0x7d2b7d64), C32e(0xa495a4d7), + C32e(0xfba0fb9b), C32e(0xb398b332), C32e(0x68d16827), C32e(0x817f815d), + C32e(0xaa66aa88), C32e(0x827e82a8), C32e(0xe6abe676), C32e(0x9e839e16), + C32e(0x45ca4503), C32e(0x7b297b95), C32e(0x6ed36ed6), C32e(0x443c4450), + C32e(0x8b798b55), C32e(0x3de23d63), C32e(0x271d272c), C32e(0x9a769a41), + C32e(0x4d3b4dad), C32e(0xfa56fac8), C32e(0xd24ed2e8), C32e(0x221e2228), + C32e(0x76db763f), C32e(0x1e0a1e18), C32e(0xb46cb490), C32e(0x37e4376b), + C32e(0xe75de725), C32e(0xb26eb261), C32e(0x2aef2a86), C32e(0xf1a6f193), + C32e(0xe3a8e372), C32e(0xf7a4f762), C32e(0x593759bd), C32e(0x868b86ff), + C32e(0x563256b1), C32e(0xc543c50d), C32e(0xeb59ebdc), C32e(0xc2b7c2af), + C32e(0x8f8c8f02), C32e(0xac64ac79), C32e(0x6dd26d23), C32e(0x3be03b92), + C32e(0xc7b4c7ab), C32e(0x15fa1543), C32e(0x090709fd), C32e(0x6f256f85), + C32e(0xeaafea8f), C32e(0x898e89f3), C32e(0x20e9208e), C32e(0x28182820), + C32e(0x64d564de), C32e(0x838883fb), C32e(0xb16fb194), C32e(0x967296b8), + C32e(0x6c246c70), C32e(0x08f108ae), C32e(0x52c752e6), C32e(0xf351f335), + C32e(0x6523658d), C32e(0x847c8459), C32e(0xbf9cbfcb), C32e(0x6321637c), + C32e(0x7cdd7c37), C32e(0x7fdc7fc2), C32e(0x9186911a), C32e(0x9485941e), + C32e(0xab90abdb), C32e(0xc642c6f8), C32e(0x57c457e2), C32e(0xe5aae583), + C32e(0x73d8733b), C32e(0x0f050f0c), C32e(0x030103f5), C32e(0x36123638), + C32e(0xfea3fe9f), C32e(0xe15fe1d4), C32e(0x10f91047), C32e(0x6bd06bd2), + C32e(0xa891a82e), C32e(0xe858e829), C32e(0x69276974), C32e(0xd0b9d04e), + C32e(0x483848a9), C32e(0x351335cd), C32e(0xceb3ce56), C32e(0x55335544), + C32e(0xd6bbd6bf), C32e(0x90709049), C32e(0x8089800e), C32e(0xf2a7f266), + C32e(0xc1b6c15a), C32e(0x66226678), C32e(0xad92ad2a), C32e(0x60206089), + C32e(0xdb49db15), C32e(0x1aff1a4f), C32e(0x887888a0), C32e(0x8e7a8e51), + C32e(0x8a8f8a06), C32e(0x13f813b2), C32e(0x9b809b12), C32e(0x39173934), + C32e(0x75da75ca), C32e(0x533153b5), C32e(0x51c65113), C32e(0xd3b8d3bb), + C32e(0x5ec35e1f), C32e(0xcbb0cb52), C32e(0x997799b4), C32e(0x3311333c), + C32e(0x46cb46f6), C32e(0x1ffc1f4b), C32e(0x61d661da), C32e(0x4e3a4e58) +}; + +static const sph_u32 T3up[] = { + C32e(0x97a5c6c6), C32e(0xeb84f8f8), C32e(0xc799eeee), C32e(0xf78df6f6), + C32e(0xe50dffff), C32e(0xb7bdd6d6), C32e(0xa7b1dede), C32e(0x39549191), + C32e(0xc0506060), C32e(0x04030202), C32e(0x87a9cece), C32e(0xac7d5656), + C32e(0xd519e7e7), C32e(0x7162b5b5), C32e(0x9ae64d4d), C32e(0xc39aecec), + C32e(0x05458f8f), C32e(0x3e9d1f1f), C32e(0x09408989), C32e(0xef87fafa), + C32e(0xc515efef), C32e(0x7febb2b2), C32e(0x07c98e8e), C32e(0xed0bfbfb), + C32e(0x82ec4141), C32e(0x7d67b3b3), C32e(0xbefd5f5f), C32e(0x8aea4545), + C32e(0x46bf2323), C32e(0xa6f75353), C32e(0xd396e4e4), C32e(0x2d5b9b9b), + C32e(0xeac27575), C32e(0xd91ce1e1), C32e(0x7aae3d3d), C32e(0x986a4c4c), + C32e(0xd85a6c6c), C32e(0xfc417e7e), C32e(0xf102f5f5), C32e(0x1d4f8383), + C32e(0xd05c6868), C32e(0xa2f45151), C32e(0xb934d1d1), C32e(0xe908f9f9), + C32e(0xdf93e2e2), C32e(0x4d73abab), C32e(0xc4536262), C32e(0x543f2a2a), + C32e(0x100c0808), C32e(0x31529595), C32e(0x8c654646), C32e(0x215e9d9d), + C32e(0x60283030), C32e(0x6ea13737), C32e(0x140f0a0a), C32e(0x5eb52f2f), + C32e(0x1c090e0e), C32e(0x48362424), C32e(0x369b1b1b), C32e(0xa53ddfdf), + C32e(0x8126cdcd), C32e(0x9c694e4e), C32e(0xfecd7f7f), C32e(0xcf9feaea), + C32e(0x241b1212), C32e(0x3a9e1d1d), C32e(0xb0745858), C32e(0x682e3434), + C32e(0x6c2d3636), C32e(0xa3b2dcdc), C32e(0x73eeb4b4), C32e(0xb6fb5b5b), + C32e(0x53f6a4a4), C32e(0xec4d7676), C32e(0x7561b7b7), C32e(0xface7d7d), + C32e(0xa47b5252), C32e(0xa13edddd), C32e(0xbc715e5e), C32e(0x26971313), + C32e(0x57f5a6a6), C32e(0x6968b9b9), C32e(0x00000000), C32e(0x992cc1c1), + C32e(0x80604040), C32e(0xdd1fe3e3), C32e(0xf2c87979), C32e(0x77edb6b6), + C32e(0xb3bed4d4), C32e(0x01468d8d), C32e(0xced96767), C32e(0xe44b7272), + C32e(0x33de9494), C32e(0x2bd49898), C32e(0x7be8b0b0), C32e(0x114a8585), + C32e(0x6d6bbbbb), C32e(0x912ac5c5), C32e(0x9ee54f4f), C32e(0xc116eded), + C32e(0x17c58686), C32e(0x2fd79a9a), C32e(0xcc556666), C32e(0x22941111), + C32e(0x0fcf8a8a), C32e(0xc910e9e9), C32e(0x08060404), C32e(0xe781fefe), + C32e(0x5bf0a0a0), C32e(0xf0447878), C32e(0x4aba2525), C32e(0x96e34b4b), + C32e(0x5ff3a2a2), C32e(0xbafe5d5d), C32e(0x1bc08080), C32e(0x0a8a0505), + C32e(0x7ead3f3f), C32e(0x42bc2121), C32e(0xe0487070), C32e(0xf904f1f1), + C32e(0xc6df6363), C32e(0xeec17777), C32e(0x4575afaf), C32e(0x84634242), + C32e(0x40302020), C32e(0xd11ae5e5), C32e(0xe10efdfd), C32e(0x656dbfbf), + C32e(0x194c8181), C32e(0x30141818), C32e(0x4c352626), C32e(0x9d2fc3c3), + C32e(0x67e1bebe), C32e(0x6aa23535), C32e(0x0bcc8888), C32e(0x5c392e2e), + C32e(0x3d579393), C32e(0xaaf25555), C32e(0xe382fcfc), C32e(0xf4477a7a), + C32e(0x8bacc8c8), C32e(0x6fe7baba), C32e(0x642b3232), C32e(0xd795e6e6), + C32e(0x9ba0c0c0), C32e(0x32981919), C32e(0x27d19e9e), C32e(0x5d7fa3a3), + C32e(0x88664444), C32e(0xa87e5454), C32e(0x76ab3b3b), C32e(0x16830b0b), + C32e(0x03ca8c8c), C32e(0x9529c7c7), C32e(0xd6d36b6b), C32e(0x503c2828), + C32e(0x5579a7a7), C32e(0x63e2bcbc), C32e(0x2c1d1616), C32e(0x4176adad), + C32e(0xad3bdbdb), C32e(0xc8566464), C32e(0xe84e7474), C32e(0x281e1414), + C32e(0x3fdb9292), C32e(0x180a0c0c), C32e(0x906c4848), C32e(0x6be4b8b8), + C32e(0x255d9f9f), C32e(0x616ebdbd), C32e(0x86ef4343), C32e(0x93a6c4c4), + C32e(0x72a83939), C32e(0x62a43131), C32e(0xbd37d3d3), C32e(0xff8bf2f2), + C32e(0xb132d5d5), C32e(0x0d438b8b), C32e(0xdc596e6e), C32e(0xafb7dada), + C32e(0x028c0101), C32e(0x7964b1b1), C32e(0x23d29c9c), C32e(0x92e04949), + C32e(0xabb4d8d8), C32e(0x43faacac), C32e(0xfd07f3f3), C32e(0x8525cfcf), + C32e(0x8fafcaca), C32e(0xf38ef4f4), C32e(0x8ee94747), C32e(0x20181010), + C32e(0xded56f6f), C32e(0xfb88f0f0), C32e(0x946f4a4a), C32e(0xb8725c5c), + C32e(0x70243838), C32e(0xaef15757), C32e(0xe6c77373), C32e(0x35519797), + C32e(0x8d23cbcb), C32e(0x597ca1a1), C32e(0xcb9ce8e8), C32e(0x7c213e3e), + C32e(0x37dd9696), C32e(0xc2dc6161), C32e(0x1a860d0d), C32e(0x1e850f0f), + C32e(0xdb90e0e0), C32e(0xf8427c7c), C32e(0xe2c47171), C32e(0x83aacccc), + C32e(0x3bd89090), C32e(0x0c050606), C32e(0xf501f7f7), C32e(0x38121c1c), + C32e(0x9fa3c2c2), C32e(0xd45f6a6a), C32e(0x47f9aeae), C32e(0xd2d06969), + C32e(0x2e911717), C32e(0x29589999), C32e(0x74273a3a), C32e(0x4eb92727), + C32e(0xa938d9d9), C32e(0xcd13ebeb), C32e(0x56b32b2b), C32e(0x44332222), + C32e(0xbfbbd2d2), C32e(0x4970a9a9), C32e(0x0e890707), C32e(0x66a73333), + C32e(0x5ab62d2d), C32e(0x78223c3c), C32e(0x2a921515), C32e(0x8920c9c9), + C32e(0x15498787), C32e(0x4fffaaaa), C32e(0xa0785050), C32e(0x517aa5a5), + C32e(0x068f0303), C32e(0xb2f85959), C32e(0x12800909), C32e(0x34171a1a), + C32e(0xcada6565), C32e(0xb531d7d7), C32e(0x13c68484), C32e(0xbbb8d0d0), + C32e(0x1fc38282), C32e(0x52b02929), C32e(0xb4775a5a), C32e(0x3c111e1e), + C32e(0xf6cb7b7b), C32e(0x4bfca8a8), C32e(0xdad66d6d), C32e(0x583a2c2c) +}; + +static const sph_u32 T3dn[] = { + C32e(0x32f4a5f4), C32e(0x6f978497), C32e(0x5eb099b0), C32e(0x7a8c8d8c), + C32e(0xe8170d17), C32e(0x0adcbddc), C32e(0x16c8b1c8), C32e(0x6dfc54fc), + C32e(0x90f050f0), C32e(0x07050305), C32e(0x2ee0a9e0), C32e(0xd1877d87), + C32e(0xcc2b192b), C32e(0x13a662a6), C32e(0x7c31e631), C32e(0x59b59ab5), + C32e(0x40cf45cf), C32e(0xa3bc9dbc), C32e(0x49c040c0), C32e(0x68928792), + C32e(0xd03f153f), C32e(0x9426eb26), C32e(0xce40c940), C32e(0xe61d0b1d), + C32e(0x6e2fec2f), C32e(0x1aa967a9), C32e(0x431cfd1c), C32e(0x6025ea25), + C32e(0xf9dabfda), C32e(0x5102f702), C32e(0x45a196a1), C32e(0x76ed5bed), + C32e(0x285dc25d), C32e(0xc5241c24), C32e(0xd4e9aee9), C32e(0xf2be6abe), + C32e(0x82ee5aee), C32e(0xbdc341c3), C32e(0xf3060206), C32e(0x52d14fd1), + C32e(0x8ce45ce4), C32e(0x5607f407), C32e(0x8d5c345c), C32e(0xe1180818), + C32e(0x4cae93ae), C32e(0x3e957395), C32e(0x97f553f5), C32e(0x6b413f41), + C32e(0x1c140c14), C32e(0x63f652f6), C32e(0xe9af65af), C32e(0x7fe25ee2), + C32e(0x48782878), C32e(0xcff8a1f8), C32e(0x1b110f11), C32e(0xebc4b5c4), + C32e(0x151b091b), C32e(0x7e5a365a), C32e(0xadb69bb6), C32e(0x98473d47), + C32e(0xa76a266a), C32e(0xf5bb69bb), C32e(0x334ccd4c), C32e(0x50ba9fba), + C32e(0x3f2d1b2d), C32e(0xa4b99eb9), C32e(0xc49c749c), C32e(0x46722e72), + C32e(0x41772d77), C32e(0x11cdb2cd), C32e(0x9d29ee29), C32e(0x4d16fb16), + C32e(0xa501f601), C32e(0xa1d74dd7), C32e(0x14a361a3), C32e(0x3449ce49), + C32e(0xdf8d7b8d), C32e(0x9f423e42), C32e(0xcd937193), C32e(0xb1a297a2), + C32e(0xa204f504), C32e(0x01b868b8), C32e(0x00000000), C32e(0xb5742c74), + C32e(0xe0a060a0), C32e(0xc2211f21), C32e(0x3a43c843), C32e(0x9a2ced2c), + C32e(0x0dd9bed9), C32e(0x47ca46ca), C32e(0x1770d970), C32e(0xafdd4bdd), + C32e(0xed79de79), C32e(0xff67d467), C32e(0x9323e823), C32e(0x5bde4ade), + C32e(0x06bd6bbd), C32e(0xbb7e2a7e), C32e(0x7b34e534), C32e(0xd73a163a), + C32e(0xd254c554), C32e(0xf862d762), C32e(0x99ff55ff), C32e(0xb6a794a7), + C32e(0xc04acf4a), C32e(0xd9301030), C32e(0x0e0a060a), C32e(0x66988198), + C32e(0xab0bf00b), C32e(0xb4cc44cc), C32e(0xf0d5bad5), C32e(0x753ee33e), + C32e(0xac0ef30e), C32e(0x4419fe19), C32e(0xdb5bc05b), C32e(0x80858a85), + C32e(0xd3ecadec), C32e(0xfedfbcdf), C32e(0xa8d848d8), C32e(0xfd0c040c), + C32e(0x197adf7a), C32e(0x2f58c158), C32e(0x309f759f), C32e(0xe7a563a5), + C32e(0x70503050), C32e(0xcb2e1a2e), C32e(0xef120e12), C32e(0x08b76db7), + C32e(0x55d44cd4), C32e(0x243c143c), C32e(0x795f355f), C32e(0xb2712f71), + C32e(0x8638e138), C32e(0xc8fda2fd), C32e(0xc74fcc4f), C32e(0x654b394b), + C32e(0x6af957f9), C32e(0x580df20d), C32e(0x619d829d), C32e(0xb3c947c9), + C32e(0x27efacef), C32e(0x8832e732), C32e(0x4f7d2b7d), C32e(0x42a495a4), + C32e(0x3bfba0fb), C32e(0xaab398b3), C32e(0xf668d168), C32e(0x22817f81), + C32e(0xeeaa66aa), C32e(0xd6827e82), C32e(0xdde6abe6), C32e(0x959e839e), + C32e(0xc945ca45), C32e(0xbc7b297b), C32e(0x056ed36e), C32e(0x6c443c44), + C32e(0x2c8b798b), C32e(0x813de23d), C32e(0x31271d27), C32e(0x379a769a), + C32e(0x964d3b4d), C32e(0x9efa56fa), C32e(0xa6d24ed2), C32e(0x36221e22), + C32e(0xe476db76), C32e(0x121e0a1e), C32e(0xfcb46cb4), C32e(0x8f37e437), + C32e(0x78e75de7), C32e(0x0fb26eb2), C32e(0x692aef2a), C32e(0x35f1a6f1), + C32e(0xdae3a8e3), C32e(0xc6f7a4f7), C32e(0x8a593759), C32e(0x74868b86), + C32e(0x83563256), C32e(0x4ec543c5), C32e(0x85eb59eb), C32e(0x18c2b7c2), + C32e(0x8e8f8c8f), C32e(0x1dac64ac), C32e(0xf16dd26d), C32e(0x723be03b), + C32e(0x1fc7b4c7), C32e(0xb915fa15), C32e(0xfa090709), C32e(0xa06f256f), + C32e(0x20eaafea), C32e(0x7d898e89), C32e(0x6720e920), C32e(0x38281828), + C32e(0x0b64d564), C32e(0x73838883), C32e(0xfbb16fb1), C32e(0xca967296), + C32e(0x546c246c), C32e(0x5f08f108), C32e(0x2152c752), C32e(0x64f351f3), + C32e(0xae652365), C32e(0x25847c84), C32e(0x57bf9cbf), C32e(0x5d632163), + C32e(0xea7cdd7c), C32e(0x1e7fdc7f), C32e(0x9c918691), C32e(0x9b948594), + C32e(0x4bab90ab), C32e(0xbac642c6), C32e(0x2657c457), C32e(0x29e5aae5), + C32e(0xe373d873), C32e(0x090f050f), C32e(0xf4030103), C32e(0x2a361236), + C32e(0x3cfea3fe), C32e(0x8be15fe1), C32e(0xbe10f910), C32e(0x026bd06b), + C32e(0xbfa891a8), C32e(0x71e858e8), C32e(0x53692769), C32e(0xf7d0b9d0), + C32e(0x91483848), C32e(0xde351335), C32e(0xe5ceb3ce), C32e(0x77553355), + C32e(0x04d6bbd6), C32e(0x39907090), C32e(0x87808980), C32e(0xc1f2a7f2), + C32e(0xecc1b6c1), C32e(0x5a662266), C32e(0xb8ad92ad), C32e(0xa9602060), + C32e(0x5cdb49db), C32e(0xb01aff1a), C32e(0xd8887888), C32e(0x2b8e7a8e), + C32e(0x898a8f8a), C32e(0x4a13f813), C32e(0x929b809b), C32e(0x23391739), + C32e(0x1075da75), C32e(0x84533153), C32e(0xd551c651), C32e(0x03d3b8d3), + C32e(0xdc5ec35e), C32e(0xe2cbb0cb), C32e(0xc3997799), C32e(0x2d331133), + C32e(0x3d46cb46), C32e(0xb71ffc1f), C32e(0x0c61d661), C32e(0x624e3a4e) +}; + +#define DECL_STATE_SMALL \ + sph_u32 H[16]; + +#define READ_STATE_SMALL(sc) do { \ + memcpy(H, (sc)->state.narrow, sizeof H); \ + } while (0) + +#define WRITE_STATE_SMALL(sc) do { \ + memcpy((sc)->state.narrow, H, sizeof H); \ + } while (0) + +#define XCAT(x, y) XCAT_(x, y) +#define XCAT_(x, y) x ## y + +#define RSTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d0] = T0up[B32_0(a[b0])] \ + ^ T1up[B32_1(a[b1])] \ + ^ T2up[B32_2(a[b2])] \ + ^ T3up[B32_3(a[b3])] \ + ^ T0dn[B32_0(a[b4])] \ + ^ T1dn[B32_1(a[b5])] \ + ^ T2dn[B32_2(a[b6])] \ + ^ T3dn[B32_3(a[b7])]; \ + t[d1] = T0dn[B32_0(a[b0])] \ + ^ T1dn[B32_1(a[b1])] \ + ^ T2dn[B32_2(a[b2])] \ + ^ T3dn[B32_3(a[b3])] \ + ^ T0up[B32_0(a[b4])] \ + ^ T1up[B32_1(a[b5])] \ + ^ T2up[B32_2(a[b6])] \ + ^ T3up[B32_3(a[b7])]; \ + } while (0) + +#define ROUND_SMALL_P(a, r) do { \ + sph_u32 t[16]; \ + a[0x0] ^= PC32up(0x00, r); \ + a[0x1] ^= PC32dn(0x00, r); \ + a[0x2] ^= PC32up(0x10, r); \ + a[0x3] ^= PC32dn(0x10, r); \ + a[0x4] ^= PC32up(0x20, r); \ + a[0x5] ^= PC32dn(0x20, r); \ + a[0x6] ^= PC32up(0x30, r); \ + a[0x7] ^= PC32dn(0x30, r); \ + a[0x8] ^= PC32up(0x40, r); \ + a[0x9] ^= PC32dn(0x40, r); \ + a[0xA] ^= PC32up(0x50, r); \ + a[0xB] ^= PC32dn(0x50, r); \ + a[0xC] ^= PC32up(0x60, r); \ + a[0xD] ^= PC32dn(0x60, r); \ + a[0xE] ^= PC32up(0x70, r); \ + a[0xF] ^= PC32dn(0x70, r); \ + RSTT(0x0, 0x1, a, 0x0, 0x2, 0x4, 0x6, 0x9, 0xB, 0xD, 0xF); \ + RSTT(0x2, 0x3, a, 0x2, 0x4, 0x6, 0x8, 0xB, 0xD, 0xF, 0x1); \ + RSTT(0x4, 0x5, a, 0x4, 0x6, 0x8, 0xA, 0xD, 0xF, 0x1, 0x3); \ + RSTT(0x6, 0x7, a, 0x6, 0x8, 0xA, 0xC, 0xF, 0x1, 0x3, 0x5); \ + RSTT(0x8, 0x9, a, 0x8, 0xA, 0xC, 0xE, 0x1, 0x3, 0x5, 0x7); \ + RSTT(0xA, 0xB, a, 0xA, 0xC, 0xE, 0x0, 0x3, 0x5, 0x7, 0x9); \ + RSTT(0xC, 0xD, a, 0xC, 0xE, 0x0, 0x2, 0x5, 0x7, 0x9, 0xB); \ + RSTT(0xE, 0xF, a, 0xE, 0x0, 0x2, 0x4, 0x7, 0x9, 0xB, 0xD); \ + memcpy(a, t, sizeof t); \ + } while (0) + +#define ROUND_SMALL_Q(a, r) do { \ + sph_u32 t[16]; \ + a[0x0] ^= QC32up(0x00, r); \ + a[0x1] ^= QC32dn(0x00, r); \ + a[0x2] ^= QC32up(0x10, r); \ + a[0x3] ^= QC32dn(0x10, r); \ + a[0x4] ^= QC32up(0x20, r); \ + a[0x5] ^= QC32dn(0x20, r); \ + a[0x6] ^= QC32up(0x30, r); \ + a[0x7] ^= QC32dn(0x30, r); \ + a[0x8] ^= QC32up(0x40, r); \ + a[0x9] ^= QC32dn(0x40, r); \ + a[0xA] ^= QC32up(0x50, r); \ + a[0xB] ^= QC32dn(0x50, r); \ + a[0xC] ^= QC32up(0x60, r); \ + a[0xD] ^= QC32dn(0x60, r); \ + a[0xE] ^= QC32up(0x70, r); \ + a[0xF] ^= QC32dn(0x70, r); \ + RSTT(0x0, 0x1, a, 0x2, 0x6, 0xA, 0xE, 0x1, 0x5, 0x9, 0xD); \ + RSTT(0x2, 0x3, a, 0x4, 0x8, 0xC, 0x0, 0x3, 0x7, 0xB, 0xF); \ + RSTT(0x4, 0x5, a, 0x6, 0xA, 0xE, 0x2, 0x5, 0x9, 0xD, 0x1); \ + RSTT(0x6, 0x7, a, 0x8, 0xC, 0x0, 0x4, 0x7, 0xB, 0xF, 0x3); \ + RSTT(0x8, 0x9, a, 0xA, 0xE, 0x2, 0x6, 0x9, 0xD, 0x1, 0x5); \ + RSTT(0xA, 0xB, a, 0xC, 0x0, 0x4, 0x8, 0xB, 0xF, 0x3, 0x7); \ + RSTT(0xC, 0xD, a, 0xE, 0x2, 0x6, 0xA, 0xD, 0x1, 0x5, 0x9); \ + RSTT(0xE, 0xF, a, 0x0, 0x4, 0x8, 0xC, 0xF, 0x3, 0x7, 0xB); \ + memcpy(a, t, sizeof t); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_P(a, r); \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_Q(a, r); \ + } while (0) + +#else + +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_P(a, r + 0); \ + ROUND_SMALL_P(a, r + 1); \ + } \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_Q(a, r + 0); \ + ROUND_SMALL_Q(a, r + 1); \ + } \ + } while (0) + +#endif + +#define COMPRESS_SMALL do { \ + sph_u32 g[16], m[16]; \ + size_t u; \ + for (u = 0; u < 16; u ++) { \ + m[u] = dec32e_aligned(buf + (u << 2)); \ + g[u] = m[u] ^ H[u]; \ + } \ + PERM_SMALL_P(g); \ + PERM_SMALL_Q(m); \ + for (u = 0; u < 16; u ++) \ + H[u] ^= g[u] ^ m[u]; \ + } while (0) + +#define FINAL_SMALL do { \ + sph_u32 x[16]; \ + size_t u; \ + memcpy(x, H, sizeof x); \ + PERM_SMALL_P(x); \ + for (u = 0; u < 16; u ++) \ + H[u] ^= x[u]; \ + } while (0) + +#define DECL_STATE_BIG \ + sph_u32 H[32]; + +#define READ_STATE_BIG(sc) do { \ + memcpy(H, (sc)->state.narrow, sizeof H); \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + memcpy((sc)->state.narrow, H, sizeof H); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define RBTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + sph_u32 fu2 = T0up[B32_2(a[b2])]; \ + sph_u32 fd2 = T0dn[B32_2(a[b2])]; \ + sph_u32 fu3 = T1up[B32_3(a[b3])]; \ + sph_u32 fd3 = T1dn[B32_3(a[b3])]; \ + sph_u32 fu6 = T0up[B32_2(a[b6])]; \ + sph_u32 fd6 = T0dn[B32_2(a[b6])]; \ + sph_u32 fu7 = T1up[B32_3(a[b7])]; \ + sph_u32 fd7 = T1dn[B32_3(a[b7])]; \ + t[d0] = T0up[B32_0(a[b0])] \ + ^ T1up[B32_1(a[b1])] \ + ^ R32u(fu2, fd2) \ + ^ R32u(fu3, fd3) \ + ^ T0dn[B32_0(a[b4])] \ + ^ T1dn[B32_1(a[b5])] \ + ^ R32d(fu6, fd6) \ + ^ R32d(fu7, fd7); \ + t[d1] = T0dn[B32_0(a[b0])] \ + ^ T1dn[B32_1(a[b1])] \ + ^ R32d(fu2, fd2) \ + ^ R32d(fu3, fd3) \ + ^ T0up[B32_0(a[b4])] \ + ^ T1up[B32_1(a[b5])] \ + ^ R32u(fu6, fd6) \ + ^ R32u(fu7, fd7); \ + } while (0) + +#else + +#define RBTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d0] = T0up[B32_0(a[b0])] \ + ^ T1up[B32_1(a[b1])] \ + ^ T2up[B32_2(a[b2])] \ + ^ T3up[B32_3(a[b3])] \ + ^ T0dn[B32_0(a[b4])] \ + ^ T1dn[B32_1(a[b5])] \ + ^ T2dn[B32_2(a[b6])] \ + ^ T3dn[B32_3(a[b7])]; \ + t[d1] = T0dn[B32_0(a[b0])] \ + ^ T1dn[B32_1(a[b1])] \ + ^ T2dn[B32_2(a[b2])] \ + ^ T3dn[B32_3(a[b3])] \ + ^ T0up[B32_0(a[b4])] \ + ^ T1up[B32_1(a[b5])] \ + ^ T2up[B32_2(a[b6])] \ + ^ T3up[B32_3(a[b7])]; \ + } while (0) + +#endif + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define ROUND_BIG_P(a, r) do { \ + sph_u32 t[32]; \ + size_t u; \ + a[0x00] ^= PC32up(0x00, r); \ + a[0x01] ^= PC32dn(0x00, r); \ + a[0x02] ^= PC32up(0x10, r); \ + a[0x03] ^= PC32dn(0x10, r); \ + a[0x04] ^= PC32up(0x20, r); \ + a[0x05] ^= PC32dn(0x20, r); \ + a[0x06] ^= PC32up(0x30, r); \ + a[0x07] ^= PC32dn(0x30, r); \ + a[0x08] ^= PC32up(0x40, r); \ + a[0x09] ^= PC32dn(0x40, r); \ + a[0x0A] ^= PC32up(0x50, r); \ + a[0x0B] ^= PC32dn(0x50, r); \ + a[0x0C] ^= PC32up(0x60, r); \ + a[0x0D] ^= PC32dn(0x60, r); \ + a[0x0E] ^= PC32up(0x70, r); \ + a[0x0F] ^= PC32dn(0x70, r); \ + a[0x10] ^= PC32up(0x80, r); \ + a[0x11] ^= PC32dn(0x80, r); \ + a[0x12] ^= PC32up(0x90, r); \ + a[0x13] ^= PC32dn(0x90, r); \ + a[0x14] ^= PC32up(0xA0, r); \ + a[0x15] ^= PC32dn(0xA0, r); \ + a[0x16] ^= PC32up(0xB0, r); \ + a[0x17] ^= PC32dn(0xB0, r); \ + a[0x18] ^= PC32up(0xC0, r); \ + a[0x19] ^= PC32dn(0xC0, r); \ + a[0x1A] ^= PC32up(0xD0, r); \ + a[0x1B] ^= PC32dn(0xD0, r); \ + a[0x1C] ^= PC32up(0xE0, r); \ + a[0x1D] ^= PC32dn(0xE0, r); \ + a[0x1E] ^= PC32up(0xF0, r); \ + a[0x1F] ^= PC32dn(0xF0, r); \ + for (u = 0; u < 32; u += 8) { \ + RBTT(u + 0x00, (u + 0x01) & 0x1F, a, \ + u + 0x00, (u + 0x02) & 0x1F, \ + (u + 0x04) & 0x1F, (u + 0x06) & 0x1F, \ + (u + 0x09) & 0x1F, (u + 0x0B) & 0x1F, \ + (u + 0x0D) & 0x1F, (u + 0x17) & 0x1F); \ + RBTT(u + 0x02, (u + 0x03) & 0x1F, a, \ + u + 0x02, (u + 0x04) & 0x1F, \ + (u + 0x06) & 0x1F, (u + 0x08) & 0x1F, \ + (u + 0x0B) & 0x1F, (u + 0x0D) & 0x1F, \ + (u + 0x0F) & 0x1F, (u + 0x19) & 0x1F); \ + RBTT(u + 0x04, (u + 0x05) & 0x1F, a, \ + u + 0x04, (u + 0x06) & 0x1F, \ + (u + 0x08) & 0x1F, (u + 0x0A) & 0x1F, \ + (u + 0x0D) & 0x1F, (u + 0x0F) & 0x1F, \ + (u + 0x11) & 0x1F, (u + 0x1B) & 0x1F); \ + RBTT(u + 0x06, (u + 0x07) & 0x1F, a, \ + u + 0x06, (u + 0x08) & 0x1F, \ + (u + 0x0A) & 0x1F, (u + 0x0C) & 0x1F, \ + (u + 0x0F) & 0x1F, (u + 0x11) & 0x1F, \ + (u + 0x13) & 0x1F, (u + 0x1D) & 0x1F); \ + } \ + memcpy(a, t, sizeof t); \ + } while (0) + +#define ROUND_BIG_Q(a, r) do { \ + sph_u32 t[32]; \ + size_t u; \ + a[0x00] ^= QC32up(0x00, r); \ + a[0x01] ^= QC32dn(0x00, r); \ + a[0x02] ^= QC32up(0x10, r); \ + a[0x03] ^= QC32dn(0x10, r); \ + a[0x04] ^= QC32up(0x20, r); \ + a[0x05] ^= QC32dn(0x20, r); \ + a[0x06] ^= QC32up(0x30, r); \ + a[0x07] ^= QC32dn(0x30, r); \ + a[0x08] ^= QC32up(0x40, r); \ + a[0x09] ^= QC32dn(0x40, r); \ + a[0x0A] ^= QC32up(0x50, r); \ + a[0x0B] ^= QC32dn(0x50, r); \ + a[0x0C] ^= QC32up(0x60, r); \ + a[0x0D] ^= QC32dn(0x60, r); \ + a[0x0E] ^= QC32up(0x70, r); \ + a[0x0F] ^= QC32dn(0x70, r); \ + a[0x10] ^= QC32up(0x80, r); \ + a[0x11] ^= QC32dn(0x80, r); \ + a[0x12] ^= QC32up(0x90, r); \ + a[0x13] ^= QC32dn(0x90, r); \ + a[0x14] ^= QC32up(0xA0, r); \ + a[0x15] ^= QC32dn(0xA0, r); \ + a[0x16] ^= QC32up(0xB0, r); \ + a[0x17] ^= QC32dn(0xB0, r); \ + a[0x18] ^= QC32up(0xC0, r); \ + a[0x19] ^= QC32dn(0xC0, r); \ + a[0x1A] ^= QC32up(0xD0, r); \ + a[0x1B] ^= QC32dn(0xD0, r); \ + a[0x1C] ^= QC32up(0xE0, r); \ + a[0x1D] ^= QC32dn(0xE0, r); \ + a[0x1E] ^= QC32up(0xF0, r); \ + a[0x1F] ^= QC32dn(0xF0, r); \ + for (u = 0; u < 32; u += 8) { \ + RBTT(u + 0x00, (u + 0x01) & 0x1F, a, \ + (u + 0x02) & 0x1F, (u + 0x06) & 0x1F, \ + (u + 0x0A) & 0x1F, (u + 0x16) & 0x1F, \ + (u + 0x01) & 0x1F, (u + 0x05) & 0x1F, \ + (u + 0x09) & 0x1F, (u + 0x0D) & 0x1F); \ + RBTT(u + 0x02, (u + 0x03) & 0x1F, a, \ + (u + 0x04) & 0x1F, (u + 0x08) & 0x1F, \ + (u + 0x0C) & 0x1F, (u + 0x18) & 0x1F, \ + (u + 0x03) & 0x1F, (u + 0x07) & 0x1F, \ + (u + 0x0B) & 0x1F, (u + 0x0F) & 0x1F); \ + RBTT(u + 0x04, (u + 0x05) & 0x1F, a, \ + (u + 0x06) & 0x1F, (u + 0x0A) & 0x1F, \ + (u + 0x0E) & 0x1F, (u + 0x1A) & 0x1F, \ + (u + 0x05) & 0x1F, (u + 0x09) & 0x1F, \ + (u + 0x0D) & 0x1F, (u + 0x11) & 0x1F); \ + RBTT(u + 0x06, (u + 0x07) & 0x1F, a, \ + (u + 0x08) & 0x1F, (u + 0x0C) & 0x1F, \ + (u + 0x10) & 0x1F, (u + 0x1C) & 0x1F, \ + (u + 0x07) & 0x1F, (u + 0x0B) & 0x1F, \ + (u + 0x0F) & 0x1F, (u + 0x13) & 0x1F); \ + } \ + memcpy(a, t, sizeof t); \ + } while (0) + +#else + +#define ROUND_BIG_P(a, r) do { \ + sph_u32 t[32]; \ + a[0x00] ^= PC32up(0x00, r); \ + a[0x01] ^= PC32dn(0x00, r); \ + a[0x02] ^= PC32up(0x10, r); \ + a[0x03] ^= PC32dn(0x10, r); \ + a[0x04] ^= PC32up(0x20, r); \ + a[0x05] ^= PC32dn(0x20, r); \ + a[0x06] ^= PC32up(0x30, r); \ + a[0x07] ^= PC32dn(0x30, r); \ + a[0x08] ^= PC32up(0x40, r); \ + a[0x09] ^= PC32dn(0x40, r); \ + a[0x0A] ^= PC32up(0x50, r); \ + a[0x0B] ^= PC32dn(0x50, r); \ + a[0x0C] ^= PC32up(0x60, r); \ + a[0x0D] ^= PC32dn(0x60, r); \ + a[0x0E] ^= PC32up(0x70, r); \ + a[0x0F] ^= PC32dn(0x70, r); \ + a[0x10] ^= PC32up(0x80, r); \ + a[0x11] ^= PC32dn(0x80, r); \ + a[0x12] ^= PC32up(0x90, r); \ + a[0x13] ^= PC32dn(0x90, r); \ + a[0x14] ^= PC32up(0xA0, r); \ + a[0x15] ^= PC32dn(0xA0, r); \ + a[0x16] ^= PC32up(0xB0, r); \ + a[0x17] ^= PC32dn(0xB0, r); \ + a[0x18] ^= PC32up(0xC0, r); \ + a[0x19] ^= PC32dn(0xC0, r); \ + a[0x1A] ^= PC32up(0xD0, r); \ + a[0x1B] ^= PC32dn(0xD0, r); \ + a[0x1C] ^= PC32up(0xE0, r); \ + a[0x1D] ^= PC32dn(0xE0, r); \ + a[0x1E] ^= PC32up(0xF0, r); \ + a[0x1F] ^= PC32dn(0xF0, r); \ + RBTT(0x00, 0x01, a, \ + 0x00, 0x02, 0x04, 0x06, 0x09, 0x0B, 0x0D, 0x17); \ + RBTT(0x02, 0x03, a, \ + 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x0F, 0x19); \ + RBTT(0x04, 0x05, a, \ + 0x04, 0x06, 0x08, 0x0A, 0x0D, 0x0F, 0x11, 0x1B); \ + RBTT(0x06, 0x07, a, \ + 0x06, 0x08, 0x0A, 0x0C, 0x0F, 0x11, 0x13, 0x1D); \ + RBTT(0x08, 0x09, a, \ + 0x08, 0x0A, 0x0C, 0x0E, 0x11, 0x13, 0x15, 0x1F); \ + RBTT(0x0A, 0x0B, a, \ + 0x0A, 0x0C, 0x0E, 0x10, 0x13, 0x15, 0x17, 0x01); \ + RBTT(0x0C, 0x0D, a, \ + 0x0C, 0x0E, 0x10, 0x12, 0x15, 0x17, 0x19, 0x03); \ + RBTT(0x0E, 0x0F, a, \ + 0x0E, 0x10, 0x12, 0x14, 0x17, 0x19, 0x1B, 0x05); \ + RBTT(0x10, 0x11, a, \ + 0x10, 0x12, 0x14, 0x16, 0x19, 0x1B, 0x1D, 0x07); \ + RBTT(0x12, 0x13, a, \ + 0x12, 0x14, 0x16, 0x18, 0x1B, 0x1D, 0x1F, 0x09); \ + RBTT(0x14, 0x15, a, \ + 0x14, 0x16, 0x18, 0x1A, 0x1D, 0x1F, 0x01, 0x0B); \ + RBTT(0x16, 0x17, a, \ + 0x16, 0x18, 0x1A, 0x1C, 0x1F, 0x01, 0x03, 0x0D); \ + RBTT(0x18, 0x19, a, \ + 0x18, 0x1A, 0x1C, 0x1E, 0x01, 0x03, 0x05, 0x0F); \ + RBTT(0x1A, 0x1B, a, \ + 0x1A, 0x1C, 0x1E, 0x00, 0x03, 0x05, 0x07, 0x11); \ + RBTT(0x1C, 0x1D, a, \ + 0x1C, 0x1E, 0x00, 0x02, 0x05, 0x07, 0x09, 0x13); \ + RBTT(0x1E, 0x1F, a, \ + 0x1E, 0x00, 0x02, 0x04, 0x07, 0x09, 0x0B, 0x15); \ + memcpy(a, t, sizeof t); \ + } while (0) + +#define ROUND_BIG_Q(a, r) do { \ + sph_u32 t[32]; \ + a[0x00] ^= QC32up(0x00, r); \ + a[0x01] ^= QC32dn(0x00, r); \ + a[0x02] ^= QC32up(0x10, r); \ + a[0x03] ^= QC32dn(0x10, r); \ + a[0x04] ^= QC32up(0x20, r); \ + a[0x05] ^= QC32dn(0x20, r); \ + a[0x06] ^= QC32up(0x30, r); \ + a[0x07] ^= QC32dn(0x30, r); \ + a[0x08] ^= QC32up(0x40, r); \ + a[0x09] ^= QC32dn(0x40, r); \ + a[0x0A] ^= QC32up(0x50, r); \ + a[0x0B] ^= QC32dn(0x50, r); \ + a[0x0C] ^= QC32up(0x60, r); \ + a[0x0D] ^= QC32dn(0x60, r); \ + a[0x0E] ^= QC32up(0x70, r); \ + a[0x0F] ^= QC32dn(0x70, r); \ + a[0x10] ^= QC32up(0x80, r); \ + a[0x11] ^= QC32dn(0x80, r); \ + a[0x12] ^= QC32up(0x90, r); \ + a[0x13] ^= QC32dn(0x90, r); \ + a[0x14] ^= QC32up(0xA0, r); \ + a[0x15] ^= QC32dn(0xA0, r); \ + a[0x16] ^= QC32up(0xB0, r); \ + a[0x17] ^= QC32dn(0xB0, r); \ + a[0x18] ^= QC32up(0xC0, r); \ + a[0x19] ^= QC32dn(0xC0, r); \ + a[0x1A] ^= QC32up(0xD0, r); \ + a[0x1B] ^= QC32dn(0xD0, r); \ + a[0x1C] ^= QC32up(0xE0, r); \ + a[0x1D] ^= QC32dn(0xE0, r); \ + a[0x1E] ^= QC32up(0xF0, r); \ + a[0x1F] ^= QC32dn(0xF0, r); \ + RBTT(0x00, 0x01, a, \ + 0x02, 0x06, 0x0A, 0x16, 0x01, 0x05, 0x09, 0x0D); \ + RBTT(0x02, 0x03, a, \ + 0x04, 0x08, 0x0C, 0x18, 0x03, 0x07, 0x0B, 0x0F); \ + RBTT(0x04, 0x05, a, \ + 0x06, 0x0A, 0x0E, 0x1A, 0x05, 0x09, 0x0D, 0x11); \ + RBTT(0x06, 0x07, a, \ + 0x08, 0x0C, 0x10, 0x1C, 0x07, 0x0B, 0x0F, 0x13); \ + RBTT(0x08, 0x09, a, \ + 0x0A, 0x0E, 0x12, 0x1E, 0x09, 0x0D, 0x11, 0x15); \ + RBTT(0x0A, 0x0B, a, \ + 0x0C, 0x10, 0x14, 0x00, 0x0B, 0x0F, 0x13, 0x17); \ + RBTT(0x0C, 0x0D, a, \ + 0x0E, 0x12, 0x16, 0x02, 0x0D, 0x11, 0x15, 0x19); \ + RBTT(0x0E, 0x0F, a, \ + 0x10, 0x14, 0x18, 0x04, 0x0F, 0x13, 0x17, 0x1B); \ + RBTT(0x10, 0x11, a, \ + 0x12, 0x16, 0x1A, 0x06, 0x11, 0x15, 0x19, 0x1D); \ + RBTT(0x12, 0x13, a, \ + 0x14, 0x18, 0x1C, 0x08, 0x13, 0x17, 0x1B, 0x1F); \ + RBTT(0x14, 0x15, a, \ + 0x16, 0x1A, 0x1E, 0x0A, 0x15, 0x19, 0x1D, 0x01); \ + RBTT(0x16, 0x17, a, \ + 0x18, 0x1C, 0x00, 0x0C, 0x17, 0x1B, 0x1F, 0x03); \ + RBTT(0x18, 0x19, a, \ + 0x1A, 0x1E, 0x02, 0x0E, 0x19, 0x1D, 0x01, 0x05); \ + RBTT(0x1A, 0x1B, a, \ + 0x1C, 0x00, 0x04, 0x10, 0x1B, 0x1F, 0x03, 0x07); \ + RBTT(0x1C, 0x1D, a, \ + 0x1E, 0x02, 0x06, 0x12, 0x1D, 0x01, 0x05, 0x09); \ + RBTT(0x1E, 0x1F, a, \ + 0x00, 0x04, 0x08, 0x14, 0x1F, 0x03, 0x07, 0x0B); \ + memcpy(a, t, sizeof t); \ + } while (0) + +#endif + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define PERM_BIG_P(a) do { \ + int r; \ + for (r = 0; r < 14; r ++) \ + ROUND_BIG_P(a, r); \ + } while (0) + +#define PERM_BIG_Q(a) do { \ + int r; \ + for (r = 0; r < 14; r ++) \ + ROUND_BIG_Q(a, r); \ + } while (0) + +#else + +#define PERM_BIG_P(a) do { \ + int r; \ + for (r = 0; r < 14; r += 2) { \ + ROUND_BIG_P(a, r + 0); \ + ROUND_BIG_P(a, r + 1); \ + } \ + } while (0) + +#define PERM_BIG_Q(a) do { \ + int r; \ + for (r = 0; r < 14; r += 2) { \ + ROUND_BIG_Q(a, r + 0); \ + ROUND_BIG_Q(a, r + 1); \ + } \ + } while (0) + +#endif + +#define COMPRESS_BIG do { \ + sph_u32 g[32], m[32]; \ + size_t u; \ + for (u = 0; u < 32; u ++) { \ + m[u] = dec32e_aligned(buf + (u << 2)); \ + g[u] = m[u] ^ H[u]; \ + } \ + PERM_BIG_P(g); \ + PERM_BIG_Q(m); \ + for (u = 0; u < 32; u ++) \ + H[u] ^= g[u] ^ m[u]; \ + } while (0) + +#define FINAL_BIG do { \ + sph_u32 x[32]; \ + size_t u; \ + memcpy(x, H, sizeof x); \ + PERM_BIG_P(x); \ + for (u = 0; u < 32; u ++) \ + H[u] ^= x[u]; \ + } while (0) + +#endif + +static void +groestl_small_init(sph_groestl_small_context *sc, unsigned out_size) +{ + size_t u; + + sc->ptr = 0; +#if SPH_GROESTL_64 + for (u = 0; u < 7; u ++) + sc->state.wide[u] = 0; +#if USE_LE + sc->state.wide[7] = ((sph_u64)(out_size & 0xFF) << 56) + | ((sph_u64)(out_size & 0xFF00) << 40); +#else + sc->state.wide[7] = (sph_u64)out_size; +#endif +#else + for (u = 0; u < 15; u ++) + sc->state.narrow[u] = 0; +#if USE_LE + sc->state.narrow[15] = ((sph_u32)(out_size & 0xFF) << 24) + | ((sph_u32)(out_size & 0xFF00) << 8); +#else + sc->state.narrow[15] = (sph_u32)out_size; +#endif +#endif +#if SPH_64 + sc->count = 0; +#else + sc->count_high = 0; + sc->count_low = 0; +#endif +} + +static void +groestl_small_core(sph_groestl_small_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE_SMALL + + 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_SMALL(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) { + COMPRESS_SMALL; +#if SPH_64 + sc->count ++; +#else + if ((sc->count_low = SPH_T32(sc->count_low + 1)) == 0) + sc->count_high = SPH_T32(sc->count_high + 1); +#endif + ptr = 0; + } + } + WRITE_STATE_SMALL(sc); + sc->ptr = ptr; +} + +static void +groestl_small_close(sph_groestl_small_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_len) +{ + unsigned char *buf; + unsigned char pad[72]; + size_t u, ptr, pad_len; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif + unsigned z; + DECL_STATE_SMALL + + buf = sc->buf; + ptr = sc->ptr; + z = 0x80 >> n; + pad[0] = ((ub & -z) | z) & 0xFF; + if (ptr < 56) { + pad_len = 64 - ptr; +#if SPH_64 + count = SPH_T64(sc->count + 1); +#else + count_low = SPH_T32(sc->count_low + 1); + count_high = SPH_T32(sc->count_high); + if (count_low == 0) + count_high = SPH_T32(count_high + 1); +#endif + } else { + pad_len = 128 - ptr; +#if SPH_64 + count = SPH_T64(sc->count + 2); +#else + count_low = SPH_T32(sc->count_low + 2); + count_high = SPH_T32(sc->count_high); + if (count_low <= 1) + count_high = SPH_T32(count_high + 1); +#endif + } + memset(pad + 1, 0, pad_len - 9); +#if SPH_64 + sph_enc64be(pad + pad_len - 8, count); +#else + sph_enc64be(pad + pad_len - 8, count_high); + sph_enc64be(pad + pad_len - 4, count_low); +#endif + groestl_small_core(sc, pad, pad_len); + READ_STATE_SMALL(sc); + FINAL_SMALL; +#if SPH_GROESTL_64 + for (u = 0; u < 4; u ++) + enc64e(pad + (u << 3), H[u + 4]); +#else + for (u = 0; u < 8; u ++) + enc32e(pad + (u << 2), H[u + 8]); +#endif + memcpy(dst, pad + 32 - out_len, out_len); + groestl_small_init(sc, (unsigned)out_len << 3); +} + +static void +groestl_big_init(sph_groestl_big_context *sc, unsigned out_size) +{ + size_t u; + + sc->ptr = 0; +#if SPH_GROESTL_64 + for (u = 0; u < 15; u ++) + sc->state.wide[u] = 0; +#if USE_LE + sc->state.wide[15] = ((sph_u64)(out_size & 0xFF) << 56) + | ((sph_u64)(out_size & 0xFF00) << 40); +#else + sc->state.wide[15] = (sph_u64)out_size; +#endif +#else + for (u = 0; u < 31; u ++) + sc->state.narrow[u] = 0; +#if USE_LE + sc->state.narrow[31] = ((sph_u32)(out_size & 0xFF) << 24) + | ((sph_u32)(out_size & 0xFF00) << 8); +#else + sc->state.narrow[31] = (sph_u32)out_size; +#endif +#endif +#if SPH_64 + sc->count = 0; +#else + sc->count_high = 0; + sc->count_low = 0; +#endif +} + +static void +groestl_big_core(sph_groestl_big_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE_BIG + + 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_BIG(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) { + COMPRESS_BIG; +#if SPH_64 + sc->count ++; +#else + if ((sc->count_low = SPH_T32(sc->count_low + 1)) == 0) + sc->count_high = SPH_T32(sc->count_high + 1); +#endif + ptr = 0; + } + } + WRITE_STATE_BIG(sc); + sc->ptr = ptr; +} + +static void +groestl_big_close(sph_groestl_big_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_len) +{ + unsigned char *buf; + unsigned char pad[136]; + size_t ptr, pad_len, u; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif + unsigned z; + DECL_STATE_BIG + + buf = sc->buf; + ptr = sc->ptr; + z = 0x80 >> n; + pad[0] = ((ub & -z) | z) & 0xFF; + if (ptr < 120) { + pad_len = 128 - ptr; +#if SPH_64 + count = SPH_T64(sc->count + 1); +#else + count_low = SPH_T32(sc->count_low + 1); + count_high = SPH_T32(sc->count_high); + if (count_low == 0) + count_high = SPH_T32(count_high + 1); +#endif + } else { + pad_len = 256 - ptr; +#if SPH_64 + count = SPH_T64(sc->count + 2); +#else + count_low = SPH_T32(sc->count_low + 2); + count_high = SPH_T32(sc->count_high); + if (count_low <= 1) + count_high = SPH_T32(count_high + 1); +#endif + } + memset(pad + 1, 0, pad_len - 9); +#if SPH_64 + sph_enc64be(pad + pad_len - 8, count); +#else + sph_enc64be(pad + pad_len - 8, count_high); + sph_enc64be(pad + pad_len - 4, count_low); +#endif + groestl_big_core(sc, pad, pad_len); + READ_STATE_BIG(sc); + FINAL_BIG; +#if SPH_GROESTL_64 + for (u = 0; u < 8; u ++) + enc64e(pad + (u << 3), H[u + 8]); +#else + for (u = 0; u < 16; u ++) + enc32e(pad + (u << 2), H[u + 16]); +#endif + memcpy(dst, pad + 64 - out_len, out_len); + groestl_big_init(sc, (unsigned)out_len << 3); +} + +/* see sph_groestl.h */ +void +sph_groestl224_init(void *cc) +{ + groestl_small_init(cc, 224); +} + +/* see sph_groestl.h */ +void +sph_groestl224(void *cc, const void *data, size_t len) +{ + groestl_small_core(cc, data, len); +} + +/* see sph_groestl.h */ +void +sph_groestl224_close(void *cc, void *dst) +{ + groestl_small_close(cc, 0, 0, dst, 28); +} + +/* see sph_groestl.h */ +void +sph_groestl224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + groestl_small_close(cc, ub, n, dst, 28); +} + +/* see sph_groestl.h */ +void +sph_groestl256_init(void *cc) +{ + groestl_small_init(cc, 256); +} + +/* see sph_groestl.h */ +void +sph_groestl256(void *cc, const void *data, size_t len) +{ + groestl_small_core(cc, data, len); +} + +/* see sph_groestl.h */ +void +sph_groestl256_close(void *cc, void *dst) +{ + groestl_small_close(cc, 0, 0, dst, 32); +} + +/* see sph_groestl.h */ +void +sph_groestl256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + groestl_small_close(cc, ub, n, dst, 32); +} + +/* see sph_groestl.h */ +void +sph_groestl384_init(void *cc) +{ + groestl_big_init(cc, 384); +} + +/* see sph_groestl.h */ +void +sph_groestl384(void *cc, const void *data, size_t len) +{ + groestl_big_core(cc, data, len); +} + +/* see sph_groestl.h */ +void +sph_groestl384_close(void *cc, void *dst) +{ + groestl_big_close(cc, 0, 0, dst, 48); +} + +/* see sph_groestl.h */ +void +sph_groestl384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + groestl_big_close(cc, ub, n, dst, 48); +} + +/* see sph_groestl.h */ +void +sph_groestl512_init(void *cc) +{ + groestl_big_init(cc, 512); +} + +/* see sph_groestl.h */ +void +sph_groestl512(void *cc, const void *data, size_t len) +{ + groestl_big_core(cc, data, len); +} + +/* see sph_groestl.h */ +void +sph_groestl512_close(void *cc, void *dst) +{ + groestl_big_close(cc, 0, 0, dst, 64); +} + +/* see sph_groestl.h */ +void +sph_groestl512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + groestl_big_close(cc, ub, n, dst, 64); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/hamsi.c b/src/hamsi.c new file mode 100644 index 0000000..8e87ab4 --- /dev/null +++ b/src/hamsi.c @@ -0,0 +1,867 @@ +/* $Id: hamsi.c 251 2010-10-19 14:31:51Z tp $ */ +/* + * Hamsi 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 + */ + +#include +#include + +#include "sph_hamsi.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_HAMSI +#define SPH_SMALL_FOOTPRINT_HAMSI 1 +#endif + +/* + * The SPH_HAMSI_EXPAND_* define how many input bits we handle in one + * table lookup during message expansion (1 to 8, inclusive). If we note + * w the number of bits per message word (w=32 for Hamsi-224/256, w=64 + * for Hamsi-384/512), r the size of a "row" in 32-bit words (r=8 for + * Hamsi-224/256, r=16 for Hamsi-384/512), and n the expansion level, + * then we will get t tables (where t=ceil(w/n)) of individual size + * 2^n*r*4 (in bytes). The last table may be shorter (e.g. with w=32 and + * n=5, there are 7 tables, but the last one uses only two bits on + * input, not five). + * + * Also, we read t rows of r words from RAM. Words in a given row are + * concatenated in RAM in that order, so most of the cost is about + * reading the first row word; comparatively, cache misses are thus + * less expensive with Hamsi-512 (r=16) than with Hamsi-256 (r=8). + * + * When n=1, tables are "special" in that we omit the first entry of + * each table (which always contains 0), so that total table size is + * halved. + * + * We thus have the following (size1 is the cumulative table size of + * Hamsi-224/256; size2 is for Hamsi-384/512; similarly, t1 and t2 + * are for Hamsi-224/256 and Hamsi-384/512, respectively). + * + * n size1 size2 t1 t2 + * --------------------------------------- + * 1 1024 4096 32 64 + * 2 2048 8192 16 32 + * 3 2688 10880 11 22 + * 4 4096 16384 8 16 + * 5 6272 25600 7 13 + * 6 10368 41984 6 11 + * 7 16896 73856 5 10 + * 8 32768 131072 4 8 + * + * So there is a trade-off: a lower n makes the tables fit better in + * L1 cache, but increases the number of memory accesses. The optimal + * value depends on the amount of available L1 cache and the relative + * impact of a cache miss. + * + * Experimentally, in ideal benchmark conditions (which are not necessarily + * realistic with regards to L1 cache contention), it seems that n=8 is + * the best value on "big" architectures (those with 32 kB or more of L1 + * cache), while n=4 is better on "small" architectures. This was tested + * on an Intel Core2 Q6600 (both 32-bit and 64-bit mode), a PowerPC G3 + * (32 kB L1 cache, hence "big"), and a MIPS-compatible Broadcom BCM3302 + * (8 kB L1 cache). + * + * Note: with n=1, the 32 tables (actually implemented as one big table) + * are read entirely and sequentially, regardless of the input data, + * thus avoiding any data-dependent table access pattern. + */ + +#if !defined SPH_HAMSI_EXPAND_SMALL +#if SPH_SMALL_FOOTPRINT_HAMSI +#define SPH_HAMSI_EXPAND_SMALL 4 +#else +#define SPH_HAMSI_EXPAND_SMALL 8 +#endif +#endif + +#if !defined SPH_HAMSI_EXPAND_BIG +#define SPH_HAMSI_EXPAND_BIG 8 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +#include "hamsi_helper.c" + +static const sph_u32 IV224[] = { + SPH_C32(0xc3967a67), SPH_C32(0xc3bc6c20), SPH_C32(0x4bc3bcc3), + SPH_C32(0xa7c3bc6b), SPH_C32(0x2c204b61), SPH_C32(0x74686f6c), + SPH_C32(0x69656b65), SPH_C32(0x20556e69) +}; + +/* + * This version is the one used in the Hamsi submission package for + * round 2 of the SHA-3 competition; the UTF-8 encoding is wrong and + * shall soon be corrected in the official Hamsi specification. + * +static const sph_u32 IV224[] = { + SPH_C32(0x3c967a67), SPH_C32(0x3cbc6c20), SPH_C32(0xb4c343c3), + SPH_C32(0xa73cbc6b), SPH_C32(0x2c204b61), SPH_C32(0x74686f6c), + SPH_C32(0x69656b65), SPH_C32(0x20556e69) +}; + */ + +static const sph_u32 IV256[] = { + SPH_C32(0x76657273), SPH_C32(0x69746569), SPH_C32(0x74204c65), + SPH_C32(0x7576656e), SPH_C32(0x2c204465), SPH_C32(0x70617274), + SPH_C32(0x656d656e), SPH_C32(0x7420456c) +}; + +static const sph_u32 IV384[] = { + SPH_C32(0x656b7472), SPH_C32(0x6f746563), SPH_C32(0x686e6965), + SPH_C32(0x6b2c2043), SPH_C32(0x6f6d7075), SPH_C32(0x74657220), + SPH_C32(0x53656375), SPH_C32(0x72697479), SPH_C32(0x20616e64), + SPH_C32(0x20496e64), SPH_C32(0x75737472), SPH_C32(0x69616c20), + SPH_C32(0x43727970), SPH_C32(0x746f6772), SPH_C32(0x61706879), + SPH_C32(0x2c204b61) +}; + +static const sph_u32 IV512[] = { + SPH_C32(0x73746565), SPH_C32(0x6c706172), SPH_C32(0x6b204172), + SPH_C32(0x656e6265), SPH_C32(0x72672031), SPH_C32(0x302c2062), + SPH_C32(0x75732032), SPH_C32(0x3434362c), SPH_C32(0x20422d33), + SPH_C32(0x30303120), SPH_C32(0x4c657576), SPH_C32(0x656e2d48), + SPH_C32(0x65766572), SPH_C32(0x6c65652c), SPH_C32(0x2042656c), + SPH_C32(0x6769756d) +}; + +static const sph_u32 alpha_n[] = { + SPH_C32(0xff00f0f0), SPH_C32(0xccccaaaa), SPH_C32(0xf0f0cccc), + SPH_C32(0xff00aaaa), SPH_C32(0xccccaaaa), SPH_C32(0xf0f0ff00), + SPH_C32(0xaaaacccc), SPH_C32(0xf0f0ff00), SPH_C32(0xf0f0cccc), + SPH_C32(0xaaaaff00), SPH_C32(0xccccff00), SPH_C32(0xaaaaf0f0), + SPH_C32(0xaaaaf0f0), SPH_C32(0xff00cccc), SPH_C32(0xccccf0f0), + SPH_C32(0xff00aaaa), SPH_C32(0xccccaaaa), SPH_C32(0xff00f0f0), + SPH_C32(0xff00aaaa), SPH_C32(0xf0f0cccc), SPH_C32(0xf0f0ff00), + SPH_C32(0xccccaaaa), SPH_C32(0xf0f0ff00), SPH_C32(0xaaaacccc), + SPH_C32(0xaaaaff00), SPH_C32(0xf0f0cccc), SPH_C32(0xaaaaf0f0), + SPH_C32(0xccccff00), SPH_C32(0xff00cccc), SPH_C32(0xaaaaf0f0), + SPH_C32(0xff00aaaa), SPH_C32(0xccccf0f0) +}; + +static const sph_u32 alpha_f[] = { + SPH_C32(0xcaf9639c), SPH_C32(0x0ff0f9c0), SPH_C32(0x639c0ff0), + SPH_C32(0xcaf9f9c0), SPH_C32(0x0ff0f9c0), SPH_C32(0x639ccaf9), + SPH_C32(0xf9c00ff0), SPH_C32(0x639ccaf9), SPH_C32(0x639c0ff0), + SPH_C32(0xf9c0caf9), SPH_C32(0x0ff0caf9), SPH_C32(0xf9c0639c), + SPH_C32(0xf9c0639c), SPH_C32(0xcaf90ff0), SPH_C32(0x0ff0639c), + SPH_C32(0xcaf9f9c0), SPH_C32(0x0ff0f9c0), SPH_C32(0xcaf9639c), + SPH_C32(0xcaf9f9c0), SPH_C32(0x639c0ff0), SPH_C32(0x639ccaf9), + SPH_C32(0x0ff0f9c0), SPH_C32(0x639ccaf9), SPH_C32(0xf9c00ff0), + SPH_C32(0xf9c0caf9), SPH_C32(0x639c0ff0), SPH_C32(0xf9c0639c), + SPH_C32(0x0ff0caf9), SPH_C32(0xcaf90ff0), SPH_C32(0xf9c0639c), + SPH_C32(0xcaf9f9c0), SPH_C32(0x0ff0639c) +}; + +#define DECL_STATE_SMALL \ + sph_u32 c0, c1, c2, c3, c4, c5, c6, c7; + +#define READ_STATE_SMALL(sc) do { \ + c0 = sc->h[0x0]; \ + c1 = sc->h[0x1]; \ + c2 = sc->h[0x2]; \ + c3 = sc->h[0x3]; \ + c4 = sc->h[0x4]; \ + c5 = sc->h[0x5]; \ + c6 = sc->h[0x6]; \ + c7 = sc->h[0x7]; \ + } while (0) + +#define WRITE_STATE_SMALL(sc) do { \ + sc->h[0x0] = c0; \ + sc->h[0x1] = c1; \ + sc->h[0x2] = c2; \ + sc->h[0x3] = c3; \ + sc->h[0x4] = c4; \ + sc->h[0x5] = c5; \ + sc->h[0x6] = c6; \ + sc->h[0x7] = c7; \ + } while (0) + +#define s0 m0 +#define s1 m1 +#define s2 c0 +#define s3 c1 +#define s4 c2 +#define s5 c3 +#define s6 m2 +#define s7 m3 +#define s8 m4 +#define s9 m5 +#define sA c4 +#define sB c5 +#define sC c6 +#define sD c7 +#define sE m6 +#define sF m7 + +#define SBOX(a, b, c, d) do { \ + sph_u32 t; \ + t = (a); \ + (a) &= (c); \ + (a) ^= (d); \ + (c) ^= (b); \ + (c) ^= (a); \ + (d) |= t; \ + (d) ^= (b); \ + t ^= (c); \ + (b) = (d); \ + (d) |= t; \ + (d) ^= (a); \ + (a) &= (b); \ + t ^= (a); \ + (b) ^= (d); \ + (b) ^= t; \ + (a) = (c); \ + (c) = (b); \ + (b) = (d); \ + (d) = SPH_T32(~t); \ + } while (0) + +#define L(a, b, c, d) do { \ + (a) = SPH_ROTL32(a, 13); \ + (c) = SPH_ROTL32(c, 3); \ + (b) ^= (a) ^ (c); \ + (d) ^= (c) ^ SPH_T32((a) << 3); \ + (b) = SPH_ROTL32(b, 1); \ + (d) = SPH_ROTL32(d, 7); \ + (a) ^= (b) ^ (d); \ + (c) ^= (d) ^ SPH_T32((b) << 7); \ + (a) = SPH_ROTL32(a, 5); \ + (c) = SPH_ROTL32(c, 22); \ + } while (0) + +#define ROUND_SMALL(rc, alpha) do { \ + s0 ^= alpha[0x00]; \ + s1 ^= alpha[0x01] ^ (sph_u32)(rc); \ + s2 ^= alpha[0x02]; \ + s3 ^= alpha[0x03]; \ + s4 ^= alpha[0x08]; \ + s5 ^= alpha[0x09]; \ + s6 ^= alpha[0x0A]; \ + s7 ^= alpha[0x0B]; \ + s8 ^= alpha[0x10]; \ + s9 ^= alpha[0x11]; \ + sA ^= alpha[0x12]; \ + sB ^= alpha[0x13]; \ + sC ^= alpha[0x18]; \ + sD ^= alpha[0x19]; \ + sE ^= alpha[0x1A]; \ + sF ^= alpha[0x1B]; \ + SBOX(s0, s4, s8, sC); \ + SBOX(s1, s5, s9, sD); \ + SBOX(s2, s6, sA, sE); \ + SBOX(s3, s7, sB, sF); \ + L(s0, s5, sA, sF); \ + L(s1, s6, sB, sC); \ + L(s2, s7, s8, sD); \ + L(s3, s4, s9, sE); \ + } while (0) + +#define P_SMALL do { \ + ROUND_SMALL(0, alpha_n); \ + ROUND_SMALL(1, alpha_n); \ + ROUND_SMALL(2, alpha_n); \ + } while (0) + +#define PF_SMALL do { \ + ROUND_SMALL(0, alpha_f); \ + ROUND_SMALL(1, alpha_f); \ + ROUND_SMALL(2, alpha_f); \ + ROUND_SMALL(3, alpha_f); \ + ROUND_SMALL(4, alpha_f); \ + ROUND_SMALL(5, alpha_f); \ + } while (0) + +#define T_SMALL do { \ + /* order is important */ \ + c7 = (sc->h[7] ^= sB); \ + c6 = (sc->h[6] ^= sA); \ + c5 = (sc->h[5] ^= s9); \ + c4 = (sc->h[4] ^= s8); \ + c3 = (sc->h[3] ^= s3); \ + c2 = (sc->h[2] ^= s2); \ + c1 = (sc->h[1] ^= s1); \ + c0 = (sc->h[0] ^= s0); \ + } while (0) + +static void +hamsi_small(sph_hamsi_small_context *sc, const unsigned char *buf, size_t num) +{ + DECL_STATE_SMALL +#if !SPH_64 + sph_u32 tmp; +#endif + +#if SPH_64 + sc->count += (sph_u64)num << 5; +#else + tmp = SPH_T32((sph_u32)num << 5); + sc->count_low = SPH_T32(sc->count_low + tmp); + sc->count_high += (sph_u32)((num >> 13) >> 14); + if (sc->count_low < tmp) + sc->count_high ++; +#endif + READ_STATE_SMALL(sc); + while (num -- > 0) { + sph_u32 m0, m1, m2, m3, m4, m5, m6, m7; + + INPUT_SMALL; + P_SMALL; + T_SMALL; + buf += 4; + } + WRITE_STATE_SMALL(sc); +} + +static void +hamsi_small_final(sph_hamsi_small_context *sc, const unsigned char *buf) +{ + sph_u32 m0, m1, m2, m3, m4, m5, m6, m7; + DECL_STATE_SMALL + + READ_STATE_SMALL(sc); + INPUT_SMALL; + PF_SMALL; + T_SMALL; + WRITE_STATE_SMALL(sc); +} + +static void +hamsi_small_init(sph_hamsi_small_context *sc, const sph_u32 *iv) +{ + sc->partial_len = 0; + memcpy(sc->h, iv, sizeof sc->h); +#if SPH_64 + sc->count = 0; +#else + sc->count_high = sc->count_low = 0; +#endif +} + +static void +hamsi_small_core(sph_hamsi_small_context *sc, const void *data, size_t len) +{ + if (sc->partial_len != 0) { + size_t mlen; + + mlen = 4 - sc->partial_len; + if (len < mlen) { + memcpy(sc->partial + sc->partial_len, data, len); + sc->partial_len += len; + return; + } else { + memcpy(sc->partial + sc->partial_len, data, mlen); + len -= mlen; + data = (const unsigned char *)data + mlen; + hamsi_small(sc, sc->partial, 1); + sc->partial_len = 0; + } + } + + hamsi_small(sc, data, (len >> 2)); + data = (const unsigned char *)data + (len & ~(size_t)3); + len &= (size_t)3; + memcpy(sc->partial, data, len); + sc->partial_len = len; +} + +static void +hamsi_small_close(sph_hamsi_small_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_size_w32) +{ + unsigned char pad[12]; + size_t ptr, u; + unsigned z; + unsigned char *out; + + ptr = sc->partial_len; + memcpy(pad, sc->partial, ptr); +#if SPH_64 + sph_enc64be(pad + 4, sc->count + (ptr << 3) + n); +#else + sph_enc32be(pad + 4, sc->count_high); + sph_enc32be(pad + 8, sc->count_low + (ptr << 3) + n); +#endif + z = 0x80 >> n; + pad[ptr ++] = ((ub & -z) | z) & 0xFF; + while (ptr < 4) + pad[ptr ++] = 0; + hamsi_small(sc, pad, 2); + hamsi_small_final(sc, pad + 8); + out = dst; + for (u = 0; u < out_size_w32; u ++) + sph_enc32be(out + (u << 2), sc->h[u]); +} + +#define DECL_STATE_BIG \ + sph_u32 c0, c1, c2, c3, c4, c5, c6, c7; \ + sph_u32 c8, c9, cA, cB, cC, cD, cE, cF; + +#define READ_STATE_BIG(sc) do { \ + c0 = sc->h[0x0]; \ + c1 = sc->h[0x1]; \ + c2 = sc->h[0x2]; \ + c3 = sc->h[0x3]; \ + c4 = sc->h[0x4]; \ + c5 = sc->h[0x5]; \ + c6 = sc->h[0x6]; \ + c7 = sc->h[0x7]; \ + c8 = sc->h[0x8]; \ + c9 = sc->h[0x9]; \ + cA = sc->h[0xA]; \ + cB = sc->h[0xB]; \ + cC = sc->h[0xC]; \ + cD = sc->h[0xD]; \ + cE = sc->h[0xE]; \ + cF = sc->h[0xF]; \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + sc->h[0x0] = c0; \ + sc->h[0x1] = c1; \ + sc->h[0x2] = c2; \ + sc->h[0x3] = c3; \ + sc->h[0x4] = c4; \ + sc->h[0x5] = c5; \ + sc->h[0x6] = c6; \ + sc->h[0x7] = c7; \ + sc->h[0x8] = c8; \ + sc->h[0x9] = c9; \ + sc->h[0xA] = cA; \ + sc->h[0xB] = cB; \ + sc->h[0xC] = cC; \ + sc->h[0xD] = cD; \ + sc->h[0xE] = cE; \ + sc->h[0xF] = cF; \ + } while (0) + +#define s00 m0 +#define s01 m1 +#define s02 c0 +#define s03 c1 +#define s04 m2 +#define s05 m3 +#define s06 c2 +#define s07 c3 +#define s08 c4 +#define s09 c5 +#define s0A m4 +#define s0B m5 +#define s0C c6 +#define s0D c7 +#define s0E m6 +#define s0F m7 +#define s10 m8 +#define s11 m9 +#define s12 c8 +#define s13 c9 +#define s14 mA +#define s15 mB +#define s16 cA +#define s17 cB +#define s18 cC +#define s19 cD +#define s1A mC +#define s1B mD +#define s1C cE +#define s1D cF +#define s1E mE +#define s1F mF + +#define ROUND_BIG(rc, alpha) do { \ + s00 ^= alpha[0x00]; \ + s01 ^= alpha[0x01] ^ (sph_u32)(rc); \ + s02 ^= alpha[0x02]; \ + s03 ^= alpha[0x03]; \ + s04 ^= alpha[0x04]; \ + s05 ^= alpha[0x05]; \ + s06 ^= alpha[0x06]; \ + s07 ^= alpha[0x07]; \ + s08 ^= alpha[0x08]; \ + s09 ^= alpha[0x09]; \ + s0A ^= alpha[0x0A]; \ + s0B ^= alpha[0x0B]; \ + s0C ^= alpha[0x0C]; \ + s0D ^= alpha[0x0D]; \ + s0E ^= alpha[0x0E]; \ + s0F ^= alpha[0x0F]; \ + s10 ^= alpha[0x10]; \ + s11 ^= alpha[0x11]; \ + s12 ^= alpha[0x12]; \ + s13 ^= alpha[0x13]; \ + s14 ^= alpha[0x14]; \ + s15 ^= alpha[0x15]; \ + s16 ^= alpha[0x16]; \ + s17 ^= alpha[0x17]; \ + s18 ^= alpha[0x18]; \ + s19 ^= alpha[0x19]; \ + s1A ^= alpha[0x1A]; \ + s1B ^= alpha[0x1B]; \ + s1C ^= alpha[0x1C]; \ + s1D ^= alpha[0x1D]; \ + s1E ^= alpha[0x1E]; \ + s1F ^= alpha[0x1F]; \ + SBOX(s00, s08, s10, s18); \ + SBOX(s01, s09, s11, s19); \ + SBOX(s02, s0A, s12, s1A); \ + SBOX(s03, s0B, s13, s1B); \ + SBOX(s04, s0C, s14, s1C); \ + SBOX(s05, s0D, s15, s1D); \ + SBOX(s06, s0E, s16, s1E); \ + SBOX(s07, s0F, s17, s1F); \ + L(s00, s09, s12, s1B); \ + L(s01, s0A, s13, s1C); \ + L(s02, s0B, s14, s1D); \ + L(s03, s0C, s15, s1E); \ + L(s04, s0D, s16, s1F); \ + L(s05, s0E, s17, s18); \ + L(s06, s0F, s10, s19); \ + L(s07, s08, s11, s1A); \ + L(s00, s02, s05, s07); \ + L(s10, s13, s15, s16); \ + L(s09, s0B, s0C, s0E); \ + L(s19, s1A, s1C, s1F); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_HAMSI + +#define P_BIG do { \ + unsigned r; \ + for (r = 0; r < 6; r ++) \ + ROUND_BIG(r, alpha_n); \ + } while (0) + +#define PF_BIG do { \ + unsigned r; \ + for (r = 0; r < 12; r ++) \ + ROUND_BIG(r, alpha_f); \ + } while (0) + +#else + +#define P_BIG do { \ + ROUND_BIG(0, alpha_n); \ + ROUND_BIG(1, alpha_n); \ + ROUND_BIG(2, alpha_n); \ + ROUND_BIG(3, alpha_n); \ + ROUND_BIG(4, alpha_n); \ + ROUND_BIG(5, alpha_n); \ + } while (0) + +#define PF_BIG do { \ + ROUND_BIG(0, alpha_f); \ + ROUND_BIG(1, alpha_f); \ + ROUND_BIG(2, alpha_f); \ + ROUND_BIG(3, alpha_f); \ + ROUND_BIG(4, alpha_f); \ + ROUND_BIG(5, alpha_f); \ + ROUND_BIG(6, alpha_f); \ + ROUND_BIG(7, alpha_f); \ + ROUND_BIG(8, alpha_f); \ + ROUND_BIG(9, alpha_f); \ + ROUND_BIG(10, alpha_f); \ + ROUND_BIG(11, alpha_f); \ + } while (0) + +#endif + +#define T_BIG do { \ + /* order is important */ \ + cF = (sc->h[0xF] ^= s17); \ + cE = (sc->h[0xE] ^= s16); \ + cD = (sc->h[0xD] ^= s15); \ + cC = (sc->h[0xC] ^= s14); \ + cB = (sc->h[0xB] ^= s13); \ + cA = (sc->h[0xA] ^= s12); \ + c9 = (sc->h[0x9] ^= s11); \ + c8 = (sc->h[0x8] ^= s10); \ + c7 = (sc->h[0x7] ^= s07); \ + c6 = (sc->h[0x6] ^= s06); \ + c5 = (sc->h[0x5] ^= s05); \ + c4 = (sc->h[0x4] ^= s04); \ + c3 = (sc->h[0x3] ^= s03); \ + c2 = (sc->h[0x2] ^= s02); \ + c1 = (sc->h[0x1] ^= s01); \ + c0 = (sc->h[0x0] ^= s00); \ + } while (0) + +static void +hamsi_big(sph_hamsi_big_context *sc, const unsigned char *buf, size_t num) +{ + DECL_STATE_BIG +#if !SPH_64 + sph_u32 tmp; +#endif + +#if SPH_64 + sc->count += (sph_u64)num << 6; +#else + tmp = SPH_T32((sph_u32)num << 6); + sc->count_low = SPH_T32(sc->count_low + tmp); + sc->count_high += (sph_u32)((num >> 13) >> 13); + if (sc->count_low < tmp) + sc->count_high ++; +#endif + READ_STATE_BIG(sc); + while (num -- > 0) { + sph_u32 m0, m1, m2, m3, m4, m5, m6, m7; + sph_u32 m8, m9, mA, mB, mC, mD, mE, mF; + + INPUT_BIG; + P_BIG; + T_BIG; + buf += 8; + } + WRITE_STATE_BIG(sc); +} + +static void +hamsi_big_final(sph_hamsi_big_context *sc, const unsigned char *buf) +{ + sph_u32 m0, m1, m2, m3, m4, m5, m6, m7; + sph_u32 m8, m9, mA, mB, mC, mD, mE, mF; + DECL_STATE_BIG + + READ_STATE_BIG(sc); + INPUT_BIG; + PF_BIG; + T_BIG; + WRITE_STATE_BIG(sc); +} + +static void +hamsi_big_init(sph_hamsi_big_context *sc, const sph_u32 *iv) +{ + sc->partial_len = 0; + memcpy(sc->h, iv, sizeof sc->h); +#if SPH_64 + sc->count = 0; +#else + sc->count_high = sc->count_low = 0; +#endif +} + +static void +hamsi_big_core(sph_hamsi_big_context *sc, const void *data, size_t len) +{ + if (sc->partial_len != 0) { + size_t mlen; + + mlen = 8 - sc->partial_len; + if (len < mlen) { + memcpy(sc->partial + sc->partial_len, data, len); + sc->partial_len += len; + return; + } else { + memcpy(sc->partial + sc->partial_len, data, mlen); + len -= mlen; + data = (const unsigned char *)data + mlen; + hamsi_big(sc, sc->partial, 1); + sc->partial_len = 0; + } + } + + hamsi_big(sc, data, (len >> 3)); + data = (const unsigned char *)data + (len & ~(size_t)7); + len &= (size_t)7; + memcpy(sc->partial, data, len); + sc->partial_len = len; +} + +static void +hamsi_big_close(sph_hamsi_big_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_size_w32) +{ + unsigned char pad[8]; + size_t ptr, u; + unsigned z; + unsigned char *out; + + ptr = sc->partial_len; +#if SPH_64 + sph_enc64be(pad, sc->count + (ptr << 3) + n); +#else + sph_enc32be(pad, sc->count_high); + sph_enc32be(pad + 4, sc->count_low + (ptr << 3) + n); +#endif + z = 0x80 >> n; + sc->partial[ptr ++] = ((ub & -z) | z) & 0xFF; + while (ptr < 8) + sc->partial[ptr ++] = 0; + hamsi_big(sc, sc->partial, 1); + hamsi_big_final(sc, pad); + out = dst; + if (out_size_w32 == 12) { + sph_enc32be(out + 0, sc->h[ 0]); + sph_enc32be(out + 4, sc->h[ 1]); + sph_enc32be(out + 8, sc->h[ 3]); + sph_enc32be(out + 12, sc->h[ 4]); + sph_enc32be(out + 16, sc->h[ 5]); + sph_enc32be(out + 20, sc->h[ 6]); + sph_enc32be(out + 24, sc->h[ 8]); + sph_enc32be(out + 28, sc->h[ 9]); + sph_enc32be(out + 32, sc->h[10]); + sph_enc32be(out + 36, sc->h[12]); + sph_enc32be(out + 40, sc->h[13]); + sph_enc32be(out + 44, sc->h[15]); + } else { + for (u = 0; u < 16; u ++) + sph_enc32be(out + (u << 2), sc->h[u]); + } +} + +/* see sph_hamsi.h */ +void +sph_hamsi224_init(void *cc) +{ + hamsi_small_init(cc, IV224); +} + +/* see sph_hamsi.h */ +void +sph_hamsi224(void *cc, const void *data, size_t len) +{ + hamsi_small_core(cc, data, len); +} + +/* see sph_hamsi.h */ +void +sph_hamsi224_close(void *cc, void *dst) +{ + hamsi_small_close(cc, 0, 0, dst, 7); + hamsi_small_init(cc, IV224); +} + +/* see sph_hamsi.h */ +void +sph_hamsi224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + hamsi_small_close(cc, ub, n, dst, 7); + hamsi_small_init(cc, IV224); +} + +/* see sph_hamsi.h */ +void +sph_hamsi256_init(void *cc) +{ + hamsi_small_init(cc, IV256); +} + +/* see sph_hamsi.h */ +void +sph_hamsi256(void *cc, const void *data, size_t len) +{ + hamsi_small_core(cc, data, len); +} + +/* see sph_hamsi.h */ +void +sph_hamsi256_close(void *cc, void *dst) +{ + hamsi_small_close(cc, 0, 0, dst, 8); + hamsi_small_init(cc, IV256); +} + +/* see sph_hamsi.h */ +void +sph_hamsi256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + hamsi_small_close(cc, ub, n, dst, 8); + hamsi_small_init(cc, IV256); +} + +/* see sph_hamsi.h */ +void +sph_hamsi384_init(void *cc) +{ + hamsi_big_init(cc, IV384); +} + +/* see sph_hamsi.h */ +void +sph_hamsi384(void *cc, const void *data, size_t len) +{ + hamsi_big_core(cc, data, len); +} + +/* see sph_hamsi.h */ +void +sph_hamsi384_close(void *cc, void *dst) +{ + hamsi_big_close(cc, 0, 0, dst, 12); + hamsi_big_init(cc, IV384); +} + +/* see sph_hamsi.h */ +void +sph_hamsi384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + hamsi_big_close(cc, ub, n, dst, 12); + hamsi_big_init(cc, IV384); +} + +/* see sph_hamsi.h */ +void +sph_hamsi512_init(void *cc) +{ + hamsi_big_init(cc, IV512); +} + +/* see sph_hamsi.h */ +void +sph_hamsi512(void *cc, const void *data, size_t len) +{ + hamsi_big_core(cc, data, len); +} + +/* see sph_hamsi.h */ +void +sph_hamsi512_close(void *cc, void *dst) +{ + hamsi_big_close(cc, 0, 0, dst, 16); + hamsi_big_init(cc, IV512); +} + +/* see sph_hamsi.h */ +void +sph_hamsi512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + hamsi_big_close(cc, ub, n, dst, 16); + hamsi_big_init(cc, IV512); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/hamsi_helper.c b/src/hamsi_helper.c new file mode 100644 index 0000000..cdf2fc9 --- /dev/null +++ b/src/hamsi_helper.c @@ -0,0 +1,39648 @@ +/* $Id: hamsi_helper.c 202 2010-05-31 15:46:48Z tp $ */ +/* + * Helper code for Hamsi (input block expansion). This code is + * automatically generated and includes precomputed tables for + * expansion code which handles 2 to 8 bits at a time. + * + * This file is included from hamsi.c, and is not meant to be compiled + * independently. + * + * ==========================(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 + */ + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_HAMSI_EXPAND_SMALL == 1 + +/* Note: this table lists bits within each byte from least + siginificant to most significant. */ +static const sph_u32 T256[32][8] = { + { SPH_C32(0x74951000), SPH_C32(0x5a2b467e), SPH_C32(0x88fd1d2b), + SPH_C32(0x1ee68292), SPH_C32(0xcba90000), SPH_C32(0x90273769), + SPH_C32(0xbbdcf407), SPH_C32(0xd0f4af61) }, + { SPH_C32(0xcba90000), SPH_C32(0x90273769), SPH_C32(0xbbdcf407), + SPH_C32(0xd0f4af61), SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), + SPH_C32(0x3321e92c), SPH_C32(0xce122df3) }, + { SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), SPH_C32(0x11fa3a57), + SPH_C32(0x3dc90524), SPH_C32(0x97530000), SPH_C32(0x204f6ed3), + SPH_C32(0x77b9e80f), SPH_C32(0xa1ec5ec1) }, + { SPH_C32(0x97530000), SPH_C32(0x204f6ed3), SPH_C32(0x77b9e80f), + SPH_C32(0xa1ec5ec1), SPH_C32(0x7e792000), SPH_C32(0x9418e22f), + SPH_C32(0x6643d258), SPH_C32(0x9c255be5) }, + { SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), SPH_C32(0x8dfacfab), + SPH_C32(0xce36cc72), SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), + SPH_C32(0x848598ba), SPH_C32(0x1041003e) }, + { SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), SPH_C32(0x848598ba), + SPH_C32(0x1041003e), SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), + SPH_C32(0x097f5711), SPH_C32(0xde77cc4c) }, + { SPH_C32(0xe4788000), SPH_C32(0x859673c1), SPH_C32(0xb5fb2452), + SPH_C32(0x29cc5edf), SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), + SPH_C32(0x62fc79d0), SPH_C32(0x731ebdc2) }, + { SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), SPH_C32(0x62fc79d0), + SPH_C32(0x731ebdc2), SPH_C32(0xe0278000), SPH_C32(0x19dce008), + SPH_C32(0xd7075d82), SPH_C32(0x5ad2e31d) }, + { SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), SPH_C32(0x8589d8ab), + SPH_C32(0xe6c46464), SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), + SPH_C32(0xa29d1297), SPH_C32(0x6ee56854) }, + { SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), SPH_C32(0xa29d1297), + SPH_C32(0x6ee56854), SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), + SPH_C32(0x2714ca3c), SPH_C32(0x88210c30) }, + { SPH_C32(0xa7b80200), SPH_C32(0x1f128433), SPH_C32(0x60e5f9f2), + SPH_C32(0x9e147576), SPH_C32(0xee260000), SPH_C32(0x124b683e), + SPH_C32(0x80c2d68f), SPH_C32(0x3bf3ab2c) }, + { SPH_C32(0xee260000), SPH_C32(0x124b683e), SPH_C32(0x80c2d68f), + SPH_C32(0x3bf3ab2c), SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), + SPH_C32(0xe0272f7d), SPH_C32(0xa5e7de5a) }, + { SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), SPH_C32(0x6fc548e1), + SPH_C32(0x898d2cd6), SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), + SPH_C32(0x6a72e5bb), SPH_C32(0x247febe6) }, + { SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), SPH_C32(0x6a72e5bb), + SPH_C32(0x247febe6), SPH_C32(0x9b830400), SPH_C32(0x2227ff88), + SPH_C32(0x05b7ad5a), SPH_C32(0xadf2c730) }, + { SPH_C32(0xde320800), SPH_C32(0x288350fe), SPH_C32(0x71852ac7), + SPH_C32(0xa6bf9f96), SPH_C32(0xe18b0000), SPH_C32(0x5459887d), + SPH_C32(0xbf1283d3), SPH_C32(0x1b666a73) }, + { SPH_C32(0xe18b0000), SPH_C32(0x5459887d), SPH_C32(0xbf1283d3), + SPH_C32(0x1b666a73), SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), + SPH_C32(0xce97a914), SPH_C32(0xbdd9f5e5) }, + { SPH_C32(0x515c0010), SPH_C32(0x40f372fb), SPH_C32(0xfce72602), + SPH_C32(0x71575061), SPH_C32(0x2e390000), SPH_C32(0x64dd6689), + SPH_C32(0x3cd406fc), SPH_C32(0xb1f490bc) }, + { SPH_C32(0x2e390000), SPH_C32(0x64dd6689), SPH_C32(0x3cd406fc), + SPH_C32(0xb1f490bc), SPH_C32(0x7f650010), SPH_C32(0x242e1472), + SPH_C32(0xc03320fe), SPH_C32(0xc0a3c0dd) }, + { SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), SPH_C32(0xf9ce4c04), + SPH_C32(0xe2afa0c0), SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), + SPH_C32(0x79a90df9), SPH_C32(0x63e92178) }, + { SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), SPH_C32(0x79a90df9), + SPH_C32(0x63e92178), SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), + SPH_C32(0x806741fd), SPH_C32(0x814681b8) }, + { SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), SPH_C32(0x36656ba8), + SPH_C32(0x23633a05), SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), + SPH_C32(0x5d5ca0f7), SPH_C32(0x727784cb) }, + { SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), SPH_C32(0x5d5ca0f7), + SPH_C32(0x727784cb), SPH_C32(0x35650040), SPH_C32(0x9b96b64a), + SPH_C32(0x6b39cb5f), SPH_C32(0x5114bece) }, + { SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), SPH_C32(0xc2c46c55), + SPH_C32(0xf362b233), SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), + SPH_C32(0xd14e094b), SPH_C32(0xb772b42b) }, + { SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), SPH_C32(0xd14e094b), + SPH_C32(0xb772b42b), SPH_C32(0x62740080), SPH_C32(0x0fb84b07), + SPH_C32(0x138a651e), SPH_C32(0x44100618) }, + { SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), SPH_C32(0xae0ebb05), + SPH_C32(0xb5a4c63b), SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), + SPH_C32(0x6bf648a4), SPH_C32(0x539cbdbf) }, + { SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), SPH_C32(0x6bf648a4), + SPH_C32(0x539cbdbf), SPH_C32(0x08bf0001), SPH_C32(0x38942792), + SPH_C32(0xc5f8f3a1), SPH_C32(0xe6387b84) }, + { SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), SPH_C32(0x99e585aa), + SPH_C32(0x8d75f7f1), SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), + SPH_C32(0x79e22a4c), SPH_C32(0x1298bd46) }, + { SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), SPH_C32(0x79e22a4c), + SPH_C32(0x1298bd46), SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), + SPH_C32(0xe007afe6), SPH_C32(0x9fed4ab7) }, + { SPH_C32(0xd0080004), SPH_C32(0x8c768f77), SPH_C32(0x9dc5b050), + SPH_C32(0xaf4a29da), SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), + SPH_C32(0x98321c3d), SPH_C32(0x76acc733) }, + { SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), SPH_C32(0x98321c3d), + SPH_C32(0x76acc733), SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), + SPH_C32(0x05f7ac6d), SPH_C32(0xd9e6eee9) }, + { SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), SPH_C32(0xfe739301), + SPH_C32(0xb8a92831), SPH_C32(0x171c0000), SPH_C32(0xb26e3344), + SPH_C32(0x9e6a837e), SPH_C32(0x58f8485f) }, + { SPH_C32(0x171c0000), SPH_C32(0xb26e3344), SPH_C32(0x9e6a837e), + SPH_C32(0x58f8485f), SPH_C32(0xbfb20008), SPH_C32(0x92170a39), + SPH_C32(0x6019107f), SPH_C32(0xe051606e) } +}; + +#define INPUT_SMALL do { \ + const sph_u32 *tp = &T256[0][0]; \ + unsigned u, v; \ + m0 = 0; \ + m1 = 0; \ + m2 = 0; \ + m3 = 0; \ + m4 = 0; \ + m5 = 0; \ + m6 = 0; \ + m7 = 0; \ + for (u = 0; u < 4; u ++) { \ + unsigned db = buf[u]; \ + for (v = 0; v < 8; v ++, db >>= 1) { \ + sph_u32 dm = SPH_T32(-(sph_u32)(db & 1)); \ + m0 ^= dm & *tp ++; \ + m1 ^= dm & *tp ++; \ + m2 ^= dm & *tp ++; \ + m3 ^= dm & *tp ++; \ + m4 ^= dm & *tp ++; \ + m5 ^= dm & *tp ++; \ + m6 ^= dm & *tp ++; \ + m7 ^= dm & *tp ++; \ + } \ + } \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_SMALL == 2 + +static const sph_u32 T256_0[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xe4788000), SPH_C32(0x859673c1), SPH_C32(0xb5fb2452), + SPH_C32(0x29cc5edf), SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), + SPH_C32(0x62fc79d0), SPH_C32(0x731ebdc2) }, + { SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), SPH_C32(0x62fc79d0), + SPH_C32(0x731ebdc2), SPH_C32(0xe0278000), SPH_C32(0x19dce008), + SPH_C32(0xd7075d82), SPH_C32(0x5ad2e31d) }, + { SPH_C32(0xe0278000), SPH_C32(0x19dce008), SPH_C32(0xd7075d82), + SPH_C32(0x5ad2e31d), SPH_C32(0xe4788000), SPH_C32(0x859673c1), + SPH_C32(0xb5fb2452), SPH_C32(0x29cc5edf) } +}; + +static const sph_u32 T256_2[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), SPH_C32(0x8dfacfab), + SPH_C32(0xce36cc72), SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), + SPH_C32(0x848598ba), SPH_C32(0x1041003e) }, + { SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), SPH_C32(0x848598ba), + SPH_C32(0x1041003e), SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), + SPH_C32(0x097f5711), SPH_C32(0xde77cc4c) }, + { SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), SPH_C32(0x097f5711), + SPH_C32(0xde77cc4c), SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), + SPH_C32(0x8dfacfab), SPH_C32(0xce36cc72) } +}; + +static const sph_u32 T256_4[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), SPH_C32(0x11fa3a57), + SPH_C32(0x3dc90524), SPH_C32(0x97530000), SPH_C32(0x204f6ed3), + SPH_C32(0x77b9e80f), SPH_C32(0xa1ec5ec1) }, + { SPH_C32(0x97530000), SPH_C32(0x204f6ed3), SPH_C32(0x77b9e80f), + SPH_C32(0xa1ec5ec1), SPH_C32(0x7e792000), SPH_C32(0x9418e22f), + SPH_C32(0x6643d258), SPH_C32(0x9c255be5) }, + { SPH_C32(0x7e792000), SPH_C32(0x9418e22f), SPH_C32(0x6643d258), + SPH_C32(0x9c255be5), SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), + SPH_C32(0x11fa3a57), SPH_C32(0x3dc90524) } +}; + +static const sph_u32 T256_6[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x74951000), SPH_C32(0x5a2b467e), SPH_C32(0x88fd1d2b), + SPH_C32(0x1ee68292), SPH_C32(0xcba90000), SPH_C32(0x90273769), + SPH_C32(0xbbdcf407), SPH_C32(0xd0f4af61) }, + { SPH_C32(0xcba90000), SPH_C32(0x90273769), SPH_C32(0xbbdcf407), + SPH_C32(0xd0f4af61), SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), + SPH_C32(0x3321e92c), SPH_C32(0xce122df3) }, + { SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), SPH_C32(0x3321e92c), + SPH_C32(0xce122df3), SPH_C32(0x74951000), SPH_C32(0x5a2b467e), + SPH_C32(0x88fd1d2b), SPH_C32(0x1ee68292) } +}; + +static const sph_u32 T256_8[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xde320800), SPH_C32(0x288350fe), SPH_C32(0x71852ac7), + SPH_C32(0xa6bf9f96), SPH_C32(0xe18b0000), SPH_C32(0x5459887d), + SPH_C32(0xbf1283d3), SPH_C32(0x1b666a73) }, + { SPH_C32(0xe18b0000), SPH_C32(0x5459887d), SPH_C32(0xbf1283d3), + SPH_C32(0x1b666a73), SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), + SPH_C32(0xce97a914), SPH_C32(0xbdd9f5e5) }, + { SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), SPH_C32(0xce97a914), + SPH_C32(0xbdd9f5e5), SPH_C32(0xde320800), SPH_C32(0x288350fe), + SPH_C32(0x71852ac7), SPH_C32(0xa6bf9f96) } +}; + +static const sph_u32 T256_10[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), SPH_C32(0x6fc548e1), + SPH_C32(0x898d2cd6), SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), + SPH_C32(0x6a72e5bb), SPH_C32(0x247febe6) }, + { SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), SPH_C32(0x6a72e5bb), + SPH_C32(0x247febe6), SPH_C32(0x9b830400), SPH_C32(0x2227ff88), + SPH_C32(0x05b7ad5a), SPH_C32(0xadf2c730) }, + { SPH_C32(0x9b830400), SPH_C32(0x2227ff88), SPH_C32(0x05b7ad5a), + SPH_C32(0xadf2c730), SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), + SPH_C32(0x6fc548e1), SPH_C32(0x898d2cd6) } +}; + +static const sph_u32 T256_12[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xa7b80200), SPH_C32(0x1f128433), SPH_C32(0x60e5f9f2), + SPH_C32(0x9e147576), SPH_C32(0xee260000), SPH_C32(0x124b683e), + SPH_C32(0x80c2d68f), SPH_C32(0x3bf3ab2c) }, + { SPH_C32(0xee260000), SPH_C32(0x124b683e), SPH_C32(0x80c2d68f), + SPH_C32(0x3bf3ab2c), SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), + SPH_C32(0xe0272f7d), SPH_C32(0xa5e7de5a) }, + { SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), SPH_C32(0xe0272f7d), + SPH_C32(0xa5e7de5a), SPH_C32(0xa7b80200), SPH_C32(0x1f128433), + SPH_C32(0x60e5f9f2), SPH_C32(0x9e147576) } +}; + +static const sph_u32 T256_14[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), SPH_C32(0x8589d8ab), + SPH_C32(0xe6c46464), SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), + SPH_C32(0xa29d1297), SPH_C32(0x6ee56854) }, + { SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), SPH_C32(0xa29d1297), + SPH_C32(0x6ee56854), SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), + SPH_C32(0x2714ca3c), SPH_C32(0x88210c30) }, + { SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), SPH_C32(0x2714ca3c), + SPH_C32(0x88210c30), SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), + SPH_C32(0x8589d8ab), SPH_C32(0xe6c46464) } +}; + +static const sph_u32 T256_16[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), SPH_C32(0xc2c46c55), + SPH_C32(0xf362b233), SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), + SPH_C32(0xd14e094b), SPH_C32(0xb772b42b) }, + { SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), SPH_C32(0xd14e094b), + SPH_C32(0xb772b42b), SPH_C32(0x62740080), SPH_C32(0x0fb84b07), + SPH_C32(0x138a651e), SPH_C32(0x44100618) }, + { SPH_C32(0x62740080), SPH_C32(0x0fb84b07), SPH_C32(0x138a651e), + SPH_C32(0x44100618), SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), + SPH_C32(0xc2c46c55), SPH_C32(0xf362b233) } +}; + +static const sph_u32 T256_18[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), SPH_C32(0x36656ba8), + SPH_C32(0x23633a05), SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), + SPH_C32(0x5d5ca0f7), SPH_C32(0x727784cb) }, + { SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), SPH_C32(0x5d5ca0f7), + SPH_C32(0x727784cb), SPH_C32(0x35650040), SPH_C32(0x9b96b64a), + SPH_C32(0x6b39cb5f), SPH_C32(0x5114bece) }, + { SPH_C32(0x35650040), SPH_C32(0x9b96b64a), SPH_C32(0x6b39cb5f), + SPH_C32(0x5114bece), SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), + SPH_C32(0x36656ba8), SPH_C32(0x23633a05) } +}; + +static const sph_u32 T256_20[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), SPH_C32(0xf9ce4c04), + SPH_C32(0xe2afa0c0), SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), + SPH_C32(0x79a90df9), SPH_C32(0x63e92178) }, + { SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), SPH_C32(0x79a90df9), + SPH_C32(0x63e92178), SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), + SPH_C32(0x806741fd), SPH_C32(0x814681b8) }, + { SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), SPH_C32(0x806741fd), + SPH_C32(0x814681b8), SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), + SPH_C32(0xf9ce4c04), SPH_C32(0xe2afa0c0) } +}; + +static const sph_u32 T256_22[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x515c0010), SPH_C32(0x40f372fb), SPH_C32(0xfce72602), + SPH_C32(0x71575061), SPH_C32(0x2e390000), SPH_C32(0x64dd6689), + SPH_C32(0x3cd406fc), SPH_C32(0xb1f490bc) }, + { SPH_C32(0x2e390000), SPH_C32(0x64dd6689), SPH_C32(0x3cd406fc), + SPH_C32(0xb1f490bc), SPH_C32(0x7f650010), SPH_C32(0x242e1472), + SPH_C32(0xc03320fe), SPH_C32(0xc0a3c0dd) }, + { SPH_C32(0x7f650010), SPH_C32(0x242e1472), SPH_C32(0xc03320fe), + SPH_C32(0xc0a3c0dd), SPH_C32(0x515c0010), SPH_C32(0x40f372fb), + SPH_C32(0xfce72602), SPH_C32(0x71575061) } +}; + +static const sph_u32 T256_24[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), SPH_C32(0xfe739301), + SPH_C32(0xb8a92831), SPH_C32(0x171c0000), SPH_C32(0xb26e3344), + SPH_C32(0x9e6a837e), SPH_C32(0x58f8485f) }, + { SPH_C32(0x171c0000), SPH_C32(0xb26e3344), SPH_C32(0x9e6a837e), + SPH_C32(0x58f8485f), SPH_C32(0xbfb20008), SPH_C32(0x92170a39), + SPH_C32(0x6019107f), SPH_C32(0xe051606e) }, + { SPH_C32(0xbfb20008), SPH_C32(0x92170a39), SPH_C32(0x6019107f), + SPH_C32(0xe051606e), SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), + SPH_C32(0xfe739301), SPH_C32(0xb8a92831) } +}; + +static const sph_u32 T256_26[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xd0080004), SPH_C32(0x8c768f77), SPH_C32(0x9dc5b050), + SPH_C32(0xaf4a29da), SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), + SPH_C32(0x98321c3d), SPH_C32(0x76acc733) }, + { SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), SPH_C32(0x98321c3d), + SPH_C32(0x76acc733), SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), + SPH_C32(0x05f7ac6d), SPH_C32(0xd9e6eee9) }, + { SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), SPH_C32(0x05f7ac6d), + SPH_C32(0xd9e6eee9), SPH_C32(0xd0080004), SPH_C32(0x8c768f77), + SPH_C32(0x9dc5b050), SPH_C32(0xaf4a29da) } +}; + +static const sph_u32 T256_28[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), SPH_C32(0x99e585aa), + SPH_C32(0x8d75f7f1), SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), + SPH_C32(0x79e22a4c), SPH_C32(0x1298bd46) }, + { SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), SPH_C32(0x79e22a4c), + SPH_C32(0x1298bd46), SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), + SPH_C32(0xe007afe6), SPH_C32(0x9fed4ab7) }, + { SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), SPH_C32(0xe007afe6), + SPH_C32(0x9fed4ab7), SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), + SPH_C32(0x99e585aa), SPH_C32(0x8d75f7f1) } +}; + +static const sph_u32 T256_30[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), SPH_C32(0xae0ebb05), + SPH_C32(0xb5a4c63b), SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), + SPH_C32(0x6bf648a4), SPH_C32(0x539cbdbf) }, + { SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), SPH_C32(0x6bf648a4), + SPH_C32(0x539cbdbf), SPH_C32(0x08bf0001), SPH_C32(0x38942792), + SPH_C32(0xc5f8f3a1), SPH_C32(0xe6387b84) }, + { SPH_C32(0x08bf0001), SPH_C32(0x38942792), SPH_C32(0xc5f8f3a1), + SPH_C32(0xe6387b84), SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), + SPH_C32(0xae0ebb05), SPH_C32(0xb5a4c63b) } +}; + +#define INPUT_SMALL do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T256_0[acc >> 6][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + rp = &T256_2[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_4[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_6[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[1]; \ + rp = &T256_8[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_10[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_12[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_14[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[2]; \ + rp = &T256_16[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_18[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_20[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_22[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[3]; \ + rp = &T256_24[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_26[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_28[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_30[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_SMALL == 3 + +static const sph_u32 T256_0[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), SPH_C32(0x848598ba), + SPH_C32(0x1041003e), SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), + SPH_C32(0x097f5711), SPH_C32(0xde77cc4c) }, + { SPH_C32(0xe4788000), SPH_C32(0x859673c1), SPH_C32(0xb5fb2452), + SPH_C32(0x29cc5edf), SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), + SPH_C32(0x62fc79d0), SPH_C32(0x731ebdc2) }, + { SPH_C32(0x022f8000), SPH_C32(0xce2549e4), SPH_C32(0x317ebce8), + SPH_C32(0x398d5ee1), SPH_C32(0xf0134000), SPH_C32(0x8cee7004), + SPH_C32(0x6b832ec1), SPH_C32(0xad69718e) }, + { SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), SPH_C32(0x62fc79d0), + SPH_C32(0x731ebdc2), SPH_C32(0xe0278000), SPH_C32(0x19dce008), + SPH_C32(0xd7075d82), SPH_C32(0x5ad2e31d) }, + { SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), SPH_C32(0xe679e16a), + SPH_C32(0x635fbdfc), SPH_C32(0x146bc000), SPH_C32(0x097803c5), + SPH_C32(0xde780a93), SPH_C32(0x84a52f51) }, + { SPH_C32(0xe0278000), SPH_C32(0x19dce008), SPH_C32(0xd7075d82), + SPH_C32(0x5ad2e31d), SPH_C32(0xe4788000), SPH_C32(0x859673c1), + SPH_C32(0xb5fb2452), SPH_C32(0x29cc5edf) }, + { SPH_C32(0x06708000), SPH_C32(0x526fda2d), SPH_C32(0x5382c538), + SPH_C32(0x4a93e323), SPH_C32(0x1034c000), SPH_C32(0x9532900c), + SPH_C32(0xbc847343), SPH_C32(0xf7bb9293) } +}; + +static const sph_u32 T256_3[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), SPH_C32(0x11fa3a57), + SPH_C32(0x3dc90524), SPH_C32(0x97530000), SPH_C32(0x204f6ed3), + SPH_C32(0x77b9e80f), SPH_C32(0xa1ec5ec1) }, + { SPH_C32(0x97530000), SPH_C32(0x204f6ed3), SPH_C32(0x77b9e80f), + SPH_C32(0xa1ec5ec1), SPH_C32(0x7e792000), SPH_C32(0x9418e22f), + SPH_C32(0x6643d258), SPH_C32(0x9c255be5) }, + { SPH_C32(0x7e792000), SPH_C32(0x9418e22f), SPH_C32(0x6643d258), + SPH_C32(0x9c255be5), SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), + SPH_C32(0x11fa3a57), SPH_C32(0x3dc90524) }, + { SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), SPH_C32(0x8dfacfab), + SPH_C32(0xce36cc72), SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), + SPH_C32(0x848598ba), SPH_C32(0x1041003e) }, + { SPH_C32(0xfb316000), SPH_C32(0xef405514), SPH_C32(0x9c00f5fc), + SPH_C32(0xf3ffc956), SPH_C32(0x71040000), SPH_C32(0x6bfc54f6), + SPH_C32(0xf33c70b5), SPH_C32(0xb1ad5eff) }, + { SPH_C32(0x85484000), SPH_C32(0x7b58b73b), SPH_C32(0xfa4327a4), + SPH_C32(0x6fda92b3), SPH_C32(0x982e2000), SPH_C32(0xdfabd80a), + SPH_C32(0xe2c64ae2), SPH_C32(0x8c645bdb) }, + { SPH_C32(0x6c626000), SPH_C32(0xcf0f3bc7), SPH_C32(0xebb91df3), + SPH_C32(0x52139797), SPH_C32(0x0f7d2000), SPH_C32(0xffe4b6d9), + SPH_C32(0x957fa2ed), SPH_C32(0x2d88051a) } +}; + +static const sph_u32 T256_6[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xe18b0000), SPH_C32(0x5459887d), SPH_C32(0xbf1283d3), + SPH_C32(0x1b666a73), SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), + SPH_C32(0xce97a914), SPH_C32(0xbdd9f5e5) }, + { SPH_C32(0x74951000), SPH_C32(0x5a2b467e), SPH_C32(0x88fd1d2b), + SPH_C32(0x1ee68292), SPH_C32(0xcba90000), SPH_C32(0x90273769), + SPH_C32(0xbbdcf407), SPH_C32(0xd0f4af61) }, + { SPH_C32(0x951e1000), SPH_C32(0x0e72ce03), SPH_C32(0x37ef9ef8), + SPH_C32(0x0580e8e1), SPH_C32(0xf4100800), SPH_C32(0xecfdefea), + SPH_C32(0x754b5d13), SPH_C32(0x6d2d5a84) }, + { SPH_C32(0xcba90000), SPH_C32(0x90273769), SPH_C32(0xbbdcf407), + SPH_C32(0xd0f4af61), SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), + SPH_C32(0x3321e92c), SPH_C32(0xce122df3) }, + { SPH_C32(0x2a220000), SPH_C32(0xc47ebf14), SPH_C32(0x04ce77d4), + SPH_C32(0xcb92c512), SPH_C32(0x80851800), SPH_C32(0xb6d6a994), + SPH_C32(0xfdb64038), SPH_C32(0x73cbd816) }, + { SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), SPH_C32(0x3321e92c), + SPH_C32(0xce122df3), SPH_C32(0x74951000), SPH_C32(0x5a2b467e), + SPH_C32(0x88fd1d2b), SPH_C32(0x1ee68292) }, + { SPH_C32(0x5eb71000), SPH_C32(0x9e55f96a), SPH_C32(0x8c336aff), + SPH_C32(0xd5744780), SPH_C32(0x4b2c1800), SPH_C32(0x26f19efd), + SPH_C32(0x466ab43f), SPH_C32(0xa33f7777) } +}; + +static const sph_u32 T256_9[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), SPH_C32(0x6fc548e1), + SPH_C32(0x898d2cd6), SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), + SPH_C32(0x6a72e5bb), SPH_C32(0x247febe6) }, + { SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), SPH_C32(0x6a72e5bb), + SPH_C32(0x247febe6), SPH_C32(0x9b830400), SPH_C32(0x2227ff88), + SPH_C32(0x05b7ad5a), SPH_C32(0xadf2c730) }, + { SPH_C32(0x9b830400), SPH_C32(0x2227ff88), SPH_C32(0x05b7ad5a), + SPH_C32(0xadf2c730), SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), + SPH_C32(0x6fc548e1), SPH_C32(0x898d2cd6) }, + { SPH_C32(0xde320800), SPH_C32(0x288350fe), SPH_C32(0x71852ac7), + SPH_C32(0xa6bf9f96), SPH_C32(0xe18b0000), SPH_C32(0x5459887d), + SPH_C32(0xbf1283d3), SPH_C32(0x1b666a73) }, + { SPH_C32(0x510c0c00), SPH_C32(0x251e9889), SPH_C32(0x1e406226), + SPH_C32(0x2f32b340), SPH_C32(0xf5360000), SPH_C32(0x7be3bf82), + SPH_C32(0xd5606668), SPH_C32(0x3f198195) }, + { SPH_C32(0xca8f0800), SPH_C32(0x07396701), SPH_C32(0x1bf7cf7c), + SPH_C32(0x82c07470), SPH_C32(0x7a080400), SPH_C32(0x767e77f5), + SPH_C32(0xbaa52e89), SPH_C32(0xb694ad43) }, + { SPH_C32(0x45b10c00), SPH_C32(0x0aa4af76), SPH_C32(0x7432879d), + SPH_C32(0x0b4d58a6), SPH_C32(0x6eb50400), SPH_C32(0x59c4400a), + SPH_C32(0xd0d7cb32), SPH_C32(0x92eb46a5) } +}; + +static const sph_u32 T256_12[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), SPH_C32(0xa29d1297), + SPH_C32(0x6ee56854), SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), + SPH_C32(0x2714ca3c), SPH_C32(0x88210c30) }, + { SPH_C32(0xa7b80200), SPH_C32(0x1f128433), SPH_C32(0x60e5f9f2), + SPH_C32(0x9e147576), SPH_C32(0xee260000), SPH_C32(0x124b683e), + SPH_C32(0x80c2d68f), SPH_C32(0x3bf3ab2c) }, + { SPH_C32(0xd4f40200), SPH_C32(0x8a7d23e5), SPH_C32(0xc278eb65), + SPH_C32(0xf0f11d22), SPH_C32(0x2ace0100), SPH_C32(0x0d3bfe30), + SPH_C32(0xa7d61cb3), SPH_C32(0xb3d2a71c) }, + { SPH_C32(0xee260000), SPH_C32(0x124b683e), SPH_C32(0x80c2d68f), + SPH_C32(0x3bf3ab2c), SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), + SPH_C32(0xe0272f7d), SPH_C32(0xa5e7de5a) }, + { SPH_C32(0x9d6a0000), SPH_C32(0x8724cfe8), SPH_C32(0x225fc418), + SPH_C32(0x5516c378), SPH_C32(0x8d760300), SPH_C32(0x12297a03), + SPH_C32(0xc733e541), SPH_C32(0x2dc6d26a) }, + { SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), SPH_C32(0xe0272f7d), + SPH_C32(0xa5e7de5a), SPH_C32(0xa7b80200), SPH_C32(0x1f128433), + SPH_C32(0x60e5f9f2), SPH_C32(0x9e147576) }, + { SPH_C32(0x3ad20200), SPH_C32(0x98364bdb), SPH_C32(0x42ba3dea), + SPH_C32(0xcb02b60e), SPH_C32(0x63500300), SPH_C32(0x0062123d), + SPH_C32(0x47f133ce), SPH_C32(0x16357946) } +}; + +static const sph_u32 T256_15[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), SPH_C32(0xc2c46c55), + SPH_C32(0xf362b233), SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), + SPH_C32(0xd14e094b), SPH_C32(0xb772b42b) }, + { SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), SPH_C32(0xd14e094b), + SPH_C32(0xb772b42b), SPH_C32(0x62740080), SPH_C32(0x0fb84b07), + SPH_C32(0x138a651e), SPH_C32(0x44100618) }, + { SPH_C32(0x62740080), SPH_C32(0x0fb84b07), SPH_C32(0x138a651e), + SPH_C32(0x44100618), SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), + SPH_C32(0xc2c46c55), SPH_C32(0xf362b233) }, + { SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), SPH_C32(0x8589d8ab), + SPH_C32(0xe6c46464), SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), + SPH_C32(0xa29d1297), SPH_C32(0x6ee56854) }, + { SPH_C32(0xec760180), SPH_C32(0xcf102934), SPH_C32(0x474db4fe), + SPH_C32(0x15a6d657), SPH_C32(0x4aea0000), SPH_C32(0xdfd8f43d), + SPH_C32(0x73d31bdc), SPH_C32(0xd997dc7f) }, + { SPH_C32(0x8e020100), SPH_C32(0xc0a86233), SPH_C32(0x54c7d1e0), + SPH_C32(0x51b6d04f), SPH_C32(0x11380080), SPH_C32(0x9ad7ecd1), + SPH_C32(0xb1177789), SPH_C32(0x2af56e4c) }, + { SPH_C32(0xd5d00180), SPH_C32(0x85a77adf), SPH_C32(0x9603bdb5), + SPH_C32(0xa2d4627c), SPH_C32(0x289e0080), SPH_C32(0xd060bf3a), + SPH_C32(0x60597ec2), SPH_C32(0x9d87da67) } +}; + +static const sph_u32 T256_18[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), SPH_C32(0x79a90df9), + SPH_C32(0x63e92178), SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), + SPH_C32(0x806741fd), SPH_C32(0x814681b8) }, + { SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), SPH_C32(0x36656ba8), + SPH_C32(0x23633a05), SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), + SPH_C32(0x5d5ca0f7), SPH_C32(0x727784cb) }, + { SPH_C32(0x11bc0040), SPH_C32(0xf2e1216c), SPH_C32(0x4fcc6651), + SPH_C32(0x408a1b7d), SPH_C32(0x86610020), SPH_C32(0xe89072d0), + SPH_C32(0xdd3be10a), SPH_C32(0xf3310573) }, + { SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), SPH_C32(0x5d5ca0f7), + SPH_C32(0x727784cb), SPH_C32(0x35650040), SPH_C32(0x9b96b64a), + SPH_C32(0x6b39cb5f), SPH_C32(0x5114bece) }, + { SPH_C32(0x24d90000), SPH_C32(0x69779726), SPH_C32(0x24f5ad0e), + SPH_C32(0x119ea5b3), SPH_C32(0xcbaf0060), SPH_C32(0xd3cb9eae), + SPH_C32(0xeb5e8aa2), SPH_C32(0xd0523f76) }, + { SPH_C32(0x35650040), SPH_C32(0x9b96b64a), SPH_C32(0x6b39cb5f), + SPH_C32(0x5114bece), SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), + SPH_C32(0x36656ba8), SPH_C32(0x23633a05) }, + { SPH_C32(0x69170040), SPH_C32(0x522c7b58), SPH_C32(0x1290c6a6), + SPH_C32(0x32fd9fb6), SPH_C32(0xb3040060), SPH_C32(0x7306c49a), + SPH_C32(0xb6022a55), SPH_C32(0xa225bbbd) } +}; + +static const sph_u32 T256_21[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x515c0010), SPH_C32(0x40f372fb), SPH_C32(0xfce72602), + SPH_C32(0x71575061), SPH_C32(0x2e390000), SPH_C32(0x64dd6689), + SPH_C32(0x3cd406fc), SPH_C32(0xb1f490bc) }, + { SPH_C32(0x2e390000), SPH_C32(0x64dd6689), SPH_C32(0x3cd406fc), + SPH_C32(0xb1f490bc), SPH_C32(0x7f650010), SPH_C32(0x242e1472), + SPH_C32(0xc03320fe), SPH_C32(0xc0a3c0dd) }, + { SPH_C32(0x7f650010), SPH_C32(0x242e1472), SPH_C32(0xc03320fe), + SPH_C32(0xc0a3c0dd), SPH_C32(0x515c0010), SPH_C32(0x40f372fb), + SPH_C32(0xfce72602), SPH_C32(0x71575061) }, + { SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), SPH_C32(0xf9ce4c04), + SPH_C32(0xe2afa0c0), SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), + SPH_C32(0x79a90df9), SPH_C32(0x63e92178) }, + { SPH_C32(0xf3e40030), SPH_C32(0xc114970d), SPH_C32(0x05296a06), + SPH_C32(0x93f8f0a1), SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), + SPH_C32(0x457d0b05), SPH_C32(0xd21db1c4) }, + { SPH_C32(0x8c810020), SPH_C32(0xe53a837f), SPH_C32(0xc51a4af8), + SPH_C32(0x535b307c), SPH_C32(0x23170010), SPH_C32(0xed94d960), + SPH_C32(0xb99a2d07), SPH_C32(0xa34ae1a5) }, + { SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), SPH_C32(0x39fd6cfa), + SPH_C32(0x220c601d), SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), + SPH_C32(0x854e2bfb), SPH_C32(0x12be7119) } +}; + +static const sph_u32 T256_24[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), SPH_C32(0x98321c3d), + SPH_C32(0x76acc733), SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), + SPH_C32(0x05f7ac6d), SPH_C32(0xd9e6eee9) }, + { SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), SPH_C32(0xfe739301), + SPH_C32(0xb8a92831), SPH_C32(0x171c0000), SPH_C32(0xb26e3344), + SPH_C32(0x9e6a837e), SPH_C32(0x58f8485f) }, + { SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), SPH_C32(0x66418f3c), + SPH_C32(0xce05ef02), SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), + SPH_C32(0x9b9d2f13), SPH_C32(0x811ea6b6) }, + { SPH_C32(0x171c0000), SPH_C32(0xb26e3344), SPH_C32(0x9e6a837e), + SPH_C32(0x58f8485f), SPH_C32(0xbfb20008), SPH_C32(0x92170a39), + SPH_C32(0x6019107f), SPH_C32(0xe051606e) }, + { SPH_C32(0x7cb50000), SPH_C32(0xf285caee), SPH_C32(0x06589f43), + SPH_C32(0x2e548f6c), SPH_C32(0x0413000c), SPH_C32(0x5e8a7ce4), + SPH_C32(0x65eebc12), SPH_C32(0x39b78e87) }, + { SPH_C32(0xbfb20008), SPH_C32(0x92170a39), SPH_C32(0x6019107f), + SPH_C32(0xe051606e), SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), + SPH_C32(0xfe739301), SPH_C32(0xb8a92831) }, + { SPH_C32(0xd41b0008), SPH_C32(0xd2fcf393), SPH_C32(0xf82b0c42), + SPH_C32(0x96fda75d), SPH_C32(0x130f000c), SPH_C32(0xece44fa0), + SPH_C32(0xfb843f6c), SPH_C32(0x614fc6d8) } +}; + +static const sph_u32 T256_27[8][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), SPH_C32(0x99e585aa), + SPH_C32(0x8d75f7f1), SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), + SPH_C32(0x79e22a4c), SPH_C32(0x1298bd46) }, + { SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), SPH_C32(0x79e22a4c), + SPH_C32(0x1298bd46), SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), + SPH_C32(0xe007afe6), SPH_C32(0x9fed4ab7) }, + { SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), SPH_C32(0xe007afe6), + SPH_C32(0x9fed4ab7), SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), + SPH_C32(0x99e585aa), SPH_C32(0x8d75f7f1) }, + { SPH_C32(0xd0080004), SPH_C32(0x8c768f77), SPH_C32(0x9dc5b050), + SPH_C32(0xaf4a29da), SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), + SPH_C32(0x98321c3d), SPH_C32(0x76acc733) }, + { SPH_C32(0x582b0006), SPH_C32(0xd39128c4), SPH_C32(0x042035fa), + SPH_C32(0x223fde2b), SPH_C32(0x3a050000), SPH_C32(0x6508f6be), + SPH_C32(0xe1d03671), SPH_C32(0x64347a75) }, + { SPH_C32(0x81a40004), SPH_C32(0xa9958063), SPH_C32(0xe4279a1c), + SPH_C32(0xbdd2949c), SPH_C32(0xb2260002), SPH_C32(0x3aef510d), + SPH_C32(0x7835b3db), SPH_C32(0xe9418d84) }, + { SPH_C32(0x09870006), SPH_C32(0xf67227d0), SPH_C32(0x7dc21fb6), + SPH_C32(0x30a7636d), SPH_C32(0xe38a0002), SPH_C32(0x1f0c5e19), + SPH_C32(0x01d79997), SPH_C32(0xfbd930c2) } +}; + +static const sph_u32 T256_30[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), SPH_C32(0xae0ebb05), + SPH_C32(0xb5a4c63b), SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), + SPH_C32(0x6bf648a4), SPH_C32(0x539cbdbf) }, + { SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), SPH_C32(0x6bf648a4), + SPH_C32(0x539cbdbf), SPH_C32(0x08bf0001), SPH_C32(0x38942792), + SPH_C32(0xc5f8f3a1), SPH_C32(0xe6387b84) }, + { SPH_C32(0x08bf0001), SPH_C32(0x38942792), SPH_C32(0xc5f8f3a1), + SPH_C32(0xe6387b84), SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), + SPH_C32(0xae0ebb05), SPH_C32(0xb5a4c63b) } +}; + +#define INPUT_SMALL do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T256_0[acc >> 5][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + rp = &T256_3[(acc >> 2) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = (acc << 8) | buf[1]; \ + rp = &T256_6[(acc >> 7) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_9[(acc >> 4) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_12[(acc >> 1) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = (acc << 8) | buf[2]; \ + rp = &T256_15[(acc >> 6) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_18[(acc >> 3) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_21[acc & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[3]; \ + rp = &T256_24[acc >> 5][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_27[(acc >> 2) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_30[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_SMALL == 4 + +static const sph_u32 T256_0[16][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), SPH_C32(0x8dfacfab), + SPH_C32(0xce36cc72), SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), + SPH_C32(0x848598ba), SPH_C32(0x1041003e) }, + { SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), SPH_C32(0x848598ba), + SPH_C32(0x1041003e), SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), + SPH_C32(0x097f5711), SPH_C32(0xde77cc4c) }, + { SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), SPH_C32(0x097f5711), + SPH_C32(0xde77cc4c), SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), + SPH_C32(0x8dfacfab), SPH_C32(0xce36cc72) }, + { SPH_C32(0xe4788000), SPH_C32(0x859673c1), SPH_C32(0xb5fb2452), + SPH_C32(0x29cc5edf), SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), + SPH_C32(0x62fc79d0), SPH_C32(0x731ebdc2) }, + { SPH_C32(0xf663c000), SPH_C32(0xde81aa29), SPH_C32(0x3801ebf9), + SPH_C32(0xe7fa92ad), SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), + SPH_C32(0xe679e16a), SPH_C32(0x635fbdfc) }, + { SPH_C32(0x022f8000), SPH_C32(0xce2549e4), SPH_C32(0x317ebce8), + SPH_C32(0x398d5ee1), SPH_C32(0xf0134000), SPH_C32(0x8cee7004), + SPH_C32(0x6b832ec1), SPH_C32(0xad69718e) }, + { SPH_C32(0x1034c000), SPH_C32(0x9532900c), SPH_C32(0xbc847343), + SPH_C32(0xf7bb9293), SPH_C32(0x16444000), SPH_C32(0xc75d4a21), + SPH_C32(0xef06b67b), SPH_C32(0xbd2871b0) }, + { SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), SPH_C32(0x62fc79d0), + SPH_C32(0x731ebdc2), SPH_C32(0xe0278000), SPH_C32(0x19dce008), + SPH_C32(0xd7075d82), SPH_C32(0x5ad2e31d) }, + { SPH_C32(0x16444000), SPH_C32(0xc75d4a21), SPH_C32(0xef06b67b), + SPH_C32(0xbd2871b0), SPH_C32(0x06708000), SPH_C32(0x526fda2d), + SPH_C32(0x5382c538), SPH_C32(0x4a93e323) }, + { SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), SPH_C32(0xe679e16a), + SPH_C32(0x635fbdfc), SPH_C32(0x146bc000), SPH_C32(0x097803c5), + SPH_C32(0xde780a93), SPH_C32(0x84a52f51) }, + { SPH_C32(0xf0134000), SPH_C32(0x8cee7004), SPH_C32(0x6b832ec1), + SPH_C32(0xad69718e), SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), + SPH_C32(0x5afd9229), SPH_C32(0x94e42f6f) }, + { SPH_C32(0xe0278000), SPH_C32(0x19dce008), SPH_C32(0xd7075d82), + SPH_C32(0x5ad2e31d), SPH_C32(0xe4788000), SPH_C32(0x859673c1), + SPH_C32(0xb5fb2452), SPH_C32(0x29cc5edf) }, + { SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), SPH_C32(0x5afd9229), + SPH_C32(0x94e42f6f), SPH_C32(0x022f8000), SPH_C32(0xce2549e4), + SPH_C32(0x317ebce8), SPH_C32(0x398d5ee1) }, + { SPH_C32(0x06708000), SPH_C32(0x526fda2d), SPH_C32(0x5382c538), + SPH_C32(0x4a93e323), SPH_C32(0x1034c000), SPH_C32(0x9532900c), + SPH_C32(0xbc847343), SPH_C32(0xf7bb9293) }, + { SPH_C32(0x146bc000), SPH_C32(0x097803c5), SPH_C32(0xde780a93), + SPH_C32(0x84a52f51), SPH_C32(0xf663c000), SPH_C32(0xde81aa29), + SPH_C32(0x3801ebf9), SPH_C32(0xe7fa92ad) } +}; + +static const sph_u32 T256_4[16][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x74951000), SPH_C32(0x5a2b467e), SPH_C32(0x88fd1d2b), + SPH_C32(0x1ee68292), SPH_C32(0xcba90000), SPH_C32(0x90273769), + SPH_C32(0xbbdcf407), SPH_C32(0xd0f4af61) }, + { SPH_C32(0xcba90000), SPH_C32(0x90273769), SPH_C32(0xbbdcf407), + SPH_C32(0xd0f4af61), SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), + SPH_C32(0x3321e92c), SPH_C32(0xce122df3) }, + { SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), SPH_C32(0x3321e92c), + SPH_C32(0xce122df3), SPH_C32(0x74951000), SPH_C32(0x5a2b467e), + SPH_C32(0x88fd1d2b), SPH_C32(0x1ee68292) }, + { SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), SPH_C32(0x11fa3a57), + SPH_C32(0x3dc90524), SPH_C32(0x97530000), SPH_C32(0x204f6ed3), + SPH_C32(0x77b9e80f), SPH_C32(0xa1ec5ec1) }, + { SPH_C32(0x9dbf3000), SPH_C32(0xee7cca82), SPH_C32(0x9907277c), + SPH_C32(0x232f87b6), SPH_C32(0x5cfa0000), SPH_C32(0xb06859ba), + SPH_C32(0xcc651c08), SPH_C32(0x7118f1a0) }, + { SPH_C32(0x22832000), SPH_C32(0x2470bb95), SPH_C32(0xaa26ce50), + SPH_C32(0xed3daa45), SPH_C32(0x286f1000), SPH_C32(0xea431fc4), + SPH_C32(0x44980123), SPH_C32(0x6ffe7332) }, + { SPH_C32(0x56163000), SPH_C32(0x7e5bfdeb), SPH_C32(0x22dbd37b), + SPH_C32(0xf3db28d7), SPH_C32(0xe3c61000), SPH_C32(0x7a6428ad), + SPH_C32(0xff44f524), SPH_C32(0xbf0adc53) }, + { SPH_C32(0x97530000), SPH_C32(0x204f6ed3), SPH_C32(0x77b9e80f), + SPH_C32(0xa1ec5ec1), SPH_C32(0x7e792000), SPH_C32(0x9418e22f), + SPH_C32(0x6643d258), SPH_C32(0x9c255be5) }, + { SPH_C32(0xe3c61000), SPH_C32(0x7a6428ad), SPH_C32(0xff44f524), + SPH_C32(0xbf0adc53), SPH_C32(0xb5d02000), SPH_C32(0x043fd546), + SPH_C32(0xdd9f265f), SPH_C32(0x4cd1f484) }, + { SPH_C32(0x5cfa0000), SPH_C32(0xb06859ba), SPH_C32(0xcc651c08), + SPH_C32(0x7118f1a0), SPH_C32(0xc1453000), SPH_C32(0x5e149338), + SPH_C32(0x55623b74), SPH_C32(0x52377616) }, + { SPH_C32(0x286f1000), SPH_C32(0xea431fc4), SPH_C32(0x44980123), + SPH_C32(0x6ffe7332), SPH_C32(0x0aec3000), SPH_C32(0xce33a451), + SPH_C32(0xeebecf73), SPH_C32(0x82c3d977) }, + { SPH_C32(0x7e792000), SPH_C32(0x9418e22f), SPH_C32(0x6643d258), + SPH_C32(0x9c255be5), SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), + SPH_C32(0x11fa3a57), SPH_C32(0x3dc90524) }, + { SPH_C32(0x0aec3000), SPH_C32(0xce33a451), SPH_C32(0xeebecf73), + SPH_C32(0x82c3d977), SPH_C32(0x22832000), SPH_C32(0x2470bb95), + SPH_C32(0xaa26ce50), SPH_C32(0xed3daa45) }, + { SPH_C32(0xb5d02000), SPH_C32(0x043fd546), SPH_C32(0xdd9f265f), + SPH_C32(0x4cd1f484), SPH_C32(0x56163000), SPH_C32(0x7e5bfdeb), + SPH_C32(0x22dbd37b), SPH_C32(0xf3db28d7) }, + { SPH_C32(0xc1453000), SPH_C32(0x5e149338), SPH_C32(0x55623b74), + SPH_C32(0x52377616), SPH_C32(0x9dbf3000), SPH_C32(0xee7cca82), + SPH_C32(0x9907277c), SPH_C32(0x232f87b6) } +}; + +static const sph_u32 T256_8[16][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), SPH_C32(0x6fc548e1), + SPH_C32(0x898d2cd6), SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), + SPH_C32(0x6a72e5bb), SPH_C32(0x247febe6) }, + { SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), SPH_C32(0x6a72e5bb), + SPH_C32(0x247febe6), SPH_C32(0x9b830400), SPH_C32(0x2227ff88), + SPH_C32(0x05b7ad5a), SPH_C32(0xadf2c730) }, + { SPH_C32(0x9b830400), SPH_C32(0x2227ff88), SPH_C32(0x05b7ad5a), + SPH_C32(0xadf2c730), SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), + SPH_C32(0x6fc548e1), SPH_C32(0x898d2cd6) }, + { SPH_C32(0xde320800), SPH_C32(0x288350fe), SPH_C32(0x71852ac7), + SPH_C32(0xa6bf9f96), SPH_C32(0xe18b0000), SPH_C32(0x5459887d), + SPH_C32(0xbf1283d3), SPH_C32(0x1b666a73) }, + { SPH_C32(0x510c0c00), SPH_C32(0x251e9889), SPH_C32(0x1e406226), + SPH_C32(0x2f32b340), SPH_C32(0xf5360000), SPH_C32(0x7be3bf82), + SPH_C32(0xd5606668), SPH_C32(0x3f198195) }, + { SPH_C32(0xca8f0800), SPH_C32(0x07396701), SPH_C32(0x1bf7cf7c), + SPH_C32(0x82c07470), SPH_C32(0x7a080400), SPH_C32(0x767e77f5), + SPH_C32(0xbaa52e89), SPH_C32(0xb694ad43) }, + { SPH_C32(0x45b10c00), SPH_C32(0x0aa4af76), SPH_C32(0x7432879d), + SPH_C32(0x0b4d58a6), SPH_C32(0x6eb50400), SPH_C32(0x59c4400a), + SPH_C32(0xd0d7cb32), SPH_C32(0x92eb46a5) }, + { SPH_C32(0xe18b0000), SPH_C32(0x5459887d), SPH_C32(0xbf1283d3), + SPH_C32(0x1b666a73), SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), + SPH_C32(0xce97a914), SPH_C32(0xbdd9f5e5) }, + { SPH_C32(0x6eb50400), SPH_C32(0x59c4400a), SPH_C32(0xd0d7cb32), + SPH_C32(0x92eb46a5), SPH_C32(0x2b040800), SPH_C32(0x5360ef7c), + SPH_C32(0xa4e54caf), SPH_C32(0x99a61e03) }, + { SPH_C32(0xf5360000), SPH_C32(0x7be3bf82), SPH_C32(0xd5606668), + SPH_C32(0x3f198195), SPH_C32(0xa43a0c00), SPH_C32(0x5efd270b), + SPH_C32(0xcb20044e), SPH_C32(0x102b32d5) }, + { SPH_C32(0x7a080400), SPH_C32(0x767e77f5), SPH_C32(0xbaa52e89), + SPH_C32(0xb694ad43), SPH_C32(0xb0870c00), SPH_C32(0x714710f4), + SPH_C32(0xa152e1f5), SPH_C32(0x3454d933) }, + { SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), SPH_C32(0xce97a914), + SPH_C32(0xbdd9f5e5), SPH_C32(0xde320800), SPH_C32(0x288350fe), + SPH_C32(0x71852ac7), SPH_C32(0xa6bf9f96) }, + { SPH_C32(0xb0870c00), SPH_C32(0x714710f4), SPH_C32(0xa152e1f5), + SPH_C32(0x3454d933), SPH_C32(0xca8f0800), SPH_C32(0x07396701), + SPH_C32(0x1bf7cf7c), SPH_C32(0x82c07470) }, + { SPH_C32(0x2b040800), SPH_C32(0x5360ef7c), SPH_C32(0xa4e54caf), + SPH_C32(0x99a61e03), SPH_C32(0x45b10c00), SPH_C32(0x0aa4af76), + SPH_C32(0x7432879d), SPH_C32(0x0b4d58a6) }, + { SPH_C32(0xa43a0c00), SPH_C32(0x5efd270b), SPH_C32(0xcb20044e), + SPH_C32(0x102b32d5), SPH_C32(0x510c0c00), SPH_C32(0x251e9889), + SPH_C32(0x1e406226), SPH_C32(0x2f32b340) } +}; + +static const sph_u32 T256_12[16][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), SPH_C32(0x8589d8ab), + SPH_C32(0xe6c46464), SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), + SPH_C32(0xa29d1297), SPH_C32(0x6ee56854) }, + { SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), SPH_C32(0xa29d1297), + SPH_C32(0x6ee56854), SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), + SPH_C32(0x2714ca3c), SPH_C32(0x88210c30) }, + { SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), SPH_C32(0x2714ca3c), + SPH_C32(0x88210c30), SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), + SPH_C32(0x8589d8ab), SPH_C32(0xe6c46464) }, + { SPH_C32(0xa7b80200), SPH_C32(0x1f128433), SPH_C32(0x60e5f9f2), + SPH_C32(0x9e147576), SPH_C32(0xee260000), SPH_C32(0x124b683e), + SPH_C32(0x80c2d68f), SPH_C32(0x3bf3ab2c) }, + { SPH_C32(0x101c0300), SPH_C32(0x950db5eb), SPH_C32(0xe56c2159), + SPH_C32(0x78d01112), SPH_C32(0x9d6a0000), SPH_C32(0x8724cfe8), + SPH_C32(0x225fc418), SPH_C32(0x5516c378) }, + { SPH_C32(0xd4f40200), SPH_C32(0x8a7d23e5), SPH_C32(0xc278eb65), + SPH_C32(0xf0f11d22), SPH_C32(0x2ace0100), SPH_C32(0x0d3bfe30), + SPH_C32(0xa7d61cb3), SPH_C32(0xb3d2a71c) }, + { SPH_C32(0x63500300), SPH_C32(0x0062123d), SPH_C32(0x47f133ce), + SPH_C32(0x16357946), SPH_C32(0x59820100), SPH_C32(0x985459e6), + SPH_C32(0x054b0e24), SPH_C32(0xdd37cf48) }, + { SPH_C32(0xee260000), SPH_C32(0x124b683e), SPH_C32(0x80c2d68f), + SPH_C32(0x3bf3ab2c), SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), + SPH_C32(0xe0272f7d), SPH_C32(0xa5e7de5a) }, + { SPH_C32(0x59820100), SPH_C32(0x985459e6), SPH_C32(0x054b0e24), + SPH_C32(0xdd37cf48), SPH_C32(0x3ad20200), SPH_C32(0x98364bdb), + SPH_C32(0x42ba3dea), SPH_C32(0xcb02b60e) }, + { SPH_C32(0x9d6a0000), SPH_C32(0x8724cfe8), SPH_C32(0x225fc418), + SPH_C32(0x5516c378), SPH_C32(0x8d760300), SPH_C32(0x12297a03), + SPH_C32(0xc733e541), SPH_C32(0x2dc6d26a) }, + { SPH_C32(0x2ace0100), SPH_C32(0x0d3bfe30), SPH_C32(0xa7d61cb3), + SPH_C32(0xb3d2a71c), SPH_C32(0xfe3a0300), SPH_C32(0x8746ddd5), + SPH_C32(0x65aef7d6), SPH_C32(0x4323ba3e) }, + { SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), SPH_C32(0xe0272f7d), + SPH_C32(0xa5e7de5a), SPH_C32(0xa7b80200), SPH_C32(0x1f128433), + SPH_C32(0x60e5f9f2), SPH_C32(0x9e147576) }, + { SPH_C32(0xfe3a0300), SPH_C32(0x8746ddd5), SPH_C32(0x65aef7d6), + SPH_C32(0x4323ba3e), SPH_C32(0xd4f40200), SPH_C32(0x8a7d23e5), + SPH_C32(0xc278eb65), SPH_C32(0xf0f11d22) }, + { SPH_C32(0x3ad20200), SPH_C32(0x98364bdb), SPH_C32(0x42ba3dea), + SPH_C32(0xcb02b60e), SPH_C32(0x63500300), SPH_C32(0x0062123d), + SPH_C32(0x47f133ce), SPH_C32(0x16357946) }, + { SPH_C32(0x8d760300), SPH_C32(0x12297a03), SPH_C32(0xc733e541), + SPH_C32(0x2dc6d26a), SPH_C32(0x101c0300), SPH_C32(0x950db5eb), + SPH_C32(0xe56c2159), SPH_C32(0x78d01112) } +}; + +static const sph_u32 T256_16[16][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), SPH_C32(0x36656ba8), + SPH_C32(0x23633a05), SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), + SPH_C32(0x5d5ca0f7), SPH_C32(0x727784cb) }, + { SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), SPH_C32(0x5d5ca0f7), + SPH_C32(0x727784cb), SPH_C32(0x35650040), SPH_C32(0x9b96b64a), + SPH_C32(0x6b39cb5f), SPH_C32(0x5114bece) }, + { SPH_C32(0x35650040), SPH_C32(0x9b96b64a), SPH_C32(0x6b39cb5f), + SPH_C32(0x5114bece), SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), + SPH_C32(0x36656ba8), SPH_C32(0x23633a05) }, + { SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), SPH_C32(0xc2c46c55), + SPH_C32(0xf362b233), SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), + SPH_C32(0xd14e094b), SPH_C32(0xb772b42b) }, + { SPH_C32(0x161c00c0), SPH_C32(0x7e54f492), SPH_C32(0xf4a107fd), + SPH_C32(0xd0018836), SPH_C32(0x410d0000), SPH_C32(0xea7a09df), + SPH_C32(0x8c12a9bc), SPH_C32(0xc50530e0) }, + { SPH_C32(0x23790080), SPH_C32(0xe5c242d8), SPH_C32(0x9f98cca2), + SPH_C32(0x811536f8), SPH_C32(0x0cc30040), SPH_C32(0xd121e5a1), + SPH_C32(0xba77c214), SPH_C32(0xe6660ae5) }, + { SPH_C32(0x6eb700c0), SPH_C32(0xde99aea6), SPH_C32(0xa9fda70a), + SPH_C32(0xa2760cfd), SPH_C32(0x74680040), SPH_C32(0x71ecbf95), + SPH_C32(0xe72b62e3), SPH_C32(0x94118e2e) }, + { SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), SPH_C32(0xd14e094b), + SPH_C32(0xb772b42b), SPH_C32(0x62740080), SPH_C32(0x0fb84b07), + SPH_C32(0x138a651e), SPH_C32(0x44100618) }, + { SPH_C32(0x74680040), SPH_C32(0x71ecbf95), SPH_C32(0xe72b62e3), + SPH_C32(0x94118e2e), SPH_C32(0x1adf0080), SPH_C32(0xaf751133), + SPH_C32(0x4ed6c5e9), SPH_C32(0x366782d3) }, + { SPH_C32(0x410d0000), SPH_C32(0xea7a09df), SPH_C32(0x8c12a9bc), + SPH_C32(0xc50530e0), SPH_C32(0x571100c0), SPH_C32(0x942efd4d), + SPH_C32(0x78b3ae41), SPH_C32(0x1504b8d6) }, + { SPH_C32(0x0cc30040), SPH_C32(0xd121e5a1), SPH_C32(0xba77c214), + SPH_C32(0xe6660ae5), SPH_C32(0x2fba00c0), SPH_C32(0x34e3a779), + SPH_C32(0x25ef0eb6), SPH_C32(0x67733c1d) }, + { SPH_C32(0x62740080), SPH_C32(0x0fb84b07), SPH_C32(0x138a651e), + SPH_C32(0x44100618), SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), + SPH_C32(0xc2c46c55), SPH_C32(0xf362b233) }, + { SPH_C32(0x2fba00c0), SPH_C32(0x34e3a779), SPH_C32(0x25ef0eb6), + SPH_C32(0x67733c1d), SPH_C32(0x23790080), SPH_C32(0xe5c242d8), + SPH_C32(0x9f98cca2), SPH_C32(0x811536f8) }, + { SPH_C32(0x1adf0080), SPH_C32(0xaf751133), SPH_C32(0x4ed6c5e9), + SPH_C32(0x366782d3), SPH_C32(0x6eb700c0), SPH_C32(0xde99aea6), + SPH_C32(0xa9fda70a), SPH_C32(0xa2760cfd) }, + { SPH_C32(0x571100c0), SPH_C32(0x942efd4d), SPH_C32(0x78b3ae41), + SPH_C32(0x1504b8d6), SPH_C32(0x161c00c0), SPH_C32(0x7e54f492), + SPH_C32(0xf4a107fd), SPH_C32(0xd0018836) } +}; + +static const sph_u32 T256_20[16][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x515c0010), SPH_C32(0x40f372fb), SPH_C32(0xfce72602), + SPH_C32(0x71575061), SPH_C32(0x2e390000), SPH_C32(0x64dd6689), + SPH_C32(0x3cd406fc), SPH_C32(0xb1f490bc) }, + { SPH_C32(0x2e390000), SPH_C32(0x64dd6689), SPH_C32(0x3cd406fc), + SPH_C32(0xb1f490bc), SPH_C32(0x7f650010), SPH_C32(0x242e1472), + SPH_C32(0xc03320fe), SPH_C32(0xc0a3c0dd) }, + { SPH_C32(0x7f650010), SPH_C32(0x242e1472), SPH_C32(0xc03320fe), + SPH_C32(0xc0a3c0dd), SPH_C32(0x515c0010), SPH_C32(0x40f372fb), + SPH_C32(0xfce72602), SPH_C32(0x71575061) }, + { SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), SPH_C32(0xf9ce4c04), + SPH_C32(0xe2afa0c0), SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), + SPH_C32(0x79a90df9), SPH_C32(0x63e92178) }, + { SPH_C32(0xf3e40030), SPH_C32(0xc114970d), SPH_C32(0x05296a06), + SPH_C32(0x93f8f0a1), SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), + SPH_C32(0x457d0b05), SPH_C32(0xd21db1c4) }, + { SPH_C32(0x8c810020), SPH_C32(0xe53a837f), SPH_C32(0xc51a4af8), + SPH_C32(0x535b307c), SPH_C32(0x23170010), SPH_C32(0xed94d960), + SPH_C32(0xb99a2d07), SPH_C32(0xa34ae1a5) }, + { SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), SPH_C32(0x39fd6cfa), + SPH_C32(0x220c601d), SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), + SPH_C32(0x854e2bfb), SPH_C32(0x12be7119) }, + { SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), SPH_C32(0x79a90df9), + SPH_C32(0x63e92178), SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), + SPH_C32(0x806741fd), SPH_C32(0x814681b8) }, + { SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), SPH_C32(0x854e2bfb), + SPH_C32(0x12be7119), SPH_C32(0xd0f30020), SPH_C32(0x2c804e6d), + SPH_C32(0xbcb34701), SPH_C32(0x30b21104) }, + { SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), SPH_C32(0x457d0b05), + SPH_C32(0xd21db1c4), SPH_C32(0x81af0030), SPH_C32(0x6c733c96), + SPH_C32(0x40546103), SPH_C32(0x41e54165) }, + { SPH_C32(0x23170010), SPH_C32(0xed94d960), SPH_C32(0xb99a2d07), + SPH_C32(0xa34ae1a5), SPH_C32(0xaf960030), SPH_C32(0x08ae5a1f), + SPH_C32(0x7c8067ff), SPH_C32(0xf011d1d9) }, + { SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), SPH_C32(0x806741fd), + SPH_C32(0x814681b8), SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), + SPH_C32(0xf9ce4c04), SPH_C32(0xe2afa0c0) }, + { SPH_C32(0xaf960030), SPH_C32(0x08ae5a1f), SPH_C32(0x7c8067ff), + SPH_C32(0xf011d1d9), SPH_C32(0x8c810020), SPH_C32(0xe53a837f), + SPH_C32(0xc51a4af8), SPH_C32(0x535b307c) }, + { SPH_C32(0xd0f30020), SPH_C32(0x2c804e6d), SPH_C32(0xbcb34701), + SPH_C32(0x30b21104), SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), + SPH_C32(0x39fd6cfa), SPH_C32(0x220c601d) }, + { SPH_C32(0x81af0030), SPH_C32(0x6c733c96), SPH_C32(0x40546103), + SPH_C32(0x41e54165), SPH_C32(0xf3e40030), SPH_C32(0xc114970d), + SPH_C32(0x05296a06), SPH_C32(0x93f8f0a1) } +}; + +static const sph_u32 T256_24[16][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xd0080004), SPH_C32(0x8c768f77), SPH_C32(0x9dc5b050), + SPH_C32(0xaf4a29da), SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), + SPH_C32(0x98321c3d), SPH_C32(0x76acc733) }, + { SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), SPH_C32(0x98321c3d), + SPH_C32(0x76acc733), SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), + SPH_C32(0x05f7ac6d), SPH_C32(0xd9e6eee9) }, + { SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), SPH_C32(0x05f7ac6d), + SPH_C32(0xd9e6eee9), SPH_C32(0xd0080004), SPH_C32(0x8c768f77), + SPH_C32(0x9dc5b050), SPH_C32(0xaf4a29da) }, + { SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), SPH_C32(0xfe739301), + SPH_C32(0xb8a92831), SPH_C32(0x171c0000), SPH_C32(0xb26e3344), + SPH_C32(0x9e6a837e), SPH_C32(0x58f8485f) }, + { SPH_C32(0x78a6000c), SPH_C32(0xac0fb60a), SPH_C32(0x63b62351), + SPH_C32(0x17e301eb), SPH_C32(0x7cb50000), SPH_C32(0xf285caee), + SPH_C32(0x06589f43), SPH_C32(0x2e548f6c) }, + { SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), SPH_C32(0x66418f3c), + SPH_C32(0xce05ef02), SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), + SPH_C32(0x9b9d2f13), SPH_C32(0x811ea6b6) }, + { SPH_C32(0x130f000c), SPH_C32(0xece44fa0), SPH_C32(0xfb843f6c), + SPH_C32(0x614fc6d8), SPH_C32(0xc7140004), SPH_C32(0x3e18bc33), + SPH_C32(0x03af332e), SPH_C32(0xf7b26185) }, + { SPH_C32(0x171c0000), SPH_C32(0xb26e3344), SPH_C32(0x9e6a837e), + SPH_C32(0x58f8485f), SPH_C32(0xbfb20008), SPH_C32(0x92170a39), + SPH_C32(0x6019107f), SPH_C32(0xe051606e) }, + { SPH_C32(0xc7140004), SPH_C32(0x3e18bc33), SPH_C32(0x03af332e), + SPH_C32(0xf7b26185), SPH_C32(0xd41b0008), SPH_C32(0xd2fcf393), + SPH_C32(0xf82b0c42), SPH_C32(0x96fda75d) }, + { SPH_C32(0x7cb50000), SPH_C32(0xf285caee), SPH_C32(0x06589f43), + SPH_C32(0x2e548f6c), SPH_C32(0x0413000c), SPH_C32(0x5e8a7ce4), + SPH_C32(0x65eebc12), SPH_C32(0x39b78e87) }, + { SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), SPH_C32(0x9b9d2f13), + SPH_C32(0x811ea6b6), SPH_C32(0x6fba000c), SPH_C32(0x1e61854e), + SPH_C32(0xfddca02f), SPH_C32(0x4f1b49b4) }, + { SPH_C32(0xbfb20008), SPH_C32(0x92170a39), SPH_C32(0x6019107f), + SPH_C32(0xe051606e), SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), + SPH_C32(0xfe739301), SPH_C32(0xb8a92831) }, + { SPH_C32(0x6fba000c), SPH_C32(0x1e61854e), SPH_C32(0xfddca02f), + SPH_C32(0x4f1b49b4), SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), + SPH_C32(0x66418f3c), SPH_C32(0xce05ef02) }, + { SPH_C32(0xd41b0008), SPH_C32(0xd2fcf393), SPH_C32(0xf82b0c42), + SPH_C32(0x96fda75d), SPH_C32(0x130f000c), SPH_C32(0xece44fa0), + SPH_C32(0xfb843f6c), SPH_C32(0x614fc6d8) }, + { SPH_C32(0x0413000c), SPH_C32(0x5e8a7ce4), SPH_C32(0x65eebc12), + SPH_C32(0x39b78e87), SPH_C32(0x78a6000c), SPH_C32(0xac0fb60a), + SPH_C32(0x63b62351), SPH_C32(0x17e301eb) } +}; + +static const sph_u32 T256_28[16][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), SPH_C32(0xae0ebb05), + SPH_C32(0xb5a4c63b), SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), + SPH_C32(0x6bf648a4), SPH_C32(0x539cbdbf) }, + { SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), SPH_C32(0x6bf648a4), + SPH_C32(0x539cbdbf), SPH_C32(0x08bf0001), SPH_C32(0x38942792), + SPH_C32(0xc5f8f3a1), SPH_C32(0xe6387b84) }, + { SPH_C32(0x08bf0001), SPH_C32(0x38942792), SPH_C32(0xc5f8f3a1), + SPH_C32(0xe6387b84), SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), + SPH_C32(0xae0ebb05), SPH_C32(0xb5a4c63b) }, + { SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), SPH_C32(0x99e585aa), + SPH_C32(0x8d75f7f1), SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), + SPH_C32(0x79e22a4c), SPH_C32(0x1298bd46) }, + { SPH_C32(0x486d0003), SPH_C32(0x6c5e67a3), SPH_C32(0x37eb3eaf), + SPH_C32(0x38d131ca), SPH_C32(0x995d0000), SPH_C32(0x2ecee896), + SPH_C32(0x121462e8), SPH_C32(0x410400f9) }, + { SPH_C32(0x40d20002), SPH_C32(0x54ca4031), SPH_C32(0xf213cd0e), + SPH_C32(0xdee94a4e), SPH_C32(0x59130001), SPH_C32(0x1d772886), + SPH_C32(0xbc1ad9ed), SPH_C32(0xf4a0c6c2) }, + { SPH_C32(0x809c0003), SPH_C32(0x67738021), SPH_C32(0x5c1d760b), + SPH_C32(0x6b4d8c75), SPH_C32(0x91e20001), SPH_C32(0x165acf04), + SPH_C32(0xd7ec9149), SPH_C32(0xa73c7b7d) }, + { SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), SPH_C32(0x79e22a4c), + SPH_C32(0x1298bd46), SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), + SPH_C32(0xe007afe6), SPH_C32(0x9fed4ab7) }, + { SPH_C32(0x91e20001), SPH_C32(0x165acf04), SPH_C32(0xd7ec9149), + SPH_C32(0xa73c7b7d), SPH_C32(0x117e0002), SPH_C32(0x71294f25), + SPH_C32(0x8bf1e742), SPH_C32(0xcc71f708) }, + { SPH_C32(0x995d0000), SPH_C32(0x2ecee896), SPH_C32(0x121462e8), + SPH_C32(0x410400f9), SPH_C32(0xd1300003), SPH_C32(0x42908f35), + SPH_C32(0x25ff5c47), SPH_C32(0x79d53133) }, + { SPH_C32(0x59130001), SPH_C32(0x1d772886), SPH_C32(0xbc1ad9ed), + SPH_C32(0xf4a0c6c2), SPH_C32(0x19c10003), SPH_C32(0x49bd68b7), + SPH_C32(0x4e0914e3), SPH_C32(0x2a498c8c) }, + { SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), SPH_C32(0xe007afe6), + SPH_C32(0x9fed4ab7), SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), + SPH_C32(0x99e585aa), SPH_C32(0x8d75f7f1) }, + { SPH_C32(0x19c10003), SPH_C32(0x49bd68b7), SPH_C32(0x4e0914e3), + SPH_C32(0x2a498c8c), SPH_C32(0x40d20002), SPH_C32(0x54ca4031), + SPH_C32(0xf213cd0e), SPH_C32(0xdee94a4e) }, + { SPH_C32(0x117e0002), SPH_C32(0x71294f25), SPH_C32(0x8bf1e742), + SPH_C32(0xcc71f708), SPH_C32(0x809c0003), SPH_C32(0x67738021), + SPH_C32(0x5c1d760b), SPH_C32(0x6b4d8c75) }, + { SPH_C32(0xd1300003), SPH_C32(0x42908f35), SPH_C32(0x25ff5c47), + SPH_C32(0x79d53133), SPH_C32(0x486d0003), SPH_C32(0x6c5e67a3), + SPH_C32(0x37eb3eaf), SPH_C32(0x38d131ca) } +}; + +#define INPUT_SMALL do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T256_0[acc >> 4][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + rp = &T256_4[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[1]; \ + rp = &T256_8[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_12[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[2]; \ + rp = &T256_16[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_20[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[3]; \ + rp = &T256_24[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_28[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_SMALL == 5 + +static const sph_u32 T256_0[32][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x97530000), SPH_C32(0x204f6ed3), SPH_C32(0x77b9e80f), + SPH_C32(0xa1ec5ec1), SPH_C32(0x7e792000), SPH_C32(0x9418e22f), + SPH_C32(0x6643d258), SPH_C32(0x9c255be5) }, + { SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), SPH_C32(0x8dfacfab), + SPH_C32(0xce36cc72), SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), + SPH_C32(0x848598ba), SPH_C32(0x1041003e) }, + { SPH_C32(0x85484000), SPH_C32(0x7b58b73b), SPH_C32(0xfa4327a4), + SPH_C32(0x6fda92b3), SPH_C32(0x982e2000), SPH_C32(0xdfabd80a), + SPH_C32(0xe2c64ae2), SPH_C32(0x8c645bdb) }, + { SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), SPH_C32(0x848598ba), + SPH_C32(0x1041003e), SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), + SPH_C32(0x097f5711), SPH_C32(0xde77cc4c) }, + { SPH_C32(0x71040000), SPH_C32(0x6bfc54f6), SPH_C32(0xf33c70b5), + SPH_C32(0xb1ad5eff), SPH_C32(0x8a356000), SPH_C32(0x84bc01e2), + SPH_C32(0x6f3c8549), SPH_C32(0x425297a9) }, + { SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), SPH_C32(0x097f5711), + SPH_C32(0xde77cc4c), SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), + SPH_C32(0x8dfacfab), SPH_C32(0xce36cc72) }, + { SPH_C32(0x631f4000), SPH_C32(0x30eb8d1e), SPH_C32(0x7ec6bf1e), + SPH_C32(0x7f9b928d), SPH_C32(0x6c626000), SPH_C32(0xcf0f3bc7), + SPH_C32(0xebb91df3), SPH_C32(0x52139797) }, + { SPH_C32(0xe4788000), SPH_C32(0x859673c1), SPH_C32(0xb5fb2452), + SPH_C32(0x29cc5edf), SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), + SPH_C32(0x62fc79d0), SPH_C32(0x731ebdc2) }, + { SPH_C32(0x732b8000), SPH_C32(0xa5d91d12), SPH_C32(0xc242cc5d), + SPH_C32(0x8820001e), SPH_C32(0x7a262000), SPH_C32(0x085271e6), + SPH_C32(0x04bfab88), SPH_C32(0xef3be627) }, + { SPH_C32(0xf663c000), SPH_C32(0xde81aa29), SPH_C32(0x3801ebf9), + SPH_C32(0xe7fa92ad), SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), + SPH_C32(0xe679e16a), SPH_C32(0x635fbdfc) }, + { SPH_C32(0x6130c000), SPH_C32(0xfecec4fa), SPH_C32(0x4fb803f6), + SPH_C32(0x4616cc6c), SPH_C32(0x9c712000), SPH_C32(0x43e14bc3), + SPH_C32(0x803a3332), SPH_C32(0xff7ae619) }, + { SPH_C32(0x022f8000), SPH_C32(0xce2549e4), SPH_C32(0x317ebce8), + SPH_C32(0x398d5ee1), SPH_C32(0xf0134000), SPH_C32(0x8cee7004), + SPH_C32(0x6b832ec1), SPH_C32(0xad69718e) }, + { SPH_C32(0x957c8000), SPH_C32(0xee6a2737), SPH_C32(0x46c754e7), + SPH_C32(0x98610020), SPH_C32(0x8e6a6000), SPH_C32(0x18f6922b), + SPH_C32(0x0dc0fc99), SPH_C32(0x314c2a6b) }, + { SPH_C32(0x1034c000), SPH_C32(0x9532900c), SPH_C32(0xbc847343), + SPH_C32(0xf7bb9293), SPH_C32(0x16444000), SPH_C32(0xc75d4a21), + SPH_C32(0xef06b67b), SPH_C32(0xbd2871b0) }, + { SPH_C32(0x8767c000), SPH_C32(0xb57dfedf), SPH_C32(0xcb3d9b4c), + SPH_C32(0x5657cc52), SPH_C32(0x683d6000), SPH_C32(0x5345a80e), + SPH_C32(0x89456423), SPH_C32(0x210d2a55) }, + { SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), SPH_C32(0x62fc79d0), + SPH_C32(0x731ebdc2), SPH_C32(0xe0278000), SPH_C32(0x19dce008), + SPH_C32(0xd7075d82), SPH_C32(0x5ad2e31d) }, + { SPH_C32(0x930c0000), SPH_C32(0xbc05fd1a), SPH_C32(0x154591df), + SPH_C32(0xd2f2e303), SPH_C32(0x9e5ea000), SPH_C32(0x8dc40227), + SPH_C32(0xb1448fda), SPH_C32(0xc6f7b8f8) }, + { SPH_C32(0x16444000), SPH_C32(0xc75d4a21), SPH_C32(0xef06b67b), + SPH_C32(0xbd2871b0), SPH_C32(0x06708000), SPH_C32(0x526fda2d), + SPH_C32(0x5382c538), SPH_C32(0x4a93e323) }, + { SPH_C32(0x81174000), SPH_C32(0xe71224f2), SPH_C32(0x98bf5e74), + SPH_C32(0x1cc42f71), SPH_C32(0x7809a000), SPH_C32(0xc6773802), + SPH_C32(0x35c11760), SPH_C32(0xd6b6b8c6) }, + { SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), SPH_C32(0xe679e16a), + SPH_C32(0x635fbdfc), SPH_C32(0x146bc000), SPH_C32(0x097803c5), + SPH_C32(0xde780a93), SPH_C32(0x84a52f51) }, + { SPH_C32(0x755b0000), SPH_C32(0xf7b6c73f), SPH_C32(0x91c00965), + SPH_C32(0xc2b3e33d), SPH_C32(0x6a12e000), SPH_C32(0x9d60e1ea), + SPH_C32(0xb83bd8cb), SPH_C32(0x188074b4) }, + { SPH_C32(0xf0134000), SPH_C32(0x8cee7004), SPH_C32(0x6b832ec1), + SPH_C32(0xad69718e), SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), + SPH_C32(0x5afd9229), SPH_C32(0x94e42f6f) }, + { SPH_C32(0x67404000), SPH_C32(0xaca11ed7), SPH_C32(0x1c3ac6ce), + SPH_C32(0x0c852f4f), SPH_C32(0x8c45e000), SPH_C32(0xd6d3dbcf), + SPH_C32(0x3cbe4071), SPH_C32(0x08c1748a) }, + { SPH_C32(0xe0278000), SPH_C32(0x19dce008), SPH_C32(0xd7075d82), + SPH_C32(0x5ad2e31d), SPH_C32(0xe4788000), SPH_C32(0x859673c1), + SPH_C32(0xb5fb2452), SPH_C32(0x29cc5edf) }, + { SPH_C32(0x77748000), SPH_C32(0x39938edb), SPH_C32(0xa0beb58d), + SPH_C32(0xfb3ebddc), SPH_C32(0x9a01a000), SPH_C32(0x118e91ee), + SPH_C32(0xd3b8f60a), SPH_C32(0xb5e9053a) }, + { SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), SPH_C32(0x5afd9229), + SPH_C32(0x94e42f6f), SPH_C32(0x022f8000), SPH_C32(0xce2549e4), + SPH_C32(0x317ebce8), SPH_C32(0x398d5ee1) }, + { SPH_C32(0x656fc000), SPH_C32(0x62845733), SPH_C32(0x2d447a26), + SPH_C32(0x350871ae), SPH_C32(0x7c56a000), SPH_C32(0x5a3dabcb), + SPH_C32(0x573d6eb0), SPH_C32(0xa5a80504) }, + { SPH_C32(0x06708000), SPH_C32(0x526fda2d), SPH_C32(0x5382c538), + SPH_C32(0x4a93e323), SPH_C32(0x1034c000), SPH_C32(0x9532900c), + SPH_C32(0xbc847343), SPH_C32(0xf7bb9293) }, + { SPH_C32(0x91238000), SPH_C32(0x7220b4fe), SPH_C32(0x243b2d37), + SPH_C32(0xeb7fbde2), SPH_C32(0x6e4de000), SPH_C32(0x012a7223), + SPH_C32(0xdac7a11b), SPH_C32(0x6b9ec976) }, + { SPH_C32(0x146bc000), SPH_C32(0x097803c5), SPH_C32(0xde780a93), + SPH_C32(0x84a52f51), SPH_C32(0xf663c000), SPH_C32(0xde81aa29), + SPH_C32(0x3801ebf9), SPH_C32(0xe7fa92ad) }, + { SPH_C32(0x8338c000), SPH_C32(0x29376d16), SPH_C32(0xa9c1e29c), + SPH_C32(0x25497190), SPH_C32(0x881ae000), SPH_C32(0x4a994806), + SPH_C32(0x5e4239a1), SPH_C32(0x7bdfc948) } +}; + +static const sph_u32 T256_5[32][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xde320800), SPH_C32(0x288350fe), SPH_C32(0x71852ac7), + SPH_C32(0xa6bf9f96), SPH_C32(0xe18b0000), SPH_C32(0x5459887d), + SPH_C32(0xbf1283d3), SPH_C32(0x1b666a73) }, + { SPH_C32(0xe18b0000), SPH_C32(0x5459887d), SPH_C32(0xbf1283d3), + SPH_C32(0x1b666a73), SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), + SPH_C32(0xce97a914), SPH_C32(0xbdd9f5e5) }, + { SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), SPH_C32(0xce97a914), + SPH_C32(0xbdd9f5e5), SPH_C32(0xde320800), SPH_C32(0x288350fe), + SPH_C32(0x71852ac7), SPH_C32(0xa6bf9f96) }, + { SPH_C32(0x74951000), SPH_C32(0x5a2b467e), SPH_C32(0x88fd1d2b), + SPH_C32(0x1ee68292), SPH_C32(0xcba90000), SPH_C32(0x90273769), + SPH_C32(0xbbdcf407), SPH_C32(0xd0f4af61) }, + { SPH_C32(0xaaa71800), SPH_C32(0x72a81680), SPH_C32(0xf97837ec), + SPH_C32(0xb8591d04), SPH_C32(0x2a220000), SPH_C32(0xc47ebf14), + SPH_C32(0x04ce77d4), SPH_C32(0xcb92c512) }, + { SPH_C32(0x951e1000), SPH_C32(0x0e72ce03), SPH_C32(0x37ef9ef8), + SPH_C32(0x0580e8e1), SPH_C32(0xf4100800), SPH_C32(0xecfdefea), + SPH_C32(0x754b5d13), SPH_C32(0x6d2d5a84) }, + { SPH_C32(0x4b2c1800), SPH_C32(0x26f19efd), SPH_C32(0x466ab43f), + SPH_C32(0xa33f7777), SPH_C32(0x159b0800), SPH_C32(0xb8a46797), + SPH_C32(0xca59dec0), SPH_C32(0x764b30f7) }, + { SPH_C32(0xcba90000), SPH_C32(0x90273769), SPH_C32(0xbbdcf407), + SPH_C32(0xd0f4af61), SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), + SPH_C32(0x3321e92c), SPH_C32(0xce122df3) }, + { SPH_C32(0x159b0800), SPH_C32(0xb8a46797), SPH_C32(0xca59dec0), + SPH_C32(0x764b30f7), SPH_C32(0x5eb71000), SPH_C32(0x9e55f96a), + SPH_C32(0x8c336aff), SPH_C32(0xd5744780) }, + { SPH_C32(0x2a220000), SPH_C32(0xc47ebf14), SPH_C32(0x04ce77d4), + SPH_C32(0xcb92c512), SPH_C32(0x80851800), SPH_C32(0xb6d6a994), + SPH_C32(0xfdb64038), SPH_C32(0x73cbd816) }, + { SPH_C32(0xf4100800), SPH_C32(0xecfdefea), SPH_C32(0x754b5d13), + SPH_C32(0x6d2d5a84), SPH_C32(0x610e1800), SPH_C32(0xe28f21e9), + SPH_C32(0x42a4c3eb), SPH_C32(0x68adb265) }, + { SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), SPH_C32(0x3321e92c), + SPH_C32(0xce122df3), SPH_C32(0x74951000), SPH_C32(0x5a2b467e), + SPH_C32(0x88fd1d2b), SPH_C32(0x1ee68292) }, + { SPH_C32(0x610e1800), SPH_C32(0xe28f21e9), SPH_C32(0x42a4c3eb), + SPH_C32(0x68adb265), SPH_C32(0x951e1000), SPH_C32(0x0e72ce03), + SPH_C32(0x37ef9ef8), SPH_C32(0x0580e8e1) }, + { SPH_C32(0x5eb71000), SPH_C32(0x9e55f96a), SPH_C32(0x8c336aff), + SPH_C32(0xd5744780), SPH_C32(0x4b2c1800), SPH_C32(0x26f19efd), + SPH_C32(0x466ab43f), SPH_C32(0xa33f7777) }, + { SPH_C32(0x80851800), SPH_C32(0xb6d6a994), SPH_C32(0xfdb64038), + SPH_C32(0x73cbd816), SPH_C32(0xaaa71800), SPH_C32(0x72a81680), + SPH_C32(0xf97837ec), SPH_C32(0xb8591d04) }, + { SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), SPH_C32(0x11fa3a57), + SPH_C32(0x3dc90524), SPH_C32(0x97530000), SPH_C32(0x204f6ed3), + SPH_C32(0x77b9e80f), SPH_C32(0xa1ec5ec1) }, + { SPH_C32(0x37182800), SPH_C32(0x9cd4dc02), SPH_C32(0x607f1090), + SPH_C32(0x9b769ab2), SPH_C32(0x76d80000), SPH_C32(0x7416e6ae), + SPH_C32(0xc8ab6bdc), SPH_C32(0xba8a34b2) }, + { SPH_C32(0x08a12000), SPH_C32(0xe00e0481), SPH_C32(0xaee8b984), + SPH_C32(0x26af6f57), SPH_C32(0xa8ea0800), SPH_C32(0x5c95b650), + SPH_C32(0xb92e411b), SPH_C32(0x1c35ab24) }, + { SPH_C32(0xd6932800), SPH_C32(0xc88d547f), SPH_C32(0xdf6d9343), + SPH_C32(0x8010f0c1), SPH_C32(0x49610800), SPH_C32(0x08cc3e2d), + SPH_C32(0x063cc2c8), SPH_C32(0x0753c157) }, + { SPH_C32(0x9dbf3000), SPH_C32(0xee7cca82), SPH_C32(0x9907277c), + SPH_C32(0x232f87b6), SPH_C32(0x5cfa0000), SPH_C32(0xb06859ba), + SPH_C32(0xcc651c08), SPH_C32(0x7118f1a0) }, + { SPH_C32(0x438d3800), SPH_C32(0xc6ff9a7c), SPH_C32(0xe8820dbb), + SPH_C32(0x85901820), SPH_C32(0xbd710000), SPH_C32(0xe431d1c7), + SPH_C32(0x73779fdb), SPH_C32(0x6a7e9bd3) }, + { SPH_C32(0x7c343000), SPH_C32(0xba2542ff), SPH_C32(0x2615a4af), + SPH_C32(0x3849edc5), SPH_C32(0x63430800), SPH_C32(0xccb28139), + SPH_C32(0x02f2b51c), SPH_C32(0xccc10445) }, + { SPH_C32(0xa2063800), SPH_C32(0x92a61201), SPH_C32(0x57908e68), + SPH_C32(0x9ef67253), SPH_C32(0x82c80800), SPH_C32(0x98eb0944), + SPH_C32(0xbde036cf), SPH_C32(0xd7a76e36) }, + { SPH_C32(0x22832000), SPH_C32(0x2470bb95), SPH_C32(0xaa26ce50), + SPH_C32(0xed3daa45), SPH_C32(0x286f1000), SPH_C32(0xea431fc4), + SPH_C32(0x44980123), SPH_C32(0x6ffe7332) }, + { SPH_C32(0xfcb12800), SPH_C32(0x0cf3eb6b), SPH_C32(0xdba3e497), + SPH_C32(0x4b8235d3), SPH_C32(0xc9e41000), SPH_C32(0xbe1a97b9), + SPH_C32(0xfb8a82f0), SPH_C32(0x74981941) }, + { SPH_C32(0xc3082000), SPH_C32(0x702933e8), SPH_C32(0x15344d83), + SPH_C32(0xf65bc036), SPH_C32(0x17d61800), SPH_C32(0x9699c747), + SPH_C32(0x8a0fa837), SPH_C32(0xd22786d7) }, + { SPH_C32(0x1d3a2800), SPH_C32(0x58aa6316), SPH_C32(0x64b16744), + SPH_C32(0x50e45fa0), SPH_C32(0xf65d1800), SPH_C32(0xc2c04f3a), + SPH_C32(0x351d2be4), SPH_C32(0xc941eca4) }, + { SPH_C32(0x56163000), SPH_C32(0x7e5bfdeb), SPH_C32(0x22dbd37b), + SPH_C32(0xf3db28d7), SPH_C32(0xe3c61000), SPH_C32(0x7a6428ad), + SPH_C32(0xff44f524), SPH_C32(0xbf0adc53) }, + { SPH_C32(0x88243800), SPH_C32(0x56d8ad15), SPH_C32(0x535ef9bc), + SPH_C32(0x5564b741), SPH_C32(0x024d1000), SPH_C32(0x2e3da0d0), + SPH_C32(0x405676f7), SPH_C32(0xa46cb620) }, + { SPH_C32(0xb79d3000), SPH_C32(0x2a027596), SPH_C32(0x9dc950a8), + SPH_C32(0xe8bd42a4), SPH_C32(0xdc7f1800), SPH_C32(0x06bef02e), + SPH_C32(0x31d35c30), SPH_C32(0x02d329b6) }, + { SPH_C32(0x69af3800), SPH_C32(0x02812568), SPH_C32(0xec4c7a6f), + SPH_C32(0x4e02dd32), SPH_C32(0x3df41800), SPH_C32(0x52e77853), + SPH_C32(0x8ec1dfe3), SPH_C32(0x19b543c5) } +}; + +static const sph_u32 T256_10[32][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), SPH_C32(0xa29d1297), + SPH_C32(0x6ee56854), SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), + SPH_C32(0x2714ca3c), SPH_C32(0x88210c30) }, + { SPH_C32(0xa7b80200), SPH_C32(0x1f128433), SPH_C32(0x60e5f9f2), + SPH_C32(0x9e147576), SPH_C32(0xee260000), SPH_C32(0x124b683e), + SPH_C32(0x80c2d68f), SPH_C32(0x3bf3ab2c) }, + { SPH_C32(0xd4f40200), SPH_C32(0x8a7d23e5), SPH_C32(0xc278eb65), + SPH_C32(0xf0f11d22), SPH_C32(0x2ace0100), SPH_C32(0x0d3bfe30), + SPH_C32(0xa7d61cb3), SPH_C32(0xb3d2a71c) }, + { SPH_C32(0xee260000), SPH_C32(0x124b683e), SPH_C32(0x80c2d68f), + SPH_C32(0x3bf3ab2c), SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), + SPH_C32(0xe0272f7d), SPH_C32(0xa5e7de5a) }, + { SPH_C32(0x9d6a0000), SPH_C32(0x8724cfe8), SPH_C32(0x225fc418), + SPH_C32(0x5516c378), SPH_C32(0x8d760300), SPH_C32(0x12297a03), + SPH_C32(0xc733e541), SPH_C32(0x2dc6d26a) }, + { SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), SPH_C32(0xe0272f7d), + SPH_C32(0xa5e7de5a), SPH_C32(0xa7b80200), SPH_C32(0x1f128433), + SPH_C32(0x60e5f9f2), SPH_C32(0x9e147576) }, + { SPH_C32(0x3ad20200), SPH_C32(0x98364bdb), SPH_C32(0x42ba3dea), + SPH_C32(0xcb02b60e), SPH_C32(0x63500300), SPH_C32(0x0062123d), + SPH_C32(0x47f133ce), SPH_C32(0x16357946) }, + { SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), SPH_C32(0x6fc548e1), + SPH_C32(0x898d2cd6), SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), + SPH_C32(0x6a72e5bb), SPH_C32(0x247febe6) }, + { SPH_C32(0xfc720400), SPH_C32(0x98f26fa1), SPH_C32(0xcd585a76), + SPH_C32(0xe7684482), SPH_C32(0xd0550100), SPH_C32(0x30caa1f1), + SPH_C32(0x4d662f87), SPH_C32(0xac5ee7d6) }, + { SPH_C32(0x28860600), SPH_C32(0x128f4c44), SPH_C32(0x0f20b113), + SPH_C32(0x179959a0), SPH_C32(0xfa9b0000), SPH_C32(0x3df15fc1), + SPH_C32(0xeab03334), SPH_C32(0x1f8c40ca) }, + { SPH_C32(0x5bca0600), SPH_C32(0x87e0eb92), SPH_C32(0xadbda384), + SPH_C32(0x797c31f4), SPH_C32(0x3e730100), SPH_C32(0x2281c9cf), + SPH_C32(0xcda4f908), SPH_C32(0x97ad4cfa) }, + { SPH_C32(0x61180400), SPH_C32(0x1fd6a049), SPH_C32(0xef079e6e), + SPH_C32(0xb27e87fa), SPH_C32(0x5d230200), SPH_C32(0x22e3dbf2), + SPH_C32(0x8a55cac6), SPH_C32(0x819835bc) }, + { SPH_C32(0x12540400), SPH_C32(0x8ab9079f), SPH_C32(0x4d9a8cf9), + SPH_C32(0xdc9befae), SPH_C32(0x99cb0300), SPH_C32(0x3d934dfc), + SPH_C32(0xad4100fa), SPH_C32(0x09b9398c) }, + { SPH_C32(0xc6a00600), SPH_C32(0x00c4247a), SPH_C32(0x8fe2679c), + SPH_C32(0x2c6af28c), SPH_C32(0xb3050200), SPH_C32(0x30a8b3cc), + SPH_C32(0x0a971c49), SPH_C32(0xba6b9e90) }, + { SPH_C32(0xb5ec0600), SPH_C32(0x95ab83ac), SPH_C32(0x2d7f750b), + SPH_C32(0x428f9ad8), SPH_C32(0x77ed0300), SPH_C32(0x2fd825c2), + SPH_C32(0x2d83d675), SPH_C32(0x324a92a0) }, + { SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), SPH_C32(0x6a72e5bb), + SPH_C32(0x247febe6), SPH_C32(0x9b830400), SPH_C32(0x2227ff88), + SPH_C32(0x05b7ad5a), SPH_C32(0xadf2c730) }, + { SPH_C32(0x67f10000), SPH_C32(0xbad59029), SPH_C32(0xc8eff72c), + SPH_C32(0x4a9a83b2), SPH_C32(0x5f6b0500), SPH_C32(0x3d576986), + SPH_C32(0x22a36766), SPH_C32(0x25d3cb00) }, + { SPH_C32(0xb3050200), SPH_C32(0x30a8b3cc), SPH_C32(0x0a971c49), + SPH_C32(0xba6b9e90), SPH_C32(0x75a50400), SPH_C32(0x306c97b6), + SPH_C32(0x85757bd5), SPH_C32(0x96016c1c) }, + { SPH_C32(0xc0490200), SPH_C32(0xa5c7141a), SPH_C32(0xa80a0ede), + SPH_C32(0xd48ef6c4), SPH_C32(0xb14d0500), SPH_C32(0x2f1c01b8), + SPH_C32(0xa261b1e9), SPH_C32(0x1e20602c) }, + { SPH_C32(0xfa9b0000), SPH_C32(0x3df15fc1), SPH_C32(0xeab03334), + SPH_C32(0x1f8c40ca), SPH_C32(0xd21d0600), SPH_C32(0x2f7e1385), + SPH_C32(0xe5908227), SPH_C32(0x0815196a) }, + { SPH_C32(0x89d70000), SPH_C32(0xa89ef817), SPH_C32(0x482d21a3), + SPH_C32(0x7169289e), SPH_C32(0x16f50700), SPH_C32(0x300e858b), + SPH_C32(0xc284481b), SPH_C32(0x8034155a) }, + { SPH_C32(0x5d230200), SPH_C32(0x22e3dbf2), SPH_C32(0x8a55cac6), + SPH_C32(0x819835bc), SPH_C32(0x3c3b0600), SPH_C32(0x3d357bbb), + SPH_C32(0x655254a8), SPH_C32(0x33e6b246) }, + { SPH_C32(0x2e6f0200), SPH_C32(0xb78c7c24), SPH_C32(0x28c8d851), + SPH_C32(0xef7d5de8), SPH_C32(0xf8d30700), SPH_C32(0x2245edb5), + SPH_C32(0x42469e94), SPH_C32(0xbbc7be76) }, + { SPH_C32(0x9b830400), SPH_C32(0x2227ff88), SPH_C32(0x05b7ad5a), + SPH_C32(0xadf2c730), SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), + SPH_C32(0x6fc548e1), SPH_C32(0x898d2cd6) }, + { SPH_C32(0xe8cf0400), SPH_C32(0xb748585e), SPH_C32(0xa72abfcd), + SPH_C32(0xc317af64), SPH_C32(0x4bd60500), SPH_C32(0x12ed5e79), + SPH_C32(0x48d182dd), SPH_C32(0x01ac20e6) }, + { SPH_C32(0x3c3b0600), SPH_C32(0x3d357bbb), SPH_C32(0x655254a8), + SPH_C32(0x33e6b246), SPH_C32(0x61180400), SPH_C32(0x1fd6a049), + SPH_C32(0xef079e6e), SPH_C32(0xb27e87fa) }, + { SPH_C32(0x4f770600), SPH_C32(0xa85adc6d), SPH_C32(0xc7cf463f), + SPH_C32(0x5d03da12), SPH_C32(0xa5f00500), SPH_C32(0x00a63647), + SPH_C32(0xc8135452), SPH_C32(0x3a5f8bca) }, + { SPH_C32(0x75a50400), SPH_C32(0x306c97b6), SPH_C32(0x85757bd5), + SPH_C32(0x96016c1c), SPH_C32(0xc6a00600), SPH_C32(0x00c4247a), + SPH_C32(0x8fe2679c), SPH_C32(0x2c6af28c) }, + { SPH_C32(0x06e90400), SPH_C32(0xa5033060), SPH_C32(0x27e86942), + SPH_C32(0xf8e40448), SPH_C32(0x02480700), SPH_C32(0x1fb4b274), + SPH_C32(0xa8f6ada0), SPH_C32(0xa44bfebc) }, + { SPH_C32(0xd21d0600), SPH_C32(0x2f7e1385), SPH_C32(0xe5908227), + SPH_C32(0x0815196a), SPH_C32(0x28860600), SPH_C32(0x128f4c44), + SPH_C32(0x0f20b113), SPH_C32(0x179959a0) }, + { SPH_C32(0xa1510600), SPH_C32(0xba11b453), SPH_C32(0x470d90b0), + SPH_C32(0x66f0713e), SPH_C32(0xec6e0700), SPH_C32(0x0dffda4a), + SPH_C32(0x28347b2f), SPH_C32(0x9fb85590) } +}; + +static const sph_u32 T256_15[32][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), SPH_C32(0x36656ba8), + SPH_C32(0x23633a05), SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), + SPH_C32(0x5d5ca0f7), SPH_C32(0x727784cb) }, + { SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), SPH_C32(0x5d5ca0f7), + SPH_C32(0x727784cb), SPH_C32(0x35650040), SPH_C32(0x9b96b64a), + SPH_C32(0x6b39cb5f), SPH_C32(0x5114bece) }, + { SPH_C32(0x35650040), SPH_C32(0x9b96b64a), SPH_C32(0x6b39cb5f), + SPH_C32(0x5114bece), SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), + SPH_C32(0x36656ba8), SPH_C32(0x23633a05) }, + { SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), SPH_C32(0xc2c46c55), + SPH_C32(0xf362b233), SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), + SPH_C32(0xd14e094b), SPH_C32(0xb772b42b) }, + { SPH_C32(0x161c00c0), SPH_C32(0x7e54f492), SPH_C32(0xf4a107fd), + SPH_C32(0xd0018836), SPH_C32(0x410d0000), SPH_C32(0xea7a09df), + SPH_C32(0x8c12a9bc), SPH_C32(0xc50530e0) }, + { SPH_C32(0x23790080), SPH_C32(0xe5c242d8), SPH_C32(0x9f98cca2), + SPH_C32(0x811536f8), SPH_C32(0x0cc30040), SPH_C32(0xd121e5a1), + SPH_C32(0xba77c214), SPH_C32(0xe6660ae5) }, + { SPH_C32(0x6eb700c0), SPH_C32(0xde99aea6), SPH_C32(0xa9fda70a), + SPH_C32(0xa2760cfd), SPH_C32(0x74680040), SPH_C32(0x71ecbf95), + SPH_C32(0xe72b62e3), SPH_C32(0x94118e2e) }, + { SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), SPH_C32(0xd14e094b), + SPH_C32(0xb772b42b), SPH_C32(0x62740080), SPH_C32(0x0fb84b07), + SPH_C32(0x138a651e), SPH_C32(0x44100618) }, + { SPH_C32(0x74680040), SPH_C32(0x71ecbf95), SPH_C32(0xe72b62e3), + SPH_C32(0x94118e2e), SPH_C32(0x1adf0080), SPH_C32(0xaf751133), + SPH_C32(0x4ed6c5e9), SPH_C32(0x366782d3) }, + { SPH_C32(0x410d0000), SPH_C32(0xea7a09df), SPH_C32(0x8c12a9bc), + SPH_C32(0xc50530e0), SPH_C32(0x571100c0), SPH_C32(0x942efd4d), + SPH_C32(0x78b3ae41), SPH_C32(0x1504b8d6) }, + { SPH_C32(0x0cc30040), SPH_C32(0xd121e5a1), SPH_C32(0xba77c214), + SPH_C32(0xe6660ae5), SPH_C32(0x2fba00c0), SPH_C32(0x34e3a779), + SPH_C32(0x25ef0eb6), SPH_C32(0x67733c1d) }, + { SPH_C32(0x62740080), SPH_C32(0x0fb84b07), SPH_C32(0x138a651e), + SPH_C32(0x44100618), SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), + SPH_C32(0xc2c46c55), SPH_C32(0xf362b233) }, + { SPH_C32(0x2fba00c0), SPH_C32(0x34e3a779), SPH_C32(0x25ef0eb6), + SPH_C32(0x67733c1d), SPH_C32(0x23790080), SPH_C32(0xe5c242d8), + SPH_C32(0x9f98cca2), SPH_C32(0x811536f8) }, + { SPH_C32(0x1adf0080), SPH_C32(0xaf751133), SPH_C32(0x4ed6c5e9), + SPH_C32(0x366782d3), SPH_C32(0x6eb700c0), SPH_C32(0xde99aea6), + SPH_C32(0xa9fda70a), SPH_C32(0xa2760cfd) }, + { SPH_C32(0x571100c0), SPH_C32(0x942efd4d), SPH_C32(0x78b3ae41), + SPH_C32(0x1504b8d6), SPH_C32(0x161c00c0), SPH_C32(0x7e54f492), + SPH_C32(0xf4a107fd), SPH_C32(0xd0018836) }, + { SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), SPH_C32(0x8589d8ab), + SPH_C32(0xe6c46464), SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), + SPH_C32(0xa29d1297), SPH_C32(0x6ee56854) }, + { SPH_C32(0xfa6a0140), SPH_C32(0xb144dda6), SPH_C32(0xb3ecb303), + SPH_C32(0xc5a75e61), SPH_C32(0x0be70000), SPH_C32(0x35a2fde2), + SPH_C32(0xffc1b260), SPH_C32(0x1c92ec9f) }, + { SPH_C32(0xcf0f0100), SPH_C32(0x2ad26bec), SPH_C32(0xd8d5785c), + SPH_C32(0x94b3e0af), SPH_C32(0x46290040), SPH_C32(0x0ef9119c), + SPH_C32(0xc9a4d9c8), SPH_C32(0x3ff1d69a) }, + { SPH_C32(0x82c10140), SPH_C32(0x11898792), SPH_C32(0xeeb013f4), + SPH_C32(0xb7d0daaa), SPH_C32(0x3e820040), SPH_C32(0xae344ba8), + SPH_C32(0x94f8793f), SPH_C32(0x4d865251) }, + { SPH_C32(0xec760180), SPH_C32(0xcf102934), SPH_C32(0x474db4fe), + SPH_C32(0x15a6d657), SPH_C32(0x4aea0000), SPH_C32(0xdfd8f43d), + SPH_C32(0x73d31bdc), SPH_C32(0xd997dc7f) }, + { SPH_C32(0xa1b801c0), SPH_C32(0xf44bc54a), SPH_C32(0x7128df56), + SPH_C32(0x36c5ec52), SPH_C32(0x32410000), SPH_C32(0x7f15ae09), + SPH_C32(0x2e8fbb2b), SPH_C32(0xabe058b4) }, + { SPH_C32(0x94dd0180), SPH_C32(0x6fdd7300), SPH_C32(0x1a111409), + SPH_C32(0x67d1529c), SPH_C32(0x7f8f0040), SPH_C32(0x444e4277), + SPH_C32(0x18ead083), SPH_C32(0x888362b1) }, + { SPH_C32(0xd91301c0), SPH_C32(0x54869f7e), SPH_C32(0x2c747fa1), + SPH_C32(0x44b26899), SPH_C32(0x07240040), SPH_C32(0xe4831843), + SPH_C32(0x45b67074), SPH_C32(0xfaf4e67a) }, + { SPH_C32(0x8e020100), SPH_C32(0xc0a86233), SPH_C32(0x54c7d1e0), + SPH_C32(0x51b6d04f), SPH_C32(0x11380080), SPH_C32(0x9ad7ecd1), + SPH_C32(0xb1177789), SPH_C32(0x2af56e4c) }, + { SPH_C32(0xc3cc0140), SPH_C32(0xfbf38e4d), SPH_C32(0x62a2ba48), + SPH_C32(0x72d5ea4a), SPH_C32(0x69930080), SPH_C32(0x3a1ab6e5), + SPH_C32(0xec4bd77e), SPH_C32(0x5882ea87) }, + { SPH_C32(0xf6a90100), SPH_C32(0x60653807), SPH_C32(0x099b7117), + SPH_C32(0x23c15484), SPH_C32(0x245d00c0), SPH_C32(0x01415a9b), + SPH_C32(0xda2ebcd6), SPH_C32(0x7be1d082) }, + { SPH_C32(0xbb670140), SPH_C32(0x5b3ed479), SPH_C32(0x3ffe1abf), + SPH_C32(0x00a26e81), SPH_C32(0x5cf600c0), SPH_C32(0xa18c00af), + SPH_C32(0x87721c21), SPH_C32(0x09965449) }, + { SPH_C32(0xd5d00180), SPH_C32(0x85a77adf), SPH_C32(0x9603bdb5), + SPH_C32(0xa2d4627c), SPH_C32(0x289e0080), SPH_C32(0xd060bf3a), + SPH_C32(0x60597ec2), SPH_C32(0x9d87da67) }, + { SPH_C32(0x981e01c0), SPH_C32(0xbefc96a1), SPH_C32(0xa066d61d), + SPH_C32(0x81b75879), SPH_C32(0x50350080), SPH_C32(0x70ade50e), + SPH_C32(0x3d05de35), SPH_C32(0xeff05eac) }, + { SPH_C32(0xad7b0180), SPH_C32(0x256a20eb), SPH_C32(0xcb5f1d42), + SPH_C32(0xd0a3e6b7), SPH_C32(0x1dfb00c0), SPH_C32(0x4bf60970), + SPH_C32(0x0b60b59d), SPH_C32(0xcc9364a9) }, + { SPH_C32(0xe0b501c0), SPH_C32(0x1e31cc95), SPH_C32(0xfd3a76ea), + SPH_C32(0xf3c0dcb2), SPH_C32(0x655000c0), SPH_C32(0xeb3b5344), + SPH_C32(0x563c156a), SPH_C32(0xbee4e062) } +}; + +static const sph_u32 T256_20[32][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x171c0000), SPH_C32(0xb26e3344), SPH_C32(0x9e6a837e), + SPH_C32(0x58f8485f), SPH_C32(0xbfb20008), SPH_C32(0x92170a39), + SPH_C32(0x6019107f), SPH_C32(0xe051606e) }, + { SPH_C32(0x515c0010), SPH_C32(0x40f372fb), SPH_C32(0xfce72602), + SPH_C32(0x71575061), SPH_C32(0x2e390000), SPH_C32(0x64dd6689), + SPH_C32(0x3cd406fc), SPH_C32(0xb1f490bc) }, + { SPH_C32(0x46400010), SPH_C32(0xf29d41bf), SPH_C32(0x628da57c), + SPH_C32(0x29af183e), SPH_C32(0x918b0008), SPH_C32(0xf6ca6cb0), + SPH_C32(0x5ccd1683), SPH_C32(0x51a5f0d2) }, + { SPH_C32(0x2e390000), SPH_C32(0x64dd6689), SPH_C32(0x3cd406fc), + SPH_C32(0xb1f490bc), SPH_C32(0x7f650010), SPH_C32(0x242e1472), + SPH_C32(0xc03320fe), SPH_C32(0xc0a3c0dd) }, + { SPH_C32(0x39250000), SPH_C32(0xd6b355cd), SPH_C32(0xa2be8582), + SPH_C32(0xe90cd8e3), SPH_C32(0xc0d70018), SPH_C32(0xb6391e4b), + SPH_C32(0xa02a3081), SPH_C32(0x20f2a0b3) }, + { SPH_C32(0x7f650010), SPH_C32(0x242e1472), SPH_C32(0xc03320fe), + SPH_C32(0xc0a3c0dd), SPH_C32(0x515c0010), SPH_C32(0x40f372fb), + SPH_C32(0xfce72602), SPH_C32(0x71575061) }, + { SPH_C32(0x68790010), SPH_C32(0x96402736), SPH_C32(0x5e59a380), + SPH_C32(0x985b8882), SPH_C32(0xeeee0018), SPH_C32(0xd2e478c2), + SPH_C32(0x9cfe367d), SPH_C32(0x9106300f) }, + { SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), SPH_C32(0xf9ce4c04), + SPH_C32(0xe2afa0c0), SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), + SPH_C32(0x79a90df9), SPH_C32(0x63e92178) }, + { SPH_C32(0xb5a40020), SPH_C32(0x3389d6b2), SPH_C32(0x67a4cf7a), + SPH_C32(0xba57e89f), SPH_C32(0xe3c00008), SPH_C32(0x5badc72b), + SPH_C32(0x19b01d86), SPH_C32(0x83b84116) }, + { SPH_C32(0xf3e40030), SPH_C32(0xc114970d), SPH_C32(0x05296a06), + SPH_C32(0x93f8f0a1), SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), + SPH_C32(0x457d0b05), SPH_C32(0xd21db1c4) }, + { SPH_C32(0xe4f80030), SPH_C32(0x737aa449), SPH_C32(0x9b43e978), + SPH_C32(0xcb00b8fe), SPH_C32(0xcdf90008), SPH_C32(0x3f70a1a2), + SPH_C32(0x25641b7a), SPH_C32(0x324cd1aa) }, + { SPH_C32(0x8c810020), SPH_C32(0xe53a837f), SPH_C32(0xc51a4af8), + SPH_C32(0x535b307c), SPH_C32(0x23170010), SPH_C32(0xed94d960), + SPH_C32(0xb99a2d07), SPH_C32(0xa34ae1a5) }, + { SPH_C32(0x9b9d0020), SPH_C32(0x5754b03b), SPH_C32(0x5b70c986), + SPH_C32(0x0ba37823), SPH_C32(0x9ca50018), SPH_C32(0x7f83d359), + SPH_C32(0xd9833d78), SPH_C32(0x431b81cb) }, + { SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), SPH_C32(0x39fd6cfa), + SPH_C32(0x220c601d), SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), + SPH_C32(0x854e2bfb), SPH_C32(0x12be7119) }, + { SPH_C32(0xcac10030), SPH_C32(0x17a7c2c0), SPH_C32(0xa797ef84), + SPH_C32(0x7af42842), SPH_C32(0xb29c0018), SPH_C32(0x1b5eb5d0), + SPH_C32(0xe5573b84), SPH_C32(0xf2ef1177) }, + { SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), SPH_C32(0x79a90df9), + SPH_C32(0x63e92178), SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), + SPH_C32(0x806741fd), SPH_C32(0x814681b8) }, + { SPH_C32(0x4b6e0000), SPH_C32(0x7bd4fe56), SPH_C32(0xe7c38e87), + SPH_C32(0x3b116927), SPH_C32(0x41780028), SPH_C32(0xda4a22dd), + SPH_C32(0xe07e5182), SPH_C32(0x6117e1d6) }, + { SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), SPH_C32(0x854e2bfb), + SPH_C32(0x12be7119), SPH_C32(0xd0f30020), SPH_C32(0x2c804e6d), + SPH_C32(0xbcb34701), SPH_C32(0x30b21104) }, + { SPH_C32(0x1a320010), SPH_C32(0x3b278cad), SPH_C32(0x1b24a885), + SPH_C32(0x4a463946), SPH_C32(0x6f410028), SPH_C32(0xbe974454), + SPH_C32(0xdcaa577e), SPH_C32(0xd0e3716a) }, + { SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), SPH_C32(0x457d0b05), + SPH_C32(0xd21db1c4), SPH_C32(0x81af0030), SPH_C32(0x6c733c96), + SPH_C32(0x40546103), SPH_C32(0x41e54165) }, + { SPH_C32(0x65570000), SPH_C32(0x1f0998df), SPH_C32(0xdb17887b), + SPH_C32(0x8ae5f99b), SPH_C32(0x3e1d0038), SPH_C32(0xfe6436af), + SPH_C32(0x204d717c), SPH_C32(0xa1b4210b) }, + { SPH_C32(0x23170010), SPH_C32(0xed94d960), SPH_C32(0xb99a2d07), + SPH_C32(0xa34ae1a5), SPH_C32(0xaf960030), SPH_C32(0x08ae5a1f), + SPH_C32(0x7c8067ff), SPH_C32(0xf011d1d9) }, + { SPH_C32(0x340b0010), SPH_C32(0x5ffaea24), SPH_C32(0x27f0ae79), + SPH_C32(0xfbb2a9fa), SPH_C32(0x10240038), SPH_C32(0x9ab95026), + SPH_C32(0x1c997780), SPH_C32(0x1040b1b7) }, + { SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), SPH_C32(0x806741fd), + SPH_C32(0x814681b8), SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), + SPH_C32(0xf9ce4c04), SPH_C32(0xe2afa0c0) }, + { SPH_C32(0xe9d60020), SPH_C32(0xfa331ba0), SPH_C32(0x1e0dc283), + SPH_C32(0xd9bec9e7), SPH_C32(0x1d0a0028), SPH_C32(0x13f0efcf), + SPH_C32(0x99d75c7b), SPH_C32(0x02fec0ae) }, + { SPH_C32(0xaf960030), SPH_C32(0x08ae5a1f), SPH_C32(0x7c8067ff), + SPH_C32(0xf011d1d9), SPH_C32(0x8c810020), SPH_C32(0xe53a837f), + SPH_C32(0xc51a4af8), SPH_C32(0x535b307c) }, + { SPH_C32(0xb88a0030), SPH_C32(0xbac0695b), SPH_C32(0xe2eae481), + SPH_C32(0xa8e99986), SPH_C32(0x33330028), SPH_C32(0x772d8946), + SPH_C32(0xa5035a87), SPH_C32(0xb30a5012) }, + { SPH_C32(0xd0f30020), SPH_C32(0x2c804e6d), SPH_C32(0xbcb34701), + SPH_C32(0x30b21104), SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), + SPH_C32(0x39fd6cfa), SPH_C32(0x220c601d) }, + { SPH_C32(0xc7ef0020), SPH_C32(0x9eee7d29), SPH_C32(0x22d9c47f), + SPH_C32(0x684a595b), SPH_C32(0x626f0038), SPH_C32(0x37defbbd), + SPH_C32(0x59e47c85), SPH_C32(0xc25d0073) }, + { SPH_C32(0x81af0030), SPH_C32(0x6c733c96), SPH_C32(0x40546103), + SPH_C32(0x41e54165), SPH_C32(0xf3e40030), SPH_C32(0xc114970d), + SPH_C32(0x05296a06), SPH_C32(0x93f8f0a1) }, + { SPH_C32(0x96b30030), SPH_C32(0xde1d0fd2), SPH_C32(0xde3ee27d), + SPH_C32(0x191d093a), SPH_C32(0x4c560038), SPH_C32(0x53039d34), + SPH_C32(0x65307a79), SPH_C32(0x73a990cf) } +}; + +static const sph_u32 T256_25[32][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), SPH_C32(0x99e585aa), + SPH_C32(0x8d75f7f1), SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), + SPH_C32(0x79e22a4c), SPH_C32(0x1298bd46) }, + { SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), SPH_C32(0x79e22a4c), + SPH_C32(0x1298bd46), SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), + SPH_C32(0xe007afe6), SPH_C32(0x9fed4ab7) }, + { SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), SPH_C32(0xe007afe6), + SPH_C32(0x9fed4ab7), SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), + SPH_C32(0x99e585aa), SPH_C32(0x8d75f7f1) }, + { SPH_C32(0xd0080004), SPH_C32(0x8c768f77), SPH_C32(0x9dc5b050), + SPH_C32(0xaf4a29da), SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), + SPH_C32(0x98321c3d), SPH_C32(0x76acc733) }, + { SPH_C32(0x582b0006), SPH_C32(0xd39128c4), SPH_C32(0x042035fa), + SPH_C32(0x223fde2b), SPH_C32(0x3a050000), SPH_C32(0x6508f6be), + SPH_C32(0xe1d03671), SPH_C32(0x64347a75) }, + { SPH_C32(0x81a40004), SPH_C32(0xa9958063), SPH_C32(0xe4279a1c), + SPH_C32(0xbdd2949c), SPH_C32(0xb2260002), SPH_C32(0x3aef510d), + SPH_C32(0x7835b3db), SPH_C32(0xe9418d84) }, + { SPH_C32(0x09870006), SPH_C32(0xf67227d0), SPH_C32(0x7dc21fb6), + SPH_C32(0x30a7636d), SPH_C32(0xe38a0002), SPH_C32(0x1f0c5e19), + SPH_C32(0x01d79997), SPH_C32(0xfbd930c2) }, + { SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), SPH_C32(0x98321c3d), + SPH_C32(0x76acc733), SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), + SPH_C32(0x05f7ac6d), SPH_C32(0xd9e6eee9) }, + { SPH_C32(0xe38a0002), SPH_C32(0x1f0c5e19), SPH_C32(0x01d79997), + SPH_C32(0xfbd930c2), SPH_C32(0xea0d0004), SPH_C32(0xe97e79c9), + SPH_C32(0x7c158621), SPH_C32(0xcb7e53af) }, + { SPH_C32(0x3a050000), SPH_C32(0x6508f6be), SPH_C32(0xe1d03671), + SPH_C32(0x64347a75), SPH_C32(0x622e0006), SPH_C32(0xb699de7a), + SPH_C32(0xe5f0038b), SPH_C32(0x460ba45e) }, + { SPH_C32(0xb2260002), SPH_C32(0x3aef510d), SPH_C32(0x7835b3db), + SPH_C32(0xe9418d84), SPH_C32(0x33820006), SPH_C32(0x937ad16e), + SPH_C32(0x9c1229c7), SPH_C32(0x54931918) }, + { SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), SPH_C32(0x05f7ac6d), + SPH_C32(0xd9e6eee9), SPH_C32(0xd0080004), SPH_C32(0x8c768f77), + SPH_C32(0x9dc5b050), SPH_C32(0xaf4a29da) }, + { SPH_C32(0x33820006), SPH_C32(0x937ad16e), SPH_C32(0x9c1229c7), + SPH_C32(0x54931918), SPH_C32(0x81a40004), SPH_C32(0xa9958063), + SPH_C32(0xe4279a1c), SPH_C32(0xbdd2949c) }, + { SPH_C32(0xea0d0004), SPH_C32(0xe97e79c9), SPH_C32(0x7c158621), + SPH_C32(0xcb7e53af), SPH_C32(0x09870006), SPH_C32(0xf67227d0), + SPH_C32(0x7dc21fb6), SPH_C32(0x30a7636d) }, + { SPH_C32(0x622e0006), SPH_C32(0xb699de7a), SPH_C32(0xe5f0038b), + SPH_C32(0x460ba45e), SPH_C32(0x582b0006), SPH_C32(0xd39128c4), + SPH_C32(0x042035fa), SPH_C32(0x223fde2b) }, + { SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), SPH_C32(0xfe739301), + SPH_C32(0xb8a92831), SPH_C32(0x171c0000), SPH_C32(0xb26e3344), + SPH_C32(0x9e6a837e), SPH_C32(0x58f8485f) }, + { SPH_C32(0x208d000a), SPH_C32(0x7f9e9ece), SPH_C32(0x679616ab), + SPH_C32(0x35dcdfc0), SPH_C32(0x46b00000), SPH_C32(0x978d3c50), + SPH_C32(0xe788a932), SPH_C32(0x4a60f519) }, + { SPH_C32(0xf9020008), SPH_C32(0x059a3669), SPH_C32(0x8791b94d), + SPH_C32(0xaa319577), SPH_C32(0xce930002), SPH_C32(0xc86a9be3), + SPH_C32(0x7e6d2c98), SPH_C32(0xc71502e8) }, + { SPH_C32(0x7121000a), SPH_C32(0x5a7d91da), SPH_C32(0x1e743ce7), + SPH_C32(0x27446286), SPH_C32(0x9f3f0002), SPH_C32(0xed8994f7), + SPH_C32(0x078f06d4), SPH_C32(0xd58dbfae) }, + { SPH_C32(0x78a6000c), SPH_C32(0xac0fb60a), SPH_C32(0x63b62351), + SPH_C32(0x17e301eb), SPH_C32(0x7cb50000), SPH_C32(0xf285caee), + SPH_C32(0x06589f43), SPH_C32(0x2e548f6c) }, + { SPH_C32(0xf085000e), SPH_C32(0xf3e811b9), SPH_C32(0xfa53a6fb), + SPH_C32(0x9a96f61a), SPH_C32(0x2d190000), SPH_C32(0xd766c5fa), + SPH_C32(0x7fbab50f), SPH_C32(0x3ccc322a) }, + { SPH_C32(0x290a000c), SPH_C32(0x89ecb91e), SPH_C32(0x1a54091d), + SPH_C32(0x057bbcad), SPH_C32(0xa53a0002), SPH_C32(0x88816249), + SPH_C32(0xe65f30a5), SPH_C32(0xb1b9c5db) }, + { SPH_C32(0xa129000e), SPH_C32(0xd60b1ead), SPH_C32(0x83b18cb7), + SPH_C32(0x880e4b5c), SPH_C32(0xf4960002), SPH_C32(0xad626d5d), + SPH_C32(0x9fbd1ae9), SPH_C32(0xa321789d) }, + { SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), SPH_C32(0x66418f3c), + SPH_C32(0xce05ef02), SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), + SPH_C32(0x9b9d2f13), SPH_C32(0x811ea6b6) }, + { SPH_C32(0x4b24000a), SPH_C32(0x3f756764), SPH_C32(0xffa40a96), + SPH_C32(0x437018f3), SPH_C32(0xfd110004), SPH_C32(0x5b104a8d), + SPH_C32(0xe27f055f), SPH_C32(0x93861bf0) }, + { SPH_C32(0x92ab0008), SPH_C32(0x4571cfc3), SPH_C32(0x1fa3a570), + SPH_C32(0xdc9d5244), SPH_C32(0x75320006), SPH_C32(0x04f7ed3e), + SPH_C32(0x7b9a80f5), SPH_C32(0x1ef3ec01) }, + { SPH_C32(0x1a88000a), SPH_C32(0x1a966870), SPH_C32(0x864620da), + SPH_C32(0x51e8a5b5), SPH_C32(0x249e0006), SPH_C32(0x2114e22a), + SPH_C32(0x0278aab9), SPH_C32(0x0c6b5147) }, + { SPH_C32(0x130f000c), SPH_C32(0xece44fa0), SPH_C32(0xfb843f6c), + SPH_C32(0x614fc6d8), SPH_C32(0xc7140004), SPH_C32(0x3e18bc33), + SPH_C32(0x03af332e), SPH_C32(0xf7b26185) }, + { SPH_C32(0x9b2c000e), SPH_C32(0xb303e813), SPH_C32(0x6261bac6), + SPH_C32(0xec3a3129), SPH_C32(0x96b80004), SPH_C32(0x1bfbb327), + SPH_C32(0x7a4d1962), SPH_C32(0xe52adcc3) }, + { SPH_C32(0x42a3000c), SPH_C32(0xc90740b4), SPH_C32(0x82661520), + SPH_C32(0x73d77b9e), SPH_C32(0x1e9b0006), SPH_C32(0x441c1494), + SPH_C32(0xe3a89cc8), SPH_C32(0x685f2b32) }, + { SPH_C32(0xca80000e), SPH_C32(0x96e0e707), SPH_C32(0x1b83908a), + SPH_C32(0xfea28c6f), SPH_C32(0x4f370006), SPH_C32(0x61ff1b80), + SPH_C32(0x9a4ab684), SPH_C32(0x7ac79674) } +}; + +static const sph_u32 T256_30[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), SPH_C32(0xae0ebb05), + SPH_C32(0xb5a4c63b), SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), + SPH_C32(0x6bf648a4), SPH_C32(0x539cbdbf) }, + { SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), SPH_C32(0x6bf648a4), + SPH_C32(0x539cbdbf), SPH_C32(0x08bf0001), SPH_C32(0x38942792), + SPH_C32(0xc5f8f3a1), SPH_C32(0xe6387b84) }, + { SPH_C32(0x08bf0001), SPH_C32(0x38942792), SPH_C32(0xc5f8f3a1), + SPH_C32(0xe6387b84), SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), + SPH_C32(0xae0ebb05), SPH_C32(0xb5a4c63b) } +}; + +#define INPUT_SMALL do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T256_0[acc >> 3][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + acc = (acc << 8) | buf[1]; \ + rp = &T256_5[(acc >> 6) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_10[(acc >> 1) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = (acc << 8) | buf[2]; \ + rp = &T256_15[(acc >> 4) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = (acc << 8) | buf[3]; \ + rp = &T256_20[(acc >> 7) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_25[(acc >> 2) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_30[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_SMALL == 6 + +static const sph_u32 T256_0[64][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), SPH_C32(0x11fa3a57), + SPH_C32(0x3dc90524), SPH_C32(0x97530000), SPH_C32(0x204f6ed3), + SPH_C32(0x77b9e80f), SPH_C32(0xa1ec5ec1) }, + { SPH_C32(0x97530000), SPH_C32(0x204f6ed3), SPH_C32(0x77b9e80f), + SPH_C32(0xa1ec5ec1), SPH_C32(0x7e792000), SPH_C32(0x9418e22f), + SPH_C32(0x6643d258), SPH_C32(0x9c255be5) }, + { SPH_C32(0x7e792000), SPH_C32(0x9418e22f), SPH_C32(0x6643d258), + SPH_C32(0x9c255be5), SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), + SPH_C32(0x11fa3a57), SPH_C32(0x3dc90524) }, + { SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), SPH_C32(0x8dfacfab), + SPH_C32(0xce36cc72), SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), + SPH_C32(0x848598ba), SPH_C32(0x1041003e) }, + { SPH_C32(0xfb316000), SPH_C32(0xef405514), SPH_C32(0x9c00f5fc), + SPH_C32(0xf3ffc956), SPH_C32(0x71040000), SPH_C32(0x6bfc54f6), + SPH_C32(0xf33c70b5), SPH_C32(0xb1ad5eff) }, + { SPH_C32(0x85484000), SPH_C32(0x7b58b73b), SPH_C32(0xfa4327a4), + SPH_C32(0x6fda92b3), SPH_C32(0x982e2000), SPH_C32(0xdfabd80a), + SPH_C32(0xe2c64ae2), SPH_C32(0x8c645bdb) }, + { SPH_C32(0x6c626000), SPH_C32(0xcf0f3bc7), SPH_C32(0xebb91df3), + SPH_C32(0x52139797), SPH_C32(0x0f7d2000), SPH_C32(0xffe4b6d9), + SPH_C32(0x957fa2ed), SPH_C32(0x2d88051a) }, + { SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), SPH_C32(0x848598ba), + SPH_C32(0x1041003e), SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), + SPH_C32(0x097f5711), SPH_C32(0xde77cc4c) }, + { SPH_C32(0x0f7d2000), SPH_C32(0xffe4b6d9), SPH_C32(0x957fa2ed), + SPH_C32(0x2d88051a), SPH_C32(0x631f4000), SPH_C32(0x30eb8d1e), + SPH_C32(0x7ec6bf1e), SPH_C32(0x7f9b928d) }, + { SPH_C32(0x71040000), SPH_C32(0x6bfc54f6), SPH_C32(0xf33c70b5), + SPH_C32(0xb1ad5eff), SPH_C32(0x8a356000), SPH_C32(0x84bc01e2), + SPH_C32(0x6f3c8549), SPH_C32(0x425297a9) }, + { SPH_C32(0x982e2000), SPH_C32(0xdfabd80a), SPH_C32(0xe2c64ae2), + SPH_C32(0x8c645bdb), SPH_C32(0x1d666000), SPH_C32(0xa4f36f31), + SPH_C32(0x18856d46), SPH_C32(0xe3bec968) }, + { SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), SPH_C32(0x097f5711), + SPH_C32(0xde77cc4c), SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), + SPH_C32(0x8dfacfab), SPH_C32(0xce36cc72) }, + { SPH_C32(0x1d666000), SPH_C32(0xa4f36f31), SPH_C32(0x18856d46), + SPH_C32(0xe3bec968), SPH_C32(0x85484000), SPH_C32(0x7b58b73b), + SPH_C32(0xfa4327a4), SPH_C32(0x6fda92b3) }, + { SPH_C32(0x631f4000), SPH_C32(0x30eb8d1e), SPH_C32(0x7ec6bf1e), + SPH_C32(0x7f9b928d), SPH_C32(0x6c626000), SPH_C32(0xcf0f3bc7), + SPH_C32(0xebb91df3), SPH_C32(0x52139797) }, + { SPH_C32(0x8a356000), SPH_C32(0x84bc01e2), SPH_C32(0x6f3c8549), + SPH_C32(0x425297a9), SPH_C32(0xfb316000), SPH_C32(0xef405514), + SPH_C32(0x9c00f5fc), SPH_C32(0xf3ffc956) }, + { SPH_C32(0xe4788000), SPH_C32(0x859673c1), SPH_C32(0xb5fb2452), + SPH_C32(0x29cc5edf), SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), + SPH_C32(0x62fc79d0), SPH_C32(0x731ebdc2) }, + { SPH_C32(0x0d52a000), SPH_C32(0x31c1ff3d), SPH_C32(0xa4011e05), + SPH_C32(0x14055bfb), SPH_C32(0x930c0000), SPH_C32(0xbc05fd1a), + SPH_C32(0x154591df), SPH_C32(0xd2f2e303) }, + { SPH_C32(0x732b8000), SPH_C32(0xa5d91d12), SPH_C32(0xc242cc5d), + SPH_C32(0x8820001e), SPH_C32(0x7a262000), SPH_C32(0x085271e6), + SPH_C32(0x04bfab88), SPH_C32(0xef3be627) }, + { SPH_C32(0x9a01a000), SPH_C32(0x118e91ee), SPH_C32(0xd3b8f60a), + SPH_C32(0xb5e9053a), SPH_C32(0xed752000), SPH_C32(0x281d1f35), + SPH_C32(0x73064387), SPH_C32(0x4ed7b8e6) }, + { SPH_C32(0xf663c000), SPH_C32(0xde81aa29), SPH_C32(0x3801ebf9), + SPH_C32(0xe7fa92ad), SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), + SPH_C32(0xe679e16a), SPH_C32(0x635fbdfc) }, + { SPH_C32(0x1f49e000), SPH_C32(0x6ad626d5), SPH_C32(0x29fbd1ae), + SPH_C32(0xda339789), SPH_C32(0x755b0000), SPH_C32(0xf7b6c73f), + SPH_C32(0x91c00965), SPH_C32(0xc2b3e33d) }, + { SPH_C32(0x6130c000), SPH_C32(0xfecec4fa), SPH_C32(0x4fb803f6), + SPH_C32(0x4616cc6c), SPH_C32(0x9c712000), SPH_C32(0x43e14bc3), + SPH_C32(0x803a3332), SPH_C32(0xff7ae619) }, + { SPH_C32(0x881ae000), SPH_C32(0x4a994806), SPH_C32(0x5e4239a1), + SPH_C32(0x7bdfc948), SPH_C32(0x0b222000), SPH_C32(0x63ae2510), + SPH_C32(0xf783db3d), SPH_C32(0x5e96b8d8) }, + { SPH_C32(0x022f8000), SPH_C32(0xce2549e4), SPH_C32(0x317ebce8), + SPH_C32(0x398d5ee1), SPH_C32(0xf0134000), SPH_C32(0x8cee7004), + SPH_C32(0x6b832ec1), SPH_C32(0xad69718e) }, + { SPH_C32(0xeb05a000), SPH_C32(0x7a72c518), SPH_C32(0x208486bf), + SPH_C32(0x04445bc5), SPH_C32(0x67404000), SPH_C32(0xaca11ed7), + SPH_C32(0x1c3ac6ce), SPH_C32(0x0c852f4f) }, + { SPH_C32(0x957c8000), SPH_C32(0xee6a2737), SPH_C32(0x46c754e7), + SPH_C32(0x98610020), SPH_C32(0x8e6a6000), SPH_C32(0x18f6922b), + SPH_C32(0x0dc0fc99), SPH_C32(0x314c2a6b) }, + { SPH_C32(0x7c56a000), SPH_C32(0x5a3dabcb), SPH_C32(0x573d6eb0), + SPH_C32(0xa5a80504), SPH_C32(0x19396000), SPH_C32(0x38b9fcf8), + SPH_C32(0x7a791496), SPH_C32(0x90a074aa) }, + { SPH_C32(0x1034c000), SPH_C32(0x9532900c), SPH_C32(0xbc847343), + SPH_C32(0xf7bb9293), SPH_C32(0x16444000), SPH_C32(0xc75d4a21), + SPH_C32(0xef06b67b), SPH_C32(0xbd2871b0) }, + { SPH_C32(0xf91ee000), SPH_C32(0x21651cf0), SPH_C32(0xad7e4914), + SPH_C32(0xca7297b7), SPH_C32(0x81174000), SPH_C32(0xe71224f2), + SPH_C32(0x98bf5e74), SPH_C32(0x1cc42f71) }, + { SPH_C32(0x8767c000), SPH_C32(0xb57dfedf), SPH_C32(0xcb3d9b4c), + SPH_C32(0x5657cc52), SPH_C32(0x683d6000), SPH_C32(0x5345a80e), + SPH_C32(0x89456423), SPH_C32(0x210d2a55) }, + { SPH_C32(0x6e4de000), SPH_C32(0x012a7223), SPH_C32(0xdac7a11b), + SPH_C32(0x6b9ec976), SPH_C32(0xff6e6000), SPH_C32(0x730ac6dd), + SPH_C32(0xfefc8c2c), SPH_C32(0x80e17494) }, + { SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), SPH_C32(0x62fc79d0), + SPH_C32(0x731ebdc2), SPH_C32(0xe0278000), SPH_C32(0x19dce008), + SPH_C32(0xd7075d82), SPH_C32(0x5ad2e31d) }, + { SPH_C32(0xed752000), SPH_C32(0x281d1f35), SPH_C32(0x73064387), + SPH_C32(0x4ed7b8e6), SPH_C32(0x77748000), SPH_C32(0x39938edb), + SPH_C32(0xa0beb58d), SPH_C32(0xfb3ebddc) }, + { SPH_C32(0x930c0000), SPH_C32(0xbc05fd1a), SPH_C32(0x154591df), + SPH_C32(0xd2f2e303), SPH_C32(0x9e5ea000), SPH_C32(0x8dc40227), + SPH_C32(0xb1448fda), SPH_C32(0xc6f7b8f8) }, + { SPH_C32(0x7a262000), SPH_C32(0x085271e6), SPH_C32(0x04bfab88), + SPH_C32(0xef3be627), SPH_C32(0x090da000), SPH_C32(0xad8b6cf4), + SPH_C32(0xc6fd67d5), SPH_C32(0x671be639) }, + { SPH_C32(0x16444000), SPH_C32(0xc75d4a21), SPH_C32(0xef06b67b), + SPH_C32(0xbd2871b0), SPH_C32(0x06708000), SPH_C32(0x526fda2d), + SPH_C32(0x5382c538), SPH_C32(0x4a93e323) }, + { SPH_C32(0xff6e6000), SPH_C32(0x730ac6dd), SPH_C32(0xfefc8c2c), + SPH_C32(0x80e17494), SPH_C32(0x91238000), SPH_C32(0x7220b4fe), + SPH_C32(0x243b2d37), SPH_C32(0xeb7fbde2) }, + { SPH_C32(0x81174000), SPH_C32(0xe71224f2), SPH_C32(0x98bf5e74), + SPH_C32(0x1cc42f71), SPH_C32(0x7809a000), SPH_C32(0xc6773802), + SPH_C32(0x35c11760), SPH_C32(0xd6b6b8c6) }, + { SPH_C32(0x683d6000), SPH_C32(0x5345a80e), SPH_C32(0x89456423), + SPH_C32(0x210d2a55), SPH_C32(0xef5aa000), SPH_C32(0xe63856d1), + SPH_C32(0x4278ff6f), SPH_C32(0x775ae607) }, + { SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), SPH_C32(0xe679e16a), + SPH_C32(0x635fbdfc), SPH_C32(0x146bc000), SPH_C32(0x097803c5), + SPH_C32(0xde780a93), SPH_C32(0x84a52f51) }, + { SPH_C32(0x0b222000), SPH_C32(0x63ae2510), SPH_C32(0xf783db3d), + SPH_C32(0x5e96b8d8), SPH_C32(0x8338c000), SPH_C32(0x29376d16), + SPH_C32(0xa9c1e29c), SPH_C32(0x25497190) }, + { SPH_C32(0x755b0000), SPH_C32(0xf7b6c73f), SPH_C32(0x91c00965), + SPH_C32(0xc2b3e33d), SPH_C32(0x6a12e000), SPH_C32(0x9d60e1ea), + SPH_C32(0xb83bd8cb), SPH_C32(0x188074b4) }, + { SPH_C32(0x9c712000), SPH_C32(0x43e14bc3), SPH_C32(0x803a3332), + SPH_C32(0xff7ae619), SPH_C32(0xfd41e000), SPH_C32(0xbd2f8f39), + SPH_C32(0xcf8230c4), SPH_C32(0xb96c2a75) }, + { SPH_C32(0xf0134000), SPH_C32(0x8cee7004), SPH_C32(0x6b832ec1), + SPH_C32(0xad69718e), SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), + SPH_C32(0x5afd9229), SPH_C32(0x94e42f6f) }, + { SPH_C32(0x19396000), SPH_C32(0x38b9fcf8), SPH_C32(0x7a791496), + SPH_C32(0x90a074aa), SPH_C32(0x656fc000), SPH_C32(0x62845733), + SPH_C32(0x2d447a26), SPH_C32(0x350871ae) }, + { SPH_C32(0x67404000), SPH_C32(0xaca11ed7), SPH_C32(0x1c3ac6ce), + SPH_C32(0x0c852f4f), SPH_C32(0x8c45e000), SPH_C32(0xd6d3dbcf), + SPH_C32(0x3cbe4071), SPH_C32(0x08c1748a) }, + { SPH_C32(0x8e6a6000), SPH_C32(0x18f6922b), SPH_C32(0x0dc0fc99), + SPH_C32(0x314c2a6b), SPH_C32(0x1b16e000), SPH_C32(0xf69cb51c), + SPH_C32(0x4b07a87e), SPH_C32(0xa92d2a4b) }, + { SPH_C32(0xe0278000), SPH_C32(0x19dce008), SPH_C32(0xd7075d82), + SPH_C32(0x5ad2e31d), SPH_C32(0xe4788000), SPH_C32(0x859673c1), + SPH_C32(0xb5fb2452), SPH_C32(0x29cc5edf) }, + { SPH_C32(0x090da000), SPH_C32(0xad8b6cf4), SPH_C32(0xc6fd67d5), + SPH_C32(0x671be639), SPH_C32(0x732b8000), SPH_C32(0xa5d91d12), + SPH_C32(0xc242cc5d), SPH_C32(0x8820001e) }, + { SPH_C32(0x77748000), SPH_C32(0x39938edb), SPH_C32(0xa0beb58d), + SPH_C32(0xfb3ebddc), SPH_C32(0x9a01a000), SPH_C32(0x118e91ee), + SPH_C32(0xd3b8f60a), SPH_C32(0xb5e9053a) }, + { SPH_C32(0x9e5ea000), SPH_C32(0x8dc40227), SPH_C32(0xb1448fda), + SPH_C32(0xc6f7b8f8), SPH_C32(0x0d52a000), SPH_C32(0x31c1ff3d), + SPH_C32(0xa4011e05), SPH_C32(0x14055bfb) }, + { SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), SPH_C32(0x5afd9229), + SPH_C32(0x94e42f6f), SPH_C32(0x022f8000), SPH_C32(0xce2549e4), + SPH_C32(0x317ebce8), SPH_C32(0x398d5ee1) }, + { SPH_C32(0x1b16e000), SPH_C32(0xf69cb51c), SPH_C32(0x4b07a87e), + SPH_C32(0xa92d2a4b), SPH_C32(0x957c8000), SPH_C32(0xee6a2737), + SPH_C32(0x46c754e7), SPH_C32(0x98610020) }, + { SPH_C32(0x656fc000), SPH_C32(0x62845733), SPH_C32(0x2d447a26), + SPH_C32(0x350871ae), SPH_C32(0x7c56a000), SPH_C32(0x5a3dabcb), + SPH_C32(0x573d6eb0), SPH_C32(0xa5a80504) }, + { SPH_C32(0x8c45e000), SPH_C32(0xd6d3dbcf), SPH_C32(0x3cbe4071), + SPH_C32(0x08c1748a), SPH_C32(0xeb05a000), SPH_C32(0x7a72c518), + SPH_C32(0x208486bf), SPH_C32(0x04445bc5) }, + { SPH_C32(0x06708000), SPH_C32(0x526fda2d), SPH_C32(0x5382c538), + SPH_C32(0x4a93e323), SPH_C32(0x1034c000), SPH_C32(0x9532900c), + SPH_C32(0xbc847343), SPH_C32(0xf7bb9293) }, + { SPH_C32(0xef5aa000), SPH_C32(0xe63856d1), SPH_C32(0x4278ff6f), + SPH_C32(0x775ae607), SPH_C32(0x8767c000), SPH_C32(0xb57dfedf), + SPH_C32(0xcb3d9b4c), SPH_C32(0x5657cc52) }, + { SPH_C32(0x91238000), SPH_C32(0x7220b4fe), SPH_C32(0x243b2d37), + SPH_C32(0xeb7fbde2), SPH_C32(0x6e4de000), SPH_C32(0x012a7223), + SPH_C32(0xdac7a11b), SPH_C32(0x6b9ec976) }, + { SPH_C32(0x7809a000), SPH_C32(0xc6773802), SPH_C32(0x35c11760), + SPH_C32(0xd6b6b8c6), SPH_C32(0xf91ee000), SPH_C32(0x21651cf0), + SPH_C32(0xad7e4914), SPH_C32(0xca7297b7) }, + { SPH_C32(0x146bc000), SPH_C32(0x097803c5), SPH_C32(0xde780a93), + SPH_C32(0x84a52f51), SPH_C32(0xf663c000), SPH_C32(0xde81aa29), + SPH_C32(0x3801ebf9), SPH_C32(0xe7fa92ad) }, + { SPH_C32(0xfd41e000), SPH_C32(0xbd2f8f39), SPH_C32(0xcf8230c4), + SPH_C32(0xb96c2a75), SPH_C32(0x6130c000), SPH_C32(0xfecec4fa), + SPH_C32(0x4fb803f6), SPH_C32(0x4616cc6c) }, + { SPH_C32(0x8338c000), SPH_C32(0x29376d16), SPH_C32(0xa9c1e29c), + SPH_C32(0x25497190), SPH_C32(0x881ae000), SPH_C32(0x4a994806), + SPH_C32(0x5e4239a1), SPH_C32(0x7bdfc948) }, + { SPH_C32(0x6a12e000), SPH_C32(0x9d60e1ea), SPH_C32(0xb83bd8cb), + SPH_C32(0x188074b4), SPH_C32(0x1f49e000), SPH_C32(0x6ad626d5), + SPH_C32(0x29fbd1ae), SPH_C32(0xda339789) } +}; + +static const sph_u32 T256_6[64][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), SPH_C32(0x6fc548e1), + SPH_C32(0x898d2cd6), SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), + SPH_C32(0x6a72e5bb), SPH_C32(0x247febe6) }, + { SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), SPH_C32(0x6a72e5bb), + SPH_C32(0x247febe6), SPH_C32(0x9b830400), SPH_C32(0x2227ff88), + SPH_C32(0x05b7ad5a), SPH_C32(0xadf2c730) }, + { SPH_C32(0x9b830400), SPH_C32(0x2227ff88), SPH_C32(0x05b7ad5a), + SPH_C32(0xadf2c730), SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), + SPH_C32(0x6fc548e1), SPH_C32(0x898d2cd6) }, + { SPH_C32(0xde320800), SPH_C32(0x288350fe), SPH_C32(0x71852ac7), + SPH_C32(0xa6bf9f96), SPH_C32(0xe18b0000), SPH_C32(0x5459887d), + SPH_C32(0xbf1283d3), SPH_C32(0x1b666a73) }, + { SPH_C32(0x510c0c00), SPH_C32(0x251e9889), SPH_C32(0x1e406226), + SPH_C32(0x2f32b340), SPH_C32(0xf5360000), SPH_C32(0x7be3bf82), + SPH_C32(0xd5606668), SPH_C32(0x3f198195) }, + { SPH_C32(0xca8f0800), SPH_C32(0x07396701), SPH_C32(0x1bf7cf7c), + SPH_C32(0x82c07470), SPH_C32(0x7a080400), SPH_C32(0x767e77f5), + SPH_C32(0xbaa52e89), SPH_C32(0xb694ad43) }, + { SPH_C32(0x45b10c00), SPH_C32(0x0aa4af76), SPH_C32(0x7432879d), + SPH_C32(0x0b4d58a6), SPH_C32(0x6eb50400), SPH_C32(0x59c4400a), + SPH_C32(0xd0d7cb32), SPH_C32(0x92eb46a5) }, + { SPH_C32(0xe18b0000), SPH_C32(0x5459887d), SPH_C32(0xbf1283d3), + SPH_C32(0x1b666a73), SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), + SPH_C32(0xce97a914), SPH_C32(0xbdd9f5e5) }, + { SPH_C32(0x6eb50400), SPH_C32(0x59c4400a), SPH_C32(0xd0d7cb32), + SPH_C32(0x92eb46a5), SPH_C32(0x2b040800), SPH_C32(0x5360ef7c), + SPH_C32(0xa4e54caf), SPH_C32(0x99a61e03) }, + { SPH_C32(0xf5360000), SPH_C32(0x7be3bf82), SPH_C32(0xd5606668), + SPH_C32(0x3f198195), SPH_C32(0xa43a0c00), SPH_C32(0x5efd270b), + SPH_C32(0xcb20044e), SPH_C32(0x102b32d5) }, + { SPH_C32(0x7a080400), SPH_C32(0x767e77f5), SPH_C32(0xbaa52e89), + SPH_C32(0xb694ad43), SPH_C32(0xb0870c00), SPH_C32(0x714710f4), + SPH_C32(0xa152e1f5), SPH_C32(0x3454d933) }, + { SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), SPH_C32(0xce97a914), + SPH_C32(0xbdd9f5e5), SPH_C32(0xde320800), SPH_C32(0x288350fe), + SPH_C32(0x71852ac7), SPH_C32(0xa6bf9f96) }, + { SPH_C32(0xb0870c00), SPH_C32(0x714710f4), SPH_C32(0xa152e1f5), + SPH_C32(0x3454d933), SPH_C32(0xca8f0800), SPH_C32(0x07396701), + SPH_C32(0x1bf7cf7c), SPH_C32(0x82c07470) }, + { SPH_C32(0x2b040800), SPH_C32(0x5360ef7c), SPH_C32(0xa4e54caf), + SPH_C32(0x99a61e03), SPH_C32(0x45b10c00), SPH_C32(0x0aa4af76), + SPH_C32(0x7432879d), SPH_C32(0x0b4d58a6) }, + { SPH_C32(0xa43a0c00), SPH_C32(0x5efd270b), SPH_C32(0xcb20044e), + SPH_C32(0x102b32d5), SPH_C32(0x510c0c00), SPH_C32(0x251e9889), + SPH_C32(0x1e406226), SPH_C32(0x2f32b340) }, + { SPH_C32(0x74951000), SPH_C32(0x5a2b467e), SPH_C32(0x88fd1d2b), + SPH_C32(0x1ee68292), SPH_C32(0xcba90000), SPH_C32(0x90273769), + SPH_C32(0xbbdcf407), SPH_C32(0xd0f4af61) }, + { SPH_C32(0xfbab1400), SPH_C32(0x57b68e09), SPH_C32(0xe73855ca), + SPH_C32(0x976bae44), SPH_C32(0xdf140000), SPH_C32(0xbf9d0096), + SPH_C32(0xd1ae11bc), SPH_C32(0xf48b4487) }, + { SPH_C32(0x60281000), SPH_C32(0x75917181), SPH_C32(0xe28ff890), + SPH_C32(0x3a996974), SPH_C32(0x502a0400), SPH_C32(0xb200c8e1), + SPH_C32(0xbe6b595d), SPH_C32(0x7d066851) }, + { SPH_C32(0xef161400), SPH_C32(0x780cb9f6), SPH_C32(0x8d4ab071), + SPH_C32(0xb31445a2), SPH_C32(0x44970400), SPH_C32(0x9dbaff1e), + SPH_C32(0xd419bce6), SPH_C32(0x597983b7) }, + { SPH_C32(0xaaa71800), SPH_C32(0x72a81680), SPH_C32(0xf97837ec), + SPH_C32(0xb8591d04), SPH_C32(0x2a220000), SPH_C32(0xc47ebf14), + SPH_C32(0x04ce77d4), SPH_C32(0xcb92c512) }, + { SPH_C32(0x25991c00), SPH_C32(0x7f35def7), SPH_C32(0x96bd7f0d), + SPH_C32(0x31d431d2), SPH_C32(0x3e9f0000), SPH_C32(0xebc488eb), + SPH_C32(0x6ebc926f), SPH_C32(0xefed2ef4) }, + { SPH_C32(0xbe1a1800), SPH_C32(0x5d12217f), SPH_C32(0x930ad257), + SPH_C32(0x9c26f6e2), SPH_C32(0xb1a10400), SPH_C32(0xe659409c), + SPH_C32(0x0179da8e), SPH_C32(0x66600222) }, + { SPH_C32(0x31241c00), SPH_C32(0x508fe908), SPH_C32(0xfccf9ab6), + SPH_C32(0x15abda34), SPH_C32(0xa51c0400), SPH_C32(0xc9e37763), + SPH_C32(0x6b0b3f35), SPH_C32(0x421fe9c4) }, + { SPH_C32(0x951e1000), SPH_C32(0x0e72ce03), SPH_C32(0x37ef9ef8), + SPH_C32(0x0580e8e1), SPH_C32(0xf4100800), SPH_C32(0xecfdefea), + SPH_C32(0x754b5d13), SPH_C32(0x6d2d5a84) }, + { SPH_C32(0x1a201400), SPH_C32(0x03ef0674), SPH_C32(0x582ad619), + SPH_C32(0x8c0dc437), SPH_C32(0xe0ad0800), SPH_C32(0xc347d815), + SPH_C32(0x1f39b8a8), SPH_C32(0x4952b162) }, + { SPH_C32(0x81a31000), SPH_C32(0x21c8f9fc), SPH_C32(0x5d9d7b43), + SPH_C32(0x21ff0307), SPH_C32(0x6f930c00), SPH_C32(0xceda1062), + SPH_C32(0x70fcf049), SPH_C32(0xc0df9db4) }, + { SPH_C32(0x0e9d1400), SPH_C32(0x2c55318b), SPH_C32(0x325833a2), + SPH_C32(0xa8722fd1), SPH_C32(0x7b2e0c00), SPH_C32(0xe160279d), + SPH_C32(0x1a8e15f2), SPH_C32(0xe4a07652) }, + { SPH_C32(0x4b2c1800), SPH_C32(0x26f19efd), SPH_C32(0x466ab43f), + SPH_C32(0xa33f7777), SPH_C32(0x159b0800), SPH_C32(0xb8a46797), + SPH_C32(0xca59dec0), SPH_C32(0x764b30f7) }, + { SPH_C32(0xc4121c00), SPH_C32(0x2b6c568a), SPH_C32(0x29affcde), + SPH_C32(0x2ab25ba1), SPH_C32(0x01260800), SPH_C32(0x971e5068), + SPH_C32(0xa02b3b7b), SPH_C32(0x5234db11) }, + { SPH_C32(0x5f911800), SPH_C32(0x094ba902), SPH_C32(0x2c185184), + SPH_C32(0x87409c91), SPH_C32(0x8e180c00), SPH_C32(0x9a83981f), + SPH_C32(0xcfee739a), SPH_C32(0xdbb9f7c7) }, + { SPH_C32(0xd0af1c00), SPH_C32(0x04d66175), SPH_C32(0x43dd1965), + SPH_C32(0x0ecdb047), SPH_C32(0x9aa50c00), SPH_C32(0xb539afe0), + SPH_C32(0xa59c9621), SPH_C32(0xffc61c21) }, + { SPH_C32(0xcba90000), SPH_C32(0x90273769), SPH_C32(0xbbdcf407), + SPH_C32(0xd0f4af61), SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), + SPH_C32(0x3321e92c), SPH_C32(0xce122df3) }, + { SPH_C32(0x44970400), SPH_C32(0x9dbaff1e), SPH_C32(0xd419bce6), + SPH_C32(0x597983b7), SPH_C32(0xab811000), SPH_C32(0xe5b646e8), + SPH_C32(0x59530c97), SPH_C32(0xea6dc615) }, + { SPH_C32(0xdf140000), SPH_C32(0xbf9d0096), SPH_C32(0xd1ae11bc), + SPH_C32(0xf48b4487), SPH_C32(0x24bf1400), SPH_C32(0xe82b8e9f), + SPH_C32(0x36964476), SPH_C32(0x63e0eac3) }, + { SPH_C32(0x502a0400), SPH_C32(0xb200c8e1), SPH_C32(0xbe6b595d), + SPH_C32(0x7d066851), SPH_C32(0x30021400), SPH_C32(0xc791b960), + SPH_C32(0x5ce4a1cd), SPH_C32(0x479f0125) }, + { SPH_C32(0x159b0800), SPH_C32(0xb8a46797), SPH_C32(0xca59dec0), + SPH_C32(0x764b30f7), SPH_C32(0x5eb71000), SPH_C32(0x9e55f96a), + SPH_C32(0x8c336aff), SPH_C32(0xd5744780) }, + { SPH_C32(0x9aa50c00), SPH_C32(0xb539afe0), SPH_C32(0xa59c9621), + SPH_C32(0xffc61c21), SPH_C32(0x4a0a1000), SPH_C32(0xb1efce95), + SPH_C32(0xe6418f44), SPH_C32(0xf10bac66) }, + { SPH_C32(0x01260800), SPH_C32(0x971e5068), SPH_C32(0xa02b3b7b), + SPH_C32(0x5234db11), SPH_C32(0xc5341400), SPH_C32(0xbc7206e2), + SPH_C32(0x8984c7a5), SPH_C32(0x788680b0) }, + { SPH_C32(0x8e180c00), SPH_C32(0x9a83981f), SPH_C32(0xcfee739a), + SPH_C32(0xdbb9f7c7), SPH_C32(0xd1891400), SPH_C32(0x93c8311d), + SPH_C32(0xe3f6221e), SPH_C32(0x5cf96b56) }, + { SPH_C32(0x2a220000), SPH_C32(0xc47ebf14), SPH_C32(0x04ce77d4), + SPH_C32(0xcb92c512), SPH_C32(0x80851800), SPH_C32(0xb6d6a994), + SPH_C32(0xfdb64038), SPH_C32(0x73cbd816) }, + { SPH_C32(0xa51c0400), SPH_C32(0xc9e37763), SPH_C32(0x6b0b3f35), + SPH_C32(0x421fe9c4), SPH_C32(0x94381800), SPH_C32(0x996c9e6b), + SPH_C32(0x97c4a583), SPH_C32(0x57b433f0) }, + { SPH_C32(0x3e9f0000), SPH_C32(0xebc488eb), SPH_C32(0x6ebc926f), + SPH_C32(0xefed2ef4), SPH_C32(0x1b061c00), SPH_C32(0x94f1561c), + SPH_C32(0xf801ed62), SPH_C32(0xde391f26) }, + { SPH_C32(0xb1a10400), SPH_C32(0xe659409c), SPH_C32(0x0179da8e), + SPH_C32(0x66600222), SPH_C32(0x0fbb1c00), SPH_C32(0xbb4b61e3), + SPH_C32(0x927308d9), SPH_C32(0xfa46f4c0) }, + { SPH_C32(0xf4100800), SPH_C32(0xecfdefea), SPH_C32(0x754b5d13), + SPH_C32(0x6d2d5a84), SPH_C32(0x610e1800), SPH_C32(0xe28f21e9), + SPH_C32(0x42a4c3eb), SPH_C32(0x68adb265) }, + { SPH_C32(0x7b2e0c00), SPH_C32(0xe160279d), SPH_C32(0x1a8e15f2), + SPH_C32(0xe4a07652), SPH_C32(0x75b31800), SPH_C32(0xcd351616), + SPH_C32(0x28d62650), SPH_C32(0x4cd25983) }, + { SPH_C32(0xe0ad0800), SPH_C32(0xc347d815), SPH_C32(0x1f39b8a8), + SPH_C32(0x4952b162), SPH_C32(0xfa8d1c00), SPH_C32(0xc0a8de61), + SPH_C32(0x47136eb1), SPH_C32(0xc55f7555) }, + { SPH_C32(0x6f930c00), SPH_C32(0xceda1062), SPH_C32(0x70fcf049), + SPH_C32(0xc0df9db4), SPH_C32(0xee301c00), SPH_C32(0xef12e99e), + SPH_C32(0x2d618b0a), SPH_C32(0xe1209eb3) }, + { SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), SPH_C32(0x3321e92c), + SPH_C32(0xce122df3), SPH_C32(0x74951000), SPH_C32(0x5a2b467e), + SPH_C32(0x88fd1d2b), SPH_C32(0x1ee68292) }, + { SPH_C32(0x30021400), SPH_C32(0xc791b960), SPH_C32(0x5ce4a1cd), + SPH_C32(0x479f0125), SPH_C32(0x60281000), SPH_C32(0x75917181), + SPH_C32(0xe28ff890), SPH_C32(0x3a996974) }, + { SPH_C32(0xab811000), SPH_C32(0xe5b646e8), SPH_C32(0x59530c97), + SPH_C32(0xea6dc615), SPH_C32(0xef161400), SPH_C32(0x780cb9f6), + SPH_C32(0x8d4ab071), SPH_C32(0xb31445a2) }, + { SPH_C32(0x24bf1400), SPH_C32(0xe82b8e9f), SPH_C32(0x36964476), + SPH_C32(0x63e0eac3), SPH_C32(0xfbab1400), SPH_C32(0x57b68e09), + SPH_C32(0xe73855ca), SPH_C32(0x976bae44) }, + { SPH_C32(0x610e1800), SPH_C32(0xe28f21e9), SPH_C32(0x42a4c3eb), + SPH_C32(0x68adb265), SPH_C32(0x951e1000), SPH_C32(0x0e72ce03), + SPH_C32(0x37ef9ef8), SPH_C32(0x0580e8e1) }, + { SPH_C32(0xee301c00), SPH_C32(0xef12e99e), SPH_C32(0x2d618b0a), + SPH_C32(0xe1209eb3), SPH_C32(0x81a31000), SPH_C32(0x21c8f9fc), + SPH_C32(0x5d9d7b43), SPH_C32(0x21ff0307) }, + { SPH_C32(0x75b31800), SPH_C32(0xcd351616), SPH_C32(0x28d62650), + SPH_C32(0x4cd25983), SPH_C32(0x0e9d1400), SPH_C32(0x2c55318b), + SPH_C32(0x325833a2), SPH_C32(0xa8722fd1) }, + { SPH_C32(0xfa8d1c00), SPH_C32(0xc0a8de61), SPH_C32(0x47136eb1), + SPH_C32(0xc55f7555), SPH_C32(0x1a201400), SPH_C32(0x03ef0674), + SPH_C32(0x582ad619), SPH_C32(0x8c0dc437) }, + { SPH_C32(0x5eb71000), SPH_C32(0x9e55f96a), SPH_C32(0x8c336aff), + SPH_C32(0xd5744780), SPH_C32(0x4b2c1800), SPH_C32(0x26f19efd), + SPH_C32(0x466ab43f), SPH_C32(0xa33f7777) }, + { SPH_C32(0xd1891400), SPH_C32(0x93c8311d), SPH_C32(0xe3f6221e), + SPH_C32(0x5cf96b56), SPH_C32(0x5f911800), SPH_C32(0x094ba902), + SPH_C32(0x2c185184), SPH_C32(0x87409c91) }, + { SPH_C32(0x4a0a1000), SPH_C32(0xb1efce95), SPH_C32(0xe6418f44), + SPH_C32(0xf10bac66), SPH_C32(0xd0af1c00), SPH_C32(0x04d66175), + SPH_C32(0x43dd1965), SPH_C32(0x0ecdb047) }, + { SPH_C32(0xc5341400), SPH_C32(0xbc7206e2), SPH_C32(0x8984c7a5), + SPH_C32(0x788680b0), SPH_C32(0xc4121c00), SPH_C32(0x2b6c568a), + SPH_C32(0x29affcde), SPH_C32(0x2ab25ba1) }, + { SPH_C32(0x80851800), SPH_C32(0xb6d6a994), SPH_C32(0xfdb64038), + SPH_C32(0x73cbd816), SPH_C32(0xaaa71800), SPH_C32(0x72a81680), + SPH_C32(0xf97837ec), SPH_C32(0xb8591d04) }, + { SPH_C32(0x0fbb1c00), SPH_C32(0xbb4b61e3), SPH_C32(0x927308d9), + SPH_C32(0xfa46f4c0), SPH_C32(0xbe1a1800), SPH_C32(0x5d12217f), + SPH_C32(0x930ad257), SPH_C32(0x9c26f6e2) }, + { SPH_C32(0x94381800), SPH_C32(0x996c9e6b), SPH_C32(0x97c4a583), + SPH_C32(0x57b433f0), SPH_C32(0x31241c00), SPH_C32(0x508fe908), + SPH_C32(0xfccf9ab6), SPH_C32(0x15abda34) }, + { SPH_C32(0x1b061c00), SPH_C32(0x94f1561c), SPH_C32(0xf801ed62), + SPH_C32(0xde391f26), SPH_C32(0x25991c00), SPH_C32(0x7f35def7), + SPH_C32(0x96bd7f0d), SPH_C32(0x31d431d2) } +}; + +static const sph_u32 T256_12[64][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), SPH_C32(0xc2c46c55), + SPH_C32(0xf362b233), SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), + SPH_C32(0xd14e094b), SPH_C32(0xb772b42b) }, + { SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), SPH_C32(0xd14e094b), + SPH_C32(0xb772b42b), SPH_C32(0x62740080), SPH_C32(0x0fb84b07), + SPH_C32(0x138a651e), SPH_C32(0x44100618) }, + { SPH_C32(0x62740080), SPH_C32(0x0fb84b07), SPH_C32(0x138a651e), + SPH_C32(0x44100618), SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), + SPH_C32(0xc2c46c55), SPH_C32(0xf362b233) }, + { SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), SPH_C32(0x8589d8ab), + SPH_C32(0xe6c46464), SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), + SPH_C32(0xa29d1297), SPH_C32(0x6ee56854) }, + { SPH_C32(0xec760180), SPH_C32(0xcf102934), SPH_C32(0x474db4fe), + SPH_C32(0x15a6d657), SPH_C32(0x4aea0000), SPH_C32(0xdfd8f43d), + SPH_C32(0x73d31bdc), SPH_C32(0xd997dc7f) }, + { SPH_C32(0x8e020100), SPH_C32(0xc0a86233), SPH_C32(0x54c7d1e0), + SPH_C32(0x51b6d04f), SPH_C32(0x11380080), SPH_C32(0x9ad7ecd1), + SPH_C32(0xb1177789), SPH_C32(0x2af56e4c) }, + { SPH_C32(0xd5d00180), SPH_C32(0x85a77adf), SPH_C32(0x9603bdb5), + SPH_C32(0xa2d4627c), SPH_C32(0x289e0080), SPH_C32(0xd060bf3a), + SPH_C32(0x60597ec2), SPH_C32(0x9d87da67) }, + { SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), SPH_C32(0xa29d1297), + SPH_C32(0x6ee56854), SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), + SPH_C32(0x2714ca3c), SPH_C32(0x88210c30) }, + { SPH_C32(0x289e0080), SPH_C32(0xd060bf3a), SPH_C32(0x60597ec2), + SPH_C32(0x9d87da67), SPH_C32(0xfd4e0100), SPH_C32(0x55c7c5e5), + SPH_C32(0xf65ac377), SPH_C32(0x3f53b81b) }, + { SPH_C32(0x4aea0000), SPH_C32(0xdfd8f43d), SPH_C32(0x73d31bdc), + SPH_C32(0xd997dc7f), SPH_C32(0xa69c0180), SPH_C32(0x10c8dd09), + SPH_C32(0x349eaf22), SPH_C32(0xcc310a28) }, + { SPH_C32(0x11380080), SPH_C32(0x9ad7ecd1), SPH_C32(0xb1177789), + SPH_C32(0x2af56e4c), SPH_C32(0x9f3a0180), SPH_C32(0x5a7f8ee2), + SPH_C32(0xe5d0a669), SPH_C32(0x7b43be03) }, + { SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), SPH_C32(0x2714ca3c), + SPH_C32(0x88210c30), SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), + SPH_C32(0x8589d8ab), SPH_C32(0xe6c46464) }, + { SPH_C32(0x9f3a0180), SPH_C32(0x5a7f8ee2), SPH_C32(0xe5d0a669), + SPH_C32(0x7b43be03), SPH_C32(0x8e020100), SPH_C32(0xc0a86233), + SPH_C32(0x54c7d1e0), SPH_C32(0x51b6d04f) }, + { SPH_C32(0xfd4e0100), SPH_C32(0x55c7c5e5), SPH_C32(0xf65ac377), + SPH_C32(0x3f53b81b), SPH_C32(0xd5d00180), SPH_C32(0x85a77adf), + SPH_C32(0x9603bdb5), SPH_C32(0xa2d4627c) }, + { SPH_C32(0xa69c0180), SPH_C32(0x10c8dd09), SPH_C32(0x349eaf22), + SPH_C32(0xcc310a28), SPH_C32(0xec760180), SPH_C32(0xcf102934), + SPH_C32(0x474db4fe), SPH_C32(0x15a6d657) }, + { SPH_C32(0xa7b80200), SPH_C32(0x1f128433), SPH_C32(0x60e5f9f2), + SPH_C32(0x9e147576), SPH_C32(0xee260000), SPH_C32(0x124b683e), + SPH_C32(0x80c2d68f), SPH_C32(0x3bf3ab2c) }, + { SPH_C32(0xfc6a0280), SPH_C32(0x5a1d9cdf), SPH_C32(0xa22195a7), + SPH_C32(0x6d76c745), SPH_C32(0xd7800000), SPH_C32(0x58fc3bd5), + SPH_C32(0x518cdfc4), SPH_C32(0x8c811f07) }, + { SPH_C32(0x9e1e0200), SPH_C32(0x55a5d7d8), SPH_C32(0xb1abf0b9), + SPH_C32(0x2966c15d), SPH_C32(0x8c520080), SPH_C32(0x1df32339), + SPH_C32(0x9348b391), SPH_C32(0x7fe3ad34) }, + { SPH_C32(0xc5cc0280), SPH_C32(0x10aacf34), SPH_C32(0x736f9cec), + SPH_C32(0xda04736e), SPH_C32(0xb5f40080), SPH_C32(0x574470d2), + SPH_C32(0x4206bada), SPH_C32(0xc891191f) }, + { SPH_C32(0x101c0300), SPH_C32(0x950db5eb), SPH_C32(0xe56c2159), + SPH_C32(0x78d01112), SPH_C32(0x9d6a0000), SPH_C32(0x8724cfe8), + SPH_C32(0x225fc418), SPH_C32(0x5516c378) }, + { SPH_C32(0x4bce0380), SPH_C32(0xd002ad07), SPH_C32(0x27a84d0c), + SPH_C32(0x8bb2a321), SPH_C32(0xa4cc0000), SPH_C32(0xcd939c03), + SPH_C32(0xf311cd53), SPH_C32(0xe2647753) }, + { SPH_C32(0x29ba0300), SPH_C32(0xdfbae600), SPH_C32(0x34222812), + SPH_C32(0xcfa2a539), SPH_C32(0xff1e0080), SPH_C32(0x889c84ef), + SPH_C32(0x31d5a106), SPH_C32(0x1106c560) }, + { SPH_C32(0x72680380), SPH_C32(0x9ab5feec), SPH_C32(0xf6e64447), + SPH_C32(0x3cc0170a), SPH_C32(0xc6b80080), SPH_C32(0xc22bd704), + SPH_C32(0xe09ba84d), SPH_C32(0xa674714b) }, + { SPH_C32(0xd4f40200), SPH_C32(0x8a7d23e5), SPH_C32(0xc278eb65), + SPH_C32(0xf0f11d22), SPH_C32(0x2ace0100), SPH_C32(0x0d3bfe30), + SPH_C32(0xa7d61cb3), SPH_C32(0xb3d2a71c) }, + { SPH_C32(0x8f260280), SPH_C32(0xcf723b09), SPH_C32(0x00bc8730), + SPH_C32(0x0393af11), SPH_C32(0x13680100), SPH_C32(0x478caddb), + SPH_C32(0x769815f8), SPH_C32(0x04a01337) }, + { SPH_C32(0xed520200), SPH_C32(0xc0ca700e), SPH_C32(0x1336e22e), + SPH_C32(0x4783a909), SPH_C32(0x48ba0180), SPH_C32(0x0283b537), + SPH_C32(0xb45c79ad), SPH_C32(0xf7c2a104) }, + { SPH_C32(0xb6800280), SPH_C32(0x85c568e2), SPH_C32(0xd1f28e7b), + SPH_C32(0xb4e11b3a), SPH_C32(0x711c0180), SPH_C32(0x4834e6dc), + SPH_C32(0x651270e6), SPH_C32(0x40b0152f) }, + { SPH_C32(0x63500300), SPH_C32(0x0062123d), SPH_C32(0x47f133ce), + SPH_C32(0x16357946), SPH_C32(0x59820100), SPH_C32(0x985459e6), + SPH_C32(0x054b0e24), SPH_C32(0xdd37cf48) }, + { SPH_C32(0x38820380), SPH_C32(0x456d0ad1), SPH_C32(0x85355f9b), + SPH_C32(0xe557cb75), SPH_C32(0x60240100), SPH_C32(0xd2e30a0d), + SPH_C32(0xd405076f), SPH_C32(0x6a457b63) }, + { SPH_C32(0x5af60300), SPH_C32(0x4ad541d6), SPH_C32(0x96bf3a85), + SPH_C32(0xa147cd6d), SPH_C32(0x3bf60180), SPH_C32(0x97ec12e1), + SPH_C32(0x16c16b3a), SPH_C32(0x9927c950) }, + { SPH_C32(0x01240380), SPH_C32(0x0fda593a), SPH_C32(0x547b56d0), + SPH_C32(0x52257f5e), SPH_C32(0x02500180), SPH_C32(0xdd5b410a), + SPH_C32(0xc78f6271), SPH_C32(0x2e557d7b) }, + { SPH_C32(0xee260000), SPH_C32(0x124b683e), SPH_C32(0x80c2d68f), + SPH_C32(0x3bf3ab2c), SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), + SPH_C32(0xe0272f7d), SPH_C32(0xa5e7de5a) }, + { SPH_C32(0xb5f40080), SPH_C32(0x574470d2), SPH_C32(0x4206bada), + SPH_C32(0xc891191f), SPH_C32(0x70380200), SPH_C32(0x47eebfe6), + SPH_C32(0x31692636), SPH_C32(0x12956a71) }, + { SPH_C32(0xd7800000), SPH_C32(0x58fc3bd5), SPH_C32(0x518cdfc4), + SPH_C32(0x8c811f07), SPH_C32(0x2bea0280), SPH_C32(0x02e1a70a), + SPH_C32(0xf3ad4a63), SPH_C32(0xe1f7d842) }, + { SPH_C32(0x8c520080), SPH_C32(0x1df32339), SPH_C32(0x9348b391), + SPH_C32(0x7fe3ad34), SPH_C32(0x124c0280), SPH_C32(0x4856f4e1), + SPH_C32(0x22e34328), SPH_C32(0x56856c69) }, + { SPH_C32(0x59820100), SPH_C32(0x985459e6), SPH_C32(0x054b0e24), + SPH_C32(0xdd37cf48), SPH_C32(0x3ad20200), SPH_C32(0x98364bdb), + SPH_C32(0x42ba3dea), SPH_C32(0xcb02b60e) }, + { SPH_C32(0x02500180), SPH_C32(0xdd5b410a), SPH_C32(0xc78f6271), + SPH_C32(0x2e557d7b), SPH_C32(0x03740200), SPH_C32(0xd2811830), + SPH_C32(0x93f434a1), SPH_C32(0x7c700225) }, + { SPH_C32(0x60240100), SPH_C32(0xd2e30a0d), SPH_C32(0xd405076f), + SPH_C32(0x6a457b63), SPH_C32(0x58a60280), SPH_C32(0x978e00dc), + SPH_C32(0x513058f4), SPH_C32(0x8f12b016) }, + { SPH_C32(0x3bf60180), SPH_C32(0x97ec12e1), SPH_C32(0x16c16b3a), + SPH_C32(0x9927c950), SPH_C32(0x61000280), SPH_C32(0xdd395337), + SPH_C32(0x807e51bf), SPH_C32(0x3860043d) }, + { SPH_C32(0x9d6a0000), SPH_C32(0x8724cfe8), SPH_C32(0x225fc418), + SPH_C32(0x5516c378), SPH_C32(0x8d760300), SPH_C32(0x12297a03), + SPH_C32(0xc733e541), SPH_C32(0x2dc6d26a) }, + { SPH_C32(0xc6b80080), SPH_C32(0xc22bd704), SPH_C32(0xe09ba84d), + SPH_C32(0xa674714b), SPH_C32(0xb4d00300), SPH_C32(0x589e29e8), + SPH_C32(0x167dec0a), SPH_C32(0x9ab46641) }, + { SPH_C32(0xa4cc0000), SPH_C32(0xcd939c03), SPH_C32(0xf311cd53), + SPH_C32(0xe2647753), SPH_C32(0xef020380), SPH_C32(0x1d913104), + SPH_C32(0xd4b9805f), SPH_C32(0x69d6d472) }, + { SPH_C32(0xff1e0080), SPH_C32(0x889c84ef), SPH_C32(0x31d5a106), + SPH_C32(0x1106c560), SPH_C32(0xd6a40380), SPH_C32(0x572662ef), + SPH_C32(0x05f78914), SPH_C32(0xdea46059) }, + { SPH_C32(0x2ace0100), SPH_C32(0x0d3bfe30), SPH_C32(0xa7d61cb3), + SPH_C32(0xb3d2a71c), SPH_C32(0xfe3a0300), SPH_C32(0x8746ddd5), + SPH_C32(0x65aef7d6), SPH_C32(0x4323ba3e) }, + { SPH_C32(0x711c0180), SPH_C32(0x4834e6dc), SPH_C32(0x651270e6), + SPH_C32(0x40b0152f), SPH_C32(0xc79c0300), SPH_C32(0xcdf18e3e), + SPH_C32(0xb4e0fe9d), SPH_C32(0xf4510e15) }, + { SPH_C32(0x13680100), SPH_C32(0x478caddb), SPH_C32(0x769815f8), + SPH_C32(0x04a01337), SPH_C32(0x9c4e0380), SPH_C32(0x88fe96d2), + SPH_C32(0x762492c8), SPH_C32(0x0733bc26) }, + { SPH_C32(0x48ba0180), SPH_C32(0x0283b537), SPH_C32(0xb45c79ad), + SPH_C32(0xf7c2a104), SPH_C32(0xa5e80380), SPH_C32(0xc249c539), + SPH_C32(0xa76a9b83), SPH_C32(0xb041080d) }, + { SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), SPH_C32(0xe0272f7d), + SPH_C32(0xa5e7de5a), SPH_C32(0xa7b80200), SPH_C32(0x1f128433), + SPH_C32(0x60e5f9f2), SPH_C32(0x9e147576) }, + { SPH_C32(0x124c0280), SPH_C32(0x4856f4e1), SPH_C32(0x22e34328), + SPH_C32(0x56856c69), SPH_C32(0x9e1e0200), SPH_C32(0x55a5d7d8), + SPH_C32(0xb1abf0b9), SPH_C32(0x2966c15d) }, + { SPH_C32(0x70380200), SPH_C32(0x47eebfe6), SPH_C32(0x31692636), + SPH_C32(0x12956a71), SPH_C32(0xc5cc0280), SPH_C32(0x10aacf34), + SPH_C32(0x736f9cec), SPH_C32(0xda04736e) }, + { SPH_C32(0x2bea0280), SPH_C32(0x02e1a70a), SPH_C32(0xf3ad4a63), + SPH_C32(0xe1f7d842), SPH_C32(0xfc6a0280), SPH_C32(0x5a1d9cdf), + SPH_C32(0xa22195a7), SPH_C32(0x6d76c745) }, + { SPH_C32(0xfe3a0300), SPH_C32(0x8746ddd5), SPH_C32(0x65aef7d6), + SPH_C32(0x4323ba3e), SPH_C32(0xd4f40200), SPH_C32(0x8a7d23e5), + SPH_C32(0xc278eb65), SPH_C32(0xf0f11d22) }, + { SPH_C32(0xa5e80380), SPH_C32(0xc249c539), SPH_C32(0xa76a9b83), + SPH_C32(0xb041080d), SPH_C32(0xed520200), SPH_C32(0xc0ca700e), + SPH_C32(0x1336e22e), SPH_C32(0x4783a909) }, + { SPH_C32(0xc79c0300), SPH_C32(0xcdf18e3e), SPH_C32(0xb4e0fe9d), + SPH_C32(0xf4510e15), SPH_C32(0xb6800280), SPH_C32(0x85c568e2), + SPH_C32(0xd1f28e7b), SPH_C32(0xb4e11b3a) }, + { SPH_C32(0x9c4e0380), SPH_C32(0x88fe96d2), SPH_C32(0x762492c8), + SPH_C32(0x0733bc26), SPH_C32(0x8f260280), SPH_C32(0xcf723b09), + SPH_C32(0x00bc8730), SPH_C32(0x0393af11) }, + { SPH_C32(0x3ad20200), SPH_C32(0x98364bdb), SPH_C32(0x42ba3dea), + SPH_C32(0xcb02b60e), SPH_C32(0x63500300), SPH_C32(0x0062123d), + SPH_C32(0x47f133ce), SPH_C32(0x16357946) }, + { SPH_C32(0x61000280), SPH_C32(0xdd395337), SPH_C32(0x807e51bf), + SPH_C32(0x3860043d), SPH_C32(0x5af60300), SPH_C32(0x4ad541d6), + SPH_C32(0x96bf3a85), SPH_C32(0xa147cd6d) }, + { SPH_C32(0x03740200), SPH_C32(0xd2811830), SPH_C32(0x93f434a1), + SPH_C32(0x7c700225), SPH_C32(0x01240380), SPH_C32(0x0fda593a), + SPH_C32(0x547b56d0), SPH_C32(0x52257f5e) }, + { SPH_C32(0x58a60280), SPH_C32(0x978e00dc), SPH_C32(0x513058f4), + SPH_C32(0x8f12b016), SPH_C32(0x38820380), SPH_C32(0x456d0ad1), + SPH_C32(0x85355f9b), SPH_C32(0xe557cb75) }, + { SPH_C32(0x8d760300), SPH_C32(0x12297a03), SPH_C32(0xc733e541), + SPH_C32(0x2dc6d26a), SPH_C32(0x101c0300), SPH_C32(0x950db5eb), + SPH_C32(0xe56c2159), SPH_C32(0x78d01112) }, + { SPH_C32(0xd6a40380), SPH_C32(0x572662ef), SPH_C32(0x05f78914), + SPH_C32(0xdea46059), SPH_C32(0x29ba0300), SPH_C32(0xdfbae600), + SPH_C32(0x34222812), SPH_C32(0xcfa2a539) }, + { SPH_C32(0xb4d00300), SPH_C32(0x589e29e8), SPH_C32(0x167dec0a), + SPH_C32(0x9ab46641), SPH_C32(0x72680380), SPH_C32(0x9ab5feec), + SPH_C32(0xf6e64447), SPH_C32(0x3cc0170a) }, + { SPH_C32(0xef020380), SPH_C32(0x1d913104), SPH_C32(0xd4b9805f), + SPH_C32(0x69d6d472), SPH_C32(0x4bce0380), SPH_C32(0xd002ad07), + SPH_C32(0x27a84d0c), SPH_C32(0x8bb2a321) } +}; + +static const sph_u32 T256_18[64][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x515c0010), SPH_C32(0x40f372fb), SPH_C32(0xfce72602), + SPH_C32(0x71575061), SPH_C32(0x2e390000), SPH_C32(0x64dd6689), + SPH_C32(0x3cd406fc), SPH_C32(0xb1f490bc) }, + { SPH_C32(0x2e390000), SPH_C32(0x64dd6689), SPH_C32(0x3cd406fc), + SPH_C32(0xb1f490bc), SPH_C32(0x7f650010), SPH_C32(0x242e1472), + SPH_C32(0xc03320fe), SPH_C32(0xc0a3c0dd) }, + { SPH_C32(0x7f650010), SPH_C32(0x242e1472), SPH_C32(0xc03320fe), + SPH_C32(0xc0a3c0dd), SPH_C32(0x515c0010), SPH_C32(0x40f372fb), + SPH_C32(0xfce72602), SPH_C32(0x71575061) }, + { SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), SPH_C32(0xf9ce4c04), + SPH_C32(0xe2afa0c0), SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), + SPH_C32(0x79a90df9), SPH_C32(0x63e92178) }, + { SPH_C32(0xf3e40030), SPH_C32(0xc114970d), SPH_C32(0x05296a06), + SPH_C32(0x93f8f0a1), SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), + SPH_C32(0x457d0b05), SPH_C32(0xd21db1c4) }, + { SPH_C32(0x8c810020), SPH_C32(0xe53a837f), SPH_C32(0xc51a4af8), + SPH_C32(0x535b307c), SPH_C32(0x23170010), SPH_C32(0xed94d960), + SPH_C32(0xb99a2d07), SPH_C32(0xa34ae1a5) }, + { SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), SPH_C32(0x39fd6cfa), + SPH_C32(0x220c601d), SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), + SPH_C32(0x854e2bfb), SPH_C32(0x12be7119) }, + { SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), SPH_C32(0x79a90df9), + SPH_C32(0x63e92178), SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), + SPH_C32(0x806741fd), SPH_C32(0x814681b8) }, + { SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), SPH_C32(0x854e2bfb), + SPH_C32(0x12be7119), SPH_C32(0xd0f30020), SPH_C32(0x2c804e6d), + SPH_C32(0xbcb34701), SPH_C32(0x30b21104) }, + { SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), SPH_C32(0x457d0b05), + SPH_C32(0xd21db1c4), SPH_C32(0x81af0030), SPH_C32(0x6c733c96), + SPH_C32(0x40546103), SPH_C32(0x41e54165) }, + { SPH_C32(0x23170010), SPH_C32(0xed94d960), SPH_C32(0xb99a2d07), + SPH_C32(0xa34ae1a5), SPH_C32(0xaf960030), SPH_C32(0x08ae5a1f), + SPH_C32(0x7c8067ff), SPH_C32(0xf011d1d9) }, + { SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), SPH_C32(0x806741fd), + SPH_C32(0x814681b8), SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), + SPH_C32(0xf9ce4c04), SPH_C32(0xe2afa0c0) }, + { SPH_C32(0xaf960030), SPH_C32(0x08ae5a1f), SPH_C32(0x7c8067ff), + SPH_C32(0xf011d1d9), SPH_C32(0x8c810020), SPH_C32(0xe53a837f), + SPH_C32(0xc51a4af8), SPH_C32(0x535b307c) }, + { SPH_C32(0xd0f30020), SPH_C32(0x2c804e6d), SPH_C32(0xbcb34701), + SPH_C32(0x30b21104), SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), + SPH_C32(0x39fd6cfa), SPH_C32(0x220c601d) }, + { SPH_C32(0x81af0030), SPH_C32(0x6c733c96), SPH_C32(0x40546103), + SPH_C32(0x41e54165), SPH_C32(0xf3e40030), SPH_C32(0xc114970d), + SPH_C32(0x05296a06), SPH_C32(0x93f8f0a1) }, + { SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), SPH_C32(0x36656ba8), + SPH_C32(0x23633a05), SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), + SPH_C32(0x5d5ca0f7), SPH_C32(0x727784cb) }, + { SPH_C32(0x1c920050), SPH_C32(0x7ba89e85), SPH_C32(0xca824daa), + SPH_C32(0x52346a64), SPH_C32(0x56920000), SPH_C32(0xc4103cbd), + SPH_C32(0x6188a60b), SPH_C32(0xc3831477) }, + { SPH_C32(0x63f70040), SPH_C32(0x5f868af7), SPH_C32(0x0ab16d54), + SPH_C32(0x9297aab9), SPH_C32(0x07ce0010), SPH_C32(0x84e34e46), + SPH_C32(0x9d6f8009), SPH_C32(0xb2d44416) }, + { SPH_C32(0x32ab0050), SPH_C32(0x1f75f80c), SPH_C32(0xf6564b56), + SPH_C32(0xe3c0fad8), SPH_C32(0x29f70010), SPH_C32(0xe03e28cf), + SPH_C32(0xa1bb86f5), SPH_C32(0x0320d4aa) }, + { SPH_C32(0xef760060), SPH_C32(0xbabc0988), SPH_C32(0xcfab27ac), + SPH_C32(0xc1cc9ac5), SPH_C32(0x24d90000), SPH_C32(0x69779726), + SPH_C32(0x24f5ad0e), SPH_C32(0x119ea5b3) }, + { SPH_C32(0xbe2a0070), SPH_C32(0xfa4f7b73), SPH_C32(0x334c01ae), + SPH_C32(0xb09bcaa4), SPH_C32(0x0ae00000), SPH_C32(0x0daaf1af), + SPH_C32(0x1821abf2), SPH_C32(0xa06a350f) }, + { SPH_C32(0xc14f0060), SPH_C32(0xde616f01), SPH_C32(0xf37f2150), + SPH_C32(0x70380a79), SPH_C32(0x5bbc0010), SPH_C32(0x4d598354), + SPH_C32(0xe4c68df0), SPH_C32(0xd13d656e) }, + { SPH_C32(0x90130070), SPH_C32(0x9e921dfa), SPH_C32(0x0f980752), + SPH_C32(0x016f5a18), SPH_C32(0x75850010), SPH_C32(0x2984e5dd), + SPH_C32(0xd8128b0c), SPH_C32(0x60c9f5d2) }, + { SPH_C32(0x11bc0040), SPH_C32(0xf2e1216c), SPH_C32(0x4fcc6651), + SPH_C32(0x408a1b7d), SPH_C32(0x86610020), SPH_C32(0xe89072d0), + SPH_C32(0xdd3be10a), SPH_C32(0xf3310573) }, + { SPH_C32(0x40e00050), SPH_C32(0xb2125397), SPH_C32(0xb32b4053), + SPH_C32(0x31dd4b1c), SPH_C32(0xa8580020), SPH_C32(0x8c4d1459), + SPH_C32(0xe1efe7f6), SPH_C32(0x42c595cf) }, + { SPH_C32(0x3f850040), SPH_C32(0x963c47e5), SPH_C32(0x731860ad), + SPH_C32(0xf17e8bc1), SPH_C32(0xf9040030), SPH_C32(0xccbe66a2), + SPH_C32(0x1d08c1f4), SPH_C32(0x3392c5ae) }, + { SPH_C32(0x6ed90050), SPH_C32(0xd6cf351e), SPH_C32(0x8fff46af), + SPH_C32(0x8029dba0), SPH_C32(0xd73d0030), SPH_C32(0xa863002b), + SPH_C32(0x21dcc708), SPH_C32(0x82665512) }, + { SPH_C32(0xb3040060), SPH_C32(0x7306c49a), SPH_C32(0xb6022a55), + SPH_C32(0xa225bbbd), SPH_C32(0xda130020), SPH_C32(0x212abfc2), + SPH_C32(0xa492ecf3), SPH_C32(0x90d8240b) }, + { SPH_C32(0xe2580070), SPH_C32(0x33f5b661), SPH_C32(0x4ae50c57), + SPH_C32(0xd372ebdc), SPH_C32(0xf42a0020), SPH_C32(0x45f7d94b), + SPH_C32(0x9846ea0f), SPH_C32(0x212cb4b7) }, + { SPH_C32(0x9d3d0060), SPH_C32(0x17dba213), SPH_C32(0x8ad62ca9), + SPH_C32(0x13d12b01), SPH_C32(0xa5760030), SPH_C32(0x0504abb0), + SPH_C32(0x64a1cc0d), SPH_C32(0x507be4d6) }, + { SPH_C32(0xcc610070), SPH_C32(0x5728d0e8), SPH_C32(0x76310aab), + SPH_C32(0x62867b60), SPH_C32(0x8b4f0030), SPH_C32(0x61d9cd39), + SPH_C32(0x5875caf1), SPH_C32(0xe18f746a) }, + { SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), SPH_C32(0x5d5ca0f7), + SPH_C32(0x727784cb), SPH_C32(0x35650040), SPH_C32(0x9b96b64a), + SPH_C32(0x6b39cb5f), SPH_C32(0x5114bece) }, + { SPH_C32(0x29f70010), SPH_C32(0xe03e28cf), SPH_C32(0xa1bb86f5), + SPH_C32(0x0320d4aa), SPH_C32(0x1b5c0040), SPH_C32(0xff4bd0c3), + SPH_C32(0x57edcda3), SPH_C32(0xe0e02e72) }, + { SPH_C32(0x56920000), SPH_C32(0xc4103cbd), SPH_C32(0x6188a60b), + SPH_C32(0xc3831477), SPH_C32(0x4a000050), SPH_C32(0xbfb8a238), + SPH_C32(0xab0aeba1), SPH_C32(0x91b77e13) }, + { SPH_C32(0x07ce0010), SPH_C32(0x84e34e46), SPH_C32(0x9d6f8009), + SPH_C32(0xb2d44416), SPH_C32(0x64390050), SPH_C32(0xdb65c4b1), + SPH_C32(0x97deed5d), SPH_C32(0x2043eeaf) }, + { SPH_C32(0xda130020), SPH_C32(0x212abfc2), SPH_C32(0xa492ecf3), + SPH_C32(0x90d8240b), SPH_C32(0x69170040), SPH_C32(0x522c7b58), + SPH_C32(0x1290c6a6), SPH_C32(0x32fd9fb6) }, + { SPH_C32(0x8b4f0030), SPH_C32(0x61d9cd39), SPH_C32(0x5875caf1), + SPH_C32(0xe18f746a), SPH_C32(0x472e0040), SPH_C32(0x36f11dd1), + SPH_C32(0x2e44c05a), SPH_C32(0x83090f0a) }, + { SPH_C32(0xf42a0020), SPH_C32(0x45f7d94b), SPH_C32(0x9846ea0f), + SPH_C32(0x212cb4b7), SPH_C32(0x16720050), SPH_C32(0x76026f2a), + SPH_C32(0xd2a3e658), SPH_C32(0xf25e5f6b) }, + { SPH_C32(0xa5760030), SPH_C32(0x0504abb0), SPH_C32(0x64a1cc0d), + SPH_C32(0x507be4d6), SPH_C32(0x384b0050), SPH_C32(0x12df09a3), + SPH_C32(0xee77e0a4), SPH_C32(0x43aacfd7) }, + { SPH_C32(0x24d90000), SPH_C32(0x69779726), SPH_C32(0x24f5ad0e), + SPH_C32(0x119ea5b3), SPH_C32(0xcbaf0060), SPH_C32(0xd3cb9eae), + SPH_C32(0xeb5e8aa2), SPH_C32(0xd0523f76) }, + { SPH_C32(0x75850010), SPH_C32(0x2984e5dd), SPH_C32(0xd8128b0c), + SPH_C32(0x60c9f5d2), SPH_C32(0xe5960060), SPH_C32(0xb716f827), + SPH_C32(0xd78a8c5e), SPH_C32(0x61a6afca) }, + { SPH_C32(0x0ae00000), SPH_C32(0x0daaf1af), SPH_C32(0x1821abf2), + SPH_C32(0xa06a350f), SPH_C32(0xb4ca0070), SPH_C32(0xf7e58adc), + SPH_C32(0x2b6daa5c), SPH_C32(0x10f1ffab) }, + { SPH_C32(0x5bbc0010), SPH_C32(0x4d598354), SPH_C32(0xe4c68df0), + SPH_C32(0xd13d656e), SPH_C32(0x9af30070), SPH_C32(0x9338ec55), + SPH_C32(0x17b9aca0), SPH_C32(0xa1056f17) }, + { SPH_C32(0x86610020), SPH_C32(0xe89072d0), SPH_C32(0xdd3be10a), + SPH_C32(0xf3310573), SPH_C32(0x97dd0060), SPH_C32(0x1a7153bc), + SPH_C32(0x92f7875b), SPH_C32(0xb3bb1e0e) }, + { SPH_C32(0xd73d0030), SPH_C32(0xa863002b), SPH_C32(0x21dcc708), + SPH_C32(0x82665512), SPH_C32(0xb9e40060), SPH_C32(0x7eac3535), + SPH_C32(0xae2381a7), SPH_C32(0x024f8eb2) }, + { SPH_C32(0xa8580020), SPH_C32(0x8c4d1459), SPH_C32(0xe1efe7f6), + SPH_C32(0x42c595cf), SPH_C32(0xe8b80070), SPH_C32(0x3e5f47ce), + SPH_C32(0x52c4a7a5), SPH_C32(0x7318ded3) }, + { SPH_C32(0xf9040030), SPH_C32(0xccbe66a2), SPH_C32(0x1d08c1f4), + SPH_C32(0x3392c5ae), SPH_C32(0xc6810070), SPH_C32(0x5a822147), + SPH_C32(0x6e10a159), SPH_C32(0xc2ec4e6f) }, + { SPH_C32(0x35650040), SPH_C32(0x9b96b64a), SPH_C32(0x6b39cb5f), + SPH_C32(0x5114bece), SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), + SPH_C32(0x36656ba8), SPH_C32(0x23633a05) }, + { SPH_C32(0x64390050), SPH_C32(0xdb65c4b1), SPH_C32(0x97deed5d), + SPH_C32(0x2043eeaf), SPH_C32(0x63f70040), SPH_C32(0x5f868af7), + SPH_C32(0x0ab16d54), SPH_C32(0x9297aab9) }, + { SPH_C32(0x1b5c0040), SPH_C32(0xff4bd0c3), SPH_C32(0x57edcda3), + SPH_C32(0xe0e02e72), SPH_C32(0x32ab0050), SPH_C32(0x1f75f80c), + SPH_C32(0xf6564b56), SPH_C32(0xe3c0fad8) }, + { SPH_C32(0x4a000050), SPH_C32(0xbfb8a238), SPH_C32(0xab0aeba1), + SPH_C32(0x91b77e13), SPH_C32(0x1c920050), SPH_C32(0x7ba89e85), + SPH_C32(0xca824daa), SPH_C32(0x52346a64) }, + { SPH_C32(0x97dd0060), SPH_C32(0x1a7153bc), SPH_C32(0x92f7875b), + SPH_C32(0xb3bb1e0e), SPH_C32(0x11bc0040), SPH_C32(0xf2e1216c), + SPH_C32(0x4fcc6651), SPH_C32(0x408a1b7d) }, + { SPH_C32(0xc6810070), SPH_C32(0x5a822147), SPH_C32(0x6e10a159), + SPH_C32(0xc2ec4e6f), SPH_C32(0x3f850040), SPH_C32(0x963c47e5), + SPH_C32(0x731860ad), SPH_C32(0xf17e8bc1) }, + { SPH_C32(0xb9e40060), SPH_C32(0x7eac3535), SPH_C32(0xae2381a7), + SPH_C32(0x024f8eb2), SPH_C32(0x6ed90050), SPH_C32(0xd6cf351e), + SPH_C32(0x8fff46af), SPH_C32(0x8029dba0) }, + { SPH_C32(0xe8b80070), SPH_C32(0x3e5f47ce), SPH_C32(0x52c4a7a5), + SPH_C32(0x7318ded3), SPH_C32(0x40e00050), SPH_C32(0xb2125397), + SPH_C32(0xb32b4053), SPH_C32(0x31dd4b1c) }, + { SPH_C32(0x69170040), SPH_C32(0x522c7b58), SPH_C32(0x1290c6a6), + SPH_C32(0x32fd9fb6), SPH_C32(0xb3040060), SPH_C32(0x7306c49a), + SPH_C32(0xb6022a55), SPH_C32(0xa225bbbd) }, + { SPH_C32(0x384b0050), SPH_C32(0x12df09a3), SPH_C32(0xee77e0a4), + SPH_C32(0x43aacfd7), SPH_C32(0x9d3d0060), SPH_C32(0x17dba213), + SPH_C32(0x8ad62ca9), SPH_C32(0x13d12b01) }, + { SPH_C32(0x472e0040), SPH_C32(0x36f11dd1), SPH_C32(0x2e44c05a), + SPH_C32(0x83090f0a), SPH_C32(0xcc610070), SPH_C32(0x5728d0e8), + SPH_C32(0x76310aab), SPH_C32(0x62867b60) }, + { SPH_C32(0x16720050), SPH_C32(0x76026f2a), SPH_C32(0xd2a3e658), + SPH_C32(0xf25e5f6b), SPH_C32(0xe2580070), SPH_C32(0x33f5b661), + SPH_C32(0x4ae50c57), SPH_C32(0xd372ebdc) }, + { SPH_C32(0xcbaf0060), SPH_C32(0xd3cb9eae), SPH_C32(0xeb5e8aa2), + SPH_C32(0xd0523f76), SPH_C32(0xef760060), SPH_C32(0xbabc0988), + SPH_C32(0xcfab27ac), SPH_C32(0xc1cc9ac5) }, + { SPH_C32(0x9af30070), SPH_C32(0x9338ec55), SPH_C32(0x17b9aca0), + SPH_C32(0xa1056f17), SPH_C32(0xc14f0060), SPH_C32(0xde616f01), + SPH_C32(0xf37f2150), SPH_C32(0x70380a79) }, + { SPH_C32(0xe5960060), SPH_C32(0xb716f827), SPH_C32(0xd78a8c5e), + SPH_C32(0x61a6afca), SPH_C32(0x90130070), SPH_C32(0x9e921dfa), + SPH_C32(0x0f980752), SPH_C32(0x016f5a18) }, + { SPH_C32(0xb4ca0070), SPH_C32(0xf7e58adc), SPH_C32(0x2b6daa5c), + SPH_C32(0x10f1ffab), SPH_C32(0xbe2a0070), SPH_C32(0xfa4f7b73), + SPH_C32(0x334c01ae), SPH_C32(0xb09bcaa4) } +}; + +static const sph_u32 T256_24[64][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), SPH_C32(0x99e585aa), + SPH_C32(0x8d75f7f1), SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), + SPH_C32(0x79e22a4c), SPH_C32(0x1298bd46) }, + { SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), SPH_C32(0x79e22a4c), + SPH_C32(0x1298bd46), SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), + SPH_C32(0xe007afe6), SPH_C32(0x9fed4ab7) }, + { SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), SPH_C32(0xe007afe6), + SPH_C32(0x9fed4ab7), SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), + SPH_C32(0x99e585aa), SPH_C32(0x8d75f7f1) }, + { SPH_C32(0xd0080004), SPH_C32(0x8c768f77), SPH_C32(0x9dc5b050), + SPH_C32(0xaf4a29da), SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), + SPH_C32(0x98321c3d), SPH_C32(0x76acc733) }, + { SPH_C32(0x582b0006), SPH_C32(0xd39128c4), SPH_C32(0x042035fa), + SPH_C32(0x223fde2b), SPH_C32(0x3a050000), SPH_C32(0x6508f6be), + SPH_C32(0xe1d03671), SPH_C32(0x64347a75) }, + { SPH_C32(0x81a40004), SPH_C32(0xa9958063), SPH_C32(0xe4279a1c), + SPH_C32(0xbdd2949c), SPH_C32(0xb2260002), SPH_C32(0x3aef510d), + SPH_C32(0x7835b3db), SPH_C32(0xe9418d84) }, + { SPH_C32(0x09870006), SPH_C32(0xf67227d0), SPH_C32(0x7dc21fb6), + SPH_C32(0x30a7636d), SPH_C32(0xe38a0002), SPH_C32(0x1f0c5e19), + SPH_C32(0x01d79997), SPH_C32(0xfbd930c2) }, + { SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), SPH_C32(0x98321c3d), + SPH_C32(0x76acc733), SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), + SPH_C32(0x05f7ac6d), SPH_C32(0xd9e6eee9) }, + { SPH_C32(0xe38a0002), SPH_C32(0x1f0c5e19), SPH_C32(0x01d79997), + SPH_C32(0xfbd930c2), SPH_C32(0xea0d0004), SPH_C32(0xe97e79c9), + SPH_C32(0x7c158621), SPH_C32(0xcb7e53af) }, + { SPH_C32(0x3a050000), SPH_C32(0x6508f6be), SPH_C32(0xe1d03671), + SPH_C32(0x64347a75), SPH_C32(0x622e0006), SPH_C32(0xb699de7a), + SPH_C32(0xe5f0038b), SPH_C32(0x460ba45e) }, + { SPH_C32(0xb2260002), SPH_C32(0x3aef510d), SPH_C32(0x7835b3db), + SPH_C32(0xe9418d84), SPH_C32(0x33820006), SPH_C32(0x937ad16e), + SPH_C32(0x9c1229c7), SPH_C32(0x54931918) }, + { SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), SPH_C32(0x05f7ac6d), + SPH_C32(0xd9e6eee9), SPH_C32(0xd0080004), SPH_C32(0x8c768f77), + SPH_C32(0x9dc5b050), SPH_C32(0xaf4a29da) }, + { SPH_C32(0x33820006), SPH_C32(0x937ad16e), SPH_C32(0x9c1229c7), + SPH_C32(0x54931918), SPH_C32(0x81a40004), SPH_C32(0xa9958063), + SPH_C32(0xe4279a1c), SPH_C32(0xbdd2949c) }, + { SPH_C32(0xea0d0004), SPH_C32(0xe97e79c9), SPH_C32(0x7c158621), + SPH_C32(0xcb7e53af), SPH_C32(0x09870006), SPH_C32(0xf67227d0), + SPH_C32(0x7dc21fb6), SPH_C32(0x30a7636d) }, + { SPH_C32(0x622e0006), SPH_C32(0xb699de7a), SPH_C32(0xe5f0038b), + SPH_C32(0x460ba45e), SPH_C32(0x582b0006), SPH_C32(0xd39128c4), + SPH_C32(0x042035fa), SPH_C32(0x223fde2b) }, + { SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), SPH_C32(0xfe739301), + SPH_C32(0xb8a92831), SPH_C32(0x171c0000), SPH_C32(0xb26e3344), + SPH_C32(0x9e6a837e), SPH_C32(0x58f8485f) }, + { SPH_C32(0x208d000a), SPH_C32(0x7f9e9ece), SPH_C32(0x679616ab), + SPH_C32(0x35dcdfc0), SPH_C32(0x46b00000), SPH_C32(0x978d3c50), + SPH_C32(0xe788a932), SPH_C32(0x4a60f519) }, + { SPH_C32(0xf9020008), SPH_C32(0x059a3669), SPH_C32(0x8791b94d), + SPH_C32(0xaa319577), SPH_C32(0xce930002), SPH_C32(0xc86a9be3), + SPH_C32(0x7e6d2c98), SPH_C32(0xc71502e8) }, + { SPH_C32(0x7121000a), SPH_C32(0x5a7d91da), SPH_C32(0x1e743ce7), + SPH_C32(0x27446286), SPH_C32(0x9f3f0002), SPH_C32(0xed8994f7), + SPH_C32(0x078f06d4), SPH_C32(0xd58dbfae) }, + { SPH_C32(0x78a6000c), SPH_C32(0xac0fb60a), SPH_C32(0x63b62351), + SPH_C32(0x17e301eb), SPH_C32(0x7cb50000), SPH_C32(0xf285caee), + SPH_C32(0x06589f43), SPH_C32(0x2e548f6c) }, + { SPH_C32(0xf085000e), SPH_C32(0xf3e811b9), SPH_C32(0xfa53a6fb), + SPH_C32(0x9a96f61a), SPH_C32(0x2d190000), SPH_C32(0xd766c5fa), + SPH_C32(0x7fbab50f), SPH_C32(0x3ccc322a) }, + { SPH_C32(0x290a000c), SPH_C32(0x89ecb91e), SPH_C32(0x1a54091d), + SPH_C32(0x057bbcad), SPH_C32(0xa53a0002), SPH_C32(0x88816249), + SPH_C32(0xe65f30a5), SPH_C32(0xb1b9c5db) }, + { SPH_C32(0xa129000e), SPH_C32(0xd60b1ead), SPH_C32(0x83b18cb7), + SPH_C32(0x880e4b5c), SPH_C32(0xf4960002), SPH_C32(0xad626d5d), + SPH_C32(0x9fbd1ae9), SPH_C32(0xa321789d) }, + { SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), SPH_C32(0x66418f3c), + SPH_C32(0xce05ef02), SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), + SPH_C32(0x9b9d2f13), SPH_C32(0x811ea6b6) }, + { SPH_C32(0x4b24000a), SPH_C32(0x3f756764), SPH_C32(0xffa40a96), + SPH_C32(0x437018f3), SPH_C32(0xfd110004), SPH_C32(0x5b104a8d), + SPH_C32(0xe27f055f), SPH_C32(0x93861bf0) }, + { SPH_C32(0x92ab0008), SPH_C32(0x4571cfc3), SPH_C32(0x1fa3a570), + SPH_C32(0xdc9d5244), SPH_C32(0x75320006), SPH_C32(0x04f7ed3e), + SPH_C32(0x7b9a80f5), SPH_C32(0x1ef3ec01) }, + { SPH_C32(0x1a88000a), SPH_C32(0x1a966870), SPH_C32(0x864620da), + SPH_C32(0x51e8a5b5), SPH_C32(0x249e0006), SPH_C32(0x2114e22a), + SPH_C32(0x0278aab9), SPH_C32(0x0c6b5147) }, + { SPH_C32(0x130f000c), SPH_C32(0xece44fa0), SPH_C32(0xfb843f6c), + SPH_C32(0x614fc6d8), SPH_C32(0xc7140004), SPH_C32(0x3e18bc33), + SPH_C32(0x03af332e), SPH_C32(0xf7b26185) }, + { SPH_C32(0x9b2c000e), SPH_C32(0xb303e813), SPH_C32(0x6261bac6), + SPH_C32(0xec3a3129), SPH_C32(0x96b80004), SPH_C32(0x1bfbb327), + SPH_C32(0x7a4d1962), SPH_C32(0xe52adcc3) }, + { SPH_C32(0x42a3000c), SPH_C32(0xc90740b4), SPH_C32(0x82661520), + SPH_C32(0x73d77b9e), SPH_C32(0x1e9b0006), SPH_C32(0x441c1494), + SPH_C32(0xe3a89cc8), SPH_C32(0x685f2b32) }, + { SPH_C32(0xca80000e), SPH_C32(0x96e0e707), SPH_C32(0x1b83908a), + SPH_C32(0xfea28c6f), SPH_C32(0x4f370006), SPH_C32(0x61ff1b80), + SPH_C32(0x9a4ab684), SPH_C32(0x7ac79674) }, + { SPH_C32(0x171c0000), SPH_C32(0xb26e3344), SPH_C32(0x9e6a837e), + SPH_C32(0x58f8485f), SPH_C32(0xbfb20008), SPH_C32(0x92170a39), + SPH_C32(0x6019107f), SPH_C32(0xe051606e) }, + { SPH_C32(0x9f3f0002), SPH_C32(0xed8994f7), SPH_C32(0x078f06d4), + SPH_C32(0xd58dbfae), SPH_C32(0xee1e0008), SPH_C32(0xb7f4052d), + SPH_C32(0x19fb3a33), SPH_C32(0xf2c9dd28) }, + { SPH_C32(0x46b00000), SPH_C32(0x978d3c50), SPH_C32(0xe788a932), + SPH_C32(0x4a60f519), SPH_C32(0x663d000a), SPH_C32(0xe813a29e), + SPH_C32(0x801ebf99), SPH_C32(0x7fbc2ad9) }, + { SPH_C32(0xce930002), SPH_C32(0xc86a9be3), SPH_C32(0x7e6d2c98), + SPH_C32(0xc71502e8), SPH_C32(0x3791000a), SPH_C32(0xcdf0ad8a), + SPH_C32(0xf9fc95d5), SPH_C32(0x6d24979f) }, + { SPH_C32(0xc7140004), SPH_C32(0x3e18bc33), SPH_C32(0x03af332e), + SPH_C32(0xf7b26185), SPH_C32(0xd41b0008), SPH_C32(0xd2fcf393), + SPH_C32(0xf82b0c42), SPH_C32(0x96fda75d) }, + { SPH_C32(0x4f370006), SPH_C32(0x61ff1b80), SPH_C32(0x9a4ab684), + SPH_C32(0x7ac79674), SPH_C32(0x85b70008), SPH_C32(0xf71ffc87), + SPH_C32(0x81c9260e), SPH_C32(0x84651a1b) }, + { SPH_C32(0x96b80004), SPH_C32(0x1bfbb327), SPH_C32(0x7a4d1962), + SPH_C32(0xe52adcc3), SPH_C32(0x0d94000a), SPH_C32(0xa8f85b34), + SPH_C32(0x182ca3a4), SPH_C32(0x0910edea) }, + { SPH_C32(0x1e9b0006), SPH_C32(0x441c1494), SPH_C32(0xe3a89cc8), + SPH_C32(0x685f2b32), SPH_C32(0x5c38000a), SPH_C32(0x8d1b5420), + SPH_C32(0x61ce89e8), SPH_C32(0x1b8850ac) }, + { SPH_C32(0x7cb50000), SPH_C32(0xf285caee), SPH_C32(0x06589f43), + SPH_C32(0x2e548f6c), SPH_C32(0x0413000c), SPH_C32(0x5e8a7ce4), + SPH_C32(0x65eebc12), SPH_C32(0x39b78e87) }, + { SPH_C32(0xf4960002), SPH_C32(0xad626d5d), SPH_C32(0x9fbd1ae9), + SPH_C32(0xa321789d), SPH_C32(0x55bf000c), SPH_C32(0x7b6973f0), + SPH_C32(0x1c0c965e), SPH_C32(0x2b2f33c1) }, + { SPH_C32(0x2d190000), SPH_C32(0xd766c5fa), SPH_C32(0x7fbab50f), + SPH_C32(0x3ccc322a), SPH_C32(0xdd9c000e), SPH_C32(0x248ed443), + SPH_C32(0x85e913f4), SPH_C32(0xa65ac430) }, + { SPH_C32(0xa53a0002), SPH_C32(0x88816249), SPH_C32(0xe65f30a5), + SPH_C32(0xb1b9c5db), SPH_C32(0x8c30000e), SPH_C32(0x016ddb57), + SPH_C32(0xfc0b39b8), SPH_C32(0xb4c27976) }, + { SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), SPH_C32(0x9b9d2f13), + SPH_C32(0x811ea6b6), SPH_C32(0x6fba000c), SPH_C32(0x1e61854e), + SPH_C32(0xfddca02f), SPH_C32(0x4f1b49b4) }, + { SPH_C32(0x249e0006), SPH_C32(0x2114e22a), SPH_C32(0x0278aab9), + SPH_C32(0x0c6b5147), SPH_C32(0x3e16000c), SPH_C32(0x3b828a5a), + SPH_C32(0x843e8a63), SPH_C32(0x5d83f4f2) }, + { SPH_C32(0xfd110004), SPH_C32(0x5b104a8d), SPH_C32(0xe27f055f), + SPH_C32(0x93861bf0), SPH_C32(0xb635000e), SPH_C32(0x64652de9), + SPH_C32(0x1ddb0fc9), SPH_C32(0xd0f60303) }, + { SPH_C32(0x75320006), SPH_C32(0x04f7ed3e), SPH_C32(0x7b9a80f5), + SPH_C32(0x1ef3ec01), SPH_C32(0xe799000e), SPH_C32(0x418622fd), + SPH_C32(0x64392585), SPH_C32(0xc26ebe45) }, + { SPH_C32(0xbfb20008), SPH_C32(0x92170a39), SPH_C32(0x6019107f), + SPH_C32(0xe051606e), SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), + SPH_C32(0xfe739301), SPH_C32(0xb8a92831) }, + { SPH_C32(0x3791000a), SPH_C32(0xcdf0ad8a), SPH_C32(0xf9fc95d5), + SPH_C32(0x6d24979f), SPH_C32(0xf9020008), SPH_C32(0x059a3669), + SPH_C32(0x8791b94d), SPH_C32(0xaa319577) }, + { SPH_C32(0xee1e0008), SPH_C32(0xb7f4052d), SPH_C32(0x19fb3a33), + SPH_C32(0xf2c9dd28), SPH_C32(0x7121000a), SPH_C32(0x5a7d91da), + SPH_C32(0x1e743ce7), SPH_C32(0x27446286) }, + { SPH_C32(0x663d000a), SPH_C32(0xe813a29e), SPH_C32(0x801ebf99), + SPH_C32(0x7fbc2ad9), SPH_C32(0x208d000a), SPH_C32(0x7f9e9ece), + SPH_C32(0x679616ab), SPH_C32(0x35dcdfc0) }, + { SPH_C32(0x6fba000c), SPH_C32(0x1e61854e), SPH_C32(0xfddca02f), + SPH_C32(0x4f1b49b4), SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), + SPH_C32(0x66418f3c), SPH_C32(0xce05ef02) }, + { SPH_C32(0xe799000e), SPH_C32(0x418622fd), SPH_C32(0x64392585), + SPH_C32(0xc26ebe45), SPH_C32(0x92ab0008), SPH_C32(0x4571cfc3), + SPH_C32(0x1fa3a570), SPH_C32(0xdc9d5244) }, + { SPH_C32(0x3e16000c), SPH_C32(0x3b828a5a), SPH_C32(0x843e8a63), + SPH_C32(0x5d83f4f2), SPH_C32(0x1a88000a), SPH_C32(0x1a966870), + SPH_C32(0x864620da), SPH_C32(0x51e8a5b5) }, + { SPH_C32(0xb635000e), SPH_C32(0x64652de9), SPH_C32(0x1ddb0fc9), + SPH_C32(0xd0f60303), SPH_C32(0x4b24000a), SPH_C32(0x3f756764), + SPH_C32(0xffa40a96), SPH_C32(0x437018f3) }, + { SPH_C32(0xd41b0008), SPH_C32(0xd2fcf393), SPH_C32(0xf82b0c42), + SPH_C32(0x96fda75d), SPH_C32(0x130f000c), SPH_C32(0xece44fa0), + SPH_C32(0xfb843f6c), SPH_C32(0x614fc6d8) }, + { SPH_C32(0x5c38000a), SPH_C32(0x8d1b5420), SPH_C32(0x61ce89e8), + SPH_C32(0x1b8850ac), SPH_C32(0x42a3000c), SPH_C32(0xc90740b4), + SPH_C32(0x82661520), SPH_C32(0x73d77b9e) }, + { SPH_C32(0x85b70008), SPH_C32(0xf71ffc87), SPH_C32(0x81c9260e), + SPH_C32(0x84651a1b), SPH_C32(0xca80000e), SPH_C32(0x96e0e707), + SPH_C32(0x1b83908a), SPH_C32(0xfea28c6f) }, + { SPH_C32(0x0d94000a), SPH_C32(0xa8f85b34), SPH_C32(0x182ca3a4), + SPH_C32(0x0910edea), SPH_C32(0x9b2c000e), SPH_C32(0xb303e813), + SPH_C32(0x6261bac6), SPH_C32(0xec3a3129) }, + { SPH_C32(0x0413000c), SPH_C32(0x5e8a7ce4), SPH_C32(0x65eebc12), + SPH_C32(0x39b78e87), SPH_C32(0x78a6000c), SPH_C32(0xac0fb60a), + SPH_C32(0x63b62351), SPH_C32(0x17e301eb) }, + { SPH_C32(0x8c30000e), SPH_C32(0x016ddb57), SPH_C32(0xfc0b39b8), + SPH_C32(0xb4c27976), SPH_C32(0x290a000c), SPH_C32(0x89ecb91e), + SPH_C32(0x1a54091d), SPH_C32(0x057bbcad) }, + { SPH_C32(0x55bf000c), SPH_C32(0x7b6973f0), SPH_C32(0x1c0c965e), + SPH_C32(0x2b2f33c1), SPH_C32(0xa129000e), SPH_C32(0xd60b1ead), + SPH_C32(0x83b18cb7), SPH_C32(0x880e4b5c) }, + { SPH_C32(0xdd9c000e), SPH_C32(0x248ed443), SPH_C32(0x85e913f4), + SPH_C32(0xa65ac430), SPH_C32(0xf085000e), SPH_C32(0xf3e811b9), + SPH_C32(0xfa53a6fb), SPH_C32(0x9a96f61a) } +}; + +static const sph_u32 T256_30[4][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), SPH_C32(0xae0ebb05), + SPH_C32(0xb5a4c63b), SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), + SPH_C32(0x6bf648a4), SPH_C32(0x539cbdbf) }, + { SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), SPH_C32(0x6bf648a4), + SPH_C32(0x539cbdbf), SPH_C32(0x08bf0001), SPH_C32(0x38942792), + SPH_C32(0xc5f8f3a1), SPH_C32(0xe6387b84) }, + { SPH_C32(0x08bf0001), SPH_C32(0x38942792), SPH_C32(0xc5f8f3a1), + SPH_C32(0xe6387b84), SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), + SPH_C32(0xae0ebb05), SPH_C32(0xb5a4c63b) } +}; + +#define INPUT_SMALL do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T256_0[acc >> 2][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + acc = (acc << 8) | buf[1]; \ + rp = &T256_6[(acc >> 4) & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = (acc << 8) | buf[2]; \ + rp = &T256_12[(acc >> 6) & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_18[acc & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[3]; \ + rp = &T256_24[acc >> 2][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_30[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_SMALL == 7 + +static const sph_u32 T256_0[128][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xcba90000), SPH_C32(0x90273769), SPH_C32(0xbbdcf407), + SPH_C32(0xd0f4af61), SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), + SPH_C32(0x3321e92c), SPH_C32(0xce122df3) }, + { SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), SPH_C32(0x11fa3a57), + SPH_C32(0x3dc90524), SPH_C32(0x97530000), SPH_C32(0x204f6ed3), + SPH_C32(0x77b9e80f), SPH_C32(0xa1ec5ec1) }, + { SPH_C32(0x22832000), SPH_C32(0x2470bb95), SPH_C32(0xaa26ce50), + SPH_C32(0xed3daa45), SPH_C32(0x286f1000), SPH_C32(0xea431fc4), + SPH_C32(0x44980123), SPH_C32(0x6ffe7332) }, + { SPH_C32(0x97530000), SPH_C32(0x204f6ed3), SPH_C32(0x77b9e80f), + SPH_C32(0xa1ec5ec1), SPH_C32(0x7e792000), SPH_C32(0x9418e22f), + SPH_C32(0x6643d258), SPH_C32(0x9c255be5) }, + { SPH_C32(0x5cfa0000), SPH_C32(0xb06859ba), SPH_C32(0xcc651c08), + SPH_C32(0x7118f1a0), SPH_C32(0xc1453000), SPH_C32(0x5e149338), + SPH_C32(0x55623b74), SPH_C32(0x52377616) }, + { SPH_C32(0x7e792000), SPH_C32(0x9418e22f), SPH_C32(0x6643d258), + SPH_C32(0x9c255be5), SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), + SPH_C32(0x11fa3a57), SPH_C32(0x3dc90524) }, + { SPH_C32(0xb5d02000), SPH_C32(0x043fd546), SPH_C32(0xdd9f265f), + SPH_C32(0x4cd1f484), SPH_C32(0x56163000), SPH_C32(0x7e5bfdeb), + SPH_C32(0x22dbd37b), SPH_C32(0xf3db28d7) }, + { SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), SPH_C32(0x8dfacfab), + SPH_C32(0xce36cc72), SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), + SPH_C32(0x848598ba), SPH_C32(0x1041003e) }, + { SPH_C32(0xd9b24000), SPH_C32(0xcb30ee81), SPH_C32(0x36263bac), + SPH_C32(0x1ec26313), SPH_C32(0x596b1000), SPH_C32(0x81bf4b32), + SPH_C32(0xb7a47196), SPH_C32(0xde532dcd) }, + { SPH_C32(0xfb316000), SPH_C32(0xef405514), SPH_C32(0x9c00f5fc), + SPH_C32(0xf3ffc956), SPH_C32(0x71040000), SPH_C32(0x6bfc54f6), + SPH_C32(0xf33c70b5), SPH_C32(0xb1ad5eff) }, + { SPH_C32(0x30986000), SPH_C32(0x7f67627d), SPH_C32(0x27dc01fb), + SPH_C32(0x230b6637), SPH_C32(0xce381000), SPH_C32(0xa1f025e1), + SPH_C32(0xc01d9999), SPH_C32(0x7fbf730c) }, + { SPH_C32(0x85484000), SPH_C32(0x7b58b73b), SPH_C32(0xfa4327a4), + SPH_C32(0x6fda92b3), SPH_C32(0x982e2000), SPH_C32(0xdfabd80a), + SPH_C32(0xe2c64ae2), SPH_C32(0x8c645bdb) }, + { SPH_C32(0x4ee14000), SPH_C32(0xeb7f8052), SPH_C32(0x419fd3a3), + SPH_C32(0xbf2e3dd2), SPH_C32(0x27123000), SPH_C32(0x15a7a91d), + SPH_C32(0xd1e7a3ce), SPH_C32(0x42767628) }, + { SPH_C32(0x6c626000), SPH_C32(0xcf0f3bc7), SPH_C32(0xebb91df3), + SPH_C32(0x52139797), SPH_C32(0x0f7d2000), SPH_C32(0xffe4b6d9), + SPH_C32(0x957fa2ed), SPH_C32(0x2d88051a) }, + { SPH_C32(0xa7cb6000), SPH_C32(0x5f280cae), SPH_C32(0x5065e9f4), + SPH_C32(0x82e738f6), SPH_C32(0xb0413000), SPH_C32(0x35e8c7ce), + SPH_C32(0xa65e4bc1), SPH_C32(0xe39a28e9) }, + { SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), SPH_C32(0x848598ba), + SPH_C32(0x1041003e), SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), + SPH_C32(0x097f5711), SPH_C32(0xde77cc4c) }, + { SPH_C32(0x2dfe0000), SPH_C32(0xdb940d4c), SPH_C32(0x3f596cbd), + SPH_C32(0xc0b5af5f), SPH_C32(0x4b705000), SPH_C32(0xdaa892da), + SPH_C32(0x3a5ebe3d), SPH_C32(0x1065e1bf) }, + { SPH_C32(0x0f7d2000), SPH_C32(0xffe4b6d9), SPH_C32(0x957fa2ed), + SPH_C32(0x2d88051a), SPH_C32(0x631f4000), SPH_C32(0x30eb8d1e), + SPH_C32(0x7ec6bf1e), SPH_C32(0x7f9b928d) }, + { SPH_C32(0xc4d42000), SPH_C32(0x6fc381b0), SPH_C32(0x2ea356ea), + SPH_C32(0xfd7caa7b), SPH_C32(0xdc235000), SPH_C32(0xfae7fc09), + SPH_C32(0x4de75632), SPH_C32(0xb189bf7e) }, + { SPH_C32(0x71040000), SPH_C32(0x6bfc54f6), SPH_C32(0xf33c70b5), + SPH_C32(0xb1ad5eff), SPH_C32(0x8a356000), SPH_C32(0x84bc01e2), + SPH_C32(0x6f3c8549), SPH_C32(0x425297a9) }, + { SPH_C32(0xbaad0000), SPH_C32(0xfbdb639f), SPH_C32(0x48e084b2), + SPH_C32(0x6159f19e), SPH_C32(0x35097000), SPH_C32(0x4eb070f5), + SPH_C32(0x5c1d6c65), SPH_C32(0x8c40ba5a) }, + { SPH_C32(0x982e2000), SPH_C32(0xdfabd80a), SPH_C32(0xe2c64ae2), + SPH_C32(0x8c645bdb), SPH_C32(0x1d666000), SPH_C32(0xa4f36f31), + SPH_C32(0x18856d46), SPH_C32(0xe3bec968) }, + { SPH_C32(0x53872000), SPH_C32(0x4f8cef63), SPH_C32(0x591abee5), + SPH_C32(0x5c90f4ba), SPH_C32(0xa25a7000), SPH_C32(0x6eff1e26), + SPH_C32(0x2ba4846a), SPH_C32(0x2dace49b) }, + { SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), SPH_C32(0x097f5711), + SPH_C32(0xde77cc4c), SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), + SPH_C32(0x8dfacfab), SPH_C32(0xce36cc72) }, + { SPH_C32(0x3fe54000), SPH_C32(0x8083d4a4), SPH_C32(0xb2a3a316), + SPH_C32(0x0e83632d), SPH_C32(0xad275000), SPH_C32(0x911ba8ff), + SPH_C32(0xbedb2687), SPH_C32(0x0024e181) }, + { SPH_C32(0x1d666000), SPH_C32(0xa4f36f31), SPH_C32(0x18856d46), + SPH_C32(0xe3bec968), SPH_C32(0x85484000), SPH_C32(0x7b58b73b), + SPH_C32(0xfa4327a4), SPH_C32(0x6fda92b3) }, + { SPH_C32(0xd6cf6000), SPH_C32(0x34d45858), SPH_C32(0xa3599941), + SPH_C32(0x334a6609), SPH_C32(0x3a745000), SPH_C32(0xb154c62c), + SPH_C32(0xc962ce88), SPH_C32(0xa1c8bf40) }, + { SPH_C32(0x631f4000), SPH_C32(0x30eb8d1e), SPH_C32(0x7ec6bf1e), + SPH_C32(0x7f9b928d), SPH_C32(0x6c626000), SPH_C32(0xcf0f3bc7), + SPH_C32(0xebb91df3), SPH_C32(0x52139797) }, + { SPH_C32(0xa8b64000), SPH_C32(0xa0ccba77), SPH_C32(0xc51a4b19), + SPH_C32(0xaf6f3dec), SPH_C32(0xd35e7000), SPH_C32(0x05034ad0), + SPH_C32(0xd898f4df), SPH_C32(0x9c01ba64) }, + { SPH_C32(0x8a356000), SPH_C32(0x84bc01e2), SPH_C32(0x6f3c8549), + SPH_C32(0x425297a9), SPH_C32(0xfb316000), SPH_C32(0xef405514), + SPH_C32(0x9c00f5fc), SPH_C32(0xf3ffc956) }, + { SPH_C32(0x419c6000), SPH_C32(0x149b368b), SPH_C32(0xd4e0714e), + SPH_C32(0x92a638c8), SPH_C32(0x440d7000), SPH_C32(0x254c2403), + SPH_C32(0xaf211cd0), SPH_C32(0x3dede4a5) }, + { SPH_C32(0xe4788000), SPH_C32(0x859673c1), SPH_C32(0xb5fb2452), + SPH_C32(0x29cc5edf), SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), + SPH_C32(0x62fc79d0), SPH_C32(0x731ebdc2) }, + { SPH_C32(0x2fd18000), SPH_C32(0x15b144a8), SPH_C32(0x0e27d055), + SPH_C32(0xf938f1be), SPH_C32(0xbb631000), SPH_C32(0x5646e2de), + SPH_C32(0x51dd90fc), SPH_C32(0xbd0c9031) }, + { SPH_C32(0x0d52a000), SPH_C32(0x31c1ff3d), SPH_C32(0xa4011e05), + SPH_C32(0x14055bfb), SPH_C32(0x930c0000), SPH_C32(0xbc05fd1a), + SPH_C32(0x154591df), SPH_C32(0xd2f2e303) }, + { SPH_C32(0xc6fba000), SPH_C32(0xa1e6c854), SPH_C32(0x1fddea02), + SPH_C32(0xc4f1f49a), SPH_C32(0x2c301000), SPH_C32(0x76098c0d), + SPH_C32(0x266478f3), SPH_C32(0x1ce0cef0) }, + { SPH_C32(0x732b8000), SPH_C32(0xa5d91d12), SPH_C32(0xc242cc5d), + SPH_C32(0x8820001e), SPH_C32(0x7a262000), SPH_C32(0x085271e6), + SPH_C32(0x04bfab88), SPH_C32(0xef3be627) }, + { SPH_C32(0xb8828000), SPH_C32(0x35fe2a7b), SPH_C32(0x799e385a), + SPH_C32(0x58d4af7f), SPH_C32(0xc51a3000), SPH_C32(0xc25e00f1), + SPH_C32(0x379e42a4), SPH_C32(0x2129cbd4) }, + { SPH_C32(0x9a01a000), SPH_C32(0x118e91ee), SPH_C32(0xd3b8f60a), + SPH_C32(0xb5e9053a), SPH_C32(0xed752000), SPH_C32(0x281d1f35), + SPH_C32(0x73064387), SPH_C32(0x4ed7b8e6) }, + { SPH_C32(0x51a8a000), SPH_C32(0x81a9a687), SPH_C32(0x6864020d), + SPH_C32(0x651daa5b), SPH_C32(0x52493000), SPH_C32(0xe2116e22), + SPH_C32(0x4027aaab), SPH_C32(0x80c59515) }, + { SPH_C32(0xf663c000), SPH_C32(0xde81aa29), SPH_C32(0x3801ebf9), + SPH_C32(0xe7fa92ad), SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), + SPH_C32(0xe679e16a), SPH_C32(0x635fbdfc) }, + { SPH_C32(0x3dcac000), SPH_C32(0x4ea69d40), SPH_C32(0x83dd1ffe), + SPH_C32(0x370e3dcc), SPH_C32(0x5d341000), SPH_C32(0x1df5d8fb), + SPH_C32(0xd5580846), SPH_C32(0xad4d900f) }, + { SPH_C32(0x1f49e000), SPH_C32(0x6ad626d5), SPH_C32(0x29fbd1ae), + SPH_C32(0xda339789), SPH_C32(0x755b0000), SPH_C32(0xf7b6c73f), + SPH_C32(0x91c00965), SPH_C32(0xc2b3e33d) }, + { SPH_C32(0xd4e0e000), SPH_C32(0xfaf111bc), SPH_C32(0x922725a9), + SPH_C32(0x0ac738e8), SPH_C32(0xca671000), SPH_C32(0x3dbab628), + SPH_C32(0xa2e1e049), SPH_C32(0x0ca1cece) }, + { SPH_C32(0x6130c000), SPH_C32(0xfecec4fa), SPH_C32(0x4fb803f6), + SPH_C32(0x4616cc6c), SPH_C32(0x9c712000), SPH_C32(0x43e14bc3), + SPH_C32(0x803a3332), SPH_C32(0xff7ae619) }, + { SPH_C32(0xaa99c000), SPH_C32(0x6ee9f393), SPH_C32(0xf464f7f1), + SPH_C32(0x96e2630d), SPH_C32(0x234d3000), SPH_C32(0x89ed3ad4), + SPH_C32(0xb31bda1e), SPH_C32(0x3168cbea) }, + { SPH_C32(0x881ae000), SPH_C32(0x4a994806), SPH_C32(0x5e4239a1), + SPH_C32(0x7bdfc948), SPH_C32(0x0b222000), SPH_C32(0x63ae2510), + SPH_C32(0xf783db3d), SPH_C32(0x5e96b8d8) }, + { SPH_C32(0x43b3e000), SPH_C32(0xdabe7f6f), SPH_C32(0xe59ecda6), + SPH_C32(0xab2b6629), SPH_C32(0xb41e3000), SPH_C32(0xa9a25407), + SPH_C32(0xc4a23211), SPH_C32(0x9084952b) }, + { SPH_C32(0x022f8000), SPH_C32(0xce2549e4), SPH_C32(0x317ebce8), + SPH_C32(0x398d5ee1), SPH_C32(0xf0134000), SPH_C32(0x8cee7004), + SPH_C32(0x6b832ec1), SPH_C32(0xad69718e) }, + { SPH_C32(0xc9868000), SPH_C32(0x5e027e8d), SPH_C32(0x8aa248ef), + SPH_C32(0xe979f180), SPH_C32(0x4f2f5000), SPH_C32(0x46e20113), + SPH_C32(0x58a2c7ed), SPH_C32(0x637b5c7d) }, + { SPH_C32(0xeb05a000), SPH_C32(0x7a72c518), SPH_C32(0x208486bf), + SPH_C32(0x04445bc5), SPH_C32(0x67404000), SPH_C32(0xaca11ed7), + SPH_C32(0x1c3ac6ce), SPH_C32(0x0c852f4f) }, + { SPH_C32(0x20aca000), SPH_C32(0xea55f271), SPH_C32(0x9b5872b8), + SPH_C32(0xd4b0f4a4), SPH_C32(0xd87c5000), SPH_C32(0x66ad6fc0), + SPH_C32(0x2f1b2fe2), SPH_C32(0xc29702bc) }, + { SPH_C32(0x957c8000), SPH_C32(0xee6a2737), SPH_C32(0x46c754e7), + SPH_C32(0x98610020), SPH_C32(0x8e6a6000), SPH_C32(0x18f6922b), + SPH_C32(0x0dc0fc99), SPH_C32(0x314c2a6b) }, + { SPH_C32(0x5ed58000), SPH_C32(0x7e4d105e), SPH_C32(0xfd1ba0e0), + SPH_C32(0x4895af41), SPH_C32(0x31567000), SPH_C32(0xd2fae33c), + SPH_C32(0x3ee115b5), SPH_C32(0xff5e0798) }, + { SPH_C32(0x7c56a000), SPH_C32(0x5a3dabcb), SPH_C32(0x573d6eb0), + SPH_C32(0xa5a80504), SPH_C32(0x19396000), SPH_C32(0x38b9fcf8), + SPH_C32(0x7a791496), SPH_C32(0x90a074aa) }, + { SPH_C32(0xb7ffa000), SPH_C32(0xca1a9ca2), SPH_C32(0xece19ab7), + SPH_C32(0x755caa65), SPH_C32(0xa6057000), SPH_C32(0xf2b58def), + SPH_C32(0x4958fdba), SPH_C32(0x5eb25959) }, + { SPH_C32(0x1034c000), SPH_C32(0x9532900c), SPH_C32(0xbc847343), + SPH_C32(0xf7bb9293), SPH_C32(0x16444000), SPH_C32(0xc75d4a21), + SPH_C32(0xef06b67b), SPH_C32(0xbd2871b0) }, + { SPH_C32(0xdb9dc000), SPH_C32(0x0515a765), SPH_C32(0x07588744), + SPH_C32(0x274f3df2), SPH_C32(0xa9785000), SPH_C32(0x0d513b36), + SPH_C32(0xdc275f57), SPH_C32(0x733a5c43) }, + { SPH_C32(0xf91ee000), SPH_C32(0x21651cf0), SPH_C32(0xad7e4914), + SPH_C32(0xca7297b7), SPH_C32(0x81174000), SPH_C32(0xe71224f2), + SPH_C32(0x98bf5e74), SPH_C32(0x1cc42f71) }, + { SPH_C32(0x32b7e000), SPH_C32(0xb1422b99), SPH_C32(0x16a2bd13), + SPH_C32(0x1a8638d6), SPH_C32(0x3e2b5000), SPH_C32(0x2d1e55e5), + SPH_C32(0xab9eb758), SPH_C32(0xd2d60282) }, + { SPH_C32(0x8767c000), SPH_C32(0xb57dfedf), SPH_C32(0xcb3d9b4c), + SPH_C32(0x5657cc52), SPH_C32(0x683d6000), SPH_C32(0x5345a80e), + SPH_C32(0x89456423), SPH_C32(0x210d2a55) }, + { SPH_C32(0x4ccec000), SPH_C32(0x255ac9b6), SPH_C32(0x70e16f4b), + SPH_C32(0x86a36333), SPH_C32(0xd7017000), SPH_C32(0x9949d919), + SPH_C32(0xba648d0f), SPH_C32(0xef1f07a6) }, + { SPH_C32(0x6e4de000), SPH_C32(0x012a7223), SPH_C32(0xdac7a11b), + SPH_C32(0x6b9ec976), SPH_C32(0xff6e6000), SPH_C32(0x730ac6dd), + SPH_C32(0xfefc8c2c), SPH_C32(0x80e17494) }, + { SPH_C32(0xa5e4e000), SPH_C32(0x910d454a), SPH_C32(0x611b551c), + SPH_C32(0xbb6a6617), SPH_C32(0x40527000), SPH_C32(0xb906b7ca), + SPH_C32(0xcddd6500), SPH_C32(0x4ef35967) }, + { SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), SPH_C32(0x62fc79d0), + SPH_C32(0x731ebdc2), SPH_C32(0xe0278000), SPH_C32(0x19dce008), + SPH_C32(0xd7075d82), SPH_C32(0x5ad2e31d) }, + { SPH_C32(0xcff60000), SPH_C32(0x0c6da4a0), SPH_C32(0xd9208dd7), + SPH_C32(0xa3ea12a3), SPH_C32(0x5f1b9000), SPH_C32(0xd3d0911f), + SPH_C32(0xe426b4ae), SPH_C32(0x94c0ceee) }, + { SPH_C32(0xed752000), SPH_C32(0x281d1f35), SPH_C32(0x73064387), + SPH_C32(0x4ed7b8e6), SPH_C32(0x77748000), SPH_C32(0x39938edb), + SPH_C32(0xa0beb58d), SPH_C32(0xfb3ebddc) }, + { SPH_C32(0x26dc2000), SPH_C32(0xb83a285c), SPH_C32(0xc8dab780), + SPH_C32(0x9e231787), SPH_C32(0xc8489000), SPH_C32(0xf39fffcc), + SPH_C32(0x939f5ca1), SPH_C32(0x352c902f) }, + { SPH_C32(0x930c0000), SPH_C32(0xbc05fd1a), SPH_C32(0x154591df), + SPH_C32(0xd2f2e303), SPH_C32(0x9e5ea000), SPH_C32(0x8dc40227), + SPH_C32(0xb1448fda), SPH_C32(0xc6f7b8f8) }, + { SPH_C32(0x58a50000), SPH_C32(0x2c22ca73), SPH_C32(0xae9965d8), + SPH_C32(0x02064c62), SPH_C32(0x2162b000), SPH_C32(0x47c87330), + SPH_C32(0x826566f6), SPH_C32(0x08e5950b) }, + { SPH_C32(0x7a262000), SPH_C32(0x085271e6), SPH_C32(0x04bfab88), + SPH_C32(0xef3be627), SPH_C32(0x090da000), SPH_C32(0xad8b6cf4), + SPH_C32(0xc6fd67d5), SPH_C32(0x671be639) }, + { SPH_C32(0xb18f2000), SPH_C32(0x9875468f), SPH_C32(0xbf635f8f), + SPH_C32(0x3fcf4946), SPH_C32(0xb631b000), SPH_C32(0x67871de3), + SPH_C32(0xf5dc8ef9), SPH_C32(0xa909cbca) }, + { SPH_C32(0x16444000), SPH_C32(0xc75d4a21), SPH_C32(0xef06b67b), + SPH_C32(0xbd2871b0), SPH_C32(0x06708000), SPH_C32(0x526fda2d), + SPH_C32(0x5382c538), SPH_C32(0x4a93e323) }, + { SPH_C32(0xdded4000), SPH_C32(0x577a7d48), SPH_C32(0x54da427c), + SPH_C32(0x6ddcded1), SPH_C32(0xb94c9000), SPH_C32(0x9863ab3a), + SPH_C32(0x60a32c14), SPH_C32(0x8481ced0) }, + { SPH_C32(0xff6e6000), SPH_C32(0x730ac6dd), SPH_C32(0xfefc8c2c), + SPH_C32(0x80e17494), SPH_C32(0x91238000), SPH_C32(0x7220b4fe), + SPH_C32(0x243b2d37), SPH_C32(0xeb7fbde2) }, + { SPH_C32(0x34c76000), SPH_C32(0xe32df1b4), SPH_C32(0x4520782b), + SPH_C32(0x5015dbf5), SPH_C32(0x2e1f9000), SPH_C32(0xb82cc5e9), + SPH_C32(0x171ac41b), SPH_C32(0x256d9011) }, + { SPH_C32(0x81174000), SPH_C32(0xe71224f2), SPH_C32(0x98bf5e74), + SPH_C32(0x1cc42f71), SPH_C32(0x7809a000), SPH_C32(0xc6773802), + SPH_C32(0x35c11760), SPH_C32(0xd6b6b8c6) }, + { SPH_C32(0x4abe4000), SPH_C32(0x7735139b), SPH_C32(0x2363aa73), + SPH_C32(0xcc308010), SPH_C32(0xc735b000), SPH_C32(0x0c7b4915), + SPH_C32(0x06e0fe4c), SPH_C32(0x18a49535) }, + { SPH_C32(0x683d6000), SPH_C32(0x5345a80e), SPH_C32(0x89456423), + SPH_C32(0x210d2a55), SPH_C32(0xef5aa000), SPH_C32(0xe63856d1), + SPH_C32(0x4278ff6f), SPH_C32(0x775ae607) }, + { SPH_C32(0xa3946000), SPH_C32(0xc3629f67), SPH_C32(0x32999024), + SPH_C32(0xf1f98534), SPH_C32(0x5066b000), SPH_C32(0x2c3427c6), + SPH_C32(0x71591643), SPH_C32(0xb948cbf4) }, + { SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), SPH_C32(0xe679e16a), + SPH_C32(0x635fbdfc), SPH_C32(0x146bc000), SPH_C32(0x097803c5), + SPH_C32(0xde780a93), SPH_C32(0x84a52f51) }, + { SPH_C32(0x29a10000), SPH_C32(0x47de9e85), SPH_C32(0x5da5156d), + SPH_C32(0xb3ab129d), SPH_C32(0xab57d000), SPH_C32(0xc37472d2), + SPH_C32(0xed59e3bf), SPH_C32(0x4ab702a2) }, + { SPH_C32(0x0b222000), SPH_C32(0x63ae2510), SPH_C32(0xf783db3d), + SPH_C32(0x5e96b8d8), SPH_C32(0x8338c000), SPH_C32(0x29376d16), + SPH_C32(0xa9c1e29c), SPH_C32(0x25497190) }, + { SPH_C32(0xc08b2000), SPH_C32(0xf3891279), SPH_C32(0x4c5f2f3a), + SPH_C32(0x8e6217b9), SPH_C32(0x3c04d000), SPH_C32(0xe33b1c01), + SPH_C32(0x9ae00bb0), SPH_C32(0xeb5b5c63) }, + { SPH_C32(0x755b0000), SPH_C32(0xf7b6c73f), SPH_C32(0x91c00965), + SPH_C32(0xc2b3e33d), SPH_C32(0x6a12e000), SPH_C32(0x9d60e1ea), + SPH_C32(0xb83bd8cb), SPH_C32(0x188074b4) }, + { SPH_C32(0xbef20000), SPH_C32(0x6791f056), SPH_C32(0x2a1cfd62), + SPH_C32(0x12474c5c), SPH_C32(0xd52ef000), SPH_C32(0x576c90fd), + SPH_C32(0x8b1a31e7), SPH_C32(0xd6925947) }, + { SPH_C32(0x9c712000), SPH_C32(0x43e14bc3), SPH_C32(0x803a3332), + SPH_C32(0xff7ae619), SPH_C32(0xfd41e000), SPH_C32(0xbd2f8f39), + SPH_C32(0xcf8230c4), SPH_C32(0xb96c2a75) }, + { SPH_C32(0x57d82000), SPH_C32(0xd3c67caa), SPH_C32(0x3be6c735), + SPH_C32(0x2f8e4978), SPH_C32(0x427df000), SPH_C32(0x7723fe2e), + SPH_C32(0xfca3d9e8), SPH_C32(0x777e0786) }, + { SPH_C32(0xf0134000), SPH_C32(0x8cee7004), SPH_C32(0x6b832ec1), + SPH_C32(0xad69718e), SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), + SPH_C32(0x5afd9229), SPH_C32(0x94e42f6f) }, + { SPH_C32(0x3bba4000), SPH_C32(0x1cc9476d), SPH_C32(0xd05fdac6), + SPH_C32(0x7d9ddeef), SPH_C32(0x4d00d000), SPH_C32(0x88c748f7), + SPH_C32(0x69dc7b05), SPH_C32(0x5af6029c) }, + { SPH_C32(0x19396000), SPH_C32(0x38b9fcf8), SPH_C32(0x7a791496), + SPH_C32(0x90a074aa), SPH_C32(0x656fc000), SPH_C32(0x62845733), + SPH_C32(0x2d447a26), SPH_C32(0x350871ae) }, + { SPH_C32(0xd2906000), SPH_C32(0xa89ecb91), SPH_C32(0xc1a5e091), + SPH_C32(0x4054dbcb), SPH_C32(0xda53d000), SPH_C32(0xa8882624), + SPH_C32(0x1e65930a), SPH_C32(0xfb1a5c5d) }, + { SPH_C32(0x67404000), SPH_C32(0xaca11ed7), SPH_C32(0x1c3ac6ce), + SPH_C32(0x0c852f4f), SPH_C32(0x8c45e000), SPH_C32(0xd6d3dbcf), + SPH_C32(0x3cbe4071), SPH_C32(0x08c1748a) }, + { SPH_C32(0xace94000), SPH_C32(0x3c8629be), SPH_C32(0xa7e632c9), + SPH_C32(0xdc71802e), SPH_C32(0x3379f000), SPH_C32(0x1cdfaad8), + SPH_C32(0x0f9fa95d), SPH_C32(0xc6d35979) }, + { SPH_C32(0x8e6a6000), SPH_C32(0x18f6922b), SPH_C32(0x0dc0fc99), + SPH_C32(0x314c2a6b), SPH_C32(0x1b16e000), SPH_C32(0xf69cb51c), + SPH_C32(0x4b07a87e), SPH_C32(0xa92d2a4b) }, + { SPH_C32(0x45c36000), SPH_C32(0x88d1a542), SPH_C32(0xb61c089e), + SPH_C32(0xe1b8850a), SPH_C32(0xa42af000), SPH_C32(0x3c90c40b), + SPH_C32(0x78264152), SPH_C32(0x673f07b8) }, + { SPH_C32(0xe0278000), SPH_C32(0x19dce008), SPH_C32(0xd7075d82), + SPH_C32(0x5ad2e31d), SPH_C32(0xe4788000), SPH_C32(0x859673c1), + SPH_C32(0xb5fb2452), SPH_C32(0x29cc5edf) }, + { SPH_C32(0x2b8e8000), SPH_C32(0x89fbd761), SPH_C32(0x6cdba985), + SPH_C32(0x8a264c7c), SPH_C32(0x5b449000), SPH_C32(0x4f9a02d6), + SPH_C32(0x86dacd7e), SPH_C32(0xe7de732c) }, + { SPH_C32(0x090da000), SPH_C32(0xad8b6cf4), SPH_C32(0xc6fd67d5), + SPH_C32(0x671be639), SPH_C32(0x732b8000), SPH_C32(0xa5d91d12), + SPH_C32(0xc242cc5d), SPH_C32(0x8820001e) }, + { SPH_C32(0xc2a4a000), SPH_C32(0x3dac5b9d), SPH_C32(0x7d2193d2), + SPH_C32(0xb7ef4958), SPH_C32(0xcc179000), SPH_C32(0x6fd56c05), + SPH_C32(0xf1632571), SPH_C32(0x46322ded) }, + { SPH_C32(0x77748000), SPH_C32(0x39938edb), SPH_C32(0xa0beb58d), + SPH_C32(0xfb3ebddc), SPH_C32(0x9a01a000), SPH_C32(0x118e91ee), + SPH_C32(0xd3b8f60a), SPH_C32(0xb5e9053a) }, + { SPH_C32(0xbcdd8000), SPH_C32(0xa9b4b9b2), SPH_C32(0x1b62418a), + SPH_C32(0x2bca12bd), SPH_C32(0x253db000), SPH_C32(0xdb82e0f9), + SPH_C32(0xe0991f26), SPH_C32(0x7bfb28c9) }, + { SPH_C32(0x9e5ea000), SPH_C32(0x8dc40227), SPH_C32(0xb1448fda), + SPH_C32(0xc6f7b8f8), SPH_C32(0x0d52a000), SPH_C32(0x31c1ff3d), + SPH_C32(0xa4011e05), SPH_C32(0x14055bfb) }, + { SPH_C32(0x55f7a000), SPH_C32(0x1de3354e), SPH_C32(0x0a987bdd), + SPH_C32(0x16031799), SPH_C32(0xb26eb000), SPH_C32(0xfbcd8e2a), + SPH_C32(0x9720f729), SPH_C32(0xda177608) }, + { SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), SPH_C32(0x5afd9229), + SPH_C32(0x94e42f6f), SPH_C32(0x022f8000), SPH_C32(0xce2549e4), + SPH_C32(0x317ebce8), SPH_C32(0x398d5ee1) }, + { SPH_C32(0x3995c000), SPH_C32(0xd2ec0e89), SPH_C32(0xe121662e), + SPH_C32(0x4410800e), SPH_C32(0xbd139000), SPH_C32(0x042938f3), + SPH_C32(0x025f55c4), SPH_C32(0xf79f7312) }, + { SPH_C32(0x1b16e000), SPH_C32(0xf69cb51c), SPH_C32(0x4b07a87e), + SPH_C32(0xa92d2a4b), SPH_C32(0x957c8000), SPH_C32(0xee6a2737), + SPH_C32(0x46c754e7), SPH_C32(0x98610020) }, + { SPH_C32(0xd0bfe000), SPH_C32(0x66bb8275), SPH_C32(0xf0db5c79), + SPH_C32(0x79d9852a), SPH_C32(0x2a409000), SPH_C32(0x24665620), + SPH_C32(0x75e6bdcb), SPH_C32(0x56732dd3) }, + { SPH_C32(0x656fc000), SPH_C32(0x62845733), SPH_C32(0x2d447a26), + SPH_C32(0x350871ae), SPH_C32(0x7c56a000), SPH_C32(0x5a3dabcb), + SPH_C32(0x573d6eb0), SPH_C32(0xa5a80504) }, + { SPH_C32(0xaec6c000), SPH_C32(0xf2a3605a), SPH_C32(0x96988e21), + SPH_C32(0xe5fcdecf), SPH_C32(0xc36ab000), SPH_C32(0x9031dadc), + SPH_C32(0x641c879c), SPH_C32(0x6bba28f7) }, + { SPH_C32(0x8c45e000), SPH_C32(0xd6d3dbcf), SPH_C32(0x3cbe4071), + SPH_C32(0x08c1748a), SPH_C32(0xeb05a000), SPH_C32(0x7a72c518), + SPH_C32(0x208486bf), SPH_C32(0x04445bc5) }, + { SPH_C32(0x47ece000), SPH_C32(0x46f4eca6), SPH_C32(0x8762b476), + SPH_C32(0xd835dbeb), SPH_C32(0x5439b000), SPH_C32(0xb07eb40f), + SPH_C32(0x13a56f93), SPH_C32(0xca567636) }, + { SPH_C32(0x06708000), SPH_C32(0x526fda2d), SPH_C32(0x5382c538), + SPH_C32(0x4a93e323), SPH_C32(0x1034c000), SPH_C32(0x9532900c), + SPH_C32(0xbc847343), SPH_C32(0xf7bb9293) }, + { SPH_C32(0xcdd98000), SPH_C32(0xc248ed44), SPH_C32(0xe85e313f), + SPH_C32(0x9a674c42), SPH_C32(0xaf08d000), SPH_C32(0x5f3ee11b), + SPH_C32(0x8fa59a6f), SPH_C32(0x39a9bf60) }, + { SPH_C32(0xef5aa000), SPH_C32(0xe63856d1), SPH_C32(0x4278ff6f), + SPH_C32(0x775ae607), SPH_C32(0x8767c000), SPH_C32(0xb57dfedf), + SPH_C32(0xcb3d9b4c), SPH_C32(0x5657cc52) }, + { SPH_C32(0x24f3a000), SPH_C32(0x761f61b8), SPH_C32(0xf9a40b68), + SPH_C32(0xa7ae4966), SPH_C32(0x385bd000), SPH_C32(0x7f718fc8), + SPH_C32(0xf81c7260), SPH_C32(0x9845e1a1) }, + { SPH_C32(0x91238000), SPH_C32(0x7220b4fe), SPH_C32(0x243b2d37), + SPH_C32(0xeb7fbde2), SPH_C32(0x6e4de000), SPH_C32(0x012a7223), + SPH_C32(0xdac7a11b), SPH_C32(0x6b9ec976) }, + { SPH_C32(0x5a8a8000), SPH_C32(0xe2078397), SPH_C32(0x9fe7d930), + SPH_C32(0x3b8b1283), SPH_C32(0xd171f000), SPH_C32(0xcb260334), + SPH_C32(0xe9e64837), SPH_C32(0xa58ce485) }, + { SPH_C32(0x7809a000), SPH_C32(0xc6773802), SPH_C32(0x35c11760), + SPH_C32(0xd6b6b8c6), SPH_C32(0xf91ee000), SPH_C32(0x21651cf0), + SPH_C32(0xad7e4914), SPH_C32(0xca7297b7) }, + { SPH_C32(0xb3a0a000), SPH_C32(0x56500f6b), SPH_C32(0x8e1de367), + SPH_C32(0x064217a7), SPH_C32(0x4622f000), SPH_C32(0xeb696de7), + SPH_C32(0x9e5fa038), SPH_C32(0x0460ba44) }, + { SPH_C32(0x146bc000), SPH_C32(0x097803c5), SPH_C32(0xde780a93), + SPH_C32(0x84a52f51), SPH_C32(0xf663c000), SPH_C32(0xde81aa29), + SPH_C32(0x3801ebf9), SPH_C32(0xe7fa92ad) }, + { SPH_C32(0xdfc2c000), SPH_C32(0x995f34ac), SPH_C32(0x65a4fe94), + SPH_C32(0x54518030), SPH_C32(0x495fd000), SPH_C32(0x148ddb3e), + SPH_C32(0x0b2002d5), SPH_C32(0x29e8bf5e) }, + { SPH_C32(0xfd41e000), SPH_C32(0xbd2f8f39), SPH_C32(0xcf8230c4), + SPH_C32(0xb96c2a75), SPH_C32(0x6130c000), SPH_C32(0xfecec4fa), + SPH_C32(0x4fb803f6), SPH_C32(0x4616cc6c) }, + { SPH_C32(0x36e8e000), SPH_C32(0x2d08b850), SPH_C32(0x745ec4c3), + SPH_C32(0x69988514), SPH_C32(0xde0cd000), SPH_C32(0x34c2b5ed), + SPH_C32(0x7c99eada), SPH_C32(0x8804e19f) }, + { SPH_C32(0x8338c000), SPH_C32(0x29376d16), SPH_C32(0xa9c1e29c), + SPH_C32(0x25497190), SPH_C32(0x881ae000), SPH_C32(0x4a994806), + SPH_C32(0x5e4239a1), SPH_C32(0x7bdfc948) }, + { SPH_C32(0x4891c000), SPH_C32(0xb9105a7f), SPH_C32(0x121d169b), + SPH_C32(0xf5bddef1), SPH_C32(0x3726f000), SPH_C32(0x80953911), + SPH_C32(0x6d63d08d), SPH_C32(0xb5cde4bb) }, + { SPH_C32(0x6a12e000), SPH_C32(0x9d60e1ea), SPH_C32(0xb83bd8cb), + SPH_C32(0x188074b4), SPH_C32(0x1f49e000), SPH_C32(0x6ad626d5), + SPH_C32(0x29fbd1ae), SPH_C32(0xda339789) }, + { SPH_C32(0xa1bbe000), SPH_C32(0x0d47d683), SPH_C32(0x03e72ccc), + SPH_C32(0xc874dbd5), SPH_C32(0xa075f000), SPH_C32(0xa0da57c2), + SPH_C32(0x1ada3882), SPH_C32(0x1421ba7a) } +}; + +static const sph_u32 T256_7[128][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xa7b80200), SPH_C32(0x1f128433), SPH_C32(0x60e5f9f2), + SPH_C32(0x9e147576), SPH_C32(0xee260000), SPH_C32(0x124b683e), + SPH_C32(0x80c2d68f), SPH_C32(0x3bf3ab2c) }, + { SPH_C32(0xee260000), SPH_C32(0x124b683e), SPH_C32(0x80c2d68f), + SPH_C32(0x3bf3ab2c), SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), + SPH_C32(0xe0272f7d), SPH_C32(0xa5e7de5a) }, + { SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), SPH_C32(0xe0272f7d), + SPH_C32(0xa5e7de5a), SPH_C32(0xa7b80200), SPH_C32(0x1f128433), + SPH_C32(0x60e5f9f2), SPH_C32(0x9e147576) }, + { SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), SPH_C32(0x6fc548e1), + SPH_C32(0x898d2cd6), SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), + SPH_C32(0x6a72e5bb), SPH_C32(0x247febe6) }, + { SPH_C32(0x28860600), SPH_C32(0x128f4c44), SPH_C32(0x0f20b113), + SPH_C32(0x179959a0), SPH_C32(0xfa9b0000), SPH_C32(0x3df15fc1), + SPH_C32(0xeab03334), SPH_C32(0x1f8c40ca) }, + { SPH_C32(0x61180400), SPH_C32(0x1fd6a049), SPH_C32(0xef079e6e), + SPH_C32(0xb27e87fa), SPH_C32(0x5d230200), SPH_C32(0x22e3dbf2), + SPH_C32(0x8a55cac6), SPH_C32(0x819835bc) }, + { SPH_C32(0xc6a00600), SPH_C32(0x00c4247a), SPH_C32(0x8fe2679c), + SPH_C32(0x2c6af28c), SPH_C32(0xb3050200), SPH_C32(0x30a8b3cc), + SPH_C32(0x0a971c49), SPH_C32(0xba6b9e90) }, + { SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), SPH_C32(0x6a72e5bb), + SPH_C32(0x247febe6), SPH_C32(0x9b830400), SPH_C32(0x2227ff88), + SPH_C32(0x05b7ad5a), SPH_C32(0xadf2c730) }, + { SPH_C32(0xb3050200), SPH_C32(0x30a8b3cc), SPH_C32(0x0a971c49), + SPH_C32(0xba6b9e90), SPH_C32(0x75a50400), SPH_C32(0x306c97b6), + SPH_C32(0x85757bd5), SPH_C32(0x96016c1c) }, + { SPH_C32(0xfa9b0000), SPH_C32(0x3df15fc1), SPH_C32(0xeab03334), + SPH_C32(0x1f8c40ca), SPH_C32(0xd21d0600), SPH_C32(0x2f7e1385), + SPH_C32(0xe5908227), SPH_C32(0x0815196a) }, + { SPH_C32(0x5d230200), SPH_C32(0x22e3dbf2), SPH_C32(0x8a55cac6), + SPH_C32(0x819835bc), SPH_C32(0x3c3b0600), SPH_C32(0x3d357bbb), + SPH_C32(0x655254a8), SPH_C32(0x33e6b246) }, + { SPH_C32(0x9b830400), SPH_C32(0x2227ff88), SPH_C32(0x05b7ad5a), + SPH_C32(0xadf2c730), SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), + SPH_C32(0x6fc548e1), SPH_C32(0x898d2cd6) }, + { SPH_C32(0x3c3b0600), SPH_C32(0x3d357bbb), SPH_C32(0x655254a8), + SPH_C32(0x33e6b246), SPH_C32(0x61180400), SPH_C32(0x1fd6a049), + SPH_C32(0xef079e6e), SPH_C32(0xb27e87fa) }, + { SPH_C32(0x75a50400), SPH_C32(0x306c97b6), SPH_C32(0x85757bd5), + SPH_C32(0x96016c1c), SPH_C32(0xc6a00600), SPH_C32(0x00c4247a), + SPH_C32(0x8fe2679c), SPH_C32(0x2c6af28c) }, + { SPH_C32(0xd21d0600), SPH_C32(0x2f7e1385), SPH_C32(0xe5908227), + SPH_C32(0x0815196a), SPH_C32(0x28860600), SPH_C32(0x128f4c44), + SPH_C32(0x0f20b113), SPH_C32(0x179959a0) }, + { SPH_C32(0xde320800), SPH_C32(0x288350fe), SPH_C32(0x71852ac7), + SPH_C32(0xa6bf9f96), SPH_C32(0xe18b0000), SPH_C32(0x5459887d), + SPH_C32(0xbf1283d3), SPH_C32(0x1b666a73) }, + { SPH_C32(0x798a0a00), SPH_C32(0x3791d4cd), SPH_C32(0x1160d335), + SPH_C32(0x38abeae0), SPH_C32(0x0fad0000), SPH_C32(0x4612e043), + SPH_C32(0x3fd0555c), SPH_C32(0x2095c15f) }, + { SPH_C32(0x30140800), SPH_C32(0x3ac838c0), SPH_C32(0xf147fc48), + SPH_C32(0x9d4c34ba), SPH_C32(0xa8150200), SPH_C32(0x59006470), + SPH_C32(0x5f35acae), SPH_C32(0xbe81b429) }, + { SPH_C32(0x97ac0a00), SPH_C32(0x25dabcf3), SPH_C32(0x91a205ba), + SPH_C32(0x035841cc), SPH_C32(0x46330200), SPH_C32(0x4b4b0c4e), + SPH_C32(0xdff77a21), SPH_C32(0x85721f05) }, + { SPH_C32(0x510c0c00), SPH_C32(0x251e9889), SPH_C32(0x1e406226), + SPH_C32(0x2f32b340), SPH_C32(0xf5360000), SPH_C32(0x7be3bf82), + SPH_C32(0xd5606668), SPH_C32(0x3f198195) }, + { SPH_C32(0xf6b40e00), SPH_C32(0x3a0c1cba), SPH_C32(0x7ea59bd4), + SPH_C32(0xb126c636), SPH_C32(0x1b100000), SPH_C32(0x69a8d7bc), + SPH_C32(0x55a2b0e7), SPH_C32(0x04ea2ab9) }, + { SPH_C32(0xbf2a0c00), SPH_C32(0x3755f0b7), SPH_C32(0x9e82b4a9), + SPH_C32(0x14c1186c), SPH_C32(0xbca80200), SPH_C32(0x76ba538f), + SPH_C32(0x35474915), SPH_C32(0x9afe5fcf) }, + { SPH_C32(0x18920e00), SPH_C32(0x28477484), SPH_C32(0xfe674d5b), + SPH_C32(0x8ad56d1a), SPH_C32(0x528e0200), SPH_C32(0x64f13bb1), + SPH_C32(0xb5859f9a), SPH_C32(0xa10df4e3) }, + { SPH_C32(0xca8f0800), SPH_C32(0x07396701), SPH_C32(0x1bf7cf7c), + SPH_C32(0x82c07470), SPH_C32(0x7a080400), SPH_C32(0x767e77f5), + SPH_C32(0xbaa52e89), SPH_C32(0xb694ad43) }, + { SPH_C32(0x6d370a00), SPH_C32(0x182be332), SPH_C32(0x7b12368e), + SPH_C32(0x1cd40106), SPH_C32(0x942e0400), SPH_C32(0x64351fcb), + SPH_C32(0x3a67f806), SPH_C32(0x8d67066f) }, + { SPH_C32(0x24a90800), SPH_C32(0x15720f3f), SPH_C32(0x9b3519f3), + SPH_C32(0xb933df5c), SPH_C32(0x33960600), SPH_C32(0x7b279bf8), + SPH_C32(0x5a8201f4), SPH_C32(0x13737319) }, + { SPH_C32(0x83110a00), SPH_C32(0x0a608b0c), SPH_C32(0xfbd0e001), + SPH_C32(0x2727aa2a), SPH_C32(0xddb00600), SPH_C32(0x696cf3c6), + SPH_C32(0xda40d77b), SPH_C32(0x2880d835) }, + { SPH_C32(0x45b10c00), SPH_C32(0x0aa4af76), SPH_C32(0x7432879d), + SPH_C32(0x0b4d58a6), SPH_C32(0x6eb50400), SPH_C32(0x59c4400a), + SPH_C32(0xd0d7cb32), SPH_C32(0x92eb46a5) }, + { SPH_C32(0xe2090e00), SPH_C32(0x15b62b45), SPH_C32(0x14d77e6f), + SPH_C32(0x95592dd0), SPH_C32(0x80930400), SPH_C32(0x4b8f2834), + SPH_C32(0x50151dbd), SPH_C32(0xa918ed89) }, + { SPH_C32(0xab970c00), SPH_C32(0x18efc748), SPH_C32(0xf4f05112), + SPH_C32(0x30bef38a), SPH_C32(0x272b0600), SPH_C32(0x549dac07), + SPH_C32(0x30f0e44f), SPH_C32(0x370c98ff) }, + { SPH_C32(0x0c2f0e00), SPH_C32(0x07fd437b), SPH_C32(0x9415a8e0), + SPH_C32(0xaeaa86fc), SPH_C32(0xc90d0600), SPH_C32(0x46d6c439), + SPH_C32(0xb03232c0), SPH_C32(0x0cff33d3) }, + { SPH_C32(0xe18b0000), SPH_C32(0x5459887d), SPH_C32(0xbf1283d3), + SPH_C32(0x1b666a73), SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), + SPH_C32(0xce97a914), SPH_C32(0xbdd9f5e5) }, + { SPH_C32(0x46330200), SPH_C32(0x4b4b0c4e), SPH_C32(0xdff77a21), + SPH_C32(0x85721f05), SPH_C32(0xd19f0800), SPH_C32(0x6e91b0bd), + SPH_C32(0x4e557f9b), SPH_C32(0x862a5ec9) }, + { SPH_C32(0x0fad0000), SPH_C32(0x4612e043), SPH_C32(0x3fd0555c), + SPH_C32(0x2095c15f), SPH_C32(0x76270a00), SPH_C32(0x7183348e), + SPH_C32(0x2eb08669), SPH_C32(0x183e2bbf) }, + { SPH_C32(0xa8150200), SPH_C32(0x59006470), SPH_C32(0x5f35acae), + SPH_C32(0xbe81b429), SPH_C32(0x98010a00), SPH_C32(0x63c85cb0), + SPH_C32(0xae7250e6), SPH_C32(0x23cd8093) }, + { SPH_C32(0x6eb50400), SPH_C32(0x59c4400a), SPH_C32(0xd0d7cb32), + SPH_C32(0x92eb46a5), SPH_C32(0x2b040800), SPH_C32(0x5360ef7c), + SPH_C32(0xa4e54caf), SPH_C32(0x99a61e03) }, + { SPH_C32(0xc90d0600), SPH_C32(0x46d6c439), SPH_C32(0xb03232c0), + SPH_C32(0x0cff33d3), SPH_C32(0xc5220800), SPH_C32(0x412b8742), + SPH_C32(0x24279a20), SPH_C32(0xa255b52f) }, + { SPH_C32(0x80930400), SPH_C32(0x4b8f2834), SPH_C32(0x50151dbd), + SPH_C32(0xa918ed89), SPH_C32(0x629a0a00), SPH_C32(0x5e390371), + SPH_C32(0x44c263d2), SPH_C32(0x3c41c059) }, + { SPH_C32(0x272b0600), SPH_C32(0x549dac07), SPH_C32(0x30f0e44f), + SPH_C32(0x370c98ff), SPH_C32(0x8cbc0a00), SPH_C32(0x4c726b4f), + SPH_C32(0xc400b55d), SPH_C32(0x07b26b75) }, + { SPH_C32(0xf5360000), SPH_C32(0x7be3bf82), SPH_C32(0xd5606668), + SPH_C32(0x3f198195), SPH_C32(0xa43a0c00), SPH_C32(0x5efd270b), + SPH_C32(0xcb20044e), SPH_C32(0x102b32d5) }, + { SPH_C32(0x528e0200), SPH_C32(0x64f13bb1), SPH_C32(0xb5859f9a), + SPH_C32(0xa10df4e3), SPH_C32(0x4a1c0c00), SPH_C32(0x4cb64f35), + SPH_C32(0x4be2d2c1), SPH_C32(0x2bd899f9) }, + { SPH_C32(0x1b100000), SPH_C32(0x69a8d7bc), SPH_C32(0x55a2b0e7), + SPH_C32(0x04ea2ab9), SPH_C32(0xeda40e00), SPH_C32(0x53a4cb06), + SPH_C32(0x2b072b33), SPH_C32(0xb5ccec8f) }, + { SPH_C32(0xbca80200), SPH_C32(0x76ba538f), SPH_C32(0x35474915), + SPH_C32(0x9afe5fcf), SPH_C32(0x03820e00), SPH_C32(0x41efa338), + SPH_C32(0xabc5fdbc), SPH_C32(0x8e3f47a3) }, + { SPH_C32(0x7a080400), SPH_C32(0x767e77f5), SPH_C32(0xbaa52e89), + SPH_C32(0xb694ad43), SPH_C32(0xb0870c00), SPH_C32(0x714710f4), + SPH_C32(0xa152e1f5), SPH_C32(0x3454d933) }, + { SPH_C32(0xddb00600), SPH_C32(0x696cf3c6), SPH_C32(0xda40d77b), + SPH_C32(0x2880d835), SPH_C32(0x5ea10c00), SPH_C32(0x630c78ca), + SPH_C32(0x2190377a), SPH_C32(0x0fa7721f) }, + { SPH_C32(0x942e0400), SPH_C32(0x64351fcb), SPH_C32(0x3a67f806), + SPH_C32(0x8d67066f), SPH_C32(0xf9190e00), SPH_C32(0x7c1efcf9), + SPH_C32(0x4175ce88), SPH_C32(0x91b30769) }, + { SPH_C32(0x33960600), SPH_C32(0x7b279bf8), SPH_C32(0x5a8201f4), + SPH_C32(0x13737319), SPH_C32(0x173f0e00), SPH_C32(0x6e5594c7), + SPH_C32(0xc1b71807), SPH_C32(0xaa40ac45) }, + { SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), SPH_C32(0xce97a914), + SPH_C32(0xbdd9f5e5), SPH_C32(0xde320800), SPH_C32(0x288350fe), + SPH_C32(0x71852ac7), SPH_C32(0xa6bf9f96) }, + { SPH_C32(0x98010a00), SPH_C32(0x63c85cb0), SPH_C32(0xae7250e6), + SPH_C32(0x23cd8093), SPH_C32(0x30140800), SPH_C32(0x3ac838c0), + SPH_C32(0xf147fc48), SPH_C32(0x9d4c34ba) }, + { SPH_C32(0xd19f0800), SPH_C32(0x6e91b0bd), SPH_C32(0x4e557f9b), + SPH_C32(0x862a5ec9), SPH_C32(0x97ac0a00), SPH_C32(0x25dabcf3), + SPH_C32(0x91a205ba), SPH_C32(0x035841cc) }, + { SPH_C32(0x76270a00), SPH_C32(0x7183348e), SPH_C32(0x2eb08669), + SPH_C32(0x183e2bbf), SPH_C32(0x798a0a00), SPH_C32(0x3791d4cd), + SPH_C32(0x1160d335), SPH_C32(0x38abeae0) }, + { SPH_C32(0xb0870c00), SPH_C32(0x714710f4), SPH_C32(0xa152e1f5), + SPH_C32(0x3454d933), SPH_C32(0xca8f0800), SPH_C32(0x07396701), + SPH_C32(0x1bf7cf7c), SPH_C32(0x82c07470) }, + { SPH_C32(0x173f0e00), SPH_C32(0x6e5594c7), SPH_C32(0xc1b71807), + SPH_C32(0xaa40ac45), SPH_C32(0x24a90800), SPH_C32(0x15720f3f), + SPH_C32(0x9b3519f3), SPH_C32(0xb933df5c) }, + { SPH_C32(0x5ea10c00), SPH_C32(0x630c78ca), SPH_C32(0x2190377a), + SPH_C32(0x0fa7721f), SPH_C32(0x83110a00), SPH_C32(0x0a608b0c), + SPH_C32(0xfbd0e001), SPH_C32(0x2727aa2a) }, + { SPH_C32(0xf9190e00), SPH_C32(0x7c1efcf9), SPH_C32(0x4175ce88), + SPH_C32(0x91b30769), SPH_C32(0x6d370a00), SPH_C32(0x182be332), + SPH_C32(0x7b12368e), SPH_C32(0x1cd40106) }, + { SPH_C32(0x2b040800), SPH_C32(0x5360ef7c), SPH_C32(0xa4e54caf), + SPH_C32(0x99a61e03), SPH_C32(0x45b10c00), SPH_C32(0x0aa4af76), + SPH_C32(0x7432879d), SPH_C32(0x0b4d58a6) }, + { SPH_C32(0x8cbc0a00), SPH_C32(0x4c726b4f), SPH_C32(0xc400b55d), + SPH_C32(0x07b26b75), SPH_C32(0xab970c00), SPH_C32(0x18efc748), + SPH_C32(0xf4f05112), SPH_C32(0x30bef38a) }, + { SPH_C32(0xc5220800), SPH_C32(0x412b8742), SPH_C32(0x24279a20), + SPH_C32(0xa255b52f), SPH_C32(0x0c2f0e00), SPH_C32(0x07fd437b), + SPH_C32(0x9415a8e0), SPH_C32(0xaeaa86fc) }, + { SPH_C32(0x629a0a00), SPH_C32(0x5e390371), SPH_C32(0x44c263d2), + SPH_C32(0x3c41c059), SPH_C32(0xe2090e00), SPH_C32(0x15b62b45), + SPH_C32(0x14d77e6f), SPH_C32(0x95592dd0) }, + { SPH_C32(0xa43a0c00), SPH_C32(0x5efd270b), SPH_C32(0xcb20044e), + SPH_C32(0x102b32d5), SPH_C32(0x510c0c00), SPH_C32(0x251e9889), + SPH_C32(0x1e406226), SPH_C32(0x2f32b340) }, + { SPH_C32(0x03820e00), SPH_C32(0x41efa338), SPH_C32(0xabc5fdbc), + SPH_C32(0x8e3f47a3), SPH_C32(0xbf2a0c00), SPH_C32(0x3755f0b7), + SPH_C32(0x9e82b4a9), SPH_C32(0x14c1186c) }, + { SPH_C32(0x4a1c0c00), SPH_C32(0x4cb64f35), SPH_C32(0x4be2d2c1), + SPH_C32(0x2bd899f9), SPH_C32(0x18920e00), SPH_C32(0x28477484), + SPH_C32(0xfe674d5b), SPH_C32(0x8ad56d1a) }, + { SPH_C32(0xeda40e00), SPH_C32(0x53a4cb06), SPH_C32(0x2b072b33), + SPH_C32(0xb5ccec8f), SPH_C32(0xf6b40e00), SPH_C32(0x3a0c1cba), + SPH_C32(0x7ea59bd4), SPH_C32(0xb126c636) }, + { SPH_C32(0x74951000), SPH_C32(0x5a2b467e), SPH_C32(0x88fd1d2b), + SPH_C32(0x1ee68292), SPH_C32(0xcba90000), SPH_C32(0x90273769), + SPH_C32(0xbbdcf407), SPH_C32(0xd0f4af61) }, + { SPH_C32(0xd32d1200), SPH_C32(0x4539c24d), SPH_C32(0xe818e4d9), + SPH_C32(0x80f2f7e4), SPH_C32(0x258f0000), SPH_C32(0x826c5f57), + SPH_C32(0x3b1e2288), SPH_C32(0xeb07044d) }, + { SPH_C32(0x9ab31000), SPH_C32(0x48602e40), SPH_C32(0x083fcba4), + SPH_C32(0x251529be), SPH_C32(0x82370200), SPH_C32(0x9d7edb64), + SPH_C32(0x5bfbdb7a), SPH_C32(0x7513713b) }, + { SPH_C32(0x3d0b1200), SPH_C32(0x5772aa73), SPH_C32(0x68da3256), + SPH_C32(0xbb015cc8), SPH_C32(0x6c110200), SPH_C32(0x8f35b35a), + SPH_C32(0xdb390df5), SPH_C32(0x4ee0da17) }, + { SPH_C32(0xfbab1400), SPH_C32(0x57b68e09), SPH_C32(0xe73855ca), + SPH_C32(0x976bae44), SPH_C32(0xdf140000), SPH_C32(0xbf9d0096), + SPH_C32(0xd1ae11bc), SPH_C32(0xf48b4487) }, + { SPH_C32(0x5c131600), SPH_C32(0x48a40a3a), SPH_C32(0x87ddac38), + SPH_C32(0x097fdb32), SPH_C32(0x31320000), SPH_C32(0xadd668a8), + SPH_C32(0x516cc733), SPH_C32(0xcf78efab) }, + { SPH_C32(0x158d1400), SPH_C32(0x45fde637), SPH_C32(0x67fa8345), + SPH_C32(0xac980568), SPH_C32(0x968a0200), SPH_C32(0xb2c4ec9b), + SPH_C32(0x31893ec1), SPH_C32(0x516c9add) }, + { SPH_C32(0xb2351600), SPH_C32(0x5aef6204), SPH_C32(0x071f7ab7), + SPH_C32(0x328c701e), SPH_C32(0x78ac0200), SPH_C32(0xa08f84a5), + SPH_C32(0xb14be84e), SPH_C32(0x6a9f31f1) }, + { SPH_C32(0x60281000), SPH_C32(0x75917181), SPH_C32(0xe28ff890), + SPH_C32(0x3a996974), SPH_C32(0x502a0400), SPH_C32(0xb200c8e1), + SPH_C32(0xbe6b595d), SPH_C32(0x7d066851) }, + { SPH_C32(0xc7901200), SPH_C32(0x6a83f5b2), SPH_C32(0x826a0162), + SPH_C32(0xa48d1c02), SPH_C32(0xbe0c0400), SPH_C32(0xa04ba0df), + SPH_C32(0x3ea98fd2), SPH_C32(0x46f5c37d) }, + { SPH_C32(0x8e0e1000), SPH_C32(0x67da19bf), SPH_C32(0x624d2e1f), + SPH_C32(0x016ac258), SPH_C32(0x19b40600), SPH_C32(0xbf5924ec), + SPH_C32(0x5e4c7620), SPH_C32(0xd8e1b60b) }, + { SPH_C32(0x29b61200), SPH_C32(0x78c89d8c), SPH_C32(0x02a8d7ed), + SPH_C32(0x9f7eb72e), SPH_C32(0xf7920600), SPH_C32(0xad124cd2), + SPH_C32(0xde8ea0af), SPH_C32(0xe3121d27) }, + { SPH_C32(0xef161400), SPH_C32(0x780cb9f6), SPH_C32(0x8d4ab071), + SPH_C32(0xb31445a2), SPH_C32(0x44970400), SPH_C32(0x9dbaff1e), + SPH_C32(0xd419bce6), SPH_C32(0x597983b7) }, + { SPH_C32(0x48ae1600), SPH_C32(0x671e3dc5), SPH_C32(0xedaf4983), + SPH_C32(0x2d0030d4), SPH_C32(0xaab10400), SPH_C32(0x8ff19720), + SPH_C32(0x54db6a69), SPH_C32(0x628a289b) }, + { SPH_C32(0x01301400), SPH_C32(0x6a47d1c8), SPH_C32(0x0d8866fe), + SPH_C32(0x88e7ee8e), SPH_C32(0x0d090600), SPH_C32(0x90e31313), + SPH_C32(0x343e939b), SPH_C32(0xfc9e5ded) }, + { SPH_C32(0xa6881600), SPH_C32(0x755555fb), SPH_C32(0x6d6d9f0c), + SPH_C32(0x16f39bf8), SPH_C32(0xe32f0600), SPH_C32(0x82a87b2d), + SPH_C32(0xb4fc4514), SPH_C32(0xc76df6c1) }, + { SPH_C32(0xaaa71800), SPH_C32(0x72a81680), SPH_C32(0xf97837ec), + SPH_C32(0xb8591d04), SPH_C32(0x2a220000), SPH_C32(0xc47ebf14), + SPH_C32(0x04ce77d4), SPH_C32(0xcb92c512) }, + { SPH_C32(0x0d1f1a00), SPH_C32(0x6dba92b3), SPH_C32(0x999dce1e), + SPH_C32(0x264d6872), SPH_C32(0xc4040000), SPH_C32(0xd635d72a), + SPH_C32(0x840ca15b), SPH_C32(0xf0616e3e) }, + { SPH_C32(0x44811800), SPH_C32(0x60e37ebe), SPH_C32(0x79bae163), + SPH_C32(0x83aab628), SPH_C32(0x63bc0200), SPH_C32(0xc9275319), + SPH_C32(0xe4e958a9), SPH_C32(0x6e751b48) }, + { SPH_C32(0xe3391a00), SPH_C32(0x7ff1fa8d), SPH_C32(0x195f1891), + SPH_C32(0x1dbec35e), SPH_C32(0x8d9a0200), SPH_C32(0xdb6c3b27), + SPH_C32(0x642b8e26), SPH_C32(0x5586b064) }, + { SPH_C32(0x25991c00), SPH_C32(0x7f35def7), SPH_C32(0x96bd7f0d), + SPH_C32(0x31d431d2), SPH_C32(0x3e9f0000), SPH_C32(0xebc488eb), + SPH_C32(0x6ebc926f), SPH_C32(0xefed2ef4) }, + { SPH_C32(0x82211e00), SPH_C32(0x60275ac4), SPH_C32(0xf65886ff), + SPH_C32(0xafc044a4), SPH_C32(0xd0b90000), SPH_C32(0xf98fe0d5), + SPH_C32(0xee7e44e0), SPH_C32(0xd41e85d8) }, + { SPH_C32(0xcbbf1c00), SPH_C32(0x6d7eb6c9), SPH_C32(0x167fa982), + SPH_C32(0x0a279afe), SPH_C32(0x77010200), SPH_C32(0xe69d64e6), + SPH_C32(0x8e9bbd12), SPH_C32(0x4a0af0ae) }, + { SPH_C32(0x6c071e00), SPH_C32(0x726c32fa), SPH_C32(0x769a5070), + SPH_C32(0x9433ef88), SPH_C32(0x99270200), SPH_C32(0xf4d60cd8), + SPH_C32(0x0e596b9d), SPH_C32(0x71f95b82) }, + { SPH_C32(0xbe1a1800), SPH_C32(0x5d12217f), SPH_C32(0x930ad257), + SPH_C32(0x9c26f6e2), SPH_C32(0xb1a10400), SPH_C32(0xe659409c), + SPH_C32(0x0179da8e), SPH_C32(0x66600222) }, + { SPH_C32(0x19a21a00), SPH_C32(0x4200a54c), SPH_C32(0xf3ef2ba5), + SPH_C32(0x02328394), SPH_C32(0x5f870400), SPH_C32(0xf41228a2), + SPH_C32(0x81bb0c01), SPH_C32(0x5d93a90e) }, + { SPH_C32(0x503c1800), SPH_C32(0x4f594941), SPH_C32(0x13c804d8), + SPH_C32(0xa7d55dce), SPH_C32(0xf83f0600), SPH_C32(0xeb00ac91), + SPH_C32(0xe15ef5f3), SPH_C32(0xc387dc78) }, + { SPH_C32(0xf7841a00), SPH_C32(0x504bcd72), SPH_C32(0x732dfd2a), + SPH_C32(0x39c128b8), SPH_C32(0x16190600), SPH_C32(0xf94bc4af), + SPH_C32(0x619c237c), SPH_C32(0xf8747754) }, + { SPH_C32(0x31241c00), SPH_C32(0x508fe908), SPH_C32(0xfccf9ab6), + SPH_C32(0x15abda34), SPH_C32(0xa51c0400), SPH_C32(0xc9e37763), + SPH_C32(0x6b0b3f35), SPH_C32(0x421fe9c4) }, + { SPH_C32(0x969c1e00), SPH_C32(0x4f9d6d3b), SPH_C32(0x9c2a6344), + SPH_C32(0x8bbfaf42), SPH_C32(0x4b3a0400), SPH_C32(0xdba81f5d), + SPH_C32(0xebc9e9ba), SPH_C32(0x79ec42e8) }, + { SPH_C32(0xdf021c00), SPH_C32(0x42c48136), SPH_C32(0x7c0d4c39), + SPH_C32(0x2e587118), SPH_C32(0xec820600), SPH_C32(0xc4ba9b6e), + SPH_C32(0x8b2c1048), SPH_C32(0xe7f8379e) }, + { SPH_C32(0x78ba1e00), SPH_C32(0x5dd60505), SPH_C32(0x1ce8b5cb), + SPH_C32(0xb04c046e), SPH_C32(0x02a40600), SPH_C32(0xd6f1f350), + SPH_C32(0x0beec6c7), SPH_C32(0xdc0b9cb2) }, + { SPH_C32(0x951e1000), SPH_C32(0x0e72ce03), SPH_C32(0x37ef9ef8), + SPH_C32(0x0580e8e1), SPH_C32(0xf4100800), SPH_C32(0xecfdefea), + SPH_C32(0x754b5d13), SPH_C32(0x6d2d5a84) }, + { SPH_C32(0x32a61200), SPH_C32(0x11604a30), SPH_C32(0x570a670a), + SPH_C32(0x9b949d97), SPH_C32(0x1a360800), SPH_C32(0xfeb687d4), + SPH_C32(0xf5898b9c), SPH_C32(0x56def1a8) }, + { SPH_C32(0x7b381000), SPH_C32(0x1c39a63d), SPH_C32(0xb72d4877), + SPH_C32(0x3e7343cd), SPH_C32(0xbd8e0a00), SPH_C32(0xe1a403e7), + SPH_C32(0x956c726e), SPH_C32(0xc8ca84de) }, + { SPH_C32(0xdc801200), SPH_C32(0x032b220e), SPH_C32(0xd7c8b185), + SPH_C32(0xa06736bb), SPH_C32(0x53a80a00), SPH_C32(0xf3ef6bd9), + SPH_C32(0x15aea4e1), SPH_C32(0xf3392ff2) }, + { SPH_C32(0x1a201400), SPH_C32(0x03ef0674), SPH_C32(0x582ad619), + SPH_C32(0x8c0dc437), SPH_C32(0xe0ad0800), SPH_C32(0xc347d815), + SPH_C32(0x1f39b8a8), SPH_C32(0x4952b162) }, + { SPH_C32(0xbd981600), SPH_C32(0x1cfd8247), SPH_C32(0x38cf2feb), + SPH_C32(0x1219b141), SPH_C32(0x0e8b0800), SPH_C32(0xd10cb02b), + SPH_C32(0x9ffb6e27), SPH_C32(0x72a11a4e) }, + { SPH_C32(0xf4061400), SPH_C32(0x11a46e4a), SPH_C32(0xd8e80096), + SPH_C32(0xb7fe6f1b), SPH_C32(0xa9330a00), SPH_C32(0xce1e3418), + SPH_C32(0xff1e97d5), SPH_C32(0xecb56f38) }, + { SPH_C32(0x53be1600), SPH_C32(0x0eb6ea79), SPH_C32(0xb80df964), + SPH_C32(0x29ea1a6d), SPH_C32(0x47150a00), SPH_C32(0xdc555c26), + SPH_C32(0x7fdc415a), SPH_C32(0xd746c414) }, + { SPH_C32(0x81a31000), SPH_C32(0x21c8f9fc), SPH_C32(0x5d9d7b43), + SPH_C32(0x21ff0307), SPH_C32(0x6f930c00), SPH_C32(0xceda1062), + SPH_C32(0x70fcf049), SPH_C32(0xc0df9db4) }, + { SPH_C32(0x261b1200), SPH_C32(0x3eda7dcf), SPH_C32(0x3d7882b1), + SPH_C32(0xbfeb7671), SPH_C32(0x81b50c00), SPH_C32(0xdc91785c), + SPH_C32(0xf03e26c6), SPH_C32(0xfb2c3698) }, + { SPH_C32(0x6f851000), SPH_C32(0x338391c2), SPH_C32(0xdd5fadcc), + SPH_C32(0x1a0ca82b), SPH_C32(0x260d0e00), SPH_C32(0xc383fc6f), + SPH_C32(0x90dbdf34), SPH_C32(0x653843ee) }, + { SPH_C32(0xc83d1200), SPH_C32(0x2c9115f1), SPH_C32(0xbdba543e), + SPH_C32(0x8418dd5d), SPH_C32(0xc82b0e00), SPH_C32(0xd1c89451), + SPH_C32(0x101909bb), SPH_C32(0x5ecbe8c2) }, + { SPH_C32(0x0e9d1400), SPH_C32(0x2c55318b), SPH_C32(0x325833a2), + SPH_C32(0xa8722fd1), SPH_C32(0x7b2e0c00), SPH_C32(0xe160279d), + SPH_C32(0x1a8e15f2), SPH_C32(0xe4a07652) }, + { SPH_C32(0xa9251600), SPH_C32(0x3347b5b8), SPH_C32(0x52bdca50), + SPH_C32(0x36665aa7), SPH_C32(0x95080c00), SPH_C32(0xf32b4fa3), + SPH_C32(0x9a4cc37d), SPH_C32(0xdf53dd7e) }, + { SPH_C32(0xe0bb1400), SPH_C32(0x3e1e59b5), SPH_C32(0xb29ae52d), + SPH_C32(0x938184fd), SPH_C32(0x32b00e00), SPH_C32(0xec39cb90), + SPH_C32(0xfaa93a8f), SPH_C32(0x4147a808) }, + { SPH_C32(0x47031600), SPH_C32(0x210cdd86), SPH_C32(0xd27f1cdf), + SPH_C32(0x0d95f18b), SPH_C32(0xdc960e00), SPH_C32(0xfe72a3ae), + SPH_C32(0x7a6bec00), SPH_C32(0x7ab40324) }, + { SPH_C32(0x4b2c1800), SPH_C32(0x26f19efd), SPH_C32(0x466ab43f), + SPH_C32(0xa33f7777), SPH_C32(0x159b0800), SPH_C32(0xb8a46797), + SPH_C32(0xca59dec0), SPH_C32(0x764b30f7) }, + { SPH_C32(0xec941a00), SPH_C32(0x39e31ace), SPH_C32(0x268f4dcd), + SPH_C32(0x3d2b0201), SPH_C32(0xfbbd0800), SPH_C32(0xaaef0fa9), + SPH_C32(0x4a9b084f), SPH_C32(0x4db89bdb) }, + { SPH_C32(0xa50a1800), SPH_C32(0x34baf6c3), SPH_C32(0xc6a862b0), + SPH_C32(0x98ccdc5b), SPH_C32(0x5c050a00), SPH_C32(0xb5fd8b9a), + SPH_C32(0x2a7ef1bd), SPH_C32(0xd3aceead) }, + { SPH_C32(0x02b21a00), SPH_C32(0x2ba872f0), SPH_C32(0xa64d9b42), + SPH_C32(0x06d8a92d), SPH_C32(0xb2230a00), SPH_C32(0xa7b6e3a4), + SPH_C32(0xaabc2732), SPH_C32(0xe85f4581) }, + { SPH_C32(0xc4121c00), SPH_C32(0x2b6c568a), SPH_C32(0x29affcde), + SPH_C32(0x2ab25ba1), SPH_C32(0x01260800), SPH_C32(0x971e5068), + SPH_C32(0xa02b3b7b), SPH_C32(0x5234db11) }, + { SPH_C32(0x63aa1e00), SPH_C32(0x347ed2b9), SPH_C32(0x494a052c), + SPH_C32(0xb4a62ed7), SPH_C32(0xef000800), SPH_C32(0x85553856), + SPH_C32(0x20e9edf4), SPH_C32(0x69c7703d) }, + { SPH_C32(0x2a341c00), SPH_C32(0x39273eb4), SPH_C32(0xa96d2a51), + SPH_C32(0x1141f08d), SPH_C32(0x48b80a00), SPH_C32(0x9a47bc65), + SPH_C32(0x400c1406), SPH_C32(0xf7d3054b) }, + { SPH_C32(0x8d8c1e00), SPH_C32(0x2635ba87), SPH_C32(0xc988d3a3), + SPH_C32(0x8f5585fb), SPH_C32(0xa69e0a00), SPH_C32(0x880cd45b), + SPH_C32(0xc0cec289), SPH_C32(0xcc20ae67) }, + { SPH_C32(0x5f911800), SPH_C32(0x094ba902), SPH_C32(0x2c185184), + SPH_C32(0x87409c91), SPH_C32(0x8e180c00), SPH_C32(0x9a83981f), + SPH_C32(0xcfee739a), SPH_C32(0xdbb9f7c7) }, + { SPH_C32(0xf8291a00), SPH_C32(0x16592d31), SPH_C32(0x4cfda876), + SPH_C32(0x1954e9e7), SPH_C32(0x603e0c00), SPH_C32(0x88c8f021), + SPH_C32(0x4f2ca515), SPH_C32(0xe04a5ceb) }, + { SPH_C32(0xb1b71800), SPH_C32(0x1b00c13c), SPH_C32(0xacda870b), + SPH_C32(0xbcb337bd), SPH_C32(0xc7860e00), SPH_C32(0x97da7412), + SPH_C32(0x2fc95ce7), SPH_C32(0x7e5e299d) }, + { SPH_C32(0x160f1a00), SPH_C32(0x0412450f), SPH_C32(0xcc3f7ef9), + SPH_C32(0x22a742cb), SPH_C32(0x29a00e00), SPH_C32(0x85911c2c), + SPH_C32(0xaf0b8a68), SPH_C32(0x45ad82b1) }, + { SPH_C32(0xd0af1c00), SPH_C32(0x04d66175), SPH_C32(0x43dd1965), + SPH_C32(0x0ecdb047), SPH_C32(0x9aa50c00), SPH_C32(0xb539afe0), + SPH_C32(0xa59c9621), SPH_C32(0xffc61c21) }, + { SPH_C32(0x77171e00), SPH_C32(0x1bc4e546), SPH_C32(0x2338e097), + SPH_C32(0x90d9c531), SPH_C32(0x74830c00), SPH_C32(0xa772c7de), + SPH_C32(0x255e40ae), SPH_C32(0xc435b70d) }, + { SPH_C32(0x3e891c00), SPH_C32(0x169d094b), SPH_C32(0xc31fcfea), + SPH_C32(0x353e1b6b), SPH_C32(0xd33b0e00), SPH_C32(0xb86043ed), + SPH_C32(0x45bbb95c), SPH_C32(0x5a21c27b) }, + { SPH_C32(0x99311e00), SPH_C32(0x098f8d78), SPH_C32(0xa3fa3618), + SPH_C32(0xab2a6e1d), SPH_C32(0x3d1d0e00), SPH_C32(0xaa2b2bd3), + SPH_C32(0xc5796fd3), SPH_C32(0x61d26957) } +}; + +static const sph_u32 T256_14[128][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), SPH_C32(0x79a90df9), + SPH_C32(0x63e92178), SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), + SPH_C32(0x806741fd), SPH_C32(0x814681b8) }, + { SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), SPH_C32(0x36656ba8), + SPH_C32(0x23633a05), SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), + SPH_C32(0x5d5ca0f7), SPH_C32(0x727784cb) }, + { SPH_C32(0x11bc0040), SPH_C32(0xf2e1216c), SPH_C32(0x4fcc6651), + SPH_C32(0x408a1b7d), SPH_C32(0x86610020), SPH_C32(0xe89072d0), + SPH_C32(0xdd3be10a), SPH_C32(0xf3310573) }, + { SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), SPH_C32(0x5d5ca0f7), + SPH_C32(0x727784cb), SPH_C32(0x35650040), SPH_C32(0x9b96b64a), + SPH_C32(0x6b39cb5f), SPH_C32(0x5114bece) }, + { SPH_C32(0x24d90000), SPH_C32(0x69779726), SPH_C32(0x24f5ad0e), + SPH_C32(0x119ea5b3), SPH_C32(0xcbaf0060), SPH_C32(0xd3cb9eae), + SPH_C32(0xeb5e8aa2), SPH_C32(0xd0523f76) }, + { SPH_C32(0x35650040), SPH_C32(0x9b96b64a), SPH_C32(0x6b39cb5f), + SPH_C32(0x5114bece), SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), + SPH_C32(0x36656ba8), SPH_C32(0x23633a05) }, + { SPH_C32(0x69170040), SPH_C32(0x522c7b58), SPH_C32(0x1290c6a6), + SPH_C32(0x32fd9fb6), SPH_C32(0xb3040060), SPH_C32(0x7306c49a), + SPH_C32(0xb6022a55), SPH_C32(0xa225bbbd) }, + { SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), SPH_C32(0xc2c46c55), + SPH_C32(0xf362b233), SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), + SPH_C32(0xd14e094b), SPH_C32(0xb772b42b) }, + { SPH_C32(0x07a00080), SPH_C32(0x8cb5d5fe), SPH_C32(0xbb6d61ac), + SPH_C32(0x908b934b), SPH_C32(0xc76c0020), SPH_C32(0x02ea7b0f), + SPH_C32(0x512948b6), SPH_C32(0x36343593) }, + { SPH_C32(0x161c00c0), SPH_C32(0x7e54f492), SPH_C32(0xf4a107fd), + SPH_C32(0xd0018836), SPH_C32(0x410d0000), SPH_C32(0xea7a09df), + SPH_C32(0x8c12a9bc), SPH_C32(0xc50530e0) }, + { SPH_C32(0x4a6e00c0), SPH_C32(0xb7ee3980), SPH_C32(0x8d080a04), + SPH_C32(0xb3e8a94e), SPH_C32(0xbfc70020), SPH_C32(0xa227213b), + SPH_C32(0x0c75e841), SPH_C32(0x4443b158) }, + { SPH_C32(0x23790080), SPH_C32(0xe5c242d8), SPH_C32(0x9f98cca2), + SPH_C32(0x811536f8), SPH_C32(0x0cc30040), SPH_C32(0xd121e5a1), + SPH_C32(0xba77c214), SPH_C32(0xe6660ae5) }, + { SPH_C32(0x7f0b0080), SPH_C32(0x2c788fca), SPH_C32(0xe631c15b), + SPH_C32(0xe2fc1780), SPH_C32(0xf2090060), SPH_C32(0x997ccd45), + SPH_C32(0x3a1083e9), SPH_C32(0x67208b5d) }, + { SPH_C32(0x6eb700c0), SPH_C32(0xde99aea6), SPH_C32(0xa9fda70a), + SPH_C32(0xa2760cfd), SPH_C32(0x74680040), SPH_C32(0x71ecbf95), + SPH_C32(0xe72b62e3), SPH_C32(0x94118e2e) }, + { SPH_C32(0x32c500c0), SPH_C32(0x172363b4), SPH_C32(0xd054aaf3), + SPH_C32(0xc19f2d85), SPH_C32(0x8aa20060), SPH_C32(0x39b19771), + SPH_C32(0x674c231e), SPH_C32(0x15570f96) }, + { SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), SPH_C32(0xd14e094b), + SPH_C32(0xb772b42b), SPH_C32(0x62740080), SPH_C32(0x0fb84b07), + SPH_C32(0x138a651e), SPH_C32(0x44100618) }, + { SPH_C32(0x65d40000), SPH_C32(0x830d9ef9), SPH_C32(0xa8e704b2), + SPH_C32(0xd49b9553), SPH_C32(0x9cbe00a0), SPH_C32(0x47e563e3), + SPH_C32(0x93ed24e3), SPH_C32(0xc55687a0) }, + { SPH_C32(0x74680040), SPH_C32(0x71ecbf95), SPH_C32(0xe72b62e3), + SPH_C32(0x94118e2e), SPH_C32(0x1adf0080), SPH_C32(0xaf751133), + SPH_C32(0x4ed6c5e9), SPH_C32(0x366782d3) }, + { SPH_C32(0x281a0040), SPH_C32(0xb8567287), SPH_C32(0x9e826f1a), + SPH_C32(0xf7f8af56), SPH_C32(0xe41500a0), SPH_C32(0xe72839d7), + SPH_C32(0xceb18414), SPH_C32(0xb721036b) }, + { SPH_C32(0x410d0000), SPH_C32(0xea7a09df), SPH_C32(0x8c12a9bc), + SPH_C32(0xc50530e0), SPH_C32(0x571100c0), SPH_C32(0x942efd4d), + SPH_C32(0x78b3ae41), SPH_C32(0x1504b8d6) }, + { SPH_C32(0x1d7f0000), SPH_C32(0x23c0c4cd), SPH_C32(0xf5bba445), + SPH_C32(0xa6ec1198), SPH_C32(0xa9db00e0), SPH_C32(0xdc73d5a9), + SPH_C32(0xf8d4efbc), SPH_C32(0x9442396e) }, + { SPH_C32(0x0cc30040), SPH_C32(0xd121e5a1), SPH_C32(0xba77c214), + SPH_C32(0xe6660ae5), SPH_C32(0x2fba00c0), SPH_C32(0x34e3a779), + SPH_C32(0x25ef0eb6), SPH_C32(0x67733c1d) }, + { SPH_C32(0x50b10040), SPH_C32(0x189b28b3), SPH_C32(0xc3decfed), + SPH_C32(0x858f2b9d), SPH_C32(0xd17000e0), SPH_C32(0x7cbe8f9d), + SPH_C32(0xa5884f4b), SPH_C32(0xe635bda5) }, + { SPH_C32(0x62740080), SPH_C32(0x0fb84b07), SPH_C32(0x138a651e), + SPH_C32(0x44100618), SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), + SPH_C32(0xc2c46c55), SPH_C32(0xf362b233) }, + { SPH_C32(0x3e060080), SPH_C32(0xc6028615), SPH_C32(0x6a2368e7), + SPH_C32(0x27f92760), SPH_C32(0xa51800a0), SPH_C32(0x0d523008), + SPH_C32(0x42a32da8), SPH_C32(0x7224338b) }, + { SPH_C32(0x2fba00c0), SPH_C32(0x34e3a779), SPH_C32(0x25ef0eb6), + SPH_C32(0x67733c1d), SPH_C32(0x23790080), SPH_C32(0xe5c242d8), + SPH_C32(0x9f98cca2), SPH_C32(0x811536f8) }, + { SPH_C32(0x73c800c0), SPH_C32(0xfd596a6b), SPH_C32(0x5c46034f), + SPH_C32(0x049a1d65), SPH_C32(0xddb300a0), SPH_C32(0xad9f6a3c), + SPH_C32(0x1fff8d5f), SPH_C32(0x0053b740) }, + { SPH_C32(0x1adf0080), SPH_C32(0xaf751133), SPH_C32(0x4ed6c5e9), + SPH_C32(0x366782d3), SPH_C32(0x6eb700c0), SPH_C32(0xde99aea6), + SPH_C32(0xa9fda70a), SPH_C32(0xa2760cfd) }, + { SPH_C32(0x46ad0080), SPH_C32(0x66cfdc21), SPH_C32(0x377fc810), + SPH_C32(0x558ea3ab), SPH_C32(0x907d00e0), SPH_C32(0x96c48642), + SPH_C32(0x299ae6f7), SPH_C32(0x23308d45) }, + { SPH_C32(0x571100c0), SPH_C32(0x942efd4d), SPH_C32(0x78b3ae41), + SPH_C32(0x1504b8d6), SPH_C32(0x161c00c0), SPH_C32(0x7e54f492), + SPH_C32(0xf4a107fd), SPH_C32(0xd0018836) }, + { SPH_C32(0x0b6300c0), SPH_C32(0x5d94305f), SPH_C32(0x011aa3b8), + SPH_C32(0x76ed99ae), SPH_C32(0xe8d600e0), SPH_C32(0x3609dc76), + SPH_C32(0x74c64600), SPH_C32(0x5147098e) }, + { SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), SPH_C32(0x8589d8ab), + SPH_C32(0xe6c46464), SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), + SPH_C32(0xa29d1297), SPH_C32(0x6ee56854) }, + { SPH_C32(0xebd60100), SPH_C32(0x43a5fcca), SPH_C32(0xfc20d552), + SPH_C32(0x852d451c), SPH_C32(0x8d860020), SPH_C32(0xdd328f32), + SPH_C32(0x22fa536a), SPH_C32(0xefa3e9ec) }, + { SPH_C32(0xfa6a0140), SPH_C32(0xb144dda6), SPH_C32(0xb3ecb303), + SPH_C32(0xc5a75e61), SPH_C32(0x0be70000), SPH_C32(0x35a2fde2), + SPH_C32(0xffc1b260), SPH_C32(0x1c92ec9f) }, + { SPH_C32(0xa6180140), SPH_C32(0x78fe10b4), SPH_C32(0xca45befa), + SPH_C32(0xa64e7f19), SPH_C32(0xf52d0020), SPH_C32(0x7dffd506), + SPH_C32(0x7fa6f39d), SPH_C32(0x9dd46d27) }, + { SPH_C32(0xcf0f0100), SPH_C32(0x2ad26bec), SPH_C32(0xd8d5785c), + SPH_C32(0x94b3e0af), SPH_C32(0x46290040), SPH_C32(0x0ef9119c), + SPH_C32(0xc9a4d9c8), SPH_C32(0x3ff1d69a) }, + { SPH_C32(0x937d0100), SPH_C32(0xe368a6fe), SPH_C32(0xa17c75a5), + SPH_C32(0xf75ac1d7), SPH_C32(0xb8e30060), SPH_C32(0x46a43978), + SPH_C32(0x49c39835), SPH_C32(0xbeb75722) }, + { SPH_C32(0x82c10140), SPH_C32(0x11898792), SPH_C32(0xeeb013f4), + SPH_C32(0xb7d0daaa), SPH_C32(0x3e820040), SPH_C32(0xae344ba8), + SPH_C32(0x94f8793f), SPH_C32(0x4d865251) }, + { SPH_C32(0xdeb30140), SPH_C32(0xd8334a80), SPH_C32(0x97191e0d), + SPH_C32(0xd439fbd2), SPH_C32(0xc0480060), SPH_C32(0xe669634c), + SPH_C32(0x149f38c2), SPH_C32(0xccc0d3e9) }, + { SPH_C32(0xec760180), SPH_C32(0xcf102934), SPH_C32(0x474db4fe), + SPH_C32(0x15a6d657), SPH_C32(0x4aea0000), SPH_C32(0xdfd8f43d), + SPH_C32(0x73d31bdc), SPH_C32(0xd997dc7f) }, + { SPH_C32(0xb0040180), SPH_C32(0x06aae426), SPH_C32(0x3ee4b907), + SPH_C32(0x764ff72f), SPH_C32(0xb4200020), SPH_C32(0x9785dcd9), + SPH_C32(0xf3b45a21), SPH_C32(0x58d15dc7) }, + { SPH_C32(0xa1b801c0), SPH_C32(0xf44bc54a), SPH_C32(0x7128df56), + SPH_C32(0x36c5ec52), SPH_C32(0x32410000), SPH_C32(0x7f15ae09), + SPH_C32(0x2e8fbb2b), SPH_C32(0xabe058b4) }, + { SPH_C32(0xfdca01c0), SPH_C32(0x3df10858), SPH_C32(0x0881d2af), + SPH_C32(0x552ccd2a), SPH_C32(0xcc8b0020), SPH_C32(0x374886ed), + SPH_C32(0xaee8fad6), SPH_C32(0x2aa6d90c) }, + { SPH_C32(0x94dd0180), SPH_C32(0x6fdd7300), SPH_C32(0x1a111409), + SPH_C32(0x67d1529c), SPH_C32(0x7f8f0040), SPH_C32(0x444e4277), + SPH_C32(0x18ead083), SPH_C32(0x888362b1) }, + { SPH_C32(0xc8af0180), SPH_C32(0xa667be12), SPH_C32(0x63b819f0), + SPH_C32(0x043873e4), SPH_C32(0x81450060), SPH_C32(0x0c136a93), + SPH_C32(0x988d917e), SPH_C32(0x09c5e309) }, + { SPH_C32(0xd91301c0), SPH_C32(0x54869f7e), SPH_C32(0x2c747fa1), + SPH_C32(0x44b26899), SPH_C32(0x07240040), SPH_C32(0xe4831843), + SPH_C32(0x45b67074), SPH_C32(0xfaf4e67a) }, + { SPH_C32(0x856101c0), SPH_C32(0x9d3c526c), SPH_C32(0x55dd7258), + SPH_C32(0x275b49e1), SPH_C32(0xf9ee0060), SPH_C32(0xacde30a7), + SPH_C32(0xc5d13189), SPH_C32(0x7bb267c2) }, + { SPH_C32(0x8e020100), SPH_C32(0xc0a86233), SPH_C32(0x54c7d1e0), + SPH_C32(0x51b6d04f), SPH_C32(0x11380080), SPH_C32(0x9ad7ecd1), + SPH_C32(0xb1177789), SPH_C32(0x2af56e4c) }, + { SPH_C32(0xd2700100), SPH_C32(0x0912af21), SPH_C32(0x2d6edc19), + SPH_C32(0x325ff137), SPH_C32(0xeff200a0), SPH_C32(0xd28ac435), + SPH_C32(0x31703674), SPH_C32(0xabb3eff4) }, + { SPH_C32(0xc3cc0140), SPH_C32(0xfbf38e4d), SPH_C32(0x62a2ba48), + SPH_C32(0x72d5ea4a), SPH_C32(0x69930080), SPH_C32(0x3a1ab6e5), + SPH_C32(0xec4bd77e), SPH_C32(0x5882ea87) }, + { SPH_C32(0x9fbe0140), SPH_C32(0x3249435f), SPH_C32(0x1b0bb7b1), + SPH_C32(0x113ccb32), SPH_C32(0x975900a0), SPH_C32(0x72479e01), + SPH_C32(0x6c2c9683), SPH_C32(0xd9c46b3f) }, + { SPH_C32(0xf6a90100), SPH_C32(0x60653807), SPH_C32(0x099b7117), + SPH_C32(0x23c15484), SPH_C32(0x245d00c0), SPH_C32(0x01415a9b), + SPH_C32(0xda2ebcd6), SPH_C32(0x7be1d082) }, + { SPH_C32(0xaadb0100), SPH_C32(0xa9dff515), SPH_C32(0x70327cee), + SPH_C32(0x402875fc), SPH_C32(0xda9700e0), SPH_C32(0x491c727f), + SPH_C32(0x5a49fd2b), SPH_C32(0xfaa7513a) }, + { SPH_C32(0xbb670140), SPH_C32(0x5b3ed479), SPH_C32(0x3ffe1abf), + SPH_C32(0x00a26e81), SPH_C32(0x5cf600c0), SPH_C32(0xa18c00af), + SPH_C32(0x87721c21), SPH_C32(0x09965449) }, + { SPH_C32(0xe7150140), SPH_C32(0x9284196b), SPH_C32(0x46571746), + SPH_C32(0x634b4ff9), SPH_C32(0xa23c00e0), SPH_C32(0xe9d1284b), + SPH_C32(0x07155ddc), SPH_C32(0x88d0d5f1) }, + { SPH_C32(0xd5d00180), SPH_C32(0x85a77adf), SPH_C32(0x9603bdb5), + SPH_C32(0xa2d4627c), SPH_C32(0x289e0080), SPH_C32(0xd060bf3a), + SPH_C32(0x60597ec2), SPH_C32(0x9d87da67) }, + { SPH_C32(0x89a20180), SPH_C32(0x4c1db7cd), SPH_C32(0xefaab04c), + SPH_C32(0xc13d4304), SPH_C32(0xd65400a0), SPH_C32(0x983d97de), + SPH_C32(0xe03e3f3f), SPH_C32(0x1cc15bdf) }, + { SPH_C32(0x981e01c0), SPH_C32(0xbefc96a1), SPH_C32(0xa066d61d), + SPH_C32(0x81b75879), SPH_C32(0x50350080), SPH_C32(0x70ade50e), + SPH_C32(0x3d05de35), SPH_C32(0xeff05eac) }, + { SPH_C32(0xc46c01c0), SPH_C32(0x77465bb3), SPH_C32(0xd9cfdbe4), + SPH_C32(0xe25e7901), SPH_C32(0xaeff00a0), SPH_C32(0x38f0cdea), + SPH_C32(0xbd629fc8), SPH_C32(0x6eb6df14) }, + { SPH_C32(0xad7b0180), SPH_C32(0x256a20eb), SPH_C32(0xcb5f1d42), + SPH_C32(0xd0a3e6b7), SPH_C32(0x1dfb00c0), SPH_C32(0x4bf60970), + SPH_C32(0x0b60b59d), SPH_C32(0xcc9364a9) }, + { SPH_C32(0xf1090180), SPH_C32(0xecd0edf9), SPH_C32(0xb2f610bb), + SPH_C32(0xb34ac7cf), SPH_C32(0xe33100e0), SPH_C32(0x03ab2194), + SPH_C32(0x8b07f460), SPH_C32(0x4dd5e511) }, + { SPH_C32(0xe0b501c0), SPH_C32(0x1e31cc95), SPH_C32(0xfd3a76ea), + SPH_C32(0xf3c0dcb2), SPH_C32(0x655000c0), SPH_C32(0xeb3b5344), + SPH_C32(0x563c156a), SPH_C32(0xbee4e062) }, + { SPH_C32(0xbcc701c0), SPH_C32(0xd78b0187), SPH_C32(0x84937b13), + SPH_C32(0x9029fdca), SPH_C32(0x9b9a00e0), SPH_C32(0xa3667ba0), + SPH_C32(0xd65b5497), SPH_C32(0x3fa261da) }, + { SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), SPH_C32(0xa29d1297), + SPH_C32(0x6ee56854), SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), + SPH_C32(0x2714ca3c), SPH_C32(0x88210c30) }, + { SPH_C32(0x2f3e0000), SPH_C32(0x5cd56ac4), SPH_C32(0xdb341f6e), + SPH_C32(0x0d0c492c), SPH_C32(0x3a220120), SPH_C32(0x572dbeea), + SPH_C32(0xa7738bc1), SPH_C32(0x09678d88) }, + { SPH_C32(0x3e820040), SPH_C32(0xae344ba8), SPH_C32(0x94f8793f), + SPH_C32(0x4d865251), SPH_C32(0xbc430100), SPH_C32(0xbfbdcc3a), + SPH_C32(0x7a486acb), SPH_C32(0xfa5688fb) }, + { SPH_C32(0x62f00040), SPH_C32(0x678e86ba), SPH_C32(0xed5174c6), + SPH_C32(0x2e6f7329), SPH_C32(0x42890120), SPH_C32(0xf7e0e4de), + SPH_C32(0xfa2f2b36), SPH_C32(0x7b100943) }, + { SPH_C32(0x0be70000), SPH_C32(0x35a2fde2), SPH_C32(0xffc1b260), + SPH_C32(0x1c92ec9f), SPH_C32(0xf18d0140), SPH_C32(0x84e62044), + SPH_C32(0x4c2d0163), SPH_C32(0xd935b2fe) }, + { SPH_C32(0x57950000), SPH_C32(0xfc1830f0), SPH_C32(0x8668bf99), + SPH_C32(0x7f7bcde7), SPH_C32(0x0f470160), SPH_C32(0xccbb08a0), + SPH_C32(0xcc4a409e), SPH_C32(0x58733346) }, + { SPH_C32(0x46290040), SPH_C32(0x0ef9119c), SPH_C32(0xc9a4d9c8), + SPH_C32(0x3ff1d69a), SPH_C32(0x89260140), SPH_C32(0x242b7a70), + SPH_C32(0x1171a194), SPH_C32(0xab423635) }, + { SPH_C32(0x1a5b0040), SPH_C32(0xc743dc8e), SPH_C32(0xb00dd431), + SPH_C32(0x5c18f7e2), SPH_C32(0x77ec0160), SPH_C32(0x6c765294), + SPH_C32(0x9116e069), SPH_C32(0x2a04b78d) }, + { SPH_C32(0x289e0080), SPH_C32(0xd060bf3a), SPH_C32(0x60597ec2), + SPH_C32(0x9d87da67), SPH_C32(0xfd4e0100), SPH_C32(0x55c7c5e5), + SPH_C32(0xf65ac377), SPH_C32(0x3f53b81b) }, + { SPH_C32(0x74ec0080), SPH_C32(0x19da7228), SPH_C32(0x19f0733b), + SPH_C32(0xfe6efb1f), SPH_C32(0x03840120), SPH_C32(0x1d9aed01), + SPH_C32(0x763d828a), SPH_C32(0xbe1539a3) }, + { SPH_C32(0x655000c0), SPH_C32(0xeb3b5344), SPH_C32(0x563c156a), + SPH_C32(0xbee4e062), SPH_C32(0x85e50100), SPH_C32(0xf50a9fd1), + SPH_C32(0xab066380), SPH_C32(0x4d243cd0) }, + { SPH_C32(0x392200c0), SPH_C32(0x22819e56), SPH_C32(0x2f951893), + SPH_C32(0xdd0dc11a), SPH_C32(0x7b2f0120), SPH_C32(0xbd57b735), + SPH_C32(0x2b61227d), SPH_C32(0xcc62bd68) }, + { SPH_C32(0x50350080), SPH_C32(0x70ade50e), SPH_C32(0x3d05de35), + SPH_C32(0xeff05eac), SPH_C32(0xc82b0140), SPH_C32(0xce5173af), + SPH_C32(0x9d630828), SPH_C32(0x6e4706d5) }, + { SPH_C32(0x0c470080), SPH_C32(0xb917281c), SPH_C32(0x44acd3cc), + SPH_C32(0x8c197fd4), SPH_C32(0x36e10160), SPH_C32(0x860c5b4b), + SPH_C32(0x1d0449d5), SPH_C32(0xef01876d) }, + { SPH_C32(0x1dfb00c0), SPH_C32(0x4bf60970), SPH_C32(0x0b60b59d), + SPH_C32(0xcc9364a9), SPH_C32(0xb0800140), SPH_C32(0x6e9c299b), + SPH_C32(0xc03fa8df), SPH_C32(0x1c30821e) }, + { SPH_C32(0x418900c0), SPH_C32(0x824cc462), SPH_C32(0x72c9b864), + SPH_C32(0xaf7a45d1), SPH_C32(0x4e4a0160), SPH_C32(0x26c1017f), + SPH_C32(0x4058e922), SPH_C32(0x9d7603a6) }, + { SPH_C32(0x4aea0000), SPH_C32(0xdfd8f43d), SPH_C32(0x73d31bdc), + SPH_C32(0xd997dc7f), SPH_C32(0xa69c0180), SPH_C32(0x10c8dd09), + SPH_C32(0x349eaf22), SPH_C32(0xcc310a28) }, + { SPH_C32(0x16980000), SPH_C32(0x1662392f), SPH_C32(0x0a7a1625), + SPH_C32(0xba7efd07), SPH_C32(0x585601a0), SPH_C32(0x5895f5ed), + SPH_C32(0xb4f9eedf), SPH_C32(0x4d778b90) }, + { SPH_C32(0x07240040), SPH_C32(0xe4831843), SPH_C32(0x45b67074), + SPH_C32(0xfaf4e67a), SPH_C32(0xde370180), SPH_C32(0xb005873d), + SPH_C32(0x69c20fd5), SPH_C32(0xbe468ee3) }, + { SPH_C32(0x5b560040), SPH_C32(0x2d39d551), SPH_C32(0x3c1f7d8d), + SPH_C32(0x991dc702), SPH_C32(0x20fd01a0), SPH_C32(0xf858afd9), + SPH_C32(0xe9a54e28), SPH_C32(0x3f000f5b) }, + { SPH_C32(0x32410000), SPH_C32(0x7f15ae09), SPH_C32(0x2e8fbb2b), + SPH_C32(0xabe058b4), SPH_C32(0x93f901c0), SPH_C32(0x8b5e6b43), + SPH_C32(0x5fa7647d), SPH_C32(0x9d25b4e6) }, + { SPH_C32(0x6e330000), SPH_C32(0xb6af631b), SPH_C32(0x5726b6d2), + SPH_C32(0xc80979cc), SPH_C32(0x6d3301e0), SPH_C32(0xc30343a7), + SPH_C32(0xdfc02580), SPH_C32(0x1c63355e) }, + { SPH_C32(0x7f8f0040), SPH_C32(0x444e4277), SPH_C32(0x18ead083), + SPH_C32(0x888362b1), SPH_C32(0xeb5201c0), SPH_C32(0x2b933177), + SPH_C32(0x02fbc48a), SPH_C32(0xef52302d) }, + { SPH_C32(0x23fd0040), SPH_C32(0x8df48f65), SPH_C32(0x6143dd7a), + SPH_C32(0xeb6a43c9), SPH_C32(0x159801e0), SPH_C32(0x63ce1993), + SPH_C32(0x829c8577), SPH_C32(0x6e14b195) }, + { SPH_C32(0x11380080), SPH_C32(0x9ad7ecd1), SPH_C32(0xb1177789), + SPH_C32(0x2af56e4c), SPH_C32(0x9f3a0180), SPH_C32(0x5a7f8ee2), + SPH_C32(0xe5d0a669), SPH_C32(0x7b43be03) }, + { SPH_C32(0x4d4a0080), SPH_C32(0x536d21c3), SPH_C32(0xc8be7a70), + SPH_C32(0x491c4f34), SPH_C32(0x61f001a0), SPH_C32(0x1222a606), + SPH_C32(0x65b7e794), SPH_C32(0xfa053fbb) }, + { SPH_C32(0x5cf600c0), SPH_C32(0xa18c00af), SPH_C32(0x87721c21), + SPH_C32(0x09965449), SPH_C32(0xe7910180), SPH_C32(0xfab2d4d6), + SPH_C32(0xb88c069e), SPH_C32(0x09343ac8) }, + { SPH_C32(0x008400c0), SPH_C32(0x6836cdbd), SPH_C32(0xfedb11d8), + SPH_C32(0x6a7f7531), SPH_C32(0x195b01a0), SPH_C32(0xb2effc32), + SPH_C32(0x38eb4763), SPH_C32(0x8872bb70) }, + { SPH_C32(0x69930080), SPH_C32(0x3a1ab6e5), SPH_C32(0xec4bd77e), + SPH_C32(0x5882ea87), SPH_C32(0xaa5f01c0), SPH_C32(0xc1e938a8), + SPH_C32(0x8ee96d36), SPH_C32(0x2a5700cd) }, + { SPH_C32(0x35e10080), SPH_C32(0xf3a07bf7), SPH_C32(0x95e2da87), + SPH_C32(0x3b6bcbff), SPH_C32(0x549501e0), SPH_C32(0x89b4104c), + SPH_C32(0x0e8e2ccb), SPH_C32(0xab118175) }, + { SPH_C32(0x245d00c0), SPH_C32(0x01415a9b), SPH_C32(0xda2ebcd6), + SPH_C32(0x7be1d082), SPH_C32(0xd2f401c0), SPH_C32(0x6124629c), + SPH_C32(0xd3b5cdc1), SPH_C32(0x58208406) }, + { SPH_C32(0x782f00c0), SPH_C32(0xc8fb9789), SPH_C32(0xa387b12f), + SPH_C32(0x1808f1fa), SPH_C32(0x2c3e01e0), SPH_C32(0x29794a78), + SPH_C32(0x53d28c3c), SPH_C32(0xd96605be) }, + { SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), SPH_C32(0x2714ca3c), + SPH_C32(0x88210c30), SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), + SPH_C32(0x8589d8ab), SPH_C32(0xe6c46464) }, + { SPH_C32(0x989a0100), SPH_C32(0xd6ca5b1c), SPH_C32(0x5ebdc7c5), + SPH_C32(0xebc82d48), SPH_C32(0x496e0120), SPH_C32(0xc242193c), + SPH_C32(0x05ee9956), SPH_C32(0x6782e5dc) }, + { SPH_C32(0x89260140), SPH_C32(0x242b7a70), SPH_C32(0x1171a194), + SPH_C32(0xab423635), SPH_C32(0xcf0f0100), SPH_C32(0x2ad26bec), + SPH_C32(0xd8d5785c), SPH_C32(0x94b3e0af) }, + { SPH_C32(0xd5540140), SPH_C32(0xed91b762), SPH_C32(0x68d8ac6d), + SPH_C32(0xc8ab174d), SPH_C32(0x31c50120), SPH_C32(0x628f4308), + SPH_C32(0x58b239a1), SPH_C32(0x15f56117) }, + { SPH_C32(0xbc430100), SPH_C32(0xbfbdcc3a), SPH_C32(0x7a486acb), + SPH_C32(0xfa5688fb), SPH_C32(0x82c10140), SPH_C32(0x11898792), + SPH_C32(0xeeb013f4), SPH_C32(0xb7d0daaa) }, + { SPH_C32(0xe0310100), SPH_C32(0x76070128), SPH_C32(0x03e16732), + SPH_C32(0x99bfa983), SPH_C32(0x7c0b0160), SPH_C32(0x59d4af76), + SPH_C32(0x6ed75209), SPH_C32(0x36965b12) }, + { SPH_C32(0xf18d0140), SPH_C32(0x84e62044), SPH_C32(0x4c2d0163), + SPH_C32(0xd935b2fe), SPH_C32(0xfa6a0140), SPH_C32(0xb144dda6), + SPH_C32(0xb3ecb303), SPH_C32(0xc5a75e61) }, + { SPH_C32(0xadff0140), SPH_C32(0x4d5ced56), SPH_C32(0x35840c9a), + SPH_C32(0xbadc9386), SPH_C32(0x04a00160), SPH_C32(0xf919f542), + SPH_C32(0x338bf2fe), SPH_C32(0x44e1dfd9) }, + { SPH_C32(0x9f3a0180), SPH_C32(0x5a7f8ee2), SPH_C32(0xe5d0a669), + SPH_C32(0x7b43be03), SPH_C32(0x8e020100), SPH_C32(0xc0a86233), + SPH_C32(0x54c7d1e0), SPH_C32(0x51b6d04f) }, + { SPH_C32(0xc3480180), SPH_C32(0x93c543f0), SPH_C32(0x9c79ab90), + SPH_C32(0x18aa9f7b), SPH_C32(0x70c80120), SPH_C32(0x88f54ad7), + SPH_C32(0xd4a0901d), SPH_C32(0xd0f051f7) }, + { SPH_C32(0xd2f401c0), SPH_C32(0x6124629c), SPH_C32(0xd3b5cdc1), + SPH_C32(0x58208406), SPH_C32(0xf6a90100), SPH_C32(0x60653807), + SPH_C32(0x099b7117), SPH_C32(0x23c15484) }, + { SPH_C32(0x8e8601c0), SPH_C32(0xa89eaf8e), SPH_C32(0xaa1cc038), + SPH_C32(0x3bc9a57e), SPH_C32(0x08630120), SPH_C32(0x283810e3), + SPH_C32(0x89fc30ea), SPH_C32(0xa287d53c) }, + { SPH_C32(0xe7910180), SPH_C32(0xfab2d4d6), SPH_C32(0xb88c069e), + SPH_C32(0x09343ac8), SPH_C32(0xbb670140), SPH_C32(0x5b3ed479), + SPH_C32(0x3ffe1abf), SPH_C32(0x00a26e81) }, + { SPH_C32(0xbbe30180), SPH_C32(0x330819c4), SPH_C32(0xc1250b67), + SPH_C32(0x6add1bb0), SPH_C32(0x45ad0160), SPH_C32(0x1363fc9d), + SPH_C32(0xbf995b42), SPH_C32(0x81e4ef39) }, + { SPH_C32(0xaa5f01c0), SPH_C32(0xc1e938a8), SPH_C32(0x8ee96d36), + SPH_C32(0x2a5700cd), SPH_C32(0xc3cc0140), SPH_C32(0xfbf38e4d), + SPH_C32(0x62a2ba48), SPH_C32(0x72d5ea4a) }, + { SPH_C32(0xf62d01c0), SPH_C32(0x0853f5ba), SPH_C32(0xf74060cf), + SPH_C32(0x49be21b5), SPH_C32(0x3d060160), SPH_C32(0xb3aea6a9), + SPH_C32(0xe2c5fbb5), SPH_C32(0xf3936bf2) }, + { SPH_C32(0xfd4e0100), SPH_C32(0x55c7c5e5), SPH_C32(0xf65ac377), + SPH_C32(0x3f53b81b), SPH_C32(0xd5d00180), SPH_C32(0x85a77adf), + SPH_C32(0x9603bdb5), SPH_C32(0xa2d4627c) }, + { SPH_C32(0xa13c0100), SPH_C32(0x9c7d08f7), SPH_C32(0x8ff3ce8e), + SPH_C32(0x5cba9963), SPH_C32(0x2b1a01a0), SPH_C32(0xcdfa523b), + SPH_C32(0x1664fc48), SPH_C32(0x2392e3c4) }, + { SPH_C32(0xb0800140), SPH_C32(0x6e9c299b), SPH_C32(0xc03fa8df), + SPH_C32(0x1c30821e), SPH_C32(0xad7b0180), SPH_C32(0x256a20eb), + SPH_C32(0xcb5f1d42), SPH_C32(0xd0a3e6b7) }, + { SPH_C32(0xecf20140), SPH_C32(0xa726e489), SPH_C32(0xb996a526), + SPH_C32(0x7fd9a366), SPH_C32(0x53b101a0), SPH_C32(0x6d37080f), + SPH_C32(0x4b385cbf), SPH_C32(0x51e5670f) }, + { SPH_C32(0x85e50100), SPH_C32(0xf50a9fd1), SPH_C32(0xab066380), + SPH_C32(0x4d243cd0), SPH_C32(0xe0b501c0), SPH_C32(0x1e31cc95), + SPH_C32(0xfd3a76ea), SPH_C32(0xf3c0dcb2) }, + { SPH_C32(0xd9970100), SPH_C32(0x3cb052c3), SPH_C32(0xd2af6e79), + SPH_C32(0x2ecd1da8), SPH_C32(0x1e7f01e0), SPH_C32(0x566ce471), + SPH_C32(0x7d5d3717), SPH_C32(0x72865d0a) }, + { SPH_C32(0xc82b0140), SPH_C32(0xce5173af), SPH_C32(0x9d630828), + SPH_C32(0x6e4706d5), SPH_C32(0x981e01c0), SPH_C32(0xbefc96a1), + SPH_C32(0xa066d61d), SPH_C32(0x81b75879) }, + { SPH_C32(0x94590140), SPH_C32(0x07ebbebd), SPH_C32(0xe4ca05d1), + SPH_C32(0x0dae27ad), SPH_C32(0x66d401e0), SPH_C32(0xf6a1be45), + SPH_C32(0x200197e0), SPH_C32(0x00f1d9c1) }, + { SPH_C32(0xa69c0180), SPH_C32(0x10c8dd09), SPH_C32(0x349eaf22), + SPH_C32(0xcc310a28), SPH_C32(0xec760180), SPH_C32(0xcf102934), + SPH_C32(0x474db4fe), SPH_C32(0x15a6d657) }, + { SPH_C32(0xfaee0180), SPH_C32(0xd972101b), SPH_C32(0x4d37a2db), + SPH_C32(0xafd82b50), SPH_C32(0x12bc01a0), SPH_C32(0x874d01d0), + SPH_C32(0xc72af503), SPH_C32(0x94e057ef) }, + { SPH_C32(0xeb5201c0), SPH_C32(0x2b933177), SPH_C32(0x02fbc48a), + SPH_C32(0xef52302d), SPH_C32(0x94dd0180), SPH_C32(0x6fdd7300), + SPH_C32(0x1a111409), SPH_C32(0x67d1529c) }, + { SPH_C32(0xb72001c0), SPH_C32(0xe229fc65), SPH_C32(0x7b52c973), + SPH_C32(0x8cbb1155), SPH_C32(0x6a1701a0), SPH_C32(0x27805be4), + SPH_C32(0x9a7655f4), SPH_C32(0xe697d324) }, + { SPH_C32(0xde370180), SPH_C32(0xb005873d), SPH_C32(0x69c20fd5), + SPH_C32(0xbe468ee3), SPH_C32(0xd91301c0), SPH_C32(0x54869f7e), + SPH_C32(0x2c747fa1), SPH_C32(0x44b26899) }, + { SPH_C32(0x82450180), SPH_C32(0x79bf4a2f), SPH_C32(0x106b022c), + SPH_C32(0xddafaf9b), SPH_C32(0x27d901e0), SPH_C32(0x1cdbb79a), + SPH_C32(0xac133e5c), SPH_C32(0xc5f4e921) }, + { SPH_C32(0x93f901c0), SPH_C32(0x8b5e6b43), SPH_C32(0x5fa7647d), + SPH_C32(0x9d25b4e6), SPH_C32(0xa1b801c0), SPH_C32(0xf44bc54a), + SPH_C32(0x7128df56), SPH_C32(0x36c5ec52) }, + { SPH_C32(0xcf8b01c0), SPH_C32(0x42e4a651), SPH_C32(0x260e6984), + SPH_C32(0xfecc959e), SPH_C32(0x5f7201e0), SPH_C32(0xbc16edae), + SPH_C32(0xf14f9eab), SPH_C32(0xb7836dea) } +}; + +static const sph_u32 T256_21[128][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xd0080004), SPH_C32(0x8c768f77), SPH_C32(0x9dc5b050), + SPH_C32(0xaf4a29da), SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), + SPH_C32(0x98321c3d), SPH_C32(0x76acc733) }, + { SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), SPH_C32(0x98321c3d), + SPH_C32(0x76acc733), SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), + SPH_C32(0x05f7ac6d), SPH_C32(0xd9e6eee9) }, + { SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), SPH_C32(0x05f7ac6d), + SPH_C32(0xd9e6eee9), SPH_C32(0xd0080004), SPH_C32(0x8c768f77), + SPH_C32(0x9dc5b050), SPH_C32(0xaf4a29da) }, + { SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), SPH_C32(0xfe739301), + SPH_C32(0xb8a92831), SPH_C32(0x171c0000), SPH_C32(0xb26e3344), + SPH_C32(0x9e6a837e), SPH_C32(0x58f8485f) }, + { SPH_C32(0x78a6000c), SPH_C32(0xac0fb60a), SPH_C32(0x63b62351), + SPH_C32(0x17e301eb), SPH_C32(0x7cb50000), SPH_C32(0xf285caee), + SPH_C32(0x06589f43), SPH_C32(0x2e548f6c) }, + { SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), SPH_C32(0x66418f3c), + SPH_C32(0xce05ef02), SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), + SPH_C32(0x9b9d2f13), SPH_C32(0x811ea6b6) }, + { SPH_C32(0x130f000c), SPH_C32(0xece44fa0), SPH_C32(0xfb843f6c), + SPH_C32(0x614fc6d8), SPH_C32(0xc7140004), SPH_C32(0x3e18bc33), + SPH_C32(0x03af332e), SPH_C32(0xf7b26185) }, + { SPH_C32(0x171c0000), SPH_C32(0xb26e3344), SPH_C32(0x9e6a837e), + SPH_C32(0x58f8485f), SPH_C32(0xbfb20008), SPH_C32(0x92170a39), + SPH_C32(0x6019107f), SPH_C32(0xe051606e) }, + { SPH_C32(0xc7140004), SPH_C32(0x3e18bc33), SPH_C32(0x03af332e), + SPH_C32(0xf7b26185), SPH_C32(0xd41b0008), SPH_C32(0xd2fcf393), + SPH_C32(0xf82b0c42), SPH_C32(0x96fda75d) }, + { SPH_C32(0x7cb50000), SPH_C32(0xf285caee), SPH_C32(0x06589f43), + SPH_C32(0x2e548f6c), SPH_C32(0x0413000c), SPH_C32(0x5e8a7ce4), + SPH_C32(0x65eebc12), SPH_C32(0x39b78e87) }, + { SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), SPH_C32(0x9b9d2f13), + SPH_C32(0x811ea6b6), SPH_C32(0x6fba000c), SPH_C32(0x1e61854e), + SPH_C32(0xfddca02f), SPH_C32(0x4f1b49b4) }, + { SPH_C32(0xbfb20008), SPH_C32(0x92170a39), SPH_C32(0x6019107f), + SPH_C32(0xe051606e), SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), + SPH_C32(0xfe739301), SPH_C32(0xb8a92831) }, + { SPH_C32(0x6fba000c), SPH_C32(0x1e61854e), SPH_C32(0xfddca02f), + SPH_C32(0x4f1b49b4), SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), + SPH_C32(0x66418f3c), SPH_C32(0xce05ef02) }, + { SPH_C32(0xd41b0008), SPH_C32(0xd2fcf393), SPH_C32(0xf82b0c42), + SPH_C32(0x96fda75d), SPH_C32(0x130f000c), SPH_C32(0xece44fa0), + SPH_C32(0xfb843f6c), SPH_C32(0x614fc6d8) }, + { SPH_C32(0x0413000c), SPH_C32(0x5e8a7ce4), SPH_C32(0x65eebc12), + SPH_C32(0x39b78e87), SPH_C32(0x78a6000c), SPH_C32(0xac0fb60a), + SPH_C32(0x63b62351), SPH_C32(0x17e301eb) }, + { SPH_C32(0x515c0010), SPH_C32(0x40f372fb), SPH_C32(0xfce72602), + SPH_C32(0x71575061), SPH_C32(0x2e390000), SPH_C32(0x64dd6689), + SPH_C32(0x3cd406fc), SPH_C32(0xb1f490bc) }, + { SPH_C32(0x81540014), SPH_C32(0xcc85fd8c), SPH_C32(0x61229652), + SPH_C32(0xde1d79bb), SPH_C32(0x45900000), SPH_C32(0x24369f23), + SPH_C32(0xa4e61ac1), SPH_C32(0xc758578f) }, + { SPH_C32(0x3af50010), SPH_C32(0x00188b51), SPH_C32(0x64d53a3f), + SPH_C32(0x07fb9752), SPH_C32(0x95980004), SPH_C32(0xa8401054), + SPH_C32(0x3923aa91), SPH_C32(0x68127e55) }, + { SPH_C32(0xeafd0014), SPH_C32(0x8c6e0426), SPH_C32(0xf9108a6f), + SPH_C32(0xa8b1be88), SPH_C32(0xfe310004), SPH_C32(0xe8abe9fe), + SPH_C32(0xa111b6ac), SPH_C32(0x1ebeb966) }, + { SPH_C32(0xf9f20018), SPH_C32(0x608a4b86), SPH_C32(0x0294b503), + SPH_C32(0xc9fe7850), SPH_C32(0x39250000), SPH_C32(0xd6b355cd), + SPH_C32(0xa2be8582), SPH_C32(0xe90cd8e3) }, + { SPH_C32(0x29fa001c), SPH_C32(0xecfcc4f1), SPH_C32(0x9f510553), + SPH_C32(0x66b4518a), SPH_C32(0x528c0000), SPH_C32(0x9658ac67), + SPH_C32(0x3a8c99bf), SPH_C32(0x9fa01fd0) }, + { SPH_C32(0x925b0018), SPH_C32(0x2061b22c), SPH_C32(0x9aa6a93e), + SPH_C32(0xbf52bf63), SPH_C32(0x82840004), SPH_C32(0x1a2e2310), + SPH_C32(0xa74929ef), SPH_C32(0x30ea360a) }, + { SPH_C32(0x4253001c), SPH_C32(0xac173d5b), SPH_C32(0x0763196e), + SPH_C32(0x101896b9), SPH_C32(0xe92d0004), SPH_C32(0x5ac5daba), + SPH_C32(0x3f7b35d2), SPH_C32(0x4646f139) }, + { SPH_C32(0x46400010), SPH_C32(0xf29d41bf), SPH_C32(0x628da57c), + SPH_C32(0x29af183e), SPH_C32(0x918b0008), SPH_C32(0xf6ca6cb0), + SPH_C32(0x5ccd1683), SPH_C32(0x51a5f0d2) }, + { SPH_C32(0x96480014), SPH_C32(0x7eebcec8), SPH_C32(0xff48152c), + SPH_C32(0x86e531e4), SPH_C32(0xfa220008), SPH_C32(0xb621951a), + SPH_C32(0xc4ff0abe), SPH_C32(0x270937e1) }, + { SPH_C32(0x2de90010), SPH_C32(0xb276b815), SPH_C32(0xfabfb941), + SPH_C32(0x5f03df0d), SPH_C32(0x2a2a000c), SPH_C32(0x3a571a6d), + SPH_C32(0x593abaee), SPH_C32(0x88431e3b) }, + { SPH_C32(0xfde10014), SPH_C32(0x3e003762), SPH_C32(0x677a0911), + SPH_C32(0xf049f6d7), SPH_C32(0x4183000c), SPH_C32(0x7abce3c7), + SPH_C32(0xc108a6d3), SPH_C32(0xfeefd908) }, + { SPH_C32(0xeeee0018), SPH_C32(0xd2e478c2), SPH_C32(0x9cfe367d), + SPH_C32(0x9106300f), SPH_C32(0x86970008), SPH_C32(0x44a45ff4), + SPH_C32(0xc2a795fd), SPH_C32(0x095db88d) }, + { SPH_C32(0x3ee6001c), SPH_C32(0x5e92f7b5), SPH_C32(0x013b862d), + SPH_C32(0x3e4c19d5), SPH_C32(0xed3e0008), SPH_C32(0x044fa65e), + SPH_C32(0x5a9589c0), SPH_C32(0x7ff17fbe) }, + { SPH_C32(0x85470018), SPH_C32(0x920f8168), SPH_C32(0x04cc2a40), + SPH_C32(0xe7aaf73c), SPH_C32(0x3d36000c), SPH_C32(0x88392929), + SPH_C32(0xc7503990), SPH_C32(0xd0bb5664) }, + { SPH_C32(0x554f001c), SPH_C32(0x1e790e1f), SPH_C32(0x99099a10), + SPH_C32(0x48e0dee6), SPH_C32(0x569f000c), SPH_C32(0xc8d2d083), + SPH_C32(0x5f6225ad), SPH_C32(0xa6179157) }, + { SPH_C32(0x2e390000), SPH_C32(0x64dd6689), SPH_C32(0x3cd406fc), + SPH_C32(0xb1f490bc), SPH_C32(0x7f650010), SPH_C32(0x242e1472), + SPH_C32(0xc03320fe), SPH_C32(0xc0a3c0dd) }, + { SPH_C32(0xfe310004), SPH_C32(0xe8abe9fe), SPH_C32(0xa111b6ac), + SPH_C32(0x1ebeb966), SPH_C32(0x14cc0010), SPH_C32(0x64c5edd8), + SPH_C32(0x58013cc3), SPH_C32(0xb60f07ee) }, + { SPH_C32(0x45900000), SPH_C32(0x24369f23), SPH_C32(0xa4e61ac1), + SPH_C32(0xc758578f), SPH_C32(0xc4c40014), SPH_C32(0xe8b362af), + SPH_C32(0xc5c48c93), SPH_C32(0x19452e34) }, + { SPH_C32(0x95980004), SPH_C32(0xa8401054), SPH_C32(0x3923aa91), + SPH_C32(0x68127e55), SPH_C32(0xaf6d0014), SPH_C32(0xa8589b05), + SPH_C32(0x5df690ae), SPH_C32(0x6fe9e907) }, + { SPH_C32(0x86970008), SPH_C32(0x44a45ff4), SPH_C32(0xc2a795fd), + SPH_C32(0x095db88d), SPH_C32(0x68790010), SPH_C32(0x96402736), + SPH_C32(0x5e59a380), SPH_C32(0x985b8882) }, + { SPH_C32(0x569f000c), SPH_C32(0xc8d2d083), SPH_C32(0x5f6225ad), + SPH_C32(0xa6179157), SPH_C32(0x03d00010), SPH_C32(0xd6abde9c), + SPH_C32(0xc66bbfbd), SPH_C32(0xeef74fb1) }, + { SPH_C32(0xed3e0008), SPH_C32(0x044fa65e), SPH_C32(0x5a9589c0), + SPH_C32(0x7ff17fbe), SPH_C32(0xd3d80014), SPH_C32(0x5add51eb), + SPH_C32(0x5bae0fed), SPH_C32(0x41bd666b) }, + { SPH_C32(0x3d36000c), SPH_C32(0x88392929), SPH_C32(0xc7503990), + SPH_C32(0xd0bb5664), SPH_C32(0xb8710014), SPH_C32(0x1a36a841), + SPH_C32(0xc39c13d0), SPH_C32(0x3711a158) }, + { SPH_C32(0x39250000), SPH_C32(0xd6b355cd), SPH_C32(0xa2be8582), + SPH_C32(0xe90cd8e3), SPH_C32(0xc0d70018), SPH_C32(0xb6391e4b), + SPH_C32(0xa02a3081), SPH_C32(0x20f2a0b3) }, + { SPH_C32(0xe92d0004), SPH_C32(0x5ac5daba), SPH_C32(0x3f7b35d2), + SPH_C32(0x4646f139), SPH_C32(0xab7e0018), SPH_C32(0xf6d2e7e1), + SPH_C32(0x38182cbc), SPH_C32(0x565e6780) }, + { SPH_C32(0x528c0000), SPH_C32(0x9658ac67), SPH_C32(0x3a8c99bf), + SPH_C32(0x9fa01fd0), SPH_C32(0x7b76001c), SPH_C32(0x7aa46896), + SPH_C32(0xa5dd9cec), SPH_C32(0xf9144e5a) }, + { SPH_C32(0x82840004), SPH_C32(0x1a2e2310), SPH_C32(0xa74929ef), + SPH_C32(0x30ea360a), SPH_C32(0x10df001c), SPH_C32(0x3a4f913c), + SPH_C32(0x3def80d1), SPH_C32(0x8fb88969) }, + { SPH_C32(0x918b0008), SPH_C32(0xf6ca6cb0), SPH_C32(0x5ccd1683), + SPH_C32(0x51a5f0d2), SPH_C32(0xd7cb0018), SPH_C32(0x04572d0f), + SPH_C32(0x3e40b3ff), SPH_C32(0x780ae8ec) }, + { SPH_C32(0x4183000c), SPH_C32(0x7abce3c7), SPH_C32(0xc108a6d3), + SPH_C32(0xfeefd908), SPH_C32(0xbc620018), SPH_C32(0x44bcd4a5), + SPH_C32(0xa672afc2), SPH_C32(0x0ea62fdf) }, + { SPH_C32(0xfa220008), SPH_C32(0xb621951a), SPH_C32(0xc4ff0abe), + SPH_C32(0x270937e1), SPH_C32(0x6c6a001c), SPH_C32(0xc8ca5bd2), + SPH_C32(0x3bb71f92), SPH_C32(0xa1ec0605) }, + { SPH_C32(0x2a2a000c), SPH_C32(0x3a571a6d), SPH_C32(0x593abaee), + SPH_C32(0x88431e3b), SPH_C32(0x07c3001c), SPH_C32(0x8821a278), + SPH_C32(0xa38503af), SPH_C32(0xd740c136) }, + { SPH_C32(0x7f650010), SPH_C32(0x242e1472), SPH_C32(0xc03320fe), + SPH_C32(0xc0a3c0dd), SPH_C32(0x515c0010), SPH_C32(0x40f372fb), + SPH_C32(0xfce72602), SPH_C32(0x71575061) }, + { SPH_C32(0xaf6d0014), SPH_C32(0xa8589b05), SPH_C32(0x5df690ae), + SPH_C32(0x6fe9e907), SPH_C32(0x3af50010), SPH_C32(0x00188b51), + SPH_C32(0x64d53a3f), SPH_C32(0x07fb9752) }, + { SPH_C32(0x14cc0010), SPH_C32(0x64c5edd8), SPH_C32(0x58013cc3), + SPH_C32(0xb60f07ee), SPH_C32(0xeafd0014), SPH_C32(0x8c6e0426), + SPH_C32(0xf9108a6f), SPH_C32(0xa8b1be88) }, + { SPH_C32(0xc4c40014), SPH_C32(0xe8b362af), SPH_C32(0xc5c48c93), + SPH_C32(0x19452e34), SPH_C32(0x81540014), SPH_C32(0xcc85fd8c), + SPH_C32(0x61229652), SPH_C32(0xde1d79bb) }, + { SPH_C32(0xd7cb0018), SPH_C32(0x04572d0f), SPH_C32(0x3e40b3ff), + SPH_C32(0x780ae8ec), SPH_C32(0x46400010), SPH_C32(0xf29d41bf), + SPH_C32(0x628da57c), SPH_C32(0x29af183e) }, + { SPH_C32(0x07c3001c), SPH_C32(0x8821a278), SPH_C32(0xa38503af), + SPH_C32(0xd740c136), SPH_C32(0x2de90010), SPH_C32(0xb276b815), + SPH_C32(0xfabfb941), SPH_C32(0x5f03df0d) }, + { SPH_C32(0xbc620018), SPH_C32(0x44bcd4a5), SPH_C32(0xa672afc2), + SPH_C32(0x0ea62fdf), SPH_C32(0xfde10014), SPH_C32(0x3e003762), + SPH_C32(0x677a0911), SPH_C32(0xf049f6d7) }, + { SPH_C32(0x6c6a001c), SPH_C32(0xc8ca5bd2), SPH_C32(0x3bb71f92), + SPH_C32(0xa1ec0605), SPH_C32(0x96480014), SPH_C32(0x7eebcec8), + SPH_C32(0xff48152c), SPH_C32(0x86e531e4) }, + { SPH_C32(0x68790010), SPH_C32(0x96402736), SPH_C32(0x5e59a380), + SPH_C32(0x985b8882), SPH_C32(0xeeee0018), SPH_C32(0xd2e478c2), + SPH_C32(0x9cfe367d), SPH_C32(0x9106300f) }, + { SPH_C32(0xb8710014), SPH_C32(0x1a36a841), SPH_C32(0xc39c13d0), + SPH_C32(0x3711a158), SPH_C32(0x85470018), SPH_C32(0x920f8168), + SPH_C32(0x04cc2a40), SPH_C32(0xe7aaf73c) }, + { SPH_C32(0x03d00010), SPH_C32(0xd6abde9c), SPH_C32(0xc66bbfbd), + SPH_C32(0xeef74fb1), SPH_C32(0x554f001c), SPH_C32(0x1e790e1f), + SPH_C32(0x99099a10), SPH_C32(0x48e0dee6) }, + { SPH_C32(0xd3d80014), SPH_C32(0x5add51eb), SPH_C32(0x5bae0fed), + SPH_C32(0x41bd666b), SPH_C32(0x3ee6001c), SPH_C32(0x5e92f7b5), + SPH_C32(0x013b862d), SPH_C32(0x3e4c19d5) }, + { SPH_C32(0xc0d70018), SPH_C32(0xb6391e4b), SPH_C32(0xa02a3081), + SPH_C32(0x20f2a0b3), SPH_C32(0xf9f20018), SPH_C32(0x608a4b86), + SPH_C32(0x0294b503), SPH_C32(0xc9fe7850) }, + { SPH_C32(0x10df001c), SPH_C32(0x3a4f913c), SPH_C32(0x3def80d1), + SPH_C32(0x8fb88969), SPH_C32(0x925b0018), SPH_C32(0x2061b22c), + SPH_C32(0x9aa6a93e), SPH_C32(0xbf52bf63) }, + { SPH_C32(0xab7e0018), SPH_C32(0xf6d2e7e1), SPH_C32(0x38182cbc), + SPH_C32(0x565e6780), SPH_C32(0x4253001c), SPH_C32(0xac173d5b), + SPH_C32(0x0763196e), SPH_C32(0x101896b9) }, + { SPH_C32(0x7b76001c), SPH_C32(0x7aa46896), SPH_C32(0xa5dd9cec), + SPH_C32(0xf9144e5a), SPH_C32(0x29fa001c), SPH_C32(0xecfcc4f1), + SPH_C32(0x9f510553), SPH_C32(0x66b4518a) }, + { SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), SPH_C32(0xf9ce4c04), + SPH_C32(0xe2afa0c0), SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), + SPH_C32(0x79a90df9), SPH_C32(0x63e92178) }, + { SPH_C32(0x72b00024), SPH_C32(0x0d916a81), SPH_C32(0x640bfc54), + SPH_C32(0x4de5891a), SPH_C32(0x37db0000), SPH_C32(0x895134b8), + SPH_C32(0xe19b11c4), SPH_C32(0x1545e64b) }, + { SPH_C32(0xc9110020), SPH_C32(0xc10c1c5c), SPH_C32(0x61fc5039), + SPH_C32(0x940367f3), SPH_C32(0xe7d30004), SPH_C32(0x0527bbcf), + SPH_C32(0x7c5ea194), SPH_C32(0xba0fcf91) }, + { SPH_C32(0x19190024), SPH_C32(0x4d7a932b), SPH_C32(0xfc39e069), + SPH_C32(0x3b494e29), SPH_C32(0x8c7a0004), SPH_C32(0x45cc4265), + SPH_C32(0xe46cbda9), SPH_C32(0xcca308a2) }, + { SPH_C32(0x0a160028), SPH_C32(0xa19edc8b), SPH_C32(0x07bddf05), + SPH_C32(0x5a0688f1), SPH_C32(0x4b6e0000), SPH_C32(0x7bd4fe56), + SPH_C32(0xe7c38e87), SPH_C32(0x3b116927) }, + { SPH_C32(0xda1e002c), SPH_C32(0x2de853fc), SPH_C32(0x9a786f55), + SPH_C32(0xf54ca12b), SPH_C32(0x20c70000), SPH_C32(0x3b3f07fc), + SPH_C32(0x7ff192ba), SPH_C32(0x4dbdae14) }, + { SPH_C32(0x61bf0028), SPH_C32(0xe1752521), SPH_C32(0x9f8fc338), + SPH_C32(0x2caa4fc2), SPH_C32(0xf0cf0004), SPH_C32(0xb749888b), + SPH_C32(0xe23422ea), SPH_C32(0xe2f787ce) }, + { SPH_C32(0xb1b7002c), SPH_C32(0x6d03aa56), SPH_C32(0x024a7368), + SPH_C32(0x83e06618), SPH_C32(0x9b660004), SPH_C32(0xf7a27121), + SPH_C32(0x7a063ed7), SPH_C32(0x945b40fd) }, + { SPH_C32(0xb5a40020), SPH_C32(0x3389d6b2), SPH_C32(0x67a4cf7a), + SPH_C32(0xba57e89f), SPH_C32(0xe3c00008), SPH_C32(0x5badc72b), + SPH_C32(0x19b01d86), SPH_C32(0x83b84116) }, + { SPH_C32(0x65ac0024), SPH_C32(0xbfff59c5), SPH_C32(0xfa617f2a), + SPH_C32(0x151dc145), SPH_C32(0x88690008), SPH_C32(0x1b463e81), + SPH_C32(0x818201bb), SPH_C32(0xf5148625) }, + { SPH_C32(0xde0d0020), SPH_C32(0x73622f18), SPH_C32(0xff96d347), + SPH_C32(0xccfb2fac), SPH_C32(0x5861000c), SPH_C32(0x9730b1f6), + SPH_C32(0x1c47b1eb), SPH_C32(0x5a5eafff) }, + { SPH_C32(0x0e050024), SPH_C32(0xff14a06f), SPH_C32(0x62536317), + SPH_C32(0x63b10676), SPH_C32(0x33c8000c), SPH_C32(0xd7db485c), + SPH_C32(0x8475add6), SPH_C32(0x2cf268cc) }, + { SPH_C32(0x1d0a0028), SPH_C32(0x13f0efcf), SPH_C32(0x99d75c7b), + SPH_C32(0x02fec0ae), SPH_C32(0xf4dc0008), SPH_C32(0xe9c3f46f), + SPH_C32(0x87da9ef8), SPH_C32(0xdb400949) }, + { SPH_C32(0xcd02002c), SPH_C32(0x9f8660b8), SPH_C32(0x0412ec2b), + SPH_C32(0xadb4e974), SPH_C32(0x9f750008), SPH_C32(0xa9280dc5), + SPH_C32(0x1fe882c5), SPH_C32(0xadecce7a) }, + { SPH_C32(0x76a30028), SPH_C32(0x531b1665), SPH_C32(0x01e54046), + SPH_C32(0x7452079d), SPH_C32(0x4f7d000c), SPH_C32(0x255e82b2), + SPH_C32(0x822d3295), SPH_C32(0x02a6e7a0) }, + { SPH_C32(0xa6ab002c), SPH_C32(0xdf6d9912), SPH_C32(0x9c20f016), + SPH_C32(0xdb182e47), SPH_C32(0x24d4000c), SPH_C32(0x65b57b18), + SPH_C32(0x1a1f2ea8), SPH_C32(0x740a2093) }, + { SPH_C32(0xf3e40030), SPH_C32(0xc114970d), SPH_C32(0x05296a06), + SPH_C32(0x93f8f0a1), SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), + SPH_C32(0x457d0b05), SPH_C32(0xd21db1c4) }, + { SPH_C32(0x23ec0034), SPH_C32(0x4d62187a), SPH_C32(0x98ecda56), + SPH_C32(0x3cb2d97b), SPH_C32(0x19e20000), SPH_C32(0xed8c5231), + SPH_C32(0xdd4f1738), SPH_C32(0xa4b176f7) }, + { SPH_C32(0x984d0030), SPH_C32(0x81ff6ea7), SPH_C32(0x9d1b763b), + SPH_C32(0xe5543792), SPH_C32(0xc9ea0004), SPH_C32(0x61fadd46), + SPH_C32(0x408aa768), SPH_C32(0x0bfb5f2d) }, + { SPH_C32(0x48450034), SPH_C32(0x0d89e1d0), SPH_C32(0x00dec66b), + SPH_C32(0x4a1e1e48), SPH_C32(0xa2430004), SPH_C32(0x211124ec), + SPH_C32(0xd8b8bb55), SPH_C32(0x7d57981e) }, + { SPH_C32(0x5b4a0038), SPH_C32(0xe16dae70), SPH_C32(0xfb5af907), + SPH_C32(0x2b51d890), SPH_C32(0x65570000), SPH_C32(0x1f0998df), + SPH_C32(0xdb17887b), SPH_C32(0x8ae5f99b) }, + { SPH_C32(0x8b42003c), SPH_C32(0x6d1b2107), SPH_C32(0x669f4957), + SPH_C32(0x841bf14a), SPH_C32(0x0efe0000), SPH_C32(0x5fe26175), + SPH_C32(0x43259446), SPH_C32(0xfc493ea8) }, + { SPH_C32(0x30e30038), SPH_C32(0xa18657da), SPH_C32(0x6368e53a), + SPH_C32(0x5dfd1fa3), SPH_C32(0xdef60004), SPH_C32(0xd394ee02), + SPH_C32(0xdee02416), SPH_C32(0x53031772) }, + { SPH_C32(0xe0eb003c), SPH_C32(0x2df0d8ad), SPH_C32(0xfead556a), + SPH_C32(0xf2b73679), SPH_C32(0xb55f0004), SPH_C32(0x937f17a8), + SPH_C32(0x46d2382b), SPH_C32(0x25afd041) }, + { SPH_C32(0xe4f80030), SPH_C32(0x737aa449), SPH_C32(0x9b43e978), + SPH_C32(0xcb00b8fe), SPH_C32(0xcdf90008), SPH_C32(0x3f70a1a2), + SPH_C32(0x25641b7a), SPH_C32(0x324cd1aa) }, + { SPH_C32(0x34f00034), SPH_C32(0xff0c2b3e), SPH_C32(0x06865928), + SPH_C32(0x644a9124), SPH_C32(0xa6500008), SPH_C32(0x7f9b5808), + SPH_C32(0xbd560747), SPH_C32(0x44e01699) }, + { SPH_C32(0x8f510030), SPH_C32(0x33915de3), SPH_C32(0x0371f545), + SPH_C32(0xbdac7fcd), SPH_C32(0x7658000c), SPH_C32(0xf3edd77f), + SPH_C32(0x2093b717), SPH_C32(0xebaa3f43) }, + { SPH_C32(0x5f590034), SPH_C32(0xbfe7d294), SPH_C32(0x9eb44515), + SPH_C32(0x12e65617), SPH_C32(0x1df1000c), SPH_C32(0xb3062ed5), + SPH_C32(0xb8a1ab2a), SPH_C32(0x9d06f870) }, + { SPH_C32(0x4c560038), SPH_C32(0x53039d34), SPH_C32(0x65307a79), + SPH_C32(0x73a990cf), SPH_C32(0xdae50008), SPH_C32(0x8d1e92e6), + SPH_C32(0xbb0e9804), SPH_C32(0x6ab499f5) }, + { SPH_C32(0x9c5e003c), SPH_C32(0xdf751243), SPH_C32(0xf8f5ca29), + SPH_C32(0xdce3b915), SPH_C32(0xb14c0008), SPH_C32(0xcdf56b4c), + SPH_C32(0x233c8439), SPH_C32(0x1c185ec6) }, + { SPH_C32(0x27ff0038), SPH_C32(0x13e8649e), SPH_C32(0xfd026644), + SPH_C32(0x050557fc), SPH_C32(0x6144000c), SPH_C32(0x4183e43b), + SPH_C32(0xbef93469), SPH_C32(0xb352771c) }, + { SPH_C32(0xf7f7003c), SPH_C32(0x9f9eebe9), SPH_C32(0x60c7d614), + SPH_C32(0xaa4f7e26), SPH_C32(0x0aed000c), SPH_C32(0x01681d91), + SPH_C32(0x26cb2854), SPH_C32(0xc5feb02f) }, + { SPH_C32(0x8c810020), SPH_C32(0xe53a837f), SPH_C32(0xc51a4af8), + SPH_C32(0x535b307c), SPH_C32(0x23170010), SPH_C32(0xed94d960), + SPH_C32(0xb99a2d07), SPH_C32(0xa34ae1a5) }, + { SPH_C32(0x5c890024), SPH_C32(0x694c0c08), SPH_C32(0x58dffaa8), + SPH_C32(0xfc1119a6), SPH_C32(0x48be0010), SPH_C32(0xad7f20ca), + SPH_C32(0x21a8313a), SPH_C32(0xd5e62696) }, + { SPH_C32(0xe7280020), SPH_C32(0xa5d17ad5), SPH_C32(0x5d2856c5), + SPH_C32(0x25f7f74f), SPH_C32(0x98b60014), SPH_C32(0x2109afbd), + SPH_C32(0xbc6d816a), SPH_C32(0x7aac0f4c) }, + { SPH_C32(0x37200024), SPH_C32(0x29a7f5a2), SPH_C32(0xc0ede695), + SPH_C32(0x8abdde95), SPH_C32(0xf31f0014), SPH_C32(0x61e25617), + SPH_C32(0x245f9d57), SPH_C32(0x0c00c87f) }, + { SPH_C32(0x242f0028), SPH_C32(0xc543ba02), SPH_C32(0x3b69d9f9), + SPH_C32(0xebf2184d), SPH_C32(0x340b0010), SPH_C32(0x5ffaea24), + SPH_C32(0x27f0ae79), SPH_C32(0xfbb2a9fa) }, + { SPH_C32(0xf427002c), SPH_C32(0x49353575), SPH_C32(0xa6ac69a9), + SPH_C32(0x44b83197), SPH_C32(0x5fa20010), SPH_C32(0x1f11138e), + SPH_C32(0xbfc2b244), SPH_C32(0x8d1e6ec9) }, + { SPH_C32(0x4f860028), SPH_C32(0x85a843a8), SPH_C32(0xa35bc5c4), + SPH_C32(0x9d5edf7e), SPH_C32(0x8faa0014), SPH_C32(0x93679cf9), + SPH_C32(0x22070214), SPH_C32(0x22544713) }, + { SPH_C32(0x9f8e002c), SPH_C32(0x09deccdf), SPH_C32(0x3e9e7594), + SPH_C32(0x3214f6a4), SPH_C32(0xe4030014), SPH_C32(0xd38c6553), + SPH_C32(0xba351e29), SPH_C32(0x54f88020) }, + { SPH_C32(0x9b9d0020), SPH_C32(0x5754b03b), SPH_C32(0x5b70c986), + SPH_C32(0x0ba37823), SPH_C32(0x9ca50018), SPH_C32(0x7f83d359), + SPH_C32(0xd9833d78), SPH_C32(0x431b81cb) }, + { SPH_C32(0x4b950024), SPH_C32(0xdb223f4c), SPH_C32(0xc6b579d6), + SPH_C32(0xa4e951f9), SPH_C32(0xf70c0018), SPH_C32(0x3f682af3), + SPH_C32(0x41b12145), SPH_C32(0x35b746f8) }, + { SPH_C32(0xf0340020), SPH_C32(0x17bf4991), SPH_C32(0xc342d5bb), + SPH_C32(0x7d0fbf10), SPH_C32(0x2704001c), SPH_C32(0xb31ea584), + SPH_C32(0xdc749115), SPH_C32(0x9afd6f22) }, + { SPH_C32(0x203c0024), SPH_C32(0x9bc9c6e6), SPH_C32(0x5e8765eb), + SPH_C32(0xd24596ca), SPH_C32(0x4cad001c), SPH_C32(0xf3f55c2e), + SPH_C32(0x44468d28), SPH_C32(0xec51a811) }, + { SPH_C32(0x33330028), SPH_C32(0x772d8946), SPH_C32(0xa5035a87), + SPH_C32(0xb30a5012), SPH_C32(0x8bb90018), SPH_C32(0xcdede01d), + SPH_C32(0x47e9be06), SPH_C32(0x1be3c994) }, + { SPH_C32(0xe33b002c), SPH_C32(0xfb5b0631), SPH_C32(0x38c6ead7), + SPH_C32(0x1c4079c8), SPH_C32(0xe0100018), SPH_C32(0x8d0619b7), + SPH_C32(0xdfdba23b), SPH_C32(0x6d4f0ea7) }, + { SPH_C32(0x589a0028), SPH_C32(0x37c670ec), SPH_C32(0x3d3146ba), + SPH_C32(0xc5a69721), SPH_C32(0x3018001c), SPH_C32(0x017096c0), + SPH_C32(0x421e126b), SPH_C32(0xc205277d) }, + { SPH_C32(0x8892002c), SPH_C32(0xbbb0ff9b), SPH_C32(0xa0f4f6ea), + SPH_C32(0x6aecbefb), SPH_C32(0x5bb1001c), SPH_C32(0x419b6f6a), + SPH_C32(0xda2c0e56), SPH_C32(0xb4a9e04e) }, + { SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), SPH_C32(0x39fd6cfa), + SPH_C32(0x220c601d), SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), + SPH_C32(0x854e2bfb), SPH_C32(0x12be7119) }, + { SPH_C32(0x0dd50034), SPH_C32(0x29bf7ef3), SPH_C32(0xa438dcaa), + SPH_C32(0x8d4649c7), SPH_C32(0x66870010), SPH_C32(0xc9a24643), + SPH_C32(0x1d7c37c6), SPH_C32(0x6412b62a) }, + { SPH_C32(0xb6740030), SPH_C32(0xe522082e), SPH_C32(0xa1cf70c7), + SPH_C32(0x54a0a72e), SPH_C32(0xb68f0014), SPH_C32(0x45d4c934), + SPH_C32(0x80b98796), SPH_C32(0xcb589ff0) }, + { SPH_C32(0x667c0034), SPH_C32(0x69548759), SPH_C32(0x3c0ac097), + SPH_C32(0xfbea8ef4), SPH_C32(0xdd260014), SPH_C32(0x053f309e), + SPH_C32(0x188b9bab), SPH_C32(0xbdf458c3) }, + { SPH_C32(0x75730038), SPH_C32(0x85b0c8f9), SPH_C32(0xc78efffb), + SPH_C32(0x9aa5482c), SPH_C32(0x1a320010), SPH_C32(0x3b278cad), + SPH_C32(0x1b24a885), SPH_C32(0x4a463946) }, + { SPH_C32(0xa57b003c), SPH_C32(0x09c6478e), SPH_C32(0x5a4b4fab), + SPH_C32(0x35ef61f6), SPH_C32(0x719b0010), SPH_C32(0x7bcc7507), + SPH_C32(0x8316b4b8), SPH_C32(0x3ceafe75) }, + { SPH_C32(0x1eda0038), SPH_C32(0xc55b3153), SPH_C32(0x5fbce3c6), + SPH_C32(0xec098f1f), SPH_C32(0xa1930014), SPH_C32(0xf7bafa70), + SPH_C32(0x1ed304e8), SPH_C32(0x93a0d7af) }, + { SPH_C32(0xced2003c), SPH_C32(0x492dbe24), SPH_C32(0xc2795396), + SPH_C32(0x4343a6c5), SPH_C32(0xca3a0014), SPH_C32(0xb75103da), + SPH_C32(0x86e118d5), SPH_C32(0xe50c109c) }, + { SPH_C32(0xcac10030), SPH_C32(0x17a7c2c0), SPH_C32(0xa797ef84), + SPH_C32(0x7af42842), SPH_C32(0xb29c0018), SPH_C32(0x1b5eb5d0), + SPH_C32(0xe5573b84), SPH_C32(0xf2ef1177) }, + { SPH_C32(0x1ac90034), SPH_C32(0x9bd14db7), SPH_C32(0x3a525fd4), + SPH_C32(0xd5be0198), SPH_C32(0xd9350018), SPH_C32(0x5bb54c7a), + SPH_C32(0x7d6527b9), SPH_C32(0x8443d644) }, + { SPH_C32(0xa1680030), SPH_C32(0x574c3b6a), SPH_C32(0x3fa5f3b9), + SPH_C32(0x0c58ef71), SPH_C32(0x093d001c), SPH_C32(0xd7c3c30d), + SPH_C32(0xe0a097e9), SPH_C32(0x2b09ff9e) }, + { SPH_C32(0x71600034), SPH_C32(0xdb3ab41d), SPH_C32(0xa26043e9), + SPH_C32(0xa312c6ab), SPH_C32(0x6294001c), SPH_C32(0x97283aa7), + SPH_C32(0x78928bd4), SPH_C32(0x5da538ad) }, + { SPH_C32(0x626f0038), SPH_C32(0x37defbbd), SPH_C32(0x59e47c85), + SPH_C32(0xc25d0073), SPH_C32(0xa5800018), SPH_C32(0xa9308694), + SPH_C32(0x7b3db8fa), SPH_C32(0xaa175928) }, + { SPH_C32(0xb267003c), SPH_C32(0xbba874ca), SPH_C32(0xc421ccd5), + SPH_C32(0x6d1729a9), SPH_C32(0xce290018), SPH_C32(0xe9db7f3e), + SPH_C32(0xe30fa4c7), SPH_C32(0xdcbb9e1b) }, + { SPH_C32(0x09c60038), SPH_C32(0x77350217), SPH_C32(0xc1d660b8), + SPH_C32(0xb4f1c740), SPH_C32(0x1e21001c), SPH_C32(0x65adf049), + SPH_C32(0x7eca1497), SPH_C32(0x73f1b7c1) }, + { SPH_C32(0xd9ce003c), SPH_C32(0xfb438d60), SPH_C32(0x5c13d0e8), + SPH_C32(0x1bbbee9a), SPH_C32(0x7588001c), SPH_C32(0x254609e3), + SPH_C32(0xe6f808aa), SPH_C32(0x055d70f2) } +}; + +static const sph_u32 T256_28[16][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), SPH_C32(0xae0ebb05), + SPH_C32(0xb5a4c63b), SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), + SPH_C32(0x6bf648a4), SPH_C32(0x539cbdbf) }, + { SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), SPH_C32(0x6bf648a4), + SPH_C32(0x539cbdbf), SPH_C32(0x08bf0001), SPH_C32(0x38942792), + SPH_C32(0xc5f8f3a1), SPH_C32(0xe6387b84) }, + { SPH_C32(0x08bf0001), SPH_C32(0x38942792), SPH_C32(0xc5f8f3a1), + SPH_C32(0xe6387b84), SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), + SPH_C32(0xae0ebb05), SPH_C32(0xb5a4c63b) }, + { SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), SPH_C32(0x99e585aa), + SPH_C32(0x8d75f7f1), SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), + SPH_C32(0x79e22a4c), SPH_C32(0x1298bd46) }, + { SPH_C32(0x486d0003), SPH_C32(0x6c5e67a3), SPH_C32(0x37eb3eaf), + SPH_C32(0x38d131ca), SPH_C32(0x995d0000), SPH_C32(0x2ecee896), + SPH_C32(0x121462e8), SPH_C32(0x410400f9) }, + { SPH_C32(0x40d20002), SPH_C32(0x54ca4031), SPH_C32(0xf213cd0e), + SPH_C32(0xdee94a4e), SPH_C32(0x59130001), SPH_C32(0x1d772886), + SPH_C32(0xbc1ad9ed), SPH_C32(0xf4a0c6c2) }, + { SPH_C32(0x809c0003), SPH_C32(0x67738021), SPH_C32(0x5c1d760b), + SPH_C32(0x6b4d8c75), SPH_C32(0x91e20001), SPH_C32(0x165acf04), + SPH_C32(0xd7ec9149), SPH_C32(0xa73c7b7d) }, + { SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), SPH_C32(0x79e22a4c), + SPH_C32(0x1298bd46), SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), + SPH_C32(0xe007afe6), SPH_C32(0x9fed4ab7) }, + { SPH_C32(0x91e20001), SPH_C32(0x165acf04), SPH_C32(0xd7ec9149), + SPH_C32(0xa73c7b7d), SPH_C32(0x117e0002), SPH_C32(0x71294f25), + SPH_C32(0x8bf1e742), SPH_C32(0xcc71f708) }, + { SPH_C32(0x995d0000), SPH_C32(0x2ecee896), SPH_C32(0x121462e8), + SPH_C32(0x410400f9), SPH_C32(0xd1300003), SPH_C32(0x42908f35), + SPH_C32(0x25ff5c47), SPH_C32(0x79d53133) }, + { SPH_C32(0x59130001), SPH_C32(0x1d772886), SPH_C32(0xbc1ad9ed), + SPH_C32(0xf4a0c6c2), SPH_C32(0x19c10003), SPH_C32(0x49bd68b7), + SPH_C32(0x4e0914e3), SPH_C32(0x2a498c8c) }, + { SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), SPH_C32(0xe007afe6), + SPH_C32(0x9fed4ab7), SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), + SPH_C32(0x99e585aa), SPH_C32(0x8d75f7f1) }, + { SPH_C32(0x19c10003), SPH_C32(0x49bd68b7), SPH_C32(0x4e0914e3), + SPH_C32(0x2a498c8c), SPH_C32(0x40d20002), SPH_C32(0x54ca4031), + SPH_C32(0xf213cd0e), SPH_C32(0xdee94a4e) }, + { SPH_C32(0x117e0002), SPH_C32(0x71294f25), SPH_C32(0x8bf1e742), + SPH_C32(0xcc71f708), SPH_C32(0x809c0003), SPH_C32(0x67738021), + SPH_C32(0x5c1d760b), SPH_C32(0x6b4d8c75) }, + { SPH_C32(0xd1300003), SPH_C32(0x42908f35), SPH_C32(0x25ff5c47), + SPH_C32(0x79d53133), SPH_C32(0x486d0003), SPH_C32(0x6c5e67a3), + SPH_C32(0x37eb3eaf), SPH_C32(0x38d131ca) } +}; + +#define INPUT_SMALL do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T256_0[acc >> 1][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + acc = (acc << 8) | buf[1]; \ + rp = &T256_7[(acc >> 2) & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = (acc << 8) | buf[2]; \ + rp = &T256_14[(acc >> 3) & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = (acc << 8) | buf[3]; \ + rp = &T256_21[(acc >> 4) & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + rp = &T256_28[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_SMALL == 8 + +static const sph_u32 T256_0[256][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x74951000), SPH_C32(0x5a2b467e), SPH_C32(0x88fd1d2b), + SPH_C32(0x1ee68292), SPH_C32(0xcba90000), SPH_C32(0x90273769), + SPH_C32(0xbbdcf407), SPH_C32(0xd0f4af61) }, + { SPH_C32(0xcba90000), SPH_C32(0x90273769), SPH_C32(0xbbdcf407), + SPH_C32(0xd0f4af61), SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), + SPH_C32(0x3321e92c), SPH_C32(0xce122df3) }, + { SPH_C32(0xbf3c1000), SPH_C32(0xca0c7117), SPH_C32(0x3321e92c), + SPH_C32(0xce122df3), SPH_C32(0x74951000), SPH_C32(0x5a2b467e), + SPH_C32(0x88fd1d2b), SPH_C32(0x1ee68292) }, + { SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), SPH_C32(0x11fa3a57), + SPH_C32(0x3dc90524), SPH_C32(0x97530000), SPH_C32(0x204f6ed3), + SPH_C32(0x77b9e80f), SPH_C32(0xa1ec5ec1) }, + { SPH_C32(0x9dbf3000), SPH_C32(0xee7cca82), SPH_C32(0x9907277c), + SPH_C32(0x232f87b6), SPH_C32(0x5cfa0000), SPH_C32(0xb06859ba), + SPH_C32(0xcc651c08), SPH_C32(0x7118f1a0) }, + { SPH_C32(0x22832000), SPH_C32(0x2470bb95), SPH_C32(0xaa26ce50), + SPH_C32(0xed3daa45), SPH_C32(0x286f1000), SPH_C32(0xea431fc4), + SPH_C32(0x44980123), SPH_C32(0x6ffe7332) }, + { SPH_C32(0x56163000), SPH_C32(0x7e5bfdeb), SPH_C32(0x22dbd37b), + SPH_C32(0xf3db28d7), SPH_C32(0xe3c61000), SPH_C32(0x7a6428ad), + SPH_C32(0xff44f524), SPH_C32(0xbf0adc53) }, + { SPH_C32(0x97530000), SPH_C32(0x204f6ed3), SPH_C32(0x77b9e80f), + SPH_C32(0xa1ec5ec1), SPH_C32(0x7e792000), SPH_C32(0x9418e22f), + SPH_C32(0x6643d258), SPH_C32(0x9c255be5) }, + { SPH_C32(0xe3c61000), SPH_C32(0x7a6428ad), SPH_C32(0xff44f524), + SPH_C32(0xbf0adc53), SPH_C32(0xb5d02000), SPH_C32(0x043fd546), + SPH_C32(0xdd9f265f), SPH_C32(0x4cd1f484) }, + { SPH_C32(0x5cfa0000), SPH_C32(0xb06859ba), SPH_C32(0xcc651c08), + SPH_C32(0x7118f1a0), SPH_C32(0xc1453000), SPH_C32(0x5e149338), + SPH_C32(0x55623b74), SPH_C32(0x52377616) }, + { SPH_C32(0x286f1000), SPH_C32(0xea431fc4), SPH_C32(0x44980123), + SPH_C32(0x6ffe7332), SPH_C32(0x0aec3000), SPH_C32(0xce33a451), + SPH_C32(0xeebecf73), SPH_C32(0x82c3d977) }, + { SPH_C32(0x7e792000), SPH_C32(0x9418e22f), SPH_C32(0x6643d258), + SPH_C32(0x9c255be5), SPH_C32(0xe92a2000), SPH_C32(0xb4578cfc), + SPH_C32(0x11fa3a57), SPH_C32(0x3dc90524) }, + { SPH_C32(0x0aec3000), SPH_C32(0xce33a451), SPH_C32(0xeebecf73), + SPH_C32(0x82c3d977), SPH_C32(0x22832000), SPH_C32(0x2470bb95), + SPH_C32(0xaa26ce50), SPH_C32(0xed3daa45) }, + { SPH_C32(0xb5d02000), SPH_C32(0x043fd546), SPH_C32(0xdd9f265f), + SPH_C32(0x4cd1f484), SPH_C32(0x56163000), SPH_C32(0x7e5bfdeb), + SPH_C32(0x22dbd37b), SPH_C32(0xf3db28d7) }, + { SPH_C32(0xc1453000), SPH_C32(0x5e149338), SPH_C32(0x55623b74), + SPH_C32(0x52377616), SPH_C32(0x9dbf3000), SPH_C32(0xee7cca82), + SPH_C32(0x9907277c), SPH_C32(0x232f87b6) }, + { SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), SPH_C32(0x8dfacfab), + SPH_C32(0xce36cc72), SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), + SPH_C32(0x848598ba), SPH_C32(0x1041003e) }, + { SPH_C32(0x668e5000), SPH_C32(0x013c9f96), SPH_C32(0x0507d280), + SPH_C32(0xd0d04ee0), SPH_C32(0x2dfe0000), SPH_C32(0xdb940d4c), + SPH_C32(0x3f596cbd), SPH_C32(0xc0b5af5f) }, + { SPH_C32(0xd9b24000), SPH_C32(0xcb30ee81), SPH_C32(0x36263bac), + SPH_C32(0x1ec26313), SPH_C32(0x596b1000), SPH_C32(0x81bf4b32), + SPH_C32(0xb7a47196), SPH_C32(0xde532dcd) }, + { SPH_C32(0xad275000), SPH_C32(0x911ba8ff), SPH_C32(0xbedb2687), + SPH_C32(0x0024e181), SPH_C32(0x92c21000), SPH_C32(0x11987c5b), + SPH_C32(0x0c788591), SPH_C32(0x0ea782ac) }, + { SPH_C32(0xfb316000), SPH_C32(0xef405514), SPH_C32(0x9c00f5fc), + SPH_C32(0xf3ffc956), SPH_C32(0x71040000), SPH_C32(0x6bfc54f6), + SPH_C32(0xf33c70b5), SPH_C32(0xb1ad5eff) }, + { SPH_C32(0x8fa47000), SPH_C32(0xb56b136a), SPH_C32(0x14fde8d7), + SPH_C32(0xed194bc4), SPH_C32(0xbaad0000), SPH_C32(0xfbdb639f), + SPH_C32(0x48e084b2), SPH_C32(0x6159f19e) }, + { SPH_C32(0x30986000), SPH_C32(0x7f67627d), SPH_C32(0x27dc01fb), + SPH_C32(0x230b6637), SPH_C32(0xce381000), SPH_C32(0xa1f025e1), + SPH_C32(0xc01d9999), SPH_C32(0x7fbf730c) }, + { SPH_C32(0x440d7000), SPH_C32(0x254c2403), SPH_C32(0xaf211cd0), + SPH_C32(0x3dede4a5), SPH_C32(0x05911000), SPH_C32(0x31d71288), + SPH_C32(0x7bc16d9e), SPH_C32(0xaf4bdc6d) }, + { SPH_C32(0x85484000), SPH_C32(0x7b58b73b), SPH_C32(0xfa4327a4), + SPH_C32(0x6fda92b3), SPH_C32(0x982e2000), SPH_C32(0xdfabd80a), + SPH_C32(0xe2c64ae2), SPH_C32(0x8c645bdb) }, + { SPH_C32(0xf1dd5000), SPH_C32(0x2173f145), SPH_C32(0x72be3a8f), + SPH_C32(0x713c1021), SPH_C32(0x53872000), SPH_C32(0x4f8cef63), + SPH_C32(0x591abee5), SPH_C32(0x5c90f4ba) }, + { SPH_C32(0x4ee14000), SPH_C32(0xeb7f8052), SPH_C32(0x419fd3a3), + SPH_C32(0xbf2e3dd2), SPH_C32(0x27123000), SPH_C32(0x15a7a91d), + SPH_C32(0xd1e7a3ce), SPH_C32(0x42767628) }, + { SPH_C32(0x3a745000), SPH_C32(0xb154c62c), SPH_C32(0xc962ce88), + SPH_C32(0xa1c8bf40), SPH_C32(0xecbb3000), SPH_C32(0x85809e74), + SPH_C32(0x6a3b57c9), SPH_C32(0x9282d949) }, + { SPH_C32(0x6c626000), SPH_C32(0xcf0f3bc7), SPH_C32(0xebb91df3), + SPH_C32(0x52139797), SPH_C32(0x0f7d2000), SPH_C32(0xffe4b6d9), + SPH_C32(0x957fa2ed), SPH_C32(0x2d88051a) }, + { SPH_C32(0x18f77000), SPH_C32(0x95247db9), SPH_C32(0x634400d8), + SPH_C32(0x4cf51505), SPH_C32(0xc4d42000), SPH_C32(0x6fc381b0), + SPH_C32(0x2ea356ea), SPH_C32(0xfd7caa7b) }, + { SPH_C32(0xa7cb6000), SPH_C32(0x5f280cae), SPH_C32(0x5065e9f4), + SPH_C32(0x82e738f6), SPH_C32(0xb0413000), SPH_C32(0x35e8c7ce), + SPH_C32(0xa65e4bc1), SPH_C32(0xe39a28e9) }, + { SPH_C32(0xd35e7000), SPH_C32(0x05034ad0), SPH_C32(0xd898f4df), + SPH_C32(0x9c01ba64), SPH_C32(0x7be83000), SPH_C32(0xa5cff0a7), + SPH_C32(0x1d82bfc6), SPH_C32(0x336e8788) }, + { SPH_C32(0xe6570000), SPH_C32(0x4bb33a25), SPH_C32(0x848598ba), + SPH_C32(0x1041003e), SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), + SPH_C32(0x097f5711), SPH_C32(0xde77cc4c) }, + { SPH_C32(0x92c21000), SPH_C32(0x11987c5b), SPH_C32(0x0c788591), + SPH_C32(0x0ea782ac), SPH_C32(0x3fe54000), SPH_C32(0x8083d4a4), + SPH_C32(0xb2a3a316), SPH_C32(0x0e83632d) }, + { SPH_C32(0x2dfe0000), SPH_C32(0xdb940d4c), SPH_C32(0x3f596cbd), + SPH_C32(0xc0b5af5f), SPH_C32(0x4b705000), SPH_C32(0xdaa892da), + SPH_C32(0x3a5ebe3d), SPH_C32(0x1065e1bf) }, + { SPH_C32(0x596b1000), SPH_C32(0x81bf4b32), SPH_C32(0xb7a47196), + SPH_C32(0xde532dcd), SPH_C32(0x80d95000), SPH_C32(0x4a8fa5b3), + SPH_C32(0x81824a3a), SPH_C32(0xc0914ede) }, + { SPH_C32(0x0f7d2000), SPH_C32(0xffe4b6d9), SPH_C32(0x957fa2ed), + SPH_C32(0x2d88051a), SPH_C32(0x631f4000), SPH_C32(0x30eb8d1e), + SPH_C32(0x7ec6bf1e), SPH_C32(0x7f9b928d) }, + { SPH_C32(0x7be83000), SPH_C32(0xa5cff0a7), SPH_C32(0x1d82bfc6), + SPH_C32(0x336e8788), SPH_C32(0xa8b64000), SPH_C32(0xa0ccba77), + SPH_C32(0xc51a4b19), SPH_C32(0xaf6f3dec) }, + { SPH_C32(0xc4d42000), SPH_C32(0x6fc381b0), SPH_C32(0x2ea356ea), + SPH_C32(0xfd7caa7b), SPH_C32(0xdc235000), SPH_C32(0xfae7fc09), + SPH_C32(0x4de75632), SPH_C32(0xb189bf7e) }, + { SPH_C32(0xb0413000), SPH_C32(0x35e8c7ce), SPH_C32(0xa65e4bc1), + SPH_C32(0xe39a28e9), SPH_C32(0x178a5000), SPH_C32(0x6ac0cb60), + SPH_C32(0xf63ba235), SPH_C32(0x617d101f) }, + { SPH_C32(0x71040000), SPH_C32(0x6bfc54f6), SPH_C32(0xf33c70b5), + SPH_C32(0xb1ad5eff), SPH_C32(0x8a356000), SPH_C32(0x84bc01e2), + SPH_C32(0x6f3c8549), SPH_C32(0x425297a9) }, + { SPH_C32(0x05911000), SPH_C32(0x31d71288), SPH_C32(0x7bc16d9e), + SPH_C32(0xaf4bdc6d), SPH_C32(0x419c6000), SPH_C32(0x149b368b), + SPH_C32(0xd4e0714e), SPH_C32(0x92a638c8) }, + { SPH_C32(0xbaad0000), SPH_C32(0xfbdb639f), SPH_C32(0x48e084b2), + SPH_C32(0x6159f19e), SPH_C32(0x35097000), SPH_C32(0x4eb070f5), + SPH_C32(0x5c1d6c65), SPH_C32(0x8c40ba5a) }, + { SPH_C32(0xce381000), SPH_C32(0xa1f025e1), SPH_C32(0xc01d9999), + SPH_C32(0x7fbf730c), SPH_C32(0xfea07000), SPH_C32(0xde97479c), + SPH_C32(0xe7c19862), SPH_C32(0x5cb4153b) }, + { SPH_C32(0x982e2000), SPH_C32(0xdfabd80a), SPH_C32(0xe2c64ae2), + SPH_C32(0x8c645bdb), SPH_C32(0x1d666000), SPH_C32(0xa4f36f31), + SPH_C32(0x18856d46), SPH_C32(0xe3bec968) }, + { SPH_C32(0xecbb3000), SPH_C32(0x85809e74), SPH_C32(0x6a3b57c9), + SPH_C32(0x9282d949), SPH_C32(0xd6cf6000), SPH_C32(0x34d45858), + SPH_C32(0xa3599941), SPH_C32(0x334a6609) }, + { SPH_C32(0x53872000), SPH_C32(0x4f8cef63), SPH_C32(0x591abee5), + SPH_C32(0x5c90f4ba), SPH_C32(0xa25a7000), SPH_C32(0x6eff1e26), + SPH_C32(0x2ba4846a), SPH_C32(0x2dace49b) }, + { SPH_C32(0x27123000), SPH_C32(0x15a7a91d), SPH_C32(0xd1e7a3ce), + SPH_C32(0x42767628), SPH_C32(0x69f37000), SPH_C32(0xfed8294f), + SPH_C32(0x9078706d), SPH_C32(0xfd584bfa) }, + { SPH_C32(0xf44c4000), SPH_C32(0x10a4e3cd), SPH_C32(0x097f5711), + SPH_C32(0xde77cc4c), SPH_C32(0x121b4000), SPH_C32(0x5b17d9e8), + SPH_C32(0x8dfacfab), SPH_C32(0xce36cc72) }, + { SPH_C32(0x80d95000), SPH_C32(0x4a8fa5b3), SPH_C32(0x81824a3a), + SPH_C32(0xc0914ede), SPH_C32(0xd9b24000), SPH_C32(0xcb30ee81), + SPH_C32(0x36263bac), SPH_C32(0x1ec26313) }, + { SPH_C32(0x3fe54000), SPH_C32(0x8083d4a4), SPH_C32(0xb2a3a316), + SPH_C32(0x0e83632d), SPH_C32(0xad275000), SPH_C32(0x911ba8ff), + SPH_C32(0xbedb2687), SPH_C32(0x0024e181) }, + { SPH_C32(0x4b705000), SPH_C32(0xdaa892da), SPH_C32(0x3a5ebe3d), + SPH_C32(0x1065e1bf), SPH_C32(0x668e5000), SPH_C32(0x013c9f96), + SPH_C32(0x0507d280), SPH_C32(0xd0d04ee0) }, + { SPH_C32(0x1d666000), SPH_C32(0xa4f36f31), SPH_C32(0x18856d46), + SPH_C32(0xe3bec968), SPH_C32(0x85484000), SPH_C32(0x7b58b73b), + SPH_C32(0xfa4327a4), SPH_C32(0x6fda92b3) }, + { SPH_C32(0x69f37000), SPH_C32(0xfed8294f), SPH_C32(0x9078706d), + SPH_C32(0xfd584bfa), SPH_C32(0x4ee14000), SPH_C32(0xeb7f8052), + SPH_C32(0x419fd3a3), SPH_C32(0xbf2e3dd2) }, + { SPH_C32(0xd6cf6000), SPH_C32(0x34d45858), SPH_C32(0xa3599941), + SPH_C32(0x334a6609), SPH_C32(0x3a745000), SPH_C32(0xb154c62c), + SPH_C32(0xc962ce88), SPH_C32(0xa1c8bf40) }, + { SPH_C32(0xa25a7000), SPH_C32(0x6eff1e26), SPH_C32(0x2ba4846a), + SPH_C32(0x2dace49b), SPH_C32(0xf1dd5000), SPH_C32(0x2173f145), + SPH_C32(0x72be3a8f), SPH_C32(0x713c1021) }, + { SPH_C32(0x631f4000), SPH_C32(0x30eb8d1e), SPH_C32(0x7ec6bf1e), + SPH_C32(0x7f9b928d), SPH_C32(0x6c626000), SPH_C32(0xcf0f3bc7), + SPH_C32(0xebb91df3), SPH_C32(0x52139797) }, + { SPH_C32(0x178a5000), SPH_C32(0x6ac0cb60), SPH_C32(0xf63ba235), + SPH_C32(0x617d101f), SPH_C32(0xa7cb6000), SPH_C32(0x5f280cae), + SPH_C32(0x5065e9f4), SPH_C32(0x82e738f6) }, + { SPH_C32(0xa8b64000), SPH_C32(0xa0ccba77), SPH_C32(0xc51a4b19), + SPH_C32(0xaf6f3dec), SPH_C32(0xd35e7000), SPH_C32(0x05034ad0), + SPH_C32(0xd898f4df), SPH_C32(0x9c01ba64) }, + { SPH_C32(0xdc235000), SPH_C32(0xfae7fc09), SPH_C32(0x4de75632), + SPH_C32(0xb189bf7e), SPH_C32(0x18f77000), SPH_C32(0x95247db9), + SPH_C32(0x634400d8), SPH_C32(0x4cf51505) }, + { SPH_C32(0x8a356000), SPH_C32(0x84bc01e2), SPH_C32(0x6f3c8549), + SPH_C32(0x425297a9), SPH_C32(0xfb316000), SPH_C32(0xef405514), + SPH_C32(0x9c00f5fc), SPH_C32(0xf3ffc956) }, + { SPH_C32(0xfea07000), SPH_C32(0xde97479c), SPH_C32(0xe7c19862), + SPH_C32(0x5cb4153b), SPH_C32(0x30986000), SPH_C32(0x7f67627d), + SPH_C32(0x27dc01fb), SPH_C32(0x230b6637) }, + { SPH_C32(0x419c6000), SPH_C32(0x149b368b), SPH_C32(0xd4e0714e), + SPH_C32(0x92a638c8), SPH_C32(0x440d7000), SPH_C32(0x254c2403), + SPH_C32(0xaf211cd0), SPH_C32(0x3dede4a5) }, + { SPH_C32(0x35097000), SPH_C32(0x4eb070f5), SPH_C32(0x5c1d6c65), + SPH_C32(0x8c40ba5a), SPH_C32(0x8fa47000), SPH_C32(0xb56b136a), + SPH_C32(0x14fde8d7), SPH_C32(0xed194bc4) }, + { SPH_C32(0xe4788000), SPH_C32(0x859673c1), SPH_C32(0xb5fb2452), + SPH_C32(0x29cc5edf), SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), + SPH_C32(0x62fc79d0), SPH_C32(0x731ebdc2) }, + { SPH_C32(0x90ed9000), SPH_C32(0xdfbd35bf), SPH_C32(0x3d063979), + SPH_C32(0x372adc4d), SPH_C32(0xcff60000), SPH_C32(0x0c6da4a0), + SPH_C32(0xd9208dd7), SPH_C32(0xa3ea12a3) }, + { SPH_C32(0x2fd18000), SPH_C32(0x15b144a8), SPH_C32(0x0e27d055), + SPH_C32(0xf938f1be), SPH_C32(0xbb631000), SPH_C32(0x5646e2de), + SPH_C32(0x51dd90fc), SPH_C32(0xbd0c9031) }, + { SPH_C32(0x5b449000), SPH_C32(0x4f9a02d6), SPH_C32(0x86dacd7e), + SPH_C32(0xe7de732c), SPH_C32(0x70ca1000), SPH_C32(0xc661d5b7), + SPH_C32(0xea0164fb), SPH_C32(0x6df83f50) }, + { SPH_C32(0x0d52a000), SPH_C32(0x31c1ff3d), SPH_C32(0xa4011e05), + SPH_C32(0x14055bfb), SPH_C32(0x930c0000), SPH_C32(0xbc05fd1a), + SPH_C32(0x154591df), SPH_C32(0xd2f2e303) }, + { SPH_C32(0x79c7b000), SPH_C32(0x6beab943), SPH_C32(0x2cfc032e), + SPH_C32(0x0ae3d969), SPH_C32(0x58a50000), SPH_C32(0x2c22ca73), + SPH_C32(0xae9965d8), SPH_C32(0x02064c62) }, + { SPH_C32(0xc6fba000), SPH_C32(0xa1e6c854), SPH_C32(0x1fddea02), + SPH_C32(0xc4f1f49a), SPH_C32(0x2c301000), SPH_C32(0x76098c0d), + SPH_C32(0x266478f3), SPH_C32(0x1ce0cef0) }, + { SPH_C32(0xb26eb000), SPH_C32(0xfbcd8e2a), SPH_C32(0x9720f729), + SPH_C32(0xda177608), SPH_C32(0xe7991000), SPH_C32(0xe62ebb64), + SPH_C32(0x9db88cf4), SPH_C32(0xcc146191) }, + { SPH_C32(0x732b8000), SPH_C32(0xa5d91d12), SPH_C32(0xc242cc5d), + SPH_C32(0x8820001e), SPH_C32(0x7a262000), SPH_C32(0x085271e6), + SPH_C32(0x04bfab88), SPH_C32(0xef3be627) }, + { SPH_C32(0x07be9000), SPH_C32(0xfff25b6c), SPH_C32(0x4abfd176), + SPH_C32(0x96c6828c), SPH_C32(0xb18f2000), SPH_C32(0x9875468f), + SPH_C32(0xbf635f8f), SPH_C32(0x3fcf4946) }, + { SPH_C32(0xb8828000), SPH_C32(0x35fe2a7b), SPH_C32(0x799e385a), + SPH_C32(0x58d4af7f), SPH_C32(0xc51a3000), SPH_C32(0xc25e00f1), + SPH_C32(0x379e42a4), SPH_C32(0x2129cbd4) }, + { SPH_C32(0xcc179000), SPH_C32(0x6fd56c05), SPH_C32(0xf1632571), + SPH_C32(0x46322ded), SPH_C32(0x0eb33000), SPH_C32(0x52793798), + SPH_C32(0x8c42b6a3), SPH_C32(0xf1dd64b5) }, + { SPH_C32(0x9a01a000), SPH_C32(0x118e91ee), SPH_C32(0xd3b8f60a), + SPH_C32(0xb5e9053a), SPH_C32(0xed752000), SPH_C32(0x281d1f35), + SPH_C32(0x73064387), SPH_C32(0x4ed7b8e6) }, + { SPH_C32(0xee94b000), SPH_C32(0x4ba5d790), SPH_C32(0x5b45eb21), + SPH_C32(0xab0f87a8), SPH_C32(0x26dc2000), SPH_C32(0xb83a285c), + SPH_C32(0xc8dab780), SPH_C32(0x9e231787) }, + { SPH_C32(0x51a8a000), SPH_C32(0x81a9a687), SPH_C32(0x6864020d), + SPH_C32(0x651daa5b), SPH_C32(0x52493000), SPH_C32(0xe2116e22), + SPH_C32(0x4027aaab), SPH_C32(0x80c59515) }, + { SPH_C32(0x253db000), SPH_C32(0xdb82e0f9), SPH_C32(0xe0991f26), + SPH_C32(0x7bfb28c9), SPH_C32(0x99e03000), SPH_C32(0x7236594b), + SPH_C32(0xfbfb5eac), SPH_C32(0x50313a74) }, + { SPH_C32(0xf663c000), SPH_C32(0xde81aa29), SPH_C32(0x3801ebf9), + SPH_C32(0xe7fa92ad), SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), + SPH_C32(0xe679e16a), SPH_C32(0x635fbdfc) }, + { SPH_C32(0x82f6d000), SPH_C32(0x84aaec57), SPH_C32(0xb0fcf6d2), + SPH_C32(0xf91c103f), SPH_C32(0x29a10000), SPH_C32(0x47de9e85), + SPH_C32(0x5da5156d), SPH_C32(0xb3ab129d) }, + { SPH_C32(0x3dcac000), SPH_C32(0x4ea69d40), SPH_C32(0x83dd1ffe), + SPH_C32(0x370e3dcc), SPH_C32(0x5d341000), SPH_C32(0x1df5d8fb), + SPH_C32(0xd5580846), SPH_C32(0xad4d900f) }, + { SPH_C32(0x495fd000), SPH_C32(0x148ddb3e), SPH_C32(0x0b2002d5), + SPH_C32(0x29e8bf5e), SPH_C32(0x969d1000), SPH_C32(0x8dd2ef92), + SPH_C32(0x6e84fc41), SPH_C32(0x7db93f6e) }, + { SPH_C32(0x1f49e000), SPH_C32(0x6ad626d5), SPH_C32(0x29fbd1ae), + SPH_C32(0xda339789), SPH_C32(0x755b0000), SPH_C32(0xf7b6c73f), + SPH_C32(0x91c00965), SPH_C32(0xc2b3e33d) }, + { SPH_C32(0x6bdcf000), SPH_C32(0x30fd60ab), SPH_C32(0xa106cc85), + SPH_C32(0xc4d5151b), SPH_C32(0xbef20000), SPH_C32(0x6791f056), + SPH_C32(0x2a1cfd62), SPH_C32(0x12474c5c) }, + { SPH_C32(0xd4e0e000), SPH_C32(0xfaf111bc), SPH_C32(0x922725a9), + SPH_C32(0x0ac738e8), SPH_C32(0xca671000), SPH_C32(0x3dbab628), + SPH_C32(0xa2e1e049), SPH_C32(0x0ca1cece) }, + { SPH_C32(0xa075f000), SPH_C32(0xa0da57c2), SPH_C32(0x1ada3882), + SPH_C32(0x1421ba7a), SPH_C32(0x01ce1000), SPH_C32(0xad9d8141), + SPH_C32(0x193d144e), SPH_C32(0xdc5561af) }, + { SPH_C32(0x6130c000), SPH_C32(0xfecec4fa), SPH_C32(0x4fb803f6), + SPH_C32(0x4616cc6c), SPH_C32(0x9c712000), SPH_C32(0x43e14bc3), + SPH_C32(0x803a3332), SPH_C32(0xff7ae619) }, + { SPH_C32(0x15a5d000), SPH_C32(0xa4e58284), SPH_C32(0xc7451edd), + SPH_C32(0x58f04efe), SPH_C32(0x57d82000), SPH_C32(0xd3c67caa), + SPH_C32(0x3be6c735), SPH_C32(0x2f8e4978) }, + { SPH_C32(0xaa99c000), SPH_C32(0x6ee9f393), SPH_C32(0xf464f7f1), + SPH_C32(0x96e2630d), SPH_C32(0x234d3000), SPH_C32(0x89ed3ad4), + SPH_C32(0xb31bda1e), SPH_C32(0x3168cbea) }, + { SPH_C32(0xde0cd000), SPH_C32(0x34c2b5ed), SPH_C32(0x7c99eada), + SPH_C32(0x8804e19f), SPH_C32(0xe8e43000), SPH_C32(0x19ca0dbd), + SPH_C32(0x08c72e19), SPH_C32(0xe19c648b) }, + { SPH_C32(0x881ae000), SPH_C32(0x4a994806), SPH_C32(0x5e4239a1), + SPH_C32(0x7bdfc948), SPH_C32(0x0b222000), SPH_C32(0x63ae2510), + SPH_C32(0xf783db3d), SPH_C32(0x5e96b8d8) }, + { SPH_C32(0xfc8ff000), SPH_C32(0x10b20e78), SPH_C32(0xd6bf248a), + SPH_C32(0x65394bda), SPH_C32(0xc08b2000), SPH_C32(0xf3891279), + SPH_C32(0x4c5f2f3a), SPH_C32(0x8e6217b9) }, + { SPH_C32(0x43b3e000), SPH_C32(0xdabe7f6f), SPH_C32(0xe59ecda6), + SPH_C32(0xab2b6629), SPH_C32(0xb41e3000), SPH_C32(0xa9a25407), + SPH_C32(0xc4a23211), SPH_C32(0x9084952b) }, + { SPH_C32(0x3726f000), SPH_C32(0x80953911), SPH_C32(0x6d63d08d), + SPH_C32(0xb5cde4bb), SPH_C32(0x7fb73000), SPH_C32(0x3985636e), + SPH_C32(0x7f7ec616), SPH_C32(0x40703a4a) }, + { SPH_C32(0x022f8000), SPH_C32(0xce2549e4), SPH_C32(0x317ebce8), + SPH_C32(0x398d5ee1), SPH_C32(0xf0134000), SPH_C32(0x8cee7004), + SPH_C32(0x6b832ec1), SPH_C32(0xad69718e) }, + { SPH_C32(0x76ba9000), SPH_C32(0x940e0f9a), SPH_C32(0xb983a1c3), + SPH_C32(0x276bdc73), SPH_C32(0x3bba4000), SPH_C32(0x1cc9476d), + SPH_C32(0xd05fdac6), SPH_C32(0x7d9ddeef) }, + { SPH_C32(0xc9868000), SPH_C32(0x5e027e8d), SPH_C32(0x8aa248ef), + SPH_C32(0xe979f180), SPH_C32(0x4f2f5000), SPH_C32(0x46e20113), + SPH_C32(0x58a2c7ed), SPH_C32(0x637b5c7d) }, + { SPH_C32(0xbd139000), SPH_C32(0x042938f3), SPH_C32(0x025f55c4), + SPH_C32(0xf79f7312), SPH_C32(0x84865000), SPH_C32(0xd6c5367a), + SPH_C32(0xe37e33ea), SPH_C32(0xb38ff31c) }, + { SPH_C32(0xeb05a000), SPH_C32(0x7a72c518), SPH_C32(0x208486bf), + SPH_C32(0x04445bc5), SPH_C32(0x67404000), SPH_C32(0xaca11ed7), + SPH_C32(0x1c3ac6ce), SPH_C32(0x0c852f4f) }, + { SPH_C32(0x9f90b000), SPH_C32(0x20598366), SPH_C32(0xa8799b94), + SPH_C32(0x1aa2d957), SPH_C32(0xace94000), SPH_C32(0x3c8629be), + SPH_C32(0xa7e632c9), SPH_C32(0xdc71802e) }, + { SPH_C32(0x20aca000), SPH_C32(0xea55f271), SPH_C32(0x9b5872b8), + SPH_C32(0xd4b0f4a4), SPH_C32(0xd87c5000), SPH_C32(0x66ad6fc0), + SPH_C32(0x2f1b2fe2), SPH_C32(0xc29702bc) }, + { SPH_C32(0x5439b000), SPH_C32(0xb07eb40f), SPH_C32(0x13a56f93), + SPH_C32(0xca567636), SPH_C32(0x13d55000), SPH_C32(0xf68a58a9), + SPH_C32(0x94c7dbe5), SPH_C32(0x1263addd) }, + { SPH_C32(0x957c8000), SPH_C32(0xee6a2737), SPH_C32(0x46c754e7), + SPH_C32(0x98610020), SPH_C32(0x8e6a6000), SPH_C32(0x18f6922b), + SPH_C32(0x0dc0fc99), SPH_C32(0x314c2a6b) }, + { SPH_C32(0xe1e99000), SPH_C32(0xb4416149), SPH_C32(0xce3a49cc), + SPH_C32(0x868782b2), SPH_C32(0x45c36000), SPH_C32(0x88d1a542), + SPH_C32(0xb61c089e), SPH_C32(0xe1b8850a) }, + { SPH_C32(0x5ed58000), SPH_C32(0x7e4d105e), SPH_C32(0xfd1ba0e0), + SPH_C32(0x4895af41), SPH_C32(0x31567000), SPH_C32(0xd2fae33c), + SPH_C32(0x3ee115b5), SPH_C32(0xff5e0798) }, + { SPH_C32(0x2a409000), SPH_C32(0x24665620), SPH_C32(0x75e6bdcb), + SPH_C32(0x56732dd3), SPH_C32(0xfaff7000), SPH_C32(0x42ddd455), + SPH_C32(0x853de1b2), SPH_C32(0x2faaa8f9) }, + { SPH_C32(0x7c56a000), SPH_C32(0x5a3dabcb), SPH_C32(0x573d6eb0), + SPH_C32(0xa5a80504), SPH_C32(0x19396000), SPH_C32(0x38b9fcf8), + SPH_C32(0x7a791496), SPH_C32(0x90a074aa) }, + { SPH_C32(0x08c3b000), SPH_C32(0x0016edb5), SPH_C32(0xdfc0739b), + SPH_C32(0xbb4e8796), SPH_C32(0xd2906000), SPH_C32(0xa89ecb91), + SPH_C32(0xc1a5e091), SPH_C32(0x4054dbcb) }, + { SPH_C32(0xb7ffa000), SPH_C32(0xca1a9ca2), SPH_C32(0xece19ab7), + SPH_C32(0x755caa65), SPH_C32(0xa6057000), SPH_C32(0xf2b58def), + SPH_C32(0x4958fdba), SPH_C32(0x5eb25959) }, + { SPH_C32(0xc36ab000), SPH_C32(0x9031dadc), SPH_C32(0x641c879c), + SPH_C32(0x6bba28f7), SPH_C32(0x6dac7000), SPH_C32(0x6292ba86), + SPH_C32(0xf28409bd), SPH_C32(0x8e46f638) }, + { SPH_C32(0x1034c000), SPH_C32(0x9532900c), SPH_C32(0xbc847343), + SPH_C32(0xf7bb9293), SPH_C32(0x16444000), SPH_C32(0xc75d4a21), + SPH_C32(0xef06b67b), SPH_C32(0xbd2871b0) }, + { SPH_C32(0x64a1d000), SPH_C32(0xcf19d672), SPH_C32(0x34796e68), + SPH_C32(0xe95d1001), SPH_C32(0xdded4000), SPH_C32(0x577a7d48), + SPH_C32(0x54da427c), SPH_C32(0x6ddcded1) }, + { SPH_C32(0xdb9dc000), SPH_C32(0x0515a765), SPH_C32(0x07588744), + SPH_C32(0x274f3df2), SPH_C32(0xa9785000), SPH_C32(0x0d513b36), + SPH_C32(0xdc275f57), SPH_C32(0x733a5c43) }, + { SPH_C32(0xaf08d000), SPH_C32(0x5f3ee11b), SPH_C32(0x8fa59a6f), + SPH_C32(0x39a9bf60), SPH_C32(0x62d15000), SPH_C32(0x9d760c5f), + SPH_C32(0x67fbab50), SPH_C32(0xa3cef322) }, + { SPH_C32(0xf91ee000), SPH_C32(0x21651cf0), SPH_C32(0xad7e4914), + SPH_C32(0xca7297b7), SPH_C32(0x81174000), SPH_C32(0xe71224f2), + SPH_C32(0x98bf5e74), SPH_C32(0x1cc42f71) }, + { SPH_C32(0x8d8bf000), SPH_C32(0x7b4e5a8e), SPH_C32(0x2583543f), + SPH_C32(0xd4941525), SPH_C32(0x4abe4000), SPH_C32(0x7735139b), + SPH_C32(0x2363aa73), SPH_C32(0xcc308010) }, + { SPH_C32(0x32b7e000), SPH_C32(0xb1422b99), SPH_C32(0x16a2bd13), + SPH_C32(0x1a8638d6), SPH_C32(0x3e2b5000), SPH_C32(0x2d1e55e5), + SPH_C32(0xab9eb758), SPH_C32(0xd2d60282) }, + { SPH_C32(0x4622f000), SPH_C32(0xeb696de7), SPH_C32(0x9e5fa038), + SPH_C32(0x0460ba44), SPH_C32(0xf5825000), SPH_C32(0xbd39628c), + SPH_C32(0x1042435f), SPH_C32(0x0222ade3) }, + { SPH_C32(0x8767c000), SPH_C32(0xb57dfedf), SPH_C32(0xcb3d9b4c), + SPH_C32(0x5657cc52), SPH_C32(0x683d6000), SPH_C32(0x5345a80e), + SPH_C32(0x89456423), SPH_C32(0x210d2a55) }, + { SPH_C32(0xf3f2d000), SPH_C32(0xef56b8a1), SPH_C32(0x43c08667), + SPH_C32(0x48b14ec0), SPH_C32(0xa3946000), SPH_C32(0xc3629f67), + SPH_C32(0x32999024), SPH_C32(0xf1f98534) }, + { SPH_C32(0x4ccec000), SPH_C32(0x255ac9b6), SPH_C32(0x70e16f4b), + SPH_C32(0x86a36333), SPH_C32(0xd7017000), SPH_C32(0x9949d919), + SPH_C32(0xba648d0f), SPH_C32(0xef1f07a6) }, + { SPH_C32(0x385bd000), SPH_C32(0x7f718fc8), SPH_C32(0xf81c7260), + SPH_C32(0x9845e1a1), SPH_C32(0x1ca87000), SPH_C32(0x096eee70), + SPH_C32(0x01b87908), SPH_C32(0x3feba8c7) }, + { SPH_C32(0x6e4de000), SPH_C32(0x012a7223), SPH_C32(0xdac7a11b), + SPH_C32(0x6b9ec976), SPH_C32(0xff6e6000), SPH_C32(0x730ac6dd), + SPH_C32(0xfefc8c2c), SPH_C32(0x80e17494) }, + { SPH_C32(0x1ad8f000), SPH_C32(0x5b01345d), SPH_C32(0x523abc30), + SPH_C32(0x75784be4), SPH_C32(0x34c76000), SPH_C32(0xe32df1b4), + SPH_C32(0x4520782b), SPH_C32(0x5015dbf5) }, + { SPH_C32(0xa5e4e000), SPH_C32(0x910d454a), SPH_C32(0x611b551c), + SPH_C32(0xbb6a6617), SPH_C32(0x40527000), SPH_C32(0xb906b7ca), + SPH_C32(0xcddd6500), SPH_C32(0x4ef35967) }, + { SPH_C32(0xd171f000), SPH_C32(0xcb260334), SPH_C32(0xe9e64837), + SPH_C32(0xa58ce485), SPH_C32(0x8bfb7000), SPH_C32(0x292180a3), + SPH_C32(0x76019107), SPH_C32(0x9e07f606) }, + { SPH_C32(0x045f0000), SPH_C32(0x9c4a93c9), SPH_C32(0x62fc79d0), + SPH_C32(0x731ebdc2), SPH_C32(0xe0278000), SPH_C32(0x19dce008), + SPH_C32(0xd7075d82), SPH_C32(0x5ad2e31d) }, + { SPH_C32(0x70ca1000), SPH_C32(0xc661d5b7), SPH_C32(0xea0164fb), + SPH_C32(0x6df83f50), SPH_C32(0x2b8e8000), SPH_C32(0x89fbd761), + SPH_C32(0x6cdba985), SPH_C32(0x8a264c7c) }, + { SPH_C32(0xcff60000), SPH_C32(0x0c6da4a0), SPH_C32(0xd9208dd7), + SPH_C32(0xa3ea12a3), SPH_C32(0x5f1b9000), SPH_C32(0xd3d0911f), + SPH_C32(0xe426b4ae), SPH_C32(0x94c0ceee) }, + { SPH_C32(0xbb631000), SPH_C32(0x5646e2de), SPH_C32(0x51dd90fc), + SPH_C32(0xbd0c9031), SPH_C32(0x94b29000), SPH_C32(0x43f7a676), + SPH_C32(0x5ffa40a9), SPH_C32(0x4434618f) }, + { SPH_C32(0xed752000), SPH_C32(0x281d1f35), SPH_C32(0x73064387), + SPH_C32(0x4ed7b8e6), SPH_C32(0x77748000), SPH_C32(0x39938edb), + SPH_C32(0xa0beb58d), SPH_C32(0xfb3ebddc) }, + { SPH_C32(0x99e03000), SPH_C32(0x7236594b), SPH_C32(0xfbfb5eac), + SPH_C32(0x50313a74), SPH_C32(0xbcdd8000), SPH_C32(0xa9b4b9b2), + SPH_C32(0x1b62418a), SPH_C32(0x2bca12bd) }, + { SPH_C32(0x26dc2000), SPH_C32(0xb83a285c), SPH_C32(0xc8dab780), + SPH_C32(0x9e231787), SPH_C32(0xc8489000), SPH_C32(0xf39fffcc), + SPH_C32(0x939f5ca1), SPH_C32(0x352c902f) }, + { SPH_C32(0x52493000), SPH_C32(0xe2116e22), SPH_C32(0x4027aaab), + SPH_C32(0x80c59515), SPH_C32(0x03e19000), SPH_C32(0x63b8c8a5), + SPH_C32(0x2843a8a6), SPH_C32(0xe5d83f4e) }, + { SPH_C32(0x930c0000), SPH_C32(0xbc05fd1a), SPH_C32(0x154591df), + SPH_C32(0xd2f2e303), SPH_C32(0x9e5ea000), SPH_C32(0x8dc40227), + SPH_C32(0xb1448fda), SPH_C32(0xc6f7b8f8) }, + { SPH_C32(0xe7991000), SPH_C32(0xe62ebb64), SPH_C32(0x9db88cf4), + SPH_C32(0xcc146191), SPH_C32(0x55f7a000), SPH_C32(0x1de3354e), + SPH_C32(0x0a987bdd), SPH_C32(0x16031799) }, + { SPH_C32(0x58a50000), SPH_C32(0x2c22ca73), SPH_C32(0xae9965d8), + SPH_C32(0x02064c62), SPH_C32(0x2162b000), SPH_C32(0x47c87330), + SPH_C32(0x826566f6), SPH_C32(0x08e5950b) }, + { SPH_C32(0x2c301000), SPH_C32(0x76098c0d), SPH_C32(0x266478f3), + SPH_C32(0x1ce0cef0), SPH_C32(0xeacbb000), SPH_C32(0xd7ef4459), + SPH_C32(0x39b992f1), SPH_C32(0xd8113a6a) }, + { SPH_C32(0x7a262000), SPH_C32(0x085271e6), SPH_C32(0x04bfab88), + SPH_C32(0xef3be627), SPH_C32(0x090da000), SPH_C32(0xad8b6cf4), + SPH_C32(0xc6fd67d5), SPH_C32(0x671be639) }, + { SPH_C32(0x0eb33000), SPH_C32(0x52793798), SPH_C32(0x8c42b6a3), + SPH_C32(0xf1dd64b5), SPH_C32(0xc2a4a000), SPH_C32(0x3dac5b9d), + SPH_C32(0x7d2193d2), SPH_C32(0xb7ef4958) }, + { SPH_C32(0xb18f2000), SPH_C32(0x9875468f), SPH_C32(0xbf635f8f), + SPH_C32(0x3fcf4946), SPH_C32(0xb631b000), SPH_C32(0x67871de3), + SPH_C32(0xf5dc8ef9), SPH_C32(0xa909cbca) }, + { SPH_C32(0xc51a3000), SPH_C32(0xc25e00f1), SPH_C32(0x379e42a4), + SPH_C32(0x2129cbd4), SPH_C32(0x7d98b000), SPH_C32(0xf7a02a8a), + SPH_C32(0x4e007afe), SPH_C32(0x79fd64ab) }, + { SPH_C32(0x16444000), SPH_C32(0xc75d4a21), SPH_C32(0xef06b67b), + SPH_C32(0xbd2871b0), SPH_C32(0x06708000), SPH_C32(0x526fda2d), + SPH_C32(0x5382c538), SPH_C32(0x4a93e323) }, + { SPH_C32(0x62d15000), SPH_C32(0x9d760c5f), SPH_C32(0x67fbab50), + SPH_C32(0xa3cef322), SPH_C32(0xcdd98000), SPH_C32(0xc248ed44), + SPH_C32(0xe85e313f), SPH_C32(0x9a674c42) }, + { SPH_C32(0xdded4000), SPH_C32(0x577a7d48), SPH_C32(0x54da427c), + SPH_C32(0x6ddcded1), SPH_C32(0xb94c9000), SPH_C32(0x9863ab3a), + SPH_C32(0x60a32c14), SPH_C32(0x8481ced0) }, + { SPH_C32(0xa9785000), SPH_C32(0x0d513b36), SPH_C32(0xdc275f57), + SPH_C32(0x733a5c43), SPH_C32(0x72e59000), SPH_C32(0x08449c53), + SPH_C32(0xdb7fd813), SPH_C32(0x547561b1) }, + { SPH_C32(0xff6e6000), SPH_C32(0x730ac6dd), SPH_C32(0xfefc8c2c), + SPH_C32(0x80e17494), SPH_C32(0x91238000), SPH_C32(0x7220b4fe), + SPH_C32(0x243b2d37), SPH_C32(0xeb7fbde2) }, + { SPH_C32(0x8bfb7000), SPH_C32(0x292180a3), SPH_C32(0x76019107), + SPH_C32(0x9e07f606), SPH_C32(0x5a8a8000), SPH_C32(0xe2078397), + SPH_C32(0x9fe7d930), SPH_C32(0x3b8b1283) }, + { SPH_C32(0x34c76000), SPH_C32(0xe32df1b4), SPH_C32(0x4520782b), + SPH_C32(0x5015dbf5), SPH_C32(0x2e1f9000), SPH_C32(0xb82cc5e9), + SPH_C32(0x171ac41b), SPH_C32(0x256d9011) }, + { SPH_C32(0x40527000), SPH_C32(0xb906b7ca), SPH_C32(0xcddd6500), + SPH_C32(0x4ef35967), SPH_C32(0xe5b69000), SPH_C32(0x280bf280), + SPH_C32(0xacc6301c), SPH_C32(0xf5993f70) }, + { SPH_C32(0x81174000), SPH_C32(0xe71224f2), SPH_C32(0x98bf5e74), + SPH_C32(0x1cc42f71), SPH_C32(0x7809a000), SPH_C32(0xc6773802), + SPH_C32(0x35c11760), SPH_C32(0xd6b6b8c6) }, + { SPH_C32(0xf5825000), SPH_C32(0xbd39628c), SPH_C32(0x1042435f), + SPH_C32(0x0222ade3), SPH_C32(0xb3a0a000), SPH_C32(0x56500f6b), + SPH_C32(0x8e1de367), SPH_C32(0x064217a7) }, + { SPH_C32(0x4abe4000), SPH_C32(0x7735139b), SPH_C32(0x2363aa73), + SPH_C32(0xcc308010), SPH_C32(0xc735b000), SPH_C32(0x0c7b4915), + SPH_C32(0x06e0fe4c), SPH_C32(0x18a49535) }, + { SPH_C32(0x3e2b5000), SPH_C32(0x2d1e55e5), SPH_C32(0xab9eb758), + SPH_C32(0xd2d60282), SPH_C32(0x0c9cb000), SPH_C32(0x9c5c7e7c), + SPH_C32(0xbd3c0a4b), SPH_C32(0xc8503a54) }, + { SPH_C32(0x683d6000), SPH_C32(0x5345a80e), SPH_C32(0x89456423), + SPH_C32(0x210d2a55), SPH_C32(0xef5aa000), SPH_C32(0xe63856d1), + SPH_C32(0x4278ff6f), SPH_C32(0x775ae607) }, + { SPH_C32(0x1ca87000), SPH_C32(0x096eee70), SPH_C32(0x01b87908), + SPH_C32(0x3feba8c7), SPH_C32(0x24f3a000), SPH_C32(0x761f61b8), + SPH_C32(0xf9a40b68), SPH_C32(0xa7ae4966) }, + { SPH_C32(0xa3946000), SPH_C32(0xc3629f67), SPH_C32(0x32999024), + SPH_C32(0xf1f98534), SPH_C32(0x5066b000), SPH_C32(0x2c3427c6), + SPH_C32(0x71591643), SPH_C32(0xb948cbf4) }, + { SPH_C32(0xd7017000), SPH_C32(0x9949d919), SPH_C32(0xba648d0f), + SPH_C32(0xef1f07a6), SPH_C32(0x9bcfb000), SPH_C32(0xbc1310af), + SPH_C32(0xca85e244), SPH_C32(0x69bc6495) }, + { SPH_C32(0xe2080000), SPH_C32(0xd7f9a9ec), SPH_C32(0xe679e16a), + SPH_C32(0x635fbdfc), SPH_C32(0x146bc000), SPH_C32(0x097803c5), + SPH_C32(0xde780a93), SPH_C32(0x84a52f51) }, + { SPH_C32(0x969d1000), SPH_C32(0x8dd2ef92), SPH_C32(0x6e84fc41), + SPH_C32(0x7db93f6e), SPH_C32(0xdfc2c000), SPH_C32(0x995f34ac), + SPH_C32(0x65a4fe94), SPH_C32(0x54518030) }, + { SPH_C32(0x29a10000), SPH_C32(0x47de9e85), SPH_C32(0x5da5156d), + SPH_C32(0xb3ab129d), SPH_C32(0xab57d000), SPH_C32(0xc37472d2), + SPH_C32(0xed59e3bf), SPH_C32(0x4ab702a2) }, + { SPH_C32(0x5d341000), SPH_C32(0x1df5d8fb), SPH_C32(0xd5580846), + SPH_C32(0xad4d900f), SPH_C32(0x60fed000), SPH_C32(0x535345bb), + SPH_C32(0x568517b8), SPH_C32(0x9a43adc3) }, + { SPH_C32(0x0b222000), SPH_C32(0x63ae2510), SPH_C32(0xf783db3d), + SPH_C32(0x5e96b8d8), SPH_C32(0x8338c000), SPH_C32(0x29376d16), + SPH_C32(0xa9c1e29c), SPH_C32(0x25497190) }, + { SPH_C32(0x7fb73000), SPH_C32(0x3985636e), SPH_C32(0x7f7ec616), + SPH_C32(0x40703a4a), SPH_C32(0x4891c000), SPH_C32(0xb9105a7f), + SPH_C32(0x121d169b), SPH_C32(0xf5bddef1) }, + { SPH_C32(0xc08b2000), SPH_C32(0xf3891279), SPH_C32(0x4c5f2f3a), + SPH_C32(0x8e6217b9), SPH_C32(0x3c04d000), SPH_C32(0xe33b1c01), + SPH_C32(0x9ae00bb0), SPH_C32(0xeb5b5c63) }, + { SPH_C32(0xb41e3000), SPH_C32(0xa9a25407), SPH_C32(0xc4a23211), + SPH_C32(0x9084952b), SPH_C32(0xf7add000), SPH_C32(0x731c2b68), + SPH_C32(0x213cffb7), SPH_C32(0x3baff302) }, + { SPH_C32(0x755b0000), SPH_C32(0xf7b6c73f), SPH_C32(0x91c00965), + SPH_C32(0xc2b3e33d), SPH_C32(0x6a12e000), SPH_C32(0x9d60e1ea), + SPH_C32(0xb83bd8cb), SPH_C32(0x188074b4) }, + { SPH_C32(0x01ce1000), SPH_C32(0xad9d8141), SPH_C32(0x193d144e), + SPH_C32(0xdc5561af), SPH_C32(0xa1bbe000), SPH_C32(0x0d47d683), + SPH_C32(0x03e72ccc), SPH_C32(0xc874dbd5) }, + { SPH_C32(0xbef20000), SPH_C32(0x6791f056), SPH_C32(0x2a1cfd62), + SPH_C32(0x12474c5c), SPH_C32(0xd52ef000), SPH_C32(0x576c90fd), + SPH_C32(0x8b1a31e7), SPH_C32(0xd6925947) }, + { SPH_C32(0xca671000), SPH_C32(0x3dbab628), SPH_C32(0xa2e1e049), + SPH_C32(0x0ca1cece), SPH_C32(0x1e87f000), SPH_C32(0xc74ba794), + SPH_C32(0x30c6c5e0), SPH_C32(0x0666f626) }, + { SPH_C32(0x9c712000), SPH_C32(0x43e14bc3), SPH_C32(0x803a3332), + SPH_C32(0xff7ae619), SPH_C32(0xfd41e000), SPH_C32(0xbd2f8f39), + SPH_C32(0xcf8230c4), SPH_C32(0xb96c2a75) }, + { SPH_C32(0xe8e43000), SPH_C32(0x19ca0dbd), SPH_C32(0x08c72e19), + SPH_C32(0xe19c648b), SPH_C32(0x36e8e000), SPH_C32(0x2d08b850), + SPH_C32(0x745ec4c3), SPH_C32(0x69988514) }, + { SPH_C32(0x57d82000), SPH_C32(0xd3c67caa), SPH_C32(0x3be6c735), + SPH_C32(0x2f8e4978), SPH_C32(0x427df000), SPH_C32(0x7723fe2e), + SPH_C32(0xfca3d9e8), SPH_C32(0x777e0786) }, + { SPH_C32(0x234d3000), SPH_C32(0x89ed3ad4), SPH_C32(0xb31bda1e), + SPH_C32(0x3168cbea), SPH_C32(0x89d4f000), SPH_C32(0xe704c947), + SPH_C32(0x477f2def), SPH_C32(0xa78aa8e7) }, + { SPH_C32(0xf0134000), SPH_C32(0x8cee7004), SPH_C32(0x6b832ec1), + SPH_C32(0xad69718e), SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), + SPH_C32(0x5afd9229), SPH_C32(0x94e42f6f) }, + { SPH_C32(0x84865000), SPH_C32(0xd6c5367a), SPH_C32(0xe37e33ea), + SPH_C32(0xb38ff31c), SPH_C32(0x3995c000), SPH_C32(0xd2ec0e89), + SPH_C32(0xe121662e), SPH_C32(0x4410800e) }, + { SPH_C32(0x3bba4000), SPH_C32(0x1cc9476d), SPH_C32(0xd05fdac6), + SPH_C32(0x7d9ddeef), SPH_C32(0x4d00d000), SPH_C32(0x88c748f7), + SPH_C32(0x69dc7b05), SPH_C32(0x5af6029c) }, + { SPH_C32(0x4f2f5000), SPH_C32(0x46e20113), SPH_C32(0x58a2c7ed), + SPH_C32(0x637b5c7d), SPH_C32(0x86a9d000), SPH_C32(0x18e07f9e), + SPH_C32(0xd2008f02), SPH_C32(0x8a02adfd) }, + { SPH_C32(0x19396000), SPH_C32(0x38b9fcf8), SPH_C32(0x7a791496), + SPH_C32(0x90a074aa), SPH_C32(0x656fc000), SPH_C32(0x62845733), + SPH_C32(0x2d447a26), SPH_C32(0x350871ae) }, + { SPH_C32(0x6dac7000), SPH_C32(0x6292ba86), SPH_C32(0xf28409bd), + SPH_C32(0x8e46f638), SPH_C32(0xaec6c000), SPH_C32(0xf2a3605a), + SPH_C32(0x96988e21), SPH_C32(0xe5fcdecf) }, + { SPH_C32(0xd2906000), SPH_C32(0xa89ecb91), SPH_C32(0xc1a5e091), + SPH_C32(0x4054dbcb), SPH_C32(0xda53d000), SPH_C32(0xa8882624), + SPH_C32(0x1e65930a), SPH_C32(0xfb1a5c5d) }, + { SPH_C32(0xa6057000), SPH_C32(0xf2b58def), SPH_C32(0x4958fdba), + SPH_C32(0x5eb25959), SPH_C32(0x11fad000), SPH_C32(0x38af114d), + SPH_C32(0xa5b9670d), SPH_C32(0x2beef33c) }, + { SPH_C32(0x67404000), SPH_C32(0xaca11ed7), SPH_C32(0x1c3ac6ce), + SPH_C32(0x0c852f4f), SPH_C32(0x8c45e000), SPH_C32(0xd6d3dbcf), + SPH_C32(0x3cbe4071), SPH_C32(0x08c1748a) }, + { SPH_C32(0x13d55000), SPH_C32(0xf68a58a9), SPH_C32(0x94c7dbe5), + SPH_C32(0x1263addd), SPH_C32(0x47ece000), SPH_C32(0x46f4eca6), + SPH_C32(0x8762b476), SPH_C32(0xd835dbeb) }, + { SPH_C32(0xace94000), SPH_C32(0x3c8629be), SPH_C32(0xa7e632c9), + SPH_C32(0xdc71802e), SPH_C32(0x3379f000), SPH_C32(0x1cdfaad8), + SPH_C32(0x0f9fa95d), SPH_C32(0xc6d35979) }, + { SPH_C32(0xd87c5000), SPH_C32(0x66ad6fc0), SPH_C32(0x2f1b2fe2), + SPH_C32(0xc29702bc), SPH_C32(0xf8d0f000), SPH_C32(0x8cf89db1), + SPH_C32(0xb4435d5a), SPH_C32(0x1627f618) }, + { SPH_C32(0x8e6a6000), SPH_C32(0x18f6922b), SPH_C32(0x0dc0fc99), + SPH_C32(0x314c2a6b), SPH_C32(0x1b16e000), SPH_C32(0xf69cb51c), + SPH_C32(0x4b07a87e), SPH_C32(0xa92d2a4b) }, + { SPH_C32(0xfaff7000), SPH_C32(0x42ddd455), SPH_C32(0x853de1b2), + SPH_C32(0x2faaa8f9), SPH_C32(0xd0bfe000), SPH_C32(0x66bb8275), + SPH_C32(0xf0db5c79), SPH_C32(0x79d9852a) }, + { SPH_C32(0x45c36000), SPH_C32(0x88d1a542), SPH_C32(0xb61c089e), + SPH_C32(0xe1b8850a), SPH_C32(0xa42af000), SPH_C32(0x3c90c40b), + SPH_C32(0x78264152), SPH_C32(0x673f07b8) }, + { SPH_C32(0x31567000), SPH_C32(0xd2fae33c), SPH_C32(0x3ee115b5), + SPH_C32(0xff5e0798), SPH_C32(0x6f83f000), SPH_C32(0xacb7f362), + SPH_C32(0xc3fab555), SPH_C32(0xb7cba8d9) }, + { SPH_C32(0xe0278000), SPH_C32(0x19dce008), SPH_C32(0xd7075d82), + SPH_C32(0x5ad2e31d), SPH_C32(0xe4788000), SPH_C32(0x859673c1), + SPH_C32(0xb5fb2452), SPH_C32(0x29cc5edf) }, + { SPH_C32(0x94b29000), SPH_C32(0x43f7a676), SPH_C32(0x5ffa40a9), + SPH_C32(0x4434618f), SPH_C32(0x2fd18000), SPH_C32(0x15b144a8), + SPH_C32(0x0e27d055), SPH_C32(0xf938f1be) }, + { SPH_C32(0x2b8e8000), SPH_C32(0x89fbd761), SPH_C32(0x6cdba985), + SPH_C32(0x8a264c7c), SPH_C32(0x5b449000), SPH_C32(0x4f9a02d6), + SPH_C32(0x86dacd7e), SPH_C32(0xe7de732c) }, + { SPH_C32(0x5f1b9000), SPH_C32(0xd3d0911f), SPH_C32(0xe426b4ae), + SPH_C32(0x94c0ceee), SPH_C32(0x90ed9000), SPH_C32(0xdfbd35bf), + SPH_C32(0x3d063979), SPH_C32(0x372adc4d) }, + { SPH_C32(0x090da000), SPH_C32(0xad8b6cf4), SPH_C32(0xc6fd67d5), + SPH_C32(0x671be639), SPH_C32(0x732b8000), SPH_C32(0xa5d91d12), + SPH_C32(0xc242cc5d), SPH_C32(0x8820001e) }, + { SPH_C32(0x7d98b000), SPH_C32(0xf7a02a8a), SPH_C32(0x4e007afe), + SPH_C32(0x79fd64ab), SPH_C32(0xb8828000), SPH_C32(0x35fe2a7b), + SPH_C32(0x799e385a), SPH_C32(0x58d4af7f) }, + { SPH_C32(0xc2a4a000), SPH_C32(0x3dac5b9d), SPH_C32(0x7d2193d2), + SPH_C32(0xb7ef4958), SPH_C32(0xcc179000), SPH_C32(0x6fd56c05), + SPH_C32(0xf1632571), SPH_C32(0x46322ded) }, + { SPH_C32(0xb631b000), SPH_C32(0x67871de3), SPH_C32(0xf5dc8ef9), + SPH_C32(0xa909cbca), SPH_C32(0x07be9000), SPH_C32(0xfff25b6c), + SPH_C32(0x4abfd176), SPH_C32(0x96c6828c) }, + { SPH_C32(0x77748000), SPH_C32(0x39938edb), SPH_C32(0xa0beb58d), + SPH_C32(0xfb3ebddc), SPH_C32(0x9a01a000), SPH_C32(0x118e91ee), + SPH_C32(0xd3b8f60a), SPH_C32(0xb5e9053a) }, + { SPH_C32(0x03e19000), SPH_C32(0x63b8c8a5), SPH_C32(0x2843a8a6), + SPH_C32(0xe5d83f4e), SPH_C32(0x51a8a000), SPH_C32(0x81a9a687), + SPH_C32(0x6864020d), SPH_C32(0x651daa5b) }, + { SPH_C32(0xbcdd8000), SPH_C32(0xa9b4b9b2), SPH_C32(0x1b62418a), + SPH_C32(0x2bca12bd), SPH_C32(0x253db000), SPH_C32(0xdb82e0f9), + SPH_C32(0xe0991f26), SPH_C32(0x7bfb28c9) }, + { SPH_C32(0xc8489000), SPH_C32(0xf39fffcc), SPH_C32(0x939f5ca1), + SPH_C32(0x352c902f), SPH_C32(0xee94b000), SPH_C32(0x4ba5d790), + SPH_C32(0x5b45eb21), SPH_C32(0xab0f87a8) }, + { SPH_C32(0x9e5ea000), SPH_C32(0x8dc40227), SPH_C32(0xb1448fda), + SPH_C32(0xc6f7b8f8), SPH_C32(0x0d52a000), SPH_C32(0x31c1ff3d), + SPH_C32(0xa4011e05), SPH_C32(0x14055bfb) }, + { SPH_C32(0xeacbb000), SPH_C32(0xd7ef4459), SPH_C32(0x39b992f1), + SPH_C32(0xd8113a6a), SPH_C32(0xc6fba000), SPH_C32(0xa1e6c854), + SPH_C32(0x1fddea02), SPH_C32(0xc4f1f49a) }, + { SPH_C32(0x55f7a000), SPH_C32(0x1de3354e), SPH_C32(0x0a987bdd), + SPH_C32(0x16031799), SPH_C32(0xb26eb000), SPH_C32(0xfbcd8e2a), + SPH_C32(0x9720f729), SPH_C32(0xda177608) }, + { SPH_C32(0x2162b000), SPH_C32(0x47c87330), SPH_C32(0x826566f6), + SPH_C32(0x08e5950b), SPH_C32(0x79c7b000), SPH_C32(0x6beab943), + SPH_C32(0x2cfc032e), SPH_C32(0x0ae3d969) }, + { SPH_C32(0xf23cc000), SPH_C32(0x42cb39e0), SPH_C32(0x5afd9229), + SPH_C32(0x94e42f6f), SPH_C32(0x022f8000), SPH_C32(0xce2549e4), + SPH_C32(0x317ebce8), SPH_C32(0x398d5ee1) }, + { SPH_C32(0x86a9d000), SPH_C32(0x18e07f9e), SPH_C32(0xd2008f02), + SPH_C32(0x8a02adfd), SPH_C32(0xc9868000), SPH_C32(0x5e027e8d), + SPH_C32(0x8aa248ef), SPH_C32(0xe979f180) }, + { SPH_C32(0x3995c000), SPH_C32(0xd2ec0e89), SPH_C32(0xe121662e), + SPH_C32(0x4410800e), SPH_C32(0xbd139000), SPH_C32(0x042938f3), + SPH_C32(0x025f55c4), SPH_C32(0xf79f7312) }, + { SPH_C32(0x4d00d000), SPH_C32(0x88c748f7), SPH_C32(0x69dc7b05), + SPH_C32(0x5af6029c), SPH_C32(0x76ba9000), SPH_C32(0x940e0f9a), + SPH_C32(0xb983a1c3), SPH_C32(0x276bdc73) }, + { SPH_C32(0x1b16e000), SPH_C32(0xf69cb51c), SPH_C32(0x4b07a87e), + SPH_C32(0xa92d2a4b), SPH_C32(0x957c8000), SPH_C32(0xee6a2737), + SPH_C32(0x46c754e7), SPH_C32(0x98610020) }, + { SPH_C32(0x6f83f000), SPH_C32(0xacb7f362), SPH_C32(0xc3fab555), + SPH_C32(0xb7cba8d9), SPH_C32(0x5ed58000), SPH_C32(0x7e4d105e), + SPH_C32(0xfd1ba0e0), SPH_C32(0x4895af41) }, + { SPH_C32(0xd0bfe000), SPH_C32(0x66bb8275), SPH_C32(0xf0db5c79), + SPH_C32(0x79d9852a), SPH_C32(0x2a409000), SPH_C32(0x24665620), + SPH_C32(0x75e6bdcb), SPH_C32(0x56732dd3) }, + { SPH_C32(0xa42af000), SPH_C32(0x3c90c40b), SPH_C32(0x78264152), + SPH_C32(0x673f07b8), SPH_C32(0xe1e99000), SPH_C32(0xb4416149), + SPH_C32(0xce3a49cc), SPH_C32(0x868782b2) }, + { SPH_C32(0x656fc000), SPH_C32(0x62845733), SPH_C32(0x2d447a26), + SPH_C32(0x350871ae), SPH_C32(0x7c56a000), SPH_C32(0x5a3dabcb), + SPH_C32(0x573d6eb0), SPH_C32(0xa5a80504) }, + { SPH_C32(0x11fad000), SPH_C32(0x38af114d), SPH_C32(0xa5b9670d), + SPH_C32(0x2beef33c), SPH_C32(0xb7ffa000), SPH_C32(0xca1a9ca2), + SPH_C32(0xece19ab7), SPH_C32(0x755caa65) }, + { SPH_C32(0xaec6c000), SPH_C32(0xf2a3605a), SPH_C32(0x96988e21), + SPH_C32(0xe5fcdecf), SPH_C32(0xc36ab000), SPH_C32(0x9031dadc), + SPH_C32(0x641c879c), SPH_C32(0x6bba28f7) }, + { SPH_C32(0xda53d000), SPH_C32(0xa8882624), SPH_C32(0x1e65930a), + SPH_C32(0xfb1a5c5d), SPH_C32(0x08c3b000), SPH_C32(0x0016edb5), + SPH_C32(0xdfc0739b), SPH_C32(0xbb4e8796) }, + { SPH_C32(0x8c45e000), SPH_C32(0xd6d3dbcf), SPH_C32(0x3cbe4071), + SPH_C32(0x08c1748a), SPH_C32(0xeb05a000), SPH_C32(0x7a72c518), + SPH_C32(0x208486bf), SPH_C32(0x04445bc5) }, + { SPH_C32(0xf8d0f000), SPH_C32(0x8cf89db1), SPH_C32(0xb4435d5a), + SPH_C32(0x1627f618), SPH_C32(0x20aca000), SPH_C32(0xea55f271), + SPH_C32(0x9b5872b8), SPH_C32(0xd4b0f4a4) }, + { SPH_C32(0x47ece000), SPH_C32(0x46f4eca6), SPH_C32(0x8762b476), + SPH_C32(0xd835dbeb), SPH_C32(0x5439b000), SPH_C32(0xb07eb40f), + SPH_C32(0x13a56f93), SPH_C32(0xca567636) }, + { SPH_C32(0x3379f000), SPH_C32(0x1cdfaad8), SPH_C32(0x0f9fa95d), + SPH_C32(0xc6d35979), SPH_C32(0x9f90b000), SPH_C32(0x20598366), + SPH_C32(0xa8799b94), SPH_C32(0x1aa2d957) }, + { SPH_C32(0x06708000), SPH_C32(0x526fda2d), SPH_C32(0x5382c538), + SPH_C32(0x4a93e323), SPH_C32(0x1034c000), SPH_C32(0x9532900c), + SPH_C32(0xbc847343), SPH_C32(0xf7bb9293) }, + { SPH_C32(0x72e59000), SPH_C32(0x08449c53), SPH_C32(0xdb7fd813), + SPH_C32(0x547561b1), SPH_C32(0xdb9dc000), SPH_C32(0x0515a765), + SPH_C32(0x07588744), SPH_C32(0x274f3df2) }, + { SPH_C32(0xcdd98000), SPH_C32(0xc248ed44), SPH_C32(0xe85e313f), + SPH_C32(0x9a674c42), SPH_C32(0xaf08d000), SPH_C32(0x5f3ee11b), + SPH_C32(0x8fa59a6f), SPH_C32(0x39a9bf60) }, + { SPH_C32(0xb94c9000), SPH_C32(0x9863ab3a), SPH_C32(0x60a32c14), + SPH_C32(0x8481ced0), SPH_C32(0x64a1d000), SPH_C32(0xcf19d672), + SPH_C32(0x34796e68), SPH_C32(0xe95d1001) }, + { SPH_C32(0xef5aa000), SPH_C32(0xe63856d1), SPH_C32(0x4278ff6f), + SPH_C32(0x775ae607), SPH_C32(0x8767c000), SPH_C32(0xb57dfedf), + SPH_C32(0xcb3d9b4c), SPH_C32(0x5657cc52) }, + { SPH_C32(0x9bcfb000), SPH_C32(0xbc1310af), SPH_C32(0xca85e244), + SPH_C32(0x69bc6495), SPH_C32(0x4ccec000), SPH_C32(0x255ac9b6), + SPH_C32(0x70e16f4b), SPH_C32(0x86a36333) }, + { SPH_C32(0x24f3a000), SPH_C32(0x761f61b8), SPH_C32(0xf9a40b68), + SPH_C32(0xa7ae4966), SPH_C32(0x385bd000), SPH_C32(0x7f718fc8), + SPH_C32(0xf81c7260), SPH_C32(0x9845e1a1) }, + { SPH_C32(0x5066b000), SPH_C32(0x2c3427c6), SPH_C32(0x71591643), + SPH_C32(0xb948cbf4), SPH_C32(0xf3f2d000), SPH_C32(0xef56b8a1), + SPH_C32(0x43c08667), SPH_C32(0x48b14ec0) }, + { SPH_C32(0x91238000), SPH_C32(0x7220b4fe), SPH_C32(0x243b2d37), + SPH_C32(0xeb7fbde2), SPH_C32(0x6e4de000), SPH_C32(0x012a7223), + SPH_C32(0xdac7a11b), SPH_C32(0x6b9ec976) }, + { SPH_C32(0xe5b69000), SPH_C32(0x280bf280), SPH_C32(0xacc6301c), + SPH_C32(0xf5993f70), SPH_C32(0xa5e4e000), SPH_C32(0x910d454a), + SPH_C32(0x611b551c), SPH_C32(0xbb6a6617) }, + { SPH_C32(0x5a8a8000), SPH_C32(0xe2078397), SPH_C32(0x9fe7d930), + SPH_C32(0x3b8b1283), SPH_C32(0xd171f000), SPH_C32(0xcb260334), + SPH_C32(0xe9e64837), SPH_C32(0xa58ce485) }, + { SPH_C32(0x2e1f9000), SPH_C32(0xb82cc5e9), SPH_C32(0x171ac41b), + SPH_C32(0x256d9011), SPH_C32(0x1ad8f000), SPH_C32(0x5b01345d), + SPH_C32(0x523abc30), SPH_C32(0x75784be4) }, + { SPH_C32(0x7809a000), SPH_C32(0xc6773802), SPH_C32(0x35c11760), + SPH_C32(0xd6b6b8c6), SPH_C32(0xf91ee000), SPH_C32(0x21651cf0), + SPH_C32(0xad7e4914), SPH_C32(0xca7297b7) }, + { SPH_C32(0x0c9cb000), SPH_C32(0x9c5c7e7c), SPH_C32(0xbd3c0a4b), + SPH_C32(0xc8503a54), SPH_C32(0x32b7e000), SPH_C32(0xb1422b99), + SPH_C32(0x16a2bd13), SPH_C32(0x1a8638d6) }, + { SPH_C32(0xb3a0a000), SPH_C32(0x56500f6b), SPH_C32(0x8e1de367), + SPH_C32(0x064217a7), SPH_C32(0x4622f000), SPH_C32(0xeb696de7), + SPH_C32(0x9e5fa038), SPH_C32(0x0460ba44) }, + { SPH_C32(0xc735b000), SPH_C32(0x0c7b4915), SPH_C32(0x06e0fe4c), + SPH_C32(0x18a49535), SPH_C32(0x8d8bf000), SPH_C32(0x7b4e5a8e), + SPH_C32(0x2583543f), SPH_C32(0xd4941525) }, + { SPH_C32(0x146bc000), SPH_C32(0x097803c5), SPH_C32(0xde780a93), + SPH_C32(0x84a52f51), SPH_C32(0xf663c000), SPH_C32(0xde81aa29), + SPH_C32(0x3801ebf9), SPH_C32(0xe7fa92ad) }, + { SPH_C32(0x60fed000), SPH_C32(0x535345bb), SPH_C32(0x568517b8), + SPH_C32(0x9a43adc3), SPH_C32(0x3dcac000), SPH_C32(0x4ea69d40), + SPH_C32(0x83dd1ffe), SPH_C32(0x370e3dcc) }, + { SPH_C32(0xdfc2c000), SPH_C32(0x995f34ac), SPH_C32(0x65a4fe94), + SPH_C32(0x54518030), SPH_C32(0x495fd000), SPH_C32(0x148ddb3e), + SPH_C32(0x0b2002d5), SPH_C32(0x29e8bf5e) }, + { SPH_C32(0xab57d000), SPH_C32(0xc37472d2), SPH_C32(0xed59e3bf), + SPH_C32(0x4ab702a2), SPH_C32(0x82f6d000), SPH_C32(0x84aaec57), + SPH_C32(0xb0fcf6d2), SPH_C32(0xf91c103f) }, + { SPH_C32(0xfd41e000), SPH_C32(0xbd2f8f39), SPH_C32(0xcf8230c4), + SPH_C32(0xb96c2a75), SPH_C32(0x6130c000), SPH_C32(0xfecec4fa), + SPH_C32(0x4fb803f6), SPH_C32(0x4616cc6c) }, + { SPH_C32(0x89d4f000), SPH_C32(0xe704c947), SPH_C32(0x477f2def), + SPH_C32(0xa78aa8e7), SPH_C32(0xaa99c000), SPH_C32(0x6ee9f393), + SPH_C32(0xf464f7f1), SPH_C32(0x96e2630d) }, + { SPH_C32(0x36e8e000), SPH_C32(0x2d08b850), SPH_C32(0x745ec4c3), + SPH_C32(0x69988514), SPH_C32(0xde0cd000), SPH_C32(0x34c2b5ed), + SPH_C32(0x7c99eada), SPH_C32(0x8804e19f) }, + { SPH_C32(0x427df000), SPH_C32(0x7723fe2e), SPH_C32(0xfca3d9e8), + SPH_C32(0x777e0786), SPH_C32(0x15a5d000), SPH_C32(0xa4e58284), + SPH_C32(0xc7451edd), SPH_C32(0x58f04efe) }, + { SPH_C32(0x8338c000), SPH_C32(0x29376d16), SPH_C32(0xa9c1e29c), + SPH_C32(0x25497190), SPH_C32(0x881ae000), SPH_C32(0x4a994806), + SPH_C32(0x5e4239a1), SPH_C32(0x7bdfc948) }, + { SPH_C32(0xf7add000), SPH_C32(0x731c2b68), SPH_C32(0x213cffb7), + SPH_C32(0x3baff302), SPH_C32(0x43b3e000), SPH_C32(0xdabe7f6f), + SPH_C32(0xe59ecda6), SPH_C32(0xab2b6629) }, + { SPH_C32(0x4891c000), SPH_C32(0xb9105a7f), SPH_C32(0x121d169b), + SPH_C32(0xf5bddef1), SPH_C32(0x3726f000), SPH_C32(0x80953911), + SPH_C32(0x6d63d08d), SPH_C32(0xb5cde4bb) }, + { SPH_C32(0x3c04d000), SPH_C32(0xe33b1c01), SPH_C32(0x9ae00bb0), + SPH_C32(0xeb5b5c63), SPH_C32(0xfc8ff000), SPH_C32(0x10b20e78), + SPH_C32(0xd6bf248a), SPH_C32(0x65394bda) }, + { SPH_C32(0x6a12e000), SPH_C32(0x9d60e1ea), SPH_C32(0xb83bd8cb), + SPH_C32(0x188074b4), SPH_C32(0x1f49e000), SPH_C32(0x6ad626d5), + SPH_C32(0x29fbd1ae), SPH_C32(0xda339789) }, + { SPH_C32(0x1e87f000), SPH_C32(0xc74ba794), SPH_C32(0x30c6c5e0), + SPH_C32(0x0666f626), SPH_C32(0xd4e0e000), SPH_C32(0xfaf111bc), + SPH_C32(0x922725a9), SPH_C32(0x0ac738e8) }, + { SPH_C32(0xa1bbe000), SPH_C32(0x0d47d683), SPH_C32(0x03e72ccc), + SPH_C32(0xc874dbd5), SPH_C32(0xa075f000), SPH_C32(0xa0da57c2), + SPH_C32(0x1ada3882), SPH_C32(0x1421ba7a) }, + { SPH_C32(0xd52ef000), SPH_C32(0x576c90fd), SPH_C32(0x8b1a31e7), + SPH_C32(0xd6925947), SPH_C32(0x6bdcf000), SPH_C32(0x30fd60ab), + SPH_C32(0xa106cc85), SPH_C32(0xc4d5151b) } +}; + +static const sph_u32 T256_8[256][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), SPH_C32(0x8589d8ab), + SPH_C32(0xe6c46464), SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), + SPH_C32(0xa29d1297), SPH_C32(0x6ee56854) }, + { SPH_C32(0x734c0000), SPH_C32(0x956fa7d6), SPH_C32(0xa29d1297), + SPH_C32(0x6ee56854), SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), + SPH_C32(0x2714ca3c), SPH_C32(0x88210c30) }, + { SPH_C32(0xc4e80100), SPH_C32(0x1f70960e), SPH_C32(0x2714ca3c), + SPH_C32(0x88210c30), SPH_C32(0xb7a40100), SPH_C32(0x8a1f31d8), + SPH_C32(0x8589d8ab), SPH_C32(0xe6c46464) }, + { SPH_C32(0xa7b80200), SPH_C32(0x1f128433), SPH_C32(0x60e5f9f2), + SPH_C32(0x9e147576), SPH_C32(0xee260000), SPH_C32(0x124b683e), + SPH_C32(0x80c2d68f), SPH_C32(0x3bf3ab2c) }, + { SPH_C32(0x101c0300), SPH_C32(0x950db5eb), SPH_C32(0xe56c2159), + SPH_C32(0x78d01112), SPH_C32(0x9d6a0000), SPH_C32(0x8724cfe8), + SPH_C32(0x225fc418), SPH_C32(0x5516c378) }, + { SPH_C32(0xd4f40200), SPH_C32(0x8a7d23e5), SPH_C32(0xc278eb65), + SPH_C32(0xf0f11d22), SPH_C32(0x2ace0100), SPH_C32(0x0d3bfe30), + SPH_C32(0xa7d61cb3), SPH_C32(0xb3d2a71c) }, + { SPH_C32(0x63500300), SPH_C32(0x0062123d), SPH_C32(0x47f133ce), + SPH_C32(0x16357946), SPH_C32(0x59820100), SPH_C32(0x985459e6), + SPH_C32(0x054b0e24), SPH_C32(0xdd37cf48) }, + { SPH_C32(0xee260000), SPH_C32(0x124b683e), SPH_C32(0x80c2d68f), + SPH_C32(0x3bf3ab2c), SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), + SPH_C32(0xe0272f7d), SPH_C32(0xa5e7de5a) }, + { SPH_C32(0x59820100), SPH_C32(0x985459e6), SPH_C32(0x054b0e24), + SPH_C32(0xdd37cf48), SPH_C32(0x3ad20200), SPH_C32(0x98364bdb), + SPH_C32(0x42ba3dea), SPH_C32(0xcb02b60e) }, + { SPH_C32(0x9d6a0000), SPH_C32(0x8724cfe8), SPH_C32(0x225fc418), + SPH_C32(0x5516c378), SPH_C32(0x8d760300), SPH_C32(0x12297a03), + SPH_C32(0xc733e541), SPH_C32(0x2dc6d26a) }, + { SPH_C32(0x2ace0100), SPH_C32(0x0d3bfe30), SPH_C32(0xa7d61cb3), + SPH_C32(0xb3d2a71c), SPH_C32(0xfe3a0300), SPH_C32(0x8746ddd5), + SPH_C32(0x65aef7d6), SPH_C32(0x4323ba3e) }, + { SPH_C32(0x499e0200), SPH_C32(0x0d59ec0d), SPH_C32(0xe0272f7d), + SPH_C32(0xa5e7de5a), SPH_C32(0xa7b80200), SPH_C32(0x1f128433), + SPH_C32(0x60e5f9f2), SPH_C32(0x9e147576) }, + { SPH_C32(0xfe3a0300), SPH_C32(0x8746ddd5), SPH_C32(0x65aef7d6), + SPH_C32(0x4323ba3e), SPH_C32(0xd4f40200), SPH_C32(0x8a7d23e5), + SPH_C32(0xc278eb65), SPH_C32(0xf0f11d22) }, + { SPH_C32(0x3ad20200), SPH_C32(0x98364bdb), SPH_C32(0x42ba3dea), + SPH_C32(0xcb02b60e), SPH_C32(0x63500300), SPH_C32(0x0062123d), + SPH_C32(0x47f133ce), SPH_C32(0x16357946) }, + { SPH_C32(0x8d760300), SPH_C32(0x12297a03), SPH_C32(0xc733e541), + SPH_C32(0x2dc6d26a), SPH_C32(0x101c0300), SPH_C32(0x950db5eb), + SPH_C32(0xe56c2159), SPH_C32(0x78d01112) }, + { SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), SPH_C32(0x6fc548e1), + SPH_C32(0x898d2cd6), SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), + SPH_C32(0x6a72e5bb), SPH_C32(0x247febe6) }, + { SPH_C32(0x389a0500), SPH_C32(0x8782f9af), SPH_C32(0xea4c904a), + SPH_C32(0x6f4948b2), SPH_C32(0x67f10000), SPH_C32(0xbad59029), + SPH_C32(0xc8eff72c), SPH_C32(0x4a9a83b2) }, + { SPH_C32(0xfc720400), SPH_C32(0x98f26fa1), SPH_C32(0xcd585a76), + SPH_C32(0xe7684482), SPH_C32(0xd0550100), SPH_C32(0x30caa1f1), + SPH_C32(0x4d662f87), SPH_C32(0xac5ee7d6) }, + { SPH_C32(0x4bd60500), SPH_C32(0x12ed5e79), SPH_C32(0x48d182dd), + SPH_C32(0x01ac20e6), SPH_C32(0xa3190100), SPH_C32(0xa5a50627), + SPH_C32(0xeffb3d10), SPH_C32(0xc2bb8f82) }, + { SPH_C32(0x28860600), SPH_C32(0x128f4c44), SPH_C32(0x0f20b113), + SPH_C32(0x179959a0), SPH_C32(0xfa9b0000), SPH_C32(0x3df15fc1), + SPH_C32(0xeab03334), SPH_C32(0x1f8c40ca) }, + { SPH_C32(0x9f220700), SPH_C32(0x98907d9c), SPH_C32(0x8aa969b8), + SPH_C32(0xf15d3dc4), SPH_C32(0x89d70000), SPH_C32(0xa89ef817), + SPH_C32(0x482d21a3), SPH_C32(0x7169289e) }, + { SPH_C32(0x5bca0600), SPH_C32(0x87e0eb92), SPH_C32(0xadbda384), + SPH_C32(0x797c31f4), SPH_C32(0x3e730100), SPH_C32(0x2281c9cf), + SPH_C32(0xcda4f908), SPH_C32(0x97ad4cfa) }, + { SPH_C32(0xec6e0700), SPH_C32(0x0dffda4a), SPH_C32(0x28347b2f), + SPH_C32(0x9fb85590), SPH_C32(0x4d3f0100), SPH_C32(0xb7ee6e19), + SPH_C32(0x6f39eb9f), SPH_C32(0xf94824ae) }, + { SPH_C32(0x61180400), SPH_C32(0x1fd6a049), SPH_C32(0xef079e6e), + SPH_C32(0xb27e87fa), SPH_C32(0x5d230200), SPH_C32(0x22e3dbf2), + SPH_C32(0x8a55cac6), SPH_C32(0x819835bc) }, + { SPH_C32(0xd6bc0500), SPH_C32(0x95c99191), SPH_C32(0x6a8e46c5), + SPH_C32(0x54bae39e), SPH_C32(0x2e6f0200), SPH_C32(0xb78c7c24), + SPH_C32(0x28c8d851), SPH_C32(0xef7d5de8) }, + { SPH_C32(0x12540400), SPH_C32(0x8ab9079f), SPH_C32(0x4d9a8cf9), + SPH_C32(0xdc9befae), SPH_C32(0x99cb0300), SPH_C32(0x3d934dfc), + SPH_C32(0xad4100fa), SPH_C32(0x09b9398c) }, + { SPH_C32(0xa5f00500), SPH_C32(0x00a63647), SPH_C32(0xc8135452), + SPH_C32(0x3a5f8bca), SPH_C32(0xea870300), SPH_C32(0xa8fcea2a), + SPH_C32(0x0fdc126d), SPH_C32(0x675c51d8) }, + { SPH_C32(0xc6a00600), SPH_C32(0x00c4247a), SPH_C32(0x8fe2679c), + SPH_C32(0x2c6af28c), SPH_C32(0xb3050200), SPH_C32(0x30a8b3cc), + SPH_C32(0x0a971c49), SPH_C32(0xba6b9e90) }, + { SPH_C32(0x71040700), SPH_C32(0x8adb15a2), SPH_C32(0x0a6bbf37), + SPH_C32(0xcaae96e8), SPH_C32(0xc0490200), SPH_C32(0xa5c7141a), + SPH_C32(0xa80a0ede), SPH_C32(0xd48ef6c4) }, + { SPH_C32(0xb5ec0600), SPH_C32(0x95ab83ac), SPH_C32(0x2d7f750b), + SPH_C32(0x428f9ad8), SPH_C32(0x77ed0300), SPH_C32(0x2fd825c2), + SPH_C32(0x2d83d675), SPH_C32(0x324a92a0) }, + { SPH_C32(0x02480700), SPH_C32(0x1fb4b274), SPH_C32(0xa8f6ada0), + SPH_C32(0xa44bfebc), SPH_C32(0x04a10300), SPH_C32(0xbab78214), + SPH_C32(0x8f1ec4e2), SPH_C32(0x5caffaf4) }, + { SPH_C32(0x14bd0000), SPH_C32(0x2fba37ff), SPH_C32(0x6a72e5bb), + SPH_C32(0x247febe6), SPH_C32(0x9b830400), SPH_C32(0x2227ff88), + SPH_C32(0x05b7ad5a), SPH_C32(0xadf2c730) }, + { SPH_C32(0xa3190100), SPH_C32(0xa5a50627), SPH_C32(0xeffb3d10), + SPH_C32(0xc2bb8f82), SPH_C32(0xe8cf0400), SPH_C32(0xb748585e), + SPH_C32(0xa72abfcd), SPH_C32(0xc317af64) }, + { SPH_C32(0x67f10000), SPH_C32(0xbad59029), SPH_C32(0xc8eff72c), + SPH_C32(0x4a9a83b2), SPH_C32(0x5f6b0500), SPH_C32(0x3d576986), + SPH_C32(0x22a36766), SPH_C32(0x25d3cb00) }, + { SPH_C32(0xd0550100), SPH_C32(0x30caa1f1), SPH_C32(0x4d662f87), + SPH_C32(0xac5ee7d6), SPH_C32(0x2c270500), SPH_C32(0xa838ce50), + SPH_C32(0x803e75f1), SPH_C32(0x4b36a354) }, + { SPH_C32(0xb3050200), SPH_C32(0x30a8b3cc), SPH_C32(0x0a971c49), + SPH_C32(0xba6b9e90), SPH_C32(0x75a50400), SPH_C32(0x306c97b6), + SPH_C32(0x85757bd5), SPH_C32(0x96016c1c) }, + { SPH_C32(0x04a10300), SPH_C32(0xbab78214), SPH_C32(0x8f1ec4e2), + SPH_C32(0x5caffaf4), SPH_C32(0x06e90400), SPH_C32(0xa5033060), + SPH_C32(0x27e86942), SPH_C32(0xf8e40448) }, + { SPH_C32(0xc0490200), SPH_C32(0xa5c7141a), SPH_C32(0xa80a0ede), + SPH_C32(0xd48ef6c4), SPH_C32(0xb14d0500), SPH_C32(0x2f1c01b8), + SPH_C32(0xa261b1e9), SPH_C32(0x1e20602c) }, + { SPH_C32(0x77ed0300), SPH_C32(0x2fd825c2), SPH_C32(0x2d83d675), + SPH_C32(0x324a92a0), SPH_C32(0xc2010500), SPH_C32(0xba73a66e), + SPH_C32(0x00fca37e), SPH_C32(0x70c50878) }, + { SPH_C32(0xfa9b0000), SPH_C32(0x3df15fc1), SPH_C32(0xeab03334), + SPH_C32(0x1f8c40ca), SPH_C32(0xd21d0600), SPH_C32(0x2f7e1385), + SPH_C32(0xe5908227), SPH_C32(0x0815196a) }, + { SPH_C32(0x4d3f0100), SPH_C32(0xb7ee6e19), SPH_C32(0x6f39eb9f), + SPH_C32(0xf94824ae), SPH_C32(0xa1510600), SPH_C32(0xba11b453), + SPH_C32(0x470d90b0), SPH_C32(0x66f0713e) }, + { SPH_C32(0x89d70000), SPH_C32(0xa89ef817), SPH_C32(0x482d21a3), + SPH_C32(0x7169289e), SPH_C32(0x16f50700), SPH_C32(0x300e858b), + SPH_C32(0xc284481b), SPH_C32(0x8034155a) }, + { SPH_C32(0x3e730100), SPH_C32(0x2281c9cf), SPH_C32(0xcda4f908), + SPH_C32(0x97ad4cfa), SPH_C32(0x65b90700), SPH_C32(0xa561225d), + SPH_C32(0x60195a8c), SPH_C32(0xeed17d0e) }, + { SPH_C32(0x5d230200), SPH_C32(0x22e3dbf2), SPH_C32(0x8a55cac6), + SPH_C32(0x819835bc), SPH_C32(0x3c3b0600), SPH_C32(0x3d357bbb), + SPH_C32(0x655254a8), SPH_C32(0x33e6b246) }, + { SPH_C32(0xea870300), SPH_C32(0xa8fcea2a), SPH_C32(0x0fdc126d), + SPH_C32(0x675c51d8), SPH_C32(0x4f770600), SPH_C32(0xa85adc6d), + SPH_C32(0xc7cf463f), SPH_C32(0x5d03da12) }, + { SPH_C32(0x2e6f0200), SPH_C32(0xb78c7c24), SPH_C32(0x28c8d851), + SPH_C32(0xef7d5de8), SPH_C32(0xf8d30700), SPH_C32(0x2245edb5), + SPH_C32(0x42469e94), SPH_C32(0xbbc7be76) }, + { SPH_C32(0x99cb0300), SPH_C32(0x3d934dfc), SPH_C32(0xad4100fa), + SPH_C32(0x09b9398c), SPH_C32(0x8b9f0700), SPH_C32(0xb72a4a63), + SPH_C32(0xe0db8c03), SPH_C32(0xd522d622) }, + { SPH_C32(0x9b830400), SPH_C32(0x2227ff88), SPH_C32(0x05b7ad5a), + SPH_C32(0xadf2c730), SPH_C32(0x8f3e0400), SPH_C32(0x0d9dc877), + SPH_C32(0x6fc548e1), SPH_C32(0x898d2cd6) }, + { SPH_C32(0x2c270500), SPH_C32(0xa838ce50), SPH_C32(0x803e75f1), + SPH_C32(0x4b36a354), SPH_C32(0xfc720400), SPH_C32(0x98f26fa1), + SPH_C32(0xcd585a76), SPH_C32(0xe7684482) }, + { SPH_C32(0xe8cf0400), SPH_C32(0xb748585e), SPH_C32(0xa72abfcd), + SPH_C32(0xc317af64), SPH_C32(0x4bd60500), SPH_C32(0x12ed5e79), + SPH_C32(0x48d182dd), SPH_C32(0x01ac20e6) }, + { SPH_C32(0x5f6b0500), SPH_C32(0x3d576986), SPH_C32(0x22a36766), + SPH_C32(0x25d3cb00), SPH_C32(0x389a0500), SPH_C32(0x8782f9af), + SPH_C32(0xea4c904a), SPH_C32(0x6f4948b2) }, + { SPH_C32(0x3c3b0600), SPH_C32(0x3d357bbb), SPH_C32(0x655254a8), + SPH_C32(0x33e6b246), SPH_C32(0x61180400), SPH_C32(0x1fd6a049), + SPH_C32(0xef079e6e), SPH_C32(0xb27e87fa) }, + { SPH_C32(0x8b9f0700), SPH_C32(0xb72a4a63), SPH_C32(0xe0db8c03), + SPH_C32(0xd522d622), SPH_C32(0x12540400), SPH_C32(0x8ab9079f), + SPH_C32(0x4d9a8cf9), SPH_C32(0xdc9befae) }, + { SPH_C32(0x4f770600), SPH_C32(0xa85adc6d), SPH_C32(0xc7cf463f), + SPH_C32(0x5d03da12), SPH_C32(0xa5f00500), SPH_C32(0x00a63647), + SPH_C32(0xc8135452), SPH_C32(0x3a5f8bca) }, + { SPH_C32(0xf8d30700), SPH_C32(0x2245edb5), SPH_C32(0x42469e94), + SPH_C32(0xbbc7be76), SPH_C32(0xd6bc0500), SPH_C32(0x95c99191), + SPH_C32(0x6a8e46c5), SPH_C32(0x54bae39e) }, + { SPH_C32(0x75a50400), SPH_C32(0x306c97b6), SPH_C32(0x85757bd5), + SPH_C32(0x96016c1c), SPH_C32(0xc6a00600), SPH_C32(0x00c4247a), + SPH_C32(0x8fe2679c), SPH_C32(0x2c6af28c) }, + { SPH_C32(0xc2010500), SPH_C32(0xba73a66e), SPH_C32(0x00fca37e), + SPH_C32(0x70c50878), SPH_C32(0xb5ec0600), SPH_C32(0x95ab83ac), + SPH_C32(0x2d7f750b), SPH_C32(0x428f9ad8) }, + { SPH_C32(0x06e90400), SPH_C32(0xa5033060), SPH_C32(0x27e86942), + SPH_C32(0xf8e40448), SPH_C32(0x02480700), SPH_C32(0x1fb4b274), + SPH_C32(0xa8f6ada0), SPH_C32(0xa44bfebc) }, + { SPH_C32(0xb14d0500), SPH_C32(0x2f1c01b8), SPH_C32(0xa261b1e9), + SPH_C32(0x1e20602c), SPH_C32(0x71040700), SPH_C32(0x8adb15a2), + SPH_C32(0x0a6bbf37), SPH_C32(0xcaae96e8) }, + { SPH_C32(0xd21d0600), SPH_C32(0x2f7e1385), SPH_C32(0xe5908227), + SPH_C32(0x0815196a), SPH_C32(0x28860600), SPH_C32(0x128f4c44), + SPH_C32(0x0f20b113), SPH_C32(0x179959a0) }, + { SPH_C32(0x65b90700), SPH_C32(0xa561225d), SPH_C32(0x60195a8c), + SPH_C32(0xeed17d0e), SPH_C32(0x5bca0600), SPH_C32(0x87e0eb92), + SPH_C32(0xadbda384), SPH_C32(0x797c31f4) }, + { SPH_C32(0xa1510600), SPH_C32(0xba11b453), SPH_C32(0x470d90b0), + SPH_C32(0x66f0713e), SPH_C32(0xec6e0700), SPH_C32(0x0dffda4a), + SPH_C32(0x28347b2f), SPH_C32(0x9fb85590) }, + { SPH_C32(0x16f50700), SPH_C32(0x300e858b), SPH_C32(0xc284481b), + SPH_C32(0x8034155a), SPH_C32(0x9f220700), SPH_C32(0x98907d9c), + SPH_C32(0x8aa969b8), SPH_C32(0xf15d3dc4) }, + { SPH_C32(0xde320800), SPH_C32(0x288350fe), SPH_C32(0x71852ac7), + SPH_C32(0xa6bf9f96), SPH_C32(0xe18b0000), SPH_C32(0x5459887d), + SPH_C32(0xbf1283d3), SPH_C32(0x1b666a73) }, + { SPH_C32(0x69960900), SPH_C32(0xa29c6126), SPH_C32(0xf40cf26c), + SPH_C32(0x407bfbf2), SPH_C32(0x92c70000), SPH_C32(0xc1362fab), + SPH_C32(0x1d8f9144), SPH_C32(0x75830227) }, + { SPH_C32(0xad7e0800), SPH_C32(0xbdecf728), SPH_C32(0xd3183850), + SPH_C32(0xc85af7c2), SPH_C32(0x25630100), SPH_C32(0x4b291e73), + SPH_C32(0x980649ef), SPH_C32(0x93476643) }, + { SPH_C32(0x1ada0900), SPH_C32(0x37f3c6f0), SPH_C32(0x5691e0fb), + SPH_C32(0x2e9e93a6), SPH_C32(0x562f0100), SPH_C32(0xde46b9a5), + SPH_C32(0x3a9b5b78), SPH_C32(0xfda20e17) }, + { SPH_C32(0x798a0a00), SPH_C32(0x3791d4cd), SPH_C32(0x1160d335), + SPH_C32(0x38abeae0), SPH_C32(0x0fad0000), SPH_C32(0x4612e043), + SPH_C32(0x3fd0555c), SPH_C32(0x2095c15f) }, + { SPH_C32(0xce2e0b00), SPH_C32(0xbd8ee515), SPH_C32(0x94e90b9e), + SPH_C32(0xde6f8e84), SPH_C32(0x7ce10000), SPH_C32(0xd37d4795), + SPH_C32(0x9d4d47cb), SPH_C32(0x4e70a90b) }, + { SPH_C32(0x0ac60a00), SPH_C32(0xa2fe731b), SPH_C32(0xb3fdc1a2), + SPH_C32(0x564e82b4), SPH_C32(0xcb450100), SPH_C32(0x5962764d), + SPH_C32(0x18c49f60), SPH_C32(0xa8b4cd6f) }, + { SPH_C32(0xbd620b00), SPH_C32(0x28e142c3), SPH_C32(0x36741909), + SPH_C32(0xb08ae6d0), SPH_C32(0xb8090100), SPH_C32(0xcc0dd19b), + SPH_C32(0xba598df7), SPH_C32(0xc651a53b) }, + { SPH_C32(0x30140800), SPH_C32(0x3ac838c0), SPH_C32(0xf147fc48), + SPH_C32(0x9d4c34ba), SPH_C32(0xa8150200), SPH_C32(0x59006470), + SPH_C32(0x5f35acae), SPH_C32(0xbe81b429) }, + { SPH_C32(0x87b00900), SPH_C32(0xb0d70918), SPH_C32(0x74ce24e3), + SPH_C32(0x7b8850de), SPH_C32(0xdb590200), SPH_C32(0xcc6fc3a6), + SPH_C32(0xfda8be39), SPH_C32(0xd064dc7d) }, + { SPH_C32(0x43580800), SPH_C32(0xafa79f16), SPH_C32(0x53daeedf), + SPH_C32(0xf3a95cee), SPH_C32(0x6cfd0300), SPH_C32(0x4670f27e), + SPH_C32(0x78216692), SPH_C32(0x36a0b819) }, + { SPH_C32(0xf4fc0900), SPH_C32(0x25b8aece), SPH_C32(0xd6533674), + SPH_C32(0x156d388a), SPH_C32(0x1fb10300), SPH_C32(0xd31f55a8), + SPH_C32(0xdabc7405), SPH_C32(0x5845d04d) }, + { SPH_C32(0x97ac0a00), SPH_C32(0x25dabcf3), SPH_C32(0x91a205ba), + SPH_C32(0x035841cc), SPH_C32(0x46330200), SPH_C32(0x4b4b0c4e), + SPH_C32(0xdff77a21), SPH_C32(0x85721f05) }, + { SPH_C32(0x20080b00), SPH_C32(0xafc58d2b), SPH_C32(0x142bdd11), + SPH_C32(0xe59c25a8), SPH_C32(0x357f0200), SPH_C32(0xde24ab98), + SPH_C32(0x7d6a68b6), SPH_C32(0xeb977751) }, + { SPH_C32(0xe4e00a00), SPH_C32(0xb0b51b25), SPH_C32(0x333f172d), + SPH_C32(0x6dbd2998), SPH_C32(0x82db0300), SPH_C32(0x543b9a40), + SPH_C32(0xf8e3b01d), SPH_C32(0x0d531335) }, + { SPH_C32(0x53440b00), SPH_C32(0x3aaa2afd), SPH_C32(0xb6b6cf86), + SPH_C32(0x8b794dfc), SPH_C32(0xf1970300), SPH_C32(0xc1543d96), + SPH_C32(0x5a7ea28a), SPH_C32(0x63b67b61) }, + { SPH_C32(0x510c0c00), SPH_C32(0x251e9889), SPH_C32(0x1e406226), + SPH_C32(0x2f32b340), SPH_C32(0xf5360000), SPH_C32(0x7be3bf82), + SPH_C32(0xd5606668), SPH_C32(0x3f198195) }, + { SPH_C32(0xe6a80d00), SPH_C32(0xaf01a951), SPH_C32(0x9bc9ba8d), + SPH_C32(0xc9f6d724), SPH_C32(0x867a0000), SPH_C32(0xee8c1854), + SPH_C32(0x77fd74ff), SPH_C32(0x51fce9c1) }, + { SPH_C32(0x22400c00), SPH_C32(0xb0713f5f), SPH_C32(0xbcdd70b1), + SPH_C32(0x41d7db14), SPH_C32(0x31de0100), SPH_C32(0x6493298c), + SPH_C32(0xf274ac54), SPH_C32(0xb7388da5) }, + { SPH_C32(0x95e40d00), SPH_C32(0x3a6e0e87), SPH_C32(0x3954a81a), + SPH_C32(0xa713bf70), SPH_C32(0x42920100), SPH_C32(0xf1fc8e5a), + SPH_C32(0x50e9bec3), SPH_C32(0xd9dde5f1) }, + { SPH_C32(0xf6b40e00), SPH_C32(0x3a0c1cba), SPH_C32(0x7ea59bd4), + SPH_C32(0xb126c636), SPH_C32(0x1b100000), SPH_C32(0x69a8d7bc), + SPH_C32(0x55a2b0e7), SPH_C32(0x04ea2ab9) }, + { SPH_C32(0x41100f00), SPH_C32(0xb0132d62), SPH_C32(0xfb2c437f), + SPH_C32(0x57e2a252), SPH_C32(0x685c0000), SPH_C32(0xfcc7706a), + SPH_C32(0xf73fa270), SPH_C32(0x6a0f42ed) }, + { SPH_C32(0x85f80e00), SPH_C32(0xaf63bb6c), SPH_C32(0xdc388943), + SPH_C32(0xdfc3ae62), SPH_C32(0xdff80100), SPH_C32(0x76d841b2), + SPH_C32(0x72b67adb), SPH_C32(0x8ccb2689) }, + { SPH_C32(0x325c0f00), SPH_C32(0x257c8ab4), SPH_C32(0x59b151e8), + SPH_C32(0x3907ca06), SPH_C32(0xacb40100), SPH_C32(0xe3b7e664), + SPH_C32(0xd02b684c), SPH_C32(0xe22e4edd) }, + { SPH_C32(0xbf2a0c00), SPH_C32(0x3755f0b7), SPH_C32(0x9e82b4a9), + SPH_C32(0x14c1186c), SPH_C32(0xbca80200), SPH_C32(0x76ba538f), + SPH_C32(0x35474915), SPH_C32(0x9afe5fcf) }, + { SPH_C32(0x088e0d00), SPH_C32(0xbd4ac16f), SPH_C32(0x1b0b6c02), + SPH_C32(0xf2057c08), SPH_C32(0xcfe40200), SPH_C32(0xe3d5f459), + SPH_C32(0x97da5b82), SPH_C32(0xf41b379b) }, + { SPH_C32(0xcc660c00), SPH_C32(0xa23a5761), SPH_C32(0x3c1fa63e), + SPH_C32(0x7a247038), SPH_C32(0x78400300), SPH_C32(0x69cac581), + SPH_C32(0x12538329), SPH_C32(0x12df53ff) }, + { SPH_C32(0x7bc20d00), SPH_C32(0x282566b9), SPH_C32(0xb9967e95), + SPH_C32(0x9ce0145c), SPH_C32(0x0b0c0300), SPH_C32(0xfca56257), + SPH_C32(0xb0ce91be), SPH_C32(0x7c3a3bab) }, + { SPH_C32(0x18920e00), SPH_C32(0x28477484), SPH_C32(0xfe674d5b), + SPH_C32(0x8ad56d1a), SPH_C32(0x528e0200), SPH_C32(0x64f13bb1), + SPH_C32(0xb5859f9a), SPH_C32(0xa10df4e3) }, + { SPH_C32(0xaf360f00), SPH_C32(0xa258455c), SPH_C32(0x7bee95f0), + SPH_C32(0x6c11097e), SPH_C32(0x21c20200), SPH_C32(0xf19e9c67), + SPH_C32(0x17188d0d), SPH_C32(0xcfe89cb7) }, + { SPH_C32(0x6bde0e00), SPH_C32(0xbd28d352), SPH_C32(0x5cfa5fcc), + SPH_C32(0xe430054e), SPH_C32(0x96660300), SPH_C32(0x7b81adbf), + SPH_C32(0x929155a6), SPH_C32(0x292cf8d3) }, + { SPH_C32(0xdc7a0f00), SPH_C32(0x3737e28a), SPH_C32(0xd9738767), + SPH_C32(0x02f4612a), SPH_C32(0xe52a0300), SPH_C32(0xeeee0a69), + SPH_C32(0x300c4731), SPH_C32(0x47c99087) }, + { SPH_C32(0xca8f0800), SPH_C32(0x07396701), SPH_C32(0x1bf7cf7c), + SPH_C32(0x82c07470), SPH_C32(0x7a080400), SPH_C32(0x767e77f5), + SPH_C32(0xbaa52e89), SPH_C32(0xb694ad43) }, + { SPH_C32(0x7d2b0900), SPH_C32(0x8d2656d9), SPH_C32(0x9e7e17d7), + SPH_C32(0x64041014), SPH_C32(0x09440400), SPH_C32(0xe311d023), + SPH_C32(0x18383c1e), SPH_C32(0xd871c517) }, + { SPH_C32(0xb9c30800), SPH_C32(0x9256c0d7), SPH_C32(0xb96addeb), + SPH_C32(0xec251c24), SPH_C32(0xbee00500), SPH_C32(0x690ee1fb), + SPH_C32(0x9db1e4b5), SPH_C32(0x3eb5a173) }, + { SPH_C32(0x0e670900), SPH_C32(0x1849f10f), SPH_C32(0x3ce30540), + SPH_C32(0x0ae17840), SPH_C32(0xcdac0500), SPH_C32(0xfc61462d), + SPH_C32(0x3f2cf622), SPH_C32(0x5050c927) }, + { SPH_C32(0x6d370a00), SPH_C32(0x182be332), SPH_C32(0x7b12368e), + SPH_C32(0x1cd40106), SPH_C32(0x942e0400), SPH_C32(0x64351fcb), + SPH_C32(0x3a67f806), SPH_C32(0x8d67066f) }, + { SPH_C32(0xda930b00), SPH_C32(0x9234d2ea), SPH_C32(0xfe9bee25), + SPH_C32(0xfa106562), SPH_C32(0xe7620400), SPH_C32(0xf15ab81d), + SPH_C32(0x98faea91), SPH_C32(0xe3826e3b) }, + { SPH_C32(0x1e7b0a00), SPH_C32(0x8d4444e4), SPH_C32(0xd98f2419), + SPH_C32(0x72316952), SPH_C32(0x50c60500), SPH_C32(0x7b4589c5), + SPH_C32(0x1d73323a), SPH_C32(0x05460a5f) }, + { SPH_C32(0xa9df0b00), SPH_C32(0x075b753c), SPH_C32(0x5c06fcb2), + SPH_C32(0x94f50d36), SPH_C32(0x238a0500), SPH_C32(0xee2a2e13), + SPH_C32(0xbfee20ad), SPH_C32(0x6ba3620b) }, + { SPH_C32(0x24a90800), SPH_C32(0x15720f3f), SPH_C32(0x9b3519f3), + SPH_C32(0xb933df5c), SPH_C32(0x33960600), SPH_C32(0x7b279bf8), + SPH_C32(0x5a8201f4), SPH_C32(0x13737319) }, + { SPH_C32(0x930d0900), SPH_C32(0x9f6d3ee7), SPH_C32(0x1ebcc158), + SPH_C32(0x5ff7bb38), SPH_C32(0x40da0600), SPH_C32(0xee483c2e), + SPH_C32(0xf81f1363), SPH_C32(0x7d961b4d) }, + { SPH_C32(0x57e50800), SPH_C32(0x801da8e9), SPH_C32(0x39a80b64), + SPH_C32(0xd7d6b708), SPH_C32(0xf77e0700), SPH_C32(0x64570df6), + SPH_C32(0x7d96cbc8), SPH_C32(0x9b527f29) }, + { SPH_C32(0xe0410900), SPH_C32(0x0a029931), SPH_C32(0xbc21d3cf), + SPH_C32(0x3112d36c), SPH_C32(0x84320700), SPH_C32(0xf138aa20), + SPH_C32(0xdf0bd95f), SPH_C32(0xf5b7177d) }, + { SPH_C32(0x83110a00), SPH_C32(0x0a608b0c), SPH_C32(0xfbd0e001), + SPH_C32(0x2727aa2a), SPH_C32(0xddb00600), SPH_C32(0x696cf3c6), + SPH_C32(0xda40d77b), SPH_C32(0x2880d835) }, + { SPH_C32(0x34b50b00), SPH_C32(0x807fbad4), SPH_C32(0x7e5938aa), + SPH_C32(0xc1e3ce4e), SPH_C32(0xaefc0600), SPH_C32(0xfc035410), + SPH_C32(0x78ddc5ec), SPH_C32(0x4665b061) }, + { SPH_C32(0xf05d0a00), SPH_C32(0x9f0f2cda), SPH_C32(0x594df296), + SPH_C32(0x49c2c27e), SPH_C32(0x19580700), SPH_C32(0x761c65c8), + SPH_C32(0xfd541d47), SPH_C32(0xa0a1d405) }, + { SPH_C32(0x47f90b00), SPH_C32(0x15101d02), SPH_C32(0xdcc42a3d), + SPH_C32(0xaf06a61a), SPH_C32(0x6a140700), SPH_C32(0xe373c21e), + SPH_C32(0x5fc90fd0), SPH_C32(0xce44bc51) }, + { SPH_C32(0x45b10c00), SPH_C32(0x0aa4af76), SPH_C32(0x7432879d), + SPH_C32(0x0b4d58a6), SPH_C32(0x6eb50400), SPH_C32(0x59c4400a), + SPH_C32(0xd0d7cb32), SPH_C32(0x92eb46a5) }, + { SPH_C32(0xf2150d00), SPH_C32(0x80bb9eae), SPH_C32(0xf1bb5f36), + SPH_C32(0xed893cc2), SPH_C32(0x1df90400), SPH_C32(0xccabe7dc), + SPH_C32(0x724ad9a5), SPH_C32(0xfc0e2ef1) }, + { SPH_C32(0x36fd0c00), SPH_C32(0x9fcb08a0), SPH_C32(0xd6af950a), + SPH_C32(0x65a830f2), SPH_C32(0xaa5d0500), SPH_C32(0x46b4d604), + SPH_C32(0xf7c3010e), SPH_C32(0x1aca4a95) }, + { SPH_C32(0x81590d00), SPH_C32(0x15d43978), SPH_C32(0x53264da1), + SPH_C32(0x836c5496), SPH_C32(0xd9110500), SPH_C32(0xd3db71d2), + SPH_C32(0x555e1399), SPH_C32(0x742f22c1) }, + { SPH_C32(0xe2090e00), SPH_C32(0x15b62b45), SPH_C32(0x14d77e6f), + SPH_C32(0x95592dd0), SPH_C32(0x80930400), SPH_C32(0x4b8f2834), + SPH_C32(0x50151dbd), SPH_C32(0xa918ed89) }, + { SPH_C32(0x55ad0f00), SPH_C32(0x9fa91a9d), SPH_C32(0x915ea6c4), + SPH_C32(0x739d49b4), SPH_C32(0xf3df0400), SPH_C32(0xdee08fe2), + SPH_C32(0xf2880f2a), SPH_C32(0xc7fd85dd) }, + { SPH_C32(0x91450e00), SPH_C32(0x80d98c93), SPH_C32(0xb64a6cf8), + SPH_C32(0xfbbc4584), SPH_C32(0x447b0500), SPH_C32(0x54ffbe3a), + SPH_C32(0x7701d781), SPH_C32(0x2139e1b9) }, + { SPH_C32(0x26e10f00), SPH_C32(0x0ac6bd4b), SPH_C32(0x33c3b453), + SPH_C32(0x1d7821e0), SPH_C32(0x37370500), SPH_C32(0xc19019ec), + SPH_C32(0xd59cc516), SPH_C32(0x4fdc89ed) }, + { SPH_C32(0xab970c00), SPH_C32(0x18efc748), SPH_C32(0xf4f05112), + SPH_C32(0x30bef38a), SPH_C32(0x272b0600), SPH_C32(0x549dac07), + SPH_C32(0x30f0e44f), SPH_C32(0x370c98ff) }, + { SPH_C32(0x1c330d00), SPH_C32(0x92f0f690), SPH_C32(0x717989b9), + SPH_C32(0xd67a97ee), SPH_C32(0x54670600), SPH_C32(0xc1f20bd1), + SPH_C32(0x926df6d8), SPH_C32(0x59e9f0ab) }, + { SPH_C32(0xd8db0c00), SPH_C32(0x8d80609e), SPH_C32(0x566d4385), + SPH_C32(0x5e5b9bde), SPH_C32(0xe3c30700), SPH_C32(0x4bed3a09), + SPH_C32(0x17e42e73), SPH_C32(0xbf2d94cf) }, + { SPH_C32(0x6f7f0d00), SPH_C32(0x079f5146), SPH_C32(0xd3e49b2e), + SPH_C32(0xb89fffba), SPH_C32(0x908f0700), SPH_C32(0xde829ddf), + SPH_C32(0xb5793ce4), SPH_C32(0xd1c8fc9b) }, + { SPH_C32(0x0c2f0e00), SPH_C32(0x07fd437b), SPH_C32(0x9415a8e0), + SPH_C32(0xaeaa86fc), SPH_C32(0xc90d0600), SPH_C32(0x46d6c439), + SPH_C32(0xb03232c0), SPH_C32(0x0cff33d3) }, + { SPH_C32(0xbb8b0f00), SPH_C32(0x8de272a3), SPH_C32(0x119c704b), + SPH_C32(0x486ee298), SPH_C32(0xba410600), SPH_C32(0xd3b963ef), + SPH_C32(0x12af2057), SPH_C32(0x621a5b87) }, + { SPH_C32(0x7f630e00), SPH_C32(0x9292e4ad), SPH_C32(0x3688ba77), + SPH_C32(0xc04feea8), SPH_C32(0x0de50700), SPH_C32(0x59a65237), + SPH_C32(0x9726f8fc), SPH_C32(0x84de3fe3) }, + { SPH_C32(0xc8c70f00), SPH_C32(0x188dd575), SPH_C32(0xb30162dc), + SPH_C32(0x268b8acc), SPH_C32(0x7ea90700), SPH_C32(0xccc9f5e1), + SPH_C32(0x35bbea6b), SPH_C32(0xea3b57b7) }, + { SPH_C32(0xe18b0000), SPH_C32(0x5459887d), SPH_C32(0xbf1283d3), + SPH_C32(0x1b666a73), SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), + SPH_C32(0xce97a914), SPH_C32(0xbdd9f5e5) }, + { SPH_C32(0x562f0100), SPH_C32(0xde46b9a5), SPH_C32(0x3a9b5b78), + SPH_C32(0xfda20e17), SPH_C32(0x4cf50800), SPH_C32(0xe9b57f55), + SPH_C32(0x6c0abb83), SPH_C32(0xd33c9db1) }, + { SPH_C32(0x92c70000), SPH_C32(0xc1362fab), SPH_C32(0x1d8f9144), + SPH_C32(0x75830227), SPH_C32(0xfb510900), SPH_C32(0x63aa4e8d), + SPH_C32(0xe9836328), SPH_C32(0x35f8f9d5) }, + { SPH_C32(0x25630100), SPH_C32(0x4b291e73), SPH_C32(0x980649ef), + SPH_C32(0x93476643), SPH_C32(0x881d0900), SPH_C32(0xf6c5e95b), + SPH_C32(0x4b1e71bf), SPH_C32(0x5b1d9181) }, + { SPH_C32(0x46330200), SPH_C32(0x4b4b0c4e), SPH_C32(0xdff77a21), + SPH_C32(0x85721f05), SPH_C32(0xd19f0800), SPH_C32(0x6e91b0bd), + SPH_C32(0x4e557f9b), SPH_C32(0x862a5ec9) }, + { SPH_C32(0xf1970300), SPH_C32(0xc1543d96), SPH_C32(0x5a7ea28a), + SPH_C32(0x63b67b61), SPH_C32(0xa2d30800), SPH_C32(0xfbfe176b), + SPH_C32(0xecc86d0c), SPH_C32(0xe8cf369d) }, + { SPH_C32(0x357f0200), SPH_C32(0xde24ab98), SPH_C32(0x7d6a68b6), + SPH_C32(0xeb977751), SPH_C32(0x15770900), SPH_C32(0x71e126b3), + SPH_C32(0x6941b5a7), SPH_C32(0x0e0b52f9) }, + { SPH_C32(0x82db0300), SPH_C32(0x543b9a40), SPH_C32(0xf8e3b01d), + SPH_C32(0x0d531335), SPH_C32(0x663b0900), SPH_C32(0xe48e8165), + SPH_C32(0xcbdca730), SPH_C32(0x60ee3aad) }, + { SPH_C32(0x0fad0000), SPH_C32(0x4612e043), SPH_C32(0x3fd0555c), + SPH_C32(0x2095c15f), SPH_C32(0x76270a00), SPH_C32(0x7183348e), + SPH_C32(0x2eb08669), SPH_C32(0x183e2bbf) }, + { SPH_C32(0xb8090100), SPH_C32(0xcc0dd19b), SPH_C32(0xba598df7), + SPH_C32(0xc651a53b), SPH_C32(0x056b0a00), SPH_C32(0xe4ec9358), + SPH_C32(0x8c2d94fe), SPH_C32(0x76db43eb) }, + { SPH_C32(0x7ce10000), SPH_C32(0xd37d4795), SPH_C32(0x9d4d47cb), + SPH_C32(0x4e70a90b), SPH_C32(0xb2cf0b00), SPH_C32(0x6ef3a280), + SPH_C32(0x09a44c55), SPH_C32(0x901f278f) }, + { SPH_C32(0xcb450100), SPH_C32(0x5962764d), SPH_C32(0x18c49f60), + SPH_C32(0xa8b4cd6f), SPH_C32(0xc1830b00), SPH_C32(0xfb9c0556), + SPH_C32(0xab395ec2), SPH_C32(0xfefa4fdb) }, + { SPH_C32(0xa8150200), SPH_C32(0x59006470), SPH_C32(0x5f35acae), + SPH_C32(0xbe81b429), SPH_C32(0x98010a00), SPH_C32(0x63c85cb0), + SPH_C32(0xae7250e6), SPH_C32(0x23cd8093) }, + { SPH_C32(0x1fb10300), SPH_C32(0xd31f55a8), SPH_C32(0xdabc7405), + SPH_C32(0x5845d04d), SPH_C32(0xeb4d0a00), SPH_C32(0xf6a7fb66), + SPH_C32(0x0cef4271), SPH_C32(0x4d28e8c7) }, + { SPH_C32(0xdb590200), SPH_C32(0xcc6fc3a6), SPH_C32(0xfda8be39), + SPH_C32(0xd064dc7d), SPH_C32(0x5ce90b00), SPH_C32(0x7cb8cabe), + SPH_C32(0x89669ada), SPH_C32(0xabec8ca3) }, + { SPH_C32(0x6cfd0300), SPH_C32(0x4670f27e), SPH_C32(0x78216692), + SPH_C32(0x36a0b819), SPH_C32(0x2fa50b00), SPH_C32(0xe9d76d68), + SPH_C32(0x2bfb884d), SPH_C32(0xc509e4f7) }, + { SPH_C32(0x6eb50400), SPH_C32(0x59c4400a), SPH_C32(0xd0d7cb32), + SPH_C32(0x92eb46a5), SPH_C32(0x2b040800), SPH_C32(0x5360ef7c), + SPH_C32(0xa4e54caf), SPH_C32(0x99a61e03) }, + { SPH_C32(0xd9110500), SPH_C32(0xd3db71d2), SPH_C32(0x555e1399), + SPH_C32(0x742f22c1), SPH_C32(0x58480800), SPH_C32(0xc60f48aa), + SPH_C32(0x06785e38), SPH_C32(0xf7437657) }, + { SPH_C32(0x1df90400), SPH_C32(0xccabe7dc), SPH_C32(0x724ad9a5), + SPH_C32(0xfc0e2ef1), SPH_C32(0xefec0900), SPH_C32(0x4c107972), + SPH_C32(0x83f18693), SPH_C32(0x11871233) }, + { SPH_C32(0xaa5d0500), SPH_C32(0x46b4d604), SPH_C32(0xf7c3010e), + SPH_C32(0x1aca4a95), SPH_C32(0x9ca00900), SPH_C32(0xd97fdea4), + SPH_C32(0x216c9404), SPH_C32(0x7f627a67) }, + { SPH_C32(0xc90d0600), SPH_C32(0x46d6c439), SPH_C32(0xb03232c0), + SPH_C32(0x0cff33d3), SPH_C32(0xc5220800), SPH_C32(0x412b8742), + SPH_C32(0x24279a20), SPH_C32(0xa255b52f) }, + { SPH_C32(0x7ea90700), SPH_C32(0xccc9f5e1), SPH_C32(0x35bbea6b), + SPH_C32(0xea3b57b7), SPH_C32(0xb66e0800), SPH_C32(0xd4442094), + SPH_C32(0x86ba88b7), SPH_C32(0xccb0dd7b) }, + { SPH_C32(0xba410600), SPH_C32(0xd3b963ef), SPH_C32(0x12af2057), + SPH_C32(0x621a5b87), SPH_C32(0x01ca0900), SPH_C32(0x5e5b114c), + SPH_C32(0x0333501c), SPH_C32(0x2a74b91f) }, + { SPH_C32(0x0de50700), SPH_C32(0x59a65237), SPH_C32(0x9726f8fc), + SPH_C32(0x84de3fe3), SPH_C32(0x72860900), SPH_C32(0xcb34b69a), + SPH_C32(0xa1ae428b), SPH_C32(0x4491d14b) }, + { SPH_C32(0x80930400), SPH_C32(0x4b8f2834), SPH_C32(0x50151dbd), + SPH_C32(0xa918ed89), SPH_C32(0x629a0a00), SPH_C32(0x5e390371), + SPH_C32(0x44c263d2), SPH_C32(0x3c41c059) }, + { SPH_C32(0x37370500), SPH_C32(0xc19019ec), SPH_C32(0xd59cc516), + SPH_C32(0x4fdc89ed), SPH_C32(0x11d60a00), SPH_C32(0xcb56a4a7), + SPH_C32(0xe65f7145), SPH_C32(0x52a4a80d) }, + { SPH_C32(0xf3df0400), SPH_C32(0xdee08fe2), SPH_C32(0xf2880f2a), + SPH_C32(0xc7fd85dd), SPH_C32(0xa6720b00), SPH_C32(0x4149957f), + SPH_C32(0x63d6a9ee), SPH_C32(0xb460cc69) }, + { SPH_C32(0x447b0500), SPH_C32(0x54ffbe3a), SPH_C32(0x7701d781), + SPH_C32(0x2139e1b9), SPH_C32(0xd53e0b00), SPH_C32(0xd42632a9), + SPH_C32(0xc14bbb79), SPH_C32(0xda85a43d) }, + { SPH_C32(0x272b0600), SPH_C32(0x549dac07), SPH_C32(0x30f0e44f), + SPH_C32(0x370c98ff), SPH_C32(0x8cbc0a00), SPH_C32(0x4c726b4f), + SPH_C32(0xc400b55d), SPH_C32(0x07b26b75) }, + { SPH_C32(0x908f0700), SPH_C32(0xde829ddf), SPH_C32(0xb5793ce4), + SPH_C32(0xd1c8fc9b), SPH_C32(0xfff00a00), SPH_C32(0xd91dcc99), + SPH_C32(0x669da7ca), SPH_C32(0x69570321) }, + { SPH_C32(0x54670600), SPH_C32(0xc1f20bd1), SPH_C32(0x926df6d8), + SPH_C32(0x59e9f0ab), SPH_C32(0x48540b00), SPH_C32(0x5302fd41), + SPH_C32(0xe3147f61), SPH_C32(0x8f936745) }, + { SPH_C32(0xe3c30700), SPH_C32(0x4bed3a09), SPH_C32(0x17e42e73), + SPH_C32(0xbf2d94cf), SPH_C32(0x3b180b00), SPH_C32(0xc66d5a97), + SPH_C32(0x41896df6), SPH_C32(0xe1760f11) }, + { SPH_C32(0xf5360000), SPH_C32(0x7be3bf82), SPH_C32(0xd5606668), + SPH_C32(0x3f198195), SPH_C32(0xa43a0c00), SPH_C32(0x5efd270b), + SPH_C32(0xcb20044e), SPH_C32(0x102b32d5) }, + { SPH_C32(0x42920100), SPH_C32(0xf1fc8e5a), SPH_C32(0x50e9bec3), + SPH_C32(0xd9dde5f1), SPH_C32(0xd7760c00), SPH_C32(0xcb9280dd), + SPH_C32(0x69bd16d9), SPH_C32(0x7ece5a81) }, + { SPH_C32(0x867a0000), SPH_C32(0xee8c1854), SPH_C32(0x77fd74ff), + SPH_C32(0x51fce9c1), SPH_C32(0x60d20d00), SPH_C32(0x418db105), + SPH_C32(0xec34ce72), SPH_C32(0x980a3ee5) }, + { SPH_C32(0x31de0100), SPH_C32(0x6493298c), SPH_C32(0xf274ac54), + SPH_C32(0xb7388da5), SPH_C32(0x139e0d00), SPH_C32(0xd4e216d3), + SPH_C32(0x4ea9dce5), SPH_C32(0xf6ef56b1) }, + { SPH_C32(0x528e0200), SPH_C32(0x64f13bb1), SPH_C32(0xb5859f9a), + SPH_C32(0xa10df4e3), SPH_C32(0x4a1c0c00), SPH_C32(0x4cb64f35), + SPH_C32(0x4be2d2c1), SPH_C32(0x2bd899f9) }, + { SPH_C32(0xe52a0300), SPH_C32(0xeeee0a69), SPH_C32(0x300c4731), + SPH_C32(0x47c99087), SPH_C32(0x39500c00), SPH_C32(0xd9d9e8e3), + SPH_C32(0xe97fc056), SPH_C32(0x453df1ad) }, + { SPH_C32(0x21c20200), SPH_C32(0xf19e9c67), SPH_C32(0x17188d0d), + SPH_C32(0xcfe89cb7), SPH_C32(0x8ef40d00), SPH_C32(0x53c6d93b), + SPH_C32(0x6cf618fd), SPH_C32(0xa3f995c9) }, + { SPH_C32(0x96660300), SPH_C32(0x7b81adbf), SPH_C32(0x929155a6), + SPH_C32(0x292cf8d3), SPH_C32(0xfdb80d00), SPH_C32(0xc6a97eed), + SPH_C32(0xce6b0a6a), SPH_C32(0xcd1cfd9d) }, + { SPH_C32(0x1b100000), SPH_C32(0x69a8d7bc), SPH_C32(0x55a2b0e7), + SPH_C32(0x04ea2ab9), SPH_C32(0xeda40e00), SPH_C32(0x53a4cb06), + SPH_C32(0x2b072b33), SPH_C32(0xb5ccec8f) }, + { SPH_C32(0xacb40100), SPH_C32(0xe3b7e664), SPH_C32(0xd02b684c), + SPH_C32(0xe22e4edd), SPH_C32(0x9ee80e00), SPH_C32(0xc6cb6cd0), + SPH_C32(0x899a39a4), SPH_C32(0xdb2984db) }, + { SPH_C32(0x685c0000), SPH_C32(0xfcc7706a), SPH_C32(0xf73fa270), + SPH_C32(0x6a0f42ed), SPH_C32(0x294c0f00), SPH_C32(0x4cd45d08), + SPH_C32(0x0c13e10f), SPH_C32(0x3dede0bf) }, + { SPH_C32(0xdff80100), SPH_C32(0x76d841b2), SPH_C32(0x72b67adb), + SPH_C32(0x8ccb2689), SPH_C32(0x5a000f00), SPH_C32(0xd9bbfade), + SPH_C32(0xae8ef398), SPH_C32(0x530888eb) }, + { SPH_C32(0xbca80200), SPH_C32(0x76ba538f), SPH_C32(0x35474915), + SPH_C32(0x9afe5fcf), SPH_C32(0x03820e00), SPH_C32(0x41efa338), + SPH_C32(0xabc5fdbc), SPH_C32(0x8e3f47a3) }, + { SPH_C32(0x0b0c0300), SPH_C32(0xfca56257), SPH_C32(0xb0ce91be), + SPH_C32(0x7c3a3bab), SPH_C32(0x70ce0e00), SPH_C32(0xd48004ee), + SPH_C32(0x0958ef2b), SPH_C32(0xe0da2ff7) }, + { SPH_C32(0xcfe40200), SPH_C32(0xe3d5f459), SPH_C32(0x97da5b82), + SPH_C32(0xf41b379b), SPH_C32(0xc76a0f00), SPH_C32(0x5e9f3536), + SPH_C32(0x8cd13780), SPH_C32(0x061e4b93) }, + { SPH_C32(0x78400300), SPH_C32(0x69cac581), SPH_C32(0x12538329), + SPH_C32(0x12df53ff), SPH_C32(0xb4260f00), SPH_C32(0xcbf092e0), + SPH_C32(0x2e4c2517), SPH_C32(0x68fb23c7) }, + { SPH_C32(0x7a080400), SPH_C32(0x767e77f5), SPH_C32(0xbaa52e89), + SPH_C32(0xb694ad43), SPH_C32(0xb0870c00), SPH_C32(0x714710f4), + SPH_C32(0xa152e1f5), SPH_C32(0x3454d933) }, + { SPH_C32(0xcdac0500), SPH_C32(0xfc61462d), SPH_C32(0x3f2cf622), + SPH_C32(0x5050c927), SPH_C32(0xc3cb0c00), SPH_C32(0xe428b722), + SPH_C32(0x03cff362), SPH_C32(0x5ab1b167) }, + { SPH_C32(0x09440400), SPH_C32(0xe311d023), SPH_C32(0x18383c1e), + SPH_C32(0xd871c517), SPH_C32(0x746f0d00), SPH_C32(0x6e3786fa), + SPH_C32(0x86462bc9), SPH_C32(0xbc75d503) }, + { SPH_C32(0xbee00500), SPH_C32(0x690ee1fb), SPH_C32(0x9db1e4b5), + SPH_C32(0x3eb5a173), SPH_C32(0x07230d00), SPH_C32(0xfb58212c), + SPH_C32(0x24db395e), SPH_C32(0xd290bd57) }, + { SPH_C32(0xddb00600), SPH_C32(0x696cf3c6), SPH_C32(0xda40d77b), + SPH_C32(0x2880d835), SPH_C32(0x5ea10c00), SPH_C32(0x630c78ca), + SPH_C32(0x2190377a), SPH_C32(0x0fa7721f) }, + { SPH_C32(0x6a140700), SPH_C32(0xe373c21e), SPH_C32(0x5fc90fd0), + SPH_C32(0xce44bc51), SPH_C32(0x2ded0c00), SPH_C32(0xf663df1c), + SPH_C32(0x830d25ed), SPH_C32(0x61421a4b) }, + { SPH_C32(0xaefc0600), SPH_C32(0xfc035410), SPH_C32(0x78ddc5ec), + SPH_C32(0x4665b061), SPH_C32(0x9a490d00), SPH_C32(0x7c7ceec4), + SPH_C32(0x0684fd46), SPH_C32(0x87867e2f) }, + { SPH_C32(0x19580700), SPH_C32(0x761c65c8), SPH_C32(0xfd541d47), + SPH_C32(0xa0a1d405), SPH_C32(0xe9050d00), SPH_C32(0xe9134912), + SPH_C32(0xa419efd1), SPH_C32(0xe963167b) }, + { SPH_C32(0x942e0400), SPH_C32(0x64351fcb), SPH_C32(0x3a67f806), + SPH_C32(0x8d67066f), SPH_C32(0xf9190e00), SPH_C32(0x7c1efcf9), + SPH_C32(0x4175ce88), SPH_C32(0x91b30769) }, + { SPH_C32(0x238a0500), SPH_C32(0xee2a2e13), SPH_C32(0xbfee20ad), + SPH_C32(0x6ba3620b), SPH_C32(0x8a550e00), SPH_C32(0xe9715b2f), + SPH_C32(0xe3e8dc1f), SPH_C32(0xff566f3d) }, + { SPH_C32(0xe7620400), SPH_C32(0xf15ab81d), SPH_C32(0x98faea91), + SPH_C32(0xe3826e3b), SPH_C32(0x3df10f00), SPH_C32(0x636e6af7), + SPH_C32(0x666104b4), SPH_C32(0x19920b59) }, + { SPH_C32(0x50c60500), SPH_C32(0x7b4589c5), SPH_C32(0x1d73323a), + SPH_C32(0x05460a5f), SPH_C32(0x4ebd0f00), SPH_C32(0xf601cd21), + SPH_C32(0xc4fc1623), SPH_C32(0x7777630d) }, + { SPH_C32(0x33960600), SPH_C32(0x7b279bf8), SPH_C32(0x5a8201f4), + SPH_C32(0x13737319), SPH_C32(0x173f0e00), SPH_C32(0x6e5594c7), + SPH_C32(0xc1b71807), SPH_C32(0xaa40ac45) }, + { SPH_C32(0x84320700), SPH_C32(0xf138aa20), SPH_C32(0xdf0bd95f), + SPH_C32(0xf5b7177d), SPH_C32(0x64730e00), SPH_C32(0xfb3a3311), + SPH_C32(0x632a0a90), SPH_C32(0xc4a5c411) }, + { SPH_C32(0x40da0600), SPH_C32(0xee483c2e), SPH_C32(0xf81f1363), + SPH_C32(0x7d961b4d), SPH_C32(0xd3d70f00), SPH_C32(0x712502c9), + SPH_C32(0xe6a3d23b), SPH_C32(0x2261a075) }, + { SPH_C32(0xf77e0700), SPH_C32(0x64570df6), SPH_C32(0x7d96cbc8), + SPH_C32(0x9b527f29), SPH_C32(0xa09b0f00), SPH_C32(0xe44aa51f), + SPH_C32(0x443ec0ac), SPH_C32(0x4c84c821) }, + { SPH_C32(0x3fb90800), SPH_C32(0x7cdad883), SPH_C32(0xce97a914), + SPH_C32(0xbdd9f5e5), SPH_C32(0xde320800), SPH_C32(0x288350fe), + SPH_C32(0x71852ac7), SPH_C32(0xa6bf9f96) }, + { SPH_C32(0x881d0900), SPH_C32(0xf6c5e95b), SPH_C32(0x4b1e71bf), + SPH_C32(0x5b1d9181), SPH_C32(0xad7e0800), SPH_C32(0xbdecf728), + SPH_C32(0xd3183850), SPH_C32(0xc85af7c2) }, + { SPH_C32(0x4cf50800), SPH_C32(0xe9b57f55), SPH_C32(0x6c0abb83), + SPH_C32(0xd33c9db1), SPH_C32(0x1ada0900), SPH_C32(0x37f3c6f0), + SPH_C32(0x5691e0fb), SPH_C32(0x2e9e93a6) }, + { SPH_C32(0xfb510900), SPH_C32(0x63aa4e8d), SPH_C32(0xe9836328), + SPH_C32(0x35f8f9d5), SPH_C32(0x69960900), SPH_C32(0xa29c6126), + SPH_C32(0xf40cf26c), SPH_C32(0x407bfbf2) }, + { SPH_C32(0x98010a00), SPH_C32(0x63c85cb0), SPH_C32(0xae7250e6), + SPH_C32(0x23cd8093), SPH_C32(0x30140800), SPH_C32(0x3ac838c0), + SPH_C32(0xf147fc48), SPH_C32(0x9d4c34ba) }, + { SPH_C32(0x2fa50b00), SPH_C32(0xe9d76d68), SPH_C32(0x2bfb884d), + SPH_C32(0xc509e4f7), SPH_C32(0x43580800), SPH_C32(0xafa79f16), + SPH_C32(0x53daeedf), SPH_C32(0xf3a95cee) }, + { SPH_C32(0xeb4d0a00), SPH_C32(0xf6a7fb66), SPH_C32(0x0cef4271), + SPH_C32(0x4d28e8c7), SPH_C32(0xf4fc0900), SPH_C32(0x25b8aece), + SPH_C32(0xd6533674), SPH_C32(0x156d388a) }, + { SPH_C32(0x5ce90b00), SPH_C32(0x7cb8cabe), SPH_C32(0x89669ada), + SPH_C32(0xabec8ca3), SPH_C32(0x87b00900), SPH_C32(0xb0d70918), + SPH_C32(0x74ce24e3), SPH_C32(0x7b8850de) }, + { SPH_C32(0xd19f0800), SPH_C32(0x6e91b0bd), SPH_C32(0x4e557f9b), + SPH_C32(0x862a5ec9), SPH_C32(0x97ac0a00), SPH_C32(0x25dabcf3), + SPH_C32(0x91a205ba), SPH_C32(0x035841cc) }, + { SPH_C32(0x663b0900), SPH_C32(0xe48e8165), SPH_C32(0xcbdca730), + SPH_C32(0x60ee3aad), SPH_C32(0xe4e00a00), SPH_C32(0xb0b51b25), + SPH_C32(0x333f172d), SPH_C32(0x6dbd2998) }, + { SPH_C32(0xa2d30800), SPH_C32(0xfbfe176b), SPH_C32(0xecc86d0c), + SPH_C32(0xe8cf369d), SPH_C32(0x53440b00), SPH_C32(0x3aaa2afd), + SPH_C32(0xb6b6cf86), SPH_C32(0x8b794dfc) }, + { SPH_C32(0x15770900), SPH_C32(0x71e126b3), SPH_C32(0x6941b5a7), + SPH_C32(0x0e0b52f9), SPH_C32(0x20080b00), SPH_C32(0xafc58d2b), + SPH_C32(0x142bdd11), SPH_C32(0xe59c25a8) }, + { SPH_C32(0x76270a00), SPH_C32(0x7183348e), SPH_C32(0x2eb08669), + SPH_C32(0x183e2bbf), SPH_C32(0x798a0a00), SPH_C32(0x3791d4cd), + SPH_C32(0x1160d335), SPH_C32(0x38abeae0) }, + { SPH_C32(0xc1830b00), SPH_C32(0xfb9c0556), SPH_C32(0xab395ec2), + SPH_C32(0xfefa4fdb), SPH_C32(0x0ac60a00), SPH_C32(0xa2fe731b), + SPH_C32(0xb3fdc1a2), SPH_C32(0x564e82b4) }, + { SPH_C32(0x056b0a00), SPH_C32(0xe4ec9358), SPH_C32(0x8c2d94fe), + SPH_C32(0x76db43eb), SPH_C32(0xbd620b00), SPH_C32(0x28e142c3), + SPH_C32(0x36741909), SPH_C32(0xb08ae6d0) }, + { SPH_C32(0xb2cf0b00), SPH_C32(0x6ef3a280), SPH_C32(0x09a44c55), + SPH_C32(0x901f278f), SPH_C32(0xce2e0b00), SPH_C32(0xbd8ee515), + SPH_C32(0x94e90b9e), SPH_C32(0xde6f8e84) }, + { SPH_C32(0xb0870c00), SPH_C32(0x714710f4), SPH_C32(0xa152e1f5), + SPH_C32(0x3454d933), SPH_C32(0xca8f0800), SPH_C32(0x07396701), + SPH_C32(0x1bf7cf7c), SPH_C32(0x82c07470) }, + { SPH_C32(0x07230d00), SPH_C32(0xfb58212c), SPH_C32(0x24db395e), + SPH_C32(0xd290bd57), SPH_C32(0xb9c30800), SPH_C32(0x9256c0d7), + SPH_C32(0xb96addeb), SPH_C32(0xec251c24) }, + { SPH_C32(0xc3cb0c00), SPH_C32(0xe428b722), SPH_C32(0x03cff362), + SPH_C32(0x5ab1b167), SPH_C32(0x0e670900), SPH_C32(0x1849f10f), + SPH_C32(0x3ce30540), SPH_C32(0x0ae17840) }, + { SPH_C32(0x746f0d00), SPH_C32(0x6e3786fa), SPH_C32(0x86462bc9), + SPH_C32(0xbc75d503), SPH_C32(0x7d2b0900), SPH_C32(0x8d2656d9), + SPH_C32(0x9e7e17d7), SPH_C32(0x64041014) }, + { SPH_C32(0x173f0e00), SPH_C32(0x6e5594c7), SPH_C32(0xc1b71807), + SPH_C32(0xaa40ac45), SPH_C32(0x24a90800), SPH_C32(0x15720f3f), + SPH_C32(0x9b3519f3), SPH_C32(0xb933df5c) }, + { SPH_C32(0xa09b0f00), SPH_C32(0xe44aa51f), SPH_C32(0x443ec0ac), + SPH_C32(0x4c84c821), SPH_C32(0x57e50800), SPH_C32(0x801da8e9), + SPH_C32(0x39a80b64), SPH_C32(0xd7d6b708) }, + { SPH_C32(0x64730e00), SPH_C32(0xfb3a3311), SPH_C32(0x632a0a90), + SPH_C32(0xc4a5c411), SPH_C32(0xe0410900), SPH_C32(0x0a029931), + SPH_C32(0xbc21d3cf), SPH_C32(0x3112d36c) }, + { SPH_C32(0xd3d70f00), SPH_C32(0x712502c9), SPH_C32(0xe6a3d23b), + SPH_C32(0x2261a075), SPH_C32(0x930d0900), SPH_C32(0x9f6d3ee7), + SPH_C32(0x1ebcc158), SPH_C32(0x5ff7bb38) }, + { SPH_C32(0x5ea10c00), SPH_C32(0x630c78ca), SPH_C32(0x2190377a), + SPH_C32(0x0fa7721f), SPH_C32(0x83110a00), SPH_C32(0x0a608b0c), + SPH_C32(0xfbd0e001), SPH_C32(0x2727aa2a) }, + { SPH_C32(0xe9050d00), SPH_C32(0xe9134912), SPH_C32(0xa419efd1), + SPH_C32(0xe963167b), SPH_C32(0xf05d0a00), SPH_C32(0x9f0f2cda), + SPH_C32(0x594df296), SPH_C32(0x49c2c27e) }, + { SPH_C32(0x2ded0c00), SPH_C32(0xf663df1c), SPH_C32(0x830d25ed), + SPH_C32(0x61421a4b), SPH_C32(0x47f90b00), SPH_C32(0x15101d02), + SPH_C32(0xdcc42a3d), SPH_C32(0xaf06a61a) }, + { SPH_C32(0x9a490d00), SPH_C32(0x7c7ceec4), SPH_C32(0x0684fd46), + SPH_C32(0x87867e2f), SPH_C32(0x34b50b00), SPH_C32(0x807fbad4), + SPH_C32(0x7e5938aa), SPH_C32(0xc1e3ce4e) }, + { SPH_C32(0xf9190e00), SPH_C32(0x7c1efcf9), SPH_C32(0x4175ce88), + SPH_C32(0x91b30769), SPH_C32(0x6d370a00), SPH_C32(0x182be332), + SPH_C32(0x7b12368e), SPH_C32(0x1cd40106) }, + { SPH_C32(0x4ebd0f00), SPH_C32(0xf601cd21), SPH_C32(0xc4fc1623), + SPH_C32(0x7777630d), SPH_C32(0x1e7b0a00), SPH_C32(0x8d4444e4), + SPH_C32(0xd98f2419), SPH_C32(0x72316952) }, + { SPH_C32(0x8a550e00), SPH_C32(0xe9715b2f), SPH_C32(0xe3e8dc1f), + SPH_C32(0xff566f3d), SPH_C32(0xa9df0b00), SPH_C32(0x075b753c), + SPH_C32(0x5c06fcb2), SPH_C32(0x94f50d36) }, + { SPH_C32(0x3df10f00), SPH_C32(0x636e6af7), SPH_C32(0x666104b4), + SPH_C32(0x19920b59), SPH_C32(0xda930b00), SPH_C32(0x9234d2ea), + SPH_C32(0xfe9bee25), SPH_C32(0xfa106562) }, + { SPH_C32(0x2b040800), SPH_C32(0x5360ef7c), SPH_C32(0xa4e54caf), + SPH_C32(0x99a61e03), SPH_C32(0x45b10c00), SPH_C32(0x0aa4af76), + SPH_C32(0x7432879d), SPH_C32(0x0b4d58a6) }, + { SPH_C32(0x9ca00900), SPH_C32(0xd97fdea4), SPH_C32(0x216c9404), + SPH_C32(0x7f627a67), SPH_C32(0x36fd0c00), SPH_C32(0x9fcb08a0), + SPH_C32(0xd6af950a), SPH_C32(0x65a830f2) }, + { SPH_C32(0x58480800), SPH_C32(0xc60f48aa), SPH_C32(0x06785e38), + SPH_C32(0xf7437657), SPH_C32(0x81590d00), SPH_C32(0x15d43978), + SPH_C32(0x53264da1), SPH_C32(0x836c5496) }, + { SPH_C32(0xefec0900), SPH_C32(0x4c107972), SPH_C32(0x83f18693), + SPH_C32(0x11871233), SPH_C32(0xf2150d00), SPH_C32(0x80bb9eae), + SPH_C32(0xf1bb5f36), SPH_C32(0xed893cc2) }, + { SPH_C32(0x8cbc0a00), SPH_C32(0x4c726b4f), SPH_C32(0xc400b55d), + SPH_C32(0x07b26b75), SPH_C32(0xab970c00), SPH_C32(0x18efc748), + SPH_C32(0xf4f05112), SPH_C32(0x30bef38a) }, + { SPH_C32(0x3b180b00), SPH_C32(0xc66d5a97), SPH_C32(0x41896df6), + SPH_C32(0xe1760f11), SPH_C32(0xd8db0c00), SPH_C32(0x8d80609e), + SPH_C32(0x566d4385), SPH_C32(0x5e5b9bde) }, + { SPH_C32(0xfff00a00), SPH_C32(0xd91dcc99), SPH_C32(0x669da7ca), + SPH_C32(0x69570321), SPH_C32(0x6f7f0d00), SPH_C32(0x079f5146), + SPH_C32(0xd3e49b2e), SPH_C32(0xb89fffba) }, + { SPH_C32(0x48540b00), SPH_C32(0x5302fd41), SPH_C32(0xe3147f61), + SPH_C32(0x8f936745), SPH_C32(0x1c330d00), SPH_C32(0x92f0f690), + SPH_C32(0x717989b9), SPH_C32(0xd67a97ee) }, + { SPH_C32(0xc5220800), SPH_C32(0x412b8742), SPH_C32(0x24279a20), + SPH_C32(0xa255b52f), SPH_C32(0x0c2f0e00), SPH_C32(0x07fd437b), + SPH_C32(0x9415a8e0), SPH_C32(0xaeaa86fc) }, + { SPH_C32(0x72860900), SPH_C32(0xcb34b69a), SPH_C32(0xa1ae428b), + SPH_C32(0x4491d14b), SPH_C32(0x7f630e00), SPH_C32(0x9292e4ad), + SPH_C32(0x3688ba77), SPH_C32(0xc04feea8) }, + { SPH_C32(0xb66e0800), SPH_C32(0xd4442094), SPH_C32(0x86ba88b7), + SPH_C32(0xccb0dd7b), SPH_C32(0xc8c70f00), SPH_C32(0x188dd575), + SPH_C32(0xb30162dc), SPH_C32(0x268b8acc) }, + { SPH_C32(0x01ca0900), SPH_C32(0x5e5b114c), SPH_C32(0x0333501c), + SPH_C32(0x2a74b91f), SPH_C32(0xbb8b0f00), SPH_C32(0x8de272a3), + SPH_C32(0x119c704b), SPH_C32(0x486ee298) }, + { SPH_C32(0x629a0a00), SPH_C32(0x5e390371), SPH_C32(0x44c263d2), + SPH_C32(0x3c41c059), SPH_C32(0xe2090e00), SPH_C32(0x15b62b45), + SPH_C32(0x14d77e6f), SPH_C32(0x95592dd0) }, + { SPH_C32(0xd53e0b00), SPH_C32(0xd42632a9), SPH_C32(0xc14bbb79), + SPH_C32(0xda85a43d), SPH_C32(0x91450e00), SPH_C32(0x80d98c93), + SPH_C32(0xb64a6cf8), SPH_C32(0xfbbc4584) }, + { SPH_C32(0x11d60a00), SPH_C32(0xcb56a4a7), SPH_C32(0xe65f7145), + SPH_C32(0x52a4a80d), SPH_C32(0x26e10f00), SPH_C32(0x0ac6bd4b), + SPH_C32(0x33c3b453), SPH_C32(0x1d7821e0) }, + { SPH_C32(0xa6720b00), SPH_C32(0x4149957f), SPH_C32(0x63d6a9ee), + SPH_C32(0xb460cc69), SPH_C32(0x55ad0f00), SPH_C32(0x9fa91a9d), + SPH_C32(0x915ea6c4), SPH_C32(0x739d49b4) }, + { SPH_C32(0xa43a0c00), SPH_C32(0x5efd270b), SPH_C32(0xcb20044e), + SPH_C32(0x102b32d5), SPH_C32(0x510c0c00), SPH_C32(0x251e9889), + SPH_C32(0x1e406226), SPH_C32(0x2f32b340) }, + { SPH_C32(0x139e0d00), SPH_C32(0xd4e216d3), SPH_C32(0x4ea9dce5), + SPH_C32(0xf6ef56b1), SPH_C32(0x22400c00), SPH_C32(0xb0713f5f), + SPH_C32(0xbcdd70b1), SPH_C32(0x41d7db14) }, + { SPH_C32(0xd7760c00), SPH_C32(0xcb9280dd), SPH_C32(0x69bd16d9), + SPH_C32(0x7ece5a81), SPH_C32(0x95e40d00), SPH_C32(0x3a6e0e87), + SPH_C32(0x3954a81a), SPH_C32(0xa713bf70) }, + { SPH_C32(0x60d20d00), SPH_C32(0x418db105), SPH_C32(0xec34ce72), + SPH_C32(0x980a3ee5), SPH_C32(0xe6a80d00), SPH_C32(0xaf01a951), + SPH_C32(0x9bc9ba8d), SPH_C32(0xc9f6d724) }, + { SPH_C32(0x03820e00), SPH_C32(0x41efa338), SPH_C32(0xabc5fdbc), + SPH_C32(0x8e3f47a3), SPH_C32(0xbf2a0c00), SPH_C32(0x3755f0b7), + SPH_C32(0x9e82b4a9), SPH_C32(0x14c1186c) }, + { SPH_C32(0xb4260f00), SPH_C32(0xcbf092e0), SPH_C32(0x2e4c2517), + SPH_C32(0x68fb23c7), SPH_C32(0xcc660c00), SPH_C32(0xa23a5761), + SPH_C32(0x3c1fa63e), SPH_C32(0x7a247038) }, + { SPH_C32(0x70ce0e00), SPH_C32(0xd48004ee), SPH_C32(0x0958ef2b), + SPH_C32(0xe0da2ff7), SPH_C32(0x7bc20d00), SPH_C32(0x282566b9), + SPH_C32(0xb9967e95), SPH_C32(0x9ce0145c) }, + { SPH_C32(0xc76a0f00), SPH_C32(0x5e9f3536), SPH_C32(0x8cd13780), + SPH_C32(0x061e4b93), SPH_C32(0x088e0d00), SPH_C32(0xbd4ac16f), + SPH_C32(0x1b0b6c02), SPH_C32(0xf2057c08) }, + { SPH_C32(0x4a1c0c00), SPH_C32(0x4cb64f35), SPH_C32(0x4be2d2c1), + SPH_C32(0x2bd899f9), SPH_C32(0x18920e00), SPH_C32(0x28477484), + SPH_C32(0xfe674d5b), SPH_C32(0x8ad56d1a) }, + { SPH_C32(0xfdb80d00), SPH_C32(0xc6a97eed), SPH_C32(0xce6b0a6a), + SPH_C32(0xcd1cfd9d), SPH_C32(0x6bde0e00), SPH_C32(0xbd28d352), + SPH_C32(0x5cfa5fcc), SPH_C32(0xe430054e) }, + { SPH_C32(0x39500c00), SPH_C32(0xd9d9e8e3), SPH_C32(0xe97fc056), + SPH_C32(0x453df1ad), SPH_C32(0xdc7a0f00), SPH_C32(0x3737e28a), + SPH_C32(0xd9738767), SPH_C32(0x02f4612a) }, + { SPH_C32(0x8ef40d00), SPH_C32(0x53c6d93b), SPH_C32(0x6cf618fd), + SPH_C32(0xa3f995c9), SPH_C32(0xaf360f00), SPH_C32(0xa258455c), + SPH_C32(0x7bee95f0), SPH_C32(0x6c11097e) }, + { SPH_C32(0xeda40e00), SPH_C32(0x53a4cb06), SPH_C32(0x2b072b33), + SPH_C32(0xb5ccec8f), SPH_C32(0xf6b40e00), SPH_C32(0x3a0c1cba), + SPH_C32(0x7ea59bd4), SPH_C32(0xb126c636) }, + { SPH_C32(0x5a000f00), SPH_C32(0xd9bbfade), SPH_C32(0xae8ef398), + SPH_C32(0x530888eb), SPH_C32(0x85f80e00), SPH_C32(0xaf63bb6c), + SPH_C32(0xdc388943), SPH_C32(0xdfc3ae62) }, + { SPH_C32(0x9ee80e00), SPH_C32(0xc6cb6cd0), SPH_C32(0x899a39a4), + SPH_C32(0xdb2984db), SPH_C32(0x325c0f00), SPH_C32(0x257c8ab4), + SPH_C32(0x59b151e8), SPH_C32(0x3907ca06) }, + { SPH_C32(0x294c0f00), SPH_C32(0x4cd45d08), SPH_C32(0x0c13e10f), + SPH_C32(0x3dede0bf), SPH_C32(0x41100f00), SPH_C32(0xb0132d62), + SPH_C32(0xfb2c437f), SPH_C32(0x57e2a252) } +}; + +static const sph_u32 T256_16[256][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0x515c0010), SPH_C32(0x40f372fb), SPH_C32(0xfce72602), + SPH_C32(0x71575061), SPH_C32(0x2e390000), SPH_C32(0x64dd6689), + SPH_C32(0x3cd406fc), SPH_C32(0xb1f490bc) }, + { SPH_C32(0x2e390000), SPH_C32(0x64dd6689), SPH_C32(0x3cd406fc), + SPH_C32(0xb1f490bc), SPH_C32(0x7f650010), SPH_C32(0x242e1472), + SPH_C32(0xc03320fe), SPH_C32(0xc0a3c0dd) }, + { SPH_C32(0x7f650010), SPH_C32(0x242e1472), SPH_C32(0xc03320fe), + SPH_C32(0xc0a3c0dd), SPH_C32(0x515c0010), SPH_C32(0x40f372fb), + SPH_C32(0xfce72602), SPH_C32(0x71575061) }, + { SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), SPH_C32(0xf9ce4c04), + SPH_C32(0xe2afa0c0), SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), + SPH_C32(0x79a90df9), SPH_C32(0x63e92178) }, + { SPH_C32(0xf3e40030), SPH_C32(0xc114970d), SPH_C32(0x05296a06), + SPH_C32(0x93f8f0a1), SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), + SPH_C32(0x457d0b05), SPH_C32(0xd21db1c4) }, + { SPH_C32(0x8c810020), SPH_C32(0xe53a837f), SPH_C32(0xc51a4af8), + SPH_C32(0x535b307c), SPH_C32(0x23170010), SPH_C32(0xed94d960), + SPH_C32(0xb99a2d07), SPH_C32(0xa34ae1a5) }, + { SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), SPH_C32(0x39fd6cfa), + SPH_C32(0x220c601d), SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), + SPH_C32(0x854e2bfb), SPH_C32(0x12be7119) }, + { SPH_C32(0x5c720000), SPH_C32(0xc9bacd12), SPH_C32(0x79a90df9), + SPH_C32(0x63e92178), SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), + SPH_C32(0x806741fd), SPH_C32(0x814681b8) }, + { SPH_C32(0x0d2e0010), SPH_C32(0x8949bfe9), SPH_C32(0x854e2bfb), + SPH_C32(0x12be7119), SPH_C32(0xd0f30020), SPH_C32(0x2c804e6d), + SPH_C32(0xbcb34701), SPH_C32(0x30b21104) }, + { SPH_C32(0x724b0000), SPH_C32(0xad67ab9b), SPH_C32(0x457d0b05), + SPH_C32(0xd21db1c4), SPH_C32(0x81af0030), SPH_C32(0x6c733c96), + SPH_C32(0x40546103), SPH_C32(0x41e54165) }, + { SPH_C32(0x23170010), SPH_C32(0xed94d960), SPH_C32(0xb99a2d07), + SPH_C32(0xa34ae1a5), SPH_C32(0xaf960030), SPH_C32(0x08ae5a1f), + SPH_C32(0x7c8067ff), SPH_C32(0xf011d1d9) }, + { SPH_C32(0xfeca0020), SPH_C32(0x485d28e4), SPH_C32(0x806741fd), + SPH_C32(0x814681b8), SPH_C32(0xa2b80020), SPH_C32(0x81e7e5f6), + SPH_C32(0xf9ce4c04), SPH_C32(0xe2afa0c0) }, + { SPH_C32(0xaf960030), SPH_C32(0x08ae5a1f), SPH_C32(0x7c8067ff), + SPH_C32(0xf011d1d9), SPH_C32(0x8c810020), SPH_C32(0xe53a837f), + SPH_C32(0xc51a4af8), SPH_C32(0x535b307c) }, + { SPH_C32(0xd0f30020), SPH_C32(0x2c804e6d), SPH_C32(0xbcb34701), + SPH_C32(0x30b21104), SPH_C32(0xdddd0030), SPH_C32(0xa5c9f184), + SPH_C32(0x39fd6cfa), SPH_C32(0x220c601d) }, + { SPH_C32(0x81af0030), SPH_C32(0x6c733c96), SPH_C32(0x40546103), + SPH_C32(0x41e54165), SPH_C32(0xf3e40030), SPH_C32(0xc114970d), + SPH_C32(0x05296a06), SPH_C32(0x93f8f0a1) }, + { SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), SPH_C32(0x36656ba8), + SPH_C32(0x23633a05), SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), + SPH_C32(0x5d5ca0f7), SPH_C32(0x727784cb) }, + { SPH_C32(0x1c920050), SPH_C32(0x7ba89e85), SPH_C32(0xca824daa), + SPH_C32(0x52346a64), SPH_C32(0x56920000), SPH_C32(0xc4103cbd), + SPH_C32(0x6188a60b), SPH_C32(0xc3831477) }, + { SPH_C32(0x63f70040), SPH_C32(0x5f868af7), SPH_C32(0x0ab16d54), + SPH_C32(0x9297aab9), SPH_C32(0x07ce0010), SPH_C32(0x84e34e46), + SPH_C32(0x9d6f8009), SPH_C32(0xb2d44416) }, + { SPH_C32(0x32ab0050), SPH_C32(0x1f75f80c), SPH_C32(0xf6564b56), + SPH_C32(0xe3c0fad8), SPH_C32(0x29f70010), SPH_C32(0xe03e28cf), + SPH_C32(0xa1bb86f5), SPH_C32(0x0320d4aa) }, + { SPH_C32(0xef760060), SPH_C32(0xbabc0988), SPH_C32(0xcfab27ac), + SPH_C32(0xc1cc9ac5), SPH_C32(0x24d90000), SPH_C32(0x69779726), + SPH_C32(0x24f5ad0e), SPH_C32(0x119ea5b3) }, + { SPH_C32(0xbe2a0070), SPH_C32(0xfa4f7b73), SPH_C32(0x334c01ae), + SPH_C32(0xb09bcaa4), SPH_C32(0x0ae00000), SPH_C32(0x0daaf1af), + SPH_C32(0x1821abf2), SPH_C32(0xa06a350f) }, + { SPH_C32(0xc14f0060), SPH_C32(0xde616f01), SPH_C32(0xf37f2150), + SPH_C32(0x70380a79), SPH_C32(0x5bbc0010), SPH_C32(0x4d598354), + SPH_C32(0xe4c68df0), SPH_C32(0xd13d656e) }, + { SPH_C32(0x90130070), SPH_C32(0x9e921dfa), SPH_C32(0x0f980752), + SPH_C32(0x016f5a18), SPH_C32(0x75850010), SPH_C32(0x2984e5dd), + SPH_C32(0xd8128b0c), SPH_C32(0x60c9f5d2) }, + { SPH_C32(0x11bc0040), SPH_C32(0xf2e1216c), SPH_C32(0x4fcc6651), + SPH_C32(0x408a1b7d), SPH_C32(0x86610020), SPH_C32(0xe89072d0), + SPH_C32(0xdd3be10a), SPH_C32(0xf3310573) }, + { SPH_C32(0x40e00050), SPH_C32(0xb2125397), SPH_C32(0xb32b4053), + SPH_C32(0x31dd4b1c), SPH_C32(0xa8580020), SPH_C32(0x8c4d1459), + SPH_C32(0xe1efe7f6), SPH_C32(0x42c595cf) }, + { SPH_C32(0x3f850040), SPH_C32(0x963c47e5), SPH_C32(0x731860ad), + SPH_C32(0xf17e8bc1), SPH_C32(0xf9040030), SPH_C32(0xccbe66a2), + SPH_C32(0x1d08c1f4), SPH_C32(0x3392c5ae) }, + { SPH_C32(0x6ed90050), SPH_C32(0xd6cf351e), SPH_C32(0x8fff46af), + SPH_C32(0x8029dba0), SPH_C32(0xd73d0030), SPH_C32(0xa863002b), + SPH_C32(0x21dcc708), SPH_C32(0x82665512) }, + { SPH_C32(0xb3040060), SPH_C32(0x7306c49a), SPH_C32(0xb6022a55), + SPH_C32(0xa225bbbd), SPH_C32(0xda130020), SPH_C32(0x212abfc2), + SPH_C32(0xa492ecf3), SPH_C32(0x90d8240b) }, + { SPH_C32(0xe2580070), SPH_C32(0x33f5b661), SPH_C32(0x4ae50c57), + SPH_C32(0xd372ebdc), SPH_C32(0xf42a0020), SPH_C32(0x45f7d94b), + SPH_C32(0x9846ea0f), SPH_C32(0x212cb4b7) }, + { SPH_C32(0x9d3d0060), SPH_C32(0x17dba213), SPH_C32(0x8ad62ca9), + SPH_C32(0x13d12b01), SPH_C32(0xa5760030), SPH_C32(0x0504abb0), + SPH_C32(0x64a1cc0d), SPH_C32(0x507be4d6) }, + { SPH_C32(0xcc610070), SPH_C32(0x5728d0e8), SPH_C32(0x76310aab), + SPH_C32(0x62867b60), SPH_C32(0x8b4f0030), SPH_C32(0x61d9cd39), + SPH_C32(0x5875caf1), SPH_C32(0xe18f746a) }, + { SPH_C32(0x78ab0000), SPH_C32(0xa0cd5a34), SPH_C32(0x5d5ca0f7), + SPH_C32(0x727784cb), SPH_C32(0x35650040), SPH_C32(0x9b96b64a), + SPH_C32(0x6b39cb5f), SPH_C32(0x5114bece) }, + { SPH_C32(0x29f70010), SPH_C32(0xe03e28cf), SPH_C32(0xa1bb86f5), + SPH_C32(0x0320d4aa), SPH_C32(0x1b5c0040), SPH_C32(0xff4bd0c3), + SPH_C32(0x57edcda3), SPH_C32(0xe0e02e72) }, + { SPH_C32(0x56920000), SPH_C32(0xc4103cbd), SPH_C32(0x6188a60b), + SPH_C32(0xc3831477), SPH_C32(0x4a000050), SPH_C32(0xbfb8a238), + SPH_C32(0xab0aeba1), SPH_C32(0x91b77e13) }, + { SPH_C32(0x07ce0010), SPH_C32(0x84e34e46), SPH_C32(0x9d6f8009), + SPH_C32(0xb2d44416), SPH_C32(0x64390050), SPH_C32(0xdb65c4b1), + SPH_C32(0x97deed5d), SPH_C32(0x2043eeaf) }, + { SPH_C32(0xda130020), SPH_C32(0x212abfc2), SPH_C32(0xa492ecf3), + SPH_C32(0x90d8240b), SPH_C32(0x69170040), SPH_C32(0x522c7b58), + SPH_C32(0x1290c6a6), SPH_C32(0x32fd9fb6) }, + { SPH_C32(0x8b4f0030), SPH_C32(0x61d9cd39), SPH_C32(0x5875caf1), + SPH_C32(0xe18f746a), SPH_C32(0x472e0040), SPH_C32(0x36f11dd1), + SPH_C32(0x2e44c05a), SPH_C32(0x83090f0a) }, + { SPH_C32(0xf42a0020), SPH_C32(0x45f7d94b), SPH_C32(0x9846ea0f), + SPH_C32(0x212cb4b7), SPH_C32(0x16720050), SPH_C32(0x76026f2a), + SPH_C32(0xd2a3e658), SPH_C32(0xf25e5f6b) }, + { SPH_C32(0xa5760030), SPH_C32(0x0504abb0), SPH_C32(0x64a1cc0d), + SPH_C32(0x507be4d6), SPH_C32(0x384b0050), SPH_C32(0x12df09a3), + SPH_C32(0xee77e0a4), SPH_C32(0x43aacfd7) }, + { SPH_C32(0x24d90000), SPH_C32(0x69779726), SPH_C32(0x24f5ad0e), + SPH_C32(0x119ea5b3), SPH_C32(0xcbaf0060), SPH_C32(0xd3cb9eae), + SPH_C32(0xeb5e8aa2), SPH_C32(0xd0523f76) }, + { SPH_C32(0x75850010), SPH_C32(0x2984e5dd), SPH_C32(0xd8128b0c), + SPH_C32(0x60c9f5d2), SPH_C32(0xe5960060), SPH_C32(0xb716f827), + SPH_C32(0xd78a8c5e), SPH_C32(0x61a6afca) }, + { SPH_C32(0x0ae00000), SPH_C32(0x0daaf1af), SPH_C32(0x1821abf2), + SPH_C32(0xa06a350f), SPH_C32(0xb4ca0070), SPH_C32(0xf7e58adc), + SPH_C32(0x2b6daa5c), SPH_C32(0x10f1ffab) }, + { SPH_C32(0x5bbc0010), SPH_C32(0x4d598354), SPH_C32(0xe4c68df0), + SPH_C32(0xd13d656e), SPH_C32(0x9af30070), SPH_C32(0x9338ec55), + SPH_C32(0x17b9aca0), SPH_C32(0xa1056f17) }, + { SPH_C32(0x86610020), SPH_C32(0xe89072d0), SPH_C32(0xdd3be10a), + SPH_C32(0xf3310573), SPH_C32(0x97dd0060), SPH_C32(0x1a7153bc), + SPH_C32(0x92f7875b), SPH_C32(0xb3bb1e0e) }, + { SPH_C32(0xd73d0030), SPH_C32(0xa863002b), SPH_C32(0x21dcc708), + SPH_C32(0x82665512), SPH_C32(0xb9e40060), SPH_C32(0x7eac3535), + SPH_C32(0xae2381a7), SPH_C32(0x024f8eb2) }, + { SPH_C32(0xa8580020), SPH_C32(0x8c4d1459), SPH_C32(0xe1efe7f6), + SPH_C32(0x42c595cf), SPH_C32(0xe8b80070), SPH_C32(0x3e5f47ce), + SPH_C32(0x52c4a7a5), SPH_C32(0x7318ded3) }, + { SPH_C32(0xf9040030), SPH_C32(0xccbe66a2), SPH_C32(0x1d08c1f4), + SPH_C32(0x3392c5ae), SPH_C32(0xc6810070), SPH_C32(0x5a822147), + SPH_C32(0x6e10a159), SPH_C32(0xc2ec4e6f) }, + { SPH_C32(0x35650040), SPH_C32(0x9b96b64a), SPH_C32(0x6b39cb5f), + SPH_C32(0x5114bece), SPH_C32(0x4dce0040), SPH_C32(0x3b5bec7e), + SPH_C32(0x36656ba8), SPH_C32(0x23633a05) }, + { SPH_C32(0x64390050), SPH_C32(0xdb65c4b1), SPH_C32(0x97deed5d), + SPH_C32(0x2043eeaf), SPH_C32(0x63f70040), SPH_C32(0x5f868af7), + SPH_C32(0x0ab16d54), SPH_C32(0x9297aab9) }, + { SPH_C32(0x1b5c0040), SPH_C32(0xff4bd0c3), SPH_C32(0x57edcda3), + SPH_C32(0xe0e02e72), SPH_C32(0x32ab0050), SPH_C32(0x1f75f80c), + SPH_C32(0xf6564b56), SPH_C32(0xe3c0fad8) }, + { SPH_C32(0x4a000050), SPH_C32(0xbfb8a238), SPH_C32(0xab0aeba1), + SPH_C32(0x91b77e13), SPH_C32(0x1c920050), SPH_C32(0x7ba89e85), + SPH_C32(0xca824daa), SPH_C32(0x52346a64) }, + { SPH_C32(0x97dd0060), SPH_C32(0x1a7153bc), SPH_C32(0x92f7875b), + SPH_C32(0xb3bb1e0e), SPH_C32(0x11bc0040), SPH_C32(0xf2e1216c), + SPH_C32(0x4fcc6651), SPH_C32(0x408a1b7d) }, + { SPH_C32(0xc6810070), SPH_C32(0x5a822147), SPH_C32(0x6e10a159), + SPH_C32(0xc2ec4e6f), SPH_C32(0x3f850040), SPH_C32(0x963c47e5), + SPH_C32(0x731860ad), SPH_C32(0xf17e8bc1) }, + { SPH_C32(0xb9e40060), SPH_C32(0x7eac3535), SPH_C32(0xae2381a7), + SPH_C32(0x024f8eb2), SPH_C32(0x6ed90050), SPH_C32(0xd6cf351e), + SPH_C32(0x8fff46af), SPH_C32(0x8029dba0) }, + { SPH_C32(0xe8b80070), SPH_C32(0x3e5f47ce), SPH_C32(0x52c4a7a5), + SPH_C32(0x7318ded3), SPH_C32(0x40e00050), SPH_C32(0xb2125397), + SPH_C32(0xb32b4053), SPH_C32(0x31dd4b1c) }, + { SPH_C32(0x69170040), SPH_C32(0x522c7b58), SPH_C32(0x1290c6a6), + SPH_C32(0x32fd9fb6), SPH_C32(0xb3040060), SPH_C32(0x7306c49a), + SPH_C32(0xb6022a55), SPH_C32(0xa225bbbd) }, + { SPH_C32(0x384b0050), SPH_C32(0x12df09a3), SPH_C32(0xee77e0a4), + SPH_C32(0x43aacfd7), SPH_C32(0x9d3d0060), SPH_C32(0x17dba213), + SPH_C32(0x8ad62ca9), SPH_C32(0x13d12b01) }, + { SPH_C32(0x472e0040), SPH_C32(0x36f11dd1), SPH_C32(0x2e44c05a), + SPH_C32(0x83090f0a), SPH_C32(0xcc610070), SPH_C32(0x5728d0e8), + SPH_C32(0x76310aab), SPH_C32(0x62867b60) }, + { SPH_C32(0x16720050), SPH_C32(0x76026f2a), SPH_C32(0xd2a3e658), + SPH_C32(0xf25e5f6b), SPH_C32(0xe2580070), SPH_C32(0x33f5b661), + SPH_C32(0x4ae50c57), SPH_C32(0xd372ebdc) }, + { SPH_C32(0xcbaf0060), SPH_C32(0xd3cb9eae), SPH_C32(0xeb5e8aa2), + SPH_C32(0xd0523f76), SPH_C32(0xef760060), SPH_C32(0xbabc0988), + SPH_C32(0xcfab27ac), SPH_C32(0xc1cc9ac5) }, + { SPH_C32(0x9af30070), SPH_C32(0x9338ec55), SPH_C32(0x17b9aca0), + SPH_C32(0xa1056f17), SPH_C32(0xc14f0060), SPH_C32(0xde616f01), + SPH_C32(0xf37f2150), SPH_C32(0x70380a79) }, + { SPH_C32(0xe5960060), SPH_C32(0xb716f827), SPH_C32(0xd78a8c5e), + SPH_C32(0x61a6afca), SPH_C32(0x90130070), SPH_C32(0x9e921dfa), + SPH_C32(0x0f980752), SPH_C32(0x016f5a18) }, + { SPH_C32(0xb4ca0070), SPH_C32(0xf7e58adc), SPH_C32(0x2b6daa5c), + SPH_C32(0x10f1ffab), SPH_C32(0xbe2a0070), SPH_C32(0xfa4f7b73), + SPH_C32(0x334c01ae), SPH_C32(0xb09bcaa4) }, + { SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), SPH_C32(0xc2c46c55), + SPH_C32(0xf362b233), SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), + SPH_C32(0xd14e094b), SPH_C32(0xb772b42b) }, + { SPH_C32(0x0a8e0090), SPH_C32(0x05fc6a17), SPH_C32(0x3e234a57), + SPH_C32(0x8235e252), SPH_C32(0x179f0000), SPH_C32(0x2e6a3562), + SPH_C32(0xed9a0fb7), SPH_C32(0x06862497) }, + { SPH_C32(0x75eb0080), SPH_C32(0x21d27e65), SPH_C32(0xfe106aa9), + SPH_C32(0x4296228f), SPH_C32(0x46c30010), SPH_C32(0x6e994799), + SPH_C32(0x117d29b5), SPH_C32(0x77d174f6) }, + { SPH_C32(0x24b70090), SPH_C32(0x61210c9e), SPH_C32(0x02f74cab), + SPH_C32(0x33c172ee), SPH_C32(0x68fa0010), SPH_C32(0x0a442110), + SPH_C32(0x2da92f49), SPH_C32(0xc625e44a) }, + { SPH_C32(0xf96a00a0), SPH_C32(0xc4e8fd1a), SPH_C32(0x3b0a2051), + SPH_C32(0x11cd12f3), SPH_C32(0x65d40000), SPH_C32(0x830d9ef9), + SPH_C32(0xa8e704b2), SPH_C32(0xd49b9553) }, + { SPH_C32(0xa83600b0), SPH_C32(0x841b8fe1), SPH_C32(0xc7ed0653), + SPH_C32(0x609a4292), SPH_C32(0x4bed0000), SPH_C32(0xe7d0f870), + SPH_C32(0x9433024e), SPH_C32(0x656f05ef) }, + { SPH_C32(0xd75300a0), SPH_C32(0xa0359b93), SPH_C32(0x07de26ad), + SPH_C32(0xa039824f), SPH_C32(0x1ab10010), SPH_C32(0xa7238a8b), + SPH_C32(0x68d4244c), SPH_C32(0x1438558e) }, + { SPH_C32(0x860f00b0), SPH_C32(0xe0c6e968), SPH_C32(0xfb3900af), + SPH_C32(0xd16ed22e), SPH_C32(0x34880010), SPH_C32(0xc3feec02), + SPH_C32(0x540022b0), SPH_C32(0xa5ccc532) }, + { SPH_C32(0x07a00080), SPH_C32(0x8cb5d5fe), SPH_C32(0xbb6d61ac), + SPH_C32(0x908b934b), SPH_C32(0xc76c0020), SPH_C32(0x02ea7b0f), + SPH_C32(0x512948b6), SPH_C32(0x36343593) }, + { SPH_C32(0x56fc0090), SPH_C32(0xcc46a705), SPH_C32(0x478a47ae), + SPH_C32(0xe1dcc32a), SPH_C32(0xe9550020), SPH_C32(0x66371d86), + SPH_C32(0x6dfd4e4a), SPH_C32(0x87c0a52f) }, + { SPH_C32(0x29990080), SPH_C32(0xe868b377), SPH_C32(0x87b96750), + SPH_C32(0x217f03f7), SPH_C32(0xb8090030), SPH_C32(0x26c46f7d), + SPH_C32(0x911a6848), SPH_C32(0xf697f54e) }, + { SPH_C32(0x78c50090), SPH_C32(0xa89bc18c), SPH_C32(0x7b5e4152), + SPH_C32(0x50285396), SPH_C32(0x96300030), SPH_C32(0x421909f4), + SPH_C32(0xadce6eb4), SPH_C32(0x476365f2) }, + { SPH_C32(0xa51800a0), SPH_C32(0x0d523008), SPH_C32(0x42a32da8), + SPH_C32(0x7224338b), SPH_C32(0x9b1e0020), SPH_C32(0xcb50b61d), + SPH_C32(0x2880454f), SPH_C32(0x55dd14eb) }, + { SPH_C32(0xf44400b0), SPH_C32(0x4da142f3), SPH_C32(0xbe440baa), + SPH_C32(0x037363ea), SPH_C32(0xb5270020), SPH_C32(0xaf8dd094), + SPH_C32(0x145443b3), SPH_C32(0xe4298457) }, + { SPH_C32(0x8b2100a0), SPH_C32(0x698f5681), SPH_C32(0x7e772b54), + SPH_C32(0xc3d0a337), SPH_C32(0xe47b0030), SPH_C32(0xef7ea26f), + SPH_C32(0xe8b365b1), SPH_C32(0x957ed436) }, + { SPH_C32(0xda7d00b0), SPH_C32(0x297c247a), SPH_C32(0x82900d56), + SPH_C32(0xb287f356), SPH_C32(0xca420030), SPH_C32(0x8ba3c4e6), + SPH_C32(0xd467634d), SPH_C32(0x248a448a) }, + { SPH_C32(0x161c00c0), SPH_C32(0x7e54f492), SPH_C32(0xf4a107fd), + SPH_C32(0xd0018836), SPH_C32(0x410d0000), SPH_C32(0xea7a09df), + SPH_C32(0x8c12a9bc), SPH_C32(0xc50530e0) }, + { SPH_C32(0x474000d0), SPH_C32(0x3ea78669), SPH_C32(0x084621ff), + SPH_C32(0xa156d857), SPH_C32(0x6f340000), SPH_C32(0x8ea76f56), + SPH_C32(0xb0c6af40), SPH_C32(0x74f1a05c) }, + { SPH_C32(0x382500c0), SPH_C32(0x1a89921b), SPH_C32(0xc8750101), + SPH_C32(0x61f5188a), SPH_C32(0x3e680010), SPH_C32(0xce541dad), + SPH_C32(0x4c218942), SPH_C32(0x05a6f03d) }, + { SPH_C32(0x697900d0), SPH_C32(0x5a7ae0e0), SPH_C32(0x34922703), + SPH_C32(0x10a248eb), SPH_C32(0x10510010), SPH_C32(0xaa897b24), + SPH_C32(0x70f58fbe), SPH_C32(0xb4526081) }, + { SPH_C32(0xb4a400e0), SPH_C32(0xffb31164), SPH_C32(0x0d6f4bf9), + SPH_C32(0x32ae28f6), SPH_C32(0x1d7f0000), SPH_C32(0x23c0c4cd), + SPH_C32(0xf5bba445), SPH_C32(0xa6ec1198) }, + { SPH_C32(0xe5f800f0), SPH_C32(0xbf40639f), SPH_C32(0xf1886dfb), + SPH_C32(0x43f97897), SPH_C32(0x33460000), SPH_C32(0x471da244), + SPH_C32(0xc96fa2b9), SPH_C32(0x17188124) }, + { SPH_C32(0x9a9d00e0), SPH_C32(0x9b6e77ed), SPH_C32(0x31bb4d05), + SPH_C32(0x835ab84a), SPH_C32(0x621a0010), SPH_C32(0x07eed0bf), + SPH_C32(0x358884bb), SPH_C32(0x664fd145) }, + { SPH_C32(0xcbc100f0), SPH_C32(0xdb9d0516), SPH_C32(0xcd5c6b07), + SPH_C32(0xf20de82b), SPH_C32(0x4c230010), SPH_C32(0x6333b636), + SPH_C32(0x095c8247), SPH_C32(0xd7bb41f9) }, + { SPH_C32(0x4a6e00c0), SPH_C32(0xb7ee3980), SPH_C32(0x8d080a04), + SPH_C32(0xb3e8a94e), SPH_C32(0xbfc70020), SPH_C32(0xa227213b), + SPH_C32(0x0c75e841), SPH_C32(0x4443b158) }, + { SPH_C32(0x1b3200d0), SPH_C32(0xf71d4b7b), SPH_C32(0x71ef2c06), + SPH_C32(0xc2bff92f), SPH_C32(0x91fe0020), SPH_C32(0xc6fa47b2), + SPH_C32(0x30a1eebd), SPH_C32(0xf5b721e4) }, + { SPH_C32(0x645700c0), SPH_C32(0xd3335f09), SPH_C32(0xb1dc0cf8), + SPH_C32(0x021c39f2), SPH_C32(0xc0a20030), SPH_C32(0x86093549), + SPH_C32(0xcc46c8bf), SPH_C32(0x84e07185) }, + { SPH_C32(0x350b00d0), SPH_C32(0x93c02df2), SPH_C32(0x4d3b2afa), + SPH_C32(0x734b6993), SPH_C32(0xee9b0030), SPH_C32(0xe2d453c0), + SPH_C32(0xf092ce43), SPH_C32(0x3514e139) }, + { SPH_C32(0xe8d600e0), SPH_C32(0x3609dc76), SPH_C32(0x74c64600), + SPH_C32(0x5147098e), SPH_C32(0xe3b50020), SPH_C32(0x6b9dec29), + SPH_C32(0x75dce5b8), SPH_C32(0x27aa9020) }, + { SPH_C32(0xb98a00f0), SPH_C32(0x76faae8d), SPH_C32(0x88216002), + SPH_C32(0x201059ef), SPH_C32(0xcd8c0020), SPH_C32(0x0f408aa0), + SPH_C32(0x4908e344), SPH_C32(0x965e009c) }, + { SPH_C32(0xc6ef00e0), SPH_C32(0x52d4baff), SPH_C32(0x481240fc), + SPH_C32(0xe0b39932), SPH_C32(0x9cd00030), SPH_C32(0x4fb3f85b), + SPH_C32(0xb5efc546), SPH_C32(0xe70950fd) }, + { SPH_C32(0x97b300f0), SPH_C32(0x1227c804), SPH_C32(0xb4f566fe), + SPH_C32(0x91e4c953), SPH_C32(0xb2e90030), SPH_C32(0x2b6e9ed2), + SPH_C32(0x893bc3ba), SPH_C32(0x56fdc041) }, + { SPH_C32(0x23790080), SPH_C32(0xe5c242d8), SPH_C32(0x9f98cca2), + SPH_C32(0x811536f8), SPH_C32(0x0cc30040), SPH_C32(0xd121e5a1), + SPH_C32(0xba77c214), SPH_C32(0xe6660ae5) }, + { SPH_C32(0x72250090), SPH_C32(0xa5313023), SPH_C32(0x637feaa0), + SPH_C32(0xf0426699), SPH_C32(0x22fa0040), SPH_C32(0xb5fc8328), + SPH_C32(0x86a3c4e8), SPH_C32(0x57929a59) }, + { SPH_C32(0x0d400080), SPH_C32(0x811f2451), SPH_C32(0xa34cca5e), + SPH_C32(0x30e1a644), SPH_C32(0x73a60050), SPH_C32(0xf50ff1d3), + SPH_C32(0x7a44e2ea), SPH_C32(0x26c5ca38) }, + { SPH_C32(0x5c1c0090), SPH_C32(0xc1ec56aa), SPH_C32(0x5fabec5c), + SPH_C32(0x41b6f625), SPH_C32(0x5d9f0050), SPH_C32(0x91d2975a), + SPH_C32(0x4690e416), SPH_C32(0x97315a84) }, + { SPH_C32(0x81c100a0), SPH_C32(0x6425a72e), SPH_C32(0x665680a6), + SPH_C32(0x63ba9638), SPH_C32(0x50b10040), SPH_C32(0x189b28b3), + SPH_C32(0xc3decfed), SPH_C32(0x858f2b9d) }, + { SPH_C32(0xd09d00b0), SPH_C32(0x24d6d5d5), SPH_C32(0x9ab1a6a4), + SPH_C32(0x12edc659), SPH_C32(0x7e880040), SPH_C32(0x7c464e3a), + SPH_C32(0xff0ac911), SPH_C32(0x347bbb21) }, + { SPH_C32(0xaff800a0), SPH_C32(0x00f8c1a7), SPH_C32(0x5a82865a), + SPH_C32(0xd24e0684), SPH_C32(0x2fd40050), SPH_C32(0x3cb53cc1), + SPH_C32(0x03edef13), SPH_C32(0x452ceb40) }, + { SPH_C32(0xfea400b0), SPH_C32(0x400bb35c), SPH_C32(0xa665a058), + SPH_C32(0xa31956e5), SPH_C32(0x01ed0050), SPH_C32(0x58685a48), + SPH_C32(0x3f39e9ef), SPH_C32(0xf4d87bfc) }, + { SPH_C32(0x7f0b0080), SPH_C32(0x2c788fca), SPH_C32(0xe631c15b), + SPH_C32(0xe2fc1780), SPH_C32(0xf2090060), SPH_C32(0x997ccd45), + SPH_C32(0x3a1083e9), SPH_C32(0x67208b5d) }, + { SPH_C32(0x2e570090), SPH_C32(0x6c8bfd31), SPH_C32(0x1ad6e759), + SPH_C32(0x93ab47e1), SPH_C32(0xdc300060), SPH_C32(0xfda1abcc), + SPH_C32(0x06c48515), SPH_C32(0xd6d41be1) }, + { SPH_C32(0x51320080), SPH_C32(0x48a5e943), SPH_C32(0xdae5c7a7), + SPH_C32(0x5308873c), SPH_C32(0x8d6c0070), SPH_C32(0xbd52d937), + SPH_C32(0xfa23a317), SPH_C32(0xa7834b80) }, + { SPH_C32(0x006e0090), SPH_C32(0x08569bb8), SPH_C32(0x2602e1a5), + SPH_C32(0x225fd75d), SPH_C32(0xa3550070), SPH_C32(0xd98fbfbe), + SPH_C32(0xc6f7a5eb), SPH_C32(0x1677db3c) }, + { SPH_C32(0xddb300a0), SPH_C32(0xad9f6a3c), SPH_C32(0x1fff8d5f), + SPH_C32(0x0053b740), SPH_C32(0xae7b0060), SPH_C32(0x50c60057), + SPH_C32(0x43b98e10), SPH_C32(0x04c9aa25) }, + { SPH_C32(0x8cef00b0), SPH_C32(0xed6c18c7), SPH_C32(0xe318ab5d), + SPH_C32(0x7104e721), SPH_C32(0x80420060), SPH_C32(0x341b66de), + SPH_C32(0x7f6d88ec), SPH_C32(0xb53d3a99) }, + { SPH_C32(0xf38a00a0), SPH_C32(0xc9420cb5), SPH_C32(0x232b8ba3), + SPH_C32(0xb1a727fc), SPH_C32(0xd11e0070), SPH_C32(0x74e81425), + SPH_C32(0x838aaeee), SPH_C32(0xc46a6af8) }, + { SPH_C32(0xa2d600b0), SPH_C32(0x89b17e4e), SPH_C32(0xdfccada1), + SPH_C32(0xc0f0779d), SPH_C32(0xff270070), SPH_C32(0x103572ac), + SPH_C32(0xbf5ea812), SPH_C32(0x759efa44) }, + { SPH_C32(0x6eb700c0), SPH_C32(0xde99aea6), SPH_C32(0xa9fda70a), + SPH_C32(0xa2760cfd), SPH_C32(0x74680040), SPH_C32(0x71ecbf95), + SPH_C32(0xe72b62e3), SPH_C32(0x94118e2e) }, + { SPH_C32(0x3feb00d0), SPH_C32(0x9e6adc5d), SPH_C32(0x551a8108), + SPH_C32(0xd3215c9c), SPH_C32(0x5a510040), SPH_C32(0x1531d91c), + SPH_C32(0xdbff641f), SPH_C32(0x25e51e92) }, + { SPH_C32(0x408e00c0), SPH_C32(0xba44c82f), SPH_C32(0x9529a1f6), + SPH_C32(0x13829c41), SPH_C32(0x0b0d0050), SPH_C32(0x55c2abe7), + SPH_C32(0x2718421d), SPH_C32(0x54b24ef3) }, + { SPH_C32(0x11d200d0), SPH_C32(0xfab7bad4), SPH_C32(0x69ce87f4), + SPH_C32(0x62d5cc20), SPH_C32(0x25340050), SPH_C32(0x311fcd6e), + SPH_C32(0x1bcc44e1), SPH_C32(0xe546de4f) }, + { SPH_C32(0xcc0f00e0), SPH_C32(0x5f7e4b50), SPH_C32(0x5033eb0e), + SPH_C32(0x40d9ac3d), SPH_C32(0x281a0040), SPH_C32(0xb8567287), + SPH_C32(0x9e826f1a), SPH_C32(0xf7f8af56) }, + { SPH_C32(0x9d5300f0), SPH_C32(0x1f8d39ab), SPH_C32(0xacd4cd0c), + SPH_C32(0x318efc5c), SPH_C32(0x06230040), SPH_C32(0xdc8b140e), + SPH_C32(0xa25669e6), SPH_C32(0x460c3fea) }, + { SPH_C32(0xe23600e0), SPH_C32(0x3ba32dd9), SPH_C32(0x6ce7edf2), + SPH_C32(0xf12d3c81), SPH_C32(0x577f0050), SPH_C32(0x9c7866f5), + SPH_C32(0x5eb14fe4), SPH_C32(0x375b6f8b) }, + { SPH_C32(0xb36a00f0), SPH_C32(0x7b505f22), SPH_C32(0x9000cbf0), + SPH_C32(0x807a6ce0), SPH_C32(0x79460050), SPH_C32(0xf8a5007c), + SPH_C32(0x62654918), SPH_C32(0x86afff37) }, + { SPH_C32(0x32c500c0), SPH_C32(0x172363b4), SPH_C32(0xd054aaf3), + SPH_C32(0xc19f2d85), SPH_C32(0x8aa20060), SPH_C32(0x39b19771), + SPH_C32(0x674c231e), SPH_C32(0x15570f96) }, + { SPH_C32(0x639900d0), SPH_C32(0x57d0114f), SPH_C32(0x2cb38cf1), + SPH_C32(0xb0c87de4), SPH_C32(0xa49b0060), SPH_C32(0x5d6cf1f8), + SPH_C32(0x5b9825e2), SPH_C32(0xa4a39f2a) }, + { SPH_C32(0x1cfc00c0), SPH_C32(0x73fe053d), SPH_C32(0xec80ac0f), + SPH_C32(0x706bbd39), SPH_C32(0xf5c70070), SPH_C32(0x1d9f8303), + SPH_C32(0xa77f03e0), SPH_C32(0xd5f4cf4b) }, + { SPH_C32(0x4da000d0), SPH_C32(0x330d77c6), SPH_C32(0x10678a0d), + SPH_C32(0x013ced58), SPH_C32(0xdbfe0070), SPH_C32(0x7942e58a), + SPH_C32(0x9bab051c), SPH_C32(0x64005ff7) }, + { SPH_C32(0x907d00e0), SPH_C32(0x96c48642), SPH_C32(0x299ae6f7), + SPH_C32(0x23308d45), SPH_C32(0xd6d00060), SPH_C32(0xf00b5a63), + SPH_C32(0x1ee52ee7), SPH_C32(0x76be2eee) }, + { SPH_C32(0xc12100f0), SPH_C32(0xd637f4b9), SPH_C32(0xd57dc0f5), + SPH_C32(0x5267dd24), SPH_C32(0xf8e90060), SPH_C32(0x94d63cea), + SPH_C32(0x2231281b), SPH_C32(0xc74abe52) }, + { SPH_C32(0xbe4400e0), SPH_C32(0xf219e0cb), SPH_C32(0x154ee00b), + SPH_C32(0x92c41df9), SPH_C32(0xa9b50070), SPH_C32(0xd4254e11), + SPH_C32(0xded60e19), SPH_C32(0xb61dee33) }, + { SPH_C32(0xef1800f0), SPH_C32(0xb2ea9230), SPH_C32(0xe9a9c609), + SPH_C32(0xe3934d98), SPH_C32(0x878c0070), SPH_C32(0xb0f82898), + SPH_C32(0xe20208e5), SPH_C32(0x07e97e8f) }, + { SPH_C32(0x39a60000), SPH_C32(0x4ab753eb), SPH_C32(0xd14e094b), + SPH_C32(0xb772b42b), SPH_C32(0x62740080), SPH_C32(0x0fb84b07), + SPH_C32(0x138a651e), SPH_C32(0x44100618) }, + { SPH_C32(0x68fa0010), SPH_C32(0x0a442110), SPH_C32(0x2da92f49), + SPH_C32(0xc625e44a), SPH_C32(0x4c4d0080), SPH_C32(0x6b652d8e), + SPH_C32(0x2f5e63e2), SPH_C32(0xf5e496a4) }, + { SPH_C32(0x179f0000), SPH_C32(0x2e6a3562), SPH_C32(0xed9a0fb7), + SPH_C32(0x06862497), SPH_C32(0x1d110090), SPH_C32(0x2b965f75), + SPH_C32(0xd3b945e0), SPH_C32(0x84b3c6c5) }, + { SPH_C32(0x46c30010), SPH_C32(0x6e994799), SPH_C32(0x117d29b5), + SPH_C32(0x77d174f6), SPH_C32(0x33280090), SPH_C32(0x4f4b39fc), + SPH_C32(0xef6d431c), SPH_C32(0x35475679) }, + { SPH_C32(0x9b1e0020), SPH_C32(0xcb50b61d), SPH_C32(0x2880454f), + SPH_C32(0x55dd14eb), SPH_C32(0x3e060080), SPH_C32(0xc6028615), + SPH_C32(0x6a2368e7), SPH_C32(0x27f92760) }, + { SPH_C32(0xca420030), SPH_C32(0x8ba3c4e6), SPH_C32(0xd467634d), + SPH_C32(0x248a448a), SPH_C32(0x103f0080), SPH_C32(0xa2dfe09c), + SPH_C32(0x56f76e1b), SPH_C32(0x960db7dc) }, + { SPH_C32(0xb5270020), SPH_C32(0xaf8dd094), SPH_C32(0x145443b3), + SPH_C32(0xe4298457), SPH_C32(0x41630090), SPH_C32(0xe22c9267), + SPH_C32(0xaa104819), SPH_C32(0xe75ae7bd) }, + { SPH_C32(0xe47b0030), SPH_C32(0xef7ea26f), SPH_C32(0xe8b365b1), + SPH_C32(0x957ed436), SPH_C32(0x6f5a0090), SPH_C32(0x86f1f4ee), + SPH_C32(0x96c44ee5), SPH_C32(0x56ae7701) }, + { SPH_C32(0x65d40000), SPH_C32(0x830d9ef9), SPH_C32(0xa8e704b2), + SPH_C32(0xd49b9553), SPH_C32(0x9cbe00a0), SPH_C32(0x47e563e3), + SPH_C32(0x93ed24e3), SPH_C32(0xc55687a0) }, + { SPH_C32(0x34880010), SPH_C32(0xc3feec02), SPH_C32(0x540022b0), + SPH_C32(0xa5ccc532), SPH_C32(0xb28700a0), SPH_C32(0x2338056a), + SPH_C32(0xaf39221f), SPH_C32(0x74a2171c) }, + { SPH_C32(0x4bed0000), SPH_C32(0xe7d0f870), SPH_C32(0x9433024e), + SPH_C32(0x656f05ef), SPH_C32(0xe3db00b0), SPH_C32(0x63cb7791), + SPH_C32(0x53de041d), SPH_C32(0x05f5477d) }, + { SPH_C32(0x1ab10010), SPH_C32(0xa7238a8b), SPH_C32(0x68d4244c), + SPH_C32(0x1438558e), SPH_C32(0xcde200b0), SPH_C32(0x07161118), + SPH_C32(0x6f0a02e1), SPH_C32(0xb401d7c1) }, + { SPH_C32(0xc76c0020), SPH_C32(0x02ea7b0f), SPH_C32(0x512948b6), + SPH_C32(0x36343593), SPH_C32(0xc0cc00a0), SPH_C32(0x8e5faef1), + SPH_C32(0xea44291a), SPH_C32(0xa6bfa6d8) }, + { SPH_C32(0x96300030), SPH_C32(0x421909f4), SPH_C32(0xadce6eb4), + SPH_C32(0x476365f2), SPH_C32(0xeef500a0), SPH_C32(0xea82c878), + SPH_C32(0xd6902fe6), SPH_C32(0x174b3664) }, + { SPH_C32(0xe9550020), SPH_C32(0x66371d86), SPH_C32(0x6dfd4e4a), + SPH_C32(0x87c0a52f), SPH_C32(0xbfa900b0), SPH_C32(0xaa71ba83), + SPH_C32(0x2a7709e4), SPH_C32(0x661c6605) }, + { SPH_C32(0xb8090030), SPH_C32(0x26c46f7d), SPH_C32(0x911a6848), + SPH_C32(0xf697f54e), SPH_C32(0x919000b0), SPH_C32(0xceacdc0a), + SPH_C32(0x16a30f18), SPH_C32(0xd7e8f6b9) }, + { SPH_C32(0x74680040), SPH_C32(0x71ecbf95), SPH_C32(0xe72b62e3), + SPH_C32(0x94118e2e), SPH_C32(0x1adf0080), SPH_C32(0xaf751133), + SPH_C32(0x4ed6c5e9), SPH_C32(0x366782d3) }, + { SPH_C32(0x25340050), SPH_C32(0x311fcd6e), SPH_C32(0x1bcc44e1), + SPH_C32(0xe546de4f), SPH_C32(0x34e60080), SPH_C32(0xcba877ba), + SPH_C32(0x7202c315), SPH_C32(0x8793126f) }, + { SPH_C32(0x5a510040), SPH_C32(0x1531d91c), SPH_C32(0xdbff641f), + SPH_C32(0x25e51e92), SPH_C32(0x65ba0090), SPH_C32(0x8b5b0541), + SPH_C32(0x8ee5e517), SPH_C32(0xf6c4420e) }, + { SPH_C32(0x0b0d0050), SPH_C32(0x55c2abe7), SPH_C32(0x2718421d), + SPH_C32(0x54b24ef3), SPH_C32(0x4b830090), SPH_C32(0xef8663c8), + SPH_C32(0xb231e3eb), SPH_C32(0x4730d2b2) }, + { SPH_C32(0xd6d00060), SPH_C32(0xf00b5a63), SPH_C32(0x1ee52ee7), + SPH_C32(0x76be2eee), SPH_C32(0x46ad0080), SPH_C32(0x66cfdc21), + SPH_C32(0x377fc810), SPH_C32(0x558ea3ab) }, + { SPH_C32(0x878c0070), SPH_C32(0xb0f82898), SPH_C32(0xe20208e5), + SPH_C32(0x07e97e8f), SPH_C32(0x68940080), SPH_C32(0x0212baa8), + SPH_C32(0x0babceec), SPH_C32(0xe47a3317) }, + { SPH_C32(0xf8e90060), SPH_C32(0x94d63cea), SPH_C32(0x2231281b), + SPH_C32(0xc74abe52), SPH_C32(0x39c80090), SPH_C32(0x42e1c853), + SPH_C32(0xf74ce8ee), SPH_C32(0x952d6376) }, + { SPH_C32(0xa9b50070), SPH_C32(0xd4254e11), SPH_C32(0xded60e19), + SPH_C32(0xb61dee33), SPH_C32(0x17f10090), SPH_C32(0x263caeda), + SPH_C32(0xcb98ee12), SPH_C32(0x24d9f3ca) }, + { SPH_C32(0x281a0040), SPH_C32(0xb8567287), SPH_C32(0x9e826f1a), + SPH_C32(0xf7f8af56), SPH_C32(0xe41500a0), SPH_C32(0xe72839d7), + SPH_C32(0xceb18414), SPH_C32(0xb721036b) }, + { SPH_C32(0x79460050), SPH_C32(0xf8a5007c), SPH_C32(0x62654918), + SPH_C32(0x86afff37), SPH_C32(0xca2c00a0), SPH_C32(0x83f55f5e), + SPH_C32(0xf26582e8), SPH_C32(0x06d593d7) }, + { SPH_C32(0x06230040), SPH_C32(0xdc8b140e), SPH_C32(0xa25669e6), + SPH_C32(0x460c3fea), SPH_C32(0x9b7000b0), SPH_C32(0xc3062da5), + SPH_C32(0x0e82a4ea), SPH_C32(0x7782c3b6) }, + { SPH_C32(0x577f0050), SPH_C32(0x9c7866f5), SPH_C32(0x5eb14fe4), + SPH_C32(0x375b6f8b), SPH_C32(0xb54900b0), SPH_C32(0xa7db4b2c), + SPH_C32(0x3256a216), SPH_C32(0xc676530a) }, + { SPH_C32(0x8aa20060), SPH_C32(0x39b19771), SPH_C32(0x674c231e), + SPH_C32(0x15570f96), SPH_C32(0xb86700a0), SPH_C32(0x2e92f4c5), + SPH_C32(0xb71889ed), SPH_C32(0xd4c82213) }, + { SPH_C32(0xdbfe0070), SPH_C32(0x7942e58a), SPH_C32(0x9bab051c), + SPH_C32(0x64005ff7), SPH_C32(0x965e00a0), SPH_C32(0x4a4f924c), + SPH_C32(0x8bcc8f11), SPH_C32(0x653cb2af) }, + { SPH_C32(0xa49b0060), SPH_C32(0x5d6cf1f8), SPH_C32(0x5b9825e2), + SPH_C32(0xa4a39f2a), SPH_C32(0xc70200b0), SPH_C32(0x0abce0b7), + SPH_C32(0x772ba913), SPH_C32(0x146be2ce) }, + { SPH_C32(0xf5c70070), SPH_C32(0x1d9f8303), SPH_C32(0xa77f03e0), + SPH_C32(0xd5f4cf4b), SPH_C32(0xe93b00b0), SPH_C32(0x6e61863e), + SPH_C32(0x4bffafef), SPH_C32(0xa59f7272) }, + { SPH_C32(0x410d0000), SPH_C32(0xea7a09df), SPH_C32(0x8c12a9bc), + SPH_C32(0xc50530e0), SPH_C32(0x571100c0), SPH_C32(0x942efd4d), + SPH_C32(0x78b3ae41), SPH_C32(0x1504b8d6) }, + { SPH_C32(0x10510010), SPH_C32(0xaa897b24), SPH_C32(0x70f58fbe), + SPH_C32(0xb4526081), SPH_C32(0x792800c0), SPH_C32(0xf0f39bc4), + SPH_C32(0x4467a8bd), SPH_C32(0xa4f0286a) }, + { SPH_C32(0x6f340000), SPH_C32(0x8ea76f56), SPH_C32(0xb0c6af40), + SPH_C32(0x74f1a05c), SPH_C32(0x287400d0), SPH_C32(0xb000e93f), + SPH_C32(0xb8808ebf), SPH_C32(0xd5a7780b) }, + { SPH_C32(0x3e680010), SPH_C32(0xce541dad), SPH_C32(0x4c218942), + SPH_C32(0x05a6f03d), SPH_C32(0x064d00d0), SPH_C32(0xd4dd8fb6), + SPH_C32(0x84548843), SPH_C32(0x6453e8b7) }, + { SPH_C32(0xe3b50020), SPH_C32(0x6b9dec29), SPH_C32(0x75dce5b8), + SPH_C32(0x27aa9020), SPH_C32(0x0b6300c0), SPH_C32(0x5d94305f), + SPH_C32(0x011aa3b8), SPH_C32(0x76ed99ae) }, + { SPH_C32(0xb2e90030), SPH_C32(0x2b6e9ed2), SPH_C32(0x893bc3ba), + SPH_C32(0x56fdc041), SPH_C32(0x255a00c0), SPH_C32(0x394956d6), + SPH_C32(0x3dcea544), SPH_C32(0xc7190912) }, + { SPH_C32(0xcd8c0020), SPH_C32(0x0f408aa0), SPH_C32(0x4908e344), + SPH_C32(0x965e009c), SPH_C32(0x740600d0), SPH_C32(0x79ba242d), + SPH_C32(0xc1298346), SPH_C32(0xb64e5973) }, + { SPH_C32(0x9cd00030), SPH_C32(0x4fb3f85b), SPH_C32(0xb5efc546), + SPH_C32(0xe70950fd), SPH_C32(0x5a3f00d0), SPH_C32(0x1d6742a4), + SPH_C32(0xfdfd85ba), SPH_C32(0x07bac9cf) }, + { SPH_C32(0x1d7f0000), SPH_C32(0x23c0c4cd), SPH_C32(0xf5bba445), + SPH_C32(0xa6ec1198), SPH_C32(0xa9db00e0), SPH_C32(0xdc73d5a9), + SPH_C32(0xf8d4efbc), SPH_C32(0x9442396e) }, + { SPH_C32(0x4c230010), SPH_C32(0x6333b636), SPH_C32(0x095c8247), + SPH_C32(0xd7bb41f9), SPH_C32(0x87e200e0), SPH_C32(0xb8aeb320), + SPH_C32(0xc400e940), SPH_C32(0x25b6a9d2) }, + { SPH_C32(0x33460000), SPH_C32(0x471da244), SPH_C32(0xc96fa2b9), + SPH_C32(0x17188124), SPH_C32(0xd6be00f0), SPH_C32(0xf85dc1db), + SPH_C32(0x38e7cf42), SPH_C32(0x54e1f9b3) }, + { SPH_C32(0x621a0010), SPH_C32(0x07eed0bf), SPH_C32(0x358884bb), + SPH_C32(0x664fd145), SPH_C32(0xf88700f0), SPH_C32(0x9c80a752), + SPH_C32(0x0433c9be), SPH_C32(0xe515690f) }, + { SPH_C32(0xbfc70020), SPH_C32(0xa227213b), SPH_C32(0x0c75e841), + SPH_C32(0x4443b158), SPH_C32(0xf5a900e0), SPH_C32(0x15c918bb), + SPH_C32(0x817de245), SPH_C32(0xf7ab1816) }, + { SPH_C32(0xee9b0030), SPH_C32(0xe2d453c0), SPH_C32(0xf092ce43), + SPH_C32(0x3514e139), SPH_C32(0xdb9000e0), SPH_C32(0x71147e32), + SPH_C32(0xbda9e4b9), SPH_C32(0x465f88aa) }, + { SPH_C32(0x91fe0020), SPH_C32(0xc6fa47b2), SPH_C32(0x30a1eebd), + SPH_C32(0xf5b721e4), SPH_C32(0x8acc00f0), SPH_C32(0x31e70cc9), + SPH_C32(0x414ec2bb), SPH_C32(0x3708d8cb) }, + { SPH_C32(0xc0a20030), SPH_C32(0x86093549), SPH_C32(0xcc46c8bf), + SPH_C32(0x84e07185), SPH_C32(0xa4f500f0), SPH_C32(0x553a6a40), + SPH_C32(0x7d9ac447), SPH_C32(0x86fc4877) }, + { SPH_C32(0x0cc30040), SPH_C32(0xd121e5a1), SPH_C32(0xba77c214), + SPH_C32(0xe6660ae5), SPH_C32(0x2fba00c0), SPH_C32(0x34e3a779), + SPH_C32(0x25ef0eb6), SPH_C32(0x67733c1d) }, + { SPH_C32(0x5d9f0050), SPH_C32(0x91d2975a), SPH_C32(0x4690e416), + SPH_C32(0x97315a84), SPH_C32(0x018300c0), SPH_C32(0x503ec1f0), + SPH_C32(0x193b084a), SPH_C32(0xd687aca1) }, + { SPH_C32(0x22fa0040), SPH_C32(0xb5fc8328), SPH_C32(0x86a3c4e8), + SPH_C32(0x57929a59), SPH_C32(0x50df00d0), SPH_C32(0x10cdb30b), + SPH_C32(0xe5dc2e48), SPH_C32(0xa7d0fcc0) }, + { SPH_C32(0x73a60050), SPH_C32(0xf50ff1d3), SPH_C32(0x7a44e2ea), + SPH_C32(0x26c5ca38), SPH_C32(0x7ee600d0), SPH_C32(0x7410d582), + SPH_C32(0xd90828b4), SPH_C32(0x16246c7c) }, + { SPH_C32(0xae7b0060), SPH_C32(0x50c60057), SPH_C32(0x43b98e10), + SPH_C32(0x04c9aa25), SPH_C32(0x73c800c0), SPH_C32(0xfd596a6b), + SPH_C32(0x5c46034f), SPH_C32(0x049a1d65) }, + { SPH_C32(0xff270070), SPH_C32(0x103572ac), SPH_C32(0xbf5ea812), + SPH_C32(0x759efa44), SPH_C32(0x5df100c0), SPH_C32(0x99840ce2), + SPH_C32(0x609205b3), SPH_C32(0xb56e8dd9) }, + { SPH_C32(0x80420060), SPH_C32(0x341b66de), SPH_C32(0x7f6d88ec), + SPH_C32(0xb53d3a99), SPH_C32(0x0cad00d0), SPH_C32(0xd9777e19), + SPH_C32(0x9c7523b1), SPH_C32(0xc439ddb8) }, + { SPH_C32(0xd11e0070), SPH_C32(0x74e81425), SPH_C32(0x838aaeee), + SPH_C32(0xc46a6af8), SPH_C32(0x229400d0), SPH_C32(0xbdaa1890), + SPH_C32(0xa0a1254d), SPH_C32(0x75cd4d04) }, + { SPH_C32(0x50b10040), SPH_C32(0x189b28b3), SPH_C32(0xc3decfed), + SPH_C32(0x858f2b9d), SPH_C32(0xd17000e0), SPH_C32(0x7cbe8f9d), + SPH_C32(0xa5884f4b), SPH_C32(0xe635bda5) }, + { SPH_C32(0x01ed0050), SPH_C32(0x58685a48), SPH_C32(0x3f39e9ef), + SPH_C32(0xf4d87bfc), SPH_C32(0xff4900e0), SPH_C32(0x1863e914), + SPH_C32(0x995c49b7), SPH_C32(0x57c12d19) }, + { SPH_C32(0x7e880040), SPH_C32(0x7c464e3a), SPH_C32(0xff0ac911), + SPH_C32(0x347bbb21), SPH_C32(0xae1500f0), SPH_C32(0x58909bef), + SPH_C32(0x65bb6fb5), SPH_C32(0x26967d78) }, + { SPH_C32(0x2fd40050), SPH_C32(0x3cb53cc1), SPH_C32(0x03edef13), + SPH_C32(0x452ceb40), SPH_C32(0x802c00f0), SPH_C32(0x3c4dfd66), + SPH_C32(0x596f6949), SPH_C32(0x9762edc4) }, + { SPH_C32(0xf2090060), SPH_C32(0x997ccd45), SPH_C32(0x3a1083e9), + SPH_C32(0x67208b5d), SPH_C32(0x8d0200e0), SPH_C32(0xb504428f), + SPH_C32(0xdc2142b2), SPH_C32(0x85dc9cdd) }, + { SPH_C32(0xa3550070), SPH_C32(0xd98fbfbe), SPH_C32(0xc6f7a5eb), + SPH_C32(0x1677db3c), SPH_C32(0xa33b00e0), SPH_C32(0xd1d92406), + SPH_C32(0xe0f5444e), SPH_C32(0x34280c61) }, + { SPH_C32(0xdc300060), SPH_C32(0xfda1abcc), SPH_C32(0x06c48515), + SPH_C32(0xd6d41be1), SPH_C32(0xf26700f0), SPH_C32(0x912a56fd), + SPH_C32(0x1c12624c), SPH_C32(0x457f5c00) }, + { SPH_C32(0x8d6c0070), SPH_C32(0xbd52d937), SPH_C32(0xfa23a317), + SPH_C32(0xa7834b80), SPH_C32(0xdc5e00f0), SPH_C32(0xf5f73074), + SPH_C32(0x20c664b0), SPH_C32(0xf48bccbc) }, + { SPH_C32(0x62740080), SPH_C32(0x0fb84b07), SPH_C32(0x138a651e), + SPH_C32(0x44100618), SPH_C32(0x5bd20080), SPH_C32(0x450f18ec), + SPH_C32(0xc2c46c55), SPH_C32(0xf362b233) }, + { SPH_C32(0x33280090), SPH_C32(0x4f4b39fc), SPH_C32(0xef6d431c), + SPH_C32(0x35475679), SPH_C32(0x75eb0080), SPH_C32(0x21d27e65), + SPH_C32(0xfe106aa9), SPH_C32(0x4296228f) }, + { SPH_C32(0x4c4d0080), SPH_C32(0x6b652d8e), SPH_C32(0x2f5e63e2), + SPH_C32(0xf5e496a4), SPH_C32(0x24b70090), SPH_C32(0x61210c9e), + SPH_C32(0x02f74cab), SPH_C32(0x33c172ee) }, + { SPH_C32(0x1d110090), SPH_C32(0x2b965f75), SPH_C32(0xd3b945e0), + SPH_C32(0x84b3c6c5), SPH_C32(0x0a8e0090), SPH_C32(0x05fc6a17), + SPH_C32(0x3e234a57), SPH_C32(0x8235e252) }, + { SPH_C32(0xc0cc00a0), SPH_C32(0x8e5faef1), SPH_C32(0xea44291a), + SPH_C32(0xa6bfa6d8), SPH_C32(0x07a00080), SPH_C32(0x8cb5d5fe), + SPH_C32(0xbb6d61ac), SPH_C32(0x908b934b) }, + { SPH_C32(0x919000b0), SPH_C32(0xceacdc0a), SPH_C32(0x16a30f18), + SPH_C32(0xd7e8f6b9), SPH_C32(0x29990080), SPH_C32(0xe868b377), + SPH_C32(0x87b96750), SPH_C32(0x217f03f7) }, + { SPH_C32(0xeef500a0), SPH_C32(0xea82c878), SPH_C32(0xd6902fe6), + SPH_C32(0x174b3664), SPH_C32(0x78c50090), SPH_C32(0xa89bc18c), + SPH_C32(0x7b5e4152), SPH_C32(0x50285396) }, + { SPH_C32(0xbfa900b0), SPH_C32(0xaa71ba83), SPH_C32(0x2a7709e4), + SPH_C32(0x661c6605), SPH_C32(0x56fc0090), SPH_C32(0xcc46a705), + SPH_C32(0x478a47ae), SPH_C32(0xe1dcc32a) }, + { SPH_C32(0x3e060080), SPH_C32(0xc6028615), SPH_C32(0x6a2368e7), + SPH_C32(0x27f92760), SPH_C32(0xa51800a0), SPH_C32(0x0d523008), + SPH_C32(0x42a32da8), SPH_C32(0x7224338b) }, + { SPH_C32(0x6f5a0090), SPH_C32(0x86f1f4ee), SPH_C32(0x96c44ee5), + SPH_C32(0x56ae7701), SPH_C32(0x8b2100a0), SPH_C32(0x698f5681), + SPH_C32(0x7e772b54), SPH_C32(0xc3d0a337) }, + { SPH_C32(0x103f0080), SPH_C32(0xa2dfe09c), SPH_C32(0x56f76e1b), + SPH_C32(0x960db7dc), SPH_C32(0xda7d00b0), SPH_C32(0x297c247a), + SPH_C32(0x82900d56), SPH_C32(0xb287f356) }, + { SPH_C32(0x41630090), SPH_C32(0xe22c9267), SPH_C32(0xaa104819), + SPH_C32(0xe75ae7bd), SPH_C32(0xf44400b0), SPH_C32(0x4da142f3), + SPH_C32(0xbe440baa), SPH_C32(0x037363ea) }, + { SPH_C32(0x9cbe00a0), SPH_C32(0x47e563e3), SPH_C32(0x93ed24e3), + SPH_C32(0xc55687a0), SPH_C32(0xf96a00a0), SPH_C32(0xc4e8fd1a), + SPH_C32(0x3b0a2051), SPH_C32(0x11cd12f3) }, + { SPH_C32(0xcde200b0), SPH_C32(0x07161118), SPH_C32(0x6f0a02e1), + SPH_C32(0xb401d7c1), SPH_C32(0xd75300a0), SPH_C32(0xa0359b93), + SPH_C32(0x07de26ad), SPH_C32(0xa039824f) }, + { SPH_C32(0xb28700a0), SPH_C32(0x2338056a), SPH_C32(0xaf39221f), + SPH_C32(0x74a2171c), SPH_C32(0x860f00b0), SPH_C32(0xe0c6e968), + SPH_C32(0xfb3900af), SPH_C32(0xd16ed22e) }, + { SPH_C32(0xe3db00b0), SPH_C32(0x63cb7791), SPH_C32(0x53de041d), + SPH_C32(0x05f5477d), SPH_C32(0xa83600b0), SPH_C32(0x841b8fe1), + SPH_C32(0xc7ed0653), SPH_C32(0x609a4292) }, + { SPH_C32(0x2fba00c0), SPH_C32(0x34e3a779), SPH_C32(0x25ef0eb6), + SPH_C32(0x67733c1d), SPH_C32(0x23790080), SPH_C32(0xe5c242d8), + SPH_C32(0x9f98cca2), SPH_C32(0x811536f8) }, + { SPH_C32(0x7ee600d0), SPH_C32(0x7410d582), SPH_C32(0xd90828b4), + SPH_C32(0x16246c7c), SPH_C32(0x0d400080), SPH_C32(0x811f2451), + SPH_C32(0xa34cca5e), SPH_C32(0x30e1a644) }, + { SPH_C32(0x018300c0), SPH_C32(0x503ec1f0), SPH_C32(0x193b084a), + SPH_C32(0xd687aca1), SPH_C32(0x5c1c0090), SPH_C32(0xc1ec56aa), + SPH_C32(0x5fabec5c), SPH_C32(0x41b6f625) }, + { SPH_C32(0x50df00d0), SPH_C32(0x10cdb30b), SPH_C32(0xe5dc2e48), + SPH_C32(0xa7d0fcc0), SPH_C32(0x72250090), SPH_C32(0xa5313023), + SPH_C32(0x637feaa0), SPH_C32(0xf0426699) }, + { SPH_C32(0x8d0200e0), SPH_C32(0xb504428f), SPH_C32(0xdc2142b2), + SPH_C32(0x85dc9cdd), SPH_C32(0x7f0b0080), SPH_C32(0x2c788fca), + SPH_C32(0xe631c15b), SPH_C32(0xe2fc1780) }, + { SPH_C32(0xdc5e00f0), SPH_C32(0xf5f73074), SPH_C32(0x20c664b0), + SPH_C32(0xf48bccbc), SPH_C32(0x51320080), SPH_C32(0x48a5e943), + SPH_C32(0xdae5c7a7), SPH_C32(0x5308873c) }, + { SPH_C32(0xa33b00e0), SPH_C32(0xd1d92406), SPH_C32(0xe0f5444e), + SPH_C32(0x34280c61), SPH_C32(0x006e0090), SPH_C32(0x08569bb8), + SPH_C32(0x2602e1a5), SPH_C32(0x225fd75d) }, + { SPH_C32(0xf26700f0), SPH_C32(0x912a56fd), SPH_C32(0x1c12624c), + SPH_C32(0x457f5c00), SPH_C32(0x2e570090), SPH_C32(0x6c8bfd31), + SPH_C32(0x1ad6e759), SPH_C32(0x93ab47e1) }, + { SPH_C32(0x73c800c0), SPH_C32(0xfd596a6b), SPH_C32(0x5c46034f), + SPH_C32(0x049a1d65), SPH_C32(0xddb300a0), SPH_C32(0xad9f6a3c), + SPH_C32(0x1fff8d5f), SPH_C32(0x0053b740) }, + { SPH_C32(0x229400d0), SPH_C32(0xbdaa1890), SPH_C32(0xa0a1254d), + SPH_C32(0x75cd4d04), SPH_C32(0xf38a00a0), SPH_C32(0xc9420cb5), + SPH_C32(0x232b8ba3), SPH_C32(0xb1a727fc) }, + { SPH_C32(0x5df100c0), SPH_C32(0x99840ce2), SPH_C32(0x609205b3), + SPH_C32(0xb56e8dd9), SPH_C32(0xa2d600b0), SPH_C32(0x89b17e4e), + SPH_C32(0xdfccada1), SPH_C32(0xc0f0779d) }, + { SPH_C32(0x0cad00d0), SPH_C32(0xd9777e19), SPH_C32(0x9c7523b1), + SPH_C32(0xc439ddb8), SPH_C32(0x8cef00b0), SPH_C32(0xed6c18c7), + SPH_C32(0xe318ab5d), SPH_C32(0x7104e721) }, + { SPH_C32(0xd17000e0), SPH_C32(0x7cbe8f9d), SPH_C32(0xa5884f4b), + SPH_C32(0xe635bda5), SPH_C32(0x81c100a0), SPH_C32(0x6425a72e), + SPH_C32(0x665680a6), SPH_C32(0x63ba9638) }, + { SPH_C32(0x802c00f0), SPH_C32(0x3c4dfd66), SPH_C32(0x596f6949), + SPH_C32(0x9762edc4), SPH_C32(0xaff800a0), SPH_C32(0x00f8c1a7), + SPH_C32(0x5a82865a), SPH_C32(0xd24e0684) }, + { SPH_C32(0xff4900e0), SPH_C32(0x1863e914), SPH_C32(0x995c49b7), + SPH_C32(0x57c12d19), SPH_C32(0xfea400b0), SPH_C32(0x400bb35c), + SPH_C32(0xa665a058), SPH_C32(0xa31956e5) }, + { SPH_C32(0xae1500f0), SPH_C32(0x58909bef), SPH_C32(0x65bb6fb5), + SPH_C32(0x26967d78), SPH_C32(0xd09d00b0), SPH_C32(0x24d6d5d5), + SPH_C32(0x9ab1a6a4), SPH_C32(0x12edc659) }, + { SPH_C32(0x1adf0080), SPH_C32(0xaf751133), SPH_C32(0x4ed6c5e9), + SPH_C32(0x366782d3), SPH_C32(0x6eb700c0), SPH_C32(0xde99aea6), + SPH_C32(0xa9fda70a), SPH_C32(0xa2760cfd) }, + { SPH_C32(0x4b830090), SPH_C32(0xef8663c8), SPH_C32(0xb231e3eb), + SPH_C32(0x4730d2b2), SPH_C32(0x408e00c0), SPH_C32(0xba44c82f), + SPH_C32(0x9529a1f6), SPH_C32(0x13829c41) }, + { SPH_C32(0x34e60080), SPH_C32(0xcba877ba), SPH_C32(0x7202c315), + SPH_C32(0x8793126f), SPH_C32(0x11d200d0), SPH_C32(0xfab7bad4), + SPH_C32(0x69ce87f4), SPH_C32(0x62d5cc20) }, + { SPH_C32(0x65ba0090), SPH_C32(0x8b5b0541), SPH_C32(0x8ee5e517), + SPH_C32(0xf6c4420e), SPH_C32(0x3feb00d0), SPH_C32(0x9e6adc5d), + SPH_C32(0x551a8108), SPH_C32(0xd3215c9c) }, + { SPH_C32(0xb86700a0), SPH_C32(0x2e92f4c5), SPH_C32(0xb71889ed), + SPH_C32(0xd4c82213), SPH_C32(0x32c500c0), SPH_C32(0x172363b4), + SPH_C32(0xd054aaf3), SPH_C32(0xc19f2d85) }, + { SPH_C32(0xe93b00b0), SPH_C32(0x6e61863e), SPH_C32(0x4bffafef), + SPH_C32(0xa59f7272), SPH_C32(0x1cfc00c0), SPH_C32(0x73fe053d), + SPH_C32(0xec80ac0f), SPH_C32(0x706bbd39) }, + { SPH_C32(0x965e00a0), SPH_C32(0x4a4f924c), SPH_C32(0x8bcc8f11), + SPH_C32(0x653cb2af), SPH_C32(0x4da000d0), SPH_C32(0x330d77c6), + SPH_C32(0x10678a0d), SPH_C32(0x013ced58) }, + { SPH_C32(0xc70200b0), SPH_C32(0x0abce0b7), SPH_C32(0x772ba913), + SPH_C32(0x146be2ce), SPH_C32(0x639900d0), SPH_C32(0x57d0114f), + SPH_C32(0x2cb38cf1), SPH_C32(0xb0c87de4) }, + { SPH_C32(0x46ad0080), SPH_C32(0x66cfdc21), SPH_C32(0x377fc810), + SPH_C32(0x558ea3ab), SPH_C32(0x907d00e0), SPH_C32(0x96c48642), + SPH_C32(0x299ae6f7), SPH_C32(0x23308d45) }, + { SPH_C32(0x17f10090), SPH_C32(0x263caeda), SPH_C32(0xcb98ee12), + SPH_C32(0x24d9f3ca), SPH_C32(0xbe4400e0), SPH_C32(0xf219e0cb), + SPH_C32(0x154ee00b), SPH_C32(0x92c41df9) }, + { SPH_C32(0x68940080), SPH_C32(0x0212baa8), SPH_C32(0x0babceec), + SPH_C32(0xe47a3317), SPH_C32(0xef1800f0), SPH_C32(0xb2ea9230), + SPH_C32(0xe9a9c609), SPH_C32(0xe3934d98) }, + { SPH_C32(0x39c80090), SPH_C32(0x42e1c853), SPH_C32(0xf74ce8ee), + SPH_C32(0x952d6376), SPH_C32(0xc12100f0), SPH_C32(0xd637f4b9), + SPH_C32(0xd57dc0f5), SPH_C32(0x5267dd24) }, + { SPH_C32(0xe41500a0), SPH_C32(0xe72839d7), SPH_C32(0xceb18414), + SPH_C32(0xb721036b), SPH_C32(0xcc0f00e0), SPH_C32(0x5f7e4b50), + SPH_C32(0x5033eb0e), SPH_C32(0x40d9ac3d) }, + { SPH_C32(0xb54900b0), SPH_C32(0xa7db4b2c), SPH_C32(0x3256a216), + SPH_C32(0xc676530a), SPH_C32(0xe23600e0), SPH_C32(0x3ba32dd9), + SPH_C32(0x6ce7edf2), SPH_C32(0xf12d3c81) }, + { SPH_C32(0xca2c00a0), SPH_C32(0x83f55f5e), SPH_C32(0xf26582e8), + SPH_C32(0x06d593d7), SPH_C32(0xb36a00f0), SPH_C32(0x7b505f22), + SPH_C32(0x9000cbf0), SPH_C32(0x807a6ce0) }, + { SPH_C32(0x9b7000b0), SPH_C32(0xc3062da5), SPH_C32(0x0e82a4ea), + SPH_C32(0x7782c3b6), SPH_C32(0x9d5300f0), SPH_C32(0x1f8d39ab), + SPH_C32(0xacd4cd0c), SPH_C32(0x318efc5c) }, + { SPH_C32(0x571100c0), SPH_C32(0x942efd4d), SPH_C32(0x78b3ae41), + SPH_C32(0x1504b8d6), SPH_C32(0x161c00c0), SPH_C32(0x7e54f492), + SPH_C32(0xf4a107fd), SPH_C32(0xd0018836) }, + { SPH_C32(0x064d00d0), SPH_C32(0xd4dd8fb6), SPH_C32(0x84548843), + SPH_C32(0x6453e8b7), SPH_C32(0x382500c0), SPH_C32(0x1a89921b), + SPH_C32(0xc8750101), SPH_C32(0x61f5188a) }, + { SPH_C32(0x792800c0), SPH_C32(0xf0f39bc4), SPH_C32(0x4467a8bd), + SPH_C32(0xa4f0286a), SPH_C32(0x697900d0), SPH_C32(0x5a7ae0e0), + SPH_C32(0x34922703), SPH_C32(0x10a248eb) }, + { SPH_C32(0x287400d0), SPH_C32(0xb000e93f), SPH_C32(0xb8808ebf), + SPH_C32(0xd5a7780b), SPH_C32(0x474000d0), SPH_C32(0x3ea78669), + SPH_C32(0x084621ff), SPH_C32(0xa156d857) }, + { SPH_C32(0xf5a900e0), SPH_C32(0x15c918bb), SPH_C32(0x817de245), + SPH_C32(0xf7ab1816), SPH_C32(0x4a6e00c0), SPH_C32(0xb7ee3980), + SPH_C32(0x8d080a04), SPH_C32(0xb3e8a94e) }, + { SPH_C32(0xa4f500f0), SPH_C32(0x553a6a40), SPH_C32(0x7d9ac447), + SPH_C32(0x86fc4877), SPH_C32(0x645700c0), SPH_C32(0xd3335f09), + SPH_C32(0xb1dc0cf8), SPH_C32(0x021c39f2) }, + { SPH_C32(0xdb9000e0), SPH_C32(0x71147e32), SPH_C32(0xbda9e4b9), + SPH_C32(0x465f88aa), SPH_C32(0x350b00d0), SPH_C32(0x93c02df2), + SPH_C32(0x4d3b2afa), SPH_C32(0x734b6993) }, + { SPH_C32(0x8acc00f0), SPH_C32(0x31e70cc9), SPH_C32(0x414ec2bb), + SPH_C32(0x3708d8cb), SPH_C32(0x1b3200d0), SPH_C32(0xf71d4b7b), + SPH_C32(0x71ef2c06), SPH_C32(0xc2bff92f) }, + { SPH_C32(0x0b6300c0), SPH_C32(0x5d94305f), SPH_C32(0x011aa3b8), + SPH_C32(0x76ed99ae), SPH_C32(0xe8d600e0), SPH_C32(0x3609dc76), + SPH_C32(0x74c64600), SPH_C32(0x5147098e) }, + { SPH_C32(0x5a3f00d0), SPH_C32(0x1d6742a4), SPH_C32(0xfdfd85ba), + SPH_C32(0x07bac9cf), SPH_C32(0xc6ef00e0), SPH_C32(0x52d4baff), + SPH_C32(0x481240fc), SPH_C32(0xe0b39932) }, + { SPH_C32(0x255a00c0), SPH_C32(0x394956d6), SPH_C32(0x3dcea544), + SPH_C32(0xc7190912), SPH_C32(0x97b300f0), SPH_C32(0x1227c804), + SPH_C32(0xb4f566fe), SPH_C32(0x91e4c953) }, + { SPH_C32(0x740600d0), SPH_C32(0x79ba242d), SPH_C32(0xc1298346), + SPH_C32(0xb64e5973), SPH_C32(0xb98a00f0), SPH_C32(0x76faae8d), + SPH_C32(0x88216002), SPH_C32(0x201059ef) }, + { SPH_C32(0xa9db00e0), SPH_C32(0xdc73d5a9), SPH_C32(0xf8d4efbc), + SPH_C32(0x9442396e), SPH_C32(0xb4a400e0), SPH_C32(0xffb31164), + SPH_C32(0x0d6f4bf9), SPH_C32(0x32ae28f6) }, + { SPH_C32(0xf88700f0), SPH_C32(0x9c80a752), SPH_C32(0x0433c9be), + SPH_C32(0xe515690f), SPH_C32(0x9a9d00e0), SPH_C32(0x9b6e77ed), + SPH_C32(0x31bb4d05), SPH_C32(0x835ab84a) }, + { SPH_C32(0x87e200e0), SPH_C32(0xb8aeb320), SPH_C32(0xc400e940), + SPH_C32(0x25b6a9d2), SPH_C32(0xcbc100f0), SPH_C32(0xdb9d0516), + SPH_C32(0xcd5c6b07), SPH_C32(0xf20de82b) }, + { SPH_C32(0xd6be00f0), SPH_C32(0xf85dc1db), SPH_C32(0x38e7cf42), + SPH_C32(0x54e1f9b3), SPH_C32(0xe5f800f0), SPH_C32(0xbf40639f), + SPH_C32(0xf1886dfb), SPH_C32(0x43f97897) } +}; + +static const sph_u32 T256_24[256][8] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000) }, + { SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), SPH_C32(0xae0ebb05), + SPH_C32(0xb5a4c63b), SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), + SPH_C32(0x6bf648a4), SPH_C32(0x539cbdbf) }, + { SPH_C32(0xc8f10000), SPH_C32(0x0b2de782), SPH_C32(0x6bf648a4), + SPH_C32(0x539cbdbf), SPH_C32(0x08bf0001), SPH_C32(0x38942792), + SPH_C32(0xc5f8f3a1), SPH_C32(0xe6387b84) }, + { SPH_C32(0x08bf0001), SPH_C32(0x38942792), SPH_C32(0xc5f8f3a1), + SPH_C32(0xe6387b84), SPH_C32(0xc04e0001), SPH_C32(0x33b9c010), + SPH_C32(0xae0ebb05), SPH_C32(0xb5a4c63b) }, + { SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), SPH_C32(0x99e585aa), + SPH_C32(0x8d75f7f1), SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), + SPH_C32(0x79e22a4c), SPH_C32(0x1298bd46) }, + { SPH_C32(0x486d0003), SPH_C32(0x6c5e67a3), SPH_C32(0x37eb3eaf), + SPH_C32(0x38d131ca), SPH_C32(0x995d0000), SPH_C32(0x2ecee896), + SPH_C32(0x121462e8), SPH_C32(0x410400f9) }, + { SPH_C32(0x40d20002), SPH_C32(0x54ca4031), SPH_C32(0xf213cd0e), + SPH_C32(0xdee94a4e), SPH_C32(0x59130001), SPH_C32(0x1d772886), + SPH_C32(0xbc1ad9ed), SPH_C32(0xf4a0c6c2) }, + { SPH_C32(0x809c0003), SPH_C32(0x67738021), SPH_C32(0x5c1d760b), + SPH_C32(0x6b4d8c75), SPH_C32(0x91e20001), SPH_C32(0x165acf04), + SPH_C32(0xd7ec9149), SPH_C32(0xa73c7b7d) }, + { SPH_C32(0x51ac0000), SPH_C32(0x25e30f14), SPH_C32(0x79e22a4c), + SPH_C32(0x1298bd46), SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), + SPH_C32(0xe007afe6), SPH_C32(0x9fed4ab7) }, + { SPH_C32(0x91e20001), SPH_C32(0x165acf04), SPH_C32(0xd7ec9149), + SPH_C32(0xa73c7b7d), SPH_C32(0x117e0002), SPH_C32(0x71294f25), + SPH_C32(0x8bf1e742), SPH_C32(0xcc71f708) }, + { SPH_C32(0x995d0000), SPH_C32(0x2ecee896), SPH_C32(0x121462e8), + SPH_C32(0x410400f9), SPH_C32(0xd1300003), SPH_C32(0x42908f35), + SPH_C32(0x25ff5c47), SPH_C32(0x79d53133) }, + { SPH_C32(0x59130001), SPH_C32(0x1d772886), SPH_C32(0xbc1ad9ed), + SPH_C32(0xf4a0c6c2), SPH_C32(0x19c10003), SPH_C32(0x49bd68b7), + SPH_C32(0x4e0914e3), SPH_C32(0x2a498c8c) }, + { SPH_C32(0xd98f0002), SPH_C32(0x7a04a8a7), SPH_C32(0xe007afe6), + SPH_C32(0x9fed4ab7), SPH_C32(0x88230002), SPH_C32(0x5fe7a7b3), + SPH_C32(0x99e585aa), SPH_C32(0x8d75f7f1) }, + { SPH_C32(0x19c10003), SPH_C32(0x49bd68b7), SPH_C32(0x4e0914e3), + SPH_C32(0x2a498c8c), SPH_C32(0x40d20002), SPH_C32(0x54ca4031), + SPH_C32(0xf213cd0e), SPH_C32(0xdee94a4e) }, + { SPH_C32(0x117e0002), SPH_C32(0x71294f25), SPH_C32(0x8bf1e742), + SPH_C32(0xcc71f708), SPH_C32(0x809c0003), SPH_C32(0x67738021), + SPH_C32(0x5c1d760b), SPH_C32(0x6b4d8c75) }, + { SPH_C32(0xd1300003), SPH_C32(0x42908f35), SPH_C32(0x25ff5c47), + SPH_C32(0x79d53133), SPH_C32(0x486d0003), SPH_C32(0x6c5e67a3), + SPH_C32(0x37eb3eaf), SPH_C32(0x38d131ca) }, + { SPH_C32(0xd0080004), SPH_C32(0x8c768f77), SPH_C32(0x9dc5b050), + SPH_C32(0xaf4a29da), SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), + SPH_C32(0x98321c3d), SPH_C32(0x76acc733) }, + { SPH_C32(0x10460005), SPH_C32(0xbfcf4f67), SPH_C32(0x33cb0b55), + SPH_C32(0x1aeeefe1), SPH_C32(0xa3580000), SPH_C32(0x4bc61e28), + SPH_C32(0xf3c45499), SPH_C32(0x25307a8c) }, + { SPH_C32(0x18f90004), SPH_C32(0x875b68f5), SPH_C32(0xf633f8f4), + SPH_C32(0xfcd69465), SPH_C32(0x63160001), SPH_C32(0x787fde38), + SPH_C32(0x5dcaef9c), SPH_C32(0x9094bcb7) }, + { SPH_C32(0xd8b70005), SPH_C32(0xb4e2a8e5), SPH_C32(0x583d43f1), + SPH_C32(0x4972525e), SPH_C32(0xabe70001), SPH_C32(0x735239ba), + SPH_C32(0x363ca738), SPH_C32(0xc3080108) }, + { SPH_C32(0x582b0006), SPH_C32(0xd39128c4), SPH_C32(0x042035fa), + SPH_C32(0x223fde2b), SPH_C32(0x3a050000), SPH_C32(0x6508f6be), + SPH_C32(0xe1d03671), SPH_C32(0x64347a75) }, + { SPH_C32(0x98650007), SPH_C32(0xe028e8d4), SPH_C32(0xaa2e8eff), + SPH_C32(0x979b1810), SPH_C32(0xf2f40000), SPH_C32(0x6e25113c), + SPH_C32(0x8a267ed5), SPH_C32(0x37a8c7ca) }, + { SPH_C32(0x90da0006), SPH_C32(0xd8bccf46), SPH_C32(0x6fd67d5e), + SPH_C32(0x71a36394), SPH_C32(0x32ba0001), SPH_C32(0x5d9cd12c), + SPH_C32(0x2428c5d0), SPH_C32(0x820c01f1) }, + { SPH_C32(0x50940007), SPH_C32(0xeb050f56), SPH_C32(0xc1d8c65b), + SPH_C32(0xc407a5af), SPH_C32(0xfa4b0001), SPH_C32(0x56b136ae), + SPH_C32(0x4fde8d74), SPH_C32(0xd190bc4e) }, + { SPH_C32(0x81a40004), SPH_C32(0xa9958063), SPH_C32(0xe4279a1c), + SPH_C32(0xbdd2949c), SPH_C32(0xb2260002), SPH_C32(0x3aef510d), + SPH_C32(0x7835b3db), SPH_C32(0xe9418d84) }, + { SPH_C32(0x41ea0005), SPH_C32(0x9a2c4073), SPH_C32(0x4a292119), + SPH_C32(0x087652a7), SPH_C32(0x7ad70002), SPH_C32(0x31c2b68f), + SPH_C32(0x13c3fb7f), SPH_C32(0xbadd303b) }, + { SPH_C32(0x49550004), SPH_C32(0xa2b867e1), SPH_C32(0x8fd1d2b8), + SPH_C32(0xee4e2923), SPH_C32(0xba990003), SPH_C32(0x027b769f), + SPH_C32(0xbdcd407a), SPH_C32(0x0f79f600) }, + { SPH_C32(0x891b0005), SPH_C32(0x9101a7f1), SPH_C32(0x21df69bd), + SPH_C32(0x5beaef18), SPH_C32(0x72680003), SPH_C32(0x0956911d), + SPH_C32(0xd63b08de), SPH_C32(0x5ce54bbf) }, + { SPH_C32(0x09870006), SPH_C32(0xf67227d0), SPH_C32(0x7dc21fb6), + SPH_C32(0x30a7636d), SPH_C32(0xe38a0002), SPH_C32(0x1f0c5e19), + SPH_C32(0x01d79997), SPH_C32(0xfbd930c2) }, + { SPH_C32(0xc9c90007), SPH_C32(0xc5cbe7c0), SPH_C32(0xd3cca4b3), + SPH_C32(0x8503a556), SPH_C32(0x2b7b0002), SPH_C32(0x1421b99b), + SPH_C32(0x6a21d133), SPH_C32(0xa8458d7d) }, + { SPH_C32(0xc1760006), SPH_C32(0xfd5fc052), SPH_C32(0x16345712), + SPH_C32(0x633bded2), SPH_C32(0xeb350003), SPH_C32(0x2798798b), + SPH_C32(0xc42f6a36), SPH_C32(0x1de14b46) }, + { SPH_C32(0x01380007), SPH_C32(0xcee60042), SPH_C32(0xb83aec17), + SPH_C32(0xd69f18e9), SPH_C32(0x23c40003), SPH_C32(0x2cb59e09), + SPH_C32(0xafd92292), SPH_C32(0x4e7df6f9) }, + { SPH_C32(0x6ba90000), SPH_C32(0x40ebf9aa), SPH_C32(0x98321c3d), + SPH_C32(0x76acc733), SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), + SPH_C32(0x05f7ac6d), SPH_C32(0xd9e6eee9) }, + { SPH_C32(0xabe70001), SPH_C32(0x735239ba), SPH_C32(0x363ca738), + SPH_C32(0xc3080108), SPH_C32(0x73500004), SPH_C32(0xc7b0915f), + SPH_C32(0x6e01e4c9), SPH_C32(0x8a7a5356) }, + { SPH_C32(0xa3580000), SPH_C32(0x4bc61e28), SPH_C32(0xf3c45499), + SPH_C32(0x25307a8c), SPH_C32(0xb31e0005), SPH_C32(0xf409514f), + SPH_C32(0xc00f5fcc), SPH_C32(0x3fde956d) }, + { SPH_C32(0x63160001), SPH_C32(0x787fde38), SPH_C32(0x5dcaef9c), + SPH_C32(0x9094bcb7), SPH_C32(0x7bef0005), SPH_C32(0xff24b6cd), + SPH_C32(0xabf91768), SPH_C32(0x6c4228d2) }, + { SPH_C32(0xe38a0002), SPH_C32(0x1f0c5e19), SPH_C32(0x01d79997), + SPH_C32(0xfbd930c2), SPH_C32(0xea0d0004), SPH_C32(0xe97e79c9), + SPH_C32(0x7c158621), SPH_C32(0xcb7e53af) }, + { SPH_C32(0x23c40003), SPH_C32(0x2cb59e09), SPH_C32(0xafd92292), + SPH_C32(0x4e7df6f9), SPH_C32(0x22fc0004), SPH_C32(0xe2539e4b), + SPH_C32(0x17e3ce85), SPH_C32(0x98e2ee10) }, + { SPH_C32(0x2b7b0002), SPH_C32(0x1421b99b), SPH_C32(0x6a21d133), + SPH_C32(0xa8458d7d), SPH_C32(0xe2b20005), SPH_C32(0xd1ea5e5b), + SPH_C32(0xb9ed7580), SPH_C32(0x2d46282b) }, + { SPH_C32(0xeb350003), SPH_C32(0x2798798b), SPH_C32(0xc42f6a36), + SPH_C32(0x1de14b46), SPH_C32(0x2a430005), SPH_C32(0xdac7b9d9), + SPH_C32(0xd21b3d24), SPH_C32(0x7eda9594) }, + { SPH_C32(0x3a050000), SPH_C32(0x6508f6be), SPH_C32(0xe1d03671), + SPH_C32(0x64347a75), SPH_C32(0x622e0006), SPH_C32(0xb699de7a), + SPH_C32(0xe5f0038b), SPH_C32(0x460ba45e) }, + { SPH_C32(0xfa4b0001), SPH_C32(0x56b136ae), SPH_C32(0x4fde8d74), + SPH_C32(0xd190bc4e), SPH_C32(0xaadf0006), SPH_C32(0xbdb439f8), + SPH_C32(0x8e064b2f), SPH_C32(0x159719e1) }, + { SPH_C32(0xf2f40000), SPH_C32(0x6e25113c), SPH_C32(0x8a267ed5), + SPH_C32(0x37a8c7ca), SPH_C32(0x6a910007), SPH_C32(0x8e0df9e8), + SPH_C32(0x2008f02a), SPH_C32(0xa033dfda) }, + { SPH_C32(0x32ba0001), SPH_C32(0x5d9cd12c), SPH_C32(0x2428c5d0), + SPH_C32(0x820c01f1), SPH_C32(0xa2600007), SPH_C32(0x85201e6a), + SPH_C32(0x4bfeb88e), SPH_C32(0xf3af6265) }, + { SPH_C32(0xb2260002), SPH_C32(0x3aef510d), SPH_C32(0x7835b3db), + SPH_C32(0xe9418d84), SPH_C32(0x33820006), SPH_C32(0x937ad16e), + SPH_C32(0x9c1229c7), SPH_C32(0x54931918) }, + { SPH_C32(0x72680003), SPH_C32(0x0956911d), SPH_C32(0xd63b08de), + SPH_C32(0x5ce54bbf), SPH_C32(0xfb730006), SPH_C32(0x985736ec), + SPH_C32(0xf7e46163), SPH_C32(0x070fa4a7) }, + { SPH_C32(0x7ad70002), SPH_C32(0x31c2b68f), SPH_C32(0x13c3fb7f), + SPH_C32(0xbadd303b), SPH_C32(0x3b3d0007), SPH_C32(0xabeef6fc), + SPH_C32(0x59eada66), SPH_C32(0xb2ab629c) }, + { SPH_C32(0xba990003), SPH_C32(0x027b769f), SPH_C32(0xbdcd407a), + SPH_C32(0x0f79f600), SPH_C32(0xf3cc0007), SPH_C32(0xa0c3117e), + SPH_C32(0x321c92c2), SPH_C32(0xe137df23) }, + { SPH_C32(0xbba10004), SPH_C32(0xcc9d76dd), SPH_C32(0x05f7ac6d), + SPH_C32(0xd9e6eee9), SPH_C32(0xd0080004), SPH_C32(0x8c768f77), + SPH_C32(0x9dc5b050), SPH_C32(0xaf4a29da) }, + { SPH_C32(0x7bef0005), SPH_C32(0xff24b6cd), SPH_C32(0xabf91768), + SPH_C32(0x6c4228d2), SPH_C32(0x18f90004), SPH_C32(0x875b68f5), + SPH_C32(0xf633f8f4), SPH_C32(0xfcd69465) }, + { SPH_C32(0x73500004), SPH_C32(0xc7b0915f), SPH_C32(0x6e01e4c9), + SPH_C32(0x8a7a5356), SPH_C32(0xd8b70005), SPH_C32(0xb4e2a8e5), + SPH_C32(0x583d43f1), SPH_C32(0x4972525e) }, + { SPH_C32(0xb31e0005), SPH_C32(0xf409514f), SPH_C32(0xc00f5fcc), + SPH_C32(0x3fde956d), SPH_C32(0x10460005), SPH_C32(0xbfcf4f67), + SPH_C32(0x33cb0b55), SPH_C32(0x1aeeefe1) }, + { SPH_C32(0x33820006), SPH_C32(0x937ad16e), SPH_C32(0x9c1229c7), + SPH_C32(0x54931918), SPH_C32(0x81a40004), SPH_C32(0xa9958063), + SPH_C32(0xe4279a1c), SPH_C32(0xbdd2949c) }, + { SPH_C32(0xf3cc0007), SPH_C32(0xa0c3117e), SPH_C32(0x321c92c2), + SPH_C32(0xe137df23), SPH_C32(0x49550004), SPH_C32(0xa2b867e1), + SPH_C32(0x8fd1d2b8), SPH_C32(0xee4e2923) }, + { SPH_C32(0xfb730006), SPH_C32(0x985736ec), SPH_C32(0xf7e46163), + SPH_C32(0x070fa4a7), SPH_C32(0x891b0005), SPH_C32(0x9101a7f1), + SPH_C32(0x21df69bd), SPH_C32(0x5beaef18) }, + { SPH_C32(0x3b3d0007), SPH_C32(0xabeef6fc), SPH_C32(0x59eada66), + SPH_C32(0xb2ab629c), SPH_C32(0x41ea0005), SPH_C32(0x9a2c4073), + SPH_C32(0x4a292119), SPH_C32(0x087652a7) }, + { SPH_C32(0xea0d0004), SPH_C32(0xe97e79c9), SPH_C32(0x7c158621), + SPH_C32(0xcb7e53af), SPH_C32(0x09870006), SPH_C32(0xf67227d0), + SPH_C32(0x7dc21fb6), SPH_C32(0x30a7636d) }, + { SPH_C32(0x2a430005), SPH_C32(0xdac7b9d9), SPH_C32(0xd21b3d24), + SPH_C32(0x7eda9594), SPH_C32(0xc1760006), SPH_C32(0xfd5fc052), + SPH_C32(0x16345712), SPH_C32(0x633bded2) }, + { SPH_C32(0x22fc0004), SPH_C32(0xe2539e4b), SPH_C32(0x17e3ce85), + SPH_C32(0x98e2ee10), SPH_C32(0x01380007), SPH_C32(0xcee60042), + SPH_C32(0xb83aec17), SPH_C32(0xd69f18e9) }, + { SPH_C32(0xe2b20005), SPH_C32(0xd1ea5e5b), SPH_C32(0xb9ed7580), + SPH_C32(0x2d46282b), SPH_C32(0xc9c90007), SPH_C32(0xc5cbe7c0), + SPH_C32(0xd3cca4b3), SPH_C32(0x8503a556) }, + { SPH_C32(0x622e0006), SPH_C32(0xb699de7a), SPH_C32(0xe5f0038b), + SPH_C32(0x460ba45e), SPH_C32(0x582b0006), SPH_C32(0xd39128c4), + SPH_C32(0x042035fa), SPH_C32(0x223fde2b) }, + { SPH_C32(0xa2600007), SPH_C32(0x85201e6a), SPH_C32(0x4bfeb88e), + SPH_C32(0xf3af6265), SPH_C32(0x90da0006), SPH_C32(0xd8bccf46), + SPH_C32(0x6fd67d5e), SPH_C32(0x71a36394) }, + { SPH_C32(0xaadf0006), SPH_C32(0xbdb439f8), SPH_C32(0x8e064b2f), + SPH_C32(0x159719e1), SPH_C32(0x50940007), SPH_C32(0xeb050f56), + SPH_C32(0xc1d8c65b), SPH_C32(0xc407a5af) }, + { SPH_C32(0x6a910007), SPH_C32(0x8e0df9e8), SPH_C32(0x2008f02a), + SPH_C32(0xa033dfda), SPH_C32(0x98650007), SPH_C32(0xe028e8d4), + SPH_C32(0xaa2e8eff), SPH_C32(0x979b1810) }, + { SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), SPH_C32(0xfe739301), + SPH_C32(0xb8a92831), SPH_C32(0x171c0000), SPH_C32(0xb26e3344), + SPH_C32(0x9e6a837e), SPH_C32(0x58f8485f) }, + { SPH_C32(0x68e00009), SPH_C32(0x13c0f96d), SPH_C32(0x507d2804), + SPH_C32(0x0d0dee0a), SPH_C32(0xdfed0000), SPH_C32(0xb943d4c6), + SPH_C32(0xf59ccbda), SPH_C32(0x0b64f5e0) }, + { SPH_C32(0x605f0008), SPH_C32(0x2b54deff), SPH_C32(0x9585dba5), + SPH_C32(0xeb35958e), SPH_C32(0x1fa30001), SPH_C32(0x8afa14d6), + SPH_C32(0x5b9270df), SPH_C32(0xbec033db) }, + { SPH_C32(0xa0110009), SPH_C32(0x18ed1eef), SPH_C32(0x3b8b60a0), + SPH_C32(0x5e9153b5), SPH_C32(0xd7520001), SPH_C32(0x81d7f354), + SPH_C32(0x3064387b), SPH_C32(0xed5c8e64) }, + { SPH_C32(0x208d000a), SPH_C32(0x7f9e9ece), SPH_C32(0x679616ab), + SPH_C32(0x35dcdfc0), SPH_C32(0x46b00000), SPH_C32(0x978d3c50), + SPH_C32(0xe788a932), SPH_C32(0x4a60f519) }, + { SPH_C32(0xe0c3000b), SPH_C32(0x4c275ede), SPH_C32(0xc998adae), + SPH_C32(0x807819fb), SPH_C32(0x8e410000), SPH_C32(0x9ca0dbd2), + SPH_C32(0x8c7ee196), SPH_C32(0x19fc48a6) }, + { SPH_C32(0xe87c000a), SPH_C32(0x74b3794c), SPH_C32(0x0c605e0f), + SPH_C32(0x6640627f), SPH_C32(0x4e0f0001), SPH_C32(0xaf191bc2), + SPH_C32(0x22705a93), SPH_C32(0xac588e9d) }, + { SPH_C32(0x2832000b), SPH_C32(0x470ab95c), SPH_C32(0xa26ee50a), + SPH_C32(0xd3e4a444), SPH_C32(0x86fe0001), SPH_C32(0xa434fc40), + SPH_C32(0x49861237), SPH_C32(0xffc43322) }, + { SPH_C32(0xf9020008), SPH_C32(0x059a3669), SPH_C32(0x8791b94d), + SPH_C32(0xaa319577), SPH_C32(0xce930002), SPH_C32(0xc86a9be3), + SPH_C32(0x7e6d2c98), SPH_C32(0xc71502e8) }, + { SPH_C32(0x394c0009), SPH_C32(0x3623f679), SPH_C32(0x299f0248), + SPH_C32(0x1f95534c), SPH_C32(0x06620002), SPH_C32(0xc3477c61), + SPH_C32(0x159b643c), SPH_C32(0x9489bf57) }, + { SPH_C32(0x31f30008), SPH_C32(0x0eb7d1eb), SPH_C32(0xec67f1e9), + SPH_C32(0xf9ad28c8), SPH_C32(0xc62c0003), SPH_C32(0xf0febc71), + SPH_C32(0xbb95df39), SPH_C32(0x212d796c) }, + { SPH_C32(0xf1bd0009), SPH_C32(0x3d0e11fb), SPH_C32(0x42694aec), + SPH_C32(0x4c09eef3), SPH_C32(0x0edd0003), SPH_C32(0xfbd35bf3), + SPH_C32(0xd063979d), SPH_C32(0x72b1c4d3) }, + { SPH_C32(0x7121000a), SPH_C32(0x5a7d91da), SPH_C32(0x1e743ce7), + SPH_C32(0x27446286), SPH_C32(0x9f3f0002), SPH_C32(0xed8994f7), + SPH_C32(0x078f06d4), SPH_C32(0xd58dbfae) }, + { SPH_C32(0xb16f000b), SPH_C32(0x69c451ca), SPH_C32(0xb07a87e2), + SPH_C32(0x92e0a4bd), SPH_C32(0x57ce0002), SPH_C32(0xe6a47375), + SPH_C32(0x6c794e70), SPH_C32(0x86110211) }, + { SPH_C32(0xb9d0000a), SPH_C32(0x51507658), SPH_C32(0x75827443), + SPH_C32(0x74d8df39), SPH_C32(0x97800003), SPH_C32(0xd51db365), + SPH_C32(0xc277f575), SPH_C32(0x33b5c42a) }, + { SPH_C32(0x799e000b), SPH_C32(0x62e9b648), SPH_C32(0xdb8ccf46), + SPH_C32(0xc17c1902), SPH_C32(0x5f710003), SPH_C32(0xde3054e7), + SPH_C32(0xa981bdd1), SPH_C32(0x60297995) }, + { SPH_C32(0x78a6000c), SPH_C32(0xac0fb60a), SPH_C32(0x63b62351), + SPH_C32(0x17e301eb), SPH_C32(0x7cb50000), SPH_C32(0xf285caee), + SPH_C32(0x06589f43), SPH_C32(0x2e548f6c) }, + { SPH_C32(0xb8e8000d), SPH_C32(0x9fb6761a), SPH_C32(0xcdb89854), + SPH_C32(0xa247c7d0), SPH_C32(0xb4440000), SPH_C32(0xf9a82d6c), + SPH_C32(0x6daed7e7), SPH_C32(0x7dc832d3) }, + { SPH_C32(0xb057000c), SPH_C32(0xa7225188), SPH_C32(0x08406bf5), + SPH_C32(0x447fbc54), SPH_C32(0x740a0001), SPH_C32(0xca11ed7c), + SPH_C32(0xc3a06ce2), SPH_C32(0xc86cf4e8) }, + { SPH_C32(0x7019000d), SPH_C32(0x949b9198), SPH_C32(0xa64ed0f0), + SPH_C32(0xf1db7a6f), SPH_C32(0xbcfb0001), SPH_C32(0xc13c0afe), + SPH_C32(0xa8562446), SPH_C32(0x9bf04957) }, + { SPH_C32(0xf085000e), SPH_C32(0xf3e811b9), SPH_C32(0xfa53a6fb), + SPH_C32(0x9a96f61a), SPH_C32(0x2d190000), SPH_C32(0xd766c5fa), + SPH_C32(0x7fbab50f), SPH_C32(0x3ccc322a) }, + { SPH_C32(0x30cb000f), SPH_C32(0xc051d1a9), SPH_C32(0x545d1dfe), + SPH_C32(0x2f323021), SPH_C32(0xe5e80000), SPH_C32(0xdc4b2278), + SPH_C32(0x144cfdab), SPH_C32(0x6f508f95) }, + { SPH_C32(0x3874000e), SPH_C32(0xf8c5f63b), SPH_C32(0x91a5ee5f), + SPH_C32(0xc90a4ba5), SPH_C32(0x25a60001), SPH_C32(0xeff2e268), + SPH_C32(0xba4246ae), SPH_C32(0xdaf449ae) }, + { SPH_C32(0xf83a000f), SPH_C32(0xcb7c362b), SPH_C32(0x3fab555a), + SPH_C32(0x7cae8d9e), SPH_C32(0xed570001), SPH_C32(0xe4df05ea), + SPH_C32(0xd1b40e0a), SPH_C32(0x8968f411) }, + { SPH_C32(0x290a000c), SPH_C32(0x89ecb91e), SPH_C32(0x1a54091d), + SPH_C32(0x057bbcad), SPH_C32(0xa53a0002), SPH_C32(0x88816249), + SPH_C32(0xe65f30a5), SPH_C32(0xb1b9c5db) }, + { SPH_C32(0xe944000d), SPH_C32(0xba55790e), SPH_C32(0xb45ab218), + SPH_C32(0xb0df7a96), SPH_C32(0x6dcb0002), SPH_C32(0x83ac85cb), + SPH_C32(0x8da97801), SPH_C32(0xe2257864) }, + { SPH_C32(0xe1fb000c), SPH_C32(0x82c15e9c), SPH_C32(0x71a241b9), + SPH_C32(0x56e70112), SPH_C32(0xad850003), SPH_C32(0xb01545db), + SPH_C32(0x23a7c304), SPH_C32(0x5781be5f) }, + { SPH_C32(0x21b5000d), SPH_C32(0xb1789e8c), SPH_C32(0xdfacfabc), + SPH_C32(0xe343c729), SPH_C32(0x65740003), SPH_C32(0xbb38a259), + SPH_C32(0x48518ba0), SPH_C32(0x041d03e0) }, + { SPH_C32(0xa129000e), SPH_C32(0xd60b1ead), SPH_C32(0x83b18cb7), + SPH_C32(0x880e4b5c), SPH_C32(0xf4960002), SPH_C32(0xad626d5d), + SPH_C32(0x9fbd1ae9), SPH_C32(0xa321789d) }, + { SPH_C32(0x6167000f), SPH_C32(0xe5b2debd), SPH_C32(0x2dbf37b2), + SPH_C32(0x3daa8d67), SPH_C32(0x3c670002), SPH_C32(0xa64f8adf), + SPH_C32(0xf44b524d), SPH_C32(0xf0bdc522) }, + { SPH_C32(0x69d8000e), SPH_C32(0xdd26f92f), SPH_C32(0xe847c413), + SPH_C32(0xdb92f6e3), SPH_C32(0xfc290003), SPH_C32(0x95f64acf), + SPH_C32(0x5a45e948), SPH_C32(0x45190319) }, + { SPH_C32(0xa996000f), SPH_C32(0xee9f393f), SPH_C32(0x46497f16), + SPH_C32(0x6e3630d8), SPH_C32(0x34d80003), SPH_C32(0x9edbad4d), + SPH_C32(0x31b3a1ec), SPH_C32(0x1685bea6) }, + { SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), SPH_C32(0x66418f3c), + SPH_C32(0xce05ef02), SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), + SPH_C32(0x9b9d2f13), SPH_C32(0x811ea6b6) }, + { SPH_C32(0x03490009), SPH_C32(0x532b00c7), SPH_C32(0xc84f3439), + SPH_C32(0x7ba12939), SPH_C32(0x644c0004), SPH_C32(0x75dea21b), + SPH_C32(0xf06b67b7), SPH_C32(0xd2821b09) }, + { SPH_C32(0x0bf60008), SPH_C32(0x6bbf2755), SPH_C32(0x0db7c798), + SPH_C32(0x9d9952bd), SPH_C32(0xa4020005), SPH_C32(0x4667620b), + SPH_C32(0x5e65dcb2), SPH_C32(0x6726dd32) }, + { SPH_C32(0xcbb80009), SPH_C32(0x5806e745), SPH_C32(0xa3b97c9d), + SPH_C32(0x283d9486), SPH_C32(0x6cf30005), SPH_C32(0x4d4a8589), + SPH_C32(0x35939416), SPH_C32(0x34ba608d) }, + { SPH_C32(0x4b24000a), SPH_C32(0x3f756764), SPH_C32(0xffa40a96), + SPH_C32(0x437018f3), SPH_C32(0xfd110004), SPH_C32(0x5b104a8d), + SPH_C32(0xe27f055f), SPH_C32(0x93861bf0) }, + { SPH_C32(0x8b6a000b), SPH_C32(0x0ccca774), SPH_C32(0x51aab193), + SPH_C32(0xf6d4dec8), SPH_C32(0x35e00004), SPH_C32(0x503dad0f), + SPH_C32(0x89894dfb), SPH_C32(0xc01aa64f) }, + { SPH_C32(0x83d5000a), SPH_C32(0x345880e6), SPH_C32(0x94524232), + SPH_C32(0x10eca54c), SPH_C32(0xf5ae0005), SPH_C32(0x63846d1f), + SPH_C32(0x2787f6fe), SPH_C32(0x75be6074) }, + { SPH_C32(0x439b000b), SPH_C32(0x07e140f6), SPH_C32(0x3a5cf937), + SPH_C32(0xa5486377), SPH_C32(0x3d5f0005), SPH_C32(0x68a98a9d), + SPH_C32(0x4c71be5a), SPH_C32(0x2622ddcb) }, + { SPH_C32(0x92ab0008), SPH_C32(0x4571cfc3), SPH_C32(0x1fa3a570), + SPH_C32(0xdc9d5244), SPH_C32(0x75320006), SPH_C32(0x04f7ed3e), + SPH_C32(0x7b9a80f5), SPH_C32(0x1ef3ec01) }, + { SPH_C32(0x52e50009), SPH_C32(0x76c80fd3), SPH_C32(0xb1ad1e75), + SPH_C32(0x6939947f), SPH_C32(0xbdc30006), SPH_C32(0x0fda0abc), + SPH_C32(0x106cc851), SPH_C32(0x4d6f51be) }, + { SPH_C32(0x5a5a0008), SPH_C32(0x4e5c2841), SPH_C32(0x7455edd4), + SPH_C32(0x8f01effb), SPH_C32(0x7d8d0007), SPH_C32(0x3c63caac), + SPH_C32(0xbe627354), SPH_C32(0xf8cb9785) }, + { SPH_C32(0x9a140009), SPH_C32(0x7de5e851), SPH_C32(0xda5b56d1), + SPH_C32(0x3aa529c0), SPH_C32(0xb57c0007), SPH_C32(0x374e2d2e), + SPH_C32(0xd5943bf0), SPH_C32(0xab572a3a) }, + { SPH_C32(0x1a88000a), SPH_C32(0x1a966870), SPH_C32(0x864620da), + SPH_C32(0x51e8a5b5), SPH_C32(0x249e0006), SPH_C32(0x2114e22a), + SPH_C32(0x0278aab9), SPH_C32(0x0c6b5147) }, + { SPH_C32(0xdac6000b), SPH_C32(0x292fa860), SPH_C32(0x28489bdf), + SPH_C32(0xe44c638e), SPH_C32(0xec6f0006), SPH_C32(0x2a3905a8), + SPH_C32(0x698ee21d), SPH_C32(0x5ff7ecf8) }, + { SPH_C32(0xd279000a), SPH_C32(0x11bb8ff2), SPH_C32(0xedb0687e), + SPH_C32(0x0274180a), SPH_C32(0x2c210007), SPH_C32(0x1980c5b8), + SPH_C32(0xc7805918), SPH_C32(0xea532ac3) }, + { SPH_C32(0x1237000b), SPH_C32(0x22024fe2), SPH_C32(0x43bed37b), + SPH_C32(0xb7d0de31), SPH_C32(0xe4d00007), SPH_C32(0x12ad223a), + SPH_C32(0xac7611bc), SPH_C32(0xb9cf977c) }, + { SPH_C32(0x130f000c), SPH_C32(0xece44fa0), SPH_C32(0xfb843f6c), + SPH_C32(0x614fc6d8), SPH_C32(0xc7140004), SPH_C32(0x3e18bc33), + SPH_C32(0x03af332e), SPH_C32(0xf7b26185) }, + { SPH_C32(0xd341000d), SPH_C32(0xdf5d8fb0), SPH_C32(0x558a8469), + SPH_C32(0xd4eb00e3), SPH_C32(0x0fe50004), SPH_C32(0x35355bb1), + SPH_C32(0x68597b8a), SPH_C32(0xa42edc3a) }, + { SPH_C32(0xdbfe000c), SPH_C32(0xe7c9a822), SPH_C32(0x907277c8), + SPH_C32(0x32d37b67), SPH_C32(0xcfab0005), SPH_C32(0x068c9ba1), + SPH_C32(0xc657c08f), SPH_C32(0x118a1a01) }, + { SPH_C32(0x1bb0000d), SPH_C32(0xd4706832), SPH_C32(0x3e7ccccd), + SPH_C32(0x8777bd5c), SPH_C32(0x075a0005), SPH_C32(0x0da17c23), + SPH_C32(0xada1882b), SPH_C32(0x4216a7be) }, + { SPH_C32(0x9b2c000e), SPH_C32(0xb303e813), SPH_C32(0x6261bac6), + SPH_C32(0xec3a3129), SPH_C32(0x96b80004), SPH_C32(0x1bfbb327), + SPH_C32(0x7a4d1962), SPH_C32(0xe52adcc3) }, + { SPH_C32(0x5b62000f), SPH_C32(0x80ba2803), SPH_C32(0xcc6f01c3), + SPH_C32(0x599ef712), SPH_C32(0x5e490004), SPH_C32(0x10d654a5), + SPH_C32(0x11bb51c6), SPH_C32(0xb6b6617c) }, + { SPH_C32(0x53dd000e), SPH_C32(0xb82e0f91), SPH_C32(0x0997f262), + SPH_C32(0xbfa68c96), SPH_C32(0x9e070005), SPH_C32(0x236f94b5), + SPH_C32(0xbfb5eac3), SPH_C32(0x0312a747) }, + { SPH_C32(0x9393000f), SPH_C32(0x8b97cf81), SPH_C32(0xa7994967), + SPH_C32(0x0a024aad), SPH_C32(0x56f60005), SPH_C32(0x28427337), + SPH_C32(0xd443a267), SPH_C32(0x508e1af8) }, + { SPH_C32(0x42a3000c), SPH_C32(0xc90740b4), SPH_C32(0x82661520), + SPH_C32(0x73d77b9e), SPH_C32(0x1e9b0006), SPH_C32(0x441c1494), + SPH_C32(0xe3a89cc8), SPH_C32(0x685f2b32) }, + { SPH_C32(0x82ed000d), SPH_C32(0xfabe80a4), SPH_C32(0x2c68ae25), + SPH_C32(0xc673bda5), SPH_C32(0xd66a0006), SPH_C32(0x4f31f316), + SPH_C32(0x885ed46c), SPH_C32(0x3bc3968d) }, + { SPH_C32(0x8a52000c), SPH_C32(0xc22aa736), SPH_C32(0xe9905d84), + SPH_C32(0x204bc621), SPH_C32(0x16240007), SPH_C32(0x7c883306), + SPH_C32(0x26506f69), SPH_C32(0x8e6750b6) }, + { SPH_C32(0x4a1c000d), SPH_C32(0xf1936726), SPH_C32(0x479ee681), + SPH_C32(0x95ef001a), SPH_C32(0xded50007), SPH_C32(0x77a5d484), + SPH_C32(0x4da627cd), SPH_C32(0xddfbed09) }, + { SPH_C32(0xca80000e), SPH_C32(0x96e0e707), SPH_C32(0x1b83908a), + SPH_C32(0xfea28c6f), SPH_C32(0x4f370006), SPH_C32(0x61ff1b80), + SPH_C32(0x9a4ab684), SPH_C32(0x7ac79674) }, + { SPH_C32(0x0ace000f), SPH_C32(0xa5592717), SPH_C32(0xb58d2b8f), + SPH_C32(0x4b064a54), SPH_C32(0x87c60006), SPH_C32(0x6ad2fc02), + SPH_C32(0xf1bcfe20), SPH_C32(0x295b2bcb) }, + { SPH_C32(0x0271000e), SPH_C32(0x9dcd0085), SPH_C32(0x7075d82e), + SPH_C32(0xad3e31d0), SPH_C32(0x47880007), SPH_C32(0x596b3c12), + SPH_C32(0x5fb24525), SPH_C32(0x9cffedf0) }, + { SPH_C32(0xc23f000f), SPH_C32(0xae74c095), SPH_C32(0xde7b632b), + SPH_C32(0x189af7eb), SPH_C32(0x8f790007), SPH_C32(0x5246db90), + SPH_C32(0x34440d81), SPH_C32(0xcf63504f) }, + { SPH_C32(0x171c0000), SPH_C32(0xb26e3344), SPH_C32(0x9e6a837e), + SPH_C32(0x58f8485f), SPH_C32(0xbfb20008), SPH_C32(0x92170a39), + SPH_C32(0x6019107f), SPH_C32(0xe051606e) }, + { SPH_C32(0xd7520001), SPH_C32(0x81d7f354), SPH_C32(0x3064387b), + SPH_C32(0xed5c8e64), SPH_C32(0x77430008), SPH_C32(0x993aedbb), + SPH_C32(0x0bef58db), SPH_C32(0xb3cdddd1) }, + { SPH_C32(0xdfed0000), SPH_C32(0xb943d4c6), SPH_C32(0xf59ccbda), + SPH_C32(0x0b64f5e0), SPH_C32(0xb70d0009), SPH_C32(0xaa832dab), + SPH_C32(0xa5e1e3de), SPH_C32(0x06691bea) }, + { SPH_C32(0x1fa30001), SPH_C32(0x8afa14d6), SPH_C32(0x5b9270df), + SPH_C32(0xbec033db), SPH_C32(0x7ffc0009), SPH_C32(0xa1aeca29), + SPH_C32(0xce17ab7a), SPH_C32(0x55f5a655) }, + { SPH_C32(0x9f3f0002), SPH_C32(0xed8994f7), SPH_C32(0x078f06d4), + SPH_C32(0xd58dbfae), SPH_C32(0xee1e0008), SPH_C32(0xb7f4052d), + SPH_C32(0x19fb3a33), SPH_C32(0xf2c9dd28) }, + { SPH_C32(0x5f710003), SPH_C32(0xde3054e7), SPH_C32(0xa981bdd1), + SPH_C32(0x60297995), SPH_C32(0x26ef0008), SPH_C32(0xbcd9e2af), + SPH_C32(0x720d7297), SPH_C32(0xa1556097) }, + { SPH_C32(0x57ce0002), SPH_C32(0xe6a47375), SPH_C32(0x6c794e70), + SPH_C32(0x86110211), SPH_C32(0xe6a10009), SPH_C32(0x8f6022bf), + SPH_C32(0xdc03c992), SPH_C32(0x14f1a6ac) }, + { SPH_C32(0x97800003), SPH_C32(0xd51db365), SPH_C32(0xc277f575), + SPH_C32(0x33b5c42a), SPH_C32(0x2e500009), SPH_C32(0x844dc53d), + SPH_C32(0xb7f58136), SPH_C32(0x476d1b13) }, + { SPH_C32(0x46b00000), SPH_C32(0x978d3c50), SPH_C32(0xe788a932), + SPH_C32(0x4a60f519), SPH_C32(0x663d000a), SPH_C32(0xe813a29e), + SPH_C32(0x801ebf99), SPH_C32(0x7fbc2ad9) }, + { SPH_C32(0x86fe0001), SPH_C32(0xa434fc40), SPH_C32(0x49861237), + SPH_C32(0xffc43322), SPH_C32(0xaecc000a), SPH_C32(0xe33e451c), + SPH_C32(0xebe8f73d), SPH_C32(0x2c209766) }, + { SPH_C32(0x8e410000), SPH_C32(0x9ca0dbd2), SPH_C32(0x8c7ee196), + SPH_C32(0x19fc48a6), SPH_C32(0x6e82000b), SPH_C32(0xd087850c), + SPH_C32(0x45e64c38), SPH_C32(0x9984515d) }, + { SPH_C32(0x4e0f0001), SPH_C32(0xaf191bc2), SPH_C32(0x22705a93), + SPH_C32(0xac588e9d), SPH_C32(0xa673000b), SPH_C32(0xdbaa628e), + SPH_C32(0x2e10049c), SPH_C32(0xca18ece2) }, + { SPH_C32(0xce930002), SPH_C32(0xc86a9be3), SPH_C32(0x7e6d2c98), + SPH_C32(0xc71502e8), SPH_C32(0x3791000a), SPH_C32(0xcdf0ad8a), + SPH_C32(0xf9fc95d5), SPH_C32(0x6d24979f) }, + { SPH_C32(0x0edd0003), SPH_C32(0xfbd35bf3), SPH_C32(0xd063979d), + SPH_C32(0x72b1c4d3), SPH_C32(0xff60000a), SPH_C32(0xc6dd4a08), + SPH_C32(0x920add71), SPH_C32(0x3eb82a20) }, + { SPH_C32(0x06620002), SPH_C32(0xc3477c61), SPH_C32(0x159b643c), + SPH_C32(0x9489bf57), SPH_C32(0x3f2e000b), SPH_C32(0xf5648a18), + SPH_C32(0x3c046674), SPH_C32(0x8b1cec1b) }, + { SPH_C32(0xc62c0003), SPH_C32(0xf0febc71), SPH_C32(0xbb95df39), + SPH_C32(0x212d796c), SPH_C32(0xf7df000b), SPH_C32(0xfe496d9a), + SPH_C32(0x57f22ed0), SPH_C32(0xd88051a4) }, + { SPH_C32(0xc7140004), SPH_C32(0x3e18bc33), SPH_C32(0x03af332e), + SPH_C32(0xf7b26185), SPH_C32(0xd41b0008), SPH_C32(0xd2fcf393), + SPH_C32(0xf82b0c42), SPH_C32(0x96fda75d) }, + { SPH_C32(0x075a0005), SPH_C32(0x0da17c23), SPH_C32(0xada1882b), + SPH_C32(0x4216a7be), SPH_C32(0x1cea0008), SPH_C32(0xd9d11411), + SPH_C32(0x93dd44e6), SPH_C32(0xc5611ae2) }, + { SPH_C32(0x0fe50004), SPH_C32(0x35355bb1), SPH_C32(0x68597b8a), + SPH_C32(0xa42edc3a), SPH_C32(0xdca40009), SPH_C32(0xea68d401), + SPH_C32(0x3dd3ffe3), SPH_C32(0x70c5dcd9) }, + { SPH_C32(0xcfab0005), SPH_C32(0x068c9ba1), SPH_C32(0xc657c08f), + SPH_C32(0x118a1a01), SPH_C32(0x14550009), SPH_C32(0xe1453383), + SPH_C32(0x5625b747), SPH_C32(0x23596166) }, + { SPH_C32(0x4f370006), SPH_C32(0x61ff1b80), SPH_C32(0x9a4ab684), + SPH_C32(0x7ac79674), SPH_C32(0x85b70008), SPH_C32(0xf71ffc87), + SPH_C32(0x81c9260e), SPH_C32(0x84651a1b) }, + { SPH_C32(0x8f790007), SPH_C32(0x5246db90), SPH_C32(0x34440d81), + SPH_C32(0xcf63504f), SPH_C32(0x4d460008), SPH_C32(0xfc321b05), + SPH_C32(0xea3f6eaa), SPH_C32(0xd7f9a7a4) }, + { SPH_C32(0x87c60006), SPH_C32(0x6ad2fc02), SPH_C32(0xf1bcfe20), + SPH_C32(0x295b2bcb), SPH_C32(0x8d080009), SPH_C32(0xcf8bdb15), + SPH_C32(0x4431d5af), SPH_C32(0x625d619f) }, + { SPH_C32(0x47880007), SPH_C32(0x596b3c12), SPH_C32(0x5fb24525), + SPH_C32(0x9cffedf0), SPH_C32(0x45f90009), SPH_C32(0xc4a63c97), + SPH_C32(0x2fc79d0b), SPH_C32(0x31c1dc20) }, + { SPH_C32(0x96b80004), SPH_C32(0x1bfbb327), SPH_C32(0x7a4d1962), + SPH_C32(0xe52adcc3), SPH_C32(0x0d94000a), SPH_C32(0xa8f85b34), + SPH_C32(0x182ca3a4), SPH_C32(0x0910edea) }, + { SPH_C32(0x56f60005), SPH_C32(0x28427337), SPH_C32(0xd443a267), + SPH_C32(0x508e1af8), SPH_C32(0xc565000a), SPH_C32(0xa3d5bcb6), + SPH_C32(0x73daeb00), SPH_C32(0x5a8c5055) }, + { SPH_C32(0x5e490004), SPH_C32(0x10d654a5), SPH_C32(0x11bb51c6), + SPH_C32(0xb6b6617c), SPH_C32(0x052b000b), SPH_C32(0x906c7ca6), + SPH_C32(0xddd45005), SPH_C32(0xef28966e) }, + { SPH_C32(0x9e070005), SPH_C32(0x236f94b5), SPH_C32(0xbfb5eac3), + SPH_C32(0x0312a747), SPH_C32(0xcdda000b), SPH_C32(0x9b419b24), + SPH_C32(0xb62218a1), SPH_C32(0xbcb42bd1) }, + { SPH_C32(0x1e9b0006), SPH_C32(0x441c1494), SPH_C32(0xe3a89cc8), + SPH_C32(0x685f2b32), SPH_C32(0x5c38000a), SPH_C32(0x8d1b5420), + SPH_C32(0x61ce89e8), SPH_C32(0x1b8850ac) }, + { SPH_C32(0xded50007), SPH_C32(0x77a5d484), SPH_C32(0x4da627cd), + SPH_C32(0xddfbed09), SPH_C32(0x94c9000a), SPH_C32(0x8636b3a2), + SPH_C32(0x0a38c14c), SPH_C32(0x4814ed13) }, + { SPH_C32(0xd66a0006), SPH_C32(0x4f31f316), SPH_C32(0x885ed46c), + SPH_C32(0x3bc3968d), SPH_C32(0x5487000b), SPH_C32(0xb58f73b2), + SPH_C32(0xa4367a49), SPH_C32(0xfdb02b28) }, + { SPH_C32(0x16240007), SPH_C32(0x7c883306), SPH_C32(0x26506f69), + SPH_C32(0x8e6750b6), SPH_C32(0x9c76000b), SPH_C32(0xbea29430), + SPH_C32(0xcfc032ed), SPH_C32(0xae2c9697) }, + { SPH_C32(0x7cb50000), SPH_C32(0xf285caee), SPH_C32(0x06589f43), + SPH_C32(0x2e548f6c), SPH_C32(0x0413000c), SPH_C32(0x5e8a7ce4), + SPH_C32(0x65eebc12), SPH_C32(0x39b78e87) }, + { SPH_C32(0xbcfb0001), SPH_C32(0xc13c0afe), SPH_C32(0xa8562446), + SPH_C32(0x9bf04957), SPH_C32(0xcce2000c), SPH_C32(0x55a79b66), + SPH_C32(0x0e18f4b6), SPH_C32(0x6a2b3338) }, + { SPH_C32(0xb4440000), SPH_C32(0xf9a82d6c), SPH_C32(0x6daed7e7), + SPH_C32(0x7dc832d3), SPH_C32(0x0cac000d), SPH_C32(0x661e5b76), + SPH_C32(0xa0164fb3), SPH_C32(0xdf8ff503) }, + { SPH_C32(0x740a0001), SPH_C32(0xca11ed7c), SPH_C32(0xc3a06ce2), + SPH_C32(0xc86cf4e8), SPH_C32(0xc45d000d), SPH_C32(0x6d33bcf4), + SPH_C32(0xcbe00717), SPH_C32(0x8c1348bc) }, + { SPH_C32(0xf4960002), SPH_C32(0xad626d5d), SPH_C32(0x9fbd1ae9), + SPH_C32(0xa321789d), SPH_C32(0x55bf000c), SPH_C32(0x7b6973f0), + SPH_C32(0x1c0c965e), SPH_C32(0x2b2f33c1) }, + { SPH_C32(0x34d80003), SPH_C32(0x9edbad4d), SPH_C32(0x31b3a1ec), + SPH_C32(0x1685bea6), SPH_C32(0x9d4e000c), SPH_C32(0x70449472), + SPH_C32(0x77fadefa), SPH_C32(0x78b38e7e) }, + { SPH_C32(0x3c670002), SPH_C32(0xa64f8adf), SPH_C32(0xf44b524d), + SPH_C32(0xf0bdc522), SPH_C32(0x5d00000d), SPH_C32(0x43fd5462), + SPH_C32(0xd9f465ff), SPH_C32(0xcd174845) }, + { SPH_C32(0xfc290003), SPH_C32(0x95f64acf), SPH_C32(0x5a45e948), + SPH_C32(0x45190319), SPH_C32(0x95f1000d), SPH_C32(0x48d0b3e0), + SPH_C32(0xb2022d5b), SPH_C32(0x9e8bf5fa) }, + { SPH_C32(0x2d190000), SPH_C32(0xd766c5fa), SPH_C32(0x7fbab50f), + SPH_C32(0x3ccc322a), SPH_C32(0xdd9c000e), SPH_C32(0x248ed443), + SPH_C32(0x85e913f4), SPH_C32(0xa65ac430) }, + { SPH_C32(0xed570001), SPH_C32(0xe4df05ea), SPH_C32(0xd1b40e0a), + SPH_C32(0x8968f411), SPH_C32(0x156d000e), SPH_C32(0x2fa333c1), + SPH_C32(0xee1f5b50), SPH_C32(0xf5c6798f) }, + { SPH_C32(0xe5e80000), SPH_C32(0xdc4b2278), SPH_C32(0x144cfdab), + SPH_C32(0x6f508f95), SPH_C32(0xd523000f), SPH_C32(0x1c1af3d1), + SPH_C32(0x4011e055), SPH_C32(0x4062bfb4) }, + { SPH_C32(0x25a60001), SPH_C32(0xeff2e268), SPH_C32(0xba4246ae), + SPH_C32(0xdaf449ae), SPH_C32(0x1dd2000f), SPH_C32(0x17371453), + SPH_C32(0x2be7a8f1), SPH_C32(0x13fe020b) }, + { SPH_C32(0xa53a0002), SPH_C32(0x88816249), SPH_C32(0xe65f30a5), + SPH_C32(0xb1b9c5db), SPH_C32(0x8c30000e), SPH_C32(0x016ddb57), + SPH_C32(0xfc0b39b8), SPH_C32(0xb4c27976) }, + { SPH_C32(0x65740003), SPH_C32(0xbb38a259), SPH_C32(0x48518ba0), + SPH_C32(0x041d03e0), SPH_C32(0x44c1000e), SPH_C32(0x0a403cd5), + SPH_C32(0x97fd711c), SPH_C32(0xe75ec4c9) }, + { SPH_C32(0x6dcb0002), SPH_C32(0x83ac85cb), SPH_C32(0x8da97801), + SPH_C32(0xe2257864), SPH_C32(0x848f000f), SPH_C32(0x39f9fcc5), + SPH_C32(0x39f3ca19), SPH_C32(0x52fa02f2) }, + { SPH_C32(0xad850003), SPH_C32(0xb01545db), SPH_C32(0x23a7c304), + SPH_C32(0x5781be5f), SPH_C32(0x4c7e000f), SPH_C32(0x32d41b47), + SPH_C32(0x520582bd), SPH_C32(0x0166bf4d) }, + { SPH_C32(0xacbd0004), SPH_C32(0x7ef34599), SPH_C32(0x9b9d2f13), + SPH_C32(0x811ea6b6), SPH_C32(0x6fba000c), SPH_C32(0x1e61854e), + SPH_C32(0xfddca02f), SPH_C32(0x4f1b49b4) }, + { SPH_C32(0x6cf30005), SPH_C32(0x4d4a8589), SPH_C32(0x35939416), + SPH_C32(0x34ba608d), SPH_C32(0xa74b000c), SPH_C32(0x154c62cc), + SPH_C32(0x962ae88b), SPH_C32(0x1c87f40b) }, + { SPH_C32(0x644c0004), SPH_C32(0x75dea21b), SPH_C32(0xf06b67b7), + SPH_C32(0xd2821b09), SPH_C32(0x6705000d), SPH_C32(0x26f5a2dc), + SPH_C32(0x3824538e), SPH_C32(0xa9233230) }, + { SPH_C32(0xa4020005), SPH_C32(0x4667620b), SPH_C32(0x5e65dcb2), + SPH_C32(0x6726dd32), SPH_C32(0xaff4000d), SPH_C32(0x2dd8455e), + SPH_C32(0x53d21b2a), SPH_C32(0xfabf8f8f) }, + { SPH_C32(0x249e0006), SPH_C32(0x2114e22a), SPH_C32(0x0278aab9), + SPH_C32(0x0c6b5147), SPH_C32(0x3e16000c), SPH_C32(0x3b828a5a), + SPH_C32(0x843e8a63), SPH_C32(0x5d83f4f2) }, + { SPH_C32(0xe4d00007), SPH_C32(0x12ad223a), SPH_C32(0xac7611bc), + SPH_C32(0xb9cf977c), SPH_C32(0xf6e7000c), SPH_C32(0x30af6dd8), + SPH_C32(0xefc8c2c7), SPH_C32(0x0e1f494d) }, + { SPH_C32(0xec6f0006), SPH_C32(0x2a3905a8), SPH_C32(0x698ee21d), + SPH_C32(0x5ff7ecf8), SPH_C32(0x36a9000d), SPH_C32(0x0316adc8), + SPH_C32(0x41c679c2), SPH_C32(0xbbbb8f76) }, + { SPH_C32(0x2c210007), SPH_C32(0x1980c5b8), SPH_C32(0xc7805918), + SPH_C32(0xea532ac3), SPH_C32(0xfe58000d), SPH_C32(0x083b4a4a), + SPH_C32(0x2a303166), SPH_C32(0xe82732c9) }, + { SPH_C32(0xfd110004), SPH_C32(0x5b104a8d), SPH_C32(0xe27f055f), + SPH_C32(0x93861bf0), SPH_C32(0xb635000e), SPH_C32(0x64652de9), + SPH_C32(0x1ddb0fc9), SPH_C32(0xd0f60303) }, + { SPH_C32(0x3d5f0005), SPH_C32(0x68a98a9d), SPH_C32(0x4c71be5a), + SPH_C32(0x2622ddcb), SPH_C32(0x7ec4000e), SPH_C32(0x6f48ca6b), + SPH_C32(0x762d476d), SPH_C32(0x836abebc) }, + { SPH_C32(0x35e00004), SPH_C32(0x503dad0f), SPH_C32(0x89894dfb), + SPH_C32(0xc01aa64f), SPH_C32(0xbe8a000f), SPH_C32(0x5cf10a7b), + SPH_C32(0xd823fc68), SPH_C32(0x36ce7887) }, + { SPH_C32(0xf5ae0005), SPH_C32(0x63846d1f), SPH_C32(0x2787f6fe), + SPH_C32(0x75be6074), SPH_C32(0x767b000f), SPH_C32(0x57dcedf9), + SPH_C32(0xb3d5b4cc), SPH_C32(0x6552c538) }, + { SPH_C32(0x75320006), SPH_C32(0x04f7ed3e), SPH_C32(0x7b9a80f5), + SPH_C32(0x1ef3ec01), SPH_C32(0xe799000e), SPH_C32(0x418622fd), + SPH_C32(0x64392585), SPH_C32(0xc26ebe45) }, + { SPH_C32(0xb57c0007), SPH_C32(0x374e2d2e), SPH_C32(0xd5943bf0), + SPH_C32(0xab572a3a), SPH_C32(0x2f68000e), SPH_C32(0x4aabc57f), + SPH_C32(0x0fcf6d21), SPH_C32(0x91f203fa) }, + { SPH_C32(0xbdc30006), SPH_C32(0x0fda0abc), SPH_C32(0x106cc851), + SPH_C32(0x4d6f51be), SPH_C32(0xef26000f), SPH_C32(0x7912056f), + SPH_C32(0xa1c1d624), SPH_C32(0x2456c5c1) }, + { SPH_C32(0x7d8d0007), SPH_C32(0x3c63caac), SPH_C32(0xbe627354), + SPH_C32(0xf8cb9785), SPH_C32(0x27d7000f), SPH_C32(0x723fe2ed), + SPH_C32(0xca379e80), SPH_C32(0x77ca787e) }, + { SPH_C32(0xbfb20008), SPH_C32(0x92170a39), SPH_C32(0x6019107f), + SPH_C32(0xe051606e), SPH_C32(0xa8ae0008), SPH_C32(0x2079397d), + SPH_C32(0xfe739301), SPH_C32(0xb8a92831) }, + { SPH_C32(0x7ffc0009), SPH_C32(0xa1aeca29), SPH_C32(0xce17ab7a), + SPH_C32(0x55f5a655), SPH_C32(0x605f0008), SPH_C32(0x2b54deff), + SPH_C32(0x9585dba5), SPH_C32(0xeb35958e) }, + { SPH_C32(0x77430008), SPH_C32(0x993aedbb), SPH_C32(0x0bef58db), + SPH_C32(0xb3cdddd1), SPH_C32(0xa0110009), SPH_C32(0x18ed1eef), + SPH_C32(0x3b8b60a0), SPH_C32(0x5e9153b5) }, + { SPH_C32(0xb70d0009), SPH_C32(0xaa832dab), SPH_C32(0xa5e1e3de), + SPH_C32(0x06691bea), SPH_C32(0x68e00009), SPH_C32(0x13c0f96d), + SPH_C32(0x507d2804), SPH_C32(0x0d0dee0a) }, + { SPH_C32(0x3791000a), SPH_C32(0xcdf0ad8a), SPH_C32(0xf9fc95d5), + SPH_C32(0x6d24979f), SPH_C32(0xf9020008), SPH_C32(0x059a3669), + SPH_C32(0x8791b94d), SPH_C32(0xaa319577) }, + { SPH_C32(0xf7df000b), SPH_C32(0xfe496d9a), SPH_C32(0x57f22ed0), + SPH_C32(0xd88051a4), SPH_C32(0x31f30008), SPH_C32(0x0eb7d1eb), + SPH_C32(0xec67f1e9), SPH_C32(0xf9ad28c8) }, + { SPH_C32(0xff60000a), SPH_C32(0xc6dd4a08), SPH_C32(0x920add71), + SPH_C32(0x3eb82a20), SPH_C32(0xf1bd0009), SPH_C32(0x3d0e11fb), + SPH_C32(0x42694aec), SPH_C32(0x4c09eef3) }, + { SPH_C32(0x3f2e000b), SPH_C32(0xf5648a18), SPH_C32(0x3c046674), + SPH_C32(0x8b1cec1b), SPH_C32(0x394c0009), SPH_C32(0x3623f679), + SPH_C32(0x299f0248), SPH_C32(0x1f95534c) }, + { SPH_C32(0xee1e0008), SPH_C32(0xb7f4052d), SPH_C32(0x19fb3a33), + SPH_C32(0xf2c9dd28), SPH_C32(0x7121000a), SPH_C32(0x5a7d91da), + SPH_C32(0x1e743ce7), SPH_C32(0x27446286) }, + { SPH_C32(0x2e500009), SPH_C32(0x844dc53d), SPH_C32(0xb7f58136), + SPH_C32(0x476d1b13), SPH_C32(0xb9d0000a), SPH_C32(0x51507658), + SPH_C32(0x75827443), SPH_C32(0x74d8df39) }, + { SPH_C32(0x26ef0008), SPH_C32(0xbcd9e2af), SPH_C32(0x720d7297), + SPH_C32(0xa1556097), SPH_C32(0x799e000b), SPH_C32(0x62e9b648), + SPH_C32(0xdb8ccf46), SPH_C32(0xc17c1902) }, + { SPH_C32(0xe6a10009), SPH_C32(0x8f6022bf), SPH_C32(0xdc03c992), + SPH_C32(0x14f1a6ac), SPH_C32(0xb16f000b), SPH_C32(0x69c451ca), + SPH_C32(0xb07a87e2), SPH_C32(0x92e0a4bd) }, + { SPH_C32(0x663d000a), SPH_C32(0xe813a29e), SPH_C32(0x801ebf99), + SPH_C32(0x7fbc2ad9), SPH_C32(0x208d000a), SPH_C32(0x7f9e9ece), + SPH_C32(0x679616ab), SPH_C32(0x35dcdfc0) }, + { SPH_C32(0xa673000b), SPH_C32(0xdbaa628e), SPH_C32(0x2e10049c), + SPH_C32(0xca18ece2), SPH_C32(0xe87c000a), SPH_C32(0x74b3794c), + SPH_C32(0x0c605e0f), SPH_C32(0x6640627f) }, + { SPH_C32(0xaecc000a), SPH_C32(0xe33e451c), SPH_C32(0xebe8f73d), + SPH_C32(0x2c209766), SPH_C32(0x2832000b), SPH_C32(0x470ab95c), + SPH_C32(0xa26ee50a), SPH_C32(0xd3e4a444) }, + { SPH_C32(0x6e82000b), SPH_C32(0xd087850c), SPH_C32(0x45e64c38), + SPH_C32(0x9984515d), SPH_C32(0xe0c3000b), SPH_C32(0x4c275ede), + SPH_C32(0xc998adae), SPH_C32(0x807819fb) }, + { SPH_C32(0x6fba000c), SPH_C32(0x1e61854e), SPH_C32(0xfddca02f), + SPH_C32(0x4f1b49b4), SPH_C32(0xc3070008), SPH_C32(0x6092c0d7), + SPH_C32(0x66418f3c), SPH_C32(0xce05ef02) }, + { SPH_C32(0xaff4000d), SPH_C32(0x2dd8455e), SPH_C32(0x53d21b2a), + SPH_C32(0xfabf8f8f), SPH_C32(0x0bf60008), SPH_C32(0x6bbf2755), + SPH_C32(0x0db7c798), SPH_C32(0x9d9952bd) }, + { SPH_C32(0xa74b000c), SPH_C32(0x154c62cc), SPH_C32(0x962ae88b), + SPH_C32(0x1c87f40b), SPH_C32(0xcbb80009), SPH_C32(0x5806e745), + SPH_C32(0xa3b97c9d), SPH_C32(0x283d9486) }, + { SPH_C32(0x6705000d), SPH_C32(0x26f5a2dc), SPH_C32(0x3824538e), + SPH_C32(0xa9233230), SPH_C32(0x03490009), SPH_C32(0x532b00c7), + SPH_C32(0xc84f3439), SPH_C32(0x7ba12939) }, + { SPH_C32(0xe799000e), SPH_C32(0x418622fd), SPH_C32(0x64392585), + SPH_C32(0xc26ebe45), SPH_C32(0x92ab0008), SPH_C32(0x4571cfc3), + SPH_C32(0x1fa3a570), SPH_C32(0xdc9d5244) }, + { SPH_C32(0x27d7000f), SPH_C32(0x723fe2ed), SPH_C32(0xca379e80), + SPH_C32(0x77ca787e), SPH_C32(0x5a5a0008), SPH_C32(0x4e5c2841), + SPH_C32(0x7455edd4), SPH_C32(0x8f01effb) }, + { SPH_C32(0x2f68000e), SPH_C32(0x4aabc57f), SPH_C32(0x0fcf6d21), + SPH_C32(0x91f203fa), SPH_C32(0x9a140009), SPH_C32(0x7de5e851), + SPH_C32(0xda5b56d1), SPH_C32(0x3aa529c0) }, + { SPH_C32(0xef26000f), SPH_C32(0x7912056f), SPH_C32(0xa1c1d624), + SPH_C32(0x2456c5c1), SPH_C32(0x52e50009), SPH_C32(0x76c80fd3), + SPH_C32(0xb1ad1e75), SPH_C32(0x6939947f) }, + { SPH_C32(0x3e16000c), SPH_C32(0x3b828a5a), SPH_C32(0x843e8a63), + SPH_C32(0x5d83f4f2), SPH_C32(0x1a88000a), SPH_C32(0x1a966870), + SPH_C32(0x864620da), SPH_C32(0x51e8a5b5) }, + { SPH_C32(0xfe58000d), SPH_C32(0x083b4a4a), SPH_C32(0x2a303166), + SPH_C32(0xe82732c9), SPH_C32(0xd279000a), SPH_C32(0x11bb8ff2), + SPH_C32(0xedb0687e), SPH_C32(0x0274180a) }, + { SPH_C32(0xf6e7000c), SPH_C32(0x30af6dd8), SPH_C32(0xefc8c2c7), + SPH_C32(0x0e1f494d), SPH_C32(0x1237000b), SPH_C32(0x22024fe2), + SPH_C32(0x43bed37b), SPH_C32(0xb7d0de31) }, + { SPH_C32(0x36a9000d), SPH_C32(0x0316adc8), SPH_C32(0x41c679c2), + SPH_C32(0xbbbb8f76), SPH_C32(0xdac6000b), SPH_C32(0x292fa860), + SPH_C32(0x28489bdf), SPH_C32(0xe44c638e) }, + { SPH_C32(0xb635000e), SPH_C32(0x64652de9), SPH_C32(0x1ddb0fc9), + SPH_C32(0xd0f60303), SPH_C32(0x4b24000a), SPH_C32(0x3f756764), + SPH_C32(0xffa40a96), SPH_C32(0x437018f3) }, + { SPH_C32(0x767b000f), SPH_C32(0x57dcedf9), SPH_C32(0xb3d5b4cc), + SPH_C32(0x6552c538), SPH_C32(0x83d5000a), SPH_C32(0x345880e6), + SPH_C32(0x94524232), SPH_C32(0x10eca54c) }, + { SPH_C32(0x7ec4000e), SPH_C32(0x6f48ca6b), SPH_C32(0x762d476d), + SPH_C32(0x836abebc), SPH_C32(0x439b000b), SPH_C32(0x07e140f6), + SPH_C32(0x3a5cf937), SPH_C32(0xa5486377) }, + { SPH_C32(0xbe8a000f), SPH_C32(0x5cf10a7b), SPH_C32(0xd823fc68), + SPH_C32(0x36ce7887), SPH_C32(0x8b6a000b), SPH_C32(0x0ccca774), + SPH_C32(0x51aab193), SPH_C32(0xf6d4dec8) }, + { SPH_C32(0xd41b0008), SPH_C32(0xd2fcf393), SPH_C32(0xf82b0c42), + SPH_C32(0x96fda75d), SPH_C32(0x130f000c), SPH_C32(0xece44fa0), + SPH_C32(0xfb843f6c), SPH_C32(0x614fc6d8) }, + { SPH_C32(0x14550009), SPH_C32(0xe1453383), SPH_C32(0x5625b747), + SPH_C32(0x23596166), SPH_C32(0xdbfe000c), SPH_C32(0xe7c9a822), + SPH_C32(0x907277c8), SPH_C32(0x32d37b67) }, + { SPH_C32(0x1cea0008), SPH_C32(0xd9d11411), SPH_C32(0x93dd44e6), + SPH_C32(0xc5611ae2), SPH_C32(0x1bb0000d), SPH_C32(0xd4706832), + SPH_C32(0x3e7ccccd), SPH_C32(0x8777bd5c) }, + { SPH_C32(0xdca40009), SPH_C32(0xea68d401), SPH_C32(0x3dd3ffe3), + SPH_C32(0x70c5dcd9), SPH_C32(0xd341000d), SPH_C32(0xdf5d8fb0), + SPH_C32(0x558a8469), SPH_C32(0xd4eb00e3) }, + { SPH_C32(0x5c38000a), SPH_C32(0x8d1b5420), SPH_C32(0x61ce89e8), + SPH_C32(0x1b8850ac), SPH_C32(0x42a3000c), SPH_C32(0xc90740b4), + SPH_C32(0x82661520), SPH_C32(0x73d77b9e) }, + { SPH_C32(0x9c76000b), SPH_C32(0xbea29430), SPH_C32(0xcfc032ed), + SPH_C32(0xae2c9697), SPH_C32(0x8a52000c), SPH_C32(0xc22aa736), + SPH_C32(0xe9905d84), SPH_C32(0x204bc621) }, + { SPH_C32(0x94c9000a), SPH_C32(0x8636b3a2), SPH_C32(0x0a38c14c), + SPH_C32(0x4814ed13), SPH_C32(0x4a1c000d), SPH_C32(0xf1936726), + SPH_C32(0x479ee681), SPH_C32(0x95ef001a) }, + { SPH_C32(0x5487000b), SPH_C32(0xb58f73b2), SPH_C32(0xa4367a49), + SPH_C32(0xfdb02b28), SPH_C32(0x82ed000d), SPH_C32(0xfabe80a4), + SPH_C32(0x2c68ae25), SPH_C32(0xc673bda5) }, + { SPH_C32(0x85b70008), SPH_C32(0xf71ffc87), SPH_C32(0x81c9260e), + SPH_C32(0x84651a1b), SPH_C32(0xca80000e), SPH_C32(0x96e0e707), + SPH_C32(0x1b83908a), SPH_C32(0xfea28c6f) }, + { SPH_C32(0x45f90009), SPH_C32(0xc4a63c97), SPH_C32(0x2fc79d0b), + SPH_C32(0x31c1dc20), SPH_C32(0x0271000e), SPH_C32(0x9dcd0085), + SPH_C32(0x7075d82e), SPH_C32(0xad3e31d0) }, + { SPH_C32(0x4d460008), SPH_C32(0xfc321b05), SPH_C32(0xea3f6eaa), + SPH_C32(0xd7f9a7a4), SPH_C32(0xc23f000f), SPH_C32(0xae74c095), + SPH_C32(0xde7b632b), SPH_C32(0x189af7eb) }, + { SPH_C32(0x8d080009), SPH_C32(0xcf8bdb15), SPH_C32(0x4431d5af), + SPH_C32(0x625d619f), SPH_C32(0x0ace000f), SPH_C32(0xa5592717), + SPH_C32(0xb58d2b8f), SPH_C32(0x4b064a54) }, + { SPH_C32(0x0d94000a), SPH_C32(0xa8f85b34), SPH_C32(0x182ca3a4), + SPH_C32(0x0910edea), SPH_C32(0x9b2c000e), SPH_C32(0xb303e813), + SPH_C32(0x6261bac6), SPH_C32(0xec3a3129) }, + { SPH_C32(0xcdda000b), SPH_C32(0x9b419b24), SPH_C32(0xb62218a1), + SPH_C32(0xbcb42bd1), SPH_C32(0x53dd000e), SPH_C32(0xb82e0f91), + SPH_C32(0x0997f262), SPH_C32(0xbfa68c96) }, + { SPH_C32(0xc565000a), SPH_C32(0xa3d5bcb6), SPH_C32(0x73daeb00), + SPH_C32(0x5a8c5055), SPH_C32(0x9393000f), SPH_C32(0x8b97cf81), + SPH_C32(0xa7994967), SPH_C32(0x0a024aad) }, + { SPH_C32(0x052b000b), SPH_C32(0x906c7ca6), SPH_C32(0xddd45005), + SPH_C32(0xef28966e), SPH_C32(0x5b62000f), SPH_C32(0x80ba2803), + SPH_C32(0xcc6f01c3), SPH_C32(0x599ef712) }, + { SPH_C32(0x0413000c), SPH_C32(0x5e8a7ce4), SPH_C32(0x65eebc12), + SPH_C32(0x39b78e87), SPH_C32(0x78a6000c), SPH_C32(0xac0fb60a), + SPH_C32(0x63b62351), SPH_C32(0x17e301eb) }, + { SPH_C32(0xc45d000d), SPH_C32(0x6d33bcf4), SPH_C32(0xcbe00717), + SPH_C32(0x8c1348bc), SPH_C32(0xb057000c), SPH_C32(0xa7225188), + SPH_C32(0x08406bf5), SPH_C32(0x447fbc54) }, + { SPH_C32(0xcce2000c), SPH_C32(0x55a79b66), SPH_C32(0x0e18f4b6), + SPH_C32(0x6a2b3338), SPH_C32(0x7019000d), SPH_C32(0x949b9198), + SPH_C32(0xa64ed0f0), SPH_C32(0xf1db7a6f) }, + { SPH_C32(0x0cac000d), SPH_C32(0x661e5b76), SPH_C32(0xa0164fb3), + SPH_C32(0xdf8ff503), SPH_C32(0xb8e8000d), SPH_C32(0x9fb6761a), + SPH_C32(0xcdb89854), SPH_C32(0xa247c7d0) }, + { SPH_C32(0x8c30000e), SPH_C32(0x016ddb57), SPH_C32(0xfc0b39b8), + SPH_C32(0xb4c27976), SPH_C32(0x290a000c), SPH_C32(0x89ecb91e), + SPH_C32(0x1a54091d), SPH_C32(0x057bbcad) }, + { SPH_C32(0x4c7e000f), SPH_C32(0x32d41b47), SPH_C32(0x520582bd), + SPH_C32(0x0166bf4d), SPH_C32(0xe1fb000c), SPH_C32(0x82c15e9c), + SPH_C32(0x71a241b9), SPH_C32(0x56e70112) }, + { SPH_C32(0x44c1000e), SPH_C32(0x0a403cd5), SPH_C32(0x97fd711c), + SPH_C32(0xe75ec4c9), SPH_C32(0x21b5000d), SPH_C32(0xb1789e8c), + SPH_C32(0xdfacfabc), SPH_C32(0xe343c729) }, + { SPH_C32(0x848f000f), SPH_C32(0x39f9fcc5), SPH_C32(0x39f3ca19), + SPH_C32(0x52fa02f2), SPH_C32(0xe944000d), SPH_C32(0xba55790e), + SPH_C32(0xb45ab218), SPH_C32(0xb0df7a96) }, + { SPH_C32(0x55bf000c), SPH_C32(0x7b6973f0), SPH_C32(0x1c0c965e), + SPH_C32(0x2b2f33c1), SPH_C32(0xa129000e), SPH_C32(0xd60b1ead), + SPH_C32(0x83b18cb7), SPH_C32(0x880e4b5c) }, + { SPH_C32(0x95f1000d), SPH_C32(0x48d0b3e0), SPH_C32(0xb2022d5b), + SPH_C32(0x9e8bf5fa), SPH_C32(0x69d8000e), SPH_C32(0xdd26f92f), + SPH_C32(0xe847c413), SPH_C32(0xdb92f6e3) }, + { SPH_C32(0x9d4e000c), SPH_C32(0x70449472), SPH_C32(0x77fadefa), + SPH_C32(0x78b38e7e), SPH_C32(0xa996000f), SPH_C32(0xee9f393f), + SPH_C32(0x46497f16), SPH_C32(0x6e3630d8) }, + { SPH_C32(0x5d00000d), SPH_C32(0x43fd5462), SPH_C32(0xd9f465ff), + SPH_C32(0xcd174845), SPH_C32(0x6167000f), SPH_C32(0xe5b2debd), + SPH_C32(0x2dbf37b2), SPH_C32(0x3daa8d67) }, + { SPH_C32(0xdd9c000e), SPH_C32(0x248ed443), SPH_C32(0x85e913f4), + SPH_C32(0xa65ac430), SPH_C32(0xf085000e), SPH_C32(0xf3e811b9), + SPH_C32(0xfa53a6fb), SPH_C32(0x9a96f61a) }, + { SPH_C32(0x1dd2000f), SPH_C32(0x17371453), SPH_C32(0x2be7a8f1), + SPH_C32(0x13fe020b), SPH_C32(0x3874000e), SPH_C32(0xf8c5f63b), + SPH_C32(0x91a5ee5f), SPH_C32(0xc90a4ba5) }, + { SPH_C32(0x156d000e), SPH_C32(0x2fa333c1), SPH_C32(0xee1f5b50), + SPH_C32(0xf5c6798f), SPH_C32(0xf83a000f), SPH_C32(0xcb7c362b), + SPH_C32(0x3fab555a), SPH_C32(0x7cae8d9e) }, + { SPH_C32(0xd523000f), SPH_C32(0x1c1af3d1), SPH_C32(0x4011e055), + SPH_C32(0x4062bfb4), SPH_C32(0x30cb000f), SPH_C32(0xc051d1a9), + SPH_C32(0x545d1dfe), SPH_C32(0x2f323021) } +}; + +#define INPUT_SMALL do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T256_0[acc][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + acc = buf[1]; \ + rp = &T256_8[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[2]; \ + rp = &T256_16[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + acc = buf[3]; \ + rp = &T256_24[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_BIG == 1 + +/* Note: this table lists bits within each byte from least + siginificant to most significant. */ +static const sph_u32 T512[64][16] = { + { SPH_C32(0xef0b0270), SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), + SPH_C32(0x69490000), SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), + SPH_C32(0x66140a51), SPH_C32(0x924f5d0a), SPH_C32(0xc96b0030), + SPH_C32(0xe7250000), SPH_C32(0x2f840000), SPH_C32(0x264f0000), + SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), SPH_C32(0x509f6984), + SPH_C32(0x9e69af68) }, + { SPH_C32(0xc96b0030), SPH_C32(0xe7250000), SPH_C32(0x2f840000), + SPH_C32(0x264f0000), SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), + SPH_C32(0x509f6984), SPH_C32(0x9e69af68), SPH_C32(0x26600240), + SPH_C32(0xddd80000), SPH_C32(0x722a0000), SPH_C32(0x4f060000), + SPH_C32(0x936667ff), SPH_C32(0x29f944ce), SPH_C32(0x368b63d5), + SPH_C32(0x0c26f262) }, + { SPH_C32(0x145a3c00), SPH_C32(0xb9e90000), SPH_C32(0x61270000), + SPH_C32(0xf1610000), SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), + SPH_C32(0x47a96720), SPH_C32(0xe18e24c5), SPH_C32(0x23671400), + SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), SPH_C32(0xfb750000), + SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), SPH_C32(0x02c40a3f), + SPH_C32(0xdc24e61f) }, + { SPH_C32(0x23671400), SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), + SPH_C32(0xfb750000), SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), + SPH_C32(0x02c40a3f), SPH_C32(0xdc24e61f), SPH_C32(0x373d2800), + SPH_C32(0x71500000), SPH_C32(0x95e00000), SPH_C32(0x0a140000), + SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), SPH_C32(0x456d6d1f), + SPH_C32(0x3daac2da) }, + { SPH_C32(0x54285c00), SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), + SPH_C32(0xa1c50000), SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), + SPH_C32(0x6bb0419d), SPH_C32(0x551b3782), SPH_C32(0x9cbb1800), + SPH_C32(0xb0d30000), SPH_C32(0x92510000), SPH_C32(0xed930000), + SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), SPH_C32(0x430633da), + SPH_C32(0x78cace29) }, + { SPH_C32(0x9cbb1800), SPH_C32(0xb0d30000), SPH_C32(0x92510000), + SPH_C32(0xed930000), SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), + SPH_C32(0x430633da), SPH_C32(0x78cace29), SPH_C32(0xc8934400), + SPH_C32(0x5a3e0000), SPH_C32(0x57870000), SPH_C32(0x4c560000), + SPH_C32(0xea982435), SPH_C32(0x75b11115), SPH_C32(0x28b67247), + SPH_C32(0x2dd1f9ab) }, + { SPH_C32(0x29449c00), SPH_C32(0x64e70000), SPH_C32(0xf24b0000), + SPH_C32(0xc2f30000), SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), + SPH_C32(0xf3e04259), SPH_C32(0x8d0d9ec4), SPH_C32(0x466d0c00), + SPH_C32(0x08620000), SPH_C32(0xdd5d0000), SPH_C32(0xbadd0000), + SPH_C32(0x6a927942), SPH_C32(0x441f2b93), SPH_C32(0x218ace6f), + SPH_C32(0xbf2c0be2) }, + { SPH_C32(0x466d0c00), SPH_C32(0x08620000), SPH_C32(0xdd5d0000), + SPH_C32(0xbadd0000), SPH_C32(0x6a927942), SPH_C32(0x441f2b93), + SPH_C32(0x218ace6f), SPH_C32(0xbf2c0be2), SPH_C32(0x6f299000), + SPH_C32(0x6c850000), SPH_C32(0x2f160000), SPH_C32(0x782e0000), + SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), SPH_C32(0xd26a8c36), + SPH_C32(0x32219526) }, + { SPH_C32(0xf6800005), SPH_C32(0x3443c000), SPH_C32(0x24070000), + SPH_C32(0x8f3d0000), SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), + SPH_C32(0xcdc58b19), SPH_C32(0xd795ba31), SPH_C32(0xa67f0001), + SPH_C32(0x71378000), SPH_C32(0x19fc0000), SPH_C32(0x96db0000), + SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), SPH_C32(0x2c6d478f), + SPH_C32(0xac8e6c88) }, + { SPH_C32(0xa67f0001), SPH_C32(0x71378000), SPH_C32(0x19fc0000), + SPH_C32(0x96db0000), SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), + SPH_C32(0x2c6d478f), SPH_C32(0xac8e6c88), SPH_C32(0x50ff0004), + SPH_C32(0x45744000), SPH_C32(0x3dfb0000), SPH_C32(0x19e60000), + SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), SPH_C32(0xe1a8cc96), + SPH_C32(0x7b1bd6b9) }, + { SPH_C32(0xf7750009), SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), + SPH_C32(0x04920000), SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), + SPH_C32(0x7a87f14e), SPH_C32(0x9e16981a), SPH_C32(0xd46a0000), + SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), SPH_C32(0x4a290000), + SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), SPH_C32(0x98369604), + SPH_C32(0xf746c320) }, + { SPH_C32(0xd46a0000), SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), + SPH_C32(0x4a290000), SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), + SPH_C32(0x98369604), SPH_C32(0xf746c320), SPH_C32(0x231f0009), + SPH_C32(0x42f40000), SPH_C32(0x66790000), SPH_C32(0x4ebb0000), + SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), SPH_C32(0xe2b1674a), + SPH_C32(0x69505b3a) }, + { SPH_C32(0x774400f0), SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), + SPH_C32(0x34140000), SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), + SPH_C32(0x0bc3cd1e), SPH_C32(0xcf3775cb), SPH_C32(0xf46c0050), + SPH_C32(0x96180000), SPH_C32(0x14a50000), SPH_C32(0x031f0000), + SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), SPH_C32(0x9ca470d2), + SPH_C32(0x8a341574) }, + { SPH_C32(0xf46c0050), SPH_C32(0x96180000), SPH_C32(0x14a50000), + SPH_C32(0x031f0000), SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), + SPH_C32(0x9ca470d2), SPH_C32(0x8a341574), SPH_C32(0x832800a0), + SPH_C32(0x67420000), SPH_C32(0xe1170000), SPH_C32(0x370b0000), + SPH_C32(0xcba30034), SPH_C32(0x3c34923c), SPH_C32(0x9767bdcc), + SPH_C32(0x450360bf) }, + { SPH_C32(0xe8870170), SPH_C32(0x9d720000), SPH_C32(0x12db0000), + SPH_C32(0xd4220000), SPH_C32(0xf2886b27), SPH_C32(0xa921e543), + SPH_C32(0x4ef8b518), SPH_C32(0x618813b1), SPH_C32(0xb4370060), + SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), SPH_C32(0x5cae0000), + SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), SPH_C32(0x1b365f3d), + SPH_C32(0xf3d45758) }, + { SPH_C32(0xb4370060), SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), + SPH_C32(0x5cae0000), SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), + SPH_C32(0x1b365f3d), SPH_C32(0xf3d45758), SPH_C32(0x5cb00110), + SPH_C32(0x913e0000), SPH_C32(0x44190000), SPH_C32(0x888c0000), + SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), SPH_C32(0x55ceea25), + SPH_C32(0x925c44e9) }, + { SPH_C32(0x0c720000), SPH_C32(0x49e50f00), SPH_C32(0x42790000), + SPH_C32(0x5cea0000), SPH_C32(0x33aa301a), SPH_C32(0x15822514), + SPH_C32(0x95a34b7b), SPH_C32(0xb44b0090), SPH_C32(0xfe220000), + SPH_C32(0xa7580500), SPH_C32(0x25d10000), SPH_C32(0xf7600000), + SPH_C32(0x893178da), SPH_C32(0x1fd4f860), SPH_C32(0x4ed0a315), + SPH_C32(0xa123ff9f) }, + { SPH_C32(0xfe220000), SPH_C32(0xa7580500), SPH_C32(0x25d10000), + SPH_C32(0xf7600000), SPH_C32(0x893178da), SPH_C32(0x1fd4f860), + SPH_C32(0x4ed0a315), SPH_C32(0xa123ff9f), SPH_C32(0xf2500000), + SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), SPH_C32(0xab8a0000), + SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), SPH_C32(0xdb73e86e), + SPH_C32(0x1568ff0f) }, + { SPH_C32(0x45180000), SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), + SPH_C32(0x3b480000), SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), + SPH_C32(0x16bca6b0), SPH_C32(0xdf33f4df), SPH_C32(0xb83d0000), + SPH_C32(0x16710600), SPH_C32(0x379a0000), SPH_C32(0xf5b10000), + SPH_C32(0x228161ac), SPH_C32(0xae48f145), SPH_C32(0x66241616), + SPH_C32(0xc5c1eb3e) }, + { SPH_C32(0xb83d0000), SPH_C32(0x16710600), SPH_C32(0x379a0000), + SPH_C32(0xf5b10000), SPH_C32(0x228161ac), SPH_C32(0xae48f145), + SPH_C32(0x66241616), SPH_C32(0xc5c1eb3e), SPH_C32(0xfd250000), + SPH_C32(0xb3c41100), SPH_C32(0xcef00000), SPH_C32(0xcef90000), + SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), SPH_C32(0x7098b0a6), + SPH_C32(0x1af21fe1) }, + { SPH_C32(0x75a40000), SPH_C32(0xc28b2700), SPH_C32(0x94a40000), + SPH_C32(0x90f50000), SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), + SPH_C32(0x1767c483), SPH_C32(0xaedf667e), SPH_C32(0xd1660000), + SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), SPH_C32(0xf6940000), + SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), SPH_C32(0xb4431b17), + SPH_C32(0x857f3c2b) }, + { SPH_C32(0xd1660000), SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), + SPH_C32(0xf6940000), SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), + SPH_C32(0xb4431b17), SPH_C32(0x857f3c2b), SPH_C32(0xa4c20000), + SPH_C32(0xd9372400), SPH_C32(0x0a480000), SPH_C32(0x66610000), + SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), SPH_C32(0xa324df94), + SPH_C32(0x2ba05a55) }, + { SPH_C32(0x75c90003), SPH_C32(0x0e10c000), SPH_C32(0xd1200000), + SPH_C32(0xbaea0000), SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), + SPH_C32(0xbb28761d), SPH_C32(0x00b72e2b), SPH_C32(0xeecf0001), + SPH_C32(0x6f564000), SPH_C32(0xf33e0000), SPH_C32(0xa79e0000), + SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), SPH_C32(0x4a3b40ba), + SPH_C32(0xfeabf254) }, + { SPH_C32(0xeecf0001), SPH_C32(0x6f564000), SPH_C32(0xf33e0000), + SPH_C32(0xa79e0000), SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), + SPH_C32(0x4a3b40ba), SPH_C32(0xfeabf254), SPH_C32(0x9b060002), + SPH_C32(0x61468000), SPH_C32(0x221e0000), SPH_C32(0x1d740000), + SPH_C32(0x36715d27), SPH_C32(0x30495c92), SPH_C32(0xf11336a7), + SPH_C32(0xfe1cdc7f) }, + { SPH_C32(0x86790000), SPH_C32(0x3f390002), SPH_C32(0xe19ae000), + SPH_C32(0x98560000), SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), + SPH_C32(0xd3dd4944), SPH_C32(0x161ddab9), SPH_C32(0x30b70000), + SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), SPH_C32(0x42c40000), + SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), SPH_C32(0x21afa1ea), + SPH_C32(0xb0a51834) }, + { SPH_C32(0x30b70000), SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), + SPH_C32(0x42c40000), SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), + SPH_C32(0x21afa1ea), SPH_C32(0xb0a51834), SPH_C32(0xb6ce0000), + SPH_C32(0xdae90002), SPH_C32(0x156e8000), SPH_C32(0xda920000), + SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), SPH_C32(0xf272e8ae), + SPH_C32(0xa6b8c28d) }, + { SPH_C32(0x14190000), SPH_C32(0x23ca003c), SPH_C32(0x50df0000), + SPH_C32(0x44b60000), SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), + SPH_C32(0x61e610b0), SPH_C32(0xdbcadb80), SPH_C32(0xe3430000), + SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), SPH_C32(0xaa4e0000), + SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), SPH_C32(0x123db156), + SPH_C32(0x3a4e99d7) }, + { SPH_C32(0xe3430000), SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), + SPH_C32(0xaa4e0000), SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), + SPH_C32(0x123db156), SPH_C32(0x3a4e99d7), SPH_C32(0xf75a0000), + SPH_C32(0x19840028), SPH_C32(0xa2190000), SPH_C32(0xeef80000), + SPH_C32(0xc0722516), SPH_C32(0x19981260), SPH_C32(0x73dba1e6), + SPH_C32(0xe1844257) }, + { SPH_C32(0x54500000), SPH_C32(0x0671005c), SPH_C32(0x25ae0000), + SPH_C32(0x6a1e0000), SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), + SPH_C32(0xbfba18c3), SPH_C32(0x7e715d17), SPH_C32(0xbc8d0000), + SPH_C32(0xfc3b0018), SPH_C32(0x19830000), SPH_C32(0xd10b0000), + SPH_C32(0xae1878c4), SPH_C32(0x42a69856), SPH_C32(0x0012da37), + SPH_C32(0x2c3b504e) }, + { SPH_C32(0xbc8d0000), SPH_C32(0xfc3b0018), SPH_C32(0x19830000), + SPH_C32(0xd10b0000), SPH_C32(0xae1878c4), SPH_C32(0x42a69856), + SPH_C32(0x0012da37), SPH_C32(0x2c3b504e), SPH_C32(0xe8dd0000), + SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), SPH_C32(0xbb150000), + SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), SPH_C32(0xbfa8c2f4), + SPH_C32(0x524a0d59) }, + { SPH_C32(0x69510000), SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), + SPH_C32(0xac2f0000), SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), + SPH_C32(0x87ec287c), SPH_C32(0xbce1a3ce), SPH_C32(0xc6730000), + SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), SPH_C32(0x218d0000), + SPH_C32(0x23111587), SPH_C32(0x7913512f), SPH_C32(0x1d28ac88), + SPH_C32(0x378dd173) }, + { SPH_C32(0xc6730000), SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), + SPH_C32(0x218d0000), SPH_C32(0x23111587), SPH_C32(0x7913512f), + SPH_C32(0x1d28ac88), SPH_C32(0x378dd173), SPH_C32(0xaf220000), + SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), SPH_C32(0x8da20000), + SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), SPH_C32(0x9ac484f4), + SPH_C32(0x8b6c72bd) }, + { SPH_C32(0xcc140000), SPH_C32(0xa5630000), SPH_C32(0x5ab90780), + SPH_C32(0x3b500000), SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), + SPH_C32(0x694348c1), SPH_C32(0xca5a87fe), SPH_C32(0x819e0000), + SPH_C32(0xec570000), SPH_C32(0x66320280), SPH_C32(0x95f30000), + SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), SPH_C32(0xe65aa22d), + SPH_C32(0x8e67b7fa) }, + { SPH_C32(0x819e0000), SPH_C32(0xec570000), SPH_C32(0x66320280), + SPH_C32(0x95f30000), SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), + SPH_C32(0xe65aa22d), SPH_C32(0x8e67b7fa), SPH_C32(0x4d8a0000), + SPH_C32(0x49340000), SPH_C32(0x3c8b0500), SPH_C32(0xaea30000), + SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), SPH_C32(0x8f19eaec), + SPH_C32(0x443d3004) }, + { SPH_C32(0x78230000), SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), + SPH_C32(0x90a50000), SPH_C32(0x713e2879), SPH_C32(0x7ee98924), + SPH_C32(0xf08ca062), SPH_C32(0x636f8bab), SPH_C32(0x02af0000), + SPH_C32(0xb7280000), SPH_C32(0xba1c0300), SPH_C32(0x56980000), + SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), SPH_C32(0xa95c149a), + SPH_C32(0xf4f6ea7b) }, + { SPH_C32(0x02af0000), SPH_C32(0xb7280000), SPH_C32(0xba1c0300), + SPH_C32(0x56980000), SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), + SPH_C32(0xa95c149a), SPH_C32(0xf4f6ea7b), SPH_C32(0x7a8c0000), + SPH_C32(0xa5d40000), SPH_C32(0x13260880), SPH_C32(0xc63d0000), + SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), SPH_C32(0x59d0b4f8), + SPH_C32(0x979961d0) }, + { SPH_C32(0xac480000), SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), + SPH_C32(0x03430000), SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), + SPH_C32(0xfe72c7fe), SPH_C32(0x91e478f6), SPH_C32(0x1e4e0000), + SPH_C32(0xdecf0000), SPH_C32(0x6df80180), SPH_C32(0x77240000), + SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), SPH_C32(0xcda31812), + SPH_C32(0x98aa496e) }, + { SPH_C32(0x1e4e0000), SPH_C32(0xdecf0000), SPH_C32(0x6df80180), + SPH_C32(0x77240000), SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), + SPH_C32(0xcda31812), SPH_C32(0x98aa496e), SPH_C32(0xb2060000), + SPH_C32(0xc5690000), SPH_C32(0x28031200), SPH_C32(0x74670000), + SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), SPH_C32(0x33d1dfec), + SPH_C32(0x094e3198) }, + { SPH_C32(0xaec30000), SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), + SPH_C32(0x2c150000), SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), + SPH_C32(0xab92f78f), SPH_C32(0xa312567b), SPH_C32(0xdb250000), + SPH_C32(0x09290000), SPH_C32(0x49aac000), SPH_C32(0x81e10000), + SPH_C32(0xcafe6b59), SPH_C32(0x42793431), SPH_C32(0x43566b76), + SPH_C32(0xe86cba2e) }, + { SPH_C32(0xdb250000), SPH_C32(0x09290000), SPH_C32(0x49aac000), + SPH_C32(0x81e10000), SPH_C32(0xcafe6b59), SPH_C32(0x42793431), + SPH_C32(0x43566b76), SPH_C32(0xe86cba2e), SPH_C32(0x75e60000), + SPH_C32(0x95660001), SPH_C32(0x307b2000), SPH_C32(0xadf40000), + SPH_C32(0x8f321eea), SPH_C32(0x24298307), SPH_C32(0xe8c49cf9), + SPH_C32(0x4b7eec55) }, + { SPH_C32(0x58430000), SPH_C32(0x807e0000), SPH_C32(0x78330001), + SPH_C32(0xc66b3800), SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), + SPH_C32(0xac73fe6f), SPH_C32(0x3a4479b1), SPH_C32(0x1d5a0000), + SPH_C32(0x2b720000), SPH_C32(0x488d0000), SPH_C32(0xaf611800), + SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), SPH_C32(0x81a20429), + SPH_C32(0x1e7536a6) }, + { SPH_C32(0x1d5a0000), SPH_C32(0x2b720000), SPH_C32(0x488d0000), + SPH_C32(0xaf611800), SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), + SPH_C32(0x81a20429), SPH_C32(0x1e7536a6), SPH_C32(0x45190000), + SPH_C32(0xab0c0000), SPH_C32(0x30be0001), SPH_C32(0x690a2000), + SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), SPH_C32(0x2dd1fa46), + SPH_C32(0x24314f17) }, + { SPH_C32(0xa53b0000), SPH_C32(0x14260000), SPH_C32(0x4e30001e), + SPH_C32(0x7cae0000), SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), + SPH_C32(0xf73168d8), SPH_C32(0x0b1b4946), SPH_C32(0x07ed0000), + SPH_C32(0xb2500000), SPH_C32(0x8774000a), SPH_C32(0x970d0000), + SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), SPH_C32(0xf4786222), + SPH_C32(0x9075b1ce) }, + { SPH_C32(0x07ed0000), SPH_C32(0xb2500000), SPH_C32(0x8774000a), + SPH_C32(0x970d0000), SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), + SPH_C32(0xf4786222), SPH_C32(0x9075b1ce), SPH_C32(0xa2d60000), + SPH_C32(0xa6760000), SPH_C32(0xc9440014), SPH_C32(0xeba30000), + SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), SPH_C32(0x03490afa), + SPH_C32(0x9b6ef888) }, + { SPH_C32(0x88980000), SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), + SPH_C32(0xfb4e0000), SPH_C32(0xf158079a), SPH_C32(0x61ae9167), + SPH_C32(0xa895706c), SPH_C32(0xe6107494), SPH_C32(0x0bc20000), + SPH_C32(0xdb630000), SPH_C32(0x7e88000c), SPH_C32(0x15860000), + SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), SPH_C32(0xf460449e), + SPH_C32(0xd8b61463) }, + { SPH_C32(0x0bc20000), SPH_C32(0xdb630000), SPH_C32(0x7e88000c), + SPH_C32(0x15860000), SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), + SPH_C32(0xf460449e), SPH_C32(0xd8b61463), SPH_C32(0x835a0000), + SPH_C32(0xc4f70000), SPH_C32(0x01470022), SPH_C32(0xeec80000), + SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), SPH_C32(0x5cf534f2), + SPH_C32(0x3ea660f7) }, + { SPH_C32(0x52500000), SPH_C32(0x29540000), SPH_C32(0x6a61004e), + SPH_C32(0xf0ff0000), SPH_C32(0x9a317eec), SPH_C32(0x452341ce), + SPH_C32(0xcf568fe5), SPH_C32(0x5303130f), SPH_C32(0x538d0000), + SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), SPH_C32(0x56ff0000), + SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), SPH_C32(0xa9444018), + SPH_C32(0x7f975691) }, + { SPH_C32(0x538d0000), SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), + SPH_C32(0x56ff0000), SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), + SPH_C32(0xa9444018), SPH_C32(0x7f975691), SPH_C32(0x01dd0000), + SPH_C32(0x80a80000), SPH_C32(0xf4960048), SPH_C32(0xa6000000), + SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), SPH_C32(0x6612cffd), + SPH_C32(0x2c94459e) }, + { SPH_C32(0xe6280000), SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), + SPH_C32(0xd3d002e0), SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), + SPH_C32(0x289506b4), SPH_C32(0xd75a4897), SPH_C32(0xf0c50000), + SPH_C32(0x59230000), SPH_C32(0x45820000), SPH_C32(0xe18d00c0), + SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), SPH_C32(0xcbe0fe1c), + SPH_C32(0x56a7b19f) }, + { SPH_C32(0xf0c50000), SPH_C32(0x59230000), SPH_C32(0x45820000), + SPH_C32(0xe18d00c0), SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), + SPH_C32(0xcbe0fe1c), SPH_C32(0x56a7b19f), SPH_C32(0x16ed0000), + SPH_C32(0x15680000), SPH_C32(0xedd70000), SPH_C32(0x325d0220), + SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), SPH_C32(0xe375f8a8), + SPH_C32(0x81fdf908) }, + { SPH_C32(0xb4310000), SPH_C32(0x77330000), SPH_C32(0xb15d0000), + SPH_C32(0x7fd004e0), SPH_C32(0x78a26138), SPH_C32(0xd116c35d), + SPH_C32(0xd256d489), SPH_C32(0x4e6f74de), SPH_C32(0xe3060000), + SPH_C32(0xbdc10000), SPH_C32(0x87130000), SPH_C32(0xbff20060), + SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), SPH_C32(0x73c5ab06), + SPH_C32(0x5bd61539) }, + { SPH_C32(0xe3060000), SPH_C32(0xbdc10000), SPH_C32(0x87130000), + SPH_C32(0xbff20060), SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), + SPH_C32(0x73c5ab06), SPH_C32(0x5bd61539), SPH_C32(0x57370000), + SPH_C32(0xcaf20000), SPH_C32(0x364e0000), SPH_C32(0xc0220480), + SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), SPH_C32(0xa1937f8f), + SPH_C32(0x15b961e7) }, + { SPH_C32(0x02f20000), SPH_C32(0xa2810000), SPH_C32(0x873f0000), + SPH_C32(0xe36c7800), SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), + SPH_C32(0xc4c23237), SPH_C32(0x7f32259e), SPH_C32(0xbadd0000), + SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), SPH_C32(0xf7282800), + SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), SPH_C32(0xea5a8d14), + SPH_C32(0x2a2c18f0) }, + { SPH_C32(0xbadd0000), SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), + SPH_C32(0xf7282800), SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), + SPH_C32(0xea5a8d14), SPH_C32(0x2a2c18f0), SPH_C32(0xb82f0000), + SPH_C32(0xb12c0000), SPH_C32(0x30d80000), SPH_C32(0x14445000), + SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), SPH_C32(0x2e98bf23), + SPH_C32(0x551e3d6e) }, + { SPH_C32(0x1e6c0000), SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), + SPH_C32(0xbcb6b800), SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), + SPH_C32(0x6a0c1bc8), SPH_C32(0xb99dc2eb), SPH_C32(0x92560000), + SPH_C32(0x1eda0000), SPH_C32(0xea510000), SPH_C32(0xe8b13000), + SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), SPH_C32(0xb15c2254), + SPH_C32(0x33c5244f) }, + { SPH_C32(0x92560000), SPH_C32(0x1eda0000), SPH_C32(0xea510000), + SPH_C32(0xe8b13000), SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), + SPH_C32(0xb15c2254), SPH_C32(0x33c5244f), SPH_C32(0x8c3a0000), + SPH_C32(0xda980000), SPH_C32(0x607f0000), SPH_C32(0x54078800), + SPH_C32(0x85714513), SPH_C32(0x6006b243), SPH_C32(0xdb50399c), + SPH_C32(0x8a58e6a4) }, + { SPH_C32(0x033d0000), SPH_C32(0x08b30000), SPH_C32(0xf33a0000), + SPH_C32(0x3ac20007), SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), + SPH_C32(0x0ea5cfe3), SPH_C32(0xe6da7ffe), SPH_C32(0xa8da0000), + SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), SPH_C32(0x07da0002), + SPH_C32(0x7d669583), SPH_C32(0x1f98708a), SPH_C32(0xbb668808), + SPH_C32(0xda878000) }, + { SPH_C32(0xa8da0000), SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), + SPH_C32(0x07da0002), SPH_C32(0x7d669583), SPH_C32(0x1f98708a), + SPH_C32(0xbb668808), SPH_C32(0xda878000), SPH_C32(0xabe70000), + SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), SPH_C32(0x3d180005), + SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), SPH_C32(0xb5c347eb), + SPH_C32(0x3c5dfffe) }, + { SPH_C32(0x01930000), SPH_C32(0xe7820000), SPH_C32(0xedfb0000), + SPH_C32(0xcf0c000b), SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), + SPH_C32(0x063661e1), SPH_C32(0x536f9e7b), SPH_C32(0x92280000), + SPH_C32(0xdc850000), SPH_C32(0x57fa0000), SPH_C32(0x56dc0003), + SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), SPH_C32(0x90cef752), + SPH_C32(0x7b1675d7) }, + { SPH_C32(0x92280000), SPH_C32(0xdc850000), SPH_C32(0x57fa0000), + SPH_C32(0x56dc0003), SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), + SPH_C32(0x90cef752), SPH_C32(0x7b1675d7), SPH_C32(0x93bb0000), + SPH_C32(0x3b070000), SPH_C32(0xba010000), SPH_C32(0x99d00008), + SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), SPH_C32(0x96f896b3), + SPH_C32(0x2879ebac) }, + { SPH_C32(0x5fa80000), SPH_C32(0x56030000), SPH_C32(0x43ae0000), + SPH_C32(0x64f30013), SPH_C32(0x257e86bf), SPH_C32(0x1311944e), + SPH_C32(0x541e95bf), SPH_C32(0x8ea4db69), SPH_C32(0x00440000), + SPH_C32(0x7f480000), SPH_C32(0xda7c0000), SPH_C32(0x2a230001), + SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), SPH_C32(0x030a9e60), + SPH_C32(0xbe0a679e) }, + { SPH_C32(0x00440000), SPH_C32(0x7f480000), SPH_C32(0xda7c0000), + SPH_C32(0x2a230001), SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), + SPH_C32(0x030a9e60), SPH_C32(0xbe0a679e), SPH_C32(0x5fec0000), + SPH_C32(0x294b0000), SPH_C32(0x99d20000), SPH_C32(0x4ed00012), + SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), SPH_C32(0x57140bdf), + SPH_C32(0x30aebcf7) }, + { SPH_C32(0xee930000), SPH_C32(0xd6070000), SPH_C32(0x92c10000), + SPH_C32(0x2b9801e0), SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), + SPH_C32(0x45312374), SPH_C32(0x201f6a64), SPH_C32(0x7b280000), + SPH_C32(0x57420000), SPH_C32(0xa9e50000), SPH_C32(0x634300a0), + SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), SPH_C32(0x27f83b03), + SPH_C32(0xc7ff60f0) }, + { SPH_C32(0x7b280000), SPH_C32(0x57420000), SPH_C32(0xa9e50000), + SPH_C32(0x634300a0), SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), + SPH_C32(0x27f83b03), SPH_C32(0xc7ff60f0), SPH_C32(0x95bb0000), + SPH_C32(0x81450000), SPH_C32(0x3b240000), SPH_C32(0x48db0140), + SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), SPH_C32(0x62c91877), + SPH_C32(0xe7e00a94) } +}; + +#define INPUT_BIG do { \ + const sph_u32 *tp = &T512[0][0]; \ + unsigned u, v; \ + m0 = 0; \ + m1 = 0; \ + m2 = 0; \ + m3 = 0; \ + m4 = 0; \ + m5 = 0; \ + m6 = 0; \ + m7 = 0; \ + m8 = 0; \ + m9 = 0; \ + mA = 0; \ + mB = 0; \ + mC = 0; \ + mD = 0; \ + mE = 0; \ + mF = 0; \ + for (u = 0; u < 8; u ++) { \ + unsigned db = buf[u]; \ + for (v = 0; v < 8; v ++, db >>= 1) { \ + sph_u32 dm = SPH_T32(-(sph_u32)(db & 1)); \ + m0 ^= dm & *tp ++; \ + m1 ^= dm & *tp ++; \ + m2 ^= dm & *tp ++; \ + m3 ^= dm & *tp ++; \ + m4 ^= dm & *tp ++; \ + m5 ^= dm & *tp ++; \ + m6 ^= dm & *tp ++; \ + m7 ^= dm & *tp ++; \ + m8 ^= dm & *tp ++; \ + m9 ^= dm & *tp ++; \ + mA ^= dm & *tp ++; \ + mB ^= dm & *tp ++; \ + mC ^= dm & *tp ++; \ + mD ^= dm & *tp ++; \ + mE ^= dm & *tp ++; \ + mF ^= dm & *tp ++; \ + } \ + } \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_BIG == 2 + +static const sph_u32 T512_0[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x29449c00), SPH_C32(0x64e70000), SPH_C32(0xf24b0000), + SPH_C32(0xc2f30000), SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), + SPH_C32(0xf3e04259), SPH_C32(0x8d0d9ec4), SPH_C32(0x466d0c00), + SPH_C32(0x08620000), SPH_C32(0xdd5d0000), SPH_C32(0xbadd0000), + SPH_C32(0x6a927942), SPH_C32(0x441f2b93), SPH_C32(0x218ace6f), + SPH_C32(0xbf2c0be2) }, + { SPH_C32(0x466d0c00), SPH_C32(0x08620000), SPH_C32(0xdd5d0000), + SPH_C32(0xbadd0000), SPH_C32(0x6a927942), SPH_C32(0x441f2b93), + SPH_C32(0x218ace6f), SPH_C32(0xbf2c0be2), SPH_C32(0x6f299000), + SPH_C32(0x6c850000), SPH_C32(0x2f160000), SPH_C32(0x782e0000), + SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), SPH_C32(0xd26a8c36), + SPH_C32(0x32219526) }, + { SPH_C32(0x6f299000), SPH_C32(0x6c850000), SPH_C32(0x2f160000), + SPH_C32(0x782e0000), SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), + SPH_C32(0xd26a8c36), SPH_C32(0x32219526), SPH_C32(0x29449c00), + SPH_C32(0x64e70000), SPH_C32(0xf24b0000), SPH_C32(0xc2f30000), + SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), SPH_C32(0xf3e04259), + SPH_C32(0x8d0d9ec4) } +}; + +static const sph_u32 T512_2[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x54285c00), SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), + SPH_C32(0xa1c50000), SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), + SPH_C32(0x6bb0419d), SPH_C32(0x551b3782), SPH_C32(0x9cbb1800), + SPH_C32(0xb0d30000), SPH_C32(0x92510000), SPH_C32(0xed930000), + SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), SPH_C32(0x430633da), + SPH_C32(0x78cace29) }, + { SPH_C32(0x9cbb1800), SPH_C32(0xb0d30000), SPH_C32(0x92510000), + SPH_C32(0xed930000), SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), + SPH_C32(0x430633da), SPH_C32(0x78cace29), SPH_C32(0xc8934400), + SPH_C32(0x5a3e0000), SPH_C32(0x57870000), SPH_C32(0x4c560000), + SPH_C32(0xea982435), SPH_C32(0x75b11115), SPH_C32(0x28b67247), + SPH_C32(0x2dd1f9ab) }, + { SPH_C32(0xc8934400), SPH_C32(0x5a3e0000), SPH_C32(0x57870000), + SPH_C32(0x4c560000), SPH_C32(0xea982435), SPH_C32(0x75b11115), + SPH_C32(0x28b67247), SPH_C32(0x2dd1f9ab), SPH_C32(0x54285c00), + SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), SPH_C32(0xa1c50000), + SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), SPH_C32(0x6bb0419d), + SPH_C32(0x551b3782) } +}; + +static const sph_u32 T512_4[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x145a3c00), SPH_C32(0xb9e90000), SPH_C32(0x61270000), + SPH_C32(0xf1610000), SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), + SPH_C32(0x47a96720), SPH_C32(0xe18e24c5), SPH_C32(0x23671400), + SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), SPH_C32(0xfb750000), + SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), SPH_C32(0x02c40a3f), + SPH_C32(0xdc24e61f) }, + { SPH_C32(0x23671400), SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), + SPH_C32(0xfb750000), SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), + SPH_C32(0x02c40a3f), SPH_C32(0xdc24e61f), SPH_C32(0x373d2800), + SPH_C32(0x71500000), SPH_C32(0x95e00000), SPH_C32(0x0a140000), + SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), SPH_C32(0x456d6d1f), + SPH_C32(0x3daac2da) }, + { SPH_C32(0x373d2800), SPH_C32(0x71500000), SPH_C32(0x95e00000), + SPH_C32(0x0a140000), SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), + SPH_C32(0x456d6d1f), SPH_C32(0x3daac2da), SPH_C32(0x145a3c00), + SPH_C32(0xb9e90000), SPH_C32(0x61270000), SPH_C32(0xf1610000), + SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), SPH_C32(0x47a96720), + SPH_C32(0xe18e24c5) } +}; + +static const sph_u32 T512_6[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xef0b0270), SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), + SPH_C32(0x69490000), SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), + SPH_C32(0x66140a51), SPH_C32(0x924f5d0a), SPH_C32(0xc96b0030), + SPH_C32(0xe7250000), SPH_C32(0x2f840000), SPH_C32(0x264f0000), + SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), SPH_C32(0x509f6984), + SPH_C32(0x9e69af68) }, + { SPH_C32(0xc96b0030), SPH_C32(0xe7250000), SPH_C32(0x2f840000), + SPH_C32(0x264f0000), SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), + SPH_C32(0x509f6984), SPH_C32(0x9e69af68), SPH_C32(0x26600240), + SPH_C32(0xddd80000), SPH_C32(0x722a0000), SPH_C32(0x4f060000), + SPH_C32(0x936667ff), SPH_C32(0x29f944ce), SPH_C32(0x368b63d5), + SPH_C32(0x0c26f262) }, + { SPH_C32(0x26600240), SPH_C32(0xddd80000), SPH_C32(0x722a0000), + SPH_C32(0x4f060000), SPH_C32(0x936667ff), SPH_C32(0x29f944ce), + SPH_C32(0x368b63d5), SPH_C32(0x0c26f262), SPH_C32(0xef0b0270), + SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), SPH_C32(0x69490000), + SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), SPH_C32(0x66140a51), + SPH_C32(0x924f5d0a) } +}; + +static const sph_u32 T512_8[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xe8870170), SPH_C32(0x9d720000), SPH_C32(0x12db0000), + SPH_C32(0xd4220000), SPH_C32(0xf2886b27), SPH_C32(0xa921e543), + SPH_C32(0x4ef8b518), SPH_C32(0x618813b1), SPH_C32(0xb4370060), + SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), SPH_C32(0x5cae0000), + SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), SPH_C32(0x1b365f3d), + SPH_C32(0xf3d45758) }, + { SPH_C32(0xb4370060), SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), + SPH_C32(0x5cae0000), SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), + SPH_C32(0x1b365f3d), SPH_C32(0xf3d45758), SPH_C32(0x5cb00110), + SPH_C32(0x913e0000), SPH_C32(0x44190000), SPH_C32(0x888c0000), + SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), SPH_C32(0x55ceea25), + SPH_C32(0x925c44e9) }, + { SPH_C32(0x5cb00110), SPH_C32(0x913e0000), SPH_C32(0x44190000), + SPH_C32(0x888c0000), SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), + SPH_C32(0x55ceea25), SPH_C32(0x925c44e9), SPH_C32(0xe8870170), + SPH_C32(0x9d720000), SPH_C32(0x12db0000), SPH_C32(0xd4220000), + SPH_C32(0xf2886b27), SPH_C32(0xa921e543), SPH_C32(0x4ef8b518), + SPH_C32(0x618813b1) } +}; + +static const sph_u32 T512_10[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x774400f0), SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), + SPH_C32(0x34140000), SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), + SPH_C32(0x0bc3cd1e), SPH_C32(0xcf3775cb), SPH_C32(0xf46c0050), + SPH_C32(0x96180000), SPH_C32(0x14a50000), SPH_C32(0x031f0000), + SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), SPH_C32(0x9ca470d2), + SPH_C32(0x8a341574) }, + { SPH_C32(0xf46c0050), SPH_C32(0x96180000), SPH_C32(0x14a50000), + SPH_C32(0x031f0000), SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), + SPH_C32(0x9ca470d2), SPH_C32(0x8a341574), SPH_C32(0x832800a0), + SPH_C32(0x67420000), SPH_C32(0xe1170000), SPH_C32(0x370b0000), + SPH_C32(0xcba30034), SPH_C32(0x3c34923c), SPH_C32(0x9767bdcc), + SPH_C32(0x450360bf) }, + { SPH_C32(0x832800a0), SPH_C32(0x67420000), SPH_C32(0xe1170000), + SPH_C32(0x370b0000), SPH_C32(0xcba30034), SPH_C32(0x3c34923c), + SPH_C32(0x9767bdcc), SPH_C32(0x450360bf), SPH_C32(0x774400f0), + SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), SPH_C32(0x34140000), + SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), SPH_C32(0x0bc3cd1e), + SPH_C32(0xcf3775cb) } +}; + +static const sph_u32 T512_12[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xf7750009), SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), + SPH_C32(0x04920000), SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), + SPH_C32(0x7a87f14e), SPH_C32(0x9e16981a), SPH_C32(0xd46a0000), + SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), SPH_C32(0x4a290000), + SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), SPH_C32(0x98369604), + SPH_C32(0xf746c320) }, + { SPH_C32(0xd46a0000), SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), + SPH_C32(0x4a290000), SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), + SPH_C32(0x98369604), SPH_C32(0xf746c320), SPH_C32(0x231f0009), + SPH_C32(0x42f40000), SPH_C32(0x66790000), SPH_C32(0x4ebb0000), + SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), SPH_C32(0xe2b1674a), + SPH_C32(0x69505b3a) }, + { SPH_C32(0x231f0009), SPH_C32(0x42f40000), SPH_C32(0x66790000), + SPH_C32(0x4ebb0000), SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), + SPH_C32(0xe2b1674a), SPH_C32(0x69505b3a), SPH_C32(0xf7750009), + SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), SPH_C32(0x04920000), + SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), SPH_C32(0x7a87f14e), + SPH_C32(0x9e16981a) } +}; + +static const sph_u32 T512_14[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xf6800005), SPH_C32(0x3443c000), SPH_C32(0x24070000), + SPH_C32(0x8f3d0000), SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), + SPH_C32(0xcdc58b19), SPH_C32(0xd795ba31), SPH_C32(0xa67f0001), + SPH_C32(0x71378000), SPH_C32(0x19fc0000), SPH_C32(0x96db0000), + SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), SPH_C32(0x2c6d478f), + SPH_C32(0xac8e6c88) }, + { SPH_C32(0xa67f0001), SPH_C32(0x71378000), SPH_C32(0x19fc0000), + SPH_C32(0x96db0000), SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), + SPH_C32(0x2c6d478f), SPH_C32(0xac8e6c88), SPH_C32(0x50ff0004), + SPH_C32(0x45744000), SPH_C32(0x3dfb0000), SPH_C32(0x19e60000), + SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), SPH_C32(0xe1a8cc96), + SPH_C32(0x7b1bd6b9) }, + { SPH_C32(0x50ff0004), SPH_C32(0x45744000), SPH_C32(0x3dfb0000), + SPH_C32(0x19e60000), SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), + SPH_C32(0xe1a8cc96), SPH_C32(0x7b1bd6b9), SPH_C32(0xf6800005), + SPH_C32(0x3443c000), SPH_C32(0x24070000), SPH_C32(0x8f3d0000), + SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), SPH_C32(0xcdc58b19), + SPH_C32(0xd795ba31) } +}; + +static const sph_u32 T512_16[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x75c90003), SPH_C32(0x0e10c000), SPH_C32(0xd1200000), + SPH_C32(0xbaea0000), SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), + SPH_C32(0xbb28761d), SPH_C32(0x00b72e2b), SPH_C32(0xeecf0001), + SPH_C32(0x6f564000), SPH_C32(0xf33e0000), SPH_C32(0xa79e0000), + SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), SPH_C32(0x4a3b40ba), + SPH_C32(0xfeabf254) }, + { SPH_C32(0xeecf0001), SPH_C32(0x6f564000), SPH_C32(0xf33e0000), + SPH_C32(0xa79e0000), SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), + SPH_C32(0x4a3b40ba), SPH_C32(0xfeabf254), SPH_C32(0x9b060002), + SPH_C32(0x61468000), SPH_C32(0x221e0000), SPH_C32(0x1d740000), + SPH_C32(0x36715d27), SPH_C32(0x30495c92), SPH_C32(0xf11336a7), + SPH_C32(0xfe1cdc7f) }, + { SPH_C32(0x9b060002), SPH_C32(0x61468000), SPH_C32(0x221e0000), + SPH_C32(0x1d740000), SPH_C32(0x36715d27), SPH_C32(0x30495c92), + SPH_C32(0xf11336a7), SPH_C32(0xfe1cdc7f), SPH_C32(0x75c90003), + SPH_C32(0x0e10c000), SPH_C32(0xd1200000), SPH_C32(0xbaea0000), + SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), SPH_C32(0xbb28761d), + SPH_C32(0x00b72e2b) } +}; + +static const sph_u32 T512_18[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x75a40000), SPH_C32(0xc28b2700), SPH_C32(0x94a40000), + SPH_C32(0x90f50000), SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), + SPH_C32(0x1767c483), SPH_C32(0xaedf667e), SPH_C32(0xd1660000), + SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), SPH_C32(0xf6940000), + SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), SPH_C32(0xb4431b17), + SPH_C32(0x857f3c2b) }, + { SPH_C32(0xd1660000), SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), + SPH_C32(0xf6940000), SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), + SPH_C32(0xb4431b17), SPH_C32(0x857f3c2b), SPH_C32(0xa4c20000), + SPH_C32(0xd9372400), SPH_C32(0x0a480000), SPH_C32(0x66610000), + SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), SPH_C32(0xa324df94), + SPH_C32(0x2ba05a55) }, + { SPH_C32(0xa4c20000), SPH_C32(0xd9372400), SPH_C32(0x0a480000), + SPH_C32(0x66610000), SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), + SPH_C32(0xa324df94), SPH_C32(0x2ba05a55), SPH_C32(0x75a40000), + SPH_C32(0xc28b2700), SPH_C32(0x94a40000), SPH_C32(0x90f50000), + SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), SPH_C32(0x1767c483), + SPH_C32(0xaedf667e) } +}; + +static const sph_u32 T512_20[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x45180000), SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), + SPH_C32(0x3b480000), SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), + SPH_C32(0x16bca6b0), SPH_C32(0xdf33f4df), SPH_C32(0xb83d0000), + SPH_C32(0x16710600), SPH_C32(0x379a0000), SPH_C32(0xf5b10000), + SPH_C32(0x228161ac), SPH_C32(0xae48f145), SPH_C32(0x66241616), + SPH_C32(0xc5c1eb3e) }, + { SPH_C32(0xb83d0000), SPH_C32(0x16710600), SPH_C32(0x379a0000), + SPH_C32(0xf5b10000), SPH_C32(0x228161ac), SPH_C32(0xae48f145), + SPH_C32(0x66241616), SPH_C32(0xc5c1eb3e), SPH_C32(0xfd250000), + SPH_C32(0xb3c41100), SPH_C32(0xcef00000), SPH_C32(0xcef90000), + SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), SPH_C32(0x7098b0a6), + SPH_C32(0x1af21fe1) }, + { SPH_C32(0xfd250000), SPH_C32(0xb3c41100), SPH_C32(0xcef00000), + SPH_C32(0xcef90000), SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), + SPH_C32(0x7098b0a6), SPH_C32(0x1af21fe1), SPH_C32(0x45180000), + SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), SPH_C32(0x3b480000), + SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), SPH_C32(0x16bca6b0), + SPH_C32(0xdf33f4df) } +}; + +static const sph_u32 T512_22[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x0c720000), SPH_C32(0x49e50f00), SPH_C32(0x42790000), + SPH_C32(0x5cea0000), SPH_C32(0x33aa301a), SPH_C32(0x15822514), + SPH_C32(0x95a34b7b), SPH_C32(0xb44b0090), SPH_C32(0xfe220000), + SPH_C32(0xa7580500), SPH_C32(0x25d10000), SPH_C32(0xf7600000), + SPH_C32(0x893178da), SPH_C32(0x1fd4f860), SPH_C32(0x4ed0a315), + SPH_C32(0xa123ff9f) }, + { SPH_C32(0xfe220000), SPH_C32(0xa7580500), SPH_C32(0x25d10000), + SPH_C32(0xf7600000), SPH_C32(0x893178da), SPH_C32(0x1fd4f860), + SPH_C32(0x4ed0a315), SPH_C32(0xa123ff9f), SPH_C32(0xf2500000), + SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), SPH_C32(0xab8a0000), + SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), SPH_C32(0xdb73e86e), + SPH_C32(0x1568ff0f) }, + { SPH_C32(0xf2500000), SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), + SPH_C32(0xab8a0000), SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), + SPH_C32(0xdb73e86e), SPH_C32(0x1568ff0f), SPH_C32(0x0c720000), + SPH_C32(0x49e50f00), SPH_C32(0x42790000), SPH_C32(0x5cea0000), + SPH_C32(0x33aa301a), SPH_C32(0x15822514), SPH_C32(0x95a34b7b), + SPH_C32(0xb44b0090) } +}; + +static const sph_u32 T512_24[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x69510000), SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), + SPH_C32(0xac2f0000), SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), + SPH_C32(0x87ec287c), SPH_C32(0xbce1a3ce), SPH_C32(0xc6730000), + SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), SPH_C32(0x218d0000), + SPH_C32(0x23111587), SPH_C32(0x7913512f), SPH_C32(0x1d28ac88), + SPH_C32(0x378dd173) }, + { SPH_C32(0xc6730000), SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), + SPH_C32(0x218d0000), SPH_C32(0x23111587), SPH_C32(0x7913512f), + SPH_C32(0x1d28ac88), SPH_C32(0x378dd173), SPH_C32(0xaf220000), + SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), SPH_C32(0x8da20000), + SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), SPH_C32(0x9ac484f4), + SPH_C32(0x8b6c72bd) }, + { SPH_C32(0xaf220000), SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), + SPH_C32(0x8da20000), SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), + SPH_C32(0x9ac484f4), SPH_C32(0x8b6c72bd), SPH_C32(0x69510000), + SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), SPH_C32(0xac2f0000), + SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), SPH_C32(0x87ec287c), + SPH_C32(0xbce1a3ce) } +}; + +static const sph_u32 T512_26[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x54500000), SPH_C32(0x0671005c), SPH_C32(0x25ae0000), + SPH_C32(0x6a1e0000), SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), + SPH_C32(0xbfba18c3), SPH_C32(0x7e715d17), SPH_C32(0xbc8d0000), + SPH_C32(0xfc3b0018), SPH_C32(0x19830000), SPH_C32(0xd10b0000), + SPH_C32(0xae1878c4), SPH_C32(0x42a69856), SPH_C32(0x0012da37), + SPH_C32(0x2c3b504e) }, + { SPH_C32(0xbc8d0000), SPH_C32(0xfc3b0018), SPH_C32(0x19830000), + SPH_C32(0xd10b0000), SPH_C32(0xae1878c4), SPH_C32(0x42a69856), + SPH_C32(0x0012da37), SPH_C32(0x2c3b504e), SPH_C32(0xe8dd0000), + SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), SPH_C32(0xbb150000), + SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), SPH_C32(0xbfa8c2f4), + SPH_C32(0x524a0d59) }, + { SPH_C32(0xe8dd0000), SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), + SPH_C32(0xbb150000), SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), + SPH_C32(0xbfa8c2f4), SPH_C32(0x524a0d59), SPH_C32(0x54500000), + SPH_C32(0x0671005c), SPH_C32(0x25ae0000), SPH_C32(0x6a1e0000), + SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), SPH_C32(0xbfba18c3), + SPH_C32(0x7e715d17) } +}; + +static const sph_u32 T512_28[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x14190000), SPH_C32(0x23ca003c), SPH_C32(0x50df0000), + SPH_C32(0x44b60000), SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), + SPH_C32(0x61e610b0), SPH_C32(0xdbcadb80), SPH_C32(0xe3430000), + SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), SPH_C32(0xaa4e0000), + SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), SPH_C32(0x123db156), + SPH_C32(0x3a4e99d7) }, + { SPH_C32(0xe3430000), SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), + SPH_C32(0xaa4e0000), SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), + SPH_C32(0x123db156), SPH_C32(0x3a4e99d7), SPH_C32(0xf75a0000), + SPH_C32(0x19840028), SPH_C32(0xa2190000), SPH_C32(0xeef80000), + SPH_C32(0xc0722516), SPH_C32(0x19981260), SPH_C32(0x73dba1e6), + SPH_C32(0xe1844257) }, + { SPH_C32(0xf75a0000), SPH_C32(0x19840028), SPH_C32(0xa2190000), + SPH_C32(0xeef80000), SPH_C32(0xc0722516), SPH_C32(0x19981260), + SPH_C32(0x73dba1e6), SPH_C32(0xe1844257), SPH_C32(0x14190000), + SPH_C32(0x23ca003c), SPH_C32(0x50df0000), SPH_C32(0x44b60000), + SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), SPH_C32(0x61e610b0), + SPH_C32(0xdbcadb80) } +}; + +static const sph_u32 T512_30[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x86790000), SPH_C32(0x3f390002), SPH_C32(0xe19ae000), + SPH_C32(0x98560000), SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), + SPH_C32(0xd3dd4944), SPH_C32(0x161ddab9), SPH_C32(0x30b70000), + SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), SPH_C32(0x42c40000), + SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), SPH_C32(0x21afa1ea), + SPH_C32(0xb0a51834) }, + { SPH_C32(0x30b70000), SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), + SPH_C32(0x42c40000), SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), + SPH_C32(0x21afa1ea), SPH_C32(0xb0a51834), SPH_C32(0xb6ce0000), + SPH_C32(0xdae90002), SPH_C32(0x156e8000), SPH_C32(0xda920000), + SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), SPH_C32(0xf272e8ae), + SPH_C32(0xa6b8c28d) }, + { SPH_C32(0xb6ce0000), SPH_C32(0xdae90002), SPH_C32(0x156e8000), + SPH_C32(0xda920000), SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), + SPH_C32(0xf272e8ae), SPH_C32(0xa6b8c28d), SPH_C32(0x86790000), + SPH_C32(0x3f390002), SPH_C32(0xe19ae000), SPH_C32(0x98560000), + SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), SPH_C32(0xd3dd4944), + SPH_C32(0x161ddab9) } +}; + +static const sph_u32 T512_32[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xaec30000), SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), + SPH_C32(0x2c150000), SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), + SPH_C32(0xab92f78f), SPH_C32(0xa312567b), SPH_C32(0xdb250000), + SPH_C32(0x09290000), SPH_C32(0x49aac000), SPH_C32(0x81e10000), + SPH_C32(0xcafe6b59), SPH_C32(0x42793431), SPH_C32(0x43566b76), + SPH_C32(0xe86cba2e) }, + { SPH_C32(0xdb250000), SPH_C32(0x09290000), SPH_C32(0x49aac000), + SPH_C32(0x81e10000), SPH_C32(0xcafe6b59), SPH_C32(0x42793431), + SPH_C32(0x43566b76), SPH_C32(0xe86cba2e), SPH_C32(0x75e60000), + SPH_C32(0x95660001), SPH_C32(0x307b2000), SPH_C32(0xadf40000), + SPH_C32(0x8f321eea), SPH_C32(0x24298307), SPH_C32(0xe8c49cf9), + SPH_C32(0x4b7eec55) }, + { SPH_C32(0x75e60000), SPH_C32(0x95660001), SPH_C32(0x307b2000), + SPH_C32(0xadf40000), SPH_C32(0x8f321eea), SPH_C32(0x24298307), + SPH_C32(0xe8c49cf9), SPH_C32(0x4b7eec55), SPH_C32(0xaec30000), + SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), SPH_C32(0x2c150000), + SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), SPH_C32(0xab92f78f), + SPH_C32(0xa312567b) } +}; + +static const sph_u32 T512_34[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xac480000), SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), + SPH_C32(0x03430000), SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), + SPH_C32(0xfe72c7fe), SPH_C32(0x91e478f6), SPH_C32(0x1e4e0000), + SPH_C32(0xdecf0000), SPH_C32(0x6df80180), SPH_C32(0x77240000), + SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), SPH_C32(0xcda31812), + SPH_C32(0x98aa496e) }, + { SPH_C32(0x1e4e0000), SPH_C32(0xdecf0000), SPH_C32(0x6df80180), + SPH_C32(0x77240000), SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), + SPH_C32(0xcda31812), SPH_C32(0x98aa496e), SPH_C32(0xb2060000), + SPH_C32(0xc5690000), SPH_C32(0x28031200), SPH_C32(0x74670000), + SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), SPH_C32(0x33d1dfec), + SPH_C32(0x094e3198) }, + { SPH_C32(0xb2060000), SPH_C32(0xc5690000), SPH_C32(0x28031200), + SPH_C32(0x74670000), SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), + SPH_C32(0x33d1dfec), SPH_C32(0x094e3198), SPH_C32(0xac480000), + SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), SPH_C32(0x03430000), + SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), SPH_C32(0xfe72c7fe), + SPH_C32(0x91e478f6) } +}; + +static const sph_u32 T512_36[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x78230000), SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), + SPH_C32(0x90a50000), SPH_C32(0x713e2879), SPH_C32(0x7ee98924), + SPH_C32(0xf08ca062), SPH_C32(0x636f8bab), SPH_C32(0x02af0000), + SPH_C32(0xb7280000), SPH_C32(0xba1c0300), SPH_C32(0x56980000), + SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), SPH_C32(0xa95c149a), + SPH_C32(0xf4f6ea7b) }, + { SPH_C32(0x02af0000), SPH_C32(0xb7280000), SPH_C32(0xba1c0300), + SPH_C32(0x56980000), SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), + SPH_C32(0xa95c149a), SPH_C32(0xf4f6ea7b), SPH_C32(0x7a8c0000), + SPH_C32(0xa5d40000), SPH_C32(0x13260880), SPH_C32(0xc63d0000), + SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), SPH_C32(0x59d0b4f8), + SPH_C32(0x979961d0) }, + { SPH_C32(0x7a8c0000), SPH_C32(0xa5d40000), SPH_C32(0x13260880), + SPH_C32(0xc63d0000), SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), + SPH_C32(0x59d0b4f8), SPH_C32(0x979961d0), SPH_C32(0x78230000), + SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), SPH_C32(0x90a50000), + SPH_C32(0x713e2879), SPH_C32(0x7ee98924), SPH_C32(0xf08ca062), + SPH_C32(0x636f8bab) } +}; + +static const sph_u32 T512_38[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xcc140000), SPH_C32(0xa5630000), SPH_C32(0x5ab90780), + SPH_C32(0x3b500000), SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), + SPH_C32(0x694348c1), SPH_C32(0xca5a87fe), SPH_C32(0x819e0000), + SPH_C32(0xec570000), SPH_C32(0x66320280), SPH_C32(0x95f30000), + SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), SPH_C32(0xe65aa22d), + SPH_C32(0x8e67b7fa) }, + { SPH_C32(0x819e0000), SPH_C32(0xec570000), SPH_C32(0x66320280), + SPH_C32(0x95f30000), SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), + SPH_C32(0xe65aa22d), SPH_C32(0x8e67b7fa), SPH_C32(0x4d8a0000), + SPH_C32(0x49340000), SPH_C32(0x3c8b0500), SPH_C32(0xaea30000), + SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), SPH_C32(0x8f19eaec), + SPH_C32(0x443d3004) }, + { SPH_C32(0x4d8a0000), SPH_C32(0x49340000), SPH_C32(0x3c8b0500), + SPH_C32(0xaea30000), SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), + SPH_C32(0x8f19eaec), SPH_C32(0x443d3004), SPH_C32(0xcc140000), + SPH_C32(0xa5630000), SPH_C32(0x5ab90780), SPH_C32(0x3b500000), + SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), SPH_C32(0x694348c1), + SPH_C32(0xca5a87fe) } +}; + +static const sph_u32 T512_40[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x52500000), SPH_C32(0x29540000), SPH_C32(0x6a61004e), + SPH_C32(0xf0ff0000), SPH_C32(0x9a317eec), SPH_C32(0x452341ce), + SPH_C32(0xcf568fe5), SPH_C32(0x5303130f), SPH_C32(0x538d0000), + SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), SPH_C32(0x56ff0000), + SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), SPH_C32(0xa9444018), + SPH_C32(0x7f975691) }, + { SPH_C32(0x538d0000), SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), + SPH_C32(0x56ff0000), SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), + SPH_C32(0xa9444018), SPH_C32(0x7f975691), SPH_C32(0x01dd0000), + SPH_C32(0x80a80000), SPH_C32(0xf4960048), SPH_C32(0xa6000000), + SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), SPH_C32(0x6612cffd), + SPH_C32(0x2c94459e) }, + { SPH_C32(0x01dd0000), SPH_C32(0x80a80000), SPH_C32(0xf4960048), + SPH_C32(0xa6000000), SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), + SPH_C32(0x6612cffd), SPH_C32(0x2c94459e), SPH_C32(0x52500000), + SPH_C32(0x29540000), SPH_C32(0x6a61004e), SPH_C32(0xf0ff0000), + SPH_C32(0x9a317eec), SPH_C32(0x452341ce), SPH_C32(0xcf568fe5), + SPH_C32(0x5303130f) } +}; + +static const sph_u32 T512_42[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x88980000), SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), + SPH_C32(0xfb4e0000), SPH_C32(0xf158079a), SPH_C32(0x61ae9167), + SPH_C32(0xa895706c), SPH_C32(0xe6107494), SPH_C32(0x0bc20000), + SPH_C32(0xdb630000), SPH_C32(0x7e88000c), SPH_C32(0x15860000), + SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), SPH_C32(0xf460449e), + SPH_C32(0xd8b61463) }, + { SPH_C32(0x0bc20000), SPH_C32(0xdb630000), SPH_C32(0x7e88000c), + SPH_C32(0x15860000), SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), + SPH_C32(0xf460449e), SPH_C32(0xd8b61463), SPH_C32(0x835a0000), + SPH_C32(0xc4f70000), SPH_C32(0x01470022), SPH_C32(0xeec80000), + SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), SPH_C32(0x5cf534f2), + SPH_C32(0x3ea660f7) }, + { SPH_C32(0x835a0000), SPH_C32(0xc4f70000), SPH_C32(0x01470022), + SPH_C32(0xeec80000), SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), + SPH_C32(0x5cf534f2), SPH_C32(0x3ea660f7), SPH_C32(0x88980000), + SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), SPH_C32(0xfb4e0000), + SPH_C32(0xf158079a), SPH_C32(0x61ae9167), SPH_C32(0xa895706c), + SPH_C32(0xe6107494) } +}; + +static const sph_u32 T512_44[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xa53b0000), SPH_C32(0x14260000), SPH_C32(0x4e30001e), + SPH_C32(0x7cae0000), SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), + SPH_C32(0xf73168d8), SPH_C32(0x0b1b4946), SPH_C32(0x07ed0000), + SPH_C32(0xb2500000), SPH_C32(0x8774000a), SPH_C32(0x970d0000), + SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), SPH_C32(0xf4786222), + SPH_C32(0x9075b1ce) }, + { SPH_C32(0x07ed0000), SPH_C32(0xb2500000), SPH_C32(0x8774000a), + SPH_C32(0x970d0000), SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), + SPH_C32(0xf4786222), SPH_C32(0x9075b1ce), SPH_C32(0xa2d60000), + SPH_C32(0xa6760000), SPH_C32(0xc9440014), SPH_C32(0xeba30000), + SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), SPH_C32(0x03490afa), + SPH_C32(0x9b6ef888) }, + { SPH_C32(0xa2d60000), SPH_C32(0xa6760000), SPH_C32(0xc9440014), + SPH_C32(0xeba30000), SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), + SPH_C32(0x03490afa), SPH_C32(0x9b6ef888), SPH_C32(0xa53b0000), + SPH_C32(0x14260000), SPH_C32(0x4e30001e), SPH_C32(0x7cae0000), + SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), SPH_C32(0xf73168d8), + SPH_C32(0x0b1b4946) } +}; + +static const sph_u32 T512_46[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x58430000), SPH_C32(0x807e0000), SPH_C32(0x78330001), + SPH_C32(0xc66b3800), SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), + SPH_C32(0xac73fe6f), SPH_C32(0x3a4479b1), SPH_C32(0x1d5a0000), + SPH_C32(0x2b720000), SPH_C32(0x488d0000), SPH_C32(0xaf611800), + SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), SPH_C32(0x81a20429), + SPH_C32(0x1e7536a6) }, + { SPH_C32(0x1d5a0000), SPH_C32(0x2b720000), SPH_C32(0x488d0000), + SPH_C32(0xaf611800), SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), + SPH_C32(0x81a20429), SPH_C32(0x1e7536a6), SPH_C32(0x45190000), + SPH_C32(0xab0c0000), SPH_C32(0x30be0001), SPH_C32(0x690a2000), + SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), SPH_C32(0x2dd1fa46), + SPH_C32(0x24314f17) }, + { SPH_C32(0x45190000), SPH_C32(0xab0c0000), SPH_C32(0x30be0001), + SPH_C32(0x690a2000), SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), + SPH_C32(0x2dd1fa46), SPH_C32(0x24314f17), SPH_C32(0x58430000), + SPH_C32(0x807e0000), SPH_C32(0x78330001), SPH_C32(0xc66b3800), + SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), SPH_C32(0xac73fe6f), + SPH_C32(0x3a4479b1) } +}; + +static const sph_u32 T512_48[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x1e6c0000), SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), + SPH_C32(0xbcb6b800), SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), + SPH_C32(0x6a0c1bc8), SPH_C32(0xb99dc2eb), SPH_C32(0x92560000), + SPH_C32(0x1eda0000), SPH_C32(0xea510000), SPH_C32(0xe8b13000), + SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), SPH_C32(0xb15c2254), + SPH_C32(0x33c5244f) }, + { SPH_C32(0x92560000), SPH_C32(0x1eda0000), SPH_C32(0xea510000), + SPH_C32(0xe8b13000), SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), + SPH_C32(0xb15c2254), SPH_C32(0x33c5244f), SPH_C32(0x8c3a0000), + SPH_C32(0xda980000), SPH_C32(0x607f0000), SPH_C32(0x54078800), + SPH_C32(0x85714513), SPH_C32(0x6006b243), SPH_C32(0xdb50399c), + SPH_C32(0x8a58e6a4) }, + { SPH_C32(0x8c3a0000), SPH_C32(0xda980000), SPH_C32(0x607f0000), + SPH_C32(0x54078800), SPH_C32(0x85714513), SPH_C32(0x6006b243), + SPH_C32(0xdb50399c), SPH_C32(0x8a58e6a4), SPH_C32(0x1e6c0000), + SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), SPH_C32(0xbcb6b800), + SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), SPH_C32(0x6a0c1bc8), + SPH_C32(0xb99dc2eb) } +}; + +static const sph_u32 T512_50[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x02f20000), SPH_C32(0xa2810000), SPH_C32(0x873f0000), + SPH_C32(0xe36c7800), SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), + SPH_C32(0xc4c23237), SPH_C32(0x7f32259e), SPH_C32(0xbadd0000), + SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), SPH_C32(0xf7282800), + SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), SPH_C32(0xea5a8d14), + SPH_C32(0x2a2c18f0) }, + { SPH_C32(0xbadd0000), SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), + SPH_C32(0xf7282800), SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), + SPH_C32(0xea5a8d14), SPH_C32(0x2a2c18f0), SPH_C32(0xb82f0000), + SPH_C32(0xb12c0000), SPH_C32(0x30d80000), SPH_C32(0x14445000), + SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), SPH_C32(0x2e98bf23), + SPH_C32(0x551e3d6e) }, + { SPH_C32(0xb82f0000), SPH_C32(0xb12c0000), SPH_C32(0x30d80000), + SPH_C32(0x14445000), SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), + SPH_C32(0x2e98bf23), SPH_C32(0x551e3d6e), SPH_C32(0x02f20000), + SPH_C32(0xa2810000), SPH_C32(0x873f0000), SPH_C32(0xe36c7800), + SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), SPH_C32(0xc4c23237), + SPH_C32(0x7f32259e) } +}; + +static const sph_u32 T512_52[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xb4310000), SPH_C32(0x77330000), SPH_C32(0xb15d0000), + SPH_C32(0x7fd004e0), SPH_C32(0x78a26138), SPH_C32(0xd116c35d), + SPH_C32(0xd256d489), SPH_C32(0x4e6f74de), SPH_C32(0xe3060000), + SPH_C32(0xbdc10000), SPH_C32(0x87130000), SPH_C32(0xbff20060), + SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), SPH_C32(0x73c5ab06), + SPH_C32(0x5bd61539) }, + { SPH_C32(0xe3060000), SPH_C32(0xbdc10000), SPH_C32(0x87130000), + SPH_C32(0xbff20060), SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), + SPH_C32(0x73c5ab06), SPH_C32(0x5bd61539), SPH_C32(0x57370000), + SPH_C32(0xcaf20000), SPH_C32(0x364e0000), SPH_C32(0xc0220480), + SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), SPH_C32(0xa1937f8f), + SPH_C32(0x15b961e7) }, + { SPH_C32(0x57370000), SPH_C32(0xcaf20000), SPH_C32(0x364e0000), + SPH_C32(0xc0220480), SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), + SPH_C32(0xa1937f8f), SPH_C32(0x15b961e7), SPH_C32(0xb4310000), + SPH_C32(0x77330000), SPH_C32(0xb15d0000), SPH_C32(0x7fd004e0), + SPH_C32(0x78a26138), SPH_C32(0xd116c35d), SPH_C32(0xd256d489), + SPH_C32(0x4e6f74de) } +}; + +static const sph_u32 T512_54[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xe6280000), SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), + SPH_C32(0xd3d002e0), SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), + SPH_C32(0x289506b4), SPH_C32(0xd75a4897), SPH_C32(0xf0c50000), + SPH_C32(0x59230000), SPH_C32(0x45820000), SPH_C32(0xe18d00c0), + SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), SPH_C32(0xcbe0fe1c), + SPH_C32(0x56a7b19f) }, + { SPH_C32(0xf0c50000), SPH_C32(0x59230000), SPH_C32(0x45820000), + SPH_C32(0xe18d00c0), SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), + SPH_C32(0xcbe0fe1c), SPH_C32(0x56a7b19f), SPH_C32(0x16ed0000), + SPH_C32(0x15680000), SPH_C32(0xedd70000), SPH_C32(0x325d0220), + SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), SPH_C32(0xe375f8a8), + SPH_C32(0x81fdf908) }, + { SPH_C32(0x16ed0000), SPH_C32(0x15680000), SPH_C32(0xedd70000), + SPH_C32(0x325d0220), SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), + SPH_C32(0xe375f8a8), SPH_C32(0x81fdf908), SPH_C32(0xe6280000), + SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), SPH_C32(0xd3d002e0), + SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), SPH_C32(0x289506b4), + SPH_C32(0xd75a4897) } +}; + +static const sph_u32 T512_56[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xee930000), SPH_C32(0xd6070000), SPH_C32(0x92c10000), + SPH_C32(0x2b9801e0), SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), + SPH_C32(0x45312374), SPH_C32(0x201f6a64), SPH_C32(0x7b280000), + SPH_C32(0x57420000), SPH_C32(0xa9e50000), SPH_C32(0x634300a0), + SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), SPH_C32(0x27f83b03), + SPH_C32(0xc7ff60f0) }, + { SPH_C32(0x7b280000), SPH_C32(0x57420000), SPH_C32(0xa9e50000), + SPH_C32(0x634300a0), SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), + SPH_C32(0x27f83b03), SPH_C32(0xc7ff60f0), SPH_C32(0x95bb0000), + SPH_C32(0x81450000), SPH_C32(0x3b240000), SPH_C32(0x48db0140), + SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), SPH_C32(0x62c91877), + SPH_C32(0xe7e00a94) }, + { SPH_C32(0x95bb0000), SPH_C32(0x81450000), SPH_C32(0x3b240000), + SPH_C32(0x48db0140), SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), + SPH_C32(0x62c91877), SPH_C32(0xe7e00a94), SPH_C32(0xee930000), + SPH_C32(0xd6070000), SPH_C32(0x92c10000), SPH_C32(0x2b9801e0), + SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), SPH_C32(0x45312374), + SPH_C32(0x201f6a64) } +}; + +static const sph_u32 T512_58[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x5fa80000), SPH_C32(0x56030000), SPH_C32(0x43ae0000), + SPH_C32(0x64f30013), SPH_C32(0x257e86bf), SPH_C32(0x1311944e), + SPH_C32(0x541e95bf), SPH_C32(0x8ea4db69), SPH_C32(0x00440000), + SPH_C32(0x7f480000), SPH_C32(0xda7c0000), SPH_C32(0x2a230001), + SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), SPH_C32(0x030a9e60), + SPH_C32(0xbe0a679e) }, + { SPH_C32(0x00440000), SPH_C32(0x7f480000), SPH_C32(0xda7c0000), + SPH_C32(0x2a230001), SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), + SPH_C32(0x030a9e60), SPH_C32(0xbe0a679e), SPH_C32(0x5fec0000), + SPH_C32(0x294b0000), SPH_C32(0x99d20000), SPH_C32(0x4ed00012), + SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), SPH_C32(0x57140bdf), + SPH_C32(0x30aebcf7) }, + { SPH_C32(0x5fec0000), SPH_C32(0x294b0000), SPH_C32(0x99d20000), + SPH_C32(0x4ed00012), SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), + SPH_C32(0x57140bdf), SPH_C32(0x30aebcf7), SPH_C32(0x5fa80000), + SPH_C32(0x56030000), SPH_C32(0x43ae0000), SPH_C32(0x64f30013), + SPH_C32(0x257e86bf), SPH_C32(0x1311944e), SPH_C32(0x541e95bf), + SPH_C32(0x8ea4db69) } +}; + +static const sph_u32 T512_60[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x01930000), SPH_C32(0xe7820000), SPH_C32(0xedfb0000), + SPH_C32(0xcf0c000b), SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), + SPH_C32(0x063661e1), SPH_C32(0x536f9e7b), SPH_C32(0x92280000), + SPH_C32(0xdc850000), SPH_C32(0x57fa0000), SPH_C32(0x56dc0003), + SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), SPH_C32(0x90cef752), + SPH_C32(0x7b1675d7) }, + { SPH_C32(0x92280000), SPH_C32(0xdc850000), SPH_C32(0x57fa0000), + SPH_C32(0x56dc0003), SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), + SPH_C32(0x90cef752), SPH_C32(0x7b1675d7), SPH_C32(0x93bb0000), + SPH_C32(0x3b070000), SPH_C32(0xba010000), SPH_C32(0x99d00008), + SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), SPH_C32(0x96f896b3), + SPH_C32(0x2879ebac) }, + { SPH_C32(0x93bb0000), SPH_C32(0x3b070000), SPH_C32(0xba010000), + SPH_C32(0x99d00008), SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), + SPH_C32(0x96f896b3), SPH_C32(0x2879ebac), SPH_C32(0x01930000), + SPH_C32(0xe7820000), SPH_C32(0xedfb0000), SPH_C32(0xcf0c000b), + SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), SPH_C32(0x063661e1), + SPH_C32(0x536f9e7b) } +}; + +static const sph_u32 T512_62[4][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x033d0000), SPH_C32(0x08b30000), SPH_C32(0xf33a0000), + SPH_C32(0x3ac20007), SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), + SPH_C32(0x0ea5cfe3), SPH_C32(0xe6da7ffe), SPH_C32(0xa8da0000), + SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), SPH_C32(0x07da0002), + SPH_C32(0x7d669583), SPH_C32(0x1f98708a), SPH_C32(0xbb668808), + SPH_C32(0xda878000) }, + { SPH_C32(0xa8da0000), SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), + SPH_C32(0x07da0002), SPH_C32(0x7d669583), SPH_C32(0x1f98708a), + SPH_C32(0xbb668808), SPH_C32(0xda878000), SPH_C32(0xabe70000), + SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), SPH_C32(0x3d180005), + SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), SPH_C32(0xb5c347eb), + SPH_C32(0x3c5dfffe) }, + { SPH_C32(0xabe70000), SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), + SPH_C32(0x3d180005), SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), + SPH_C32(0xb5c347eb), SPH_C32(0x3c5dfffe), SPH_C32(0x033d0000), + SPH_C32(0x08b30000), SPH_C32(0xf33a0000), SPH_C32(0x3ac20007), + SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), SPH_C32(0x0ea5cfe3), + SPH_C32(0xe6da7ffe) } +}; + +#define INPUT_BIG do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T512_0[acc >> 6][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + m8 = rp[8]; \ + m9 = rp[9]; \ + mA = rp[10]; \ + mB = rp[11]; \ + mC = rp[12]; \ + mD = rp[13]; \ + mE = rp[14]; \ + mF = rp[15]; \ + rp = &T512_2[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_4[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_6[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[1]; \ + rp = &T512_8[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_10[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_12[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_14[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[2]; \ + rp = &T512_16[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_18[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_20[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_22[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[3]; \ + rp = &T512_24[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_26[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_28[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_30[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[4]; \ + rp = &T512_32[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_34[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_36[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_38[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[5]; \ + rp = &T512_40[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_42[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_44[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_46[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[6]; \ + rp = &T512_48[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_50[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_52[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_54[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[7]; \ + rp = &T512_56[acc >> 6][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_58[(acc >> 4) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_60[(acc >> 2) & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_62[acc & 0x03][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_BIG == 3 + +static const sph_u32 T512_0[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x9cbb1800), SPH_C32(0xb0d30000), SPH_C32(0x92510000), + SPH_C32(0xed930000), SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), + SPH_C32(0x430633da), SPH_C32(0x78cace29), SPH_C32(0xc8934400), + SPH_C32(0x5a3e0000), SPH_C32(0x57870000), SPH_C32(0x4c560000), + SPH_C32(0xea982435), SPH_C32(0x75b11115), SPH_C32(0x28b67247), + SPH_C32(0x2dd1f9ab) }, + { SPH_C32(0x29449c00), SPH_C32(0x64e70000), SPH_C32(0xf24b0000), + SPH_C32(0xc2f30000), SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), + SPH_C32(0xf3e04259), SPH_C32(0x8d0d9ec4), SPH_C32(0x466d0c00), + SPH_C32(0x08620000), SPH_C32(0xdd5d0000), SPH_C32(0xbadd0000), + SPH_C32(0x6a927942), SPH_C32(0x441f2b93), SPH_C32(0x218ace6f), + SPH_C32(0xbf2c0be2) }, + { SPH_C32(0xb5ff8400), SPH_C32(0xd4340000), SPH_C32(0x601a0000), + SPH_C32(0x2f600000), SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), + SPH_C32(0xb0e67183), SPH_C32(0xf5c750ed), SPH_C32(0x8efe4800), + SPH_C32(0x525c0000), SPH_C32(0x8ada0000), SPH_C32(0xf68b0000), + SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), SPH_C32(0x093cbc28), + SPH_C32(0x92fdf249) }, + { SPH_C32(0x466d0c00), SPH_C32(0x08620000), SPH_C32(0xdd5d0000), + SPH_C32(0xbadd0000), SPH_C32(0x6a927942), SPH_C32(0x441f2b93), + SPH_C32(0x218ace6f), SPH_C32(0xbf2c0be2), SPH_C32(0x6f299000), + SPH_C32(0x6c850000), SPH_C32(0x2f160000), SPH_C32(0x782e0000), + SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), SPH_C32(0xd26a8c36), + SPH_C32(0x32219526) }, + { SPH_C32(0xdad61400), SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), + SPH_C32(0x574e0000), SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), + SPH_C32(0x628cfdb5), SPH_C32(0xc7e6c5cb), SPH_C32(0xa7bad400), + SPH_C32(0x36bb0000), SPH_C32(0x78910000), SPH_C32(0x34780000), + SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), SPH_C32(0xfadcfe71), + SPH_C32(0x1ff06c8d) }, + { SPH_C32(0x6f299000), SPH_C32(0x6c850000), SPH_C32(0x2f160000), + SPH_C32(0x782e0000), SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), + SPH_C32(0xd26a8c36), SPH_C32(0x32219526), SPH_C32(0x29449c00), + SPH_C32(0x64e70000), SPH_C32(0xf24b0000), SPH_C32(0xc2f30000), + SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), SPH_C32(0xf3e04259), + SPH_C32(0x8d0d9ec4) }, + { SPH_C32(0xf3928800), SPH_C32(0xdc560000), SPH_C32(0xbd470000), + SPH_C32(0x95bd0000), SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), + SPH_C32(0x916cbfec), SPH_C32(0x4aeb5b0f), SPH_C32(0xe1d7d800), + SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), SPH_C32(0x8ea50000), + SPH_C32(0xe4466aba), SPH_C32(0x23732650), SPH_C32(0xdb56301e), + SPH_C32(0xa0dc676f) } +}; + +static const sph_u32 T512_3[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x145a3c00), SPH_C32(0xb9e90000), SPH_C32(0x61270000), + SPH_C32(0xf1610000), SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), + SPH_C32(0x47a96720), SPH_C32(0xe18e24c5), SPH_C32(0x23671400), + SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), SPH_C32(0xfb750000), + SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), SPH_C32(0x02c40a3f), + SPH_C32(0xdc24e61f) }, + { SPH_C32(0x23671400), SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), + SPH_C32(0xfb750000), SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), + SPH_C32(0x02c40a3f), SPH_C32(0xdc24e61f), SPH_C32(0x373d2800), + SPH_C32(0x71500000), SPH_C32(0x95e00000), SPH_C32(0x0a140000), + SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), SPH_C32(0x456d6d1f), + SPH_C32(0x3daac2da) }, + { SPH_C32(0x373d2800), SPH_C32(0x71500000), SPH_C32(0x95e00000), + SPH_C32(0x0a140000), SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), + SPH_C32(0x456d6d1f), SPH_C32(0x3daac2da), SPH_C32(0x145a3c00), + SPH_C32(0xb9e90000), SPH_C32(0x61270000), SPH_C32(0xf1610000), + SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), SPH_C32(0x47a96720), + SPH_C32(0xe18e24c5) }, + { SPH_C32(0x54285c00), SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), + SPH_C32(0xa1c50000), SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), + SPH_C32(0x6bb0419d), SPH_C32(0x551b3782), SPH_C32(0x9cbb1800), + SPH_C32(0xb0d30000), SPH_C32(0x92510000), SPH_C32(0xed930000), + SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), SPH_C32(0x430633da), + SPH_C32(0x78cace29) }, + { SPH_C32(0x40726000), SPH_C32(0x53040000), SPH_C32(0xa4f10000), + SPH_C32(0x50a40000), SPH_C32(0x7dc35a1c), SPH_C32(0x24ecf999), + SPH_C32(0x2c1926bd), SPH_C32(0xb4951347), SPH_C32(0xbfdc0c00), + SPH_C32(0x786a0000), SPH_C32(0x66960000), SPH_C32(0x16e60000), + SPH_C32(0x2af76720), SPH_C32(0x19b270bd), SPH_C32(0x41c239e5), + SPH_C32(0xa4ee2836) }, + { SPH_C32(0x774f4800), SPH_C32(0x22540000), SPH_C32(0x31110000), + SPH_C32(0x5ab00000), SPH_C32(0xc06f4315), SPH_C32(0x6c0361a8), + SPH_C32(0x69744ba2), SPH_C32(0x893fd19d), SPH_C32(0xab863000), + SPH_C32(0xc1830000), SPH_C32(0x07b10000), SPH_C32(0xe7870000), + SPH_C32(0xe4965a4c), SPH_C32(0xa9fb4dc5), SPH_C32(0x066b5ec5), + SPH_C32(0x45600cf3) }, + { SPH_C32(0x63157400), SPH_C32(0x9bbd0000), SPH_C32(0x50360000), + SPH_C32(0xabd10000), SPH_C32(0x0e0e7e79), SPH_C32(0xdc4a5cd0), + SPH_C32(0x2edd2c82), SPH_C32(0x68b1f558), SPH_C32(0x88e12400), + SPH_C32(0x093a0000), SPH_C32(0xf3760000), SPH_C32(0x1cf20000), + SPH_C32(0x975b7e29), SPH_C32(0x515de88c), SPH_C32(0x04af54fa), + SPH_C32(0x9944eaec) } +}; + +static const sph_u32 T512_6[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xb4370060), SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), + SPH_C32(0x5cae0000), SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), + SPH_C32(0x1b365f3d), SPH_C32(0xf3d45758), SPH_C32(0x5cb00110), + SPH_C32(0x913e0000), SPH_C32(0x44190000), SPH_C32(0x888c0000), + SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), SPH_C32(0x55ceea25), + SPH_C32(0x925c44e9) }, + { SPH_C32(0xef0b0270), SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), + SPH_C32(0x69490000), SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), + SPH_C32(0x66140a51), SPH_C32(0x924f5d0a), SPH_C32(0xc96b0030), + SPH_C32(0xe7250000), SPH_C32(0x2f840000), SPH_C32(0x264f0000), + SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), SPH_C32(0x509f6984), + SPH_C32(0x9e69af68) }, + { SPH_C32(0x5b3c0210), SPH_C32(0x36b10000), SPH_C32(0x0b6c0000), + SPH_C32(0x35e70000), SPH_C32(0x0f5b2339), SPH_C32(0x7f3b4ddc), + SPH_C32(0x7d22556c), SPH_C32(0x619b0a52), SPH_C32(0x95db0120), + SPH_C32(0x761b0000), SPH_C32(0x6b9d0000), SPH_C32(0xaec30000), + SPH_C32(0x6eb52fe1), SPH_C32(0xffe3ec51), SPH_C32(0x055183a1), + SPH_C32(0x0c35eb81) }, + { SPH_C32(0xc96b0030), SPH_C32(0xe7250000), SPH_C32(0x2f840000), + SPH_C32(0x264f0000), SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), + SPH_C32(0x509f6984), SPH_C32(0x9e69af68), SPH_C32(0x26600240), + SPH_C32(0xddd80000), SPH_C32(0x722a0000), SPH_C32(0x4f060000), + SPH_C32(0x936667ff), SPH_C32(0x29f944ce), SPH_C32(0x368b63d5), + SPH_C32(0x0c26f262) }, + { SPH_C32(0x7d5c0050), SPH_C32(0xeb690000), SPH_C32(0x79460000), + SPH_C32(0x7ae10000), SPH_C32(0x9c3d44c6), SPH_C32(0x56c20912), + SPH_C32(0x4ba936b9), SPH_C32(0x6dbdf830), SPH_C32(0x7ad00350), + SPH_C32(0x4ce60000), SPH_C32(0x36330000), SPH_C32(0xc78a0000), + SPH_C32(0xf5ba13e7), SPH_C32(0xbbe659a8), SPH_C32(0x634589f0), + SPH_C32(0x9e7ab68b) }, + { SPH_C32(0x26600240), SPH_C32(0xddd80000), SPH_C32(0x722a0000), + SPH_C32(0x4f060000), SPH_C32(0x936667ff), SPH_C32(0x29f944ce), + SPH_C32(0x368b63d5), SPH_C32(0x0c26f262), SPH_C32(0xef0b0270), + SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), SPH_C32(0x69490000), + SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), SPH_C32(0x66140a51), + SPH_C32(0x924f5d0a) }, + { SPH_C32(0x92570220), SPH_C32(0xd1940000), SPH_C32(0x24e80000), + SPH_C32(0x13a80000), SPH_C32(0x073278c0), SPH_C32(0x12c7bceb), + SPH_C32(0x2dbd3ce8), SPH_C32(0xfff2a53a), SPH_C32(0xb3bb0360), + SPH_C32(0xabc30000), SPH_C32(0x19b70000), SPH_C32(0xe1c50000), + SPH_C32(0xfdd3481e), SPH_C32(0xd61aa89f), SPH_C32(0x33dae074), + SPH_C32(0x001319e3) } +}; + +static const sph_u32 T512_9[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x774400f0), SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), + SPH_C32(0x34140000), SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), + SPH_C32(0x0bc3cd1e), SPH_C32(0xcf3775cb), SPH_C32(0xf46c0050), + SPH_C32(0x96180000), SPH_C32(0x14a50000), SPH_C32(0x031f0000), + SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), SPH_C32(0x9ca470d2), + SPH_C32(0x8a341574) }, + { SPH_C32(0xf46c0050), SPH_C32(0x96180000), SPH_C32(0x14a50000), + SPH_C32(0x031f0000), SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), + SPH_C32(0x9ca470d2), SPH_C32(0x8a341574), SPH_C32(0x832800a0), + SPH_C32(0x67420000), SPH_C32(0xe1170000), SPH_C32(0x370b0000), + SPH_C32(0xcba30034), SPH_C32(0x3c34923c), SPH_C32(0x9767bdcc), + SPH_C32(0x450360bf) }, + { SPH_C32(0x832800a0), SPH_C32(0x67420000), SPH_C32(0xe1170000), + SPH_C32(0x370b0000), SPH_C32(0xcba30034), SPH_C32(0x3c34923c), + SPH_C32(0x9767bdcc), SPH_C32(0x450360bf), SPH_C32(0x774400f0), + SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), SPH_C32(0x34140000), + SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), SPH_C32(0x0bc3cd1e), + SPH_C32(0xcf3775cb) }, + { SPH_C32(0xe8870170), SPH_C32(0x9d720000), SPH_C32(0x12db0000), + SPH_C32(0xd4220000), SPH_C32(0xf2886b27), SPH_C32(0xa921e543), + SPH_C32(0x4ef8b518), SPH_C32(0x618813b1), SPH_C32(0xb4370060), + SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), SPH_C32(0x5cae0000), + SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), SPH_C32(0x1b365f3d), + SPH_C32(0xf3d45758) }, + { SPH_C32(0x9fc30180), SPH_C32(0x6c280000), SPH_C32(0xe7690000), + SPH_C32(0xe0360000), SPH_C32(0x7bbf15ab), SPH_C32(0xf3aa0966), + SPH_C32(0x453b7806), SPH_C32(0xaebf667a), SPH_C32(0x405b0030), + SPH_C32(0x9a540000), SPH_C32(0x42670000), SPH_C32(0x5fb10000), + SPH_C32(0xd6c06187), SPH_C32(0x5d81863c), SPH_C32(0x87922fef), + SPH_C32(0x79e0422c) }, + { SPH_C32(0x1ceb0120), SPH_C32(0x0b6a0000), SPH_C32(0x067e0000), + SPH_C32(0xd73d0000), SPH_C32(0xb01c159f), SPH_C32(0xcf9e9b5a), + SPH_C32(0xd25cc5ca), SPH_C32(0xebbc06c5), SPH_C32(0x371f00c0), + SPH_C32(0x6b0e0000), SPH_C32(0xb7d50000), SPH_C32(0x6ba50000), + SPH_C32(0x5ff71f0b), SPH_C32(0x070a6a19), SPH_C32(0x8c51e2f1), + SPH_C32(0xb6d737e7) }, + { SPH_C32(0x6baf01d0), SPH_C32(0xfa300000), SPH_C32(0xf3cc0000), + SPH_C32(0xe3290000), SPH_C32(0x392b6b13), SPH_C32(0x9515777f), + SPH_C32(0xd99f08d4), SPH_C32(0x248b730e), SPH_C32(0xc3730090), + SPH_C32(0xfd160000), SPH_C32(0xa3700000), SPH_C32(0x68ba0000), + SPH_C32(0x1d6361b3), SPH_C32(0x61b51400), SPH_C32(0x10f59223), + SPH_C32(0x3ce32293) } +}; + +static const sph_u32 T512_12[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xa67f0001), SPH_C32(0x71378000), SPH_C32(0x19fc0000), + SPH_C32(0x96db0000), SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), + SPH_C32(0x2c6d478f), SPH_C32(0xac8e6c88), SPH_C32(0x50ff0004), + SPH_C32(0x45744000), SPH_C32(0x3dfb0000), SPH_C32(0x19e60000), + SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), SPH_C32(0xe1a8cc96), + SPH_C32(0x7b1bd6b9) }, + { SPH_C32(0xf7750009), SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), + SPH_C32(0x04920000), SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), + SPH_C32(0x7a87f14e), SPH_C32(0x9e16981a), SPH_C32(0xd46a0000), + SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), SPH_C32(0x4a290000), + SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), SPH_C32(0x98369604), + SPH_C32(0xf746c320) }, + { SPH_C32(0x510a0008), SPH_C32(0xbe0b4000), SPH_C32(0xda2a0000), + SPH_C32(0x92490000), SPH_C32(0x381e7454), SPH_C32(0x13229849), + SPH_C32(0x56eab6c1), SPH_C32(0x3298f492), SPH_C32(0x84950004), + SPH_C32(0xc8bc8000), SPH_C32(0x98540000), SPH_C32(0x53cf0000), + SPH_C32(0xe7f2147c), SPH_C32(0x28c6fd31), SPH_C32(0x799e5a92), + SPH_C32(0x8c5d1599) }, + { SPH_C32(0xd46a0000), SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), + SPH_C32(0x4a290000), SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), + SPH_C32(0x98369604), SPH_C32(0xf746c320), SPH_C32(0x231f0009), + SPH_C32(0x42f40000), SPH_C32(0x66790000), SPH_C32(0x4ebb0000), + SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), SPH_C32(0xe2b1674a), + SPH_C32(0x69505b3a) }, + { SPH_C32(0x72150001), SPH_C32(0xfcff4000), SPH_C32(0xbc530000), + SPH_C32(0xdcf20000), SPH_C32(0xc6c52f87), SPH_C32(0x227e289f), + SPH_C32(0xb45bd18b), SPH_C32(0x5bc8afa8), SPH_C32(0x73e0000d), + SPH_C32(0x07804000), SPH_C32(0x5b820000), SPH_C32(0x575d0000), + SPH_C32(0xe5670dd5), SPH_C32(0xd02ecb8b), SPH_C32(0x0319abdc), + SPH_C32(0x124b8d83) }, + { SPH_C32(0x231f0009), SPH_C32(0x42f40000), SPH_C32(0x66790000), + SPH_C32(0x4ebb0000), SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), + SPH_C32(0xe2b1674a), SPH_C32(0x69505b3a), SPH_C32(0xf7750009), + SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), SPH_C32(0x04920000), + SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), SPH_C32(0x7a87f14e), + SPH_C32(0x9e16981a) }, + { SPH_C32(0x85600008), SPH_C32(0x33c38000), SPH_C32(0x7f850000), + SPH_C32(0xd8600000), SPH_C32(0xc450362e), SPH_C32(0xda961e25), + SPH_C32(0xcedc20c5), SPH_C32(0xc5de37b2), SPH_C32(0xa78a000d), + SPH_C32(0x8a488000), SPH_C32(0xfe2d0000), SPH_C32(0x1d740000), + SPH_C32(0x19294faf), SPH_C32(0x199a4de7), SPH_C32(0x9b2f3dd8), + SPH_C32(0xe50d4ea3) } +}; + +static const sph_u32 T512_15[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x75c90003), SPH_C32(0x0e10c000), SPH_C32(0xd1200000), + SPH_C32(0xbaea0000), SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), + SPH_C32(0xbb28761d), SPH_C32(0x00b72e2b), SPH_C32(0xeecf0001), + SPH_C32(0x6f564000), SPH_C32(0xf33e0000), SPH_C32(0xa79e0000), + SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), SPH_C32(0x4a3b40ba), + SPH_C32(0xfeabf254) }, + { SPH_C32(0xeecf0001), SPH_C32(0x6f564000), SPH_C32(0xf33e0000), + SPH_C32(0xa79e0000), SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), + SPH_C32(0x4a3b40ba), SPH_C32(0xfeabf254), SPH_C32(0x9b060002), + SPH_C32(0x61468000), SPH_C32(0x221e0000), SPH_C32(0x1d740000), + SPH_C32(0x36715d27), SPH_C32(0x30495c92), SPH_C32(0xf11336a7), + SPH_C32(0xfe1cdc7f) }, + { SPH_C32(0x9b060002), SPH_C32(0x61468000), SPH_C32(0x221e0000), + SPH_C32(0x1d740000), SPH_C32(0x36715d27), SPH_C32(0x30495c92), + SPH_C32(0xf11336a7), SPH_C32(0xfe1cdc7f), SPH_C32(0x75c90003), + SPH_C32(0x0e10c000), SPH_C32(0xd1200000), SPH_C32(0xbaea0000), + SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), SPH_C32(0xbb28761d), + SPH_C32(0x00b72e2b) }, + { SPH_C32(0xf6800005), SPH_C32(0x3443c000), SPH_C32(0x24070000), + SPH_C32(0x8f3d0000), SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), + SPH_C32(0xcdc58b19), SPH_C32(0xd795ba31), SPH_C32(0xa67f0001), + SPH_C32(0x71378000), SPH_C32(0x19fc0000), SPH_C32(0x96db0000), + SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), SPH_C32(0x2c6d478f), + SPH_C32(0xac8e6c88) }, + { SPH_C32(0x83490006), SPH_C32(0x3a530000), SPH_C32(0xf5270000), + SPH_C32(0x35d70000), SPH_C32(0xaaf314c5), SPH_C32(0x8de062f9), + SPH_C32(0x76edfd04), SPH_C32(0xd722941a), SPH_C32(0x48b00000), + SPH_C32(0x1e61c000), SPH_C32(0xeac20000), SPH_C32(0x31450000), + SPH_C32(0x873e1fe4), SPH_C32(0x5cdb4536), SPH_C32(0x66560735), + SPH_C32(0x52259edc) }, + { SPH_C32(0x184f0004), SPH_C32(0x5b158000), SPH_C32(0xd7390000), + SPH_C32(0x28a30000), SPH_C32(0x9c8249e2), SPH_C32(0xbda93e6b), + SPH_C32(0x87fecba3), SPH_C32(0x293e4865), SPH_C32(0x3d790003), + SPH_C32(0x10710000), SPH_C32(0x3be20000), SPH_C32(0x8baf0000), + SPH_C32(0x0cfa30da), SPH_C32(0xdb83f261), SPH_C32(0xdd7e7128), + SPH_C32(0x5292b0f7) }, + { SPH_C32(0x6d860007), SPH_C32(0x55054000), SPH_C32(0x06190000), + SPH_C32(0x92490000), SPH_C32(0x174666dc), SPH_C32(0x3af1893c), + SPH_C32(0x3cd6bdbe), SPH_C32(0x2989664e), SPH_C32(0xd3b60002), + SPH_C32(0x7f274000), SPH_C32(0xc8dc0000), SPH_C32(0x2c310000), + SPH_C32(0xb14f42c3), SPH_C32(0x6c9219a4), SPH_C32(0x97453192), + SPH_C32(0xac3942a3) } +}; + +static const sph_u32 T512_18[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xb83d0000), SPH_C32(0x16710600), SPH_C32(0x379a0000), + SPH_C32(0xf5b10000), SPH_C32(0x228161ac), SPH_C32(0xae48f145), + SPH_C32(0x66241616), SPH_C32(0xc5c1eb3e), SPH_C32(0xfd250000), + SPH_C32(0xb3c41100), SPH_C32(0xcef00000), SPH_C32(0xcef90000), + SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), SPH_C32(0x7098b0a6), + SPH_C32(0x1af21fe1) }, + { SPH_C32(0x75a40000), SPH_C32(0xc28b2700), SPH_C32(0x94a40000), + SPH_C32(0x90f50000), SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), + SPH_C32(0x1767c483), SPH_C32(0xaedf667e), SPH_C32(0xd1660000), + SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), SPH_C32(0xf6940000), + SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), SPH_C32(0xb4431b17), + SPH_C32(0x857f3c2b) }, + { SPH_C32(0xcd990000), SPH_C32(0xd4fa2100), SPH_C32(0xa33e0000), + SPH_C32(0x65440000), SPH_C32(0xd9f9364c), SPH_C32(0xe786faeb), + SPH_C32(0x7143d295), SPH_C32(0x6b1e8d40), SPH_C32(0x2c430000), + SPH_C32(0xa8781200), SPH_C32(0x501c0000), SPH_C32(0x386d0000), + SPH_C32(0x3f4f30a7), SPH_C32(0x422b9861), SPH_C32(0xc4dbabb1), + SPH_C32(0x9f8d23ca) }, + { SPH_C32(0xd1660000), SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), + SPH_C32(0xf6940000), SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), + SPH_C32(0xb4431b17), SPH_C32(0x857f3c2b), SPH_C32(0xa4c20000), + SPH_C32(0xd9372400), SPH_C32(0x0a480000), SPH_C32(0x66610000), + SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), SPH_C32(0xa324df94), + SPH_C32(0x2ba05a55) }, + { SPH_C32(0x695b0000), SPH_C32(0x0dcd0500), SPH_C32(0xa9760000), + SPH_C32(0x03250000), SPH_C32(0x2183248b), SPH_C32(0x61380db7), + SPH_C32(0xd2670d01), SPH_C32(0x40bed715), SPH_C32(0x59e70000), + SPH_C32(0x6af33500), SPH_C32(0xc4b80000), SPH_C32(0xa8980000), + SPH_C32(0xc4376747), SPH_C32(0x0be593cf), SPH_C32(0xd3bc6f32), + SPH_C32(0x315245b4) }, + { SPH_C32(0xa4c20000), SPH_C32(0xd9372400), SPH_C32(0x0a480000), + SPH_C32(0x66610000), SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), + SPH_C32(0xa324df94), SPH_C32(0x2ba05a55), SPH_C32(0x75a40000), + SPH_C32(0xc28b2700), SPH_C32(0x94a40000), SPH_C32(0x90f50000), + SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), SPH_C32(0x1767c483), + SPH_C32(0xaedf667e) }, + { SPH_C32(0x1cff0000), SPH_C32(0xcf462200), SPH_C32(0x3dd20000), + SPH_C32(0x93d00000), SPH_C32(0xdafb736b), SPH_C32(0x28f60619), + SPH_C32(0xc500c982), SPH_C32(0xee61b16b), SPH_C32(0x88810000), + SPH_C32(0x714f3600), SPH_C32(0x5a540000), SPH_C32(0x5e0c0000), + SPH_C32(0xc7352260), SPH_C32(0xc4956f3d), SPH_C32(0x67ff7425), + SPH_C32(0xb42d799f) } +}; + +static const sph_u32 T512_21[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x0c720000), SPH_C32(0x49e50f00), SPH_C32(0x42790000), + SPH_C32(0x5cea0000), SPH_C32(0x33aa301a), SPH_C32(0x15822514), + SPH_C32(0x95a34b7b), SPH_C32(0xb44b0090), SPH_C32(0xfe220000), + SPH_C32(0xa7580500), SPH_C32(0x25d10000), SPH_C32(0xf7600000), + SPH_C32(0x893178da), SPH_C32(0x1fd4f860), SPH_C32(0x4ed0a315), + SPH_C32(0xa123ff9f) }, + { SPH_C32(0xfe220000), SPH_C32(0xa7580500), SPH_C32(0x25d10000), + SPH_C32(0xf7600000), SPH_C32(0x893178da), SPH_C32(0x1fd4f860), + SPH_C32(0x4ed0a315), SPH_C32(0xa123ff9f), SPH_C32(0xf2500000), + SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), SPH_C32(0xab8a0000), + SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), SPH_C32(0xdb73e86e), + SPH_C32(0x1568ff0f) }, + { SPH_C32(0xf2500000), SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), + SPH_C32(0xab8a0000), SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), + SPH_C32(0xdb73e86e), SPH_C32(0x1568ff0f), SPH_C32(0x0c720000), + SPH_C32(0x49e50f00), SPH_C32(0x42790000), SPH_C32(0x5cea0000), + SPH_C32(0x33aa301a), SPH_C32(0x15822514), SPH_C32(0x95a34b7b), + SPH_C32(0xb44b0090) }, + { SPH_C32(0x45180000), SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), + SPH_C32(0x3b480000), SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), + SPH_C32(0x16bca6b0), SPH_C32(0xdf33f4df), SPH_C32(0xb83d0000), + SPH_C32(0x16710600), SPH_C32(0x379a0000), SPH_C32(0xf5b10000), + SPH_C32(0x228161ac), SPH_C32(0xae48f145), SPH_C32(0x66241616), + SPH_C32(0xc5c1eb3e) }, + { SPH_C32(0x496a0000), SPH_C32(0xec501800), SPH_C32(0xbb130000), + SPH_C32(0x67a20000), SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), + SPH_C32(0x831fedcb), SPH_C32(0x6b78f44f), SPH_C32(0x461f0000), + SPH_C32(0xb1290300), SPH_C32(0x124b0000), SPH_C32(0x02d10000), + SPH_C32(0xabb01976), SPH_C32(0xb19c0925), SPH_C32(0x28f4b503), + SPH_C32(0x64e214a1) }, + { SPH_C32(0xbb3a0000), SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), + SPH_C32(0xcc280000), SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), + SPH_C32(0x586c05a5), SPH_C32(0x7e100b40), SPH_C32(0x4a6d0000), + SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), SPH_C32(0x5e3b0000), + SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), SPH_C32(0xbd57fe78), + SPH_C32(0xd0a91431) }, + { SPH_C32(0xb7480000), SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), + SPH_C32(0x90c20000), SPH_C32(0xa4575cec), SPH_C32(0x294548a2), + SPH_C32(0xcdcf4ede), SPH_C32(0xca5b0bd0), SPH_C32(0xb44f0000), + SPH_C32(0x5f940900), SPH_C32(0x75e30000), SPH_C32(0xa95b0000), + SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), SPH_C32(0xf3875d6d), + SPH_C32(0x718aebae) } +}; + +static const sph_u32 T512_24[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xbc8d0000), SPH_C32(0xfc3b0018), SPH_C32(0x19830000), + SPH_C32(0xd10b0000), SPH_C32(0xae1878c4), SPH_C32(0x42a69856), + SPH_C32(0x0012da37), SPH_C32(0x2c3b504e), SPH_C32(0xe8dd0000), + SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), SPH_C32(0xbb150000), + SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), SPH_C32(0xbfa8c2f4), + SPH_C32(0x524a0d59) }, + { SPH_C32(0x69510000), SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), + SPH_C32(0xac2f0000), SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), + SPH_C32(0x87ec287c), SPH_C32(0xbce1a3ce), SPH_C32(0xc6730000), + SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), SPH_C32(0x218d0000), + SPH_C32(0x23111587), SPH_C32(0x7913512f), SPH_C32(0x1d28ac88), + SPH_C32(0x378dd173) }, + { SPH_C32(0xd5dc0000), SPH_C32(0x28da0084), SPH_C32(0xdaa00000), + SPH_C32(0x7d240000), SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), + SPH_C32(0x87fef24b), SPH_C32(0x90daf380), SPH_C32(0x2eae0000), + SPH_C32(0x55c70048), SPH_C32(0x98ec0000), SPH_C32(0x9a980000), + SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), SPH_C32(0xa2806e7c), + SPH_C32(0x65c7dc2a) }, + { SPH_C32(0xc6730000), SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), + SPH_C32(0x218d0000), SPH_C32(0x23111587), SPH_C32(0x7913512f), + SPH_C32(0x1d28ac88), SPH_C32(0x378dd173), SPH_C32(0xaf220000), + SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), SPH_C32(0x8da20000), + SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), SPH_C32(0x9ac484f4), + SPH_C32(0x8b6c72bd) }, + { SPH_C32(0x7afe0000), SPH_C32(0x53b60014), SPH_C32(0xbd420000), + SPH_C32(0xf0860000), SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), + SPH_C32(0x1d3a76bf), SPH_C32(0x1bb6813d), SPH_C32(0x47ff0000), + SPH_C32(0x812600d4), SPH_C32(0x5bcf0000), SPH_C32(0x36b70000), + SPH_C32(0x47392832), SPH_C32(0x935f59b7), SPH_C32(0x256c4600), + SPH_C32(0xd9267fe4) }, + { SPH_C32(0xaf220000), SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), + SPH_C32(0x8da20000), SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), + SPH_C32(0x9ac484f4), SPH_C32(0x8b6c72bd), SPH_C32(0x69510000), + SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), SPH_C32(0xac2f0000), + SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), SPH_C32(0x87ec287c), + SPH_C32(0xbce1a3ce) }, + { SPH_C32(0x13af0000), SPH_C32(0x87570088), SPH_C32(0x7e610000), + SPH_C32(0x5ca90000), SPH_C32(0x699c66ed), SPH_C32(0xf511dca5), + SPH_C32(0x9ad65ec3), SPH_C32(0xa75722f3), SPH_C32(0x818c0000), + SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), SPH_C32(0x173a0000), + SPH_C32(0x64283db5), SPH_C32(0xea4c0898), SPH_C32(0x3844ea88), + SPH_C32(0xeeabae97) } +}; + +static const sph_u32 T512_27[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x14190000), SPH_C32(0x23ca003c), SPH_C32(0x50df0000), + SPH_C32(0x44b60000), SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), + SPH_C32(0x61e610b0), SPH_C32(0xdbcadb80), SPH_C32(0xe3430000), + SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), SPH_C32(0xaa4e0000), + SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), SPH_C32(0x123db156), + SPH_C32(0x3a4e99d7) }, + { SPH_C32(0xe3430000), SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), + SPH_C32(0xaa4e0000), SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), + SPH_C32(0x123db156), SPH_C32(0x3a4e99d7), SPH_C32(0xf75a0000), + SPH_C32(0x19840028), SPH_C32(0xa2190000), SPH_C32(0xeef80000), + SPH_C32(0xc0722516), SPH_C32(0x19981260), SPH_C32(0x73dba1e6), + SPH_C32(0xe1844257) }, + { SPH_C32(0xf75a0000), SPH_C32(0x19840028), SPH_C32(0xa2190000), + SPH_C32(0xeef80000), SPH_C32(0xc0722516), SPH_C32(0x19981260), + SPH_C32(0x73dba1e6), SPH_C32(0xe1844257), SPH_C32(0x14190000), + SPH_C32(0x23ca003c), SPH_C32(0x50df0000), SPH_C32(0x44b60000), + SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), SPH_C32(0x61e610b0), + SPH_C32(0xdbcadb80) }, + { SPH_C32(0x54500000), SPH_C32(0x0671005c), SPH_C32(0x25ae0000), + SPH_C32(0x6a1e0000), SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), + SPH_C32(0xbfba18c3), SPH_C32(0x7e715d17), SPH_C32(0xbc8d0000), + SPH_C32(0xfc3b0018), SPH_C32(0x19830000), SPH_C32(0xd10b0000), + SPH_C32(0xae1878c4), SPH_C32(0x42a69856), SPH_C32(0x0012da37), + SPH_C32(0x2c3b504e) }, + { SPH_C32(0x40490000), SPH_C32(0x25bb0060), SPH_C32(0x75710000), + SPH_C32(0x2ea80000), SPH_C32(0x35c9296f), SPH_C32(0x5abd2967), + SPH_C32(0xde5c0873), SPH_C32(0xa5bb8697), SPH_C32(0x5fce0000), + SPH_C32(0xc675000c), SPH_C32(0xeb450000), SPH_C32(0x7b450000), + SPH_C32(0x75063a62), SPH_C32(0x67cd2643), SPH_C32(0x122f6b61), + SPH_C32(0x1675c999) }, + { SPH_C32(0xb7130000), SPH_C32(0x3c3f0048), SPH_C32(0xd7680000), + SPH_C32(0xc0500000), SPH_C32(0xf5bb0c79), SPH_C32(0x43253b07), + SPH_C32(0xad87a995), SPH_C32(0x443fc4c0), SPH_C32(0x4bd70000), + SPH_C32(0xe5bf0030), SPH_C32(0xbb9a0000), SPH_C32(0x3ff30000), + SPH_C32(0x6e6a5dd2), SPH_C32(0x5b3e8a36), SPH_C32(0x73c97bd1), + SPH_C32(0xcdbf1219) }, + { SPH_C32(0xa30a0000), SPH_C32(0x1ff50074), SPH_C32(0x87b70000), + SPH_C32(0x84e60000), SPH_C32(0xeed76bc9), SPH_C32(0x7fd69772), + SPH_C32(0xcc61b925), SPH_C32(0x9ff51f40), SPH_C32(0xa8940000), + SPH_C32(0xdff10024), SPH_C32(0x495c0000), SPH_C32(0x95bd0000), + SPH_C32(0xb5741f74), SPH_C32(0x7e553423), SPH_C32(0x61f4ca87), + SPH_C32(0xf7f18bce) } +}; + +static const sph_u32 T512_30[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xdb250000), SPH_C32(0x09290000), SPH_C32(0x49aac000), + SPH_C32(0x81e10000), SPH_C32(0xcafe6b59), SPH_C32(0x42793431), + SPH_C32(0x43566b76), SPH_C32(0xe86cba2e), SPH_C32(0x75e60000), + SPH_C32(0x95660001), SPH_C32(0x307b2000), SPH_C32(0xadf40000), + SPH_C32(0x8f321eea), SPH_C32(0x24298307), SPH_C32(0xe8c49cf9), + SPH_C32(0x4b7eec55) }, + { SPH_C32(0x86790000), SPH_C32(0x3f390002), SPH_C32(0xe19ae000), + SPH_C32(0x98560000), SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), + SPH_C32(0xd3dd4944), SPH_C32(0x161ddab9), SPH_C32(0x30b70000), + SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), SPH_C32(0x42c40000), + SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), SPH_C32(0x21afa1ea), + SPH_C32(0xb0a51834) }, + { SPH_C32(0x5d5c0000), SPH_C32(0x36100002), SPH_C32(0xa8302000), + SPH_C32(0x19b70000), SPH_C32(0x5f9b0c57), SPH_C32(0x0cf1fcdb), + SPH_C32(0x908b2232), SPH_C32(0xfe716097), SPH_C32(0x45510000), + SPH_C32(0x70b60001), SPH_C32(0xc48f4000), SPH_C32(0xef300000), + SPH_C32(0xec8a2380), SPH_C32(0x5c931767), SPH_C32(0xc96b3d13), + SPH_C32(0xfbdbf461) }, + { SPH_C32(0x30b70000), SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), + SPH_C32(0x42c40000), SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), + SPH_C32(0x21afa1ea), SPH_C32(0xb0a51834), SPH_C32(0xb6ce0000), + SPH_C32(0xdae90002), SPH_C32(0x156e8000), SPH_C32(0xda920000), + SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), SPH_C32(0xf272e8ae), + SPH_C32(0xa6b8c28d) }, + { SPH_C32(0xeb920000), SPH_C32(0xecf90000), SPH_C32(0xbd5ea000), + SPH_C32(0xc3250000), SPH_C32(0xa9465633), SPH_C32(0x3ac3a051), + SPH_C32(0x62f9ca9c), SPH_C32(0x58c9a21a), SPH_C32(0xc3280000), + SPH_C32(0x4f8f0003), SPH_C32(0x2515a000), SPH_C32(0x77660000), + SPH_C32(0x79ef448e), SPH_C32(0x121bdf8d), SPH_C32(0x1ab67457), + SPH_C32(0xedc62ed8) }, + { SPH_C32(0xb6ce0000), SPH_C32(0xdae90002), SPH_C32(0x156e8000), + SPH_C32(0xda920000), SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), + SPH_C32(0xf272e8ae), SPH_C32(0xa6b8c28d), SPH_C32(0x86790000), + SPH_C32(0x3f390002), SPH_C32(0xe19ae000), SPH_C32(0x98560000), + SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), SPH_C32(0xd3dd4944), + SPH_C32(0x161ddab9) }, + { SPH_C32(0x6deb0000), SPH_C32(0xd3c00002), SPH_C32(0x5cc44000), + SPH_C32(0x5b730000), SPH_C32(0x3c23313d), SPH_C32(0x744b68bb), + SPH_C32(0xb12483d8), SPH_C32(0x4ed478a3), SPH_C32(0xf39f0000), + SPH_C32(0xaa5f0003), SPH_C32(0xd1e1c000), SPH_C32(0x35a20000), + SPH_C32(0x1a5779e4), SPH_C32(0x6aa14bed), SPH_C32(0x3b19d5bd), + SPH_C32(0x5d6336ec) } +}; + +static const sph_u32 T512_33[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xac480000), SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), + SPH_C32(0x03430000), SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), + SPH_C32(0xfe72c7fe), SPH_C32(0x91e478f6), SPH_C32(0x1e4e0000), + SPH_C32(0xdecf0000), SPH_C32(0x6df80180), SPH_C32(0x77240000), + SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), SPH_C32(0xcda31812), + SPH_C32(0x98aa496e) }, + { SPH_C32(0x1e4e0000), SPH_C32(0xdecf0000), SPH_C32(0x6df80180), + SPH_C32(0x77240000), SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), + SPH_C32(0xcda31812), SPH_C32(0x98aa496e), SPH_C32(0xb2060000), + SPH_C32(0xc5690000), SPH_C32(0x28031200), SPH_C32(0x74670000), + SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), SPH_C32(0x33d1dfec), + SPH_C32(0x094e3198) }, + { SPH_C32(0xb2060000), SPH_C32(0xc5690000), SPH_C32(0x28031200), + SPH_C32(0x74670000), SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), + SPH_C32(0x33d1dfec), SPH_C32(0x094e3198), SPH_C32(0xac480000), + SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), SPH_C32(0x03430000), + SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), SPH_C32(0xfe72c7fe), + SPH_C32(0x91e478f6) }, + { SPH_C32(0xaec30000), SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), + SPH_C32(0x2c150000), SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), + SPH_C32(0xab92f78f), SPH_C32(0xa312567b), SPH_C32(0xdb250000), + SPH_C32(0x09290000), SPH_C32(0x49aac000), SPH_C32(0x81e10000), + SPH_C32(0xcafe6b59), SPH_C32(0x42793431), SPH_C32(0x43566b76), + SPH_C32(0xe86cba2e) }, + { SPH_C32(0x028b0000), SPH_C32(0x87e90001), SPH_C32(0x3c2af380), + SPH_C32(0x2f560000), SPH_C32(0x1f4944d9), SPH_C32(0x79e2e780), + SPH_C32(0x55e03071), SPH_C32(0x32f62e8d), SPH_C32(0xc56b0000), + SPH_C32(0xd7e60000), SPH_C32(0x2452c180), SPH_C32(0xf6c50000), + SPH_C32(0x26b96cc7), SPH_C32(0xb6d95d7f), SPH_C32(0x8ef57364), + SPH_C32(0x70c6f340) }, + { SPH_C32(0xb08d0000), SPH_C32(0x42800001), SPH_C32(0x1429e180), + SPH_C32(0x5b310000), SPH_C32(0xa98b722d), SPH_C32(0x92f0de78), + SPH_C32(0x6631ef9d), SPH_C32(0x3bb81f15), SPH_C32(0x69230000), + SPH_C32(0xcc400000), SPH_C32(0x61a9d200), SPH_C32(0xf5860000), + SPH_C32(0x7c3c5dad), SPH_C32(0xa96b0dc9), SPH_C32(0x7087b49a), + SPH_C32(0xe1228bb6) }, + { SPH_C32(0x1cc50000), SPH_C32(0x59260001), SPH_C32(0x51d2f200), + SPH_C32(0x58720000), SPH_C32(0xf30e4347), SPH_C32(0x8d428ece), + SPH_C32(0x98432863), SPH_C32(0xaa5c67e3), SPH_C32(0x776d0000), + SPH_C32(0x128f0000), SPH_C32(0x0c51d380), SPH_C32(0x82a20000), + SPH_C32(0x907b5a33), SPH_C32(0x5dcb6487), SPH_C32(0xbd24ac88), + SPH_C32(0x7988c2d8) } +}; + +static const sph_u32 T512_36[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x819e0000), SPH_C32(0xec570000), SPH_C32(0x66320280), + SPH_C32(0x95f30000), SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), + SPH_C32(0xe65aa22d), SPH_C32(0x8e67b7fa), SPH_C32(0x4d8a0000), + SPH_C32(0x49340000), SPH_C32(0x3c8b0500), SPH_C32(0xaea30000), + SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), SPH_C32(0x8f19eaec), + SPH_C32(0x443d3004) }, + { SPH_C32(0x78230000), SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), + SPH_C32(0x90a50000), SPH_C32(0x713e2879), SPH_C32(0x7ee98924), + SPH_C32(0xf08ca062), SPH_C32(0x636f8bab), SPH_C32(0x02af0000), + SPH_C32(0xb7280000), SPH_C32(0xba1c0300), SPH_C32(0x56980000), + SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), SPH_C32(0xa95c149a), + SPH_C32(0xf4f6ea7b) }, + { SPH_C32(0xf9bd0000), SPH_C32(0xfeab0000), SPH_C32(0xcf080900), + SPH_C32(0x05560000), SPH_C32(0x2c97007b), SPH_C32(0x361db598), + SPH_C32(0x16d6024f), SPH_C32(0xed083c51), SPH_C32(0x4f250000), + SPH_C32(0xfe1c0000), SPH_C32(0x86970600), SPH_C32(0xf83b0000), + SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), SPH_C32(0x2645fe76), + SPH_C32(0xb0cbda7f) }, + { SPH_C32(0x02af0000), SPH_C32(0xb7280000), SPH_C32(0xba1c0300), + SPH_C32(0x56980000), SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), + SPH_C32(0xa95c149a), SPH_C32(0xf4f6ea7b), SPH_C32(0x7a8c0000), + SPH_C32(0xa5d40000), SPH_C32(0x13260880), SPH_C32(0xc63d0000), + SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), SPH_C32(0x59d0b4f8), + SPH_C32(0x979961d0) }, + { SPH_C32(0x83310000), SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), + SPH_C32(0xc36b0000), SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), + SPH_C32(0x4f06b6b7), SPH_C32(0x7a915d81), SPH_C32(0x37060000), + SPH_C32(0xece00000), SPH_C32(0x2fad0d80), SPH_C32(0x689e0000), + SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), SPH_C32(0xd6c95e14), + SPH_C32(0xd3a451d4) }, + { SPH_C32(0x7a8c0000), SPH_C32(0xa5d40000), SPH_C32(0x13260880), + SPH_C32(0xc63d0000), SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), + SPH_C32(0x59d0b4f8), SPH_C32(0x979961d0), SPH_C32(0x78230000), + SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), SPH_C32(0x90a50000), + SPH_C32(0x713e2879), SPH_C32(0x7ee98924), SPH_C32(0xf08ca062), + SPH_C32(0x636f8bab) }, + { SPH_C32(0xfb120000), SPH_C32(0x49830000), SPH_C32(0x75140a00), + SPH_C32(0x53ce0000), SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), + SPH_C32(0xbf8a16d5), SPH_C32(0x19fed62a), SPH_C32(0x35a90000), + SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), SPH_C32(0x3e060000), + SPH_C32(0x67471384), SPH_C32(0xb1868180), SPH_C32(0x7f954a8e), + SPH_C32(0x2752bbaf) } +}; + +static const sph_u32 T512_39[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x52500000), SPH_C32(0x29540000), SPH_C32(0x6a61004e), + SPH_C32(0xf0ff0000), SPH_C32(0x9a317eec), SPH_C32(0x452341ce), + SPH_C32(0xcf568fe5), SPH_C32(0x5303130f), SPH_C32(0x538d0000), + SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), SPH_C32(0x56ff0000), + SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), SPH_C32(0xa9444018), + SPH_C32(0x7f975691) }, + { SPH_C32(0x538d0000), SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), + SPH_C32(0x56ff0000), SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), + SPH_C32(0xa9444018), SPH_C32(0x7f975691), SPH_C32(0x01dd0000), + SPH_C32(0x80a80000), SPH_C32(0xf4960048), SPH_C32(0xa6000000), + SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), SPH_C32(0x6612cffd), + SPH_C32(0x2c94459e) }, + { SPH_C32(0x01dd0000), SPH_C32(0x80a80000), SPH_C32(0xf4960048), + SPH_C32(0xa6000000), SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), + SPH_C32(0x6612cffd), SPH_C32(0x2c94459e), SPH_C32(0x52500000), + SPH_C32(0x29540000), SPH_C32(0x6a61004e), SPH_C32(0xf0ff0000), + SPH_C32(0x9a317eec), SPH_C32(0x452341ce), SPH_C32(0xcf568fe5), + SPH_C32(0x5303130f) }, + { SPH_C32(0xcc140000), SPH_C32(0xa5630000), SPH_C32(0x5ab90780), + SPH_C32(0x3b500000), SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), + SPH_C32(0x694348c1), SPH_C32(0xca5a87fe), SPH_C32(0x819e0000), + SPH_C32(0xec570000), SPH_C32(0x66320280), SPH_C32(0x95f30000), + SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), SPH_C32(0xe65aa22d), + SPH_C32(0x8e67b7fa) }, + { SPH_C32(0x9e440000), SPH_C32(0x8c370000), SPH_C32(0x30d807ce), + SPH_C32(0xcbaf0000), SPH_C32(0xd1e16d13), SPH_C32(0xc2b875d6), + SPH_C32(0xa615c724), SPH_C32(0x995994f1), SPH_C32(0xd2130000), + SPH_C32(0x45ab0000), SPH_C32(0xf8c50286), SPH_C32(0xc30c0000), + SPH_C32(0x574d284c), SPH_C32(0xda31f145), SPH_C32(0x4f1ee235), + SPH_C32(0xf1f0e16b) }, + { SPH_C32(0x9f990000), SPH_C32(0x0c9f0000), SPH_C32(0xc44e0786), + SPH_C32(0x6daf0000), SPH_C32(0x413413b1), SPH_C32(0x155ef9e1), + SPH_C32(0xc00708d9), SPH_C32(0xb5cdd16f), SPH_C32(0x80430000), + SPH_C32(0x6cff0000), SPH_C32(0x92a402c8), SPH_C32(0x33f30000), + SPH_C32(0xcd7c56a0), SPH_C32(0x9f12b08b), SPH_C32(0x80486dd0), + SPH_C32(0xa2f3f264) }, + { SPH_C32(0xcdc90000), SPH_C32(0x25cb0000), SPH_C32(0xae2f07c8), + SPH_C32(0x9d500000), SPH_C32(0xdb056d5d), SPH_C32(0x507db82f), + SPH_C32(0x0f51873c), SPH_C32(0xe6cec260), SPH_C32(0xd3ce0000), + SPH_C32(0xc5030000), SPH_C32(0x0c5302ce), SPH_C32(0x650c0000), + SPH_C32(0xc79856ee), SPH_C32(0x0dd77d72), SPH_C32(0x290c2dc8), + SPH_C32(0xdd64a4f5) } +}; + +static const sph_u32 T512_42[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x07ed0000), SPH_C32(0xb2500000), SPH_C32(0x8774000a), + SPH_C32(0x970d0000), SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), + SPH_C32(0xf4786222), SPH_C32(0x9075b1ce), SPH_C32(0xa2d60000), + SPH_C32(0xa6760000), SPH_C32(0xc9440014), SPH_C32(0xeba30000), + SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), SPH_C32(0x03490afa), + SPH_C32(0x9b6ef888) }, + { SPH_C32(0x88980000), SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), + SPH_C32(0xfb4e0000), SPH_C32(0xf158079a), SPH_C32(0x61ae9167), + SPH_C32(0xa895706c), SPH_C32(0xe6107494), SPH_C32(0x0bc20000), + SPH_C32(0xdb630000), SPH_C32(0x7e88000c), SPH_C32(0x15860000), + SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), SPH_C32(0xf460449e), + SPH_C32(0xd8b61463) }, + { SPH_C32(0x8f750000), SPH_C32(0xadc40000), SPH_C32(0xf8bb0024), + SPH_C32(0x6c430000), SPH_C32(0xb22a2434), SPH_C32(0x2969ffc3), + SPH_C32(0x5ced124e), SPH_C32(0x7665c55a), SPH_C32(0xa9140000), + SPH_C32(0x7d150000), SPH_C32(0xb7cc0018), SPH_C32(0xfe250000), + SPH_C32(0x5d116688), SPH_C32(0x45997fda), SPH_C32(0xf7294e64), + SPH_C32(0x43d8eceb) }, + { SPH_C32(0x0bc20000), SPH_C32(0xdb630000), SPH_C32(0x7e88000c), + SPH_C32(0x15860000), SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), + SPH_C32(0xf460449e), SPH_C32(0xd8b61463), SPH_C32(0x835a0000), + SPH_C32(0xc4f70000), SPH_C32(0x01470022), SPH_C32(0xeec80000), + SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), SPH_C32(0x5cf534f2), + SPH_C32(0x3ea660f7) }, + { SPH_C32(0x0c2f0000), SPH_C32(0x69330000), SPH_C32(0xf9fc0006), + SPH_C32(0x828b0000), SPH_C32(0xd28f6b5d), SPH_C32(0x3d46d5e7), + SPH_C32(0x001826bc), SPH_C32(0x48c3a5ad), SPH_C32(0x218c0000), + SPH_C32(0x62810000), SPH_C32(0xc8030036), SPH_C32(0x056b0000), + SPH_C32(0xac496112), SPH_C32(0x2437eebd), SPH_C32(0x5fbc3e08), + SPH_C32(0xa5c8987f) }, + { SPH_C32(0x835a0000), SPH_C32(0xc4f70000), SPH_C32(0x01470022), + SPH_C32(0xeec80000), SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), + SPH_C32(0x5cf534f2), SPH_C32(0x3ea660f7), SPH_C32(0x88980000), + SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), SPH_C32(0xfb4e0000), + SPH_C32(0xf158079a), SPH_C32(0x61ae9167), SPH_C32(0xa895706c), + SPH_C32(0xe6107494) }, + { SPH_C32(0x84b70000), SPH_C32(0x76a70000), SPH_C32(0x86330028), + SPH_C32(0x79c50000), SPH_C32(0x23d76cc7), SPH_C32(0x5ce84480), + SPH_C32(0xa88d56d0), SPH_C32(0xaed3d139), SPH_C32(0x2a4e0000), + SPH_C32(0xb9e20000), SPH_C32(0xb68b003a), SPH_C32(0x10ed0000), + SPH_C32(0x3db429e1), SPH_C32(0x51b655fe), SPH_C32(0xabdc7a96), + SPH_C32(0x7d7e8c1c) } +}; + +static const sph_u32 T512_45[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x58430000), SPH_C32(0x807e0000), SPH_C32(0x78330001), + SPH_C32(0xc66b3800), SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), + SPH_C32(0xac73fe6f), SPH_C32(0x3a4479b1), SPH_C32(0x1d5a0000), + SPH_C32(0x2b720000), SPH_C32(0x488d0000), SPH_C32(0xaf611800), + SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), SPH_C32(0x81a20429), + SPH_C32(0x1e7536a6) }, + { SPH_C32(0x1d5a0000), SPH_C32(0x2b720000), SPH_C32(0x488d0000), + SPH_C32(0xaf611800), SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), + SPH_C32(0x81a20429), SPH_C32(0x1e7536a6), SPH_C32(0x45190000), + SPH_C32(0xab0c0000), SPH_C32(0x30be0001), SPH_C32(0x690a2000), + SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), SPH_C32(0x2dd1fa46), + SPH_C32(0x24314f17) }, + { SPH_C32(0x45190000), SPH_C32(0xab0c0000), SPH_C32(0x30be0001), + SPH_C32(0x690a2000), SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), + SPH_C32(0x2dd1fa46), SPH_C32(0x24314f17), SPH_C32(0x58430000), + SPH_C32(0x807e0000), SPH_C32(0x78330001), SPH_C32(0xc66b3800), + SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), SPH_C32(0xac73fe6f), + SPH_C32(0x3a4479b1) }, + { SPH_C32(0xa53b0000), SPH_C32(0x14260000), SPH_C32(0x4e30001e), + SPH_C32(0x7cae0000), SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), + SPH_C32(0xf73168d8), SPH_C32(0x0b1b4946), SPH_C32(0x07ed0000), + SPH_C32(0xb2500000), SPH_C32(0x8774000a), SPH_C32(0x970d0000), + SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), SPH_C32(0xf4786222), + SPH_C32(0x9075b1ce) }, + { SPH_C32(0xfd780000), SPH_C32(0x94580000), SPH_C32(0x3603001f), + SPH_C32(0xbac53800), SPH_C32(0x68a95109), SPH_C32(0x017295e0), + SPH_C32(0x5b4296b7), SPH_C32(0x315f30f7), SPH_C32(0x1ab70000), + SPH_C32(0x99220000), SPH_C32(0xcff9000a), SPH_C32(0x386c1800), + SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), SPH_C32(0x75da660b), + SPH_C32(0x8e008768) }, + { SPH_C32(0xb8610000), SPH_C32(0x3f540000), SPH_C32(0x06bd001e), + SPH_C32(0xd3cf1800), SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), + SPH_C32(0x76936cf1), SPH_C32(0x156e7fe0), SPH_C32(0x42f40000), + SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), SPH_C32(0xfe072000), + SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), SPH_C32(0xd9a99864), + SPH_C32(0xb444fed9) }, + { SPH_C32(0xe0220000), SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), + SPH_C32(0x15a42000), SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), + SPH_C32(0xdae0929e), SPH_C32(0x2f2a0651), SPH_C32(0x5fae0000), + SPH_C32(0x322e0000), SPH_C32(0xff47000b), SPH_C32(0x51663800), + SPH_C32(0xa4457f72), SPH_C32(0x316a5179), SPH_C32(0x580b9c4d), + SPH_C32(0xaa31c87f) } +}; + +static const sph_u32 T512_48[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xbadd0000), SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), + SPH_C32(0xf7282800), SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), + SPH_C32(0xea5a8d14), SPH_C32(0x2a2c18f0), SPH_C32(0xb82f0000), + SPH_C32(0xb12c0000), SPH_C32(0x30d80000), SPH_C32(0x14445000), + SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), SPH_C32(0x2e98bf23), + SPH_C32(0x551e3d6e) }, + { SPH_C32(0x1e6c0000), SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), + SPH_C32(0xbcb6b800), SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), + SPH_C32(0x6a0c1bc8), SPH_C32(0xb99dc2eb), SPH_C32(0x92560000), + SPH_C32(0x1eda0000), SPH_C32(0xea510000), SPH_C32(0xe8b13000), + SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), SPH_C32(0xb15c2254), + SPH_C32(0x33c5244f) }, + { SPH_C32(0xa4b10000), SPH_C32(0xd7ef0000), SPH_C32(0x3dc90000), + SPH_C32(0x4b9e9000), SPH_C32(0xf30107fb), SPH_C32(0xbde710e0), + SPH_C32(0x805696dc), SPH_C32(0x93b1da1b), SPH_C32(0x2a790000), + SPH_C32(0xaff60000), SPH_C32(0xda890000), SPH_C32(0xfcf56000), + SPH_C32(0x686d3607), SPH_C32(0xdadc8975), SPH_C32(0x9fc49d77), + SPH_C32(0x66db1921) }, + { SPH_C32(0x92560000), SPH_C32(0x1eda0000), SPH_C32(0xea510000), + SPH_C32(0xe8b13000), SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), + SPH_C32(0xb15c2254), SPH_C32(0x33c5244f), SPH_C32(0x8c3a0000), + SPH_C32(0xda980000), SPH_C32(0x607f0000), SPH_C32(0x54078800), + SPH_C32(0x85714513), SPH_C32(0x6006b243), SPH_C32(0xdb50399c), + SPH_C32(0x8a58e6a4) }, + { SPH_C32(0x288b0000), SPH_C32(0x0d770000), SPH_C32(0x5db60000), + SPH_C32(0x1f991800), SPH_C32(0x767042e8), SPH_C32(0xdde1a2a3), + SPH_C32(0x5b06af40), SPH_C32(0x19e93cbf), SPH_C32(0x34150000), + SPH_C32(0x6bb40000), SPH_C32(0x50a70000), SPH_C32(0x4043d800), + SPH_C32(0x442925b1), SPH_C32(0x51215aaf), SPH_C32(0xf5c886bf), + SPH_C32(0xdf46dbca) }, + { SPH_C32(0x8c3a0000), SPH_C32(0xda980000), SPH_C32(0x607f0000), + SPH_C32(0x54078800), SPH_C32(0x85714513), SPH_C32(0x6006b243), + SPH_C32(0xdb50399c), SPH_C32(0x8a58e6a4), SPH_C32(0x1e6c0000), + SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), SPH_C32(0xbcb6b800), + SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), SPH_C32(0x6a0c1bc8), + SPH_C32(0xb99dc2eb) }, + { SPH_C32(0x36e70000), SPH_C32(0xc9350000), SPH_C32(0xd7980000), + SPH_C32(0xa32fa000), SPH_C32(0x5a34515e), SPH_C32(0x561c7179), + SPH_C32(0x310ab488), SPH_C32(0xa074fe54), SPH_C32(0xa6430000), + SPH_C32(0x756e0000), SPH_C32(0xbaf60000), SPH_C32(0xa8f2e800), + SPH_C32(0xed1c7314), SPH_C32(0xbada3b36), SPH_C32(0x4494a4eb), + SPH_C32(0xec83ff85) } +}; + +static const sph_u32 T512_51[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xb4310000), SPH_C32(0x77330000), SPH_C32(0xb15d0000), + SPH_C32(0x7fd004e0), SPH_C32(0x78a26138), SPH_C32(0xd116c35d), + SPH_C32(0xd256d489), SPH_C32(0x4e6f74de), SPH_C32(0xe3060000), + SPH_C32(0xbdc10000), SPH_C32(0x87130000), SPH_C32(0xbff20060), + SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), SPH_C32(0x73c5ab06), + SPH_C32(0x5bd61539) }, + { SPH_C32(0xe3060000), SPH_C32(0xbdc10000), SPH_C32(0x87130000), + SPH_C32(0xbff20060), SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), + SPH_C32(0x73c5ab06), SPH_C32(0x5bd61539), SPH_C32(0x57370000), + SPH_C32(0xcaf20000), SPH_C32(0x364e0000), SPH_C32(0xc0220480), + SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), SPH_C32(0xa1937f8f), + SPH_C32(0x15b961e7) }, + { SPH_C32(0x57370000), SPH_C32(0xcaf20000), SPH_C32(0x364e0000), + SPH_C32(0xc0220480), SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), + SPH_C32(0xa1937f8f), SPH_C32(0x15b961e7), SPH_C32(0xb4310000), + SPH_C32(0x77330000), SPH_C32(0xb15d0000), SPH_C32(0x7fd004e0), + SPH_C32(0x78a26138), SPH_C32(0xd116c35d), SPH_C32(0xd256d489), + SPH_C32(0x4e6f74de) }, + { SPH_C32(0x02f20000), SPH_C32(0xa2810000), SPH_C32(0x873f0000), + SPH_C32(0xe36c7800), SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), + SPH_C32(0xc4c23237), SPH_C32(0x7f32259e), SPH_C32(0xbadd0000), + SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), SPH_C32(0xf7282800), + SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), SPH_C32(0xea5a8d14), + SPH_C32(0x2a2c18f0) }, + { SPH_C32(0xb6c30000), SPH_C32(0xd5b20000), SPH_C32(0x36620000), + SPH_C32(0x9cbc7ce0), SPH_C32(0x66bf15d7), SPH_C32(0xd62be88b), + SPH_C32(0x1694e6be), SPH_C32(0x315d5140), SPH_C32(0x59db0000), + SPH_C32(0xae6c0000), SPH_C32(0x30f40000), SPH_C32(0x48da2860), + SPH_C32(0xf1ff1e57), SPH_C32(0xbbaff46b), SPH_C32(0x999f2612), + SPH_C32(0x71fa0dc9) }, + { SPH_C32(0xe1f40000), SPH_C32(0x1f400000), SPH_C32(0x002c0000), + SPH_C32(0x5c9e7860), SPH_C32(0x30a77ef5), SPH_C32(0x8a881c87), + SPH_C32(0xb7079931), SPH_C32(0x24e430a7), SPH_C32(0xedea0000), + SPH_C32(0xd95f0000), SPH_C32(0x81a90000), SPH_C32(0x370a2c80), + SPH_C32(0x895d7f6f), SPH_C32(0x6ab93736), SPH_C32(0x4bc9f29b), + SPH_C32(0x3f957917) }, + { SPH_C32(0x55c50000), SPH_C32(0x68730000), SPH_C32(0xb1710000), + SPH_C32(0x234e7c80), SPH_C32(0x48051fcd), SPH_C32(0x5b9edfda), + SPH_C32(0x65514db8), SPH_C32(0x6a8b4479), SPH_C32(0x0eec0000), + SPH_C32(0x649e0000), SPH_C32(0x06ba0000), SPH_C32(0x88f82ce0), + SPH_C32(0xa7e77575), SPH_C32(0xe70c0067), SPH_C32(0x380c599d), + SPH_C32(0x64436c2e) } +}; + +static const sph_u32 T512_54[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x7b280000), SPH_C32(0x57420000), SPH_C32(0xa9e50000), + SPH_C32(0x634300a0), SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), + SPH_C32(0x27f83b03), SPH_C32(0xc7ff60f0), SPH_C32(0x95bb0000), + SPH_C32(0x81450000), SPH_C32(0x3b240000), SPH_C32(0x48db0140), + SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), SPH_C32(0x62c91877), + SPH_C32(0xe7e00a94) }, + { SPH_C32(0xe6280000), SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), + SPH_C32(0xd3d002e0), SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), + SPH_C32(0x289506b4), SPH_C32(0xd75a4897), SPH_C32(0xf0c50000), + SPH_C32(0x59230000), SPH_C32(0x45820000), SPH_C32(0xe18d00c0), + SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), SPH_C32(0xcbe0fe1c), + SPH_C32(0x56a7b19f) }, + { SPH_C32(0x9d000000), SPH_C32(0x1b090000), SPH_C32(0x01b00000), + SPH_C32(0xb0930240), SPH_C32(0x46ba7497), SPH_C32(0xf53e2561), + SPH_C32(0x0f6d3db7), SPH_C32(0x10a52867), SPH_C32(0x657e0000), + SPH_C32(0xd8660000), SPH_C32(0x7ea60000), SPH_C32(0xa9560180), + SPH_C32(0x31e76a62), SPH_C32(0x94183875), SPH_C32(0xa929e66b), + SPH_C32(0xb147bb0b) }, + { SPH_C32(0xf0c50000), SPH_C32(0x59230000), SPH_C32(0x45820000), + SPH_C32(0xe18d00c0), SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), + SPH_C32(0xcbe0fe1c), SPH_C32(0x56a7b19f), SPH_C32(0x16ed0000), + SPH_C32(0x15680000), SPH_C32(0xedd70000), SPH_C32(0x325d0220), + SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), SPH_C32(0xe375f8a8), + SPH_C32(0x81fdf908) }, + { SPH_C32(0x8bed0000), SPH_C32(0x0e610000), SPH_C32(0xec670000), + SPH_C32(0x82ce0060), SPH_C32(0xa5b6421e), SPH_C32(0xaf74c322), + SPH_C32(0xec18c51f), SPH_C32(0x9158d16f), SPH_C32(0x83560000), + SPH_C32(0x942d0000), SPH_C32(0xd6f30000), SPH_C32(0x7a860360), + SPH_C32(0xe9865ada), SPH_C32(0x0cbf88af), SPH_C32(0x81bce0df), + SPH_C32(0x661df39c) }, + { SPH_C32(0x16ed0000), SPH_C32(0x15680000), SPH_C32(0xedd70000), + SPH_C32(0x325d0220), SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), + SPH_C32(0xe375f8a8), SPH_C32(0x81fdf908), SPH_C32(0xe6280000), + SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), SPH_C32(0xd3d002e0), + SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), SPH_C32(0x289506b4), + SPH_C32(0xd75a4897) }, + { SPH_C32(0x6dc50000), SPH_C32(0x422a0000), SPH_C32(0x44320000), + SPH_C32(0x511e0280), SPH_C32(0x7dd772a6), SPH_C32(0x37d373f8), + SPH_C32(0xc48dc3ab), SPH_C32(0x460299f8), SPH_C32(0x73930000), + SPH_C32(0xcd0e0000), SPH_C32(0x93710000), SPH_C32(0x9b0b03a0), + SPH_C32(0xd2eb5ceb), SPH_C32(0xce52de36), SPH_C32(0x4a5c1ec3), + SPH_C32(0x30ba4203) } +}; + +static const sph_u32 T512_57[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x5fa80000), SPH_C32(0x56030000), SPH_C32(0x43ae0000), + SPH_C32(0x64f30013), SPH_C32(0x257e86bf), SPH_C32(0x1311944e), + SPH_C32(0x541e95bf), SPH_C32(0x8ea4db69), SPH_C32(0x00440000), + SPH_C32(0x7f480000), SPH_C32(0xda7c0000), SPH_C32(0x2a230001), + SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), SPH_C32(0x030a9e60), + SPH_C32(0xbe0a679e) }, + { SPH_C32(0x00440000), SPH_C32(0x7f480000), SPH_C32(0xda7c0000), + SPH_C32(0x2a230001), SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), + SPH_C32(0x030a9e60), SPH_C32(0xbe0a679e), SPH_C32(0x5fec0000), + SPH_C32(0x294b0000), SPH_C32(0x99d20000), SPH_C32(0x4ed00012), + SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), SPH_C32(0x57140bdf), + SPH_C32(0x30aebcf7) }, + { SPH_C32(0x5fec0000), SPH_C32(0x294b0000), SPH_C32(0x99d20000), + SPH_C32(0x4ed00012), SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), + SPH_C32(0x57140bdf), SPH_C32(0x30aebcf7), SPH_C32(0x5fa80000), + SPH_C32(0x56030000), SPH_C32(0x43ae0000), SPH_C32(0x64f30013), + SPH_C32(0x257e86bf), SPH_C32(0x1311944e), SPH_C32(0x541e95bf), + SPH_C32(0x8ea4db69) }, + { SPH_C32(0xee930000), SPH_C32(0xd6070000), SPH_C32(0x92c10000), + SPH_C32(0x2b9801e0), SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), + SPH_C32(0x45312374), SPH_C32(0x201f6a64), SPH_C32(0x7b280000), + SPH_C32(0x57420000), SPH_C32(0xa9e50000), SPH_C32(0x634300a0), + SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), SPH_C32(0x27f83b03), + SPH_C32(0xc7ff60f0) }, + { SPH_C32(0xb13b0000), SPH_C32(0x80040000), SPH_C32(0xd16f0000), + SPH_C32(0x4f6b01f3), SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), + SPH_C32(0x112fb6cb), SPH_C32(0xaebbb10d), SPH_C32(0x7b6c0000), + SPH_C32(0x280a0000), SPH_C32(0x73990000), SPH_C32(0x496000a1), + SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), SPH_C32(0x24f2a563), + SPH_C32(0x79f5076e) }, + { SPH_C32(0xeed70000), SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), + SPH_C32(0x01bb01e1), SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), + SPH_C32(0x463bbd14), SPH_C32(0x9e150dfa), SPH_C32(0x24c40000), + SPH_C32(0x7e090000), SPH_C32(0x30370000), SPH_C32(0x2d9300b2), + SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), SPH_C32(0x70ec30dc), + SPH_C32(0xf751dc07) }, + { SPH_C32(0xb17f0000), SPH_C32(0xff4c0000), SPH_C32(0x0b130000), + SPH_C32(0x654801f2), SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), + SPH_C32(0x122528ab), SPH_C32(0x10b1d693), SPH_C32(0x24800000), + SPH_C32(0x01410000), SPH_C32(0xea4b0000), SPH_C32(0x07b000b3), + SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), SPH_C32(0x73e6aebc), + SPH_C32(0x495bbb99) } +}; + +static const sph_u32 T512_60[8][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xa8da0000), SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), + SPH_C32(0x07da0002), SPH_C32(0x7d669583), SPH_C32(0x1f98708a), + SPH_C32(0xbb668808), SPH_C32(0xda878000), SPH_C32(0xabe70000), + SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), SPH_C32(0x3d180005), + SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), SPH_C32(0xb5c347eb), + SPH_C32(0x3c5dfffe) }, + { SPH_C32(0x01930000), SPH_C32(0xe7820000), SPH_C32(0xedfb0000), + SPH_C32(0xcf0c000b), SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), + SPH_C32(0x063661e1), SPH_C32(0x536f9e7b), SPH_C32(0x92280000), + SPH_C32(0xdc850000), SPH_C32(0x57fa0000), SPH_C32(0x56dc0003), + SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), SPH_C32(0x90cef752), + SPH_C32(0x7b1675d7) }, + { SPH_C32(0xa9490000), SPH_C32(0x713c0000), SPH_C32(0xb1e60000), + SPH_C32(0xc8d60009), SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), + SPH_C32(0xbd50e9e9), SPH_C32(0x89e81e7b), SPH_C32(0x39cf0000), + SPH_C32(0x42880000), SPH_C32(0xf8dd0000), SPH_C32(0x6bc40006), + SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), SPH_C32(0x250db0b9), + SPH_C32(0x474b8a29) }, + { SPH_C32(0x92280000), SPH_C32(0xdc850000), SPH_C32(0x57fa0000), + SPH_C32(0x56dc0003), SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), + SPH_C32(0x90cef752), SPH_C32(0x7b1675d7), SPH_C32(0x93bb0000), + SPH_C32(0x3b070000), SPH_C32(0xba010000), SPH_C32(0x99d00008), + SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), SPH_C32(0x96f896b3), + SPH_C32(0x2879ebac) }, + { SPH_C32(0x3af20000), SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), + SPH_C32(0x51060001), SPH_C32(0xc78fb695), SPH_C32(0x4577d386), + SPH_C32(0x2ba87f5a), SPH_C32(0xa191f5d7), SPH_C32(0x385c0000), + SPH_C32(0xa50a0000), SPH_C32(0x15260000), SPH_C32(0xa4c8000d), + SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), SPH_C32(0x233bd158), + SPH_C32(0x14241452) }, + { SPH_C32(0x93bb0000), SPH_C32(0x3b070000), SPH_C32(0xba010000), + SPH_C32(0x99d00008), SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), + SPH_C32(0x96f896b3), SPH_C32(0x2879ebac), SPH_C32(0x01930000), + SPH_C32(0xe7820000), SPH_C32(0xedfb0000), SPH_C32(0xcf0c000b), + SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), SPH_C32(0x063661e1), + SPH_C32(0x536f9e7b) }, + { SPH_C32(0x3b610000), SPH_C32(0xadb90000), SPH_C32(0xe61c0000), + SPH_C32(0x9e0a000a), SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), + SPH_C32(0x2d9e1ebb), SPH_C32(0xf2fe6bac), SPH_C32(0xaa740000), + SPH_C32(0x798f0000), SPH_C32(0x42dc0000), SPH_C32(0xf214000e), + SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), SPH_C32(0xb3f5260a), + SPH_C32(0x6f326185) } +}; + +static const sph_u32 T512_63[2][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x033d0000), SPH_C32(0x08b30000), SPH_C32(0xf33a0000), + SPH_C32(0x3ac20007), SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), + SPH_C32(0x0ea5cfe3), SPH_C32(0xe6da7ffe), SPH_C32(0xa8da0000), + SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), SPH_C32(0x07da0002), + SPH_C32(0x7d669583), SPH_C32(0x1f98708a), SPH_C32(0xbb668808), + SPH_C32(0xda878000) } +}; + +#define INPUT_BIG do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T512_0[acc >> 5][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + m8 = rp[8]; \ + m9 = rp[9]; \ + mA = rp[10]; \ + mB = rp[11]; \ + mC = rp[12]; \ + mD = rp[13]; \ + mE = rp[14]; \ + mF = rp[15]; \ + rp = &T512_3[(acc >> 2) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[1]; \ + rp = &T512_6[(acc >> 7) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_9[(acc >> 4) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_12[(acc >> 1) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[2]; \ + rp = &T512_15[(acc >> 6) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_18[(acc >> 3) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_21[acc & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[3]; \ + rp = &T512_24[acc >> 5][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_27[(acc >> 2) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[4]; \ + rp = &T512_30[(acc >> 7) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_33[(acc >> 4) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_36[(acc >> 1) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[5]; \ + rp = &T512_39[(acc >> 6) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_42[(acc >> 3) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_45[acc & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[6]; \ + rp = &T512_48[acc >> 5][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_51[(acc >> 2) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[7]; \ + rp = &T512_54[(acc >> 7) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_57[(acc >> 4) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_60[(acc >> 1) & 0x07][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_63[acc & 0x01][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_BIG == 4 + +static const sph_u32 T512_0[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x54285c00), SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), + SPH_C32(0xa1c50000), SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), + SPH_C32(0x6bb0419d), SPH_C32(0x551b3782), SPH_C32(0x9cbb1800), + SPH_C32(0xb0d30000), SPH_C32(0x92510000), SPH_C32(0xed930000), + SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), SPH_C32(0x430633da), + SPH_C32(0x78cace29) }, + { SPH_C32(0x9cbb1800), SPH_C32(0xb0d30000), SPH_C32(0x92510000), + SPH_C32(0xed930000), SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), + SPH_C32(0x430633da), SPH_C32(0x78cace29), SPH_C32(0xc8934400), + SPH_C32(0x5a3e0000), SPH_C32(0x57870000), SPH_C32(0x4c560000), + SPH_C32(0xea982435), SPH_C32(0x75b11115), SPH_C32(0x28b67247), + SPH_C32(0x2dd1f9ab) }, + { SPH_C32(0xc8934400), SPH_C32(0x5a3e0000), SPH_C32(0x57870000), + SPH_C32(0x4c560000), SPH_C32(0xea982435), SPH_C32(0x75b11115), + SPH_C32(0x28b67247), SPH_C32(0x2dd1f9ab), SPH_C32(0x54285c00), + SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), SPH_C32(0xa1c50000), + SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), SPH_C32(0x6bb0419d), + SPH_C32(0x551b3782) }, + { SPH_C32(0x29449c00), SPH_C32(0x64e70000), SPH_C32(0xf24b0000), + SPH_C32(0xc2f30000), SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), + SPH_C32(0xf3e04259), SPH_C32(0x8d0d9ec4), SPH_C32(0x466d0c00), + SPH_C32(0x08620000), SPH_C32(0xdd5d0000), SPH_C32(0xbadd0000), + SPH_C32(0x6a927942), SPH_C32(0x441f2b93), SPH_C32(0x218ace6f), + SPH_C32(0xbf2c0be2) }, + { SPH_C32(0x7d6cc000), SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), + SPH_C32(0x63360000), SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), + SPH_C32(0x985003c4), SPH_C32(0xd816a946), SPH_C32(0xdad61400), + SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), SPH_C32(0x574e0000), + SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), SPH_C32(0x628cfdb5), + SPH_C32(0xc7e6c5cb) }, + { SPH_C32(0xb5ff8400), SPH_C32(0xd4340000), SPH_C32(0x601a0000), + SPH_C32(0x2f600000), SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), + SPH_C32(0xb0e67183), SPH_C32(0xf5c750ed), SPH_C32(0x8efe4800), + SPH_C32(0x525c0000), SPH_C32(0x8ada0000), SPH_C32(0xf68b0000), + SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), SPH_C32(0x093cbc28), + SPH_C32(0x92fdf249) }, + { SPH_C32(0xe1d7d800), SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), + SPH_C32(0x8ea50000), SPH_C32(0xe4466aba), SPH_C32(0x23732650), + SPH_C32(0xdb56301e), SPH_C32(0xa0dc676f), SPH_C32(0x12455000), + SPH_C32(0xe28f0000), SPH_C32(0x188b0000), SPH_C32(0x1b180000), + SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), SPH_C32(0x4a3a8ff2), + SPH_C32(0xea373c60) }, + { SPH_C32(0x466d0c00), SPH_C32(0x08620000), SPH_C32(0xdd5d0000), + SPH_C32(0xbadd0000), SPH_C32(0x6a927942), SPH_C32(0x441f2b93), + SPH_C32(0x218ace6f), SPH_C32(0xbf2c0be2), SPH_C32(0x6f299000), + SPH_C32(0x6c850000), SPH_C32(0x2f160000), SPH_C32(0x782e0000), + SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), SPH_C32(0xd26a8c36), + SPH_C32(0x32219526) }, + { SPH_C32(0x12455000), SPH_C32(0xe28f0000), SPH_C32(0x188b0000), + SPH_C32(0x1b180000), SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), + SPH_C32(0x4a3a8ff2), SPH_C32(0xea373c60), SPH_C32(0xf3928800), + SPH_C32(0xdc560000), SPH_C32(0xbd470000), SPH_C32(0x95bd0000), + SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), SPH_C32(0x916cbfec), + SPH_C32(0x4aeb5b0f) }, + { SPH_C32(0xdad61400), SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), + SPH_C32(0x574e0000), SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), + SPH_C32(0x628cfdb5), SPH_C32(0xc7e6c5cb), SPH_C32(0xa7bad400), + SPH_C32(0x36bb0000), SPH_C32(0x78910000), SPH_C32(0x34780000), + SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), SPH_C32(0xfadcfe71), + SPH_C32(0x1ff06c8d) }, + { SPH_C32(0x8efe4800), SPH_C32(0x525c0000), SPH_C32(0x8ada0000), + SPH_C32(0xf68b0000), SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), + SPH_C32(0x093cbc28), SPH_C32(0x92fdf249), SPH_C32(0x3b01cc00), + SPH_C32(0x86680000), SPH_C32(0xeac00000), SPH_C32(0xd9eb0000), + SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), SPH_C32(0xb9dacdab), + SPH_C32(0x673aa2a4) }, + { SPH_C32(0x6f299000), SPH_C32(0x6c850000), SPH_C32(0x2f160000), + SPH_C32(0x782e0000), SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), + SPH_C32(0xd26a8c36), SPH_C32(0x32219526), SPH_C32(0x29449c00), + SPH_C32(0x64e70000), SPH_C32(0xf24b0000), SPH_C32(0xc2f30000), + SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), SPH_C32(0xf3e04259), + SPH_C32(0x8d0d9ec4) }, + { SPH_C32(0x3b01cc00), SPH_C32(0x86680000), SPH_C32(0xeac00000), + SPH_C32(0xd9eb0000), SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), + SPH_C32(0xb9dacdab), SPH_C32(0x673aa2a4), SPH_C32(0xb5ff8400), + SPH_C32(0xd4340000), SPH_C32(0x601a0000), SPH_C32(0x2f600000), + SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), SPH_C32(0xb0e67183), + SPH_C32(0xf5c750ed) }, + { SPH_C32(0xf3928800), SPH_C32(0xdc560000), SPH_C32(0xbd470000), + SPH_C32(0x95bd0000), SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), + SPH_C32(0x916cbfec), SPH_C32(0x4aeb5b0f), SPH_C32(0xe1d7d800), + SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), SPH_C32(0x8ea50000), + SPH_C32(0xe4466aba), SPH_C32(0x23732650), SPH_C32(0xdb56301e), + SPH_C32(0xa0dc676f) }, + { SPH_C32(0xa7bad400), SPH_C32(0x36bb0000), SPH_C32(0x78910000), + SPH_C32(0x34780000), SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), + SPH_C32(0xfadcfe71), SPH_C32(0x1ff06c8d), SPH_C32(0x7d6cc000), + SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), SPH_C32(0x63360000), + SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), SPH_C32(0x985003c4), + SPH_C32(0xd816a946) } +}; + +static const sph_u32 T512_4[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xef0b0270), SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), + SPH_C32(0x69490000), SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), + SPH_C32(0x66140a51), SPH_C32(0x924f5d0a), SPH_C32(0xc96b0030), + SPH_C32(0xe7250000), SPH_C32(0x2f840000), SPH_C32(0x264f0000), + SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), SPH_C32(0x509f6984), + SPH_C32(0x9e69af68) }, + { SPH_C32(0xc96b0030), SPH_C32(0xe7250000), SPH_C32(0x2f840000), + SPH_C32(0x264f0000), SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), + SPH_C32(0x509f6984), SPH_C32(0x9e69af68), SPH_C32(0x26600240), + SPH_C32(0xddd80000), SPH_C32(0x722a0000), SPH_C32(0x4f060000), + SPH_C32(0x936667ff), SPH_C32(0x29f944ce), SPH_C32(0x368b63d5), + SPH_C32(0x0c26f262) }, + { SPH_C32(0x26600240), SPH_C32(0xddd80000), SPH_C32(0x722a0000), + SPH_C32(0x4f060000), SPH_C32(0x936667ff), SPH_C32(0x29f944ce), + SPH_C32(0x368b63d5), SPH_C32(0x0c26f262), SPH_C32(0xef0b0270), + SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), SPH_C32(0x69490000), + SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), SPH_C32(0x66140a51), + SPH_C32(0x924f5d0a) }, + { SPH_C32(0x145a3c00), SPH_C32(0xb9e90000), SPH_C32(0x61270000), + SPH_C32(0xf1610000), SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), + SPH_C32(0x47a96720), SPH_C32(0xe18e24c5), SPH_C32(0x23671400), + SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), SPH_C32(0xfb750000), + SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), SPH_C32(0x02c40a3f), + SPH_C32(0xdc24e61f) }, + { SPH_C32(0xfb513e70), SPH_C32(0x83140000), SPH_C32(0x3c890000), + SPH_C32(0x98280000), SPH_C32(0x556e016a), SPH_C32(0xf44c8881), + SPH_C32(0x21bd6d71), SPH_C32(0x73c179cf), SPH_C32(0xea0c1430), + SPH_C32(0x2f9c0000), SPH_C32(0xdb430000), SPH_C32(0xdd3a0000), + SPH_C32(0x7ba47f9c), SPH_C32(0x955a547e), SPH_C32(0x525b63bb), + SPH_C32(0x424d4977) }, + { SPH_C32(0xdd313c30), SPH_C32(0x5ecc0000), SPH_C32(0x4ea30000), + SPH_C32(0xd72e0000), SPH_C32(0xc6086695), SPH_C32(0xddb5cc4f), + SPH_C32(0x17360ea4), SPH_C32(0x7fe78bad), SPH_C32(0x05071640), + SPH_C32(0x15610000), SPH_C32(0x86ed0000), SPH_C32(0xb4730000), + SPH_C32(0xe0ab439a), SPH_C32(0xd15fe187), SPH_C32(0x344f69ea), + SPH_C32(0xd002147d) }, + { SPH_C32(0x323a3e40), SPH_C32(0x64310000), SPH_C32(0x130d0000), + SPH_C32(0xbe670000), SPH_C32(0x5d075a93), SPH_C32(0x99b079b6), + SPH_C32(0x712204f5), SPH_C32(0xeda8d6a7), SPH_C32(0xcc6c1670), + SPH_C32(0xf2440000), SPH_C32(0xa9690000), SPH_C32(0x923c0000), + SPH_C32(0xe8c21863), SPH_C32(0xbca310b0), SPH_C32(0x64d0006e), + SPH_C32(0x4e6bbb15) }, + { SPH_C32(0x23671400), SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), + SPH_C32(0xfb750000), SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), + SPH_C32(0x02c40a3f), SPH_C32(0xdc24e61f), SPH_C32(0x373d2800), + SPH_C32(0x71500000), SPH_C32(0x95e00000), SPH_C32(0x0a140000), + SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), SPH_C32(0x456d6d1f), + SPH_C32(0x3daac2da) }, + { SPH_C32(0xcc6c1670), SPH_C32(0xf2440000), SPH_C32(0xa9690000), + SPH_C32(0x923c0000), SPH_C32(0xe8c21863), SPH_C32(0xbca310b0), + SPH_C32(0x64d0006e), SPH_C32(0x4e6bbb15), SPH_C32(0xfe562830), + SPH_C32(0x96750000), SPH_C32(0xba640000), SPH_C32(0x2c5b0000), + SPH_C32(0xb5c542f0), SPH_C32(0x25136906), SPH_C32(0x15f2049b), + SPH_C32(0xa3c36db2) }, + { SPH_C32(0xea0c1430), SPH_C32(0x2f9c0000), SPH_C32(0xdb430000), + SPH_C32(0xdd3a0000), SPH_C32(0x7ba47f9c), SPH_C32(0x955a547e), + SPH_C32(0x525b63bb), SPH_C32(0x424d4977), SPH_C32(0x115d2a40), + SPH_C32(0xac880000), SPH_C32(0xe7ca0000), SPH_C32(0x45120000), + SPH_C32(0x2eca7ef6), SPH_C32(0x6116dcff), SPH_C32(0x73e60eca), + SPH_C32(0x318c30b8) }, + { SPH_C32(0x05071640), SPH_C32(0x15610000), SPH_C32(0x86ed0000), + SPH_C32(0xb4730000), SPH_C32(0xe0ab439a), SPH_C32(0xd15fe187), + SPH_C32(0x344f69ea), SPH_C32(0xd002147d), SPH_C32(0xd8362a70), + SPH_C32(0x4bad0000), SPH_C32(0xc84e0000), SPH_C32(0x635d0000), + SPH_C32(0x26a3250f), SPH_C32(0x0cea2dc8), SPH_C32(0x2379674e), + SPH_C32(0xafe59fd0) }, + { SPH_C32(0x373d2800), SPH_C32(0x71500000), SPH_C32(0x95e00000), + SPH_C32(0x0a140000), SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), + SPH_C32(0x456d6d1f), SPH_C32(0x3daac2da), SPH_C32(0x145a3c00), + SPH_C32(0xb9e90000), SPH_C32(0x61270000), SPH_C32(0xf1610000), + SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), SPH_C32(0x47a96720), + SPH_C32(0xe18e24c5) }, + { SPH_C32(0xd8362a70), SPH_C32(0x4bad0000), SPH_C32(0xc84e0000), + SPH_C32(0x635d0000), SPH_C32(0x26a3250f), SPH_C32(0x0cea2dc8), + SPH_C32(0x2379674e), SPH_C32(0xafe59fd0), SPH_C32(0xdd313c30), + SPH_C32(0x5ecc0000), SPH_C32(0x4ea30000), SPH_C32(0xd72e0000), + SPH_C32(0xc6086695), SPH_C32(0xddb5cc4f), SPH_C32(0x17360ea4), + SPH_C32(0x7fe78bad) }, + { SPH_C32(0xfe562830), SPH_C32(0x96750000), SPH_C32(0xba640000), + SPH_C32(0x2c5b0000), SPH_C32(0xb5c542f0), SPH_C32(0x25136906), + SPH_C32(0x15f2049b), SPH_C32(0xa3c36db2), SPH_C32(0x323a3e40), + SPH_C32(0x64310000), SPH_C32(0x130d0000), SPH_C32(0xbe670000), + SPH_C32(0x5d075a93), SPH_C32(0x99b079b6), SPH_C32(0x712204f5), + SPH_C32(0xeda8d6a7) }, + { SPH_C32(0x115d2a40), SPH_C32(0xac880000), SPH_C32(0xe7ca0000), + SPH_C32(0x45120000), SPH_C32(0x2eca7ef6), SPH_C32(0x6116dcff), + SPH_C32(0x73e60eca), SPH_C32(0x318c30b8), SPH_C32(0xfb513e70), + SPH_C32(0x83140000), SPH_C32(0x3c890000), SPH_C32(0x98280000), + SPH_C32(0x556e016a), SPH_C32(0xf44c8881), SPH_C32(0x21bd6d71), + SPH_C32(0x73c179cf) } +}; + +static const sph_u32 T512_8[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x774400f0), SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), + SPH_C32(0x34140000), SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), + SPH_C32(0x0bc3cd1e), SPH_C32(0xcf3775cb), SPH_C32(0xf46c0050), + SPH_C32(0x96180000), SPH_C32(0x14a50000), SPH_C32(0x031f0000), + SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), SPH_C32(0x9ca470d2), + SPH_C32(0x8a341574) }, + { SPH_C32(0xf46c0050), SPH_C32(0x96180000), SPH_C32(0x14a50000), + SPH_C32(0x031f0000), SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), + SPH_C32(0x9ca470d2), SPH_C32(0x8a341574), SPH_C32(0x832800a0), + SPH_C32(0x67420000), SPH_C32(0xe1170000), SPH_C32(0x370b0000), + SPH_C32(0xcba30034), SPH_C32(0x3c34923c), SPH_C32(0x9767bdcc), + SPH_C32(0x450360bf) }, + { SPH_C32(0x832800a0), SPH_C32(0x67420000), SPH_C32(0xe1170000), + SPH_C32(0x370b0000), SPH_C32(0xcba30034), SPH_C32(0x3c34923c), + SPH_C32(0x9767bdcc), SPH_C32(0x450360bf), SPH_C32(0x774400f0), + SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), SPH_C32(0x34140000), + SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), SPH_C32(0x0bc3cd1e), + SPH_C32(0xcf3775cb) }, + { SPH_C32(0xe8870170), SPH_C32(0x9d720000), SPH_C32(0x12db0000), + SPH_C32(0xd4220000), SPH_C32(0xf2886b27), SPH_C32(0xa921e543), + SPH_C32(0x4ef8b518), SPH_C32(0x618813b1), SPH_C32(0xb4370060), + SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), SPH_C32(0x5cae0000), + SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), SPH_C32(0x1b365f3d), + SPH_C32(0xf3d45758) }, + { SPH_C32(0x9fc30180), SPH_C32(0x6c280000), SPH_C32(0xe7690000), + SPH_C32(0xe0360000), SPH_C32(0x7bbf15ab), SPH_C32(0xf3aa0966), + SPH_C32(0x453b7806), SPH_C32(0xaebf667a), SPH_C32(0x405b0030), + SPH_C32(0x9a540000), SPH_C32(0x42670000), SPH_C32(0x5fb10000), + SPH_C32(0xd6c06187), SPH_C32(0x5d81863c), SPH_C32(0x87922fef), + SPH_C32(0x79e0422c) }, + { SPH_C32(0x1ceb0120), SPH_C32(0x0b6a0000), SPH_C32(0x067e0000), + SPH_C32(0xd73d0000), SPH_C32(0xb01c159f), SPH_C32(0xcf9e9b5a), + SPH_C32(0xd25cc5ca), SPH_C32(0xebbc06c5), SPH_C32(0x371f00c0), + SPH_C32(0x6b0e0000), SPH_C32(0xb7d50000), SPH_C32(0x6ba50000), + SPH_C32(0x5ff71f0b), SPH_C32(0x070a6a19), SPH_C32(0x8c51e2f1), + SPH_C32(0xb6d737e7) }, + { SPH_C32(0x6baf01d0), SPH_C32(0xfa300000), SPH_C32(0xf3cc0000), + SPH_C32(0xe3290000), SPH_C32(0x392b6b13), SPH_C32(0x9515777f), + SPH_C32(0xd99f08d4), SPH_C32(0x248b730e), SPH_C32(0xc3730090), + SPH_C32(0xfd160000), SPH_C32(0xa3700000), SPH_C32(0x68ba0000), + SPH_C32(0x1d6361b3), SPH_C32(0x61b51400), SPH_C32(0x10f59223), + SPH_C32(0x3ce32293) }, + { SPH_C32(0xb4370060), SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), + SPH_C32(0x5cae0000), SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), + SPH_C32(0x1b365f3d), SPH_C32(0xf3d45758), SPH_C32(0x5cb00110), + SPH_C32(0x913e0000), SPH_C32(0x44190000), SPH_C32(0x888c0000), + SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), SPH_C32(0x55ceea25), + SPH_C32(0x925c44e9) }, + { SPH_C32(0xc3730090), SPH_C32(0xfd160000), SPH_C32(0xa3700000), + SPH_C32(0x68ba0000), SPH_C32(0x1d6361b3), SPH_C32(0x61b51400), + SPH_C32(0x10f59223), SPH_C32(0x3ce32293), SPH_C32(0xa8dc0140), + SPH_C32(0x07260000), SPH_C32(0x50bc0000), SPH_C32(0x8b930000), + SPH_C32(0x24480aa0), SPH_C32(0xf4a0637f), SPH_C32(0xc96a9af7), + SPH_C32(0x1868519d) }, + { SPH_C32(0x405b0030), SPH_C32(0x9a540000), SPH_C32(0x42670000), + SPH_C32(0x5fb10000), SPH_C32(0xd6c06187), SPH_C32(0x5d81863c), + SPH_C32(0x87922fef), SPH_C32(0x79e0422c), SPH_C32(0xdf9801b0), + SPH_C32(0xf67c0000), SPH_C32(0xa50e0000), SPH_C32(0xbf870000), + SPH_C32(0xad7f742c), SPH_C32(0xae2b8f5a), SPH_C32(0xc2a957e9), + SPH_C32(0xd75f2456) }, + { SPH_C32(0x371f00c0), SPH_C32(0x6b0e0000), SPH_C32(0xb7d50000), + SPH_C32(0x6ba50000), SPH_C32(0x5ff71f0b), SPH_C32(0x070a6a19), + SPH_C32(0x8c51e2f1), SPH_C32(0xb6d737e7), SPH_C32(0x2bf401e0), + SPH_C32(0x60640000), SPH_C32(0xb1ab0000), SPH_C32(0xbc980000), + SPH_C32(0xefeb0a94), SPH_C32(0xc894f143), SPH_C32(0x5e0d273b), + SPH_C32(0x5d6b3122) }, + { SPH_C32(0x5cb00110), SPH_C32(0x913e0000), SPH_C32(0x44190000), + SPH_C32(0x888c0000), SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), + SPH_C32(0x55ceea25), SPH_C32(0x925c44e9), SPH_C32(0xe8870170), + SPH_C32(0x9d720000), SPH_C32(0x12db0000), SPH_C32(0xd4220000), + SPH_C32(0xf2886b27), SPH_C32(0xa921e543), SPH_C32(0x4ef8b518), + SPH_C32(0x618813b1) }, + { SPH_C32(0x2bf401e0), SPH_C32(0x60640000), SPH_C32(0xb1ab0000), + SPH_C32(0xbc980000), SPH_C32(0xefeb0a94), SPH_C32(0xc894f143), + SPH_C32(0x5e0d273b), SPH_C32(0x5d6b3122), SPH_C32(0x1ceb0120), + SPH_C32(0x0b6a0000), SPH_C32(0x067e0000), SPH_C32(0xd73d0000), + SPH_C32(0xb01c159f), SPH_C32(0xcf9e9b5a), SPH_C32(0xd25cc5ca), + SPH_C32(0xebbc06c5) }, + { SPH_C32(0xa8dc0140), SPH_C32(0x07260000), SPH_C32(0x50bc0000), + SPH_C32(0x8b930000), SPH_C32(0x24480aa0), SPH_C32(0xf4a0637f), + SPH_C32(0xc96a9af7), SPH_C32(0x1868519d), SPH_C32(0x6baf01d0), + SPH_C32(0xfa300000), SPH_C32(0xf3cc0000), SPH_C32(0xe3290000), + SPH_C32(0x392b6b13), SPH_C32(0x9515777f), SPH_C32(0xd99f08d4), + SPH_C32(0x248b730e) }, + { SPH_C32(0xdf9801b0), SPH_C32(0xf67c0000), SPH_C32(0xa50e0000), + SPH_C32(0xbf870000), SPH_C32(0xad7f742c), SPH_C32(0xae2b8f5a), + SPH_C32(0xc2a957e9), SPH_C32(0xd75f2456), SPH_C32(0x9fc30180), + SPH_C32(0x6c280000), SPH_C32(0xe7690000), SPH_C32(0xe0360000), + SPH_C32(0x7bbf15ab), SPH_C32(0xf3aa0966), SPH_C32(0x453b7806), + SPH_C32(0xaebf667a) } +}; + +static const sph_u32 T512_12[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xf6800005), SPH_C32(0x3443c000), SPH_C32(0x24070000), + SPH_C32(0x8f3d0000), SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), + SPH_C32(0xcdc58b19), SPH_C32(0xd795ba31), SPH_C32(0xa67f0001), + SPH_C32(0x71378000), SPH_C32(0x19fc0000), SPH_C32(0x96db0000), + SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), SPH_C32(0x2c6d478f), + SPH_C32(0xac8e6c88) }, + { SPH_C32(0xa67f0001), SPH_C32(0x71378000), SPH_C32(0x19fc0000), + SPH_C32(0x96db0000), SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), + SPH_C32(0x2c6d478f), SPH_C32(0xac8e6c88), SPH_C32(0x50ff0004), + SPH_C32(0x45744000), SPH_C32(0x3dfb0000), SPH_C32(0x19e60000), + SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), SPH_C32(0xe1a8cc96), + SPH_C32(0x7b1bd6b9) }, + { SPH_C32(0x50ff0004), SPH_C32(0x45744000), SPH_C32(0x3dfb0000), + SPH_C32(0x19e60000), SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), + SPH_C32(0xe1a8cc96), SPH_C32(0x7b1bd6b9), SPH_C32(0xf6800005), + SPH_C32(0x3443c000), SPH_C32(0x24070000), SPH_C32(0x8f3d0000), + SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), SPH_C32(0xcdc58b19), + SPH_C32(0xd795ba31) }, + { SPH_C32(0xf7750009), SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), + SPH_C32(0x04920000), SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), + SPH_C32(0x7a87f14e), SPH_C32(0x9e16981a), SPH_C32(0xd46a0000), + SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), SPH_C32(0x4a290000), + SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), SPH_C32(0x98369604), + SPH_C32(0xf746c320) }, + { SPH_C32(0x01f5000c), SPH_C32(0xfb7f0000), SPH_C32(0xe7d10000), + SPH_C32(0x8baf0000), SPH_C32(0x23a22252), SPH_C32(0xf250e314), + SPH_C32(0xb7427a57), SPH_C32(0x4983222b), SPH_C32(0x72150001), + SPH_C32(0xfcff4000), SPH_C32(0xbc530000), SPH_C32(0xdcf20000), + SPH_C32(0xc6c52f87), SPH_C32(0x227e289f), SPH_C32(0xb45bd18b), + SPH_C32(0x5bc8afa8) }, + { SPH_C32(0x510a0008), SPH_C32(0xbe0b4000), SPH_C32(0xda2a0000), + SPH_C32(0x92490000), SPH_C32(0x381e7454), SPH_C32(0x13229849), + SPH_C32(0x56eab6c1), SPH_C32(0x3298f492), SPH_C32(0x84950004), + SPH_C32(0xc8bc8000), SPH_C32(0x98540000), SPH_C32(0x53cf0000), + SPH_C32(0xe7f2147c), SPH_C32(0x28c6fd31), SPH_C32(0x799e5a92), + SPH_C32(0x8c5d1599) }, + { SPH_C32(0xa78a000d), SPH_C32(0x8a488000), SPH_C32(0xfe2d0000), + SPH_C32(0x1d740000), SPH_C32(0x19294faf), SPH_C32(0x199a4de7), + SPH_C32(0x9b2f3dd8), SPH_C32(0xe50d4ea3), SPH_C32(0x22ea0005), + SPH_C32(0xb98b0000), SPH_C32(0x81a80000), SPH_C32(0xc5140000), + SPH_C32(0xdd797981), SPH_C32(0xc30c53c2), SPH_C32(0x55f31d1d), + SPH_C32(0x20d37911) }, + { SPH_C32(0xd46a0000), SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), + SPH_C32(0x4a290000), SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), + SPH_C32(0x98369604), SPH_C32(0xf746c320), SPH_C32(0x231f0009), + SPH_C32(0x42f40000), SPH_C32(0x66790000), SPH_C32(0x4ebb0000), + SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), SPH_C32(0xe2b1674a), + SPH_C32(0x69505b3a) }, + { SPH_C32(0x22ea0005), SPH_C32(0xb98b0000), SPH_C32(0x81a80000), + SPH_C32(0xc5140000), SPH_C32(0xdd797981), SPH_C32(0xc30c53c2), + SPH_C32(0x55f31d1d), SPH_C32(0x20d37911), SPH_C32(0x85600008), + SPH_C32(0x33c38000), SPH_C32(0x7f850000), SPH_C32(0xd8600000), + SPH_C32(0xc450362e), SPH_C32(0xda961e25), SPH_C32(0xcedc20c5), + SPH_C32(0xc5de37b2) }, + { SPH_C32(0x72150001), SPH_C32(0xfcff4000), SPH_C32(0xbc530000), + SPH_C32(0xdcf20000), SPH_C32(0xc6c52f87), SPH_C32(0x227e289f), + SPH_C32(0xb45bd18b), SPH_C32(0x5bc8afa8), SPH_C32(0x73e0000d), + SPH_C32(0x07804000), SPH_C32(0x5b820000), SPH_C32(0x575d0000), + SPH_C32(0xe5670dd5), SPH_C32(0xd02ecb8b), SPH_C32(0x0319abdc), + SPH_C32(0x124b8d83) }, + { SPH_C32(0x84950004), SPH_C32(0xc8bc8000), SPH_C32(0x98540000), + SPH_C32(0x53cf0000), SPH_C32(0xe7f2147c), SPH_C32(0x28c6fd31), + SPH_C32(0x799e5a92), SPH_C32(0x8c5d1599), SPH_C32(0xd59f000c), + SPH_C32(0x76b7c000), SPH_C32(0x427e0000), SPH_C32(0xc1860000), + SPH_C32(0xdfec6028), SPH_C32(0x3be46578), SPH_C32(0x2f74ec53), + SPH_C32(0xbec5e10b) }, + { SPH_C32(0x231f0009), SPH_C32(0x42f40000), SPH_C32(0x66790000), + SPH_C32(0x4ebb0000), SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), + SPH_C32(0xe2b1674a), SPH_C32(0x69505b3a), SPH_C32(0xf7750009), + SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), SPH_C32(0x04920000), + SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), SPH_C32(0x7a87f14e), + SPH_C32(0x9e16981a) }, + { SPH_C32(0xd59f000c), SPH_C32(0x76b7c000), SPH_C32(0x427e0000), + SPH_C32(0xc1860000), SPH_C32(0xdfec6028), SPH_C32(0x3be46578), + SPH_C32(0x2f74ec53), SPH_C32(0xbec5e10b), SPH_C32(0x510a0008), + SPH_C32(0xbe0b4000), SPH_C32(0xda2a0000), SPH_C32(0x92490000), + SPH_C32(0x381e7454), SPH_C32(0x13229849), SPH_C32(0x56eab6c1), + SPH_C32(0x3298f492) }, + { SPH_C32(0x85600008), SPH_C32(0x33c38000), SPH_C32(0x7f850000), + SPH_C32(0xd8600000), SPH_C32(0xc450362e), SPH_C32(0xda961e25), + SPH_C32(0xcedc20c5), SPH_C32(0xc5de37b2), SPH_C32(0xa78a000d), + SPH_C32(0x8a488000), SPH_C32(0xfe2d0000), SPH_C32(0x1d740000), + SPH_C32(0x19294faf), SPH_C32(0x199a4de7), SPH_C32(0x9b2f3dd8), + SPH_C32(0xe50d4ea3) }, + { SPH_C32(0x73e0000d), SPH_C32(0x07804000), SPH_C32(0x5b820000), + SPH_C32(0x575d0000), SPH_C32(0xe5670dd5), SPH_C32(0xd02ecb8b), + SPH_C32(0x0319abdc), SPH_C32(0x124b8d83), SPH_C32(0x01f5000c), + SPH_C32(0xfb7f0000), SPH_C32(0xe7d10000), SPH_C32(0x8baf0000), + SPH_C32(0x23a22252), SPH_C32(0xf250e314), SPH_C32(0xb7427a57), + SPH_C32(0x4983222b) } +}; + +static const sph_u32 T512_16[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x75a40000), SPH_C32(0xc28b2700), SPH_C32(0x94a40000), + SPH_C32(0x90f50000), SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), + SPH_C32(0x1767c483), SPH_C32(0xaedf667e), SPH_C32(0xd1660000), + SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), SPH_C32(0xf6940000), + SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), SPH_C32(0xb4431b17), + SPH_C32(0x857f3c2b) }, + { SPH_C32(0xd1660000), SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), + SPH_C32(0xf6940000), SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), + SPH_C32(0xb4431b17), SPH_C32(0x857f3c2b), SPH_C32(0xa4c20000), + SPH_C32(0xd9372400), SPH_C32(0x0a480000), SPH_C32(0x66610000), + SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), SPH_C32(0xa324df94), + SPH_C32(0x2ba05a55) }, + { SPH_C32(0xa4c20000), SPH_C32(0xd9372400), SPH_C32(0x0a480000), + SPH_C32(0x66610000), SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), + SPH_C32(0xa324df94), SPH_C32(0x2ba05a55), SPH_C32(0x75a40000), + SPH_C32(0xc28b2700), SPH_C32(0x94a40000), SPH_C32(0x90f50000), + SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), SPH_C32(0x1767c483), + SPH_C32(0xaedf667e) }, + { SPH_C32(0x75c90003), SPH_C32(0x0e10c000), SPH_C32(0xd1200000), + SPH_C32(0xbaea0000), SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), + SPH_C32(0xbb28761d), SPH_C32(0x00b72e2b), SPH_C32(0xeecf0001), + SPH_C32(0x6f564000), SPH_C32(0xf33e0000), SPH_C32(0xa79e0000), + SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), SPH_C32(0x4a3b40ba), + SPH_C32(0xfeabf254) }, + { SPH_C32(0x006d0003), SPH_C32(0xcc9be700), SPH_C32(0x45840000), + SPH_C32(0x2a1f0000), SPH_C32(0x70bc78de), SPH_C32(0xce96bcf9), + SPH_C32(0xac4fb29e), SPH_C32(0xae684855), SPH_C32(0x3fa90001), + SPH_C32(0x74ea4300), SPH_C32(0x6dd20000), SPH_C32(0x510a0000), + SPH_C32(0xbeb7373e), SPH_C32(0x78611737), SPH_C32(0xfe785bad), + SPH_C32(0x7bd4ce7f) }, + { SPH_C32(0xa4af0003), SPH_C32(0x15acc300), SPH_C32(0x4fcc0000), + SPH_C32(0x4c7e0000), SPH_C32(0x88c66a19), SPH_C32(0x48284ba5), + SPH_C32(0x0f6b6d0a), SPH_C32(0x85c81200), SPH_C32(0x4a0d0001), + SPH_C32(0xb6616400), SPH_C32(0xf9760000), SPH_C32(0xc1ff0000), + SPH_C32(0x45cf60de), SPH_C32(0x31af1c99), SPH_C32(0xe91f9f2e), + SPH_C32(0xd50ba801) }, + { SPH_C32(0xd10b0003), SPH_C32(0xd727e400), SPH_C32(0xdb680000), + SPH_C32(0xdc8b0000), SPH_C32(0x73be3df9), SPH_C32(0x01e6400b), + SPH_C32(0x180ca989), SPH_C32(0x2b17747e), SPH_C32(0x9b6b0001), + SPH_C32(0xaddd6700), SPH_C32(0x679a0000), SPH_C32(0x376b0000), + SPH_C32(0x46cd25f9), SPH_C32(0xfedfe06b), SPH_C32(0x5d5c8439), + SPH_C32(0x5074942a) }, + { SPH_C32(0xeecf0001), SPH_C32(0x6f564000), SPH_C32(0xf33e0000), + SPH_C32(0xa79e0000), SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), + SPH_C32(0x4a3b40ba), SPH_C32(0xfeabf254), SPH_C32(0x9b060002), + SPH_C32(0x61468000), SPH_C32(0x221e0000), SPH_C32(0x1d740000), + SPH_C32(0x36715d27), SPH_C32(0x30495c92), SPH_C32(0xf11336a7), + SPH_C32(0xfe1cdc7f) }, + { SPH_C32(0x9b6b0001), SPH_C32(0xaddd6700), SPH_C32(0x679a0000), + SPH_C32(0x376b0000), SPH_C32(0x46cd25f9), SPH_C32(0xfedfe06b), + SPH_C32(0x5d5c8439), SPH_C32(0x5074942a), SPH_C32(0x4a600002), + SPH_C32(0x7afa8300), SPH_C32(0xbcf20000), SPH_C32(0xebe00000), + SPH_C32(0x35731800), SPH_C32(0xff39a060), SPH_C32(0x45502db0), + SPH_C32(0x7b63e054) }, + { SPH_C32(0x3fa90001), SPH_C32(0x74ea4300), SPH_C32(0x6dd20000), + SPH_C32(0x510a0000), SPH_C32(0xbeb7373e), SPH_C32(0x78611737), + SPH_C32(0xfe785bad), SPH_C32(0x7bd4ce7f), SPH_C32(0x3fc40002), + SPH_C32(0xb871a400), SPH_C32(0x28560000), SPH_C32(0x7b150000), + SPH_C32(0xce0b4fe0), SPH_C32(0xb6f7abce), SPH_C32(0x5237e933), + SPH_C32(0xd5bc862a) }, + { SPH_C32(0x4a0d0001), SPH_C32(0xb6616400), SPH_C32(0xf9760000), + SPH_C32(0xc1ff0000), SPH_C32(0x45cf60de), SPH_C32(0x31af1c99), + SPH_C32(0xe91f9f2e), SPH_C32(0xd50ba801), SPH_C32(0xeea20002), + SPH_C32(0xa3cda700), SPH_C32(0xb6ba0000), SPH_C32(0x8d810000), + SPH_C32(0xcd090ac7), SPH_C32(0x7987573c), SPH_C32(0xe674f224), + SPH_C32(0x50c3ba01) }, + { SPH_C32(0x9b060002), SPH_C32(0x61468000), SPH_C32(0x221e0000), + SPH_C32(0x1d740000), SPH_C32(0x36715d27), SPH_C32(0x30495c92), + SPH_C32(0xf11336a7), SPH_C32(0xfe1cdc7f), SPH_C32(0x75c90003), + SPH_C32(0x0e10c000), SPH_C32(0xd1200000), SPH_C32(0xbaea0000), + SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), SPH_C32(0xbb28761d), + SPH_C32(0x00b72e2b) }, + { SPH_C32(0xeea20002), SPH_C32(0xa3cda700), SPH_C32(0xb6ba0000), + SPH_C32(0x8d810000), SPH_C32(0xcd090ac7), SPH_C32(0x7987573c), + SPH_C32(0xe674f224), SPH_C32(0x50c3ba01), SPH_C32(0xa4af0003), + SPH_C32(0x15acc300), SPH_C32(0x4fcc0000), SPH_C32(0x4c7e0000), + SPH_C32(0x88c66a19), SPH_C32(0x48284ba5), SPH_C32(0x0f6b6d0a), + SPH_C32(0x85c81200) }, + { SPH_C32(0x4a600002), SPH_C32(0x7afa8300), SPH_C32(0xbcf20000), + SPH_C32(0xebe00000), SPH_C32(0x35731800), SPH_C32(0xff39a060), + SPH_C32(0x45502db0), SPH_C32(0x7b63e054), SPH_C32(0xd10b0003), + SPH_C32(0xd727e400), SPH_C32(0xdb680000), SPH_C32(0xdc8b0000), + SPH_C32(0x73be3df9), SPH_C32(0x01e6400b), SPH_C32(0x180ca989), + SPH_C32(0x2b17747e) }, + { SPH_C32(0x3fc40002), SPH_C32(0xb871a400), SPH_C32(0x28560000), + SPH_C32(0x7b150000), SPH_C32(0xce0b4fe0), SPH_C32(0xb6f7abce), + SPH_C32(0x5237e933), SPH_C32(0xd5bc862a), SPH_C32(0x006d0003), + SPH_C32(0xcc9be700), SPH_C32(0x45840000), SPH_C32(0x2a1f0000), + SPH_C32(0x70bc78de), SPH_C32(0xce96bcf9), SPH_C32(0xac4fb29e), + SPH_C32(0xae684855) } +}; + +static const sph_u32 T512_20[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x0c720000), SPH_C32(0x49e50f00), SPH_C32(0x42790000), + SPH_C32(0x5cea0000), SPH_C32(0x33aa301a), SPH_C32(0x15822514), + SPH_C32(0x95a34b7b), SPH_C32(0xb44b0090), SPH_C32(0xfe220000), + SPH_C32(0xa7580500), SPH_C32(0x25d10000), SPH_C32(0xf7600000), + SPH_C32(0x893178da), SPH_C32(0x1fd4f860), SPH_C32(0x4ed0a315), + SPH_C32(0xa123ff9f) }, + { SPH_C32(0xfe220000), SPH_C32(0xa7580500), SPH_C32(0x25d10000), + SPH_C32(0xf7600000), SPH_C32(0x893178da), SPH_C32(0x1fd4f860), + SPH_C32(0x4ed0a315), SPH_C32(0xa123ff9f), SPH_C32(0xf2500000), + SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), SPH_C32(0xab8a0000), + SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), SPH_C32(0xdb73e86e), + SPH_C32(0x1568ff0f) }, + { SPH_C32(0xf2500000), SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), + SPH_C32(0xab8a0000), SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), + SPH_C32(0xdb73e86e), SPH_C32(0x1568ff0f), SPH_C32(0x0c720000), + SPH_C32(0x49e50f00), SPH_C32(0x42790000), SPH_C32(0x5cea0000), + SPH_C32(0x33aa301a), SPH_C32(0x15822514), SPH_C32(0x95a34b7b), + SPH_C32(0xb44b0090) }, + { SPH_C32(0x45180000), SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), + SPH_C32(0x3b480000), SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), + SPH_C32(0x16bca6b0), SPH_C32(0xdf33f4df), SPH_C32(0xb83d0000), + SPH_C32(0x16710600), SPH_C32(0x379a0000), SPH_C32(0xf5b10000), + SPH_C32(0x228161ac), SPH_C32(0xae48f145), SPH_C32(0x66241616), + SPH_C32(0xc5c1eb3e) }, + { SPH_C32(0x496a0000), SPH_C32(0xec501800), SPH_C32(0xbb130000), + SPH_C32(0x67a20000), SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), + SPH_C32(0x831fedcb), SPH_C32(0x6b78f44f), SPH_C32(0x461f0000), + SPH_C32(0xb1290300), SPH_C32(0x124b0000), SPH_C32(0x02d10000), + SPH_C32(0xabb01976), SPH_C32(0xb19c0925), SPH_C32(0x28f4b503), + SPH_C32(0x64e214a1) }, + { SPH_C32(0xbb3a0000), SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), + SPH_C32(0xcc280000), SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), + SPH_C32(0x586c05a5), SPH_C32(0x7e100b40), SPH_C32(0x4a6d0000), + SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), SPH_C32(0x5e3b0000), + SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), SPH_C32(0xbd57fe78), + SPH_C32(0xd0a91431) }, + { SPH_C32(0xb7480000), SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), + SPH_C32(0x90c20000), SPH_C32(0xa4575cec), SPH_C32(0x294548a2), + SPH_C32(0xcdcf4ede), SPH_C32(0xca5b0bd0), SPH_C32(0xb44f0000), + SPH_C32(0x5f940900), SPH_C32(0x75e30000), SPH_C32(0xa95b0000), + SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), SPH_C32(0xf3875d6d), + SPH_C32(0x718aebae) }, + { SPH_C32(0xb83d0000), SPH_C32(0x16710600), SPH_C32(0x379a0000), + SPH_C32(0xf5b10000), SPH_C32(0x228161ac), SPH_C32(0xae48f145), + SPH_C32(0x66241616), SPH_C32(0xc5c1eb3e), SPH_C32(0xfd250000), + SPH_C32(0xb3c41100), SPH_C32(0xcef00000), SPH_C32(0xcef90000), + SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), SPH_C32(0x7098b0a6), + SPH_C32(0x1af21fe1) }, + { SPH_C32(0xb44f0000), SPH_C32(0x5f940900), SPH_C32(0x75e30000), + SPH_C32(0xa95b0000), SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), + SPH_C32(0xf3875d6d), SPH_C32(0x718aebae), SPH_C32(0x03070000), + SPH_C32(0x149c1400), SPH_C32(0xeb210000), SPH_C32(0x39990000), + SPH_C32(0xb57c0d5a), SPH_C32(0x928f9cf3), SPH_C32(0x3e4813b3), + SPH_C32(0xbbd1e07e) }, + { SPH_C32(0x461f0000), SPH_C32(0xb1290300), SPH_C32(0x124b0000), + SPH_C32(0x02d10000), SPH_C32(0xabb01976), SPH_C32(0xb19c0925), + SPH_C32(0x28f4b503), SPH_C32(0x64e214a1), SPH_C32(0x0f750000), + SPH_C32(0x5d791b00), SPH_C32(0xa9580000), SPH_C32(0x65730000), + SPH_C32(0x86d63d40), SPH_C32(0x870db9e7), SPH_C32(0xabeb58c8), + SPH_C32(0x0f9ae0ee) }, + { SPH_C32(0x4a6d0000), SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), + SPH_C32(0x5e3b0000), SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), + SPH_C32(0xbd57fe78), SPH_C32(0xd0a91431), SPH_C32(0xf1570000), + SPH_C32(0xfa211e00), SPH_C32(0x8c890000), SPH_C32(0x92130000), + SPH_C32(0x0fe7459a), SPH_C32(0x98d94187), SPH_C32(0xe53bfbdd), + SPH_C32(0xaeb91f71) }, + { SPH_C32(0xfd250000), SPH_C32(0xb3c41100), SPH_C32(0xcef00000), + SPH_C32(0xcef90000), SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), + SPH_C32(0x7098b0a6), SPH_C32(0x1af21fe1), SPH_C32(0x45180000), + SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), SPH_C32(0x3b480000), + SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), SPH_C32(0x16bca6b0), + SPH_C32(0xdf33f4df) }, + { SPH_C32(0xf1570000), SPH_C32(0xfa211e00), SPH_C32(0x8c890000), + SPH_C32(0x92130000), SPH_C32(0x0fe7459a), SPH_C32(0x98d94187), + SPH_C32(0xe53bfbdd), SPH_C32(0xaeb91f71), SPH_C32(0xbb3a0000), + SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), SPH_C32(0xcc280000), + SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), SPH_C32(0x586c05a5), + SPH_C32(0x7e100b40) }, + { SPH_C32(0x03070000), SPH_C32(0x149c1400), SPH_C32(0xeb210000), + SPH_C32(0x39990000), SPH_C32(0xb57c0d5a), SPH_C32(0x928f9cf3), + SPH_C32(0x3e4813b3), SPH_C32(0xbbd1e07e), SPH_C32(0xb7480000), + SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), SPH_C32(0x90c20000), + SPH_C32(0xa4575cec), SPH_C32(0x294548a2), SPH_C32(0xcdcf4ede), + SPH_C32(0xca5b0bd0) }, + { SPH_C32(0x0f750000), SPH_C32(0x5d791b00), SPH_C32(0xa9580000), + SPH_C32(0x65730000), SPH_C32(0x86d63d40), SPH_C32(0x870db9e7), + SPH_C32(0xabeb58c8), SPH_C32(0x0f9ae0ee), SPH_C32(0x496a0000), + SPH_C32(0xec501800), SPH_C32(0xbb130000), SPH_C32(0x67a20000), + SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), SPH_C32(0x831fedcb), + SPH_C32(0x6b78f44f) } +}; + +static const sph_u32 T512_24[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x54500000), SPH_C32(0x0671005c), SPH_C32(0x25ae0000), + SPH_C32(0x6a1e0000), SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), + SPH_C32(0xbfba18c3), SPH_C32(0x7e715d17), SPH_C32(0xbc8d0000), + SPH_C32(0xfc3b0018), SPH_C32(0x19830000), SPH_C32(0xd10b0000), + SPH_C32(0xae1878c4), SPH_C32(0x42a69856), SPH_C32(0x0012da37), + SPH_C32(0x2c3b504e) }, + { SPH_C32(0xbc8d0000), SPH_C32(0xfc3b0018), SPH_C32(0x19830000), + SPH_C32(0xd10b0000), SPH_C32(0xae1878c4), SPH_C32(0x42a69856), + SPH_C32(0x0012da37), SPH_C32(0x2c3b504e), SPH_C32(0xe8dd0000), + SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), SPH_C32(0xbb150000), + SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), SPH_C32(0xbfa8c2f4), + SPH_C32(0x524a0d59) }, + { SPH_C32(0xe8dd0000), SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), + SPH_C32(0xbb150000), SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), + SPH_C32(0xbfa8c2f4), SPH_C32(0x524a0d59), SPH_C32(0x54500000), + SPH_C32(0x0671005c), SPH_C32(0x25ae0000), SPH_C32(0x6a1e0000), + SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), SPH_C32(0xbfba18c3), + SPH_C32(0x7e715d17) }, + { SPH_C32(0x69510000), SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), + SPH_C32(0xac2f0000), SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), + SPH_C32(0x87ec287c), SPH_C32(0xbce1a3ce), SPH_C32(0xc6730000), + SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), SPH_C32(0x218d0000), + SPH_C32(0x23111587), SPH_C32(0x7913512f), SPH_C32(0x1d28ac88), + SPH_C32(0x378dd173) }, + { SPH_C32(0x3d010000), SPH_C32(0xd29000c0), SPH_C32(0xe68d0000), + SPH_C32(0xc6310000), SPH_C32(0xca304571), SPH_C32(0xa8ea90ce), + SPH_C32(0x385630bf), SPH_C32(0xc290fed9), SPH_C32(0x7afe0000), + SPH_C32(0x53b60014), SPH_C32(0xbd420000), SPH_C32(0xf0860000), + SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), SPH_C32(0x1d3a76bf), + SPH_C32(0x1bb6813d) }, + { SPH_C32(0xd5dc0000), SPH_C32(0x28da0084), SPH_C32(0xdaa00000), + SPH_C32(0x7d240000), SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), + SPH_C32(0x87fef24b), SPH_C32(0x90daf380), SPH_C32(0x2eae0000), + SPH_C32(0x55c70048), SPH_C32(0x98ec0000), SPH_C32(0x9a980000), + SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), SPH_C32(0xa2806e7c), + SPH_C32(0x65c7dc2a) }, + { SPH_C32(0x818c0000), SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), + SPH_C32(0x173a0000), SPH_C32(0x64283db5), SPH_C32(0xea4c0898), + SPH_C32(0x3844ea88), SPH_C32(0xeeabae97), SPH_C32(0x92230000), + SPH_C32(0xa9fc0050), SPH_C32(0x816f0000), SPH_C32(0x4b930000), + SPH_C32(0x0db45b58), SPH_C32(0x1f5dd43d), SPH_C32(0xa292b44b), + SPH_C32(0x49fc8c64) }, + { SPH_C32(0xc6730000), SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), + SPH_C32(0x218d0000), SPH_C32(0x23111587), SPH_C32(0x7913512f), + SPH_C32(0x1d28ac88), SPH_C32(0x378dd173), SPH_C32(0xaf220000), + SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), SPH_C32(0x8da20000), + SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), SPH_C32(0x9ac484f4), + SPH_C32(0x8b6c72bd) }, + { SPH_C32(0x92230000), SPH_C32(0xa9fc0050), SPH_C32(0x816f0000), + SPH_C32(0x4b930000), SPH_C32(0x0db45b58), SPH_C32(0x1f5dd43d), + SPH_C32(0xa292b44b), SPH_C32(0x49fc8c64), SPH_C32(0x13af0000), + SPH_C32(0x87570088), SPH_C32(0x7e610000), SPH_C32(0x5ca90000), + SPH_C32(0x699c66ed), SPH_C32(0xf511dca5), SPH_C32(0x9ad65ec3), + SPH_C32(0xa75722f3) }, + { SPH_C32(0x7afe0000), SPH_C32(0x53b60014), SPH_C32(0xbd420000), + SPH_C32(0xf0860000), SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), + SPH_C32(0x1d3a76bf), SPH_C32(0x1bb6813d), SPH_C32(0x47ff0000), + SPH_C32(0x812600d4), SPH_C32(0x5bcf0000), SPH_C32(0x36b70000), + SPH_C32(0x47392832), SPH_C32(0x935f59b7), SPH_C32(0x256c4600), + SPH_C32(0xd9267fe4) }, + { SPH_C32(0x2eae0000), SPH_C32(0x55c70048), SPH_C32(0x98ec0000), + SPH_C32(0x9a980000), SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), + SPH_C32(0xa2806e7c), SPH_C32(0x65c7dc2a), SPH_C32(0xfb720000), + SPH_C32(0x7d1d00cc), SPH_C32(0x424c0000), SPH_C32(0xe7bc0000), + SPH_C32(0xe92150f6), SPH_C32(0xd1f9c1e1), SPH_C32(0x257e9c37), + SPH_C32(0xf51d2faa) }, + { SPH_C32(0xaf220000), SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), + SPH_C32(0x8da20000), SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), + SPH_C32(0x9ac484f4), SPH_C32(0x8b6c72bd), SPH_C32(0x69510000), + SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), SPH_C32(0xac2f0000), + SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), SPH_C32(0x87ec287c), + SPH_C32(0xbce1a3ce) }, + { SPH_C32(0xfb720000), SPH_C32(0x7d1d00cc), SPH_C32(0x424c0000), + SPH_C32(0xe7bc0000), SPH_C32(0xe92150f6), SPH_C32(0xd1f9c1e1), + SPH_C32(0x257e9c37), SPH_C32(0xf51d2faa), SPH_C32(0xd5dc0000), + SPH_C32(0x28da0084), SPH_C32(0xdaa00000), SPH_C32(0x7d240000), + SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), SPH_C32(0x87fef24b), + SPH_C32(0x90daf380) }, + { SPH_C32(0x13af0000), SPH_C32(0x87570088), SPH_C32(0x7e610000), + SPH_C32(0x5ca90000), SPH_C32(0x699c66ed), SPH_C32(0xf511dca5), + SPH_C32(0x9ad65ec3), SPH_C32(0xa75722f3), SPH_C32(0x818c0000), + SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), SPH_C32(0x173a0000), + SPH_C32(0x64283db5), SPH_C32(0xea4c0898), SPH_C32(0x3844ea88), + SPH_C32(0xeeabae97) }, + { SPH_C32(0x47ff0000), SPH_C32(0x812600d4), SPH_C32(0x5bcf0000), + SPH_C32(0x36b70000), SPH_C32(0x47392832), SPH_C32(0x935f59b7), + SPH_C32(0x256c4600), SPH_C32(0xd9267fe4), SPH_C32(0x3d010000), + SPH_C32(0xd29000c0), SPH_C32(0xe68d0000), SPH_C32(0xc6310000), + SPH_C32(0xca304571), SPH_C32(0xa8ea90ce), SPH_C32(0x385630bf), + SPH_C32(0xc290fed9) } +}; + +static const sph_u32 T512_28[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x86790000), SPH_C32(0x3f390002), SPH_C32(0xe19ae000), + SPH_C32(0x98560000), SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), + SPH_C32(0xd3dd4944), SPH_C32(0x161ddab9), SPH_C32(0x30b70000), + SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), SPH_C32(0x42c40000), + SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), SPH_C32(0x21afa1ea), + SPH_C32(0xb0a51834) }, + { SPH_C32(0x30b70000), SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), + SPH_C32(0x42c40000), SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), + SPH_C32(0x21afa1ea), SPH_C32(0xb0a51834), SPH_C32(0xb6ce0000), + SPH_C32(0xdae90002), SPH_C32(0x156e8000), SPH_C32(0xda920000), + SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), SPH_C32(0xf272e8ae), + SPH_C32(0xa6b8c28d) }, + { SPH_C32(0xb6ce0000), SPH_C32(0xdae90002), SPH_C32(0x156e8000), + SPH_C32(0xda920000), SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), + SPH_C32(0xf272e8ae), SPH_C32(0xa6b8c28d), SPH_C32(0x86790000), + SPH_C32(0x3f390002), SPH_C32(0xe19ae000), SPH_C32(0x98560000), + SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), SPH_C32(0xd3dd4944), + SPH_C32(0x161ddab9) }, + { SPH_C32(0x14190000), SPH_C32(0x23ca003c), SPH_C32(0x50df0000), + SPH_C32(0x44b60000), SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), + SPH_C32(0x61e610b0), SPH_C32(0xdbcadb80), SPH_C32(0xe3430000), + SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), SPH_C32(0xaa4e0000), + SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), SPH_C32(0x123db156), + SPH_C32(0x3a4e99d7) }, + { SPH_C32(0x92600000), SPH_C32(0x1cf3003e), SPH_C32(0xb145e000), + SPH_C32(0xdce00000), SPH_C32(0x8e0900be), SPH_C32(0x727b649f), + SPH_C32(0xb23b59f4), SPH_C32(0xcdd70139), SPH_C32(0xd3f40000), + SPH_C32(0xdf9e0014), SPH_C32(0x06326000), SPH_C32(0xe88a0000), + SPH_C32(0xb8a67fcc), SPH_C32(0x5dd12a75), SPH_C32(0x339210bc), + SPH_C32(0x8aeb81e3) }, + { SPH_C32(0x24ae0000), SPH_C32(0xc61a003c), SPH_C32(0xa42b6000), + SPH_C32(0x06720000), SPH_C32(0x78d45ada), SPH_C32(0x44493815), + SPH_C32(0x4049b15a), SPH_C32(0x6b6fc3b4), SPH_C32(0x558d0000), + SPH_C32(0xe0a70016), SPH_C32(0xe7a88000), SPH_C32(0x70dc0000), + SPH_C32(0x2dc318c2), SPH_C32(0x1359e29f), SPH_C32(0xe04f59f8), + SPH_C32(0x9cf65b5a) }, + { SPH_C32(0xa2d70000), SPH_C32(0xf923003e), SPH_C32(0x45b18000), + SPH_C32(0x9e240000), SPH_C32(0xedb13dd4), SPH_C32(0x0ac1f0ff), + SPH_C32(0x9394f81e), SPH_C32(0x7d72190d), SPH_C32(0x653a0000), + SPH_C32(0x05770016), SPH_C32(0x135ce000), SPH_C32(0x32180000), + SPH_C32(0x4e7b25a8), SPH_C32(0x6be376ff), SPH_C32(0xc1e0f812), + SPH_C32(0x2c53436e) }, + { SPH_C32(0xe3430000), SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), + SPH_C32(0xaa4e0000), SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), + SPH_C32(0x123db156), SPH_C32(0x3a4e99d7), SPH_C32(0xf75a0000), + SPH_C32(0x19840028), SPH_C32(0xa2190000), SPH_C32(0xeef80000), + SPH_C32(0xc0722516), SPH_C32(0x19981260), SPH_C32(0x73dba1e6), + SPH_C32(0xe1844257) }, + { SPH_C32(0x653a0000), SPH_C32(0x05770016), SPH_C32(0x135ce000), + SPH_C32(0x32180000), SPH_C32(0x4e7b25a8), SPH_C32(0x6be376ff), + SPH_C32(0xc1e0f812), SPH_C32(0x2c53436e), SPH_C32(0xc7ed0000), + SPH_C32(0xfc540028), SPH_C32(0x56ed6000), SPH_C32(0xac3c0000), + SPH_C32(0xa3ca187c), SPH_C32(0x61228600), SPH_C32(0x5274000c), + SPH_C32(0x51215a63) }, + { SPH_C32(0xd3f40000), SPH_C32(0xdf9e0014), SPH_C32(0x06326000), + SPH_C32(0xe88a0000), SPH_C32(0xb8a67fcc), SPH_C32(0x5dd12a75), + SPH_C32(0x339210bc), SPH_C32(0x8aeb81e3), SPH_C32(0x41940000), + SPH_C32(0xc36d002a), SPH_C32(0xb7778000), SPH_C32(0x346a0000), + SPH_C32(0x36af7f72), SPH_C32(0x2faa4eea), SPH_C32(0x81a94948), + SPH_C32(0x473c80da) }, + { SPH_C32(0x558d0000), SPH_C32(0xe0a70016), SPH_C32(0xe7a88000), + SPH_C32(0x70dc0000), SPH_C32(0x2dc318c2), SPH_C32(0x1359e29f), + SPH_C32(0xe04f59f8), SPH_C32(0x9cf65b5a), SPH_C32(0x71230000), + SPH_C32(0x26bd002a), SPH_C32(0x4383e000), SPH_C32(0x76ae0000), + SPH_C32(0x55174218), SPH_C32(0x5710da8a), SPH_C32(0xa006e8a2), + SPH_C32(0xf79998ee) }, + { SPH_C32(0xf75a0000), SPH_C32(0x19840028), SPH_C32(0xa2190000), + SPH_C32(0xeef80000), SPH_C32(0xc0722516), SPH_C32(0x19981260), + SPH_C32(0x73dba1e6), SPH_C32(0xe1844257), SPH_C32(0x14190000), + SPH_C32(0x23ca003c), SPH_C32(0x50df0000), SPH_C32(0x44b60000), + SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), SPH_C32(0x61e610b0), + SPH_C32(0xdbcadb80) }, + { SPH_C32(0x71230000), SPH_C32(0x26bd002a), SPH_C32(0x4383e000), + SPH_C32(0x76ae0000), SPH_C32(0x55174218), SPH_C32(0x5710da8a), + SPH_C32(0xa006e8a2), SPH_C32(0xf79998ee), SPH_C32(0x24ae0000), + SPH_C32(0xc61a003c), SPH_C32(0xa42b6000), SPH_C32(0x06720000), + SPH_C32(0x78d45ada), SPH_C32(0x44493815), SPH_C32(0x4049b15a), + SPH_C32(0x6b6fc3b4) }, + { SPH_C32(0xc7ed0000), SPH_C32(0xfc540028), SPH_C32(0x56ed6000), + SPH_C32(0xac3c0000), SPH_C32(0xa3ca187c), SPH_C32(0x61228600), + SPH_C32(0x5274000c), SPH_C32(0x51215a63), SPH_C32(0xa2d70000), + SPH_C32(0xf923003e), SPH_C32(0x45b18000), SPH_C32(0x9e240000), + SPH_C32(0xedb13dd4), SPH_C32(0x0ac1f0ff), SPH_C32(0x9394f81e), + SPH_C32(0x7d72190d) }, + { SPH_C32(0x41940000), SPH_C32(0xc36d002a), SPH_C32(0xb7778000), + SPH_C32(0x346a0000), SPH_C32(0x36af7f72), SPH_C32(0x2faa4eea), + SPH_C32(0x81a94948), SPH_C32(0x473c80da), SPH_C32(0x92600000), + SPH_C32(0x1cf3003e), SPH_C32(0xb145e000), SPH_C32(0xdce00000), + SPH_C32(0x8e0900be), SPH_C32(0x727b649f), SPH_C32(0xb23b59f4), + SPH_C32(0xcdd70139) } +}; + +static const sph_u32 T512_32[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xac480000), SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), + SPH_C32(0x03430000), SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), + SPH_C32(0xfe72c7fe), SPH_C32(0x91e478f6), SPH_C32(0x1e4e0000), + SPH_C32(0xdecf0000), SPH_C32(0x6df80180), SPH_C32(0x77240000), + SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), SPH_C32(0xcda31812), + SPH_C32(0x98aa496e) }, + { SPH_C32(0x1e4e0000), SPH_C32(0xdecf0000), SPH_C32(0x6df80180), + SPH_C32(0x77240000), SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), + SPH_C32(0xcda31812), SPH_C32(0x98aa496e), SPH_C32(0xb2060000), + SPH_C32(0xc5690000), SPH_C32(0x28031200), SPH_C32(0x74670000), + SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), SPH_C32(0x33d1dfec), + SPH_C32(0x094e3198) }, + { SPH_C32(0xb2060000), SPH_C32(0xc5690000), SPH_C32(0x28031200), + SPH_C32(0x74670000), SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), + SPH_C32(0x33d1dfec), SPH_C32(0x094e3198), SPH_C32(0xac480000), + SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), SPH_C32(0x03430000), + SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), SPH_C32(0xfe72c7fe), + SPH_C32(0x91e478f6) }, + { SPH_C32(0xaec30000), SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), + SPH_C32(0x2c150000), SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), + SPH_C32(0xab92f78f), SPH_C32(0xa312567b), SPH_C32(0xdb250000), + SPH_C32(0x09290000), SPH_C32(0x49aac000), SPH_C32(0x81e10000), + SPH_C32(0xcafe6b59), SPH_C32(0x42793431), SPH_C32(0x43566b76), + SPH_C32(0xe86cba2e) }, + { SPH_C32(0x028b0000), SPH_C32(0x87e90001), SPH_C32(0x3c2af380), + SPH_C32(0x2f560000), SPH_C32(0x1f4944d9), SPH_C32(0x79e2e780), + SPH_C32(0x55e03071), SPH_C32(0x32f62e8d), SPH_C32(0xc56b0000), + SPH_C32(0xd7e60000), SPH_C32(0x2452c180), SPH_C32(0xf6c50000), + SPH_C32(0x26b96cc7), SPH_C32(0xb6d95d7f), SPH_C32(0x8ef57364), + SPH_C32(0x70c6f340) }, + { SPH_C32(0xb08d0000), SPH_C32(0x42800001), SPH_C32(0x1429e180), + SPH_C32(0x5b310000), SPH_C32(0xa98b722d), SPH_C32(0x92f0de78), + SPH_C32(0x6631ef9d), SPH_C32(0x3bb81f15), SPH_C32(0x69230000), + SPH_C32(0xcc400000), SPH_C32(0x61a9d200), SPH_C32(0xf5860000), + SPH_C32(0x7c3c5dad), SPH_C32(0xa96b0dc9), SPH_C32(0x7087b49a), + SPH_C32(0xe1228bb6) }, + { SPH_C32(0x1cc50000), SPH_C32(0x59260001), SPH_C32(0x51d2f200), + SPH_C32(0x58720000), SPH_C32(0xf30e4347), SPH_C32(0x8d428ece), + SPH_C32(0x98432863), SPH_C32(0xaa5c67e3), SPH_C32(0x776d0000), + SPH_C32(0x128f0000), SPH_C32(0x0c51d380), SPH_C32(0x82a20000), + SPH_C32(0x907b5a33), SPH_C32(0x5dcb6487), SPH_C32(0xbd24ac88), + SPH_C32(0x7988c2d8) }, + { SPH_C32(0xdb250000), SPH_C32(0x09290000), SPH_C32(0x49aac000), + SPH_C32(0x81e10000), SPH_C32(0xcafe6b59), SPH_C32(0x42793431), + SPH_C32(0x43566b76), SPH_C32(0xe86cba2e), SPH_C32(0x75e60000), + SPH_C32(0x95660001), SPH_C32(0x307b2000), SPH_C32(0xadf40000), + SPH_C32(0x8f321eea), SPH_C32(0x24298307), SPH_C32(0xe8c49cf9), + SPH_C32(0x4b7eec55) }, + { SPH_C32(0x776d0000), SPH_C32(0x128f0000), SPH_C32(0x0c51d380), + SPH_C32(0x82a20000), SPH_C32(0x907b5a33), SPH_C32(0x5dcb6487), + SPH_C32(0xbd24ac88), SPH_C32(0x7988c2d8), SPH_C32(0x6ba80000), + SPH_C32(0x4ba90001), SPH_C32(0x5d832180), SPH_C32(0xdad00000), + SPH_C32(0x63751974), SPH_C32(0xd089ea49), SPH_C32(0x256784eb), + SPH_C32(0xd3d4a53b) }, + { SPH_C32(0xc56b0000), SPH_C32(0xd7e60000), SPH_C32(0x2452c180), + SPH_C32(0xf6c50000), SPH_C32(0x26b96cc7), SPH_C32(0xb6d95d7f), + SPH_C32(0x8ef57364), SPH_C32(0x70c6f340), SPH_C32(0xc7e00000), + SPH_C32(0x500f0001), SPH_C32(0x18783200), SPH_C32(0xd9930000), + SPH_C32(0x39f0281e), SPH_C32(0xcf3bbaff), SPH_C32(0xdb154315), + SPH_C32(0x4230ddcd) }, + { SPH_C32(0x69230000), SPH_C32(0xcc400000), SPH_C32(0x61a9d200), + SPH_C32(0xf5860000), SPH_C32(0x7c3c5dad), SPH_C32(0xa96b0dc9), + SPH_C32(0x7087b49a), SPH_C32(0xe1228bb6), SPH_C32(0xd9ae0000), + SPH_C32(0x8ec00001), SPH_C32(0x75803380), SPH_C32(0xaeb70000), + SPH_C32(0xd5b72f80), SPH_C32(0x3b9bd3b1), SPH_C32(0x16b65b07), + SPH_C32(0xda9a94a3) }, + { SPH_C32(0x75e60000), SPH_C32(0x95660001), SPH_C32(0x307b2000), + SPH_C32(0xadf40000), SPH_C32(0x8f321eea), SPH_C32(0x24298307), + SPH_C32(0xe8c49cf9), SPH_C32(0x4b7eec55), SPH_C32(0xaec30000), + SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), SPH_C32(0x2c150000), + SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), SPH_C32(0xab92f78f), + SPH_C32(0xa312567b) }, + { SPH_C32(0xd9ae0000), SPH_C32(0x8ec00001), SPH_C32(0x75803380), + SPH_C32(0xaeb70000), SPH_C32(0xd5b72f80), SPH_C32(0x3b9bd3b1), + SPH_C32(0x16b65b07), SPH_C32(0xda9a94a3), SPH_C32(0xb08d0000), + SPH_C32(0x42800001), SPH_C32(0x1429e180), SPH_C32(0x5b310000), + SPH_C32(0xa98b722d), SPH_C32(0x92f0de78), SPH_C32(0x6631ef9d), + SPH_C32(0x3bb81f15) }, + { SPH_C32(0x6ba80000), SPH_C32(0x4ba90001), SPH_C32(0x5d832180), + SPH_C32(0xdad00000), SPH_C32(0x63751974), SPH_C32(0xd089ea49), + SPH_C32(0x256784eb), SPH_C32(0xd3d4a53b), SPH_C32(0x1cc50000), + SPH_C32(0x59260001), SPH_C32(0x51d2f200), SPH_C32(0x58720000), + SPH_C32(0xf30e4347), SPH_C32(0x8d428ece), SPH_C32(0x98432863), + SPH_C32(0xaa5c67e3) }, + { SPH_C32(0xc7e00000), SPH_C32(0x500f0001), SPH_C32(0x18783200), + SPH_C32(0xd9930000), SPH_C32(0x39f0281e), SPH_C32(0xcf3bbaff), + SPH_C32(0xdb154315), SPH_C32(0x4230ddcd), SPH_C32(0x028b0000), + SPH_C32(0x87e90001), SPH_C32(0x3c2af380), SPH_C32(0x2f560000), + SPH_C32(0x1f4944d9), SPH_C32(0x79e2e780), SPH_C32(0x55e03071), + SPH_C32(0x32f62e8d) } +}; + +static const sph_u32 T512_36[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xcc140000), SPH_C32(0xa5630000), SPH_C32(0x5ab90780), + SPH_C32(0x3b500000), SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), + SPH_C32(0x694348c1), SPH_C32(0xca5a87fe), SPH_C32(0x819e0000), + SPH_C32(0xec570000), SPH_C32(0x66320280), SPH_C32(0x95f30000), + SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), SPH_C32(0xe65aa22d), + SPH_C32(0x8e67b7fa) }, + { SPH_C32(0x819e0000), SPH_C32(0xec570000), SPH_C32(0x66320280), + SPH_C32(0x95f30000), SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), + SPH_C32(0xe65aa22d), SPH_C32(0x8e67b7fa), SPH_C32(0x4d8a0000), + SPH_C32(0x49340000), SPH_C32(0x3c8b0500), SPH_C32(0xaea30000), + SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), SPH_C32(0x8f19eaec), + SPH_C32(0x443d3004) }, + { SPH_C32(0x4d8a0000), SPH_C32(0x49340000), SPH_C32(0x3c8b0500), + SPH_C32(0xaea30000), SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), + SPH_C32(0x8f19eaec), SPH_C32(0x443d3004), SPH_C32(0xcc140000), + SPH_C32(0xa5630000), SPH_C32(0x5ab90780), SPH_C32(0x3b500000), + SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), SPH_C32(0x694348c1), + SPH_C32(0xca5a87fe) }, + { SPH_C32(0x78230000), SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), + SPH_C32(0x90a50000), SPH_C32(0x713e2879), SPH_C32(0x7ee98924), + SPH_C32(0xf08ca062), SPH_C32(0x636f8bab), SPH_C32(0x02af0000), + SPH_C32(0xb7280000), SPH_C32(0xba1c0300), SPH_C32(0x56980000), + SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), SPH_C32(0xa95c149a), + SPH_C32(0xf4f6ea7b) }, + { SPH_C32(0xb4370000), SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), + SPH_C32(0xabf50000), SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), + SPH_C32(0x99cfe8a3), SPH_C32(0xa9350c55), SPH_C32(0x83310000), + SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), SPH_C32(0xc36b0000), + SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), SPH_C32(0x4f06b6b7), + SPH_C32(0x7a915d81) }, + { SPH_C32(0xf9bd0000), SPH_C32(0xfeab0000), SPH_C32(0xcf080900), + SPH_C32(0x05560000), SPH_C32(0x2c97007b), SPH_C32(0x361db598), + SPH_C32(0x16d6024f), SPH_C32(0xed083c51), SPH_C32(0x4f250000), + SPH_C32(0xfe1c0000), SPH_C32(0x86970600), SPH_C32(0xf83b0000), + SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), SPH_C32(0x2645fe76), + SPH_C32(0xb0cbda7f) }, + { SPH_C32(0x35a90000), SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), + SPH_C32(0x3e060000), SPH_C32(0x67471384), SPH_C32(0xb1868180), + SPH_C32(0x7f954a8e), SPH_C32(0x2752bbaf), SPH_C32(0xcebb0000), + SPH_C32(0x124b0000), SPH_C32(0xe0a50480), SPH_C32(0x6dc80000), + SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), SPH_C32(0xc01f5c5b), + SPH_C32(0x3eac6d85) }, + { SPH_C32(0x02af0000), SPH_C32(0xb7280000), SPH_C32(0xba1c0300), + SPH_C32(0x56980000), SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), + SPH_C32(0xa95c149a), SPH_C32(0xf4f6ea7b), SPH_C32(0x7a8c0000), + SPH_C32(0xa5d40000), SPH_C32(0x13260880), SPH_C32(0xc63d0000), + SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), SPH_C32(0x59d0b4f8), + SPH_C32(0x979961d0) }, + { SPH_C32(0xcebb0000), SPH_C32(0x124b0000), SPH_C32(0xe0a50480), + SPH_C32(0x6dc80000), SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), + SPH_C32(0xc01f5c5b), SPH_C32(0x3eac6d85), SPH_C32(0xfb120000), + SPH_C32(0x49830000), SPH_C32(0x75140a00), SPH_C32(0x53ce0000), + SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), SPH_C32(0xbf8a16d5), + SPH_C32(0x19fed62a) }, + { SPH_C32(0x83310000), SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), + SPH_C32(0xc36b0000), SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), + SPH_C32(0x4f06b6b7), SPH_C32(0x7a915d81), SPH_C32(0x37060000), + SPH_C32(0xece00000), SPH_C32(0x2fad0d80), SPH_C32(0x689e0000), + SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), SPH_C32(0xd6c95e14), + SPH_C32(0xd3a451d4) }, + { SPH_C32(0x4f250000), SPH_C32(0xfe1c0000), SPH_C32(0x86970600), + SPH_C32(0xf83b0000), SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), + SPH_C32(0x2645fe76), SPH_C32(0xb0cbda7f), SPH_C32(0xb6980000), + SPH_C32(0x00b70000), SPH_C32(0x499f0f00), SPH_C32(0xfd6d0000), + SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), SPH_C32(0x3093fc39), + SPH_C32(0x5dc3e62e) }, + { SPH_C32(0x7a8c0000), SPH_C32(0xa5d40000), SPH_C32(0x13260880), + SPH_C32(0xc63d0000), SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), + SPH_C32(0x59d0b4f8), SPH_C32(0x979961d0), SPH_C32(0x78230000), + SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), SPH_C32(0x90a50000), + SPH_C32(0x713e2879), SPH_C32(0x7ee98924), SPH_C32(0xf08ca062), + SPH_C32(0x636f8bab) }, + { SPH_C32(0xb6980000), SPH_C32(0x00b70000), SPH_C32(0x499f0f00), + SPH_C32(0xfd6d0000), SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), + SPH_C32(0x3093fc39), SPH_C32(0x5dc3e62e), SPH_C32(0xf9bd0000), + SPH_C32(0xfeab0000), SPH_C32(0xcf080900), SPH_C32(0x05560000), + SPH_C32(0x2c97007b), SPH_C32(0x361db598), SPH_C32(0x16d6024f), + SPH_C32(0xed083c51) }, + { SPH_C32(0xfb120000), SPH_C32(0x49830000), SPH_C32(0x75140a00), + SPH_C32(0x53ce0000), SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), + SPH_C32(0xbf8a16d5), SPH_C32(0x19fed62a), SPH_C32(0x35a90000), + SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), SPH_C32(0x3e060000), + SPH_C32(0x67471384), SPH_C32(0xb1868180), SPH_C32(0x7f954a8e), + SPH_C32(0x2752bbaf) }, + { SPH_C32(0x37060000), SPH_C32(0xece00000), SPH_C32(0x2fad0d80), + SPH_C32(0x689e0000), SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), + SPH_C32(0xd6c95e14), SPH_C32(0xd3a451d4), SPH_C32(0xb4370000), + SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), SPH_C32(0xabf50000), + SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), SPH_C32(0x99cfe8a3), + SPH_C32(0xa9350c55) } +}; + +static const sph_u32 T512_40[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x88980000), SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), + SPH_C32(0xfb4e0000), SPH_C32(0xf158079a), SPH_C32(0x61ae9167), + SPH_C32(0xa895706c), SPH_C32(0xe6107494), SPH_C32(0x0bc20000), + SPH_C32(0xdb630000), SPH_C32(0x7e88000c), SPH_C32(0x15860000), + SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), SPH_C32(0xf460449e), + SPH_C32(0xd8b61463) }, + { SPH_C32(0x0bc20000), SPH_C32(0xdb630000), SPH_C32(0x7e88000c), + SPH_C32(0x15860000), SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), + SPH_C32(0xf460449e), SPH_C32(0xd8b61463), SPH_C32(0x835a0000), + SPH_C32(0xc4f70000), SPH_C32(0x01470022), SPH_C32(0xeec80000), + SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), SPH_C32(0x5cf534f2), + SPH_C32(0x3ea660f7) }, + { SPH_C32(0x835a0000), SPH_C32(0xc4f70000), SPH_C32(0x01470022), + SPH_C32(0xeec80000), SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), + SPH_C32(0x5cf534f2), SPH_C32(0x3ea660f7), SPH_C32(0x88980000), + SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), SPH_C32(0xfb4e0000), + SPH_C32(0xf158079a), SPH_C32(0x61ae9167), SPH_C32(0xa895706c), + SPH_C32(0xe6107494) }, + { SPH_C32(0x52500000), SPH_C32(0x29540000), SPH_C32(0x6a61004e), + SPH_C32(0xf0ff0000), SPH_C32(0x9a317eec), SPH_C32(0x452341ce), + SPH_C32(0xcf568fe5), SPH_C32(0x5303130f), SPH_C32(0x538d0000), + SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), SPH_C32(0x56ff0000), + SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), SPH_C32(0xa9444018), + SPH_C32(0x7f975691) }, + { SPH_C32(0xdac80000), SPH_C32(0x36c00000), SPH_C32(0x15ae0060), + SPH_C32(0x0bb10000), SPH_C32(0x6b697976), SPH_C32(0x248dd0a9), + SPH_C32(0x67c3ff89), SPH_C32(0xb513679b), SPH_C32(0x584f0000), + SPH_C32(0x729f0000), SPH_C32(0xe07f000a), SPH_C32(0x43790000), + SPH_C32(0x9b1948bd), SPH_C32(0xe74476ba), SPH_C32(0x5d240486), + SPH_C32(0xa72142f2) }, + { SPH_C32(0x59920000), SPH_C32(0xf2370000), SPH_C32(0x14e90042), + SPH_C32(0xe5790000), SPH_C32(0x0bcc361f), SPH_C32(0x30a2fa8d), + SPH_C32(0x3b36cb7b), SPH_C32(0x8bb5076c), SPH_C32(0xd0d70000), + SPH_C32(0x6d0b0000), SPH_C32(0x9fb00024), SPH_C32(0xb8370000), + SPH_C32(0x6a414f27), SPH_C32(0x86eae7dd), SPH_C32(0xf5b174ea), + SPH_C32(0x41313666) }, + { SPH_C32(0xd10a0000), SPH_C32(0xeda30000), SPH_C32(0x6b26006c), + SPH_C32(0x1e370000), SPH_C32(0xfa943185), SPH_C32(0x510c6bea), + SPH_C32(0x93a3bb17), SPH_C32(0x6da573f8), SPH_C32(0xdb150000), + SPH_C32(0xb6680000), SPH_C32(0xe1380028), SPH_C32(0xadb10000), + SPH_C32(0xfbbc07d4), SPH_C32(0xf36b5c9e), SPH_C32(0x01d13074), + SPH_C32(0x99872205) }, + { SPH_C32(0x538d0000), SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), + SPH_C32(0x56ff0000), SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), + SPH_C32(0xa9444018), SPH_C32(0x7f975691), SPH_C32(0x01dd0000), + SPH_C32(0x80a80000), SPH_C32(0xf4960048), SPH_C32(0xa6000000), + SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), SPH_C32(0x6612cffd), + SPH_C32(0x2c94459e) }, + { SPH_C32(0xdb150000), SPH_C32(0xb6680000), SPH_C32(0xe1380028), + SPH_C32(0xadb10000), SPH_C32(0xfbbc07d4), SPH_C32(0xf36b5c9e), + SPH_C32(0x01d13074), SPH_C32(0x99872205), SPH_C32(0x0a1f0000), + SPH_C32(0x5bcb0000), SPH_C32(0x8a1e0044), SPH_C32(0xb3860000), + SPH_C32(0x01283651), SPH_C32(0xa2673774), SPH_C32(0x92728b63), + SPH_C32(0xf42251fd) }, + { SPH_C32(0x584f0000), SPH_C32(0x729f0000), SPH_C32(0xe07f000a), + SPH_C32(0x43790000), SPH_C32(0x9b1948bd), SPH_C32(0xe74476ba), + SPH_C32(0x5d240486), SPH_C32(0xa72142f2), SPH_C32(0x82870000), + SPH_C32(0x445f0000), SPH_C32(0xf5d1006a), SPH_C32(0x48c80000), + SPH_C32(0xf07031cb), SPH_C32(0xc3c9a613), SPH_C32(0x3ae7fb0f), + SPH_C32(0x12322569) }, + { SPH_C32(0xd0d70000), SPH_C32(0x6d0b0000), SPH_C32(0x9fb00024), + SPH_C32(0xb8370000), SPH_C32(0x6a414f27), SPH_C32(0x86eae7dd), + SPH_C32(0xf5b174ea), SPH_C32(0x41313666), SPH_C32(0x89450000), + SPH_C32(0x9f3c0000), SPH_C32(0x8b590066), SPH_C32(0x5d4e0000), + SPH_C32(0x618d7938), SPH_C32(0xb6481d50), SPH_C32(0xce87bf91), + SPH_C32(0xca84310a) }, + { SPH_C32(0x01dd0000), SPH_C32(0x80a80000), SPH_C32(0xf4960048), + SPH_C32(0xa6000000), SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), + SPH_C32(0x6612cffd), SPH_C32(0x2c94459e), SPH_C32(0x52500000), + SPH_C32(0x29540000), SPH_C32(0x6a61004e), SPH_C32(0xf0ff0000), + SPH_C32(0x9a317eec), SPH_C32(0x452341ce), SPH_C32(0xcf568fe5), + SPH_C32(0x5303130f) }, + { SPH_C32(0x89450000), SPH_C32(0x9f3c0000), SPH_C32(0x8b590066), + SPH_C32(0x5d4e0000), SPH_C32(0x618d7938), SPH_C32(0xb6481d50), + SPH_C32(0xce87bf91), SPH_C32(0xca84310a), SPH_C32(0x59920000), + SPH_C32(0xf2370000), SPH_C32(0x14e90042), SPH_C32(0xe5790000), + SPH_C32(0x0bcc361f), SPH_C32(0x30a2fa8d), SPH_C32(0x3b36cb7b), + SPH_C32(0x8bb5076c) }, + { SPH_C32(0x0a1f0000), SPH_C32(0x5bcb0000), SPH_C32(0x8a1e0044), + SPH_C32(0xb3860000), SPH_C32(0x01283651), SPH_C32(0xa2673774), + SPH_C32(0x92728b63), SPH_C32(0xf42251fd), SPH_C32(0xd10a0000), + SPH_C32(0xeda30000), SPH_C32(0x6b26006c), SPH_C32(0x1e370000), + SPH_C32(0xfa943185), SPH_C32(0x510c6bea), SPH_C32(0x93a3bb17), + SPH_C32(0x6da573f8) }, + { SPH_C32(0x82870000), SPH_C32(0x445f0000), SPH_C32(0xf5d1006a), + SPH_C32(0x48c80000), SPH_C32(0xf07031cb), SPH_C32(0xc3c9a613), + SPH_C32(0x3ae7fb0f), SPH_C32(0x12322569), SPH_C32(0xdac80000), + SPH_C32(0x36c00000), SPH_C32(0x15ae0060), SPH_C32(0x0bb10000), + SPH_C32(0x6b697976), SPH_C32(0x248dd0a9), SPH_C32(0x67c3ff89), + SPH_C32(0xb513679b) } +}; + +static const sph_u32 T512_44[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x58430000), SPH_C32(0x807e0000), SPH_C32(0x78330001), + SPH_C32(0xc66b3800), SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), + SPH_C32(0xac73fe6f), SPH_C32(0x3a4479b1), SPH_C32(0x1d5a0000), + SPH_C32(0x2b720000), SPH_C32(0x488d0000), SPH_C32(0xaf611800), + SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), SPH_C32(0x81a20429), + SPH_C32(0x1e7536a6) }, + { SPH_C32(0x1d5a0000), SPH_C32(0x2b720000), SPH_C32(0x488d0000), + SPH_C32(0xaf611800), SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), + SPH_C32(0x81a20429), SPH_C32(0x1e7536a6), SPH_C32(0x45190000), + SPH_C32(0xab0c0000), SPH_C32(0x30be0001), SPH_C32(0x690a2000), + SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), SPH_C32(0x2dd1fa46), + SPH_C32(0x24314f17) }, + { SPH_C32(0x45190000), SPH_C32(0xab0c0000), SPH_C32(0x30be0001), + SPH_C32(0x690a2000), SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), + SPH_C32(0x2dd1fa46), SPH_C32(0x24314f17), SPH_C32(0x58430000), + SPH_C32(0x807e0000), SPH_C32(0x78330001), SPH_C32(0xc66b3800), + SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), SPH_C32(0xac73fe6f), + SPH_C32(0x3a4479b1) }, + { SPH_C32(0xa53b0000), SPH_C32(0x14260000), SPH_C32(0x4e30001e), + SPH_C32(0x7cae0000), SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), + SPH_C32(0xf73168d8), SPH_C32(0x0b1b4946), SPH_C32(0x07ed0000), + SPH_C32(0xb2500000), SPH_C32(0x8774000a), SPH_C32(0x970d0000), + SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), SPH_C32(0xf4786222), + SPH_C32(0x9075b1ce) }, + { SPH_C32(0xfd780000), SPH_C32(0x94580000), SPH_C32(0x3603001f), + SPH_C32(0xbac53800), SPH_C32(0x68a95109), SPH_C32(0x017295e0), + SPH_C32(0x5b4296b7), SPH_C32(0x315f30f7), SPH_C32(0x1ab70000), + SPH_C32(0x99220000), SPH_C32(0xcff9000a), SPH_C32(0x386c1800), + SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), SPH_C32(0x75da660b), + SPH_C32(0x8e008768) }, + { SPH_C32(0xb8610000), SPH_C32(0x3f540000), SPH_C32(0x06bd001e), + SPH_C32(0xd3cf1800), SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), + SPH_C32(0x76936cf1), SPH_C32(0x156e7fe0), SPH_C32(0x42f40000), + SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), SPH_C32(0xfe072000), + SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), SPH_C32(0xd9a99864), + SPH_C32(0xb444fed9) }, + { SPH_C32(0xe0220000), SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), + SPH_C32(0x15a42000), SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), + SPH_C32(0xdae0929e), SPH_C32(0x2f2a0651), SPH_C32(0x5fae0000), + SPH_C32(0x322e0000), SPH_C32(0xff47000b), SPH_C32(0x51663800), + SPH_C32(0xa4457f72), SPH_C32(0x316a5179), SPH_C32(0x580b9c4d), + SPH_C32(0xaa31c87f) }, + { SPH_C32(0x07ed0000), SPH_C32(0xb2500000), SPH_C32(0x8774000a), + SPH_C32(0x970d0000), SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), + SPH_C32(0xf4786222), SPH_C32(0x9075b1ce), SPH_C32(0xa2d60000), + SPH_C32(0xa6760000), SPH_C32(0xc9440014), SPH_C32(0xeba30000), + SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), SPH_C32(0x03490afa), + SPH_C32(0x9b6ef888) }, + { SPH_C32(0x5fae0000), SPH_C32(0x322e0000), SPH_C32(0xff47000b), + SPH_C32(0x51663800), SPH_C32(0xa4457f72), SPH_C32(0x316a5179), + SPH_C32(0x580b9c4d), SPH_C32(0xaa31c87f), SPH_C32(0xbf8c0000), + SPH_C32(0x8d040000), SPH_C32(0x81c90014), SPH_C32(0x44c21800), + SPH_C32(0xe92700be), SPH_C32(0xf8617b49), SPH_C32(0x82eb0ed3), + SPH_C32(0x851bce2e) }, + { SPH_C32(0x1ab70000), SPH_C32(0x99220000), SPH_C32(0xcff9000a), + SPH_C32(0x386c1800), SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), + SPH_C32(0x75da660b), SPH_C32(0x8e008768), SPH_C32(0xe7cf0000), + SPH_C32(0x0d7a0000), SPH_C32(0xf9fa0015), SPH_C32(0x82a92000), + SPH_C32(0x0e105c62), SPH_C32(0x81cc4494), SPH_C32(0x2e98f0bc), + SPH_C32(0xbf5fb79f) }, + { SPH_C32(0x42f40000), SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), + SPH_C32(0xfe072000), SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), + SPH_C32(0xd9a99864), SPH_C32(0xb444fed9), SPH_C32(0xfa950000), + SPH_C32(0x26080000), SPH_C32(0xb1770015), SPH_C32(0x2dc83800), + SPH_C32(0x2bdb72a7), SPH_C32(0x49b5fb44), SPH_C32(0xaf3af495), + SPH_C32(0xa12a8139) }, + { SPH_C32(0xa2d60000), SPH_C32(0xa6760000), SPH_C32(0xc9440014), + SPH_C32(0xeba30000), SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), + SPH_C32(0x03490afa), SPH_C32(0x9b6ef888), SPH_C32(0xa53b0000), + SPH_C32(0x14260000), SPH_C32(0x4e30001e), SPH_C32(0x7cae0000), + SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), SPH_C32(0xf73168d8), + SPH_C32(0x0b1b4946) }, + { SPH_C32(0xfa950000), SPH_C32(0x26080000), SPH_C32(0xb1770015), + SPH_C32(0x2dc83800), SPH_C32(0x2bdb72a7), SPH_C32(0x49b5fb44), + SPH_C32(0xaf3af495), SPH_C32(0xa12a8139), SPH_C32(0xb8610000), + SPH_C32(0x3f540000), SPH_C32(0x06bd001e), SPH_C32(0xd3cf1800), + SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), SPH_C32(0x76936cf1), + SPH_C32(0x156e7fe0) }, + { SPH_C32(0xbf8c0000), SPH_C32(0x8d040000), SPH_C32(0x81c90014), + SPH_C32(0x44c21800), SPH_C32(0xe92700be), SPH_C32(0xf8617b49), + SPH_C32(0x82eb0ed3), SPH_C32(0x851bce2e), SPH_C32(0xe0220000), + SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), SPH_C32(0x15a42000), + SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), SPH_C32(0xdae0929e), + SPH_C32(0x2f2a0651) }, + { SPH_C32(0xe7cf0000), SPH_C32(0x0d7a0000), SPH_C32(0xf9fa0015), + SPH_C32(0x82a92000), SPH_C32(0x0e105c62), SPH_C32(0x81cc4494), + SPH_C32(0x2e98f0bc), SPH_C32(0xbf5fb79f), SPH_C32(0xfd780000), + SPH_C32(0x94580000), SPH_C32(0x3603001f), SPH_C32(0xbac53800), + SPH_C32(0x68a95109), SPH_C32(0x017295e0), SPH_C32(0x5b4296b7), + SPH_C32(0x315f30f7) } +}; + +static const sph_u32 T512_48[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x02f20000), SPH_C32(0xa2810000), SPH_C32(0x873f0000), + SPH_C32(0xe36c7800), SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), + SPH_C32(0xc4c23237), SPH_C32(0x7f32259e), SPH_C32(0xbadd0000), + SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), SPH_C32(0xf7282800), + SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), SPH_C32(0xea5a8d14), + SPH_C32(0x2a2c18f0) }, + { SPH_C32(0xbadd0000), SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), + SPH_C32(0xf7282800), SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), + SPH_C32(0xea5a8d14), SPH_C32(0x2a2c18f0), SPH_C32(0xb82f0000), + SPH_C32(0xb12c0000), SPH_C32(0x30d80000), SPH_C32(0x14445000), + SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), SPH_C32(0x2e98bf23), + SPH_C32(0x551e3d6e) }, + { SPH_C32(0xb82f0000), SPH_C32(0xb12c0000), SPH_C32(0x30d80000), + SPH_C32(0x14445000), SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), + SPH_C32(0x2e98bf23), SPH_C32(0x551e3d6e), SPH_C32(0x02f20000), + SPH_C32(0xa2810000), SPH_C32(0x873f0000), SPH_C32(0xe36c7800), + SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), SPH_C32(0xc4c23237), + SPH_C32(0x7f32259e) }, + { SPH_C32(0x1e6c0000), SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), + SPH_C32(0xbcb6b800), SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), + SPH_C32(0x6a0c1bc8), SPH_C32(0xb99dc2eb), SPH_C32(0x92560000), + SPH_C32(0x1eda0000), SPH_C32(0xea510000), SPH_C32(0xe8b13000), + SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), SPH_C32(0xb15c2254), + SPH_C32(0x33c5244f) }, + { SPH_C32(0x1c9e0000), SPH_C32(0x66c30000), SPH_C32(0x0d110000), + SPH_C32(0x5fdac000), SPH_C32(0x32596759), SPH_C32(0x8cc0f80c), + SPH_C32(0xaece29ff), SPH_C32(0xc6afe775), SPH_C32(0x288b0000), + SPH_C32(0x0d770000), SPH_C32(0x5db60000), SPH_C32(0x1f991800), + SPH_C32(0x767042e8), SPH_C32(0xdde1a2a3), SPH_C32(0x5b06af40), + SPH_C32(0x19e93cbf) }, + { SPH_C32(0xa4b10000), SPH_C32(0xd7ef0000), SPH_C32(0x3dc90000), + SPH_C32(0x4b9e9000), SPH_C32(0xf30107fb), SPH_C32(0xbde710e0), + SPH_C32(0x805696dc), SPH_C32(0x93b1da1b), SPH_C32(0x2a790000), + SPH_C32(0xaff60000), SPH_C32(0xda890000), SPH_C32(0xfcf56000), + SPH_C32(0x686d3607), SPH_C32(0xdadc8975), SPH_C32(0x9fc49d77), + SPH_C32(0x66db1921) }, + { SPH_C32(0xa6430000), SPH_C32(0x756e0000), SPH_C32(0xbaf60000), + SPH_C32(0xa8f2e800), SPH_C32(0xed1c7314), SPH_C32(0xbada3b36), + SPH_C32(0x4494a4eb), SPH_C32(0xec83ff85), SPH_C32(0x90a40000), + SPH_C32(0xbc5b0000), SPH_C32(0x6d6e0000), SPH_C32(0x0bdd4800), + SPH_C32(0xb728224a), SPH_C32(0xecc64a4f), SPH_C32(0x759e1063), + SPH_C32(0x4cf701d1) }, + { SPH_C32(0x92560000), SPH_C32(0x1eda0000), SPH_C32(0xea510000), + SPH_C32(0xe8b13000), SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), + SPH_C32(0xb15c2254), SPH_C32(0x33c5244f), SPH_C32(0x8c3a0000), + SPH_C32(0xda980000), SPH_C32(0x607f0000), SPH_C32(0x54078800), + SPH_C32(0x85714513), SPH_C32(0x6006b243), SPH_C32(0xdb50399c), + SPH_C32(0x8a58e6a4) }, + { SPH_C32(0x90a40000), SPH_C32(0xbc5b0000), SPH_C32(0x6d6e0000), + SPH_C32(0x0bdd4800), SPH_C32(0xb728224a), SPH_C32(0xecc64a4f), + SPH_C32(0x759e1063), SPH_C32(0x4cf701d1), SPH_C32(0x36e70000), + SPH_C32(0xc9350000), SPH_C32(0xd7980000), SPH_C32(0xa32fa000), + SPH_C32(0x5a34515e), SPH_C32(0x561c7179), SPH_C32(0x310ab488), + SPH_C32(0xa074fe54) }, + { SPH_C32(0x288b0000), SPH_C32(0x0d770000), SPH_C32(0x5db60000), + SPH_C32(0x1f991800), SPH_C32(0x767042e8), SPH_C32(0xdde1a2a3), + SPH_C32(0x5b06af40), SPH_C32(0x19e93cbf), SPH_C32(0x34150000), + SPH_C32(0x6bb40000), SPH_C32(0x50a70000), SPH_C32(0x4043d800), + SPH_C32(0x442925b1), SPH_C32(0x51215aaf), SPH_C32(0xf5c886bf), + SPH_C32(0xdf46dbca) }, + { SPH_C32(0x2a790000), SPH_C32(0xaff60000), SPH_C32(0xda890000), + SPH_C32(0xfcf56000), SPH_C32(0x686d3607), SPH_C32(0xdadc8975), + SPH_C32(0x9fc49d77), SPH_C32(0x66db1921), SPH_C32(0x8ec80000), + SPH_C32(0x78190000), SPH_C32(0xe7400000), SPH_C32(0xb76bf000), + SPH_C32(0x9b6c31fc), SPH_C32(0x673b9995), SPH_C32(0x1f920bab), + SPH_C32(0xf56ac33a) }, + { SPH_C32(0x8c3a0000), SPH_C32(0xda980000), SPH_C32(0x607f0000), + SPH_C32(0x54078800), SPH_C32(0x85714513), SPH_C32(0x6006b243), + SPH_C32(0xdb50399c), SPH_C32(0x8a58e6a4), SPH_C32(0x1e6c0000), + SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), SPH_C32(0xbcb6b800), + SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), SPH_C32(0x6a0c1bc8), + SPH_C32(0xb99dc2eb) }, + { SPH_C32(0x8ec80000), SPH_C32(0x78190000), SPH_C32(0xe7400000), + SPH_C32(0xb76bf000), SPH_C32(0x9b6c31fc), SPH_C32(0x673b9995), + SPH_C32(0x1f920bab), SPH_C32(0xf56ac33a), SPH_C32(0xa4b10000), + SPH_C32(0xd7ef0000), SPH_C32(0x3dc90000), SPH_C32(0x4b9e9000), + SPH_C32(0xf30107fb), SPH_C32(0xbde710e0), SPH_C32(0x805696dc), + SPH_C32(0x93b1da1b) }, + { SPH_C32(0x36e70000), SPH_C32(0xc9350000), SPH_C32(0xd7980000), + SPH_C32(0xa32fa000), SPH_C32(0x5a34515e), SPH_C32(0x561c7179), + SPH_C32(0x310ab488), SPH_C32(0xa074fe54), SPH_C32(0xa6430000), + SPH_C32(0x756e0000), SPH_C32(0xbaf60000), SPH_C32(0xa8f2e800), + SPH_C32(0xed1c7314), SPH_C32(0xbada3b36), SPH_C32(0x4494a4eb), + SPH_C32(0xec83ff85) }, + { SPH_C32(0x34150000), SPH_C32(0x6bb40000), SPH_C32(0x50a70000), + SPH_C32(0x4043d800), SPH_C32(0x442925b1), SPH_C32(0x51215aaf), + SPH_C32(0xf5c886bf), SPH_C32(0xdf46dbca), SPH_C32(0x1c9e0000), + SPH_C32(0x66c30000), SPH_C32(0x0d110000), SPH_C32(0x5fdac000), + SPH_C32(0x32596759), SPH_C32(0x8cc0f80c), SPH_C32(0xaece29ff), + SPH_C32(0xc6afe775) } +}; + +static const sph_u32 T512_52[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xe6280000), SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), + SPH_C32(0xd3d002e0), SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), + SPH_C32(0x289506b4), SPH_C32(0xd75a4897), SPH_C32(0xf0c50000), + SPH_C32(0x59230000), SPH_C32(0x45820000), SPH_C32(0xe18d00c0), + SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), SPH_C32(0xcbe0fe1c), + SPH_C32(0x56a7b19f) }, + { SPH_C32(0xf0c50000), SPH_C32(0x59230000), SPH_C32(0x45820000), + SPH_C32(0xe18d00c0), SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), + SPH_C32(0xcbe0fe1c), SPH_C32(0x56a7b19f), SPH_C32(0x16ed0000), + SPH_C32(0x15680000), SPH_C32(0xedd70000), SPH_C32(0x325d0220), + SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), SPH_C32(0xe375f8a8), + SPH_C32(0x81fdf908) }, + { SPH_C32(0x16ed0000), SPH_C32(0x15680000), SPH_C32(0xedd70000), + SPH_C32(0x325d0220), SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), + SPH_C32(0xe375f8a8), SPH_C32(0x81fdf908), SPH_C32(0xe6280000), + SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), SPH_C32(0xd3d002e0), + SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), SPH_C32(0x289506b4), + SPH_C32(0xd75a4897) }, + { SPH_C32(0xb4310000), SPH_C32(0x77330000), SPH_C32(0xb15d0000), + SPH_C32(0x7fd004e0), SPH_C32(0x78a26138), SPH_C32(0xd116c35d), + SPH_C32(0xd256d489), SPH_C32(0x4e6f74de), SPH_C32(0xe3060000), + SPH_C32(0xbdc10000), SPH_C32(0x87130000), SPH_C32(0xbff20060), + SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), SPH_C32(0x73c5ab06), + SPH_C32(0x5bd61539) }, + { SPH_C32(0x52190000), SPH_C32(0x3b780000), SPH_C32(0x19080000), + SPH_C32(0xac000600), SPH_C32(0xa0c35180), SPH_C32(0x49b17387), + SPH_C32(0xfac3d23d), SPH_C32(0x99353c49), SPH_C32(0x13c30000), + SPH_C32(0xe4e20000), SPH_C32(0xc2910000), SPH_C32(0x5e7f00a0), + SPH_C32(0x15d70c2b), SPH_C32(0x4f5861c8), SPH_C32(0xb825551a), + SPH_C32(0x0d71a4a6) }, + { SPH_C32(0x44f40000), SPH_C32(0x2e100000), SPH_C32(0xf4df0000), + SPH_C32(0x9e5d0420), SPH_C32(0x43cf6709), SPH_C32(0x13fb95c4), + SPH_C32(0x19b62a95), SPH_C32(0x18c8c541), SPH_C32(0xf5eb0000), + SPH_C32(0xa8a90000), SPH_C32(0x6ac40000), SPH_C32(0x8daf0240), + SPH_C32(0xcdb63c93), SPH_C32(0xd7ffd112), SPH_C32(0x90b053ae), + SPH_C32(0xda2bec31) }, + { SPH_C32(0xa2dc0000), SPH_C32(0x625b0000), SPH_C32(0x5c8a0000), + SPH_C32(0x4d8d06c0), SPH_C32(0x9bae57b1), SPH_C32(0x8b5c251e), + SPH_C32(0x31232c21), SPH_C32(0xcf928dd6), SPH_C32(0x052e0000), + SPH_C32(0xf18a0000), SPH_C32(0x2f460000), SPH_C32(0x6c220280), + SPH_C32(0xf6db3aa2), SPH_C32(0x1512878b), SPH_C32(0x5b50adb2), + SPH_C32(0x8c8c5dae) }, + { SPH_C32(0xe3060000), SPH_C32(0xbdc10000), SPH_C32(0x87130000), + SPH_C32(0xbff20060), SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), + SPH_C32(0x73c5ab06), SPH_C32(0x5bd61539), SPH_C32(0x57370000), + SPH_C32(0xcaf20000), SPH_C32(0x364e0000), SPH_C32(0xc0220480), + SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), SPH_C32(0xa1937f8f), + SPH_C32(0x15b961e7) }, + { SPH_C32(0x052e0000), SPH_C32(0xf18a0000), SPH_C32(0x2f460000), + SPH_C32(0x6c220280), SPH_C32(0xf6db3aa2), SPH_C32(0x1512878b), + SPH_C32(0x5b50adb2), SPH_C32(0x8c8c5dae), SPH_C32(0xa7f20000), + SPH_C32(0x93d10000), SPH_C32(0x73cc0000), SPH_C32(0x21af0440), + SPH_C32(0x6d756d13), SPH_C32(0x9e4ea295), SPH_C32(0x6a738193), + SPH_C32(0x431ed078) }, + { SPH_C32(0x13c30000), SPH_C32(0xe4e20000), SPH_C32(0xc2910000), + SPH_C32(0x5e7f00a0), SPH_C32(0x15d70c2b), SPH_C32(0x4f5861c8), + SPH_C32(0xb825551a), SPH_C32(0x0d71a4a6), SPH_C32(0x41da0000), + SPH_C32(0xdf9a0000), SPH_C32(0xdb990000), SPH_C32(0xf27f06a0), + SPH_C32(0xb5145dab), SPH_C32(0x06e9124f), SPH_C32(0x42e68727), + SPH_C32(0x944498ef) }, + { SPH_C32(0xf5eb0000), SPH_C32(0xa8a90000), SPH_C32(0x6ac40000), + SPH_C32(0x8daf0240), SPH_C32(0xcdb63c93), SPH_C32(0xd7ffd112), + SPH_C32(0x90b053ae), SPH_C32(0xda2bec31), SPH_C32(0xb11f0000), + SPH_C32(0x86b90000), SPH_C32(0x9e1b0000), SPH_C32(0x13f20660), + SPH_C32(0x8e795b9a), SPH_C32(0xc40444d6), SPH_C32(0x8906793b), + SPH_C32(0xc2e32970) }, + { SPH_C32(0x57370000), SPH_C32(0xcaf20000), SPH_C32(0x364e0000), + SPH_C32(0xc0220480), SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), + SPH_C32(0xa1937f8f), SPH_C32(0x15b961e7), SPH_C32(0xb4310000), + SPH_C32(0x77330000), SPH_C32(0xb15d0000), SPH_C32(0x7fd004e0), + SPH_C32(0x78a26138), SPH_C32(0xd116c35d), SPH_C32(0xd256d489), + SPH_C32(0x4e6f74de) }, + { SPH_C32(0xb11f0000), SPH_C32(0x86b90000), SPH_C32(0x9e1b0000), + SPH_C32(0x13f20660), SPH_C32(0x8e795b9a), SPH_C32(0xc40444d6), + SPH_C32(0x8906793b), SPH_C32(0xc2e32970), SPH_C32(0x44f40000), + SPH_C32(0x2e100000), SPH_C32(0xf4df0000), SPH_C32(0x9e5d0420), + SPH_C32(0x43cf6709), SPH_C32(0x13fb95c4), SPH_C32(0x19b62a95), + SPH_C32(0x18c8c541) }, + { SPH_C32(0xa7f20000), SPH_C32(0x93d10000), SPH_C32(0x73cc0000), + SPH_C32(0x21af0440), SPH_C32(0x6d756d13), SPH_C32(0x9e4ea295), + SPH_C32(0x6a738193), SPH_C32(0x431ed078), SPH_C32(0xa2dc0000), + SPH_C32(0x625b0000), SPH_C32(0x5c8a0000), SPH_C32(0x4d8d06c0), + SPH_C32(0x9bae57b1), SPH_C32(0x8b5c251e), SPH_C32(0x31232c21), + SPH_C32(0xcf928dd6) }, + { SPH_C32(0x41da0000), SPH_C32(0xdf9a0000), SPH_C32(0xdb990000), + SPH_C32(0xf27f06a0), SPH_C32(0xb5145dab), SPH_C32(0x06e9124f), + SPH_C32(0x42e68727), SPH_C32(0x944498ef), SPH_C32(0x52190000), + SPH_C32(0x3b780000), SPH_C32(0x19080000), SPH_C32(0xac000600), + SPH_C32(0xa0c35180), SPH_C32(0x49b17387), SPH_C32(0xfac3d23d), + SPH_C32(0x99353c49) } +}; + +static const sph_u32 T512_56[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x5fa80000), SPH_C32(0x56030000), SPH_C32(0x43ae0000), + SPH_C32(0x64f30013), SPH_C32(0x257e86bf), SPH_C32(0x1311944e), + SPH_C32(0x541e95bf), SPH_C32(0x8ea4db69), SPH_C32(0x00440000), + SPH_C32(0x7f480000), SPH_C32(0xda7c0000), SPH_C32(0x2a230001), + SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), SPH_C32(0x030a9e60), + SPH_C32(0xbe0a679e) }, + { SPH_C32(0x00440000), SPH_C32(0x7f480000), SPH_C32(0xda7c0000), + SPH_C32(0x2a230001), SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), + SPH_C32(0x030a9e60), SPH_C32(0xbe0a679e), SPH_C32(0x5fec0000), + SPH_C32(0x294b0000), SPH_C32(0x99d20000), SPH_C32(0x4ed00012), + SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), SPH_C32(0x57140bdf), + SPH_C32(0x30aebcf7) }, + { SPH_C32(0x5fec0000), SPH_C32(0x294b0000), SPH_C32(0x99d20000), + SPH_C32(0x4ed00012), SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), + SPH_C32(0x57140bdf), SPH_C32(0x30aebcf7), SPH_C32(0x5fa80000), + SPH_C32(0x56030000), SPH_C32(0x43ae0000), SPH_C32(0x64f30013), + SPH_C32(0x257e86bf), SPH_C32(0x1311944e), SPH_C32(0x541e95bf), + SPH_C32(0x8ea4db69) }, + { SPH_C32(0xee930000), SPH_C32(0xd6070000), SPH_C32(0x92c10000), + SPH_C32(0x2b9801e0), SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), + SPH_C32(0x45312374), SPH_C32(0x201f6a64), SPH_C32(0x7b280000), + SPH_C32(0x57420000), SPH_C32(0xa9e50000), SPH_C32(0x634300a0), + SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), SPH_C32(0x27f83b03), + SPH_C32(0xc7ff60f0) }, + { SPH_C32(0xb13b0000), SPH_C32(0x80040000), SPH_C32(0xd16f0000), + SPH_C32(0x4f6b01f3), SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), + SPH_C32(0x112fb6cb), SPH_C32(0xaebbb10d), SPH_C32(0x7b6c0000), + SPH_C32(0x280a0000), SPH_C32(0x73990000), SPH_C32(0x496000a1), + SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), SPH_C32(0x24f2a563), + SPH_C32(0x79f5076e) }, + { SPH_C32(0xeed70000), SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), + SPH_C32(0x01bb01e1), SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), + SPH_C32(0x463bbd14), SPH_C32(0x9e150dfa), SPH_C32(0x24c40000), + SPH_C32(0x7e090000), SPH_C32(0x30370000), SPH_C32(0x2d9300b2), + SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), SPH_C32(0x70ec30dc), + SPH_C32(0xf751dc07) }, + { SPH_C32(0xb17f0000), SPH_C32(0xff4c0000), SPH_C32(0x0b130000), + SPH_C32(0x654801f2), SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), + SPH_C32(0x122528ab), SPH_C32(0x10b1d693), SPH_C32(0x24800000), + SPH_C32(0x01410000), SPH_C32(0xea4b0000), SPH_C32(0x07b000b3), + SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), SPH_C32(0x73e6aebc), + SPH_C32(0x495bbb99) }, + { SPH_C32(0x7b280000), SPH_C32(0x57420000), SPH_C32(0xa9e50000), + SPH_C32(0x634300a0), SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), + SPH_C32(0x27f83b03), SPH_C32(0xc7ff60f0), SPH_C32(0x95bb0000), + SPH_C32(0x81450000), SPH_C32(0x3b240000), SPH_C32(0x48db0140), + SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), SPH_C32(0x62c91877), + SPH_C32(0xe7e00a94) }, + { SPH_C32(0x24800000), SPH_C32(0x01410000), SPH_C32(0xea4b0000), + SPH_C32(0x07b000b3), SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), + SPH_C32(0x73e6aebc), SPH_C32(0x495bbb99), SPH_C32(0x95ff0000), + SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), SPH_C32(0x62f80141), + SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), SPH_C32(0x61c38617), + SPH_C32(0x59ea6d0a) }, + { SPH_C32(0x7b6c0000), SPH_C32(0x280a0000), SPH_C32(0x73990000), + SPH_C32(0x496000a1), SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), + SPH_C32(0x24f2a563), SPH_C32(0x79f5076e), SPH_C32(0xca570000), + SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), SPH_C32(0x060b0152), + SPH_C32(0x14592320), SPH_C32(0xec526625), SPH_C32(0x35dd13a8), + SPH_C32(0xd74eb663) }, + { SPH_C32(0x24c40000), SPH_C32(0x7e090000), SPH_C32(0x30370000), + SPH_C32(0x2d9300b2), SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), + SPH_C32(0x70ec30dc), SPH_C32(0xf751dc07), SPH_C32(0xca130000), + SPH_C32(0xd7460000), SPH_C32(0x788a0000), SPH_C32(0x2c280153), + SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), SPH_C32(0x36d78dc8), + SPH_C32(0x6944d1fd) }, + { SPH_C32(0x95bb0000), SPH_C32(0x81450000), SPH_C32(0x3b240000), + SPH_C32(0x48db0140), SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), + SPH_C32(0x62c91877), SPH_C32(0xe7e00a94), SPH_C32(0xee930000), + SPH_C32(0xd6070000), SPH_C32(0x92c10000), SPH_C32(0x2b9801e0), + SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), SPH_C32(0x45312374), + SPH_C32(0x201f6a64) }, + { SPH_C32(0xca130000), SPH_C32(0xd7460000), SPH_C32(0x788a0000), + SPH_C32(0x2c280153), SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), + SPH_C32(0x36d78dc8), SPH_C32(0x6944d1fd), SPH_C32(0xeed70000), + SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), SPH_C32(0x01bb01e1), + SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), SPH_C32(0x463bbd14), + SPH_C32(0x9e150dfa) }, + { SPH_C32(0x95ff0000), SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), + SPH_C32(0x62f80141), SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), + SPH_C32(0x61c38617), SPH_C32(0x59ea6d0a), SPH_C32(0xb17f0000), + SPH_C32(0xff4c0000), SPH_C32(0x0b130000), SPH_C32(0x654801f2), + SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), SPH_C32(0x122528ab), + SPH_C32(0x10b1d693) }, + { SPH_C32(0xca570000), SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), + SPH_C32(0x060b0152), SPH_C32(0x14592320), SPH_C32(0xec526625), + SPH_C32(0x35dd13a8), SPH_C32(0xd74eb663), SPH_C32(0xb13b0000), + SPH_C32(0x80040000), SPH_C32(0xd16f0000), SPH_C32(0x4f6b01f3), + SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), SPH_C32(0x112fb6cb), + SPH_C32(0xaebbb10d) } +}; + +static const sph_u32 T512_60[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x033d0000), SPH_C32(0x08b30000), SPH_C32(0xf33a0000), + SPH_C32(0x3ac20007), SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), + SPH_C32(0x0ea5cfe3), SPH_C32(0xe6da7ffe), SPH_C32(0xa8da0000), + SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), SPH_C32(0x07da0002), + SPH_C32(0x7d669583), SPH_C32(0x1f98708a), SPH_C32(0xbb668808), + SPH_C32(0xda878000) }, + { SPH_C32(0xa8da0000), SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), + SPH_C32(0x07da0002), SPH_C32(0x7d669583), SPH_C32(0x1f98708a), + SPH_C32(0xbb668808), SPH_C32(0xda878000), SPH_C32(0xabe70000), + SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), SPH_C32(0x3d180005), + SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), SPH_C32(0xb5c347eb), + SPH_C32(0x3c5dfffe) }, + { SPH_C32(0xabe70000), SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), + SPH_C32(0x3d180005), SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), + SPH_C32(0xb5c347eb), SPH_C32(0x3c5dfffe), SPH_C32(0x033d0000), + SPH_C32(0x08b30000), SPH_C32(0xf33a0000), SPH_C32(0x3ac20007), + SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), SPH_C32(0x0ea5cfe3), + SPH_C32(0xe6da7ffe) }, + { SPH_C32(0x01930000), SPH_C32(0xe7820000), SPH_C32(0xedfb0000), + SPH_C32(0xcf0c000b), SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), + SPH_C32(0x063661e1), SPH_C32(0x536f9e7b), SPH_C32(0x92280000), + SPH_C32(0xdc850000), SPH_C32(0x57fa0000), SPH_C32(0x56dc0003), + SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), SPH_C32(0x90cef752), + SPH_C32(0x7b1675d7) }, + { SPH_C32(0x02ae0000), SPH_C32(0xef310000), SPH_C32(0x1ec10000), + SPH_C32(0xf5ce000c), SPH_C32(0xdcf90708), SPH_C32(0xd7cdd231), + SPH_C32(0x0893ae02), SPH_C32(0xb5b5e185), SPH_C32(0x3af20000), + SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), SPH_C32(0x51060001), + SPH_C32(0xc78fb695), SPH_C32(0x4577d386), SPH_C32(0x2ba87f5a), + SPH_C32(0xa191f5d7) }, + { SPH_C32(0xa9490000), SPH_C32(0x713c0000), SPH_C32(0xb1e60000), + SPH_C32(0xc8d60009), SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), + SPH_C32(0xbd50e9e9), SPH_C32(0x89e81e7b), SPH_C32(0x39cf0000), + SPH_C32(0x42880000), SPH_C32(0xf8dd0000), SPH_C32(0x6bc40006), + SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), SPH_C32(0x250db0b9), + SPH_C32(0x474b8a29) }, + { SPH_C32(0xaa740000), SPH_C32(0x798f0000), SPH_C32(0x42dc0000), + SPH_C32(0xf214000e), SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), + SPH_C32(0xb3f5260a), SPH_C32(0x6f326185), SPH_C32(0x91150000), + SPH_C32(0xd4360000), SPH_C32(0xa4c00000), SPH_C32(0x6c1e0004), + SPH_C32(0xebc0a946), SPH_C32(0x3181c513), SPH_C32(0x9e6b38b1), + SPH_C32(0x9dcc0a29) }, + { SPH_C32(0x92280000), SPH_C32(0xdc850000), SPH_C32(0x57fa0000), + SPH_C32(0x56dc0003), SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), + SPH_C32(0x90cef752), SPH_C32(0x7b1675d7), SPH_C32(0x93bb0000), + SPH_C32(0x3b070000), SPH_C32(0xba010000), SPH_C32(0x99d00008), + SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), SPH_C32(0x96f896b3), + SPH_C32(0x2879ebac) }, + { SPH_C32(0x91150000), SPH_C32(0xd4360000), SPH_C32(0xa4c00000), + SPH_C32(0x6c1e0004), SPH_C32(0xebc0a946), SPH_C32(0x3181c513), + SPH_C32(0x9e6b38b1), SPH_C32(0x9dcc0a29), SPH_C32(0x3b610000), + SPH_C32(0xadb90000), SPH_C32(0xe61c0000), SPH_C32(0x9e0a000a), + SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), SPH_C32(0x2d9e1ebb), + SPH_C32(0xf2fe6bac) }, + { SPH_C32(0x3af20000), SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), + SPH_C32(0x51060001), SPH_C32(0xc78fb695), SPH_C32(0x4577d386), + SPH_C32(0x2ba87f5a), SPH_C32(0xa191f5d7), SPH_C32(0x385c0000), + SPH_C32(0xa50a0000), SPH_C32(0x15260000), SPH_C32(0xa4c8000d), + SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), SPH_C32(0x233bd158), + SPH_C32(0x14241452) }, + { SPH_C32(0x39cf0000), SPH_C32(0x42880000), SPH_C32(0xf8dd0000), + SPH_C32(0x6bc40006), SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), + SPH_C32(0x250db0b9), SPH_C32(0x474b8a29), SPH_C32(0x90860000), + SPH_C32(0x33b40000), SPH_C32(0x493b0000), SPH_C32(0xa312000f), + SPH_C32(0x6610241e), SPH_C32(0x8d22713d), SPH_C32(0x985d5950), + SPH_C32(0xcea39452) }, + { SPH_C32(0x93bb0000), SPH_C32(0x3b070000), SPH_C32(0xba010000), + SPH_C32(0x99d00008), SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), + SPH_C32(0x96f896b3), SPH_C32(0x2879ebac), SPH_C32(0x01930000), + SPH_C32(0xe7820000), SPH_C32(0xedfb0000), SPH_C32(0xcf0c000b), + SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), SPH_C32(0x063661e1), + SPH_C32(0x536f9e7b) }, + { SPH_C32(0x90860000), SPH_C32(0x33b40000), SPH_C32(0x493b0000), + SPH_C32(0xa312000f), SPH_C32(0x6610241e), SPH_C32(0x8d22713d), + SPH_C32(0x985d5950), SPH_C32(0xcea39452), SPH_C32(0xa9490000), + SPH_C32(0x713c0000), SPH_C32(0xb1e60000), SPH_C32(0xc8d60009), + SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), SPH_C32(0xbd50e9e9), + SPH_C32(0x89e81e7b) }, + { SPH_C32(0x3b610000), SPH_C32(0xadb90000), SPH_C32(0xe61c0000), + SPH_C32(0x9e0a000a), SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), + SPH_C32(0x2d9e1ebb), SPH_C32(0xf2fe6bac), SPH_C32(0xaa740000), + SPH_C32(0x798f0000), SPH_C32(0x42dc0000), SPH_C32(0xf214000e), + SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), SPH_C32(0xb3f5260a), + SPH_C32(0x6f326185) }, + { SPH_C32(0x385c0000), SPH_C32(0xa50a0000), SPH_C32(0x15260000), + SPH_C32(0xa4c8000d), SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), + SPH_C32(0x233bd158), SPH_C32(0x14241452), SPH_C32(0x02ae0000), + SPH_C32(0xef310000), SPH_C32(0x1ec10000), SPH_C32(0xf5ce000c), + SPH_C32(0xdcf90708), SPH_C32(0xd7cdd231), SPH_C32(0x0893ae02), + SPH_C32(0xb5b5e185) } +}; + +#define INPUT_BIG do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T512_0[acc >> 4][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + m8 = rp[8]; \ + m9 = rp[9]; \ + mA = rp[10]; \ + mB = rp[11]; \ + mC = rp[12]; \ + mD = rp[13]; \ + mE = rp[14]; \ + mF = rp[15]; \ + rp = &T512_4[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[1]; \ + rp = &T512_8[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_12[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[2]; \ + rp = &T512_16[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_20[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[3]; \ + rp = &T512_24[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_28[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[4]; \ + rp = &T512_32[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_36[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[5]; \ + rp = &T512_40[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_44[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[6]; \ + rp = &T512_48[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_52[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[7]; \ + rp = &T512_56[acc >> 4][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_60[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_BIG == 5 + +static const sph_u32 T512_0[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x23671400), SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), + SPH_C32(0xfb750000), SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), + SPH_C32(0x02c40a3f), SPH_C32(0xdc24e61f), SPH_C32(0x373d2800), + SPH_C32(0x71500000), SPH_C32(0x95e00000), SPH_C32(0x0a140000), + SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), SPH_C32(0x456d6d1f), + SPH_C32(0x3daac2da) }, + { SPH_C32(0x54285c00), SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), + SPH_C32(0xa1c50000), SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), + SPH_C32(0x6bb0419d), SPH_C32(0x551b3782), SPH_C32(0x9cbb1800), + SPH_C32(0xb0d30000), SPH_C32(0x92510000), SPH_C32(0xed930000), + SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), SPH_C32(0x430633da), + SPH_C32(0x78cace29) }, + { SPH_C32(0x774f4800), SPH_C32(0x22540000), SPH_C32(0x31110000), + SPH_C32(0x5ab00000), SPH_C32(0xc06f4315), SPH_C32(0x6c0361a8), + SPH_C32(0x69744ba2), SPH_C32(0x893fd19d), SPH_C32(0xab863000), + SPH_C32(0xc1830000), SPH_C32(0x07b10000), SPH_C32(0xe7870000), + SPH_C32(0xe4965a4c), SPH_C32(0xa9fb4dc5), SPH_C32(0x066b5ec5), + SPH_C32(0x45600cf3) }, + { SPH_C32(0x9cbb1800), SPH_C32(0xb0d30000), SPH_C32(0x92510000), + SPH_C32(0xed930000), SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), + SPH_C32(0x430633da), SPH_C32(0x78cace29), SPH_C32(0xc8934400), + SPH_C32(0x5a3e0000), SPH_C32(0x57870000), SPH_C32(0x4c560000), + SPH_C32(0xea982435), SPH_C32(0x75b11115), SPH_C32(0x28b67247), + SPH_C32(0x2dd1f9ab) }, + { SPH_C32(0xbfdc0c00), SPH_C32(0x786a0000), SPH_C32(0x66960000), + SPH_C32(0x16e60000), SPH_C32(0x2af76720), SPH_C32(0x19b270bd), + SPH_C32(0x41c239e5), SPH_C32(0xa4ee2836), SPH_C32(0xffae6c00), + SPH_C32(0x2b6e0000), SPH_C32(0xc2670000), SPH_C32(0x46420000), + SPH_C32(0x57343d3c), SPH_C32(0x3d5e8924), SPH_C32(0x6ddb1f58), + SPH_C32(0x107b3b71) }, + { SPH_C32(0xc8934400), SPH_C32(0x5a3e0000), SPH_C32(0x57870000), + SPH_C32(0x4c560000), SPH_C32(0xea982435), SPH_C32(0x75b11115), + SPH_C32(0x28b67247), SPH_C32(0x2dd1f9ab), SPH_C32(0x54285c00), + SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), SPH_C32(0xa1c50000), + SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), SPH_C32(0x6bb0419d), + SPH_C32(0x551b3782) }, + { SPH_C32(0xebf45000), SPH_C32(0x92870000), SPH_C32(0xa3400000), + SPH_C32(0xb7230000), SPH_C32(0x99550050), SPH_C32(0x8d17b45c), + SPH_C32(0x2a727878), SPH_C32(0xf1f51fb4), SPH_C32(0x63157400), + SPH_C32(0x9bbd0000), SPH_C32(0x50360000), SPH_C32(0xabd10000), + SPH_C32(0x0e0e7e79), SPH_C32(0xdc4a5cd0), SPH_C32(0x2edd2c82), + SPH_C32(0x68b1f558) }, + { SPH_C32(0x29449c00), SPH_C32(0x64e70000), SPH_C32(0xf24b0000), + SPH_C32(0xc2f30000), SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), + SPH_C32(0xf3e04259), SPH_C32(0x8d0d9ec4), SPH_C32(0x466d0c00), + SPH_C32(0x08620000), SPH_C32(0xdd5d0000), SPH_C32(0xbadd0000), + SPH_C32(0x6a927942), SPH_C32(0x441f2b93), SPH_C32(0x218ace6f), + SPH_C32(0xbf2c0be2) }, + { SPH_C32(0x0a238800), SPH_C32(0xac5e0000), SPH_C32(0x068c0000), + SPH_C32(0x39860000), SPH_C32(0x7d136aea), SPH_C32(0xae64920c), + SPH_C32(0xf1244866), SPH_C32(0x512978db), SPH_C32(0x71502400), + SPH_C32(0x79320000), SPH_C32(0x48bd0000), SPH_C32(0xb0c90000), + SPH_C32(0xd73e604b), SPH_C32(0x0cf0b3a2), SPH_C32(0x64e7a370), + SPH_C32(0x8286c938) }, + { SPH_C32(0x7d6cc000), SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), + SPH_C32(0x63360000), SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), + SPH_C32(0x985003c4), SPH_C32(0xd816a946), SPH_C32(0xdad61400), + SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), SPH_C32(0x574e0000), + SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), SPH_C32(0x628cfdb5), + SPH_C32(0xc7e6c5cb) }, + { SPH_C32(0x5e0bd400), SPH_C32(0x46b30000), SPH_C32(0xc35a0000), + SPH_C32(0x98430000), SPH_C32(0xceb10d9a), SPH_C32(0x3ac156ed), + SPH_C32(0x9a9409fb), SPH_C32(0x04324f59), SPH_C32(0xedeb3c00), + SPH_C32(0xc9e10000), SPH_C32(0xdaec0000), SPH_C32(0x5d5a0000), + SPH_C32(0x8e04230e), SPH_C32(0xede46656), SPH_C32(0x27e190aa), + SPH_C32(0xfa4c0711) }, + { SPH_C32(0xb5ff8400), SPH_C32(0xd4340000), SPH_C32(0x601a0000), + SPH_C32(0x2f600000), SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), + SPH_C32(0xb0e67183), SPH_C32(0xf5c750ed), SPH_C32(0x8efe4800), + SPH_C32(0x525c0000), SPH_C32(0x8ada0000), SPH_C32(0xf68b0000), + SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), SPH_C32(0x093cbc28), + SPH_C32(0x92fdf249) }, + { SPH_C32(0x96989000), SPH_C32(0x1c8d0000), SPH_C32(0x94dd0000), + SPH_C32(0xd4150000), SPH_C32(0x242929af), SPH_C32(0x4f7047f8), + SPH_C32(0xb2227bbc), SPH_C32(0x29e3b6f2), SPH_C32(0xb9c36000), + SPH_C32(0x230c0000), SPH_C32(0x1f3a0000), SPH_C32(0xfc9f0000), + SPH_C32(0x3da6447e), SPH_C32(0x7941a2b7), SPH_C32(0x4c51d137), + SPH_C32(0xaf573093) }, + { SPH_C32(0xe1d7d800), SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), + SPH_C32(0x8ea50000), SPH_C32(0xe4466aba), SPH_C32(0x23732650), + SPH_C32(0xdb56301e), SPH_C32(0xa0dc676f), SPH_C32(0x12455000), + SPH_C32(0xe28f0000), SPH_C32(0x188b0000), SPH_C32(0x1b180000), + SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), SPH_C32(0x4a3a8ff2), + SPH_C32(0xea373c60) }, + { SPH_C32(0xc2b0cc00), SPH_C32(0xf6600000), SPH_C32(0x510b0000), + SPH_C32(0x75d00000), SPH_C32(0x978b4edf), SPH_C32(0xdbd58319), + SPH_C32(0xd9923a21), SPH_C32(0x7cf88170), SPH_C32(0x25787800), + SPH_C32(0x93df0000), SPH_C32(0x8d6b0000), SPH_C32(0x110c0000), + SPH_C32(0x649c073b), SPH_C32(0x98557743), SPH_C32(0x0f57e2ed), + SPH_C32(0xd79dfeba) }, + { SPH_C32(0x466d0c00), SPH_C32(0x08620000), SPH_C32(0xdd5d0000), + SPH_C32(0xbadd0000), SPH_C32(0x6a927942), SPH_C32(0x441f2b93), + SPH_C32(0x218ace6f), SPH_C32(0xbf2c0be2), SPH_C32(0x6f299000), + SPH_C32(0x6c850000), SPH_C32(0x2f160000), SPH_C32(0x782e0000), + SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), SPH_C32(0xd26a8c36), + SPH_C32(0x32219526) }, + { SPH_C32(0x650a1800), SPH_C32(0xc0db0000), SPH_C32(0x299a0000), + SPH_C32(0x41a80000), SPH_C32(0x195f5d27), SPH_C32(0xbcb98eda), + SPH_C32(0x234ec450), SPH_C32(0x6308edfd), SPH_C32(0x5814b800), + SPH_C32(0x1dd50000), SPH_C32(0xbaf60000), SPH_C32(0x723a0000), + SPH_C32(0xd9e02ec4), SPH_C32(0x5a3284e7), SPH_C32(0x9707e129), + SPH_C32(0x0f8b57fc) }, + { SPH_C32(0x12455000), SPH_C32(0xe28f0000), SPH_C32(0x188b0000), + SPH_C32(0x1b180000), SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), + SPH_C32(0x4a3a8ff2), SPH_C32(0xea373c60), SPH_C32(0xf3928800), + SPH_C32(0xdc560000), SPH_C32(0xbd470000), SPH_C32(0x95bd0000), + SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), SPH_C32(0x916cbfec), + SPH_C32(0x4aeb5b0f) }, + { SPH_C32(0x31224400), SPH_C32(0x2a360000), SPH_C32(0xec4c0000), + SPH_C32(0xe06d0000), SPH_C32(0xaafd3a57), SPH_C32(0x281c4a3b), + SPH_C32(0x48fe85cd), SPH_C32(0x3613da7f), SPH_C32(0xc4afa000), + SPH_C32(0xad060000), SPH_C32(0x28a70000), SPH_C32(0x9fa90000), + SPH_C32(0x80da6d81), SPH_C32(0xbb265113), SPH_C32(0xd401d2f3), + SPH_C32(0x774199d5) }, + { SPH_C32(0xdad61400), SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), + SPH_C32(0x574e0000), SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), + SPH_C32(0x628cfdb5), SPH_C32(0xc7e6c5cb), SPH_C32(0xa7bad400), + SPH_C32(0x36bb0000), SPH_C32(0x78910000), SPH_C32(0x34780000), + SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), SPH_C32(0xfadcfe71), + SPH_C32(0x1ff06c8d) }, + { SPH_C32(0xf9b10000), SPH_C32(0x70080000), SPH_C32(0xbbcb0000), + SPH_C32(0xac3b0000), SPH_C32(0x40651e62), SPH_C32(0x5dad5b2e), + SPH_C32(0x6048f78a), SPH_C32(0x1bc223d4), SPH_C32(0x9087fc00), + SPH_C32(0x47eb0000), SPH_C32(0xed710000), SPH_C32(0x3e6c0000), + SPH_C32(0x33780af1), SPH_C32(0x2f8395f2), SPH_C32(0xbfb1936e), + SPH_C32(0x225aae57) }, + { SPH_C32(0x8efe4800), SPH_C32(0x525c0000), SPH_C32(0x8ada0000), + SPH_C32(0xf68b0000), SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), + SPH_C32(0x093cbc28), SPH_C32(0x92fdf249), SPH_C32(0x3b01cc00), + SPH_C32(0x86680000), SPH_C32(0xeac00000), SPH_C32(0xd9eb0000), + SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), SPH_C32(0xb9dacdab), + SPH_C32(0x673aa2a4) }, + { SPH_C32(0xad995c00), SPH_C32(0x9ae50000), SPH_C32(0x7e1d0000), + SPH_C32(0x0dfe0000), SPH_C32(0xf3c77912), SPH_C32(0xc9089fcf), + SPH_C32(0x0bf8b617), SPH_C32(0x4ed91456), SPH_C32(0x0c3ce400), + SPH_C32(0xf7380000), SPH_C32(0x7f200000), SPH_C32(0xd3ff0000), + SPH_C32(0x6a4249b4), SPH_C32(0xce974006), SPH_C32(0xfcb7a0b4), + SPH_C32(0x5a90607e) }, + { SPH_C32(0x6f299000), SPH_C32(0x6c850000), SPH_C32(0x2f160000), + SPH_C32(0x782e0000), SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), + SPH_C32(0xd26a8c36), SPH_C32(0x32219526), SPH_C32(0x29449c00), + SPH_C32(0x64e70000), SPH_C32(0xf24b0000), SPH_C32(0xc2f30000), + SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), SPH_C32(0xf3e04259), + SPH_C32(0x8d0d9ec4) }, + { SPH_C32(0x4c4e8400), SPH_C32(0xa43c0000), SPH_C32(0xdbd10000), + SPH_C32(0x835b0000), SPH_C32(0x178113a8), SPH_C32(0xea7bb99f), + SPH_C32(0xd0ae8609), SPH_C32(0xee057339), SPH_C32(0x1e79b400), + SPH_C32(0x15b70000), SPH_C32(0x67ab0000), SPH_C32(0xc8e70000), + SPH_C32(0xb3725786), SPH_C32(0x1e2daf74), SPH_C32(0xb68d2f46), + SPH_C32(0xb0a75c1e) }, + { SPH_C32(0x3b01cc00), SPH_C32(0x86680000), SPH_C32(0xeac00000), + SPH_C32(0xd9eb0000), SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), + SPH_C32(0xb9dacdab), SPH_C32(0x673aa2a4), SPH_C32(0xb5ff8400), + SPH_C32(0xd4340000), SPH_C32(0x601a0000), SPH_C32(0x2f600000), + SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), SPH_C32(0xb0e67183), + SPH_C32(0xf5c750ed) }, + { SPH_C32(0x1866d800), SPH_C32(0x4ed10000), SPH_C32(0x1e070000), + SPH_C32(0x229e0000), SPH_C32(0xa42374d8), SPH_C32(0x7ede7d7e), + SPH_C32(0xbb1ec794), SPH_C32(0xbb1e44bb), SPH_C32(0x82c2ac00), + SPH_C32(0xa5640000), SPH_C32(0xf5fa0000), SPH_C32(0x25740000), + SPH_C32(0xea4814c3), SPH_C32(0xff397a80), SPH_C32(0xf58b1c9c), + SPH_C32(0xc86d9237) }, + { SPH_C32(0xf3928800), SPH_C32(0xdc560000), SPH_C32(0xbd470000), + SPH_C32(0x95bd0000), SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), + SPH_C32(0x916cbfec), SPH_C32(0x4aeb5b0f), SPH_C32(0xe1d7d800), + SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), SPH_C32(0x8ea50000), + SPH_C32(0xe4466aba), SPH_C32(0x23732650), SPH_C32(0xdb56301e), + SPH_C32(0xa0dc676f) }, + { SPH_C32(0xd0f59c00), SPH_C32(0x14ef0000), SPH_C32(0x49800000), + SPH_C32(0x6ec80000), SPH_C32(0x4ebb50ed), SPH_C32(0x0b6f6c6b), + SPH_C32(0x93a8b5d3), SPH_C32(0x96cfbd10), SPH_C32(0xd6eaf000), + SPH_C32(0x4f890000), SPH_C32(0x302c0000), SPH_C32(0x84b10000), + SPH_C32(0x59ea73b3), SPH_C32(0x6b9cbe61), SPH_C32(0x9e3b5d01), + SPH_C32(0x9d76a5b5) }, + { SPH_C32(0xa7bad400), SPH_C32(0x36bb0000), SPH_C32(0x78910000), + SPH_C32(0x34780000), SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), + SPH_C32(0xfadcfe71), SPH_C32(0x1ff06c8d), SPH_C32(0x7d6cc000), + SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), SPH_C32(0x63360000), + SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), SPH_C32(0x985003c4), + SPH_C32(0xd816a946) }, + { SPH_C32(0x84ddc000), SPH_C32(0xfe020000), SPH_C32(0x8c560000), + SPH_C32(0xcf0d0000), SPH_C32(0xfd19379d), SPH_C32(0x9fcaa88a), + SPH_C32(0xf818f44e), SPH_C32(0xc3d48a92), SPH_C32(0x4a51e800), + SPH_C32(0xff5a0000), SPH_C32(0xa27d0000), SPH_C32(0x69220000), + SPH_C32(0x00d030f6), SPH_C32(0x8a886b95), SPH_C32(0xdd3d6edb), + SPH_C32(0xe5bc6b9c) } +}; + +static const sph_u32 T512_5[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xe8870170), SPH_C32(0x9d720000), SPH_C32(0x12db0000), + SPH_C32(0xd4220000), SPH_C32(0xf2886b27), SPH_C32(0xa921e543), + SPH_C32(0x4ef8b518), SPH_C32(0x618813b1), SPH_C32(0xb4370060), + SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), SPH_C32(0x5cae0000), + SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), SPH_C32(0x1b365f3d), + SPH_C32(0xf3d45758) }, + { SPH_C32(0xb4370060), SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), + SPH_C32(0x5cae0000), SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), + SPH_C32(0x1b365f3d), SPH_C32(0xf3d45758), SPH_C32(0x5cb00110), + SPH_C32(0x913e0000), SPH_C32(0x44190000), SPH_C32(0x888c0000), + SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), SPH_C32(0x55ceea25), + SPH_C32(0x925c44e9) }, + { SPH_C32(0x5cb00110), SPH_C32(0x913e0000), SPH_C32(0x44190000), + SPH_C32(0x888c0000), SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), + SPH_C32(0x55ceea25), SPH_C32(0x925c44e9), SPH_C32(0xe8870170), + SPH_C32(0x9d720000), SPH_C32(0x12db0000), SPH_C32(0xd4220000), + SPH_C32(0xf2886b27), SPH_C32(0xa921e543), SPH_C32(0x4ef8b518), + SPH_C32(0x618813b1) }, + { SPH_C32(0xef0b0270), SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), + SPH_C32(0x69490000), SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), + SPH_C32(0x66140a51), SPH_C32(0x924f5d0a), SPH_C32(0xc96b0030), + SPH_C32(0xe7250000), SPH_C32(0x2f840000), SPH_C32(0x264f0000), + SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), SPH_C32(0x509f6984), + SPH_C32(0x9e69af68) }, + { SPH_C32(0x078c0300), SPH_C32(0xa78f0000), SPH_C32(0x4f750000), + SPH_C32(0xbd6b0000), SPH_C32(0x69875721), SPH_C32(0xed2450ba), + SPH_C32(0x28ecbf49), SPH_C32(0xf3c74ebb), SPH_C32(0x7d5c0050), + SPH_C32(0xeb690000), SPH_C32(0x79460000), SPH_C32(0x7ae10000), + SPH_C32(0x9c3d44c6), SPH_C32(0x56c20912), SPH_C32(0x4ba936b9), + SPH_C32(0x6dbdf830) }, + { SPH_C32(0x5b3c0210), SPH_C32(0x36b10000), SPH_C32(0x0b6c0000), + SPH_C32(0x35e70000), SPH_C32(0x0f5b2339), SPH_C32(0x7f3b4ddc), + SPH_C32(0x7d22556c), SPH_C32(0x619b0a52), SPH_C32(0x95db0120), + SPH_C32(0x761b0000), SPH_C32(0x6b9d0000), SPH_C32(0xaec30000), + SPH_C32(0x6eb52fe1), SPH_C32(0xffe3ec51), SPH_C32(0x055183a1), + SPH_C32(0x0c35eb81) }, + { SPH_C32(0xb3bb0360), SPH_C32(0xabc30000), SPH_C32(0x19b70000), + SPH_C32(0xe1c50000), SPH_C32(0xfdd3481e), SPH_C32(0xd61aa89f), + SPH_C32(0x33dae074), SPH_C32(0x001319e3), SPH_C32(0x21ec0140), + SPH_C32(0x7a570000), SPH_C32(0x3d5f0000), SPH_C32(0xf26d0000), + SPH_C32(0xfae130de), SPH_C32(0xc4dd1474), SPH_C32(0x1e67dc9c), + SPH_C32(0xffe1bcd9) }, + { SPH_C32(0xc96b0030), SPH_C32(0xe7250000), SPH_C32(0x2f840000), + SPH_C32(0x264f0000), SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), + SPH_C32(0x509f6984), SPH_C32(0x9e69af68), SPH_C32(0x26600240), + SPH_C32(0xddd80000), SPH_C32(0x722a0000), SPH_C32(0x4f060000), + SPH_C32(0x936667ff), SPH_C32(0x29f944ce), SPH_C32(0x368b63d5), + SPH_C32(0x0c26f262) }, + { SPH_C32(0x21ec0140), SPH_C32(0x7a570000), SPH_C32(0x3d5f0000), + SPH_C32(0xf26d0000), SPH_C32(0xfae130de), SPH_C32(0xc4dd1474), + SPH_C32(0x1e67dc9c), SPH_C32(0xffe1bcd9), SPH_C32(0x92570220), + SPH_C32(0xd1940000), SPH_C32(0x24e80000), SPH_C32(0x13a80000), + SPH_C32(0x073278c0), SPH_C32(0x12c7bceb), SPH_C32(0x2dbd3ce8), + SPH_C32(0xfff2a53a) }, + { SPH_C32(0x7d5c0050), SPH_C32(0xeb690000), SPH_C32(0x79460000), + SPH_C32(0x7ae10000), SPH_C32(0x9c3d44c6), SPH_C32(0x56c20912), + SPH_C32(0x4ba936b9), SPH_C32(0x6dbdf830), SPH_C32(0x7ad00350), + SPH_C32(0x4ce60000), SPH_C32(0x36330000), SPH_C32(0xc78a0000), + SPH_C32(0xf5ba13e7), SPH_C32(0xbbe659a8), SPH_C32(0x634589f0), + SPH_C32(0x9e7ab68b) }, + { SPH_C32(0x95db0120), SPH_C32(0x761b0000), SPH_C32(0x6b9d0000), + SPH_C32(0xaec30000), SPH_C32(0x6eb52fe1), SPH_C32(0xffe3ec51), + SPH_C32(0x055183a1), SPH_C32(0x0c35eb81), SPH_C32(0xcee70330), + SPH_C32(0x40aa0000), SPH_C32(0x60f10000), SPH_C32(0x9b240000), + SPH_C32(0x61ee0cd8), SPH_C32(0x80d8a18d), SPH_C32(0x7873d6cd), + SPH_C32(0x6daee1d3) }, + { SPH_C32(0x26600240), SPH_C32(0xddd80000), SPH_C32(0x722a0000), + SPH_C32(0x4f060000), SPH_C32(0x936667ff), SPH_C32(0x29f944ce), + SPH_C32(0x368b63d5), SPH_C32(0x0c26f262), SPH_C32(0xef0b0270), + SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), SPH_C32(0x69490000), + SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), SPH_C32(0x66140a51), + SPH_C32(0x924f5d0a) }, + { SPH_C32(0xcee70330), SPH_C32(0x40aa0000), SPH_C32(0x60f10000), + SPH_C32(0x9b240000), SPH_C32(0x61ee0cd8), SPH_C32(0x80d8a18d), + SPH_C32(0x7873d6cd), SPH_C32(0x6daee1d3), SPH_C32(0x5b3c0210), + SPH_C32(0x36b10000), SPH_C32(0x0b6c0000), SPH_C32(0x35e70000), + SPH_C32(0x0f5b2339), SPH_C32(0x7f3b4ddc), SPH_C32(0x7d22556c), + SPH_C32(0x619b0a52) }, + { SPH_C32(0x92570220), SPH_C32(0xd1940000), SPH_C32(0x24e80000), + SPH_C32(0x13a80000), SPH_C32(0x073278c0), SPH_C32(0x12c7bceb), + SPH_C32(0x2dbd3ce8), SPH_C32(0xfff2a53a), SPH_C32(0xb3bb0360), + SPH_C32(0xabc30000), SPH_C32(0x19b70000), SPH_C32(0xe1c50000), + SPH_C32(0xfdd3481e), SPH_C32(0xd61aa89f), SPH_C32(0x33dae074), + SPH_C32(0x001319e3) }, + { SPH_C32(0x7ad00350), SPH_C32(0x4ce60000), SPH_C32(0x36330000), + SPH_C32(0xc78a0000), SPH_C32(0xf5ba13e7), SPH_C32(0xbbe659a8), + SPH_C32(0x634589f0), SPH_C32(0x9e7ab68b), SPH_C32(0x078c0300), + SPH_C32(0xa78f0000), SPH_C32(0x4f750000), SPH_C32(0xbd6b0000), + SPH_C32(0x69875721), SPH_C32(0xed2450ba), SPH_C32(0x28ecbf49), + SPH_C32(0xf3c74ebb) }, + { SPH_C32(0x145a3c00), SPH_C32(0xb9e90000), SPH_C32(0x61270000), + SPH_C32(0xf1610000), SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), + SPH_C32(0x47a96720), SPH_C32(0xe18e24c5), SPH_C32(0x23671400), + SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), SPH_C32(0xfb750000), + SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), SPH_C32(0x02c40a3f), + SPH_C32(0xdc24e61f) }, + { SPH_C32(0xfcdd3d70), SPH_C32(0x249b0000), SPH_C32(0x73fc0000), + SPH_C32(0x25430000), SPH_C32(0x3ce9564b), SPH_C32(0x1968d83b), + SPH_C32(0x0951d238), SPH_C32(0x80063774), SPH_C32(0x97501460), + SPH_C32(0xc4f50000), SPH_C32(0xa2050000), SPH_C32(0xa7db0000), + SPH_C32(0xe7993b5a), SPH_C32(0xc3985d6c), SPH_C32(0x19f25502), + SPH_C32(0x2ff0b147) }, + { SPH_C32(0xa06d3c60), SPH_C32(0xb5a50000), SPH_C32(0x37e50000), + SPH_C32(0xadcf0000), SPH_C32(0x5a352253), SPH_C32(0x8b77c55d), + SPH_C32(0x5c9f381d), SPH_C32(0x125a739d), SPH_C32(0x7fd71510), + SPH_C32(0x59870000), SPH_C32(0xb0de0000), SPH_C32(0x73f90000), + SPH_C32(0x1511507d), SPH_C32(0x6ab9b82f), SPH_C32(0x570ae01a), + SPH_C32(0x4e78a2f6) }, + { SPH_C32(0x48ea3d10), SPH_C32(0x28d70000), SPH_C32(0x253e0000), + SPH_C32(0x79ed0000), SPH_C32(0xa8bd4974), SPH_C32(0x2256201e), + SPH_C32(0x12678d05), SPH_C32(0x73d2602c), SPH_C32(0xcbe01570), + SPH_C32(0x55cb0000), SPH_C32(0xe61c0000), SPH_C32(0x2f570000), + SPH_C32(0x81454f42), SPH_C32(0x5187400a), SPH_C32(0x4c3cbf27), + SPH_C32(0xbdacf5ae) }, + { SPH_C32(0xfb513e70), SPH_C32(0x83140000), SPH_C32(0x3c890000), + SPH_C32(0x98280000), SPH_C32(0x556e016a), SPH_C32(0xf44c8881), + SPH_C32(0x21bd6d71), SPH_C32(0x73c179cf), SPH_C32(0xea0c1430), + SPH_C32(0x2f9c0000), SPH_C32(0xdb430000), SPH_C32(0xdd3a0000), + SPH_C32(0x7ba47f9c), SPH_C32(0x955a547e), SPH_C32(0x525b63bb), + SPH_C32(0x424d4977) }, + { SPH_C32(0x13d63f00), SPH_C32(0x1e660000), SPH_C32(0x2e520000), + SPH_C32(0x4c0a0000), SPH_C32(0xa7e66a4d), SPH_C32(0x5d6d6dc2), + SPH_C32(0x6f45d869), SPH_C32(0x12496a7e), SPH_C32(0x5e3b1450), + SPH_C32(0x23d00000), SPH_C32(0x8d810000), SPH_C32(0x81940000), + SPH_C32(0xeff060a3), SPH_C32(0xae64ac5b), SPH_C32(0x496d3c86), + SPH_C32(0xb1991e2f) }, + { SPH_C32(0x4f663e10), SPH_C32(0x8f580000), SPH_C32(0x6a4b0000), + SPH_C32(0xc4860000), SPH_C32(0xc13a1e55), SPH_C32(0xcf7270a4), + SPH_C32(0x3a8b324c), SPH_C32(0x80152e97), SPH_C32(0xb6bc1520), + SPH_C32(0xbea20000), SPH_C32(0x9f5a0000), SPH_C32(0x55b60000), + SPH_C32(0x1d780b84), SPH_C32(0x07454918), SPH_C32(0x0795899e), + SPH_C32(0xd0110d9e) }, + { SPH_C32(0xa7e13f60), SPH_C32(0x122a0000), SPH_C32(0x78900000), + SPH_C32(0x10a40000), SPH_C32(0x33b27572), SPH_C32(0x665395e7), + SPH_C32(0x74738754), SPH_C32(0xe19d3d26), SPH_C32(0x028b1540), + SPH_C32(0xb2ee0000), SPH_C32(0xc9980000), SPH_C32(0x09180000), + SPH_C32(0x892c14bb), SPH_C32(0x3c7bb13d), SPH_C32(0x1ca3d6a3), + SPH_C32(0x23c55ac6) }, + { SPH_C32(0xdd313c30), SPH_C32(0x5ecc0000), SPH_C32(0x4ea30000), + SPH_C32(0xd72e0000), SPH_C32(0xc6086695), SPH_C32(0xddb5cc4f), + SPH_C32(0x17360ea4), SPH_C32(0x7fe78bad), SPH_C32(0x05071640), + SPH_C32(0x15610000), SPH_C32(0x86ed0000), SPH_C32(0xb4730000), + SPH_C32(0xe0ab439a), SPH_C32(0xd15fe187), SPH_C32(0x344f69ea), + SPH_C32(0xd002147d) }, + { SPH_C32(0x35b63d40), SPH_C32(0xc3be0000), SPH_C32(0x5c780000), + SPH_C32(0x030c0000), SPH_C32(0x34800db2), SPH_C32(0x7494290c), + SPH_C32(0x59cebbbc), SPH_C32(0x1e6f981c), SPH_C32(0xb1301620), + SPH_C32(0x192d0000), SPH_C32(0xd02f0000), SPH_C32(0xe8dd0000), + SPH_C32(0x74ff5ca5), SPH_C32(0xea6119a2), SPH_C32(0x2f7936d7), + SPH_C32(0x23d64325) }, + { SPH_C32(0x69063c50), SPH_C32(0x52800000), SPH_C32(0x18610000), + SPH_C32(0x8b800000), SPH_C32(0x525c79aa), SPH_C32(0xe68b346a), + SPH_C32(0x0c005199), SPH_C32(0x8c33dcf5), SPH_C32(0x59b71750), + SPH_C32(0x845f0000), SPH_C32(0xc2f40000), SPH_C32(0x3cff0000), + SPH_C32(0x86773782), SPH_C32(0x4340fce1), SPH_C32(0x618183cf), + SPH_C32(0x425e5094) }, + { SPH_C32(0x81813d20), SPH_C32(0xcff20000), SPH_C32(0x0aba0000), + SPH_C32(0x5fa20000), SPH_C32(0xa0d4128d), SPH_C32(0x4faad129), + SPH_C32(0x42f8e481), SPH_C32(0xedbbcf44), SPH_C32(0xed801730), + SPH_C32(0x88130000), SPH_C32(0x94360000), SPH_C32(0x60510000), + SPH_C32(0x122328bd), SPH_C32(0x787e04c4), SPH_C32(0x7ab7dcf2), + SPH_C32(0xb18a07cc) }, + { SPH_C32(0x323a3e40), SPH_C32(0x64310000), SPH_C32(0x130d0000), + SPH_C32(0xbe670000), SPH_C32(0x5d075a93), SPH_C32(0x99b079b6), + SPH_C32(0x712204f5), SPH_C32(0xeda8d6a7), SPH_C32(0xcc6c1670), + SPH_C32(0xf2440000), SPH_C32(0xa9690000), SPH_C32(0x923c0000), + SPH_C32(0xe8c21863), SPH_C32(0xbca310b0), SPH_C32(0x64d0006e), + SPH_C32(0x4e6bbb15) }, + { SPH_C32(0xdabd3f30), SPH_C32(0xf9430000), SPH_C32(0x01d60000), + SPH_C32(0x6a450000), SPH_C32(0xaf8f31b4), SPH_C32(0x30919cf5), + SPH_C32(0x3fdab1ed), SPH_C32(0x8c20c516), SPH_C32(0x785b1610), + SPH_C32(0xfe080000), SPH_C32(0xffab0000), SPH_C32(0xce920000), + SPH_C32(0x7c96075c), SPH_C32(0x879de895), SPH_C32(0x7fe65f53), + SPH_C32(0xbdbfec4d) }, + { SPH_C32(0x860d3e20), SPH_C32(0x687d0000), SPH_C32(0x45cf0000), + SPH_C32(0xe2c90000), SPH_C32(0xc95345ac), SPH_C32(0xa28e8193), + SPH_C32(0x6a145bc8), SPH_C32(0x1e7c81ff), SPH_C32(0x90dc1760), + SPH_C32(0x637a0000), SPH_C32(0xed700000), SPH_C32(0x1ab00000), + SPH_C32(0x8e1e6c7b), SPH_C32(0x2ebc0dd6), SPH_C32(0x311eea4b), + SPH_C32(0xdc37fffc) }, + { SPH_C32(0x6e8a3f50), SPH_C32(0xf50f0000), SPH_C32(0x57140000), + SPH_C32(0x36eb0000), SPH_C32(0x3bdb2e8b), SPH_C32(0x0baf64d0), + SPH_C32(0x24eceed0), SPH_C32(0x7ff4924e), SPH_C32(0x24eb1700), + SPH_C32(0x6f360000), SPH_C32(0xbbb20000), SPH_C32(0x461e0000), + SPH_C32(0x1a4a7344), SPH_C32(0x1582f5f3), SPH_C32(0x2a28b576), + SPH_C32(0x2fe3a8a4) } +}; + +static const sph_u32 T512_10[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xa67f0001), SPH_C32(0x71378000), SPH_C32(0x19fc0000), + SPH_C32(0x96db0000), SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), + SPH_C32(0x2c6d478f), SPH_C32(0xac8e6c88), SPH_C32(0x50ff0004), + SPH_C32(0x45744000), SPH_C32(0x3dfb0000), SPH_C32(0x19e60000), + SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), SPH_C32(0xe1a8cc96), + SPH_C32(0x7b1bd6b9) }, + { SPH_C32(0xf7750009), SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), + SPH_C32(0x04920000), SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), + SPH_C32(0x7a87f14e), SPH_C32(0x9e16981a), SPH_C32(0xd46a0000), + SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), SPH_C32(0x4a290000), + SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), SPH_C32(0x98369604), + SPH_C32(0xf746c320) }, + { SPH_C32(0x510a0008), SPH_C32(0xbe0b4000), SPH_C32(0xda2a0000), + SPH_C32(0x92490000), SPH_C32(0x381e7454), SPH_C32(0x13229849), + SPH_C32(0x56eab6c1), SPH_C32(0x3298f492), SPH_C32(0x84950004), + SPH_C32(0xc8bc8000), SPH_C32(0x98540000), SPH_C32(0x53cf0000), + SPH_C32(0xe7f2147c), SPH_C32(0x28c6fd31), SPH_C32(0x799e5a92), + SPH_C32(0x8c5d1599) }, + { SPH_C32(0xd46a0000), SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), + SPH_C32(0x4a290000), SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), + SPH_C32(0x98369604), SPH_C32(0xf746c320), SPH_C32(0x231f0009), + SPH_C32(0x42f40000), SPH_C32(0x66790000), SPH_C32(0x4ebb0000), + SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), SPH_C32(0xe2b1674a), + SPH_C32(0x69505b3a) }, + { SPH_C32(0x72150001), SPH_C32(0xfcff4000), SPH_C32(0xbc530000), + SPH_C32(0xdcf20000), SPH_C32(0xc6c52f87), SPH_C32(0x227e289f), + SPH_C32(0xb45bd18b), SPH_C32(0x5bc8afa8), SPH_C32(0x73e0000d), + SPH_C32(0x07804000), SPH_C32(0x5b820000), SPH_C32(0x575d0000), + SPH_C32(0xe5670dd5), SPH_C32(0xd02ecb8b), SPH_C32(0x0319abdc), + SPH_C32(0x124b8d83) }, + { SPH_C32(0x231f0009), SPH_C32(0x42f40000), SPH_C32(0x66790000), + SPH_C32(0x4ebb0000), SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), + SPH_C32(0xe2b1674a), SPH_C32(0x69505b3a), SPH_C32(0xf7750009), + SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), SPH_C32(0x04920000), + SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), SPH_C32(0x7a87f14e), + SPH_C32(0x9e16981a) }, + { SPH_C32(0x85600008), SPH_C32(0x33c38000), SPH_C32(0x7f850000), + SPH_C32(0xd8600000), SPH_C32(0xc450362e), SPH_C32(0xda961e25), + SPH_C32(0xcedc20c5), SPH_C32(0xc5de37b2), SPH_C32(0xa78a000d), + SPH_C32(0x8a488000), SPH_C32(0xfe2d0000), SPH_C32(0x1d740000), + SPH_C32(0x19294faf), SPH_C32(0x199a4de7), SPH_C32(0x9b2f3dd8), + SPH_C32(0xe50d4ea3) }, + { SPH_C32(0x774400f0), SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), + SPH_C32(0x34140000), SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), + SPH_C32(0x0bc3cd1e), SPH_C32(0xcf3775cb), SPH_C32(0xf46c0050), + SPH_C32(0x96180000), SPH_C32(0x14a50000), SPH_C32(0x031f0000), + SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), SPH_C32(0x9ca470d2), + SPH_C32(0x8a341574) }, + { SPH_C32(0xd13b00f1), SPH_C32(0x806d8000), SPH_C32(0xec4e0000), + SPH_C32(0xa2cf0000), SPH_C32(0xb3bc1371), SPH_C32(0xb14142d6), + SPH_C32(0x27ae8a91), SPH_C32(0x63b91943), SPH_C32(0xa4930054), + SPH_C32(0xd36c4000), SPH_C32(0x295e0000), SPH_C32(0x1af90000), + SPH_C32(0x592828be), SPH_C32(0x87cd0544), SPH_C32(0x7d0cbc44), + SPH_C32(0xf12fc3cd) }, + { SPH_C32(0x803100f9), SPH_C32(0x3e66c000), SPH_C32(0x36640000), + SPH_C32(0x30860000), SPH_C32(0x8ba26725), SPH_C32(0xa263da9f), + SPH_C32(0x71443c50), SPH_C32(0x5121edd1), SPH_C32(0x20060050), + SPH_C32(0x1bd0c000), SPH_C32(0xb10a0000), SPH_C32(0x49360000), + SPH_C32(0xbeda3cc2), SPH_C32(0xaf0bf875), SPH_C32(0x0492e6d6), + SPH_C32(0x7d72d654) }, + { SPH_C32(0x264e00f8), SPH_C32(0x4f514000), SPH_C32(0x2f980000), + SPH_C32(0xa65d0000), SPH_C32(0xb1290ad8), SPH_C32(0x49a9746c), + SPH_C32(0x5d297bdf), SPH_C32(0xfdaf8159), SPH_C32(0x70f90054), + SPH_C32(0x5ea48000), SPH_C32(0x8cf10000), SPH_C32(0x50d00000), + SPH_C32(0xa5666ac4), SPH_C32(0x4e798328), SPH_C32(0xe53a2a40), + SPH_C32(0x066900ed) }, + { SPH_C32(0xa32e00f0), SPH_C32(0x7c92c000), SPH_C32(0x501d0000), + SPH_C32(0x7e3d0000), SPH_C32(0x75793cf6), SPH_C32(0x933f6a49), + SPH_C32(0x93f55b1a), SPH_C32(0x3871b6eb), SPH_C32(0xd7730059), + SPH_C32(0xd4ec0000), SPH_C32(0x72dc0000), SPH_C32(0x4da40000), + SPH_C32(0xbc4f256b), SPH_C32(0x57e3cecf), SPH_C32(0x7e151798), + SPH_C32(0xe3644e4e) }, + { SPH_C32(0x055100f1), SPH_C32(0x0da54000), SPH_C32(0x49e10000), + SPH_C32(0xe8e60000), SPH_C32(0x4ff2510b), SPH_C32(0x78f5c4ba), + SPH_C32(0xbf981c95), SPH_C32(0x94ffda63), SPH_C32(0x878c005d), + SPH_C32(0x91984000), SPH_C32(0x4f270000), SPH_C32(0x54420000), + SPH_C32(0xa7f3736d), SPH_C32(0xb691b592), SPH_C32(0x9fbddb0e), + SPH_C32(0x987f98f7) }, + { SPH_C32(0x545b00f9), SPH_C32(0xb3ae0000), SPH_C32(0x93cb0000), + SPH_C32(0x7aaf0000), SPH_C32(0x77ec255f), SPH_C32(0x6bd75cf3), + SPH_C32(0xe972aa54), SPH_C32(0xa6672ef1), SPH_C32(0x03190059), + SPH_C32(0x5924c000), SPH_C32(0xd7730000), SPH_C32(0x078d0000), + SPH_C32(0x40016711), SPH_C32(0x9e5748a3), SPH_C32(0xe623819c), + SPH_C32(0x14228d6e) }, + { SPH_C32(0xf22400f8), SPH_C32(0xc2998000), SPH_C32(0x8a370000), + SPH_C32(0xec740000), SPH_C32(0x4d6748a2), SPH_C32(0x801df200), + SPH_C32(0xc51feddb), SPH_C32(0x0ae94279), SPH_C32(0x53e6005d), + SPH_C32(0x1c508000), SPH_C32(0xea880000), SPH_C32(0x1e6b0000), + SPH_C32(0x5bbd3117), SPH_C32(0x7f2533fe), SPH_C32(0x078b4d0a), + SPH_C32(0x6f395bd7) }, + { SPH_C32(0xf46c0050), SPH_C32(0x96180000), SPH_C32(0x14a50000), + SPH_C32(0x031f0000), SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), + SPH_C32(0x9ca470d2), SPH_C32(0x8a341574), SPH_C32(0x832800a0), + SPH_C32(0x67420000), SPH_C32(0xe1170000), SPH_C32(0x370b0000), + SPH_C32(0xcba30034), SPH_C32(0x3c34923c), SPH_C32(0x9767bdcc), + SPH_C32(0x450360bf) }, + { SPH_C32(0x52130051), SPH_C32(0xe72f8000), SPH_C32(0x0d590000), + SPH_C32(0x95c40000), SPH_C32(0x781f1345), SPH_C32(0x8d75d0ea), + SPH_C32(0xb0c9375d), SPH_C32(0x26ba79fc), SPH_C32(0xd3d700a4), + SPH_C32(0x22364000), SPH_C32(0xdcec0000), SPH_C32(0x2eed0000), + SPH_C32(0xd01f5632), SPH_C32(0xdd46e961), SPH_C32(0x76cf715a), + SPH_C32(0x3e18b606) }, + { SPH_C32(0x03190059), SPH_C32(0x5924c000), SPH_C32(0xd7730000), + SPH_C32(0x078d0000), SPH_C32(0x40016711), SPH_C32(0x9e5748a3), + SPH_C32(0xe623819c), SPH_C32(0x14228d6e), SPH_C32(0x574200a0), + SPH_C32(0xea8ac000), SPH_C32(0x44b80000), SPH_C32(0x7d220000), + SPH_C32(0x37ed424e), SPH_C32(0xf5801450), SPH_C32(0x0f512bc8), + SPH_C32(0xb245a39f) }, + { SPH_C32(0xa5660058), SPH_C32(0x28134000), SPH_C32(0xce8f0000), + SPH_C32(0x91560000), SPH_C32(0x7a8a0aec), SPH_C32(0x759de650), + SPH_C32(0xca4ec613), SPH_C32(0xb8ace1e6), SPH_C32(0x07bd00a4), + SPH_C32(0xaffe8000), SPH_C32(0x79430000), SPH_C32(0x64c40000), + SPH_C32(0x2c511448), SPH_C32(0x14f26f0d), SPH_C32(0xeef9e75e), + SPH_C32(0xc95e7526) }, + { SPH_C32(0x20060050), SPH_C32(0x1bd0c000), SPH_C32(0xb10a0000), + SPH_C32(0x49360000), SPH_C32(0xbeda3cc2), SPH_C32(0xaf0bf875), + SPH_C32(0x0492e6d6), SPH_C32(0x7d72d654), SPH_C32(0xa03700a9), + SPH_C32(0x25b60000), SPH_C32(0x876e0000), SPH_C32(0x79b00000), + SPH_C32(0x35785be7), SPH_C32(0x0d6822ea), SPH_C32(0x75d6da86), + SPH_C32(0x2c533b85) }, + { SPH_C32(0x86790051), SPH_C32(0x6ae74000), SPH_C32(0xa8f60000), + SPH_C32(0xdfed0000), SPH_C32(0x8451513f), SPH_C32(0x44c15686), + SPH_C32(0x28ffa159), SPH_C32(0xd1fcbadc), SPH_C32(0xf0c800ad), + SPH_C32(0x60c24000), SPH_C32(0xba950000), SPH_C32(0x60560000), + SPH_C32(0x2ec40de1), SPH_C32(0xec1a59b7), SPH_C32(0x947e1610), + SPH_C32(0x5748ed3c) }, + { SPH_C32(0xd7730059), SPH_C32(0xd4ec0000), SPH_C32(0x72dc0000), + SPH_C32(0x4da40000), SPH_C32(0xbc4f256b), SPH_C32(0x57e3cecf), + SPH_C32(0x7e151798), SPH_C32(0xe3644e4e), SPH_C32(0x745d00a9), + SPH_C32(0xa87ec000), SPH_C32(0x22c10000), SPH_C32(0x33990000), + SPH_C32(0xc936199d), SPH_C32(0xc4dca486), SPH_C32(0xede04c82), + SPH_C32(0xdb15f8a5) }, + { SPH_C32(0x710c0058), SPH_C32(0xa5db8000), SPH_C32(0x6b200000), + SPH_C32(0xdb7f0000), SPH_C32(0x86c44896), SPH_C32(0xbc29603c), + SPH_C32(0x52785017), SPH_C32(0x4fea22c6), SPH_C32(0x24a200ad), + SPH_C32(0xed0a8000), SPH_C32(0x1f3a0000), SPH_C32(0x2a7f0000), + SPH_C32(0xd28a4f9b), SPH_C32(0x25aedfdb), SPH_C32(0x0c488014), + SPH_C32(0xa00e2e1c) }, + { SPH_C32(0x832800a0), SPH_C32(0x67420000), SPH_C32(0xe1170000), + SPH_C32(0x370b0000), SPH_C32(0xcba30034), SPH_C32(0x3c34923c), + SPH_C32(0x9767bdcc), SPH_C32(0x450360bf), SPH_C32(0x774400f0), + SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), SPH_C32(0x34140000), + SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), SPH_C32(0x0bc3cd1e), + SPH_C32(0xcf3775cb) }, + { SPH_C32(0x255700a1), SPH_C32(0x16758000), SPH_C32(0xf8eb0000), + SPH_C32(0xa1d00000), SPH_C32(0xf1286dc9), SPH_C32(0xd7fe3ccf), + SPH_C32(0xbb0afa43), SPH_C32(0xe98d0c37), SPH_C32(0x27bb00f4), + SPH_C32(0xb42e4000), SPH_C32(0xc8490000), SPH_C32(0x2df20000), + SPH_C32(0x928b288a), SPH_C32(0xbbf99778), SPH_C32(0xea6b0188), + SPH_C32(0xb42ca372) }, + { SPH_C32(0x745d00a9), SPH_C32(0xa87ec000), SPH_C32(0x22c10000), + SPH_C32(0x33990000), SPH_C32(0xc936199d), SPH_C32(0xc4dca486), + SPH_C32(0xede04c82), SPH_C32(0xdb15f8a5), SPH_C32(0xa32e00f0), + SPH_C32(0x7c92c000), SPH_C32(0x501d0000), SPH_C32(0x7e3d0000), + SPH_C32(0x75793cf6), SPH_C32(0x933f6a49), SPH_C32(0x93f55b1a), + SPH_C32(0x3871b6eb) }, + { SPH_C32(0xd22200a8), SPH_C32(0xd9494000), SPH_C32(0x3b3d0000), + SPH_C32(0xa5420000), SPH_C32(0xf3bd7460), SPH_C32(0x2f160a75), + SPH_C32(0xc18d0b0d), SPH_C32(0x779b942d), SPH_C32(0xf3d100f4), + SPH_C32(0x39e68000), SPH_C32(0x6de60000), SPH_C32(0x67db0000), + SPH_C32(0x6ec56af0), SPH_C32(0x724d1114), SPH_C32(0x725d978c), + SPH_C32(0x436a6052) }, + { SPH_C32(0x574200a0), SPH_C32(0xea8ac000), SPH_C32(0x44b80000), + SPH_C32(0x7d220000), SPH_C32(0x37ed424e), SPH_C32(0xf5801450), + SPH_C32(0x0f512bc8), SPH_C32(0xb245a39f), SPH_C32(0x545b00f9), + SPH_C32(0xb3ae0000), SPH_C32(0x93cb0000), SPH_C32(0x7aaf0000), + SPH_C32(0x77ec255f), SPH_C32(0x6bd75cf3), SPH_C32(0xe972aa54), + SPH_C32(0xa6672ef1) }, + { SPH_C32(0xf13d00a1), SPH_C32(0x9bbd4000), SPH_C32(0x5d440000), + SPH_C32(0xebf90000), SPH_C32(0x0d662fb3), SPH_C32(0x1e4abaa3), + SPH_C32(0x233c6c47), SPH_C32(0x1ecbcf17), SPH_C32(0x04a400fd), + SPH_C32(0xf6da4000), SPH_C32(0xae300000), SPH_C32(0x63490000), + SPH_C32(0x6c507359), SPH_C32(0x8aa527ae), SPH_C32(0x08da66c2), + SPH_C32(0xdd7cf848) }, + { SPH_C32(0xa03700a9), SPH_C32(0x25b60000), SPH_C32(0x876e0000), + SPH_C32(0x79b00000), SPH_C32(0x35785be7), SPH_C32(0x0d6822ea), + SPH_C32(0x75d6da86), SPH_C32(0x2c533b85), SPH_C32(0x803100f9), + SPH_C32(0x3e66c000), SPH_C32(0x36640000), SPH_C32(0x30860000), + SPH_C32(0x8ba26725), SPH_C32(0xa263da9f), SPH_C32(0x71443c50), + SPH_C32(0x5121edd1) }, + { SPH_C32(0x064800a8), SPH_C32(0x54818000), SPH_C32(0x9e920000), + SPH_C32(0xef6b0000), SPH_C32(0x0ff3361a), SPH_C32(0xe6a28c19), + SPH_C32(0x59bb9d09), SPH_C32(0x80dd570d), SPH_C32(0xd0ce00fd), + SPH_C32(0x7b128000), SPH_C32(0x0b9f0000), SPH_C32(0x29600000), + SPH_C32(0x901e3123), SPH_C32(0x4311a1c2), SPH_C32(0x90ecf0c6), + SPH_C32(0x2a3a3b68) } +}; + +static const sph_u32 T512_15[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x75a40000), SPH_C32(0xc28b2700), SPH_C32(0x94a40000), + SPH_C32(0x90f50000), SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), + SPH_C32(0x1767c483), SPH_C32(0xaedf667e), SPH_C32(0xd1660000), + SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), SPH_C32(0xf6940000), + SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), SPH_C32(0xb4431b17), + SPH_C32(0x857f3c2b) }, + { SPH_C32(0xd1660000), SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), + SPH_C32(0xf6940000), SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), + SPH_C32(0xb4431b17), SPH_C32(0x857f3c2b), SPH_C32(0xa4c20000), + SPH_C32(0xd9372400), SPH_C32(0x0a480000), SPH_C32(0x66610000), + SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), SPH_C32(0xa324df94), + SPH_C32(0x2ba05a55) }, + { SPH_C32(0xa4c20000), SPH_C32(0xd9372400), SPH_C32(0x0a480000), + SPH_C32(0x66610000), SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), + SPH_C32(0xa324df94), SPH_C32(0x2ba05a55), SPH_C32(0x75a40000), + SPH_C32(0xc28b2700), SPH_C32(0x94a40000), SPH_C32(0x90f50000), + SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), SPH_C32(0x1767c483), + SPH_C32(0xaedf667e) }, + { SPH_C32(0x75c90003), SPH_C32(0x0e10c000), SPH_C32(0xd1200000), + SPH_C32(0xbaea0000), SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), + SPH_C32(0xbb28761d), SPH_C32(0x00b72e2b), SPH_C32(0xeecf0001), + SPH_C32(0x6f564000), SPH_C32(0xf33e0000), SPH_C32(0xa79e0000), + SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), SPH_C32(0x4a3b40ba), + SPH_C32(0xfeabf254) }, + { SPH_C32(0x006d0003), SPH_C32(0xcc9be700), SPH_C32(0x45840000), + SPH_C32(0x2a1f0000), SPH_C32(0x70bc78de), SPH_C32(0xce96bcf9), + SPH_C32(0xac4fb29e), SPH_C32(0xae684855), SPH_C32(0x3fa90001), + SPH_C32(0x74ea4300), SPH_C32(0x6dd20000), SPH_C32(0x510a0000), + SPH_C32(0xbeb7373e), SPH_C32(0x78611737), SPH_C32(0xfe785bad), + SPH_C32(0x7bd4ce7f) }, + { SPH_C32(0xa4af0003), SPH_C32(0x15acc300), SPH_C32(0x4fcc0000), + SPH_C32(0x4c7e0000), SPH_C32(0x88c66a19), SPH_C32(0x48284ba5), + SPH_C32(0x0f6b6d0a), SPH_C32(0x85c81200), SPH_C32(0x4a0d0001), + SPH_C32(0xb6616400), SPH_C32(0xf9760000), SPH_C32(0xc1ff0000), + SPH_C32(0x45cf60de), SPH_C32(0x31af1c99), SPH_C32(0xe91f9f2e), + SPH_C32(0xd50ba801) }, + { SPH_C32(0xd10b0003), SPH_C32(0xd727e400), SPH_C32(0xdb680000), + SPH_C32(0xdc8b0000), SPH_C32(0x73be3df9), SPH_C32(0x01e6400b), + SPH_C32(0x180ca989), SPH_C32(0x2b17747e), SPH_C32(0x9b6b0001), + SPH_C32(0xaddd6700), SPH_C32(0x679a0000), SPH_C32(0x376b0000), + SPH_C32(0x46cd25f9), SPH_C32(0xfedfe06b), SPH_C32(0x5d5c8439), + SPH_C32(0x5074942a) }, + { SPH_C32(0xeecf0001), SPH_C32(0x6f564000), SPH_C32(0xf33e0000), + SPH_C32(0xa79e0000), SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), + SPH_C32(0x4a3b40ba), SPH_C32(0xfeabf254), SPH_C32(0x9b060002), + SPH_C32(0x61468000), SPH_C32(0x221e0000), SPH_C32(0x1d740000), + SPH_C32(0x36715d27), SPH_C32(0x30495c92), SPH_C32(0xf11336a7), + SPH_C32(0xfe1cdc7f) }, + { SPH_C32(0x9b6b0001), SPH_C32(0xaddd6700), SPH_C32(0x679a0000), + SPH_C32(0x376b0000), SPH_C32(0x46cd25f9), SPH_C32(0xfedfe06b), + SPH_C32(0x5d5c8439), SPH_C32(0x5074942a), SPH_C32(0x4a600002), + SPH_C32(0x7afa8300), SPH_C32(0xbcf20000), SPH_C32(0xebe00000), + SPH_C32(0x35731800), SPH_C32(0xff39a060), SPH_C32(0x45502db0), + SPH_C32(0x7b63e054) }, + { SPH_C32(0x3fa90001), SPH_C32(0x74ea4300), SPH_C32(0x6dd20000), + SPH_C32(0x510a0000), SPH_C32(0xbeb7373e), SPH_C32(0x78611737), + SPH_C32(0xfe785bad), SPH_C32(0x7bd4ce7f), SPH_C32(0x3fc40002), + SPH_C32(0xb871a400), SPH_C32(0x28560000), SPH_C32(0x7b150000), + SPH_C32(0xce0b4fe0), SPH_C32(0xb6f7abce), SPH_C32(0x5237e933), + SPH_C32(0xd5bc862a) }, + { SPH_C32(0x4a0d0001), SPH_C32(0xb6616400), SPH_C32(0xf9760000), + SPH_C32(0xc1ff0000), SPH_C32(0x45cf60de), SPH_C32(0x31af1c99), + SPH_C32(0xe91f9f2e), SPH_C32(0xd50ba801), SPH_C32(0xeea20002), + SPH_C32(0xa3cda700), SPH_C32(0xb6ba0000), SPH_C32(0x8d810000), + SPH_C32(0xcd090ac7), SPH_C32(0x7987573c), SPH_C32(0xe674f224), + SPH_C32(0x50c3ba01) }, + { SPH_C32(0x9b060002), SPH_C32(0x61468000), SPH_C32(0x221e0000), + SPH_C32(0x1d740000), SPH_C32(0x36715d27), SPH_C32(0x30495c92), + SPH_C32(0xf11336a7), SPH_C32(0xfe1cdc7f), SPH_C32(0x75c90003), + SPH_C32(0x0e10c000), SPH_C32(0xd1200000), SPH_C32(0xbaea0000), + SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), SPH_C32(0xbb28761d), + SPH_C32(0x00b72e2b) }, + { SPH_C32(0xeea20002), SPH_C32(0xa3cda700), SPH_C32(0xb6ba0000), + SPH_C32(0x8d810000), SPH_C32(0xcd090ac7), SPH_C32(0x7987573c), + SPH_C32(0xe674f224), SPH_C32(0x50c3ba01), SPH_C32(0xa4af0003), + SPH_C32(0x15acc300), SPH_C32(0x4fcc0000), SPH_C32(0x4c7e0000), + SPH_C32(0x88c66a19), SPH_C32(0x48284ba5), SPH_C32(0x0f6b6d0a), + SPH_C32(0x85c81200) }, + { SPH_C32(0x4a600002), SPH_C32(0x7afa8300), SPH_C32(0xbcf20000), + SPH_C32(0xebe00000), SPH_C32(0x35731800), SPH_C32(0xff39a060), + SPH_C32(0x45502db0), SPH_C32(0x7b63e054), SPH_C32(0xd10b0003), + SPH_C32(0xd727e400), SPH_C32(0xdb680000), SPH_C32(0xdc8b0000), + SPH_C32(0x73be3df9), SPH_C32(0x01e6400b), SPH_C32(0x180ca989), + SPH_C32(0x2b17747e) }, + { SPH_C32(0x3fc40002), SPH_C32(0xb871a400), SPH_C32(0x28560000), + SPH_C32(0x7b150000), SPH_C32(0xce0b4fe0), SPH_C32(0xb6f7abce), + SPH_C32(0x5237e933), SPH_C32(0xd5bc862a), SPH_C32(0x006d0003), + SPH_C32(0xcc9be700), SPH_C32(0x45840000), SPH_C32(0x2a1f0000), + SPH_C32(0x70bc78de), SPH_C32(0xce96bcf9), SPH_C32(0xac4fb29e), + SPH_C32(0xae684855) }, + { SPH_C32(0xf6800005), SPH_C32(0x3443c000), SPH_C32(0x24070000), + SPH_C32(0x8f3d0000), SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), + SPH_C32(0xcdc58b19), SPH_C32(0xd795ba31), SPH_C32(0xa67f0001), + SPH_C32(0x71378000), SPH_C32(0x19fc0000), SPH_C32(0x96db0000), + SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), SPH_C32(0x2c6d478f), + SPH_C32(0xac8e6c88) }, + { SPH_C32(0x83240005), SPH_C32(0xf6c8e700), SPH_C32(0xb0a30000), + SPH_C32(0x1fc80000), SPH_C32(0xda4f6c1b), SPH_C32(0x4376de00), + SPH_C32(0xdaa24f9a), SPH_C32(0x794adc4f), SPH_C32(0x77190001), + SPH_C32(0x6a8b8300), SPH_C32(0x87100000), SPH_C32(0x604f0000), + SPH_C32(0x398928da), SPH_C32(0x24ba5201), SPH_C32(0x982e5c98), + SPH_C32(0x29f150a3) }, + { SPH_C32(0x27e60005), SPH_C32(0x2fffc300), SPH_C32(0xbaeb0000), + SPH_C32(0x79a90000), SPH_C32(0x22357edc), SPH_C32(0xc5c8295c), + SPH_C32(0x7986900e), SPH_C32(0x52ea861a), SPH_C32(0x02bd0001), + SPH_C32(0xa800a400), SPH_C32(0x13b40000), SPH_C32(0xf0ba0000), + SPH_C32(0xc2f17f3a), SPH_C32(0x6d7459af), SPH_C32(0x8f49981b), + SPH_C32(0x872e36dd) }, + { SPH_C32(0x52420005), SPH_C32(0xed74e400), SPH_C32(0x2e4f0000), + SPH_C32(0xe95c0000), SPH_C32(0xd94d293c), SPH_C32(0x8c0622f2), + SPH_C32(0x6ee1548d), SPH_C32(0xfc35e064), SPH_C32(0xd3db0001), + SPH_C32(0xb3bca700), SPH_C32(0x8d580000), SPH_C32(0x062e0000), + SPH_C32(0xc1f33a1d), SPH_C32(0xa204a55d), SPH_C32(0x3b0a830c), + SPH_C32(0x02510af6) }, + { SPH_C32(0x83490006), SPH_C32(0x3a530000), SPH_C32(0xf5270000), + SPH_C32(0x35d70000), SPH_C32(0xaaf314c5), SPH_C32(0x8de062f9), + SPH_C32(0x76edfd04), SPH_C32(0xd722941a), SPH_C32(0x48b00000), + SPH_C32(0x1e61c000), SPH_C32(0xeac20000), SPH_C32(0x31450000), + SPH_C32(0x873e1fe4), SPH_C32(0x5cdb4536), SPH_C32(0x66560735), + SPH_C32(0x52259edc) }, + { SPH_C32(0xf6ed0006), SPH_C32(0xf8d82700), SPH_C32(0x61830000), + SPH_C32(0xa5220000), SPH_C32(0x518b4325), SPH_C32(0xc42e6957), + SPH_C32(0x618a3987), SPH_C32(0x79fdf264), SPH_C32(0x99d60000), + SPH_C32(0x05ddc300), SPH_C32(0x742e0000), SPH_C32(0xc7d10000), + SPH_C32(0x843c5ac3), SPH_C32(0x93abb9c4), SPH_C32(0xd2151c22), + SPH_C32(0xd75aa2f7) }, + { SPH_C32(0x522f0006), SPH_C32(0x21ef0300), SPH_C32(0x6bcb0000), + SPH_C32(0xc3430000), SPH_C32(0xa9f151e2), SPH_C32(0x42909e0b), + SPH_C32(0xc2aee613), SPH_C32(0x525da831), SPH_C32(0xec720000), + SPH_C32(0xc756e400), SPH_C32(0xe08a0000), SPH_C32(0x57240000), + SPH_C32(0x7f440d23), SPH_C32(0xda65b26a), SPH_C32(0xc572d8a1), + SPH_C32(0x7985c489) }, + { SPH_C32(0x278b0006), SPH_C32(0xe3642400), SPH_C32(0xff6f0000), + SPH_C32(0x53b60000), SPH_C32(0x52890602), SPH_C32(0x0b5e95a5), + SPH_C32(0xd5c92290), SPH_C32(0xfc82ce4f), SPH_C32(0x3d140000), + SPH_C32(0xdceae700), SPH_C32(0x7e660000), SPH_C32(0xa1b00000), + SPH_C32(0x7c464804), SPH_C32(0x15154e98), SPH_C32(0x7131c3b6), + SPH_C32(0xfcfaf8a2) }, + { SPH_C32(0x184f0004), SPH_C32(0x5b158000), SPH_C32(0xd7390000), + SPH_C32(0x28a30000), SPH_C32(0x9c8249e2), SPH_C32(0xbda93e6b), + SPH_C32(0x87fecba3), SPH_C32(0x293e4865), SPH_C32(0x3d790003), + SPH_C32(0x10710000), SPH_C32(0x3be20000), SPH_C32(0x8baf0000), + SPH_C32(0x0cfa30da), SPH_C32(0xdb83f261), SPH_C32(0xdd7e7128), + SPH_C32(0x5292b0f7) }, + { SPH_C32(0x6deb0004), SPH_C32(0x999ea700), SPH_C32(0x439d0000), + SPH_C32(0xb8560000), SPH_C32(0x67fa1e02), SPH_C32(0xf46735c5), + SPH_C32(0x90990f20), SPH_C32(0x87e12e1b), SPH_C32(0xec1f0003), + SPH_C32(0x0bcd0300), SPH_C32(0xa50e0000), SPH_C32(0x7d3b0000), + SPH_C32(0x0ff875fd), SPH_C32(0x14f30e93), SPH_C32(0x693d6a3f), + SPH_C32(0xd7ed8cdc) }, + { SPH_C32(0xc9290004), SPH_C32(0x40a98300), SPH_C32(0x49d50000), + SPH_C32(0xde370000), SPH_C32(0x9f800cc5), SPH_C32(0x72d9c299), + SPH_C32(0x33bdd0b4), SPH_C32(0xac41744e), SPH_C32(0x99bb0003), + SPH_C32(0xc9462400), SPH_C32(0x31aa0000), SPH_C32(0xedce0000), + SPH_C32(0xf480221d), SPH_C32(0x5d3d053d), SPH_C32(0x7e5aaebc), + SPH_C32(0x7932eaa2) }, + { SPH_C32(0xbc8d0004), SPH_C32(0x8222a400), SPH_C32(0xdd710000), + SPH_C32(0x4ec20000), SPH_C32(0x64f85b25), SPH_C32(0x3b17c937), + SPH_C32(0x24da1437), SPH_C32(0x029e1230), SPH_C32(0x48dd0003), + SPH_C32(0xd2fa2700), SPH_C32(0xaf460000), SPH_C32(0x1b5a0000), + SPH_C32(0xf782673a), SPH_C32(0x924df9cf), SPH_C32(0xca19b5ab), + SPH_C32(0xfc4dd689) }, + { SPH_C32(0x6d860007), SPH_C32(0x55054000), SPH_C32(0x06190000), + SPH_C32(0x92490000), SPH_C32(0x174666dc), SPH_C32(0x3af1893c), + SPH_C32(0x3cd6bdbe), SPH_C32(0x2989664e), SPH_C32(0xd3b60002), + SPH_C32(0x7f274000), SPH_C32(0xc8dc0000), SPH_C32(0x2c310000), + SPH_C32(0xb14f42c3), SPH_C32(0x6c9219a4), SPH_C32(0x97453192), + SPH_C32(0xac3942a3) }, + { SPH_C32(0x18220007), SPH_C32(0x978e6700), SPH_C32(0x92bd0000), + SPH_C32(0x02bc0000), SPH_C32(0xec3e313c), SPH_C32(0x733f8292), + SPH_C32(0x2bb1793d), SPH_C32(0x87560030), SPH_C32(0x02d00002), + SPH_C32(0x649b4300), SPH_C32(0x56300000), SPH_C32(0xdaa50000), + SPH_C32(0xb24d07e4), SPH_C32(0xa3e2e556), SPH_C32(0x23062a85), + SPH_C32(0x29467e88) }, + { SPH_C32(0xbce00007), SPH_C32(0x4eb94300), SPH_C32(0x98f50000), + SPH_C32(0x64dd0000), SPH_C32(0x144423fb), SPH_C32(0xf58175ce), + SPH_C32(0x8895a6a9), SPH_C32(0xacf65a65), SPH_C32(0x77740002), + SPH_C32(0xa6106400), SPH_C32(0xc2940000), SPH_C32(0x4a500000), + SPH_C32(0x49355004), SPH_C32(0xea2ceef8), SPH_C32(0x3461ee06), + SPH_C32(0x879918f6) }, + { SPH_C32(0xc9440007), SPH_C32(0x8c326400), SPH_C32(0x0c510000), + SPH_C32(0xf4280000), SPH_C32(0xef3c741b), SPH_C32(0xbc4f7e60), + SPH_C32(0x9ff2622a), SPH_C32(0x02293c1b), SPH_C32(0xa6120002), + SPH_C32(0xbdac6700), SPH_C32(0x5c780000), SPH_C32(0xbcc40000), + SPH_C32(0x4a371523), SPH_C32(0x255c120a), SPH_C32(0x8022f511), + SPH_C32(0x02e624dd) } +}; + +static const sph_u32 T512_20[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xc6730000), SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), + SPH_C32(0x218d0000), SPH_C32(0x23111587), SPH_C32(0x7913512f), + SPH_C32(0x1d28ac88), SPH_C32(0x378dd173), SPH_C32(0xaf220000), + SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), SPH_C32(0x8da20000), + SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), SPH_C32(0x9ac484f4), + SPH_C32(0x8b6c72bd) }, + { SPH_C32(0x0c720000), SPH_C32(0x49e50f00), SPH_C32(0x42790000), + SPH_C32(0x5cea0000), SPH_C32(0x33aa301a), SPH_C32(0x15822514), + SPH_C32(0x95a34b7b), SPH_C32(0xb44b0090), SPH_C32(0xfe220000), + SPH_C32(0xa7580500), SPH_C32(0x25d10000), SPH_C32(0xf7600000), + SPH_C32(0x893178da), SPH_C32(0x1fd4f860), SPH_C32(0x4ed0a315), + SPH_C32(0xa123ff9f) }, + { SPH_C32(0xca010000), SPH_C32(0xe6680f0c), SPH_C32(0xe6b80000), + SPH_C32(0x7d670000), SPH_C32(0x10bb259d), SPH_C32(0x6c91743b), + SPH_C32(0x888be7f3), SPH_C32(0x83c6d1e3), SPH_C32(0x51000000), + SPH_C32(0xdc340590), SPH_C32(0x42330000), SPH_C32(0x7ac20000), + SPH_C32(0x4eb566f3), SPH_C32(0xa863bc93), SPH_C32(0xd41427e1), + SPH_C32(0x2a4f8d22) }, + { SPH_C32(0xfe220000), SPH_C32(0xa7580500), SPH_C32(0x25d10000), + SPH_C32(0xf7600000), SPH_C32(0x893178da), SPH_C32(0x1fd4f860), + SPH_C32(0x4ed0a315), SPH_C32(0xa123ff9f), SPH_C32(0xf2500000), + SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), SPH_C32(0xab8a0000), + SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), SPH_C32(0xdb73e86e), + SPH_C32(0x1568ff0f) }, + { SPH_C32(0x38510000), SPH_C32(0x08d5050c), SPH_C32(0x81100000), + SPH_C32(0xd6ed0000), SPH_C32(0xaa206d5d), SPH_C32(0x66c7a94f), + SPH_C32(0x53f80f9d), SPH_C32(0x96ae2eec), SPH_C32(0x5d720000), + SPH_C32(0x95d10a90), SPH_C32(0x004a0000), SPH_C32(0x26280000), + SPH_C32(0x7d1f56e9), SPH_C32(0xbde19987), SPH_C32(0x41b76c9a), + SPH_C32(0x9e048db2) }, + { SPH_C32(0xf2500000), SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), + SPH_C32(0xab8a0000), SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), + SPH_C32(0xdb73e86e), SPH_C32(0x1568ff0f), SPH_C32(0x0c720000), + SPH_C32(0x49e50f00), SPH_C32(0x42790000), SPH_C32(0x5cea0000), + SPH_C32(0x33aa301a), SPH_C32(0x15822514), SPH_C32(0x95a34b7b), + SPH_C32(0xb44b0090) }, + { SPH_C32(0x34230000), SPH_C32(0x41300a0c), SPH_C32(0xc3690000), + SPH_C32(0x8a070000), SPH_C32(0x998a5d47), SPH_C32(0x73458c5b), + SPH_C32(0xc65b44e6), SPH_C32(0x22e52e7c), SPH_C32(0xa3500000), + SPH_C32(0x32890f90), SPH_C32(0x259b0000), SPH_C32(0xd1480000), + SPH_C32(0xf42e2e33), SPH_C32(0xa23561e7), SPH_C32(0x0f67cf8f), + SPH_C32(0x3f27722d) }, + { SPH_C32(0x45180000), SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), + SPH_C32(0x3b480000), SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), + SPH_C32(0x16bca6b0), SPH_C32(0xdf33f4df), SPH_C32(0xb83d0000), + SPH_C32(0x16710600), SPH_C32(0x379a0000), SPH_C32(0xf5b10000), + SPH_C32(0x228161ac), SPH_C32(0xae48f145), SPH_C32(0x66241616), + SPH_C32(0xc5c1eb3e) }, + { SPH_C32(0x836b0000), SPH_C32(0x0a38170c), SPH_C32(0x5dab0000), + SPH_C32(0x1ac50000), SPH_C32(0x3ddd01ab), SPH_C32(0x5a00c4f9), + SPH_C32(0x0b940a38), SPH_C32(0xe8be25ac), SPH_C32(0x171f0000), + SPH_C32(0x6d1d0690), SPH_C32(0x50780000), SPH_C32(0x78130000), + SPH_C32(0xe5057f85), SPH_C32(0x19ffb5b6), SPH_C32(0xfce092e2), + SPH_C32(0x4ead9983) }, + { SPH_C32(0x496a0000), SPH_C32(0xec501800), SPH_C32(0xbb130000), + SPH_C32(0x67a20000), SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), + SPH_C32(0x831fedcb), SPH_C32(0x6b78f44f), SPH_C32(0x461f0000), + SPH_C32(0xb1290300), SPH_C32(0x124b0000), SPH_C32(0x02d10000), + SPH_C32(0xabb01976), SPH_C32(0xb19c0925), SPH_C32(0x28f4b503), + SPH_C32(0x64e214a1) }, + { SPH_C32(0x8f190000), SPH_C32(0x43dd180c), SPH_C32(0x1fd20000), + SPH_C32(0x462f0000), SPH_C32(0x0e7731b1), SPH_C32(0x4f82e1ed), + SPH_C32(0x9e374143), SPH_C32(0x5cf5253c), SPH_C32(0xe93d0000), + SPH_C32(0xca450390), SPH_C32(0x75a90000), SPH_C32(0x8f730000), + SPH_C32(0x6c34075f), SPH_C32(0x062b4dd6), SPH_C32(0xb23031f7), + SPH_C32(0xef8e661c) }, + { SPH_C32(0xbb3a0000), SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), + SPH_C32(0xcc280000), SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), + SPH_C32(0x586c05a5), SPH_C32(0x7e100b40), SPH_C32(0x4a6d0000), + SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), SPH_C32(0x5e3b0000), + SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), SPH_C32(0xbd57fe78), + SPH_C32(0xd0a91431) }, + { SPH_C32(0x7d490000), SPH_C32(0xad60120c), SPH_C32(0x787a0000), + SPH_C32(0xeda50000), SPH_C32(0xb4ec7971), SPH_C32(0x45d43c99), + SPH_C32(0x4544a92d), SPH_C32(0x499dda33), SPH_C32(0xe54f0000), + SPH_C32(0x83a00c90), SPH_C32(0x37d00000), SPH_C32(0xd3990000), + SPH_C32(0x5f9e3745), SPH_C32(0x13a968c2), SPH_C32(0x27937a8c), + SPH_C32(0x5bc5668c) }, + { SPH_C32(0xb7480000), SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), + SPH_C32(0x90c20000), SPH_C32(0xa4575cec), SPH_C32(0x294548a2), + SPH_C32(0xcdcf4ede), SPH_C32(0xca5b0bd0), SPH_C32(0xb44f0000), + SPH_C32(0x5f940900), SPH_C32(0x75e30000), SPH_C32(0xa95b0000), + SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), SPH_C32(0xf3875d6d), + SPH_C32(0x718aebae) }, + { SPH_C32(0x713b0000), SPH_C32(0xe4851d0c), SPH_C32(0x3a030000), + SPH_C32(0xb14f0000), SPH_C32(0x8746496b), SPH_C32(0x5056198d), + SPH_C32(0xd0e7e256), SPH_C32(0xfdd6daa3), SPH_C32(0x1b6d0000), + SPH_C32(0x24f80990), SPH_C32(0x12010000), SPH_C32(0x24f90000), + SPH_C32(0xd6af4f9f), SPH_C32(0x0c7d90a2), SPH_C32(0x6943d999), + SPH_C32(0xfae69913) }, + { SPH_C32(0xb83d0000), SPH_C32(0x16710600), SPH_C32(0x379a0000), + SPH_C32(0xf5b10000), SPH_C32(0x228161ac), SPH_C32(0xae48f145), + SPH_C32(0x66241616), SPH_C32(0xc5c1eb3e), SPH_C32(0xfd250000), + SPH_C32(0xb3c41100), SPH_C32(0xcef00000), SPH_C32(0xcef90000), + SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), SPH_C32(0x7098b0a6), + SPH_C32(0x1af21fe1) }, + { SPH_C32(0x7e4e0000), SPH_C32(0xb9fc060c), SPH_C32(0x935b0000), + SPH_C32(0xd43c0000), SPH_C32(0x0190742b), SPH_C32(0xd75ba06a), + SPH_C32(0x7b0cba9e), SPH_C32(0xf24c3a4d), SPH_C32(0x52070000), + SPH_C32(0xc8a81190), SPH_C32(0xa9120000), SPH_C32(0x435b0000), + SPH_C32(0xfbc96ba9), SPH_C32(0x3aec2060), SPH_C32(0xea5c3452), + SPH_C32(0x919e6d5c) }, + { SPH_C32(0xb44f0000), SPH_C32(0x5f940900), SPH_C32(0x75e30000), + SPH_C32(0xa95b0000), SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), + SPH_C32(0xf3875d6d), SPH_C32(0x718aebae), SPH_C32(0x03070000), + SPH_C32(0x149c1400), SPH_C32(0xeb210000), SPH_C32(0x39990000), + SPH_C32(0xb57c0d5a), SPH_C32(0x928f9cf3), SPH_C32(0x3e4813b3), + SPH_C32(0xbbd1e07e) }, + { SPH_C32(0x723c0000), SPH_C32(0xf019090c), SPH_C32(0xd1220000), + SPH_C32(0x88d60000), SPH_C32(0x323a4431), SPH_C32(0xc2d9857e), + SPH_C32(0xeeaff1e5), SPH_C32(0x46073add), SPH_C32(0xac250000), + SPH_C32(0x6ff01490), SPH_C32(0x8cc30000), SPH_C32(0xb43b0000), + SPH_C32(0x72f81373), SPH_C32(0x2538d800), SPH_C32(0xa48c9747), + SPH_C32(0x30bd92c3) }, + { SPH_C32(0x461f0000), SPH_C32(0xb1290300), SPH_C32(0x124b0000), + SPH_C32(0x02d10000), SPH_C32(0xabb01976), SPH_C32(0xb19c0925), + SPH_C32(0x28f4b503), SPH_C32(0x64e214a1), SPH_C32(0x0f750000), + SPH_C32(0x5d791b00), SPH_C32(0xa9580000), SPH_C32(0x65730000), + SPH_C32(0x86d63d40), SPH_C32(0x870db9e7), SPH_C32(0xabeb58c8), + SPH_C32(0x0f9ae0ee) }, + { SPH_C32(0x806c0000), SPH_C32(0x1ea4030c), SPH_C32(0xb68a0000), + SPH_C32(0x235c0000), SPH_C32(0x88a10cf1), SPH_C32(0xc88f580a), + SPH_C32(0x35dc198b), SPH_C32(0x536fc5d2), SPH_C32(0xa0570000), + SPH_C32(0x26151b90), SPH_C32(0xceba0000), SPH_C32(0xe8d10000), + SPH_C32(0x41522369), SPH_C32(0x30bafd14), SPH_C32(0x312fdc3c), + SPH_C32(0x84f69253) }, + { SPH_C32(0x4a6d0000), SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), + SPH_C32(0x5e3b0000), SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), + SPH_C32(0xbd57fe78), SPH_C32(0xd0a91431), SPH_C32(0xf1570000), + SPH_C32(0xfa211e00), SPH_C32(0x8c890000), SPH_C32(0x92130000), + SPH_C32(0x0fe7459a), SPH_C32(0x98d94187), SPH_C32(0xe53bfbdd), + SPH_C32(0xaeb91f71) }, + { SPH_C32(0x8c1e0000), SPH_C32(0x57410c0c), SPH_C32(0xf4f30000), + SPH_C32(0x7fb60000), SPH_C32(0xbb0b3ceb), SPH_C32(0xdd0d7d1e), + SPH_C32(0xa07f52f0), SPH_C32(0xe724c542), SPH_C32(0x5e750000), + SPH_C32(0x814d1e90), SPH_C32(0xeb6b0000), SPH_C32(0x1fb10000), + SPH_C32(0xc8635bb3), SPH_C32(0x2f6e0574), SPH_C32(0x7fff7f29), + SPH_C32(0x25d56dcc) }, + { SPH_C32(0xfd250000), SPH_C32(0xb3c41100), SPH_C32(0xcef00000), + SPH_C32(0xcef90000), SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), + SPH_C32(0x7098b0a6), SPH_C32(0x1af21fe1), SPH_C32(0x45180000), + SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), SPH_C32(0x3b480000), + SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), SPH_C32(0x16bca6b0), + SPH_C32(0xdf33f4df) }, + { SPH_C32(0x3b560000), SPH_C32(0x1c49110c), SPH_C32(0x6a310000), + SPH_C32(0xef740000), SPH_C32(0x1f5c6007), SPH_C32(0xf44835bc), + SPH_C32(0x6db01c2e), SPH_C32(0x2d7fce92), SPH_C32(0xea3a0000), + SPH_C32(0xded91790), SPH_C32(0x9e880000), SPH_C32(0xb6ea0000), + SPH_C32(0xd9480a05), SPH_C32(0x94a4d125), SPH_C32(0x8c782244), + SPH_C32(0x545f8662) }, + { SPH_C32(0xf1570000), SPH_C32(0xfa211e00), SPH_C32(0x8c890000), + SPH_C32(0x92130000), SPH_C32(0x0fe7459a), SPH_C32(0x98d94187), + SPH_C32(0xe53bfbdd), SPH_C32(0xaeb91f71), SPH_C32(0xbb3a0000), + SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), SPH_C32(0xcc280000), + SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), SPH_C32(0x586c05a5), + SPH_C32(0x7e100b40) }, + { SPH_C32(0x37240000), SPH_C32(0x55ac1e0c), SPH_C32(0x28480000), + SPH_C32(0xb39e0000), SPH_C32(0x2cf6501d), SPH_C32(0xe1ca10a8), + SPH_C32(0xf8135755), SPH_C32(0x9934ce02), SPH_C32(0x14180000), + SPH_C32(0x79811290), SPH_C32(0xbb590000), SPH_C32(0x418a0000), + SPH_C32(0x507972df), SPH_C32(0x8b702945), SPH_C32(0xc2a88151), + SPH_C32(0xf57c79fd) }, + { SPH_C32(0x03070000), SPH_C32(0x149c1400), SPH_C32(0xeb210000), + SPH_C32(0x39990000), SPH_C32(0xb57c0d5a), SPH_C32(0x928f9cf3), + SPH_C32(0x3e4813b3), SPH_C32(0xbbd1e07e), SPH_C32(0xb7480000), + SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), SPH_C32(0x90c20000), + SPH_C32(0xa4575cec), SPH_C32(0x294548a2), SPH_C32(0xcdcf4ede), + SPH_C32(0xca5b0bd0) }, + { SPH_C32(0xc5740000), SPH_C32(0xbb11140c), SPH_C32(0x4fe00000), + SPH_C32(0x18140000), SPH_C32(0x966d18dd), SPH_C32(0xeb9ccddc), + SPH_C32(0x2360bf3b), SPH_C32(0x8c5c310d), SPH_C32(0x186a0000), + SPH_C32(0x30641d90), SPH_C32(0xf9200000), SPH_C32(0x1d600000), + SPH_C32(0x63d342c5), SPH_C32(0x9ef20c51), SPH_C32(0x570bca2a), + SPH_C32(0x4137796d) }, + { SPH_C32(0x0f750000), SPH_C32(0x5d791b00), SPH_C32(0xa9580000), + SPH_C32(0x65730000), SPH_C32(0x86d63d40), SPH_C32(0x870db9e7), + SPH_C32(0xabeb58c8), SPH_C32(0x0f9ae0ee), SPH_C32(0x496a0000), + SPH_C32(0xec501800), SPH_C32(0xbb130000), SPH_C32(0x67a20000), + SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), SPH_C32(0x831fedcb), + SPH_C32(0x6b78f44f) }, + { SPH_C32(0xc9060000), SPH_C32(0xf2f41b0c), SPH_C32(0x0d990000), + SPH_C32(0x44fe0000), SPH_C32(0xa5c728c7), SPH_C32(0xfe1ee8c8), + SPH_C32(0xb6c3f440), SPH_C32(0x3817319d), SPH_C32(0xe6480000), + SPH_C32(0x973c1890), SPH_C32(0xdcf10000), SPH_C32(0xea000000), + SPH_C32(0xeae23a1f), SPH_C32(0x8126f431), SPH_C32(0x19db693f), + SPH_C32(0xe01486f2) } +}; + +static const sph_u32 T512_25[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x14190000), SPH_C32(0x23ca003c), SPH_C32(0x50df0000), + SPH_C32(0x44b60000), SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), + SPH_C32(0x61e610b0), SPH_C32(0xdbcadb80), SPH_C32(0xe3430000), + SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), SPH_C32(0xaa4e0000), + SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), SPH_C32(0x123db156), + SPH_C32(0x3a4e99d7) }, + { SPH_C32(0xe3430000), SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), + SPH_C32(0xaa4e0000), SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), + SPH_C32(0x123db156), SPH_C32(0x3a4e99d7), SPH_C32(0xf75a0000), + SPH_C32(0x19840028), SPH_C32(0xa2190000), SPH_C32(0xeef80000), + SPH_C32(0xc0722516), SPH_C32(0x19981260), SPH_C32(0x73dba1e6), + SPH_C32(0xe1844257) }, + { SPH_C32(0xf75a0000), SPH_C32(0x19840028), SPH_C32(0xa2190000), + SPH_C32(0xeef80000), SPH_C32(0xc0722516), SPH_C32(0x19981260), + SPH_C32(0x73dba1e6), SPH_C32(0xe1844257), SPH_C32(0x14190000), + SPH_C32(0x23ca003c), SPH_C32(0x50df0000), SPH_C32(0x44b60000), + SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), SPH_C32(0x61e610b0), + SPH_C32(0xdbcadb80) }, + { SPH_C32(0x54500000), SPH_C32(0x0671005c), SPH_C32(0x25ae0000), + SPH_C32(0x6a1e0000), SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), + SPH_C32(0xbfba18c3), SPH_C32(0x7e715d17), SPH_C32(0xbc8d0000), + SPH_C32(0xfc3b0018), SPH_C32(0x19830000), SPH_C32(0xd10b0000), + SPH_C32(0xae1878c4), SPH_C32(0x42a69856), SPH_C32(0x0012da37), + SPH_C32(0x2c3b504e) }, + { SPH_C32(0x40490000), SPH_C32(0x25bb0060), SPH_C32(0x75710000), + SPH_C32(0x2ea80000), SPH_C32(0x35c9296f), SPH_C32(0x5abd2967), + SPH_C32(0xde5c0873), SPH_C32(0xa5bb8697), SPH_C32(0x5fce0000), + SPH_C32(0xc675000c), SPH_C32(0xeb450000), SPH_C32(0x7b450000), + SPH_C32(0x75063a62), SPH_C32(0x67cd2643), SPH_C32(0x122f6b61), + SPH_C32(0x1675c999) }, + { SPH_C32(0xb7130000), SPH_C32(0x3c3f0048), SPH_C32(0xd7680000), + SPH_C32(0xc0500000), SPH_C32(0xf5bb0c79), SPH_C32(0x43253b07), + SPH_C32(0xad87a995), SPH_C32(0x443fc4c0), SPH_C32(0x4bd70000), + SPH_C32(0xe5bf0030), SPH_C32(0xbb9a0000), SPH_C32(0x3ff30000), + SPH_C32(0x6e6a5dd2), SPH_C32(0x5b3e8a36), SPH_C32(0x73c97bd1), + SPH_C32(0xcdbf1219) }, + { SPH_C32(0xa30a0000), SPH_C32(0x1ff50074), SPH_C32(0x87b70000), + SPH_C32(0x84e60000), SPH_C32(0xeed76bc9), SPH_C32(0x7fd69772), + SPH_C32(0xcc61b925), SPH_C32(0x9ff51f40), SPH_C32(0xa8940000), + SPH_C32(0xdff10024), SPH_C32(0x495c0000), SPH_C32(0x95bd0000), + SPH_C32(0xb5741f74), SPH_C32(0x7e553423), SPH_C32(0x61f4ca87), + SPH_C32(0xf7f18bce) }, + { SPH_C32(0xbc8d0000), SPH_C32(0xfc3b0018), SPH_C32(0x19830000), + SPH_C32(0xd10b0000), SPH_C32(0xae1878c4), SPH_C32(0x42a69856), + SPH_C32(0x0012da37), SPH_C32(0x2c3b504e), SPH_C32(0xe8dd0000), + SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), SPH_C32(0xbb150000), + SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), SPH_C32(0xbfa8c2f4), + SPH_C32(0x524a0d59) }, + { SPH_C32(0xa8940000), SPH_C32(0xdff10024), SPH_C32(0x495c0000), + SPH_C32(0x95bd0000), SPH_C32(0xb5741f74), SPH_C32(0x7e553423), + SPH_C32(0x61f4ca87), SPH_C32(0xf7f18bce), SPH_C32(0x0b9e0000), + SPH_C32(0xc0040050), SPH_C32(0xceeb0000), SPH_C32(0x115b0000), + SPH_C32(0x5ba374bd), SPH_C32(0x0183a351), SPH_C32(0xad9573a2), + SPH_C32(0x6804948e) }, + { SPH_C32(0x5fce0000), SPH_C32(0xc675000c), SPH_C32(0xeb450000), + SPH_C32(0x7b450000), SPH_C32(0x75063a62), SPH_C32(0x67cd2643), + SPH_C32(0x122f6b61), SPH_C32(0x1675c999), SPH_C32(0x1f870000), + SPH_C32(0xe3ce006c), SPH_C32(0x9e340000), SPH_C32(0x55ed0000), + SPH_C32(0x40cf130d), SPH_C32(0x3d700f24), SPH_C32(0xcc736312), + SPH_C32(0xb3ce4f0e) }, + { SPH_C32(0x4bd70000), SPH_C32(0xe5bf0030), SPH_C32(0xbb9a0000), + SPH_C32(0x3ff30000), SPH_C32(0x6e6a5dd2), SPH_C32(0x5b3e8a36), + SPH_C32(0x73c97bd1), SPH_C32(0xcdbf1219), SPH_C32(0xfcc40000), + SPH_C32(0xd9800078), SPH_C32(0x6cf20000), SPH_C32(0xffa30000), + SPH_C32(0x9bd151ab), SPH_C32(0x181bb131), SPH_C32(0xde4ed244), + SPH_C32(0x8980d6d9) }, + { SPH_C32(0xe8dd0000), SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), + SPH_C32(0xbb150000), SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), + SPH_C32(0xbfa8c2f4), SPH_C32(0x524a0d59), SPH_C32(0x54500000), + SPH_C32(0x0671005c), SPH_C32(0x25ae0000), SPH_C32(0x6a1e0000), + SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), SPH_C32(0xbfba18c3), + SPH_C32(0x7e715d17) }, + { SPH_C32(0xfcc40000), SPH_C32(0xd9800078), SPH_C32(0x6cf20000), + SPH_C32(0xffa30000), SPH_C32(0x9bd151ab), SPH_C32(0x181bb131), + SPH_C32(0xde4ed244), SPH_C32(0x8980d6d9), SPH_C32(0xb7130000), + SPH_C32(0x3c3f0048), SPH_C32(0xd7680000), SPH_C32(0xc0500000), + SPH_C32(0xf5bb0c79), SPH_C32(0x43253b07), SPH_C32(0xad87a995), + SPH_C32(0x443fc4c0) }, + { SPH_C32(0x0b9e0000), SPH_C32(0xc0040050), SPH_C32(0xceeb0000), + SPH_C32(0x115b0000), SPH_C32(0x5ba374bd), SPH_C32(0x0183a351), + SPH_C32(0xad9573a2), SPH_C32(0x6804948e), SPH_C32(0xa30a0000), + SPH_C32(0x1ff50074), SPH_C32(0x87b70000), SPH_C32(0x84e60000), + SPH_C32(0xeed76bc9), SPH_C32(0x7fd69772), SPH_C32(0xcc61b925), + SPH_C32(0x9ff51f40) }, + { SPH_C32(0x1f870000), SPH_C32(0xe3ce006c), SPH_C32(0x9e340000), + SPH_C32(0x55ed0000), SPH_C32(0x40cf130d), SPH_C32(0x3d700f24), + SPH_C32(0xcc736312), SPH_C32(0xb3ce4f0e), SPH_C32(0x40490000), + SPH_C32(0x25bb0060), SPH_C32(0x75710000), SPH_C32(0x2ea80000), + SPH_C32(0x35c9296f), SPH_C32(0x5abd2967), SPH_C32(0xde5c0873), + SPH_C32(0xa5bb8697) }, + { SPH_C32(0x69510000), SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), + SPH_C32(0xac2f0000), SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), + SPH_C32(0x87ec287c), SPH_C32(0xbce1a3ce), SPH_C32(0xc6730000), + SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), SPH_C32(0x218d0000), + SPH_C32(0x23111587), SPH_C32(0x7913512f), SPH_C32(0x1d28ac88), + SPH_C32(0x378dd173) }, + { SPH_C32(0x7d480000), SPH_C32(0xf72b00a0), SPH_C32(0x93fc0000), + SPH_C32(0xe8990000), SPH_C32(0xfff96c1e), SPH_C32(0xf257b9a9), + SPH_C32(0xe60a38cc), SPH_C32(0x672b784e), SPH_C32(0x25300000), + SPH_C32(0x95c30018), SPH_C32(0x56070000), SPH_C32(0x8bc30000), + SPH_C32(0xf80f5721), SPH_C32(0x5c78ef3a), SPH_C32(0x0f151dde), + SPH_C32(0x0dc348a4) }, + { SPH_C32(0x8a120000), SPH_C32(0xeeaf0088), SPH_C32(0x31e50000), + SPH_C32(0x06610000), SPH_C32(0x3f8b4908), SPH_C32(0xebcfabc9), + SPH_C32(0x95d1992a), SPH_C32(0x86af3a19), SPH_C32(0x31290000), + SPH_C32(0xb6090024), SPH_C32(0x06d80000), SPH_C32(0xcf750000), + SPH_C32(0xe3633091), SPH_C32(0x608b434f), SPH_C32(0x6ef30d6e), + SPH_C32(0xd6099324) }, + { SPH_C32(0x9e0b0000), SPH_C32(0xcd6500b4), SPH_C32(0x613a0000), + SPH_C32(0x42d70000), SPH_C32(0x24e72eb8), SPH_C32(0xd73c07bc), + SPH_C32(0xf437899a), SPH_C32(0x5d65e199), SPH_C32(0xd26a0000), + SPH_C32(0x8c470030), SPH_C32(0xf41e0000), SPH_C32(0x653b0000), + SPH_C32(0x387d7237), SPH_C32(0x45e0fd5a), SPH_C32(0x7ccebc38), + SPH_C32(0xec470af3) }, + { SPH_C32(0x3d010000), SPH_C32(0xd29000c0), SPH_C32(0xe68d0000), + SPH_C32(0xc6310000), SPH_C32(0xca304571), SPH_C32(0xa8ea90ce), + SPH_C32(0x385630bf), SPH_C32(0xc290fed9), SPH_C32(0x7afe0000), + SPH_C32(0x53b60014), SPH_C32(0xbd420000), SPH_C32(0xf0860000), + SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), SPH_C32(0x1d3a76bf), + SPH_C32(0x1bb6813d) }, + { SPH_C32(0x29180000), SPH_C32(0xf15a00fc), SPH_C32(0xb6520000), + SPH_C32(0x82870000), SPH_C32(0xd15c22c1), SPH_C32(0x94193cbb), + SPH_C32(0x59b0200f), SPH_C32(0x195a2559), SPH_C32(0x99bd0000), + SPH_C32(0x69f80000), SPH_C32(0x4f840000), SPH_C32(0x5ac80000), + SPH_C32(0x56172fe5), SPH_C32(0x1ede776c), SPH_C32(0x0f07c7e9), + SPH_C32(0x21f818ea) }, + { SPH_C32(0xde420000), SPH_C32(0xe8de00d4), SPH_C32(0x144b0000), + SPH_C32(0x6c7f0000), SPH_C32(0x112e07d7), SPH_C32(0x8d812edb), + SPH_C32(0x2a6b81e9), SPH_C32(0xf8de670e), SPH_C32(0x8da40000), + SPH_C32(0x4a32003c), SPH_C32(0x1f5b0000), SPH_C32(0x1e7e0000), + SPH_C32(0x4d7b4855), SPH_C32(0x222ddb19), SPH_C32(0x6ee1d759), + SPH_C32(0xfa32c36a) }, + { SPH_C32(0xca5b0000), SPH_C32(0xcb1400e8), SPH_C32(0x44940000), + SPH_C32(0x28c90000), SPH_C32(0x0a426067), SPH_C32(0xb17282ae), + SPH_C32(0x4b8d9159), SPH_C32(0x2314bc8e), SPH_C32(0x6ee70000), + SPH_C32(0x707c0028), SPH_C32(0xed9d0000), SPH_C32(0xb4300000), + SPH_C32(0x96650af3), SPH_C32(0x0746650c), SPH_C32(0x7cdc660f), + SPH_C32(0xc07c5abd) }, + { SPH_C32(0xd5dc0000), SPH_C32(0x28da0084), SPH_C32(0xdaa00000), + SPH_C32(0x7d240000), SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), + SPH_C32(0x87fef24b), SPH_C32(0x90daf380), SPH_C32(0x2eae0000), + SPH_C32(0x55c70048), SPH_C32(0x98ec0000), SPH_C32(0x9a980000), + SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), SPH_C32(0xa2806e7c), + SPH_C32(0x65c7dc2a) }, + { SPH_C32(0xc1c50000), SPH_C32(0x0b1000b8), SPH_C32(0x8a7f0000), + SPH_C32(0x39920000), SPH_C32(0x51e114da), SPH_C32(0xb0f121ff), + SPH_C32(0xe618e2fb), SPH_C32(0x4b102800), SPH_C32(0xcded0000), + SPH_C32(0x6f89005c), SPH_C32(0x6a2a0000), SPH_C32(0x30d60000), + SPH_C32(0x78b2613a), SPH_C32(0x7890f27e), SPH_C32(0xb0bddf2a), + SPH_C32(0x5f8945fd) }, + { SPH_C32(0x369f0000), SPH_C32(0x12940090), SPH_C32(0x28660000), + SPH_C32(0xd76a0000), SPH_C32(0x919331cc), SPH_C32(0xa969339f), + SPH_C32(0x95c3431d), SPH_C32(0xaa946a57), SPH_C32(0xd9f40000), + SPH_C32(0x4c430060), SPH_C32(0x3af50000), SPH_C32(0x74600000), + SPH_C32(0x63de068a), SPH_C32(0x44635e0b), SPH_C32(0xd15bcf9a), + SPH_C32(0x84439e7d) }, + { SPH_C32(0x22860000), SPH_C32(0x315e00ac), SPH_C32(0x78b90000), + SPH_C32(0x93dc0000), SPH_C32(0x8aff567c), SPH_C32(0x959a9fea), + SPH_C32(0xf42553ad), SPH_C32(0x715eb1d7), SPH_C32(0x3ab70000), + SPH_C32(0x760d0074), SPH_C32(0xc8330000), SPH_C32(0xde2e0000), + SPH_C32(0xb8c0442c), SPH_C32(0x6108e01e), SPH_C32(0xc3667ecc), + SPH_C32(0xbe0d07aa) }, + { SPH_C32(0x818c0000), SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), + SPH_C32(0x173a0000), SPH_C32(0x64283db5), SPH_C32(0xea4c0898), + SPH_C32(0x3844ea88), SPH_C32(0xeeabae97), SPH_C32(0x92230000), + SPH_C32(0xa9fc0050), SPH_C32(0x816f0000), SPH_C32(0x4b930000), + SPH_C32(0x0db45b58), SPH_C32(0x1f5dd43d), SPH_C32(0xa292b44b), + SPH_C32(0x49fc8c64) }, + { SPH_C32(0x95950000), SPH_C32(0x0d6100e4), SPH_C32(0xafd10000), + SPH_C32(0x538c0000), SPH_C32(0x7f445a05), SPH_C32(0xd6bfa4ed), + SPH_C32(0x59a2fa38), SPH_C32(0x35617517), SPH_C32(0x71600000), + SPH_C32(0x93b20044), SPH_C32(0x73a90000), SPH_C32(0xe1dd0000), + SPH_C32(0xd6aa19fe), SPH_C32(0x3a366a28), SPH_C32(0xb0af051d), + SPH_C32(0x73b215b3) }, + { SPH_C32(0x62cf0000), SPH_C32(0x14e500cc), SPH_C32(0x0dc80000), + SPH_C32(0xbd740000), SPH_C32(0xbf367f13), SPH_C32(0xcf27b68d), + SPH_C32(0x2a795bde), SPH_C32(0xd4e53740), SPH_C32(0x65790000), + SPH_C32(0xb0780078), SPH_C32(0x23760000), SPH_C32(0xa56b0000), + SPH_C32(0xcdc67e4e), SPH_C32(0x06c5c65d), SPH_C32(0xd14915ad), + SPH_C32(0xa878ce33) }, + { SPH_C32(0x76d60000), SPH_C32(0x372f00f0), SPH_C32(0x5d170000), + SPH_C32(0xf9c20000), SPH_C32(0xa45a18a3), SPH_C32(0xf3d41af8), + SPH_C32(0x4b9f4b6e), SPH_C32(0x0f2fecc0), SPH_C32(0x863a0000), + SPH_C32(0x8a36006c), SPH_C32(0xd1b00000), SPH_C32(0x0f250000), + SPH_C32(0x16d83ce8), SPH_C32(0x23ae7848), SPH_C32(0xc374a4fb), + SPH_C32(0x923657e4) } +}; + +static const sph_u32 T512_30[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x1e4e0000), SPH_C32(0xdecf0000), SPH_C32(0x6df80180), + SPH_C32(0x77240000), SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), + SPH_C32(0xcda31812), SPH_C32(0x98aa496e), SPH_C32(0xb2060000), + SPH_C32(0xc5690000), SPH_C32(0x28031200), SPH_C32(0x74670000), + SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), SPH_C32(0x33d1dfec), + SPH_C32(0x094e3198) }, + { SPH_C32(0xaec30000), SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), + SPH_C32(0x2c150000), SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), + SPH_C32(0xab92f78f), SPH_C32(0xa312567b), SPH_C32(0xdb250000), + SPH_C32(0x09290000), SPH_C32(0x49aac000), SPH_C32(0x81e10000), + SPH_C32(0xcafe6b59), SPH_C32(0x42793431), SPH_C32(0x43566b76), + SPH_C32(0xe86cba2e) }, + { SPH_C32(0xb08d0000), SPH_C32(0x42800001), SPH_C32(0x1429e180), + SPH_C32(0x5b310000), SPH_C32(0xa98b722d), SPH_C32(0x92f0de78), + SPH_C32(0x6631ef9d), SPH_C32(0x3bb81f15), SPH_C32(0x69230000), + SPH_C32(0xcc400000), SPH_C32(0x61a9d200), SPH_C32(0xf5860000), + SPH_C32(0x7c3c5dad), SPH_C32(0xa96b0dc9), SPH_C32(0x7087b49a), + SPH_C32(0xe1228bb6) }, + { SPH_C32(0xdb250000), SPH_C32(0x09290000), SPH_C32(0x49aac000), + SPH_C32(0x81e10000), SPH_C32(0xcafe6b59), SPH_C32(0x42793431), + SPH_C32(0x43566b76), SPH_C32(0xe86cba2e), SPH_C32(0x75e60000), + SPH_C32(0x95660001), SPH_C32(0x307b2000), SPH_C32(0xadf40000), + SPH_C32(0x8f321eea), SPH_C32(0x24298307), SPH_C32(0xe8c49cf9), + SPH_C32(0x4b7eec55) }, + { SPH_C32(0xc56b0000), SPH_C32(0xd7e60000), SPH_C32(0x2452c180), + SPH_C32(0xf6c50000), SPH_C32(0x26b96cc7), SPH_C32(0xb6d95d7f), + SPH_C32(0x8ef57364), SPH_C32(0x70c6f340), SPH_C32(0xc7e00000), + SPH_C32(0x500f0001), SPH_C32(0x18783200), SPH_C32(0xd9930000), + SPH_C32(0x39f0281e), SPH_C32(0xcf3bbaff), SPH_C32(0xdb154315), + SPH_C32(0x4230ddcd) }, + { SPH_C32(0x75e60000), SPH_C32(0x95660001), SPH_C32(0x307b2000), + SPH_C32(0xadf40000), SPH_C32(0x8f321eea), SPH_C32(0x24298307), + SPH_C32(0xe8c49cf9), SPH_C32(0x4b7eec55), SPH_C32(0xaec30000), + SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), SPH_C32(0x2c150000), + SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), SPH_C32(0xab92f78f), + SPH_C32(0xa312567b) }, + { SPH_C32(0x6ba80000), SPH_C32(0x4ba90001), SPH_C32(0x5d832180), + SPH_C32(0xdad00000), SPH_C32(0x63751974), SPH_C32(0xd089ea49), + SPH_C32(0x256784eb), SPH_C32(0xd3d4a53b), SPH_C32(0x1cc50000), + SPH_C32(0x59260001), SPH_C32(0x51d2f200), SPH_C32(0x58720000), + SPH_C32(0xf30e4347), SPH_C32(0x8d428ece), SPH_C32(0x98432863), + SPH_C32(0xaa5c67e3) }, + { SPH_C32(0x86790000), SPH_C32(0x3f390002), SPH_C32(0xe19ae000), + SPH_C32(0x98560000), SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), + SPH_C32(0xd3dd4944), SPH_C32(0x161ddab9), SPH_C32(0x30b70000), + SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), SPH_C32(0x42c40000), + SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), SPH_C32(0x21afa1ea), + SPH_C32(0xb0a51834) }, + { SPH_C32(0x98370000), SPH_C32(0xe1f60002), SPH_C32(0x8c62e180), + SPH_C32(0xef720000), SPH_C32(0x79226090), SPH_C32(0xba28a1a4), + SPH_C32(0x1e7e5156), SPH_C32(0x8eb793d7), SPH_C32(0x82b10000), + SPH_C32(0x20b90000), SPH_C32(0xdcf77200), SPH_C32(0x36a30000), + SPH_C32(0xd57a0b9e), SPH_C32(0x93a8ad98), SPH_C32(0x127e7e06), + SPH_C32(0xb9eb29ac) }, + { SPH_C32(0x28ba0000), SPH_C32(0xa3760003), SPH_C32(0x984b0000), + SPH_C32(0xb4430000), SPH_C32(0xd0a912bd), SPH_C32(0x28d87fdc), + SPH_C32(0x784fbecb), SPH_C32(0xb50f8cc2), SPH_C32(0xeb920000), + SPH_C32(0xecf90000), SPH_C32(0xbd5ea000), SPH_C32(0xc3250000), + SPH_C32(0xa9465633), SPH_C32(0x3ac3a051), SPH_C32(0x62f9ca9c), + SPH_C32(0x58c9a21a) }, + { SPH_C32(0x36f40000), SPH_C32(0x7db90003), SPH_C32(0xf5b30180), + SPH_C32(0xc3670000), SPH_C32(0x3cee1523), SPH_C32(0xdc781692), + SPH_C32(0xb5eca6d9), SPH_C32(0x2da5c5ac), SPH_C32(0x59940000), + SPH_C32(0x29900000), SPH_C32(0x955db200), SPH_C32(0xb7420000), + SPH_C32(0x1f8460c7), SPH_C32(0xd1d199a9), SPH_C32(0x51281570), + SPH_C32(0x51879382) }, + { SPH_C32(0x5d5c0000), SPH_C32(0x36100002), SPH_C32(0xa8302000), + SPH_C32(0x19b70000), SPH_C32(0x5f9b0c57), SPH_C32(0x0cf1fcdb), + SPH_C32(0x908b2232), SPH_C32(0xfe716097), SPH_C32(0x45510000), + SPH_C32(0x70b60001), SPH_C32(0xc48f4000), SPH_C32(0xef300000), + SPH_C32(0xec8a2380), SPH_C32(0x5c931767), SPH_C32(0xc96b3d13), + SPH_C32(0xfbdbf461) }, + { SPH_C32(0x43120000), SPH_C32(0xe8df0002), SPH_C32(0xc5c82180), + SPH_C32(0x6e930000), SPH_C32(0xb3dc0bc9), SPH_C32(0xf8519595), + SPH_C32(0x5d283a20), SPH_C32(0x66db29f9), SPH_C32(0xf7570000), + SPH_C32(0xb5df0001), SPH_C32(0xec8c5200), SPH_C32(0x9b570000), + SPH_C32(0x5a481574), SPH_C32(0xb7812e9f), SPH_C32(0xfabae2ff), + SPH_C32(0xf295c5f9) }, + { SPH_C32(0xf39f0000), SPH_C32(0xaa5f0003), SPH_C32(0xd1e1c000), + SPH_C32(0x35a20000), SPH_C32(0x1a5779e4), SPH_C32(0x6aa14bed), + SPH_C32(0x3b19d5bd), SPH_C32(0x5d6336ec), SPH_C32(0x9e740000), + SPH_C32(0x799f0001), SPH_C32(0x8d258000), SPH_C32(0x6ed10000), + SPH_C32(0x267448d9), SPH_C32(0x1eea2356), SPH_C32(0x8a3d5665), + SPH_C32(0x13b74e4f) }, + { SPH_C32(0xedd10000), SPH_C32(0x74900003), SPH_C32(0xbc19c180), + SPH_C32(0x42860000), SPH_C32(0xf6107e7a), SPH_C32(0x9e0122a3), + SPH_C32(0xf6bacdaf), SPH_C32(0xc5c97f82), SPH_C32(0x2c720000), + SPH_C32(0xbcf60001), SPH_C32(0xa5269200), SPH_C32(0x1ab60000), + SPH_C32(0x90b67e2d), SPH_C32(0xf5f81aae), SPH_C32(0xb9ec8989), + SPH_C32(0x1af97fd7) }, + { SPH_C32(0x30b70000), SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), + SPH_C32(0x42c40000), SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), + SPH_C32(0x21afa1ea), SPH_C32(0xb0a51834), SPH_C32(0xb6ce0000), + SPH_C32(0xdae90002), SPH_C32(0x156e8000), SPH_C32(0xda920000), + SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), SPH_C32(0xf272e8ae), + SPH_C32(0xa6b8c28d) }, + { SPH_C32(0x2ef90000), SPH_C32(0x3b1f0000), SPH_C32(0x990c6180), + SPH_C32(0x35e00000), SPH_C32(0x8fff3af4), SPH_C32(0x8c1afd2e), + SPH_C32(0xec0cb9f8), SPH_C32(0x280f515a), SPH_C32(0x04c80000), + SPH_C32(0x1f800002), SPH_C32(0x3d6d9200), SPH_C32(0xaef50000), + SPH_C32(0x401f6c90), SPH_C32(0xdd206572), SPH_C32(0xc1a33742), + SPH_C32(0xaff6f315) }, + { SPH_C32(0x9e740000), SPH_C32(0x799f0001), SPH_C32(0x8d258000), + SPH_C32(0x6ed10000), SPH_C32(0x267448d9), SPH_C32(0x1eea2356), + SPH_C32(0x8a3d5665), SPH_C32(0x13b74e4f), SPH_C32(0x6deb0000), + SPH_C32(0xd3c00002), SPH_C32(0x5cc44000), SPH_C32(0x5b730000), + SPH_C32(0x3c23313d), SPH_C32(0x744b68bb), SPH_C32(0xb12483d8), + SPH_C32(0x4ed478a3) }, + { SPH_C32(0x803a0000), SPH_C32(0xa7500001), SPH_C32(0xe0dd8180), + SPH_C32(0x19f50000), SPH_C32(0xca334f47), SPH_C32(0xea4a4a18), + SPH_C32(0x479e4e77), SPH_C32(0x8b1d0721), SPH_C32(0xdfed0000), + SPH_C32(0x16a90002), SPH_C32(0x74c75200), SPH_C32(0x2f140000), + SPH_C32(0x8ae107c9), SPH_C32(0x9f595143), SPH_C32(0x82f55c34), + SPH_C32(0x479a493b) }, + { SPH_C32(0xeb920000), SPH_C32(0xecf90000), SPH_C32(0xbd5ea000), + SPH_C32(0xc3250000), SPH_C32(0xa9465633), SPH_C32(0x3ac3a051), + SPH_C32(0x62f9ca9c), SPH_C32(0x58c9a21a), SPH_C32(0xc3280000), + SPH_C32(0x4f8f0003), SPH_C32(0x2515a000), SPH_C32(0x77660000), + SPH_C32(0x79ef448e), SPH_C32(0x121bdf8d), SPH_C32(0x1ab67457), + SPH_C32(0xedc62ed8) }, + { SPH_C32(0xf5dc0000), SPH_C32(0x32360000), SPH_C32(0xd0a6a180), + SPH_C32(0xb4010000), SPH_C32(0x450151ad), SPH_C32(0xce63c91f), + SPH_C32(0xaf5ad28e), SPH_C32(0xc063eb74), SPH_C32(0x712e0000), + SPH_C32(0x8ae60003), SPH_C32(0x0d16b200), SPH_C32(0x03010000), + SPH_C32(0xcf2d727a), SPH_C32(0xf909e675), SPH_C32(0x2967abbb), + SPH_C32(0xe4881f40) }, + { SPH_C32(0x45510000), SPH_C32(0x70b60001), SPH_C32(0xc48f4000), + SPH_C32(0xef300000), SPH_C32(0xec8a2380), SPH_C32(0x5c931767), + SPH_C32(0xc96b3d13), SPH_C32(0xfbdbf461), SPH_C32(0x180d0000), + SPH_C32(0x46a60003), SPH_C32(0x6cbf6000), SPH_C32(0xf6870000), + SPH_C32(0xb3112fd7), SPH_C32(0x5062ebbc), SPH_C32(0x59e01f21), + SPH_C32(0x05aa94f6) }, + { SPH_C32(0x5b1f0000), SPH_C32(0xae790001), SPH_C32(0xa9774180), + SPH_C32(0x98140000), SPH_C32(0x00cd241e), SPH_C32(0xa8337e29), + SPH_C32(0x04c82501), SPH_C32(0x6371bd0f), SPH_C32(0xaa0b0000), + SPH_C32(0x83cf0003), SPH_C32(0x44bc7200), SPH_C32(0x82e00000), + SPH_C32(0x05d31923), SPH_C32(0xbb70d244), SPH_C32(0x6a31c0cd), + SPH_C32(0x0ce4a56e) }, + { SPH_C32(0xb6ce0000), SPH_C32(0xdae90002), SPH_C32(0x156e8000), + SPH_C32(0xda920000), SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), + SPH_C32(0xf272e8ae), SPH_C32(0xa6b8c28d), SPH_C32(0x86790000), + SPH_C32(0x3f390002), SPH_C32(0xe19ae000), SPH_C32(0x98560000), + SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), SPH_C32(0xd3dd4944), + SPH_C32(0x161ddab9) }, + { SPH_C32(0xa8800000), SPH_C32(0x04260002), SPH_C32(0x78968180), + SPH_C32(0xadb60000), SPH_C32(0x1a9a5dfa), SPH_C32(0xc29235c4), + SPH_C32(0x3fd1f0bc), SPH_C32(0x3e128be3), SPH_C32(0x347f0000), + SPH_C32(0xfa500002), SPH_C32(0xc999f200), SPH_C32(0xec310000), + SPH_C32(0x23a751fa), SPH_C32(0xa59af112), SPH_C32(0xe00c96a8), + SPH_C32(0x1f53eb21) }, + { SPH_C32(0x180d0000), SPH_C32(0x46a60003), SPH_C32(0x6cbf6000), + SPH_C32(0xf6870000), SPH_C32(0xb3112fd7), SPH_C32(0x5062ebbc), + SPH_C32(0x59e01f21), SPH_C32(0x05aa94f6), SPH_C32(0x5d5c0000), + SPH_C32(0x36100002), SPH_C32(0xa8302000), SPH_C32(0x19b70000), + SPH_C32(0x5f9b0c57), SPH_C32(0x0cf1fcdb), SPH_C32(0x908b2232), + SPH_C32(0xfe716097) }, + { SPH_C32(0x06430000), SPH_C32(0x98690003), SPH_C32(0x01476180), + SPH_C32(0x81a30000), SPH_C32(0x5f562849), SPH_C32(0xa4c282f2), + SPH_C32(0x94430733), SPH_C32(0x9d00dd98), SPH_C32(0xef5a0000), + SPH_C32(0xf3790002), SPH_C32(0x80333200), SPH_C32(0x6dd00000), + SPH_C32(0xe9593aa3), SPH_C32(0xe7e3c523), SPH_C32(0xa35afdde), + SPH_C32(0xf73f510f) }, + { SPH_C32(0x6deb0000), SPH_C32(0xd3c00002), SPH_C32(0x5cc44000), + SPH_C32(0x5b730000), SPH_C32(0x3c23313d), SPH_C32(0x744b68bb), + SPH_C32(0xb12483d8), SPH_C32(0x4ed478a3), SPH_C32(0xf39f0000), + SPH_C32(0xaa5f0003), SPH_C32(0xd1e1c000), SPH_C32(0x35a20000), + SPH_C32(0x1a5779e4), SPH_C32(0x6aa14bed), SPH_C32(0x3b19d5bd), + SPH_C32(0x5d6336ec) }, + { SPH_C32(0x73a50000), SPH_C32(0x0d0f0002), SPH_C32(0x313c4180), + SPH_C32(0x2c570000), SPH_C32(0xd06436a3), SPH_C32(0x80eb01f5), + SPH_C32(0x7c879bca), SPH_C32(0xd67e31cd), SPH_C32(0x41990000), + SPH_C32(0x6f360003), SPH_C32(0xf9e2d200), SPH_C32(0x41c50000), + SPH_C32(0xac954f10), SPH_C32(0x81b37215), SPH_C32(0x08c80a51), + SPH_C32(0x542d0774) }, + { SPH_C32(0xc3280000), SPH_C32(0x4f8f0003), SPH_C32(0x2515a000), + SPH_C32(0x77660000), SPH_C32(0x79ef448e), SPH_C32(0x121bdf8d), + SPH_C32(0x1ab67457), SPH_C32(0xedc62ed8), SPH_C32(0x28ba0000), + SPH_C32(0xa3760003), SPH_C32(0x984b0000), SPH_C32(0xb4430000), + SPH_C32(0xd0a912bd), SPH_C32(0x28d87fdc), SPH_C32(0x784fbecb), + SPH_C32(0xb50f8cc2) }, + { SPH_C32(0xdd660000), SPH_C32(0x91400003), SPH_C32(0x48eda180), + SPH_C32(0x00420000), SPH_C32(0x95a84310), SPH_C32(0xe6bbb6c3), + SPH_C32(0xd7156c45), SPH_C32(0x756c67b6), SPH_C32(0x9abc0000), + SPH_C32(0x661f0003), SPH_C32(0xb0481200), SPH_C32(0xc0240000), + SPH_C32(0x666b2449), SPH_C32(0xc3ca4624), SPH_C32(0x4b9e6127), + SPH_C32(0xbc41bd5a) } +}; + +static const sph_u32 T512_35[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xcc140000), SPH_C32(0xa5630000), SPH_C32(0x5ab90780), + SPH_C32(0x3b500000), SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), + SPH_C32(0x694348c1), SPH_C32(0xca5a87fe), SPH_C32(0x819e0000), + SPH_C32(0xec570000), SPH_C32(0x66320280), SPH_C32(0x95f30000), + SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), SPH_C32(0xe65aa22d), + SPH_C32(0x8e67b7fa) }, + { SPH_C32(0x819e0000), SPH_C32(0xec570000), SPH_C32(0x66320280), + SPH_C32(0x95f30000), SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), + SPH_C32(0xe65aa22d), SPH_C32(0x8e67b7fa), SPH_C32(0x4d8a0000), + SPH_C32(0x49340000), SPH_C32(0x3c8b0500), SPH_C32(0xaea30000), + SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), SPH_C32(0x8f19eaec), + SPH_C32(0x443d3004) }, + { SPH_C32(0x4d8a0000), SPH_C32(0x49340000), SPH_C32(0x3c8b0500), + SPH_C32(0xaea30000), SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), + SPH_C32(0x8f19eaec), SPH_C32(0x443d3004), SPH_C32(0xcc140000), + SPH_C32(0xa5630000), SPH_C32(0x5ab90780), SPH_C32(0x3b500000), + SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), SPH_C32(0x694348c1), + SPH_C32(0xca5a87fe) }, + { SPH_C32(0x78230000), SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), + SPH_C32(0x90a50000), SPH_C32(0x713e2879), SPH_C32(0x7ee98924), + SPH_C32(0xf08ca062), SPH_C32(0x636f8bab), SPH_C32(0x02af0000), + SPH_C32(0xb7280000), SPH_C32(0xba1c0300), SPH_C32(0x56980000), + SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), SPH_C32(0xa95c149a), + SPH_C32(0xf4f6ea7b) }, + { SPH_C32(0xb4370000), SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), + SPH_C32(0xabf50000), SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), + SPH_C32(0x99cfe8a3), SPH_C32(0xa9350c55), SPH_C32(0x83310000), + SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), SPH_C32(0xc36b0000), + SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), SPH_C32(0x4f06b6b7), + SPH_C32(0x7a915d81) }, + { SPH_C32(0xf9bd0000), SPH_C32(0xfeab0000), SPH_C32(0xcf080900), + SPH_C32(0x05560000), SPH_C32(0x2c97007b), SPH_C32(0x361db598), + SPH_C32(0x16d6024f), SPH_C32(0xed083c51), SPH_C32(0x4f250000), + SPH_C32(0xfe1c0000), SPH_C32(0x86970600), SPH_C32(0xf83b0000), + SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), SPH_C32(0x2645fe76), + SPH_C32(0xb0cbda7f) }, + { SPH_C32(0x35a90000), SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), + SPH_C32(0x3e060000), SPH_C32(0x67471384), SPH_C32(0xb1868180), + SPH_C32(0x7f954a8e), SPH_C32(0x2752bbaf), SPH_C32(0xcebb0000), + SPH_C32(0x124b0000), SPH_C32(0xe0a50480), SPH_C32(0x6dc80000), + SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), SPH_C32(0xc01f5c5b), + SPH_C32(0x3eac6d85) }, + { SPH_C32(0x02af0000), SPH_C32(0xb7280000), SPH_C32(0xba1c0300), + SPH_C32(0x56980000), SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), + SPH_C32(0xa95c149a), SPH_C32(0xf4f6ea7b), SPH_C32(0x7a8c0000), + SPH_C32(0xa5d40000), SPH_C32(0x13260880), SPH_C32(0xc63d0000), + SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), SPH_C32(0x59d0b4f8), + SPH_C32(0x979961d0) }, + { SPH_C32(0xcebb0000), SPH_C32(0x124b0000), SPH_C32(0xe0a50480), + SPH_C32(0x6dc80000), SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), + SPH_C32(0xc01f5c5b), SPH_C32(0x3eac6d85), SPH_C32(0xfb120000), + SPH_C32(0x49830000), SPH_C32(0x75140a00), SPH_C32(0x53ce0000), + SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), SPH_C32(0xbf8a16d5), + SPH_C32(0x19fed62a) }, + { SPH_C32(0x83310000), SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), + SPH_C32(0xc36b0000), SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), + SPH_C32(0x4f06b6b7), SPH_C32(0x7a915d81), SPH_C32(0x37060000), + SPH_C32(0xece00000), SPH_C32(0x2fad0d80), SPH_C32(0x689e0000), + SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), SPH_C32(0xd6c95e14), + SPH_C32(0xd3a451d4) }, + { SPH_C32(0x4f250000), SPH_C32(0xfe1c0000), SPH_C32(0x86970600), + SPH_C32(0xf83b0000), SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), + SPH_C32(0x2645fe76), SPH_C32(0xb0cbda7f), SPH_C32(0xb6980000), + SPH_C32(0x00b70000), SPH_C32(0x499f0f00), SPH_C32(0xfd6d0000), + SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), SPH_C32(0x3093fc39), + SPH_C32(0x5dc3e62e) }, + { SPH_C32(0x7a8c0000), SPH_C32(0xa5d40000), SPH_C32(0x13260880), + SPH_C32(0xc63d0000), SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), + SPH_C32(0x59d0b4f8), SPH_C32(0x979961d0), SPH_C32(0x78230000), + SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), SPH_C32(0x90a50000), + SPH_C32(0x713e2879), SPH_C32(0x7ee98924), SPH_C32(0xf08ca062), + SPH_C32(0x636f8bab) }, + { SPH_C32(0xb6980000), SPH_C32(0x00b70000), SPH_C32(0x499f0f00), + SPH_C32(0xfd6d0000), SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), + SPH_C32(0x3093fc39), SPH_C32(0x5dc3e62e), SPH_C32(0xf9bd0000), + SPH_C32(0xfeab0000), SPH_C32(0xcf080900), SPH_C32(0x05560000), + SPH_C32(0x2c97007b), SPH_C32(0x361db598), SPH_C32(0x16d6024f), + SPH_C32(0xed083c51) }, + { SPH_C32(0xfb120000), SPH_C32(0x49830000), SPH_C32(0x75140a00), + SPH_C32(0x53ce0000), SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), + SPH_C32(0xbf8a16d5), SPH_C32(0x19fed62a), SPH_C32(0x35a90000), + SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), SPH_C32(0x3e060000), + SPH_C32(0x67471384), SPH_C32(0xb1868180), SPH_C32(0x7f954a8e), + SPH_C32(0x2752bbaf) }, + { SPH_C32(0x37060000), SPH_C32(0xece00000), SPH_C32(0x2fad0d80), + SPH_C32(0x689e0000), SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), + SPH_C32(0xd6c95e14), SPH_C32(0xd3a451d4), SPH_C32(0xb4370000), + SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), SPH_C32(0xabf50000), + SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), SPH_C32(0x99cfe8a3), + SPH_C32(0xa9350c55) }, + { SPH_C32(0xac480000), SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), + SPH_C32(0x03430000), SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), + SPH_C32(0xfe72c7fe), SPH_C32(0x91e478f6), SPH_C32(0x1e4e0000), + SPH_C32(0xdecf0000), SPH_C32(0x6df80180), SPH_C32(0x77240000), + SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), SPH_C32(0xcda31812), + SPH_C32(0x98aa496e) }, + { SPH_C32(0x605c0000), SPH_C32(0xbec50000), SPH_C32(0x1f421400), + SPH_C32(0x38130000), SPH_C32(0x11552295), SPH_C32(0x982964ae), + SPH_C32(0x97318f3f), SPH_C32(0x5bbeff08), SPH_C32(0x9fd00000), + SPH_C32(0x32980000), SPH_C32(0x0bca0300), SPH_C32(0xe2d70000), + SPH_C32(0xb1ee2f9c), SPH_C32(0xbc5455f2), SPH_C32(0x2bf9ba3f), + SPH_C32(0x16cdfe94) }, + { SPH_C32(0x2dd60000), SPH_C32(0xf7f10000), SPH_C32(0x23c91100), + SPH_C32(0x96b00000), SPH_C32(0x072c1968), SPH_C32(0x57466c0a), + SPH_C32(0x182865d3), SPH_C32(0x1f83cf0c), SPH_C32(0x53c40000), + SPH_C32(0x97fb0000), SPH_C32(0x51730480), SPH_C32(0xd9870000), + SPH_C32(0xfa3e3c63), SPH_C32(0x3bcf61ea), SPH_C32(0x42baf2fe), + SPH_C32(0xdc97796a) }, + { SPH_C32(0xe1c20000), SPH_C32(0x52920000), SPH_C32(0x79701680), + SPH_C32(0xade00000), SPH_C32(0x4cfc0a97), SPH_C32(0xd0dd5812), + SPH_C32(0x716b2d12), SPH_C32(0xd5d948f2), SPH_C32(0xd25a0000), + SPH_C32(0x7bac0000), SPH_C32(0x37410600), SPH_C32(0x4c740000), + SPH_C32(0xa7971461), SPH_C32(0x733b5d56), SPH_C32(0xa4e050d3), + SPH_C32(0x52f0ce90) }, + { SPH_C32(0xd46b0000), SPH_C32(0x095a0000), SPH_C32(0xecc11800), + SPH_C32(0x93e60000), SPH_C32(0x2bbb1913), SPH_C32(0x615bd992), + SPH_C32(0x0efe679c), SPH_C32(0xf28bf35d), SPH_C32(0x1ce10000), + SPH_C32(0x69e70000), SPH_C32(0xd7e40280), SPH_C32(0x21bc0000), + SPH_C32(0x56ca424d), SPH_C32(0x74e8af29), SPH_C32(0x64ff0c88), + SPH_C32(0x6c5ca315) }, + { SPH_C32(0x187f0000), SPH_C32(0xac390000), SPH_C32(0xb6781f80), + SPH_C32(0xa8b60000), SPH_C32(0x606b0aec), SPH_C32(0xe6c0ed8a), + SPH_C32(0x67bd2f5d), SPH_C32(0x38d174a3), SPH_C32(0x9d7f0000), + SPH_C32(0x85b00000), SPH_C32(0xb1d60000), SPH_C32(0xb44f0000), + SPH_C32(0x0b636a4f), SPH_C32(0x3c1c9395), SPH_C32(0x82a5aea5), + SPH_C32(0xe23b14ef) }, + { SPH_C32(0x55f50000), SPH_C32(0xe50d0000), SPH_C32(0x8af31a80), + SPH_C32(0x06150000), SPH_C32(0x76123111), SPH_C32(0x29afe52e), + SPH_C32(0xe8a4c5b1), SPH_C32(0x7cec44a7), SPH_C32(0x516b0000), + SPH_C32(0x20d30000), SPH_C32(0xeb6f0780), SPH_C32(0x8f1f0000), + SPH_C32(0x40b379b0), SPH_C32(0xbb87a78d), SPH_C32(0xebe6e664), + SPH_C32(0x28619311) }, + { SPH_C32(0x99e10000), SPH_C32(0x406e0000), SPH_C32(0xd04a1d00), + SPH_C32(0x3d450000), SPH_C32(0x3dc222ee), SPH_C32(0xae34d136), + SPH_C32(0x81e78d70), SPH_C32(0xb6b6c359), SPH_C32(0xd0f50000), + SPH_C32(0xcc840000), SPH_C32(0x8d5d0500), SPH_C32(0x1aec0000), + SPH_C32(0x1d1a51b2), SPH_C32(0xf3739b31), SPH_C32(0x0dbc4449), + SPH_C32(0xa60624eb) }, + { SPH_C32(0xaee70000), SPH_C32(0xac8e0000), SPH_C32(0xffe71080), + SPH_C32(0x55db0000), SPH_C32(0xe00874b9), SPH_C32(0x9ffa96d1), + SPH_C32(0x572ed364), SPH_C32(0x6512928d), SPH_C32(0x64c20000), + SPH_C32(0x7b1b0000), SPH_C32(0x7ede0900), SPH_C32(0xb1190000), + SPH_C32(0x27f46a34), SPH_C32(0x0a01260d), SPH_C32(0x9473acea), + SPH_C32(0x0f3328be) }, + { SPH_C32(0x62f30000), SPH_C32(0x09ed0000), SPH_C32(0xa55e1700), + SPH_C32(0x6e8b0000), SPH_C32(0xabd86746), SPH_C32(0x1861a2c9), + SPH_C32(0x3e6d9ba5), SPH_C32(0xaf481573), SPH_C32(0xe55c0000), + SPH_C32(0x974c0000), SPH_C32(0x18ec0b80), SPH_C32(0x24ea0000), + SPH_C32(0x7a5d4236), SPH_C32(0x42f51ab1), SPH_C32(0x72290ec7), + SPH_C32(0x81549f44) }, + { SPH_C32(0x2f790000), SPH_C32(0x40d90000), SPH_C32(0x99d51200), + SPH_C32(0xc0280000), SPH_C32(0xbda15cbb), SPH_C32(0xd70eaa6d), + SPH_C32(0xb1747149), SPH_C32(0xeb752577), SPH_C32(0x29480000), + SPH_C32(0x322f0000), SPH_C32(0x42550c00), SPH_C32(0x1fba0000), + SPH_C32(0x318d51c9), SPH_C32(0xc56e2ea9), SPH_C32(0x1b6a4606), + SPH_C32(0x4b0e18ba) }, + { SPH_C32(0xe36d0000), SPH_C32(0xe5ba0000), SPH_C32(0xc36c1580), + SPH_C32(0xfb780000), SPH_C32(0xf6714f44), SPH_C32(0x50959e75), + SPH_C32(0xd8373988), SPH_C32(0x212fa289), SPH_C32(0xa8d60000), + SPH_C32(0xde780000), SPH_C32(0x24670e80), SPH_C32(0x8a490000), + SPH_C32(0x6c2479cb), SPH_C32(0x8d9a1215), SPH_C32(0xfd30e42b), + SPH_C32(0xc569af40) }, + { SPH_C32(0xd6c40000), SPH_C32(0xbe720000), SPH_C32(0x56dd1b00), + SPH_C32(0xc57e0000), SPH_C32(0x91365cc0), SPH_C32(0xe1131ff5), + SPH_C32(0xa7a27306), SPH_C32(0x067d1926), SPH_C32(0x666d0000), + SPH_C32(0xcc330000), SPH_C32(0xc4c20a00), SPH_C32(0xe7810000), + SPH_C32(0x9d792fe7), SPH_C32(0x8a49e06a), SPH_C32(0x3d2fb870), + SPH_C32(0xfbc5c2c5) }, + { SPH_C32(0x1ad00000), SPH_C32(0x1b110000), SPH_C32(0x0c641c80), + SPH_C32(0xfe2e0000), SPH_C32(0xdae64f3f), SPH_C32(0x66882bed), + SPH_C32(0xcee13bc7), SPH_C32(0xcc279ed8), SPH_C32(0xe7f30000), + SPH_C32(0x20640000), SPH_C32(0xa2f00880), SPH_C32(0x72720000), + SPH_C32(0xc0d007e5), SPH_C32(0xc2bddcd6), SPH_C32(0xdb751a5d), + SPH_C32(0x75a2753f) }, + { SPH_C32(0x575a0000), SPH_C32(0x52250000), SPH_C32(0x30ef1980), + SPH_C32(0x508d0000), SPH_C32(0xcc9f74c2), SPH_C32(0xa9e72349), + SPH_C32(0x41f8d12b), SPH_C32(0x881aaedc), SPH_C32(0x2be70000), + SPH_C32(0x85070000), SPH_C32(0xf8490f00), SPH_C32(0x49220000), + SPH_C32(0x8b00141a), SPH_C32(0x4526e8ce), SPH_C32(0xb236529c), + SPH_C32(0xbff8f2c1) }, + { SPH_C32(0x9b4e0000), SPH_C32(0xf7460000), SPH_C32(0x6a561e00), + SPH_C32(0x6bdd0000), SPH_C32(0x874f673d), SPH_C32(0x2e7c1751), + SPH_C32(0x28bb99ea), SPH_C32(0x42402922), SPH_C32(0xaa790000), + SPH_C32(0x69500000), SPH_C32(0x9e7b0d80), SPH_C32(0xdcd10000), + SPH_C32(0xd6a93c18), SPH_C32(0x0dd2d472), SPH_C32(0x546cf0b1), + SPH_C32(0x319f453b) } +}; + +static const sph_u32 T512_40[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x07ed0000), SPH_C32(0xb2500000), SPH_C32(0x8774000a), + SPH_C32(0x970d0000), SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), + SPH_C32(0xf4786222), SPH_C32(0x9075b1ce), SPH_C32(0xa2d60000), + SPH_C32(0xa6760000), SPH_C32(0xc9440014), SPH_C32(0xeba30000), + SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), SPH_C32(0x03490afa), + SPH_C32(0x9b6ef888) }, + { SPH_C32(0x88980000), SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), + SPH_C32(0xfb4e0000), SPH_C32(0xf158079a), SPH_C32(0x61ae9167), + SPH_C32(0xa895706c), SPH_C32(0xe6107494), SPH_C32(0x0bc20000), + SPH_C32(0xdb630000), SPH_C32(0x7e88000c), SPH_C32(0x15860000), + SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), SPH_C32(0xf460449e), + SPH_C32(0xd8b61463) }, + { SPH_C32(0x8f750000), SPH_C32(0xadc40000), SPH_C32(0xf8bb0024), + SPH_C32(0x6c430000), SPH_C32(0xb22a2434), SPH_C32(0x2969ffc3), + SPH_C32(0x5ced124e), SPH_C32(0x7665c55a), SPH_C32(0xa9140000), + SPH_C32(0x7d150000), SPH_C32(0xb7cc0018), SPH_C32(0xfe250000), + SPH_C32(0x5d116688), SPH_C32(0x45997fda), SPH_C32(0xf7294e64), + SPH_C32(0x43d8eceb) }, + { SPH_C32(0x0bc20000), SPH_C32(0xdb630000), SPH_C32(0x7e88000c), + SPH_C32(0x15860000), SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), + SPH_C32(0xf460449e), SPH_C32(0xd8b61463), SPH_C32(0x835a0000), + SPH_C32(0xc4f70000), SPH_C32(0x01470022), SPH_C32(0xeec80000), + SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), SPH_C32(0x5cf534f2), + SPH_C32(0x3ea660f7) }, + { SPH_C32(0x0c2f0000), SPH_C32(0x69330000), SPH_C32(0xf9fc0006), + SPH_C32(0x828b0000), SPH_C32(0xd28f6b5d), SPH_C32(0x3d46d5e7), + SPH_C32(0x001826bc), SPH_C32(0x48c3a5ad), SPH_C32(0x218c0000), + SPH_C32(0x62810000), SPH_C32(0xc8030036), SPH_C32(0x056b0000), + SPH_C32(0xac496112), SPH_C32(0x2437eebd), SPH_C32(0x5fbc3e08), + SPH_C32(0xa5c8987f) }, + { SPH_C32(0x835a0000), SPH_C32(0xc4f70000), SPH_C32(0x01470022), + SPH_C32(0xeec80000), SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), + SPH_C32(0x5cf534f2), SPH_C32(0x3ea660f7), SPH_C32(0x88980000), + SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), SPH_C32(0xfb4e0000), + SPH_C32(0xf158079a), SPH_C32(0x61ae9167), SPH_C32(0xa895706c), + SPH_C32(0xe6107494) }, + { SPH_C32(0x84b70000), SPH_C32(0x76a70000), SPH_C32(0x86330028), + SPH_C32(0x79c50000), SPH_C32(0x23d76cc7), SPH_C32(0x5ce84480), + SPH_C32(0xa88d56d0), SPH_C32(0xaed3d139), SPH_C32(0x2a4e0000), + SPH_C32(0xb9e20000), SPH_C32(0xb68b003a), SPH_C32(0x10ed0000), + SPH_C32(0x3db429e1), SPH_C32(0x51b655fe), SPH_C32(0xabdc7a96), + SPH_C32(0x7d7e8c1c) }, + { SPH_C32(0x52500000), SPH_C32(0x29540000), SPH_C32(0x6a61004e), + SPH_C32(0xf0ff0000), SPH_C32(0x9a317eec), SPH_C32(0x452341ce), + SPH_C32(0xcf568fe5), SPH_C32(0x5303130f), SPH_C32(0x538d0000), + SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), SPH_C32(0x56ff0000), + SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), SPH_C32(0xa9444018), + SPH_C32(0x7f975691) }, + { SPH_C32(0x55bd0000), SPH_C32(0x9b040000), SPH_C32(0xed150044), + SPH_C32(0x67f20000), SPH_C32(0xd9435d42), SPH_C32(0x0de42f6a), + SPH_C32(0x3b2eedc7), SPH_C32(0xc376a2c1), SPH_C32(0xf15b0000), + SPH_C32(0x0f8a0000), SPH_C32(0x57b30012), SPH_C32(0xbd5c0000), + SPH_C32(0xc6082e35), SPH_C32(0xa2dd0960), SPH_C32(0xaa0d4ae2), + SPH_C32(0xe4f9ae19) }, + { SPH_C32(0xdac80000), SPH_C32(0x36c00000), SPH_C32(0x15ae0060), + SPH_C32(0x0bb10000), SPH_C32(0x6b697976), SPH_C32(0x248dd0a9), + SPH_C32(0x67c3ff89), SPH_C32(0xb513679b), SPH_C32(0x584f0000), + SPH_C32(0x729f0000), SPH_C32(0xe07f000a), SPH_C32(0x43790000), + SPH_C32(0x9b1948bd), SPH_C32(0xe74476ba), SPH_C32(0x5d240486), + SPH_C32(0xa72142f2) }, + { SPH_C32(0xdd250000), SPH_C32(0x84900000), SPH_C32(0x92da006a), + SPH_C32(0x9cbc0000), SPH_C32(0x281b5ad8), SPH_C32(0x6c4abe0d), + SPH_C32(0x93bb9dab), SPH_C32(0x2566d655), SPH_C32(0xfa990000), + SPH_C32(0xd4e90000), SPH_C32(0x293b001e), SPH_C32(0xa8da0000), + SPH_C32(0x57f566c6), SPH_C32(0xd75cb223), SPH_C32(0x5e6d0e7c), + SPH_C32(0x3c4fba7a) }, + { SPH_C32(0x59920000), SPH_C32(0xf2370000), SPH_C32(0x14e90042), + SPH_C32(0xe5790000), SPH_C32(0x0bcc361f), SPH_C32(0x30a2fa8d), + SPH_C32(0x3b36cb7b), SPH_C32(0x8bb5076c), SPH_C32(0xd0d70000), + SPH_C32(0x6d0b0000), SPH_C32(0x9fb00024), SPH_C32(0xb8370000), + SPH_C32(0x6a414f27), SPH_C32(0x86eae7dd), SPH_C32(0xf5b174ea), + SPH_C32(0x41313666) }, + { SPH_C32(0x5e7f0000), SPH_C32(0x40670000), SPH_C32(0x939d0048), + SPH_C32(0x72740000), SPH_C32(0x48be15b1), SPH_C32(0x78659429), + SPH_C32(0xcf4ea959), SPH_C32(0x1bc0b6a2), SPH_C32(0x72010000), + SPH_C32(0xcb7d0000), SPH_C32(0x56f40030), SPH_C32(0x53940000), + SPH_C32(0xa6ad615c), SPH_C32(0xb6f22344), SPH_C32(0xf6f87e10), + SPH_C32(0xda5fceee) }, + { SPH_C32(0xd10a0000), SPH_C32(0xeda30000), SPH_C32(0x6b26006c), + SPH_C32(0x1e370000), SPH_C32(0xfa943185), SPH_C32(0x510c6bea), + SPH_C32(0x93a3bb17), SPH_C32(0x6da573f8), SPH_C32(0xdb150000), + SPH_C32(0xb6680000), SPH_C32(0xe1380028), SPH_C32(0xadb10000), + SPH_C32(0xfbbc07d4), SPH_C32(0xf36b5c9e), SPH_C32(0x01d13074), + SPH_C32(0x99872205) }, + { SPH_C32(0xd6e70000), SPH_C32(0x5ff30000), SPH_C32(0xec520066), + SPH_C32(0x893a0000), SPH_C32(0xb9e6122b), SPH_C32(0x19cb054e), + SPH_C32(0x67dbd935), SPH_C32(0xfdd0c236), SPH_C32(0x79c30000), + SPH_C32(0x101e0000), SPH_C32(0x287c003c), SPH_C32(0x46120000), + SPH_C32(0x375029af), SPH_C32(0xc3739807), SPH_C32(0x02983a8e), + SPH_C32(0x02e9da8d) }, + { SPH_C32(0x538d0000), SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), + SPH_C32(0x56ff0000), SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), + SPH_C32(0xa9444018), SPH_C32(0x7f975691), SPH_C32(0x01dd0000), + SPH_C32(0x80a80000), SPH_C32(0xf4960048), SPH_C32(0xa6000000), + SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), SPH_C32(0x6612cffd), + SPH_C32(0x2c94459e) }, + { SPH_C32(0x54600000), SPH_C32(0x1bac0000), SPH_C32(0x1983000c), + SPH_C32(0xc1f20000), SPH_C32(0x499623e0), SPH_C32(0xda02a35d), + SPH_C32(0x5d3c223a), SPH_C32(0xefe2e75f), SPH_C32(0xa30b0000), + SPH_C32(0x26de0000), SPH_C32(0x3dd2005c), SPH_C32(0x4da30000), + SPH_C32(0x5c3950d9), SPH_C32(0xe7fe48ae), SPH_C32(0x655bc507), + SPH_C32(0xb7fabd16) }, + { SPH_C32(0xdb150000), SPH_C32(0xb6680000), SPH_C32(0xe1380028), + SPH_C32(0xadb10000), SPH_C32(0xfbbc07d4), SPH_C32(0xf36b5c9e), + SPH_C32(0x01d13074), SPH_C32(0x99872205), SPH_C32(0x0a1f0000), + SPH_C32(0x5bcb0000), SPH_C32(0x8a1e0044), SPH_C32(0xb3860000), + SPH_C32(0x01283651), SPH_C32(0xa2673774), SPH_C32(0x92728b63), + SPH_C32(0xf42251fd) }, + { SPH_C32(0xdcf80000), SPH_C32(0x04380000), SPH_C32(0x664c0022), + SPH_C32(0x3abc0000), SPH_C32(0xb8ce247a), SPH_C32(0xbbac323a), + SPH_C32(0xf5a95256), SPH_C32(0x09f293cb), SPH_C32(0xa8c90000), + SPH_C32(0xfdbd0000), SPH_C32(0x435a0050), SPH_C32(0x58250000), + SPH_C32(0xcdc4182a), SPH_C32(0x927ff3ed), SPH_C32(0x913b8199), + SPH_C32(0x6f4ca975) }, + { SPH_C32(0x584f0000), SPH_C32(0x729f0000), SPH_C32(0xe07f000a), + SPH_C32(0x43790000), SPH_C32(0x9b1948bd), SPH_C32(0xe74476ba), + SPH_C32(0x5d240486), SPH_C32(0xa72142f2), SPH_C32(0x82870000), + SPH_C32(0x445f0000), SPH_C32(0xf5d1006a), SPH_C32(0x48c80000), + SPH_C32(0xf07031cb), SPH_C32(0xc3c9a613), SPH_C32(0x3ae7fb0f), + SPH_C32(0x12322569) }, + { SPH_C32(0x5fa20000), SPH_C32(0xc0cf0000), SPH_C32(0x670b0000), + SPH_C32(0xd4740000), SPH_C32(0xd86b6b13), SPH_C32(0xaf83181e), + SPH_C32(0xa95c66a4), SPH_C32(0x3754f33c), SPH_C32(0x20510000), + SPH_C32(0xe2290000), SPH_C32(0x3c95007e), SPH_C32(0xa36b0000), + SPH_C32(0x3c9c1fb0), SPH_C32(0xf3d1628a), SPH_C32(0x39aef1f5), + SPH_C32(0x895cdde1) }, + { SPH_C32(0xd0d70000), SPH_C32(0x6d0b0000), SPH_C32(0x9fb00024), + SPH_C32(0xb8370000), SPH_C32(0x6a414f27), SPH_C32(0x86eae7dd), + SPH_C32(0xf5b174ea), SPH_C32(0x41313666), SPH_C32(0x89450000), + SPH_C32(0x9f3c0000), SPH_C32(0x8b590066), SPH_C32(0x5d4e0000), + SPH_C32(0x618d7938), SPH_C32(0xb6481d50), SPH_C32(0xce87bf91), + SPH_C32(0xca84310a) }, + { SPH_C32(0xd73a0000), SPH_C32(0xdf5b0000), SPH_C32(0x18c4002e), + SPH_C32(0x2f3a0000), SPH_C32(0x29336c89), SPH_C32(0xce2d8979), + SPH_C32(0x01c916c8), SPH_C32(0xd14487a8), SPH_C32(0x2b930000), + SPH_C32(0x394a0000), SPH_C32(0x421d0072), SPH_C32(0xb6ed0000), + SPH_C32(0xad615743), SPH_C32(0x8650d9c9), SPH_C32(0xcdceb56b), + SPH_C32(0x51eac982) }, + { SPH_C32(0x01dd0000), SPH_C32(0x80a80000), SPH_C32(0xf4960048), + SPH_C32(0xa6000000), SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), + SPH_C32(0x6612cffd), SPH_C32(0x2c94459e), SPH_C32(0x52500000), + SPH_C32(0x29540000), SPH_C32(0x6a61004e), SPH_C32(0xf0ff0000), + SPH_C32(0x9a317eec), SPH_C32(0x452341ce), SPH_C32(0xcf568fe5), + SPH_C32(0x5303130f) }, + { SPH_C32(0x06300000), SPH_C32(0x32f80000), SPH_C32(0x73e20042), + SPH_C32(0x310d0000), SPH_C32(0xd3a75d0c), SPH_C32(0x9f21e293), + SPH_C32(0x926aaddf), SPH_C32(0xbce1f450), SPH_C32(0xf0860000), + SPH_C32(0x8f220000), SPH_C32(0xa325005a), SPH_C32(0x1b5c0000), + SPH_C32(0x56dd5097), SPH_C32(0x753b8557), SPH_C32(0xcc1f851f), + SPH_C32(0xc86deb87) }, + { SPH_C32(0x89450000), SPH_C32(0x9f3c0000), SPH_C32(0x8b590066), + SPH_C32(0x5d4e0000), SPH_C32(0x618d7938), SPH_C32(0xb6481d50), + SPH_C32(0xce87bf91), SPH_C32(0xca84310a), SPH_C32(0x59920000), + SPH_C32(0xf2370000), SPH_C32(0x14e90042), SPH_C32(0xe5790000), + SPH_C32(0x0bcc361f), SPH_C32(0x30a2fa8d), SPH_C32(0x3b36cb7b), + SPH_C32(0x8bb5076c) }, + { SPH_C32(0x8ea80000), SPH_C32(0x2d6c0000), SPH_C32(0x0c2d006c), + SPH_C32(0xca430000), SPH_C32(0x22ff5a96), SPH_C32(0xfe8f73f4), + SPH_C32(0x3affddb3), SPH_C32(0x5af180c4), SPH_C32(0xfb440000), + SPH_C32(0x54410000), SPH_C32(0xddad0056), SPH_C32(0x0eda0000), + SPH_C32(0xc7201864), SPH_C32(0x00ba3e14), SPH_C32(0x387fc181), + SPH_C32(0x10dbffe4) }, + { SPH_C32(0x0a1f0000), SPH_C32(0x5bcb0000), SPH_C32(0x8a1e0044), + SPH_C32(0xb3860000), SPH_C32(0x01283651), SPH_C32(0xa2673774), + SPH_C32(0x92728b63), SPH_C32(0xf42251fd), SPH_C32(0xd10a0000), + SPH_C32(0xeda30000), SPH_C32(0x6b26006c), SPH_C32(0x1e370000), + SPH_C32(0xfa943185), SPH_C32(0x510c6bea), SPH_C32(0x93a3bb17), + SPH_C32(0x6da573f8) }, + { SPH_C32(0x0df20000), SPH_C32(0xe99b0000), SPH_C32(0x0d6a004e), + SPH_C32(0x248b0000), SPH_C32(0x425a15ff), SPH_C32(0xeaa059d0), + SPH_C32(0x660ae941), SPH_C32(0x6457e033), SPH_C32(0x73dc0000), + SPH_C32(0x4bd50000), SPH_C32(0xa2620078), SPH_C32(0xf5940000), + SPH_C32(0x36781ffe), SPH_C32(0x6114af73), SPH_C32(0x90eab1ed), + SPH_C32(0xf6cb8b70) }, + { SPH_C32(0x82870000), SPH_C32(0x445f0000), SPH_C32(0xf5d1006a), + SPH_C32(0x48c80000), SPH_C32(0xf07031cb), SPH_C32(0xc3c9a613), + SPH_C32(0x3ae7fb0f), SPH_C32(0x12322569), SPH_C32(0xdac80000), + SPH_C32(0x36c00000), SPH_C32(0x15ae0060), SPH_C32(0x0bb10000), + SPH_C32(0x6b697976), SPH_C32(0x248dd0a9), SPH_C32(0x67c3ff89), + SPH_C32(0xb513679b) }, + { SPH_C32(0x856a0000), SPH_C32(0xf60f0000), SPH_C32(0x72a50060), + SPH_C32(0xdfc50000), SPH_C32(0xb3021265), SPH_C32(0x8b0ec8b7), + SPH_C32(0xce9f992d), SPH_C32(0x824794a7), SPH_C32(0x781e0000), + SPH_C32(0x90b60000), SPH_C32(0xdcea0074), SPH_C32(0xe0120000), + SPH_C32(0xa785570d), SPH_C32(0x14951430), SPH_C32(0x648af573), + SPH_C32(0x2e7d9f13) } +}; + +static const sph_u32 T512_45[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x1e6c0000), SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), + SPH_C32(0xbcb6b800), SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), + SPH_C32(0x6a0c1bc8), SPH_C32(0xb99dc2eb), SPH_C32(0x92560000), + SPH_C32(0x1eda0000), SPH_C32(0xea510000), SPH_C32(0xe8b13000), + SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), SPH_C32(0xb15c2254), + SPH_C32(0x33c5244f) }, + { SPH_C32(0x92560000), SPH_C32(0x1eda0000), SPH_C32(0xea510000), + SPH_C32(0xe8b13000), SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), + SPH_C32(0xb15c2254), SPH_C32(0x33c5244f), SPH_C32(0x8c3a0000), + SPH_C32(0xda980000), SPH_C32(0x607f0000), SPH_C32(0x54078800), + SPH_C32(0x85714513), SPH_C32(0x6006b243), SPH_C32(0xdb50399c), + SPH_C32(0x8a58e6a4) }, + { SPH_C32(0x8c3a0000), SPH_C32(0xda980000), SPH_C32(0x607f0000), + SPH_C32(0x54078800), SPH_C32(0x85714513), SPH_C32(0x6006b243), + SPH_C32(0xdb50399c), SPH_C32(0x8a58e6a4), SPH_C32(0x1e6c0000), + SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), SPH_C32(0xbcb6b800), + SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), SPH_C32(0x6a0c1bc8), + SPH_C32(0xb99dc2eb) }, + { SPH_C32(0x58430000), SPH_C32(0x807e0000), SPH_C32(0x78330001), + SPH_C32(0xc66b3800), SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), + SPH_C32(0xac73fe6f), SPH_C32(0x3a4479b1), SPH_C32(0x1d5a0000), + SPH_C32(0x2b720000), SPH_C32(0x488d0000), SPH_C32(0xaf611800), + SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), SPH_C32(0x81a20429), + SPH_C32(0x1e7536a6) }, + { SPH_C32(0x462f0000), SPH_C32(0x443c0000), SPH_C32(0xf21d0001), + SPH_C32(0x7add8000), SPH_C32(0xcb734f6a), SPH_C32(0xf250ec07), + SPH_C32(0xc67fe5a7), SPH_C32(0x83d9bb5a), SPH_C32(0x8f0c0000), + SPH_C32(0x35a80000), SPH_C32(0xa2dc0000), SPH_C32(0x47d02800), + SPH_C32(0x8cfe7860), SPH_C32(0x2382de49), SPH_C32(0x30fe267d), + SPH_C32(0x2db012e9) }, + { SPH_C32(0xca150000), SPH_C32(0x9ea40000), SPH_C32(0x92620001), + SPH_C32(0x2eda0800), SPH_C32(0x4e020a79), SPH_C32(0x92565e44), + SPH_C32(0x1d2fdc3b), SPH_C32(0x09815dfe), SPH_C32(0x91600000), + SPH_C32(0xf1ea0000), SPH_C32(0x28f20000), SPH_C32(0xfb669000), + SPH_C32(0xa0ba6bd6), SPH_C32(0xa87f0d93), SPH_C32(0x5af23db5), + SPH_C32(0x942dd002) }, + { SPH_C32(0xd4790000), SPH_C32(0x5ae60000), SPH_C32(0x184c0001), + SPH_C32(0x926cb000), SPH_C32(0x624619cf), SPH_C32(0x19ab8d9e), + SPH_C32(0x7723c7f3), SPH_C32(0xb01c9f15), SPH_C32(0x03360000), + SPH_C32(0xef300000), SPH_C32(0xc2a30000), SPH_C32(0x13d7a000), + SPH_C32(0x098f3d73), SPH_C32(0x43846c0a), SPH_C32(0xebae1fe1), + SPH_C32(0xa7e8f44d) }, + { SPH_C32(0x1d5a0000), SPH_C32(0x2b720000), SPH_C32(0x488d0000), + SPH_C32(0xaf611800), SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), + SPH_C32(0x81a20429), SPH_C32(0x1e7536a6), SPH_C32(0x45190000), + SPH_C32(0xab0c0000), SPH_C32(0x30be0001), SPH_C32(0x690a2000), + SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), SPH_C32(0x2dd1fa46), + SPH_C32(0x24314f17) }, + { SPH_C32(0x03360000), SPH_C32(0xef300000), SPH_C32(0xc2a30000), + SPH_C32(0x13d7a000), SPH_C32(0x098f3d73), SPH_C32(0x43846c0a), + SPH_C32(0xebae1fe1), SPH_C32(0xa7e8f44d), SPH_C32(0xd74f0000), + SPH_C32(0xb5d60000), SPH_C32(0xdaef0001), SPH_C32(0x81bb1000), + SPH_C32(0x6bc924bc), SPH_C32(0x5a2fe194), SPH_C32(0x9c8dd812), + SPH_C32(0x17f46b58) }, + { SPH_C32(0x8f0c0000), SPH_C32(0x35a80000), SPH_C32(0xa2dc0000), + SPH_C32(0x47d02800), SPH_C32(0x8cfe7860), SPH_C32(0x2382de49), + SPH_C32(0x30fe267d), SPH_C32(0x2db012e9), SPH_C32(0xc9230000), + SPH_C32(0x71940000), SPH_C32(0x50c10001), SPH_C32(0x3d0da800), + SPH_C32(0x478d370a), SPH_C32(0xd1d2324e), SPH_C32(0xf681c3da), + SPH_C32(0xae69a9b3) }, + { SPH_C32(0x91600000), SPH_C32(0xf1ea0000), SPH_C32(0x28f20000), + SPH_C32(0xfb669000), SPH_C32(0xa0ba6bd6), SPH_C32(0xa87f0d93), + SPH_C32(0x5af23db5), SPH_C32(0x942dd002), SPH_C32(0x5b750000), + SPH_C32(0x6f4e0000), SPH_C32(0xba900001), SPH_C32(0xd5bc9800), + SPH_C32(0xeeb861af), SPH_C32(0x3a2953d7), SPH_C32(0x47dde18e), + SPH_C32(0x9dac8dfc) }, + { SPH_C32(0x45190000), SPH_C32(0xab0c0000), SPH_C32(0x30be0001), + SPH_C32(0x690a2000), SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), + SPH_C32(0x2dd1fa46), SPH_C32(0x24314f17), SPH_C32(0x58430000), + SPH_C32(0x807e0000), SPH_C32(0x78330001), SPH_C32(0xc66b3800), + SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), SPH_C32(0xac73fe6f), + SPH_C32(0x3a4479b1) }, + { SPH_C32(0x5b750000), SPH_C32(0x6f4e0000), SPH_C32(0xba900001), + SPH_C32(0xd5bc9800), SPH_C32(0xeeb861af), SPH_C32(0x3a2953d7), + SPH_C32(0x47dde18e), SPH_C32(0x9dac8dfc), SPH_C32(0xca150000), + SPH_C32(0x9ea40000), SPH_C32(0x92620001), SPH_C32(0x2eda0800), + SPH_C32(0x4e020a79), SPH_C32(0x92565e44), SPH_C32(0x1d2fdc3b), + SPH_C32(0x09815dfe) }, + { SPH_C32(0xd74f0000), SPH_C32(0xb5d60000), SPH_C32(0xdaef0001), + SPH_C32(0x81bb1000), SPH_C32(0x6bc924bc), SPH_C32(0x5a2fe194), + SPH_C32(0x9c8dd812), SPH_C32(0x17f46b58), SPH_C32(0xd4790000), + SPH_C32(0x5ae60000), SPH_C32(0x184c0001), SPH_C32(0x926cb000), + SPH_C32(0x624619cf), SPH_C32(0x19ab8d9e), SPH_C32(0x7723c7f3), + SPH_C32(0xb01c9f15) }, + { SPH_C32(0xc9230000), SPH_C32(0x71940000), SPH_C32(0x50c10001), + SPH_C32(0x3d0da800), SPH_C32(0x478d370a), SPH_C32(0xd1d2324e), + SPH_C32(0xf681c3da), SPH_C32(0xae69a9b3), SPH_C32(0x462f0000), + SPH_C32(0x443c0000), SPH_C32(0xf21d0001), SPH_C32(0x7add8000), + SPH_C32(0xcb734f6a), SPH_C32(0xf250ec07), SPH_C32(0xc67fe5a7), + SPH_C32(0x83d9bb5a) }, + { SPH_C32(0xa53b0000), SPH_C32(0x14260000), SPH_C32(0x4e30001e), + SPH_C32(0x7cae0000), SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), + SPH_C32(0xf73168d8), SPH_C32(0x0b1b4946), SPH_C32(0x07ed0000), + SPH_C32(0xb2500000), SPH_C32(0x8774000a), SPH_C32(0x970d0000), + SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), SPH_C32(0xf4786222), + SPH_C32(0x9075b1ce) }, + { SPH_C32(0xbb570000), SPH_C32(0xd0640000), SPH_C32(0xc41e001e), + SPH_C32(0xc018b800), SPH_C32(0xa3da1e63), SPH_C32(0xf32279e7), + SPH_C32(0x9d3d7310), SPH_C32(0xb2868bad), SPH_C32(0x95bb0000), + SPH_C32(0xac8a0000), SPH_C32(0x6d25000a), SPH_C32(0x7fbc3000), + SPH_C32(0xea47750b), SPH_C32(0xa33c0f3d), SPH_C32(0x45244076), + SPH_C32(0xa3b09581) }, + { SPH_C32(0x376d0000), SPH_C32(0x0afc0000), SPH_C32(0xa461001e), + SPH_C32(0x941f3000), SPH_C32(0x26ab5b70), SPH_C32(0x9324cba4), + SPH_C32(0x466d4a8c), SPH_C32(0x38de6d09), SPH_C32(0x8bd70000), + SPH_C32(0x68c80000), SPH_C32(0xe70b000a), SPH_C32(0xc30a8800), + SPH_C32(0xc60366bd), SPH_C32(0x28c1dce7), SPH_C32(0x2f285bbe), + SPH_C32(0x1a2d576a) }, + { SPH_C32(0x29010000), SPH_C32(0xcebe0000), SPH_C32(0x2e4f001e), + SPH_C32(0x28a98800), SPH_C32(0x0aef48c6), SPH_C32(0x18d9187e), + SPH_C32(0x2c615144), SPH_C32(0x8143afe2), SPH_C32(0x19810000), + SPH_C32(0x76120000), SPH_C32(0x0d5a000a), SPH_C32(0x2bbbb800), + SPH_C32(0x6f363018), SPH_C32(0xc33abd7e), SPH_C32(0x9e7479ea), + SPH_C32(0x29e87325) }, + { SPH_C32(0xfd780000), SPH_C32(0x94580000), SPH_C32(0x3603001f), + SPH_C32(0xbac53800), SPH_C32(0x68a95109), SPH_C32(0x017295e0), + SPH_C32(0x5b4296b7), SPH_C32(0x315f30f7), SPH_C32(0x1ab70000), + SPH_C32(0x99220000), SPH_C32(0xcff9000a), SPH_C32(0x386c1800), + SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), SPH_C32(0x75da660b), + SPH_C32(0x8e008768) }, + { SPH_C32(0xe3140000), SPH_C32(0x501a0000), SPH_C32(0xbc2d001f), + SPH_C32(0x06738000), SPH_C32(0x44ed42bf), SPH_C32(0x8a8f463a), + SPH_C32(0x314e8d7f), SPH_C32(0x88c2f21c), SPH_C32(0x88e10000), + SPH_C32(0x87f80000), SPH_C32(0x25a8000a), SPH_C32(0xd0dd2800), + SPH_C32(0xcf8c5bce), SPH_C32(0x6b45b0ed), SPH_C32(0xc486445f), + SPH_C32(0xbdc5a327) }, + { SPH_C32(0x6f2e0000), SPH_C32(0x8a820000), SPH_C32(0xdc52001f), + SPH_C32(0x52740800), SPH_C32(0xc19c07ac), SPH_C32(0xea89f479), + SPH_C32(0xea1eb4e3), SPH_C32(0x029a14b8), SPH_C32(0x968d0000), + SPH_C32(0x43ba0000), SPH_C32(0xaf86000a), SPH_C32(0x6c6b9000), + SPH_C32(0xe3c84878), SPH_C32(0xe0b86337), SPH_C32(0xae8a5f97), + SPH_C32(0x045861cc) }, + { SPH_C32(0x71420000), SPH_C32(0x4ec00000), SPH_C32(0x567c001f), + SPH_C32(0xeec2b000), SPH_C32(0xedd8141a), SPH_C32(0x617427a3), + SPH_C32(0x8012af2b), SPH_C32(0xbb07d653), SPH_C32(0x04db0000), + SPH_C32(0x5d600000), SPH_C32(0x45d7000a), SPH_C32(0x84daa000), + SPH_C32(0x4afd1edd), SPH_C32(0x0b4302ae), SPH_C32(0x1fd67dc3), + SPH_C32(0x379d4583) }, + { SPH_C32(0xb8610000), SPH_C32(0x3f540000), SPH_C32(0x06bd001e), + SPH_C32(0xd3cf1800), SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), + SPH_C32(0x76936cf1), SPH_C32(0x156e7fe0), SPH_C32(0x42f40000), + SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), SPH_C32(0xfe072000), + SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), SPH_C32(0xd9a99864), + SPH_C32(0xb444fed9) }, + { SPH_C32(0xa60d0000), SPH_C32(0xfb160000), SPH_C32(0x8c93001e), + SPH_C32(0x6f79a000), SPH_C32(0x861130a6), SPH_C32(0x3b5bc637), + SPH_C32(0x1c9f7739), SPH_C32(0xacf3bd0b), SPH_C32(0xd0a20000), + SPH_C32(0x07860000), SPH_C32(0x5d9b000b), SPH_C32(0x16b61000), + SPH_C32(0x28bb0712), SPH_C32(0x12e88f30), SPH_C32(0x68f5ba30), + SPH_C32(0x8781da96) }, + { SPH_C32(0x2a370000), SPH_C32(0x218e0000), SPH_C32(0xecec001e), + SPH_C32(0x3b7e2800), SPH_C32(0x036075b5), SPH_C32(0x5b5d7474), + SPH_C32(0xc7cf4ea5), SPH_C32(0x26ab5baf), SPH_C32(0xcece0000), + SPH_C32(0xc3c40000), SPH_C32(0xd7b5000b), SPH_C32(0xaa00a800), + SPH_C32(0x04ff14a4), SPH_C32(0x99155cea), SPH_C32(0x02f9a1f8), + SPH_C32(0x3e1c187d) }, + { SPH_C32(0x345b0000), SPH_C32(0xe5cc0000), SPH_C32(0x66c2001e), + SPH_C32(0x87c89000), SPH_C32(0x2f246603), SPH_C32(0xd0a0a7ae), + SPH_C32(0xadc3556d), SPH_C32(0x9f369944), SPH_C32(0x5c980000), + SPH_C32(0xdd1e0000), SPH_C32(0x3de4000b), SPH_C32(0x42b19800), + SPH_C32(0xadca4201), SPH_C32(0x72ee3d73), SPH_C32(0xb3a583ac), + SPH_C32(0x0dd93c32) }, + { SPH_C32(0xe0220000), SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), + SPH_C32(0x15a42000), SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), + SPH_C32(0xdae0929e), SPH_C32(0x2f2a0651), SPH_C32(0x5fae0000), + SPH_C32(0x322e0000), SPH_C32(0xff47000b), SPH_C32(0x51663800), + SPH_C32(0xa4457f72), SPH_C32(0x316a5179), SPH_C32(0x580b9c4d), + SPH_C32(0xaa31c87f) }, + { SPH_C32(0xfe4e0000), SPH_C32(0x7b680000), SPH_C32(0xf4a0001f), + SPH_C32(0xa9129800), SPH_C32(0x61266c7a), SPH_C32(0x42f6f9ea), + SPH_C32(0xb0ec8956), SPH_C32(0x96b7c4ba), SPH_C32(0xcdf80000), + SPH_C32(0x2cf40000), SPH_C32(0x1516000b), SPH_C32(0xb9d70800), + SPH_C32(0x0d7029d7), SPH_C32(0xda9130e0), SPH_C32(0xe957be19), + SPH_C32(0x99f4ec30) }, + { SPH_C32(0x72740000), SPH_C32(0xa1f00000), SPH_C32(0x94df001f), + SPH_C32(0xfd151000), SPH_C32(0xe4572969), SPH_C32(0x22f04ba9), + SPH_C32(0x6bbcb0ca), SPH_C32(0x1cef221e), SPH_C32(0xd3940000), + SPH_C32(0xe8b60000), SPH_C32(0x9f38000b), SPH_C32(0x0561b000), + SPH_C32(0x21343a61), SPH_C32(0x516ce33a), SPH_C32(0x835ba5d1), + SPH_C32(0x20692edb) }, + { SPH_C32(0x6c180000), SPH_C32(0x65b20000), SPH_C32(0x1ef1001f), + SPH_C32(0x41a3a800), SPH_C32(0xc8133adf), SPH_C32(0xa90d9873), + SPH_C32(0x01b0ab02), SPH_C32(0xa572e0f5), SPH_C32(0x41c20000), + SPH_C32(0xf66c0000), SPH_C32(0x7569000b), SPH_C32(0xedd08000), + SPH_C32(0x88016cc4), SPH_C32(0xba9782a3), SPH_C32(0x32078785), + SPH_C32(0x13ac0a94) } +}; + +static const sph_u32 T512_50[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xf0c50000), SPH_C32(0x59230000), SPH_C32(0x45820000), + SPH_C32(0xe18d00c0), SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), + SPH_C32(0xcbe0fe1c), SPH_C32(0x56a7b19f), SPH_C32(0x16ed0000), + SPH_C32(0x15680000), SPH_C32(0xedd70000), SPH_C32(0x325d0220), + SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), SPH_C32(0xe375f8a8), + SPH_C32(0x81fdf908) }, + { SPH_C32(0xb4310000), SPH_C32(0x77330000), SPH_C32(0xb15d0000), + SPH_C32(0x7fd004e0), SPH_C32(0x78a26138), SPH_C32(0xd116c35d), + SPH_C32(0xd256d489), SPH_C32(0x4e6f74de), SPH_C32(0xe3060000), + SPH_C32(0xbdc10000), SPH_C32(0x87130000), SPH_C32(0xbff20060), + SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), SPH_C32(0x73c5ab06), + SPH_C32(0x5bd61539) }, + { SPH_C32(0x44f40000), SPH_C32(0x2e100000), SPH_C32(0xf4df0000), + SPH_C32(0x9e5d0420), SPH_C32(0x43cf6709), SPH_C32(0x13fb95c4), + SPH_C32(0x19b62a95), SPH_C32(0x18c8c541), SPH_C32(0xf5eb0000), + SPH_C32(0xa8a90000), SPH_C32(0x6ac40000), SPH_C32(0x8daf0240), + SPH_C32(0xcdb63c93), SPH_C32(0xd7ffd112), SPH_C32(0x90b053ae), + SPH_C32(0xda2bec31) }, + { SPH_C32(0xe3060000), SPH_C32(0xbdc10000), SPH_C32(0x87130000), + SPH_C32(0xbff20060), SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), + SPH_C32(0x73c5ab06), SPH_C32(0x5bd61539), SPH_C32(0x57370000), + SPH_C32(0xcaf20000), SPH_C32(0x364e0000), SPH_C32(0xc0220480), + SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), SPH_C32(0xa1937f8f), + SPH_C32(0x15b961e7) }, + { SPH_C32(0x13c30000), SPH_C32(0xe4e20000), SPH_C32(0xc2910000), + SPH_C32(0x5e7f00a0), SPH_C32(0x15d70c2b), SPH_C32(0x4f5861c8), + SPH_C32(0xb825551a), SPH_C32(0x0d71a4a6), SPH_C32(0x41da0000), + SPH_C32(0xdf9a0000), SPH_C32(0xdb990000), SPH_C32(0xf27f06a0), + SPH_C32(0xb5145dab), SPH_C32(0x06e9124f), SPH_C32(0x42e68727), + SPH_C32(0x944498ef) }, + { SPH_C32(0x57370000), SPH_C32(0xcaf20000), SPH_C32(0x364e0000), + SPH_C32(0xc0220480), SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), + SPH_C32(0xa1937f8f), SPH_C32(0x15b961e7), SPH_C32(0xb4310000), + SPH_C32(0x77330000), SPH_C32(0xb15d0000), SPH_C32(0x7fd004e0), + SPH_C32(0x78a26138), SPH_C32(0xd116c35d), SPH_C32(0xd256d489), + SPH_C32(0x4e6f74de) }, + { SPH_C32(0xa7f20000), SPH_C32(0x93d10000), SPH_C32(0x73cc0000), + SPH_C32(0x21af0440), SPH_C32(0x6d756d13), SPH_C32(0x9e4ea295), + SPH_C32(0x6a738193), SPH_C32(0x431ed078), SPH_C32(0xa2dc0000), + SPH_C32(0x625b0000), SPH_C32(0x5c8a0000), SPH_C32(0x4d8d06c0), + SPH_C32(0x9bae57b1), SPH_C32(0x8b5c251e), SPH_C32(0x31232c21), + SPH_C32(0xcf928dd6) }, + { SPH_C32(0x02f20000), SPH_C32(0xa2810000), SPH_C32(0x873f0000), + SPH_C32(0xe36c7800), SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), + SPH_C32(0xc4c23237), SPH_C32(0x7f32259e), SPH_C32(0xbadd0000), + SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), SPH_C32(0xf7282800), + SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), SPH_C32(0xea5a8d14), + SPH_C32(0x2a2c18f0) }, + { SPH_C32(0xf2370000), SPH_C32(0xfba20000), SPH_C32(0xc2bd0000), + SPH_C32(0x02e178c0), SPH_C32(0x257072de), SPH_C32(0xc5d07d4f), + SPH_C32(0x0f22cc2b), SPH_C32(0x29959401), SPH_C32(0xac300000), + SPH_C32(0x06c50000), SPH_C32(0x5a300000), SPH_C32(0xc5752a20), + SPH_C32(0x3c4922c4), SPH_C32(0x6c502579), SPH_C32(0x092f75bc), + SPH_C32(0xabd1e1f8) }, + { SPH_C32(0xb6c30000), SPH_C32(0xd5b20000), SPH_C32(0x36620000), + SPH_C32(0x9cbc7ce0), SPH_C32(0x66bf15d7), SPH_C32(0xd62be88b), + SPH_C32(0x1694e6be), SPH_C32(0x315d5140), SPH_C32(0x59db0000), + SPH_C32(0xae6c0000), SPH_C32(0x30f40000), SPH_C32(0x48da2860), + SPH_C32(0xf1ff1e57), SPH_C32(0xbbaff46b), SPH_C32(0x999f2612), + SPH_C32(0x71fa0dc9) }, + { SPH_C32(0x46060000), SPH_C32(0x8c910000), SPH_C32(0x73e00000), + SPH_C32(0x7d317c20), SPH_C32(0x5dd213e6), SPH_C32(0x14c6be12), + SPH_C32(0xdd7418a2), SPH_C32(0x67fae0df), SPH_C32(0x4f360000), + SPH_C32(0xbb040000), SPH_C32(0xdd230000), SPH_C32(0x7a872a40), + SPH_C32(0x12f328de), SPH_C32(0xe1e51228), SPH_C32(0x7aeadeba), + SPH_C32(0xf007f4c1) }, + { SPH_C32(0xe1f40000), SPH_C32(0x1f400000), SPH_C32(0x002c0000), + SPH_C32(0x5c9e7860), SPH_C32(0x30a77ef5), SPH_C32(0x8a881c87), + SPH_C32(0xb7079931), SPH_C32(0x24e430a7), SPH_C32(0xedea0000), + SPH_C32(0xd95f0000), SPH_C32(0x81a90000), SPH_C32(0x370a2c80), + SPH_C32(0x895d7f6f), SPH_C32(0x6ab93736), SPH_C32(0x4bc9f29b), + SPH_C32(0x3f957917) }, + { SPH_C32(0x11310000), SPH_C32(0x46630000), SPH_C32(0x45ae0000), + SPH_C32(0xbd1378a0), SPH_C32(0x0bca78c4), SPH_C32(0x48654a1e), + SPH_C32(0x7ce7672d), SPH_C32(0x72438138), SPH_C32(0xfb070000), + SPH_C32(0xcc370000), SPH_C32(0x6c7e0000), SPH_C32(0x05572ea0), + SPH_C32(0x6a5149e6), SPH_C32(0x30f3d175), SPH_C32(0xa8bc0a33), + SPH_C32(0xbe68801f) }, + { SPH_C32(0x55c50000), SPH_C32(0x68730000), SPH_C32(0xb1710000), + SPH_C32(0x234e7c80), SPH_C32(0x48051fcd), SPH_C32(0x5b9edfda), + SPH_C32(0x65514db8), SPH_C32(0x6a8b4479), SPH_C32(0x0eec0000), + SPH_C32(0x649e0000), SPH_C32(0x06ba0000), SPH_C32(0x88f82ce0), + SPH_C32(0xa7e77575), SPH_C32(0xe70c0067), SPH_C32(0x380c599d), + SPH_C32(0x64436c2e) }, + { SPH_C32(0xa5000000), SPH_C32(0x31500000), SPH_C32(0xf4f30000), + SPH_C32(0xc2c37c40), SPH_C32(0x736819fc), SPH_C32(0x99738943), + SPH_C32(0xaeb1b3a4), SPH_C32(0x3c2cf5e6), SPH_C32(0x18010000), + SPH_C32(0x71f60000), SPH_C32(0xeb6d0000), SPH_C32(0xbaa52ec0), + SPH_C32(0x44eb43fc), SPH_C32(0xbd46e624), SPH_C32(0xdb79a135), + SPH_C32(0xe5be9526) }, + { SPH_C32(0xbadd0000), SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), + SPH_C32(0xf7282800), SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), + SPH_C32(0xea5a8d14), SPH_C32(0x2a2c18f0), SPH_C32(0xb82f0000), + SPH_C32(0xb12c0000), SPH_C32(0x30d80000), SPH_C32(0x14445000), + SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), SPH_C32(0x2e98bf23), + SPH_C32(0x551e3d6e) }, + { SPH_C32(0x4a180000), SPH_C32(0x4a8e0000), SPH_C32(0xf2650000), + SPH_C32(0x16a528c0), SPH_C32(0xe428127c), SPH_C32(0xf4f795a3), + SPH_C32(0x21ba7308), SPH_C32(0x7c8ba96f), SPH_C32(0xaec20000), + SPH_C32(0xa4440000), SPH_C32(0xdd0f0000), SPH_C32(0x26195220), + SPH_C32(0x2254562b), SPH_C32(0x6b6d0eaf), SPH_C32(0xcded478b), + SPH_C32(0xd4e3c466) }, + { SPH_C32(0x0eec0000), SPH_C32(0x649e0000), SPH_C32(0x06ba0000), + SPH_C32(0x88f82ce0), SPH_C32(0xa7e77575), SPH_C32(0xe70c0067), + SPH_C32(0x380c599d), SPH_C32(0x64436c2e), SPH_C32(0x5b290000), + SPH_C32(0x0ced0000), SPH_C32(0xb7cb0000), SPH_C32(0xabb65060), + SPH_C32(0xefe26ab8), SPH_C32(0xbc92dfbd), SPH_C32(0x5d5d1425), + SPH_C32(0x0ec82857) }, + { SPH_C32(0xfe290000), SPH_C32(0x3dbd0000), SPH_C32(0x43380000), + SPH_C32(0x69752c20), SPH_C32(0x9c8a7344), SPH_C32(0x25e156fe), + SPH_C32(0xf3eca781), SPH_C32(0x32e4ddb1), SPH_C32(0x4dc40000), + SPH_C32(0x19850000), SPH_C32(0x5a1c0000), SPH_C32(0x99eb5240), + SPH_C32(0x0cee5c31), SPH_C32(0xe6d839fe), SPH_C32(0xbe28ec8d), + SPH_C32(0x8f35d15f) }, + { SPH_C32(0x59db0000), SPH_C32(0xae6c0000), SPH_C32(0x30f40000), + SPH_C32(0x48da2860), SPH_C32(0xf1ff1e57), SPH_C32(0xbbaff46b), + SPH_C32(0x999f2612), SPH_C32(0x71fa0dc9), SPH_C32(0xef180000), + SPH_C32(0x7bde0000), SPH_C32(0x06960000), SPH_C32(0xd4665480), + SPH_C32(0x97400b80), SPH_C32(0x6d841ce0), SPH_C32(0x8f0bc0ac), + SPH_C32(0x40a75c89) }, + { SPH_C32(0xa91e0000), SPH_C32(0xf74f0000), SPH_C32(0x75760000), + SPH_C32(0xa95728a0), SPH_C32(0xca921866), SPH_C32(0x7942a2f2), + SPH_C32(0x527fd80e), SPH_C32(0x275dbc56), SPH_C32(0xf9f50000), + SPH_C32(0x6eb60000), SPH_C32(0xeb410000), SPH_C32(0xe63b56a0), + SPH_C32(0x744c3d09), SPH_C32(0x37cefaa3), SPH_C32(0x6c7e3804), + SPH_C32(0xc15aa581) }, + { SPH_C32(0xedea0000), SPH_C32(0xd95f0000), SPH_C32(0x81a90000), + SPH_C32(0x370a2c80), SPH_C32(0x895d7f6f), SPH_C32(0x6ab93736), + SPH_C32(0x4bc9f29b), SPH_C32(0x3f957917), SPH_C32(0x0c1e0000), + SPH_C32(0xc61f0000), SPH_C32(0x81850000), SPH_C32(0x6b9454e0), + SPH_C32(0xb9fa019a), SPH_C32(0xe0312bb1), SPH_C32(0xfcce6baa), + SPH_C32(0x1b7149b0) }, + { SPH_C32(0x1d2f0000), SPH_C32(0x807c0000), SPH_C32(0xc42b0000), + SPH_C32(0xd6872c40), SPH_C32(0xb230795e), SPH_C32(0xa85461af), + SPH_C32(0x80290c87), SPH_C32(0x6932c888), SPH_C32(0x1af30000), + SPH_C32(0xd3770000), SPH_C32(0x6c520000), SPH_C32(0x59c956c0), + SPH_C32(0x5af63713), SPH_C32(0xba7bcdf2), SPH_C32(0x1fbb9302), + SPH_C32(0x9a8cb0b8) }, + { SPH_C32(0xb82f0000), SPH_C32(0xb12c0000), SPH_C32(0x30d80000), + SPH_C32(0x14445000), SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), + SPH_C32(0x2e98bf23), SPH_C32(0x551e3d6e), SPH_C32(0x02f20000), + SPH_C32(0xa2810000), SPH_C32(0x873f0000), SPH_C32(0xe36c7800), + SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), SPH_C32(0xc4c23237), + SPH_C32(0x7f32259e) }, + { SPH_C32(0x48ea0000), SPH_C32(0xe80f0000), SPH_C32(0x755a0000), + SPH_C32(0xf5c950c0), SPH_C32(0xfa356693), SPH_C32(0xf3cabe75), + SPH_C32(0xe578413f), SPH_C32(0x03b98cf1), SPH_C32(0x141f0000), + SPH_C32(0xb7e90000), SPH_C32(0x6ae80000), SPH_C32(0xd1317a20), + SPH_C32(0xfd114266), SPH_C32(0x5d77cd95), SPH_C32(0x27b7ca9f), + SPH_C32(0xfecfdc96) }, + { SPH_C32(0x0c1e0000), SPH_C32(0xc61f0000), SPH_C32(0x81850000), + SPH_C32(0x6b9454e0), SPH_C32(0xb9fa019a), SPH_C32(0xe0312bb1), + SPH_C32(0xfcce6baa), SPH_C32(0x1b7149b0), SPH_C32(0xe1f40000), + SPH_C32(0x1f400000), SPH_C32(0x002c0000), SPH_C32(0x5c9e7860), + SPH_C32(0x30a77ef5), SPH_C32(0x8a881c87), SPH_C32(0xb7079931), + SPH_C32(0x24e430a7) }, + { SPH_C32(0xfcdb0000), SPH_C32(0x9f3c0000), SPH_C32(0xc4070000), + SPH_C32(0x8a195420), SPH_C32(0x829707ab), SPH_C32(0x22dc7d28), + SPH_C32(0x372e95b6), SPH_C32(0x4dd6f82f), SPH_C32(0xf7190000), + SPH_C32(0x0a280000), SPH_C32(0xedfb0000), SPH_C32(0x6ec37a40), + SPH_C32(0xd3ab487c), SPH_C32(0xd0c2fac4), SPH_C32(0x54726199), + SPH_C32(0xa519c9af) }, + { SPH_C32(0x5b290000), SPH_C32(0x0ced0000), SPH_C32(0xb7cb0000), + SPH_C32(0xabb65060), SPH_C32(0xefe26ab8), SPH_C32(0xbc92dfbd), + SPH_C32(0x5d5d1425), SPH_C32(0x0ec82857), SPH_C32(0x55c50000), + SPH_C32(0x68730000), SPH_C32(0xb1710000), SPH_C32(0x234e7c80), + SPH_C32(0x48051fcd), SPH_C32(0x5b9edfda), SPH_C32(0x65514db8), + SPH_C32(0x6a8b4479) }, + { SPH_C32(0xabec0000), SPH_C32(0x55ce0000), SPH_C32(0xf2490000), + SPH_C32(0x4a3b50a0), SPH_C32(0xd48f6c89), SPH_C32(0x7e7f8924), + SPH_C32(0x96bdea39), SPH_C32(0x586f99c8), SPH_C32(0x43280000), + SPH_C32(0x7d1b0000), SPH_C32(0x5ca60000), SPH_C32(0x11137ea0), + SPH_C32(0xab092944), SPH_C32(0x01d43999), SPH_C32(0x8624b510), + SPH_C32(0xeb76bd71) }, + { SPH_C32(0xef180000), SPH_C32(0x7bde0000), SPH_C32(0x06960000), + SPH_C32(0xd4665480), SPH_C32(0x97400b80), SPH_C32(0x6d841ce0), + SPH_C32(0x8f0bc0ac), SPH_C32(0x40a75c89), SPH_C32(0xb6c30000), + SPH_C32(0xd5b20000), SPH_C32(0x36620000), SPH_C32(0x9cbc7ce0), + SPH_C32(0x66bf15d7), SPH_C32(0xd62be88b), SPH_C32(0x1694e6be), + SPH_C32(0x315d5140) }, + { SPH_C32(0x1fdd0000), SPH_C32(0x22fd0000), SPH_C32(0x43140000), + SPH_C32(0x35eb5440), SPH_C32(0xac2d0db1), SPH_C32(0xaf694a79), + SPH_C32(0x44eb3eb0), SPH_C32(0x1600ed16), SPH_C32(0xa02e0000), + SPH_C32(0xc0da0000), SPH_C32(0xdbb50000), SPH_C32(0xaee17ec0), + SPH_C32(0x85b3235e), SPH_C32(0x8c610ec8), SPH_C32(0xf5e11e16), + SPH_C32(0xb0a0a848) } +}; + +static const sph_u32 T512_55[32][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x5fa80000), SPH_C32(0x56030000), SPH_C32(0x43ae0000), + SPH_C32(0x64f30013), SPH_C32(0x257e86bf), SPH_C32(0x1311944e), + SPH_C32(0x541e95bf), SPH_C32(0x8ea4db69), SPH_C32(0x00440000), + SPH_C32(0x7f480000), SPH_C32(0xda7c0000), SPH_C32(0x2a230001), + SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), SPH_C32(0x030a9e60), + SPH_C32(0xbe0a679e) }, + { SPH_C32(0x00440000), SPH_C32(0x7f480000), SPH_C32(0xda7c0000), + SPH_C32(0x2a230001), SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), + SPH_C32(0x030a9e60), SPH_C32(0xbe0a679e), SPH_C32(0x5fec0000), + SPH_C32(0x294b0000), SPH_C32(0x99d20000), SPH_C32(0x4ed00012), + SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), SPH_C32(0x57140bdf), + SPH_C32(0x30aebcf7) }, + { SPH_C32(0x5fec0000), SPH_C32(0x294b0000), SPH_C32(0x99d20000), + SPH_C32(0x4ed00012), SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), + SPH_C32(0x57140bdf), SPH_C32(0x30aebcf7), SPH_C32(0x5fa80000), + SPH_C32(0x56030000), SPH_C32(0x43ae0000), SPH_C32(0x64f30013), + SPH_C32(0x257e86bf), SPH_C32(0x1311944e), SPH_C32(0x541e95bf), + SPH_C32(0x8ea4db69) }, + { SPH_C32(0xee930000), SPH_C32(0xd6070000), SPH_C32(0x92c10000), + SPH_C32(0x2b9801e0), SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), + SPH_C32(0x45312374), SPH_C32(0x201f6a64), SPH_C32(0x7b280000), + SPH_C32(0x57420000), SPH_C32(0xa9e50000), SPH_C32(0x634300a0), + SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), SPH_C32(0x27f83b03), + SPH_C32(0xc7ff60f0) }, + { SPH_C32(0xb13b0000), SPH_C32(0x80040000), SPH_C32(0xd16f0000), + SPH_C32(0x4f6b01f3), SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), + SPH_C32(0x112fb6cb), SPH_C32(0xaebbb10d), SPH_C32(0x7b6c0000), + SPH_C32(0x280a0000), SPH_C32(0x73990000), SPH_C32(0x496000a1), + SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), SPH_C32(0x24f2a563), + SPH_C32(0x79f5076e) }, + { SPH_C32(0xeed70000), SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), + SPH_C32(0x01bb01e1), SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), + SPH_C32(0x463bbd14), SPH_C32(0x9e150dfa), SPH_C32(0x24c40000), + SPH_C32(0x7e090000), SPH_C32(0x30370000), SPH_C32(0x2d9300b2), + SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), SPH_C32(0x70ec30dc), + SPH_C32(0xf751dc07) }, + { SPH_C32(0xb17f0000), SPH_C32(0xff4c0000), SPH_C32(0x0b130000), + SPH_C32(0x654801f2), SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), + SPH_C32(0x122528ab), SPH_C32(0x10b1d693), SPH_C32(0x24800000), + SPH_C32(0x01410000), SPH_C32(0xea4b0000), SPH_C32(0x07b000b3), + SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), SPH_C32(0x73e6aebc), + SPH_C32(0x495bbb99) }, + { SPH_C32(0x7b280000), SPH_C32(0x57420000), SPH_C32(0xa9e50000), + SPH_C32(0x634300a0), SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), + SPH_C32(0x27f83b03), SPH_C32(0xc7ff60f0), SPH_C32(0x95bb0000), + SPH_C32(0x81450000), SPH_C32(0x3b240000), SPH_C32(0x48db0140), + SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), SPH_C32(0x62c91877), + SPH_C32(0xe7e00a94) }, + { SPH_C32(0x24800000), SPH_C32(0x01410000), SPH_C32(0xea4b0000), + SPH_C32(0x07b000b3), SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), + SPH_C32(0x73e6aebc), SPH_C32(0x495bbb99), SPH_C32(0x95ff0000), + SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), SPH_C32(0x62f80141), + SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), SPH_C32(0x61c38617), + SPH_C32(0x59ea6d0a) }, + { SPH_C32(0x7b6c0000), SPH_C32(0x280a0000), SPH_C32(0x73990000), + SPH_C32(0x496000a1), SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), + SPH_C32(0x24f2a563), SPH_C32(0x79f5076e), SPH_C32(0xca570000), + SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), SPH_C32(0x060b0152), + SPH_C32(0x14592320), SPH_C32(0xec526625), SPH_C32(0x35dd13a8), + SPH_C32(0xd74eb663) }, + { SPH_C32(0x24c40000), SPH_C32(0x7e090000), SPH_C32(0x30370000), + SPH_C32(0x2d9300b2), SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), + SPH_C32(0x70ec30dc), SPH_C32(0xf751dc07), SPH_C32(0xca130000), + SPH_C32(0xd7460000), SPH_C32(0x788a0000), SPH_C32(0x2c280153), + SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), SPH_C32(0x36d78dc8), + SPH_C32(0x6944d1fd) }, + { SPH_C32(0x95bb0000), SPH_C32(0x81450000), SPH_C32(0x3b240000), + SPH_C32(0x48db0140), SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), + SPH_C32(0x62c91877), SPH_C32(0xe7e00a94), SPH_C32(0xee930000), + SPH_C32(0xd6070000), SPH_C32(0x92c10000), SPH_C32(0x2b9801e0), + SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), SPH_C32(0x45312374), + SPH_C32(0x201f6a64) }, + { SPH_C32(0xca130000), SPH_C32(0xd7460000), SPH_C32(0x788a0000), + SPH_C32(0x2c280153), SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), + SPH_C32(0x36d78dc8), SPH_C32(0x6944d1fd), SPH_C32(0xeed70000), + SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), SPH_C32(0x01bb01e1), + SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), SPH_C32(0x463bbd14), + SPH_C32(0x9e150dfa) }, + { SPH_C32(0x95ff0000), SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), + SPH_C32(0x62f80141), SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), + SPH_C32(0x61c38617), SPH_C32(0x59ea6d0a), SPH_C32(0xb17f0000), + SPH_C32(0xff4c0000), SPH_C32(0x0b130000), SPH_C32(0x654801f2), + SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), SPH_C32(0x122528ab), + SPH_C32(0x10b1d693) }, + { SPH_C32(0xca570000), SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), + SPH_C32(0x060b0152), SPH_C32(0x14592320), SPH_C32(0xec526625), + SPH_C32(0x35dd13a8), SPH_C32(0xd74eb663), SPH_C32(0xb13b0000), + SPH_C32(0x80040000), SPH_C32(0xd16f0000), SPH_C32(0x4f6b01f3), + SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), SPH_C32(0x112fb6cb), + SPH_C32(0xaebbb10d) }, + { SPH_C32(0xe6280000), SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), + SPH_C32(0xd3d002e0), SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), + SPH_C32(0x289506b4), SPH_C32(0xd75a4897), SPH_C32(0xf0c50000), + SPH_C32(0x59230000), SPH_C32(0x45820000), SPH_C32(0xe18d00c0), + SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), SPH_C32(0xcbe0fe1c), + SPH_C32(0x56a7b19f) }, + { SPH_C32(0xb9800000), SPH_C32(0x1a480000), SPH_C32(0xebfb0000), + SPH_C32(0xb72302f3), SPH_C32(0xfd1fb607), SPH_C32(0x8bb62494), + SPH_C32(0x7c8b930b), SPH_C32(0x59fe93fe), SPH_C32(0xf0810000), + SPH_C32(0x266b0000), SPH_C32(0x9ffe0000), SPH_C32(0xcbae00c1), + SPH_C32(0x00c0cffd), SPH_C32(0x6b5bca1e), SPH_C32(0xc8ea607c), + SPH_C32(0xe8add601) }, + { SPH_C32(0xe66c0000), SPH_C32(0x33030000), SPH_C32(0x72290000), + SPH_C32(0xf9f302e1), SPH_C32(0xe3ccf974), SPH_C32(0x31112c5d), + SPH_C32(0x2b9f98d4), SPH_C32(0x69502f09), SPH_C32(0xaf290000), + SPH_C32(0x70680000), SPH_C32(0xdc500000), SPH_C32(0xaf5d00d2), + SPH_C32(0x25be4942), SPH_C32(0x784a5e50), SPH_C32(0x9cf4f5c3), + SPH_C32(0x66090d68) }, + { SPH_C32(0xb9c40000), SPH_C32(0x65000000), SPH_C32(0x31870000), + SPH_C32(0x9d0002f2), SPH_C32(0xc6b27fcb), SPH_C32(0x2200b813), + SPH_C32(0x7f810d6b), SPH_C32(0xe7f4f460), SPH_C32(0xaf6d0000), + SPH_C32(0x0f200000), SPH_C32(0x062c0000), SPH_C32(0x857e00d3), + SPH_C32(0x1e13808e), SPH_C32(0xd1fcc2d7), SPH_C32(0x9ffe6ba3), + SPH_C32(0xd8036af6) }, + { SPH_C32(0x08bb0000), SPH_C32(0x9a4c0000), SPH_C32(0x3a940000), + SPH_C32(0xf8480300), SPH_C32(0x4c3018c4), SPH_C32(0xa3cb4b8d), + SPH_C32(0x6da425c0), SPH_C32(0xf74522f3), SPH_C32(0x8bed0000), + SPH_C32(0x0e610000), SPH_C32(0xec670000), SPH_C32(0x82ce0060), + SPH_C32(0xa5b6421e), SPH_C32(0xaf74c322), SPH_C32(0xec18c51f), + SPH_C32(0x9158d16f) }, + { SPH_C32(0x57130000), SPH_C32(0xcc4f0000), SPH_C32(0x793a0000), + SPH_C32(0x9cbb0313), SPH_C32(0x694e9e7b), SPH_C32(0xb0dadfc3), + SPH_C32(0x39bab07f), SPH_C32(0x79e1f99a), SPH_C32(0x8ba90000), + SPH_C32(0x71290000), SPH_C32(0x361b0000), SPH_C32(0xa8ed0061), + SPH_C32(0x9e1b8bd2), SPH_C32(0x06c25fa5), SPH_C32(0xef125b7f), + SPH_C32(0x2f52b6f1) }, + { SPH_C32(0x08ff0000), SPH_C32(0xe5040000), SPH_C32(0xe0e80000), + SPH_C32(0xd26b0301), SPH_C32(0x779dd108), SPH_C32(0x0a7dd70a), + SPH_C32(0x6eaebba0), SPH_C32(0x494f456d), SPH_C32(0xd4010000), + SPH_C32(0x272a0000), SPH_C32(0x75b50000), SPH_C32(0xcc1e0072), + SPH_C32(0xbb650d6d), SPH_C32(0x15d3cbeb), SPH_C32(0xbb0ccec0), + SPH_C32(0xa1f66d98) }, + { SPH_C32(0x57570000), SPH_C32(0xb3070000), SPH_C32(0xa3460000), + SPH_C32(0xb6980312), SPH_C32(0x52e357b7), SPH_C32(0x196c4344), + SPH_C32(0x3ab02e1f), SPH_C32(0xc7eb9e04), SPH_C32(0xd4450000), + SPH_C32(0x58620000), SPH_C32(0xafc90000), SPH_C32(0xe63d0073), + SPH_C32(0x80c8c4a1), SPH_C32(0xbc65576c), SPH_C32(0xb80650a0), + SPH_C32(0x1ffc0a06) }, + { SPH_C32(0x9d000000), SPH_C32(0x1b090000), SPH_C32(0x01b00000), + SPH_C32(0xb0930240), SPH_C32(0x46ba7497), SPH_C32(0xf53e2561), + SPH_C32(0x0f6d3db7), SPH_C32(0x10a52867), SPH_C32(0x657e0000), + SPH_C32(0xd8660000), SPH_C32(0x7ea60000), SPH_C32(0xa9560180), + SPH_C32(0x31e76a62), SPH_C32(0x94183875), SPH_C32(0xa929e66b), + SPH_C32(0xb147bb0b) }, + { SPH_C32(0xc2a80000), SPH_C32(0x4d0a0000), SPH_C32(0x421e0000), + SPH_C32(0xd4600253), SPH_C32(0x63c4f228), SPH_C32(0xe62fb12f), + SPH_C32(0x5b73a808), SPH_C32(0x9e01f30e), SPH_C32(0x653a0000), + SPH_C32(0xa72e0000), SPH_C32(0xa4da0000), SPH_C32(0x83750181), + SPH_C32(0x0a4aa3ae), SPH_C32(0x3daea4f2), SPH_C32(0xaa23780b), + SPH_C32(0x0f4ddc95) }, + { SPH_C32(0x9d440000), SPH_C32(0x64410000), SPH_C32(0xdbcc0000), + SPH_C32(0x9ab00241), SPH_C32(0x7d17bd5b), SPH_C32(0x5c88b9e6), + SPH_C32(0x0c67a3d7), SPH_C32(0xaeaf4ff9), SPH_C32(0x3a920000), + SPH_C32(0xf12d0000), SPH_C32(0xe7740000), SPH_C32(0xe7860192), + SPH_C32(0x2f342511), SPH_C32(0x2ebf30bc), SPH_C32(0xfe3dedb4), + SPH_C32(0x81e907fc) }, + { SPH_C32(0xc2ec0000), SPH_C32(0x32420000), SPH_C32(0x98620000), + SPH_C32(0xfe430252), SPH_C32(0x58693be4), SPH_C32(0x4f992da8), + SPH_C32(0x58793668), SPH_C32(0x200b9490), SPH_C32(0x3ad60000), + SPH_C32(0x8e650000), SPH_C32(0x3d080000), SPH_C32(0xcda50193), + SPH_C32(0x1499ecdd), SPH_C32(0x8709ac3b), SPH_C32(0xfd3773d4), + SPH_C32(0x3fe36062) }, + { SPH_C32(0x73930000), SPH_C32(0xcd0e0000), SPH_C32(0x93710000), + SPH_C32(0x9b0b03a0), SPH_C32(0xd2eb5ceb), SPH_C32(0xce52de36), + SPH_C32(0x4a5c1ec3), SPH_C32(0x30ba4203), SPH_C32(0x1e560000), + SPH_C32(0x8f240000), SPH_C32(0xd7430000), SPH_C32(0xca150120), + SPH_C32(0xaf3c2e4d), SPH_C32(0xf981adce), SPH_C32(0x8ed1dd68), + SPH_C32(0x76b8dbfb) }, + { SPH_C32(0x2c3b0000), SPH_C32(0x9b0d0000), SPH_C32(0xd0df0000), + SPH_C32(0xfff803b3), SPH_C32(0xf795da54), SPH_C32(0xdd434a78), + SPH_C32(0x1e428b7c), SPH_C32(0xbe1e996a), SPH_C32(0x1e120000), + SPH_C32(0xf06c0000), SPH_C32(0x0d3f0000), SPH_C32(0xe0360121), + SPH_C32(0x9491e781), SPH_C32(0x50373149), SPH_C32(0x8ddb4308), + SPH_C32(0xc8b2bc65) }, + { SPH_C32(0x73d70000), SPH_C32(0xb2460000), SPH_C32(0x490d0000), + SPH_C32(0xb12803a1), SPH_C32(0xe9469527), SPH_C32(0x67e442b1), + SPH_C32(0x495680a3), SPH_C32(0x8eb0259d), SPH_C32(0x41ba0000), + SPH_C32(0xa66f0000), SPH_C32(0x4e910000), SPH_C32(0x84c50132), + SPH_C32(0xb1ef613e), SPH_C32(0x4326a507), SPH_C32(0xd9c5d6b7), + SPH_C32(0x4616670c) }, + { SPH_C32(0x2c7f0000), SPH_C32(0xe4450000), SPH_C32(0x0aa30000), + SPH_C32(0xd5db03b2), SPH_C32(0xcc381398), SPH_C32(0x74f5d6ff), + SPH_C32(0x1d48151c), SPH_C32(0x0014fef4), SPH_C32(0x41fe0000), + SPH_C32(0xd9270000), SPH_C32(0x94ed0000), SPH_C32(0xaee60133), + SPH_C32(0x8a42a8f2), SPH_C32(0xea903980), SPH_C32(0xdacf48d7), + SPH_C32(0xf81c0092) } +}; + +static const sph_u32 T512_60[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x033d0000), SPH_C32(0x08b30000), SPH_C32(0xf33a0000), + SPH_C32(0x3ac20007), SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), + SPH_C32(0x0ea5cfe3), SPH_C32(0xe6da7ffe), SPH_C32(0xa8da0000), + SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), SPH_C32(0x07da0002), + SPH_C32(0x7d669583), SPH_C32(0x1f98708a), SPH_C32(0xbb668808), + SPH_C32(0xda878000) }, + { SPH_C32(0xa8da0000), SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), + SPH_C32(0x07da0002), SPH_C32(0x7d669583), SPH_C32(0x1f98708a), + SPH_C32(0xbb668808), SPH_C32(0xda878000), SPH_C32(0xabe70000), + SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), SPH_C32(0x3d180005), + SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), SPH_C32(0xb5c347eb), + SPH_C32(0x3c5dfffe) }, + { SPH_C32(0xabe70000), SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), + SPH_C32(0x3d180005), SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), + SPH_C32(0xb5c347eb), SPH_C32(0x3c5dfffe), SPH_C32(0x033d0000), + SPH_C32(0x08b30000), SPH_C32(0xf33a0000), SPH_C32(0x3ac20007), + SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), SPH_C32(0x0ea5cfe3), + SPH_C32(0xe6da7ffe) }, + { SPH_C32(0x01930000), SPH_C32(0xe7820000), SPH_C32(0xedfb0000), + SPH_C32(0xcf0c000b), SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), + SPH_C32(0x063661e1), SPH_C32(0x536f9e7b), SPH_C32(0x92280000), + SPH_C32(0xdc850000), SPH_C32(0x57fa0000), SPH_C32(0x56dc0003), + SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), SPH_C32(0x90cef752), + SPH_C32(0x7b1675d7) }, + { SPH_C32(0x02ae0000), SPH_C32(0xef310000), SPH_C32(0x1ec10000), + SPH_C32(0xf5ce000c), SPH_C32(0xdcf90708), SPH_C32(0xd7cdd231), + SPH_C32(0x0893ae02), SPH_C32(0xb5b5e185), SPH_C32(0x3af20000), + SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), SPH_C32(0x51060001), + SPH_C32(0xc78fb695), SPH_C32(0x4577d386), SPH_C32(0x2ba87f5a), + SPH_C32(0xa191f5d7) }, + { SPH_C32(0xa9490000), SPH_C32(0x713c0000), SPH_C32(0xb1e60000), + SPH_C32(0xc8d60009), SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), + SPH_C32(0xbd50e9e9), SPH_C32(0x89e81e7b), SPH_C32(0x39cf0000), + SPH_C32(0x42880000), SPH_C32(0xf8dd0000), SPH_C32(0x6bc40006), + SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), SPH_C32(0x250db0b9), + SPH_C32(0x474b8a29) }, + { SPH_C32(0xaa740000), SPH_C32(0x798f0000), SPH_C32(0x42dc0000), + SPH_C32(0xf214000e), SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), + SPH_C32(0xb3f5260a), SPH_C32(0x6f326185), SPH_C32(0x91150000), + SPH_C32(0xd4360000), SPH_C32(0xa4c00000), SPH_C32(0x6c1e0004), + SPH_C32(0xebc0a946), SPH_C32(0x3181c513), SPH_C32(0x9e6b38b1), + SPH_C32(0x9dcc0a29) }, + { SPH_C32(0x92280000), SPH_C32(0xdc850000), SPH_C32(0x57fa0000), + SPH_C32(0x56dc0003), SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), + SPH_C32(0x90cef752), SPH_C32(0x7b1675d7), SPH_C32(0x93bb0000), + SPH_C32(0x3b070000), SPH_C32(0xba010000), SPH_C32(0x99d00008), + SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), SPH_C32(0x96f896b3), + SPH_C32(0x2879ebac) }, + { SPH_C32(0x91150000), SPH_C32(0xd4360000), SPH_C32(0xa4c00000), + SPH_C32(0x6c1e0004), SPH_C32(0xebc0a946), SPH_C32(0x3181c513), + SPH_C32(0x9e6b38b1), SPH_C32(0x9dcc0a29), SPH_C32(0x3b610000), + SPH_C32(0xadb90000), SPH_C32(0xe61c0000), SPH_C32(0x9e0a000a), + SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), SPH_C32(0x2d9e1ebb), + SPH_C32(0xf2fe6bac) }, + { SPH_C32(0x3af20000), SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), + SPH_C32(0x51060001), SPH_C32(0xc78fb695), SPH_C32(0x4577d386), + SPH_C32(0x2ba87f5a), SPH_C32(0xa191f5d7), SPH_C32(0x385c0000), + SPH_C32(0xa50a0000), SPH_C32(0x15260000), SPH_C32(0xa4c8000d), + SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), SPH_C32(0x233bd158), + SPH_C32(0x14241452) }, + { SPH_C32(0x39cf0000), SPH_C32(0x42880000), SPH_C32(0xf8dd0000), + SPH_C32(0x6bc40006), SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), + SPH_C32(0x250db0b9), SPH_C32(0x474b8a29), SPH_C32(0x90860000), + SPH_C32(0x33b40000), SPH_C32(0x493b0000), SPH_C32(0xa312000f), + SPH_C32(0x6610241e), SPH_C32(0x8d22713d), SPH_C32(0x985d5950), + SPH_C32(0xcea39452) }, + { SPH_C32(0x93bb0000), SPH_C32(0x3b070000), SPH_C32(0xba010000), + SPH_C32(0x99d00008), SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), + SPH_C32(0x96f896b3), SPH_C32(0x2879ebac), SPH_C32(0x01930000), + SPH_C32(0xe7820000), SPH_C32(0xedfb0000), SPH_C32(0xcf0c000b), + SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), SPH_C32(0x063661e1), + SPH_C32(0x536f9e7b) }, + { SPH_C32(0x90860000), SPH_C32(0x33b40000), SPH_C32(0x493b0000), + SPH_C32(0xa312000f), SPH_C32(0x6610241e), SPH_C32(0x8d22713d), + SPH_C32(0x985d5950), SPH_C32(0xcea39452), SPH_C32(0xa9490000), + SPH_C32(0x713c0000), SPH_C32(0xb1e60000), SPH_C32(0xc8d60009), + SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), SPH_C32(0xbd50e9e9), + SPH_C32(0x89e81e7b) }, + { SPH_C32(0x3b610000), SPH_C32(0xadb90000), SPH_C32(0xe61c0000), + SPH_C32(0x9e0a000a), SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), + SPH_C32(0x2d9e1ebb), SPH_C32(0xf2fe6bac), SPH_C32(0xaa740000), + SPH_C32(0x798f0000), SPH_C32(0x42dc0000), SPH_C32(0xf214000e), + SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), SPH_C32(0xb3f5260a), + SPH_C32(0x6f326185) }, + { SPH_C32(0x385c0000), SPH_C32(0xa50a0000), SPH_C32(0x15260000), + SPH_C32(0xa4c8000d), SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), + SPH_C32(0x233bd158), SPH_C32(0x14241452), SPH_C32(0x02ae0000), + SPH_C32(0xef310000), SPH_C32(0x1ec10000), SPH_C32(0xf5ce000c), + SPH_C32(0xdcf90708), SPH_C32(0xd7cdd231), SPH_C32(0x0893ae02), + SPH_C32(0xb5b5e185) } +}; + +#define INPUT_BIG do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T512_0[acc >> 3][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + m8 = rp[8]; \ + m9 = rp[9]; \ + mA = rp[10]; \ + mB = rp[11]; \ + mC = rp[12]; \ + mD = rp[13]; \ + mE = rp[14]; \ + mF = rp[15]; \ + acc = (acc << 8) | buf[1]; \ + rp = &T512_5[(acc >> 6) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_10[(acc >> 1) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[2]; \ + rp = &T512_15[(acc >> 4) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[3]; \ + rp = &T512_20[(acc >> 7) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_25[(acc >> 2) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[4]; \ + rp = &T512_30[(acc >> 5) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_35[acc & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[5]; \ + rp = &T512_40[acc >> 3][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[6]; \ + rp = &T512_45[(acc >> 6) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_50[(acc >> 1) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[7]; \ + rp = &T512_55[(acc >> 4) & 0x1f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_60[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_BIG == 6 + +static const sph_u32 T512_0[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x145a3c00), SPH_C32(0xb9e90000), SPH_C32(0x61270000), + SPH_C32(0xf1610000), SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), + SPH_C32(0x47a96720), SPH_C32(0xe18e24c5), SPH_C32(0x23671400), + SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), SPH_C32(0xfb750000), + SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), SPH_C32(0x02c40a3f), + SPH_C32(0xdc24e61f) }, + { SPH_C32(0x23671400), SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), + SPH_C32(0xfb750000), SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), + SPH_C32(0x02c40a3f), SPH_C32(0xdc24e61f), SPH_C32(0x373d2800), + SPH_C32(0x71500000), SPH_C32(0x95e00000), SPH_C32(0x0a140000), + SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), SPH_C32(0x456d6d1f), + SPH_C32(0x3daac2da) }, + { SPH_C32(0x373d2800), SPH_C32(0x71500000), SPH_C32(0x95e00000), + SPH_C32(0x0a140000), SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), + SPH_C32(0x456d6d1f), SPH_C32(0x3daac2da), SPH_C32(0x145a3c00), + SPH_C32(0xb9e90000), SPH_C32(0x61270000), SPH_C32(0xf1610000), + SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), SPH_C32(0x47a96720), + SPH_C32(0xe18e24c5) }, + { SPH_C32(0x54285c00), SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), + SPH_C32(0xa1c50000), SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), + SPH_C32(0x6bb0419d), SPH_C32(0x551b3782), SPH_C32(0x9cbb1800), + SPH_C32(0xb0d30000), SPH_C32(0x92510000), SPH_C32(0xed930000), + SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), SPH_C32(0x430633da), + SPH_C32(0x78cace29) }, + { SPH_C32(0x40726000), SPH_C32(0x53040000), SPH_C32(0xa4f10000), + SPH_C32(0x50a40000), SPH_C32(0x7dc35a1c), SPH_C32(0x24ecf999), + SPH_C32(0x2c1926bd), SPH_C32(0xb4951347), SPH_C32(0xbfdc0c00), + SPH_C32(0x786a0000), SPH_C32(0x66960000), SPH_C32(0x16e60000), + SPH_C32(0x2af76720), SPH_C32(0x19b270bd), SPH_C32(0x41c239e5), + SPH_C32(0xa4ee2836) }, + { SPH_C32(0x774f4800), SPH_C32(0x22540000), SPH_C32(0x31110000), + SPH_C32(0x5ab00000), SPH_C32(0xc06f4315), SPH_C32(0x6c0361a8), + SPH_C32(0x69744ba2), SPH_C32(0x893fd19d), SPH_C32(0xab863000), + SPH_C32(0xc1830000), SPH_C32(0x07b10000), SPH_C32(0xe7870000), + SPH_C32(0xe4965a4c), SPH_C32(0xa9fb4dc5), SPH_C32(0x066b5ec5), + SPH_C32(0x45600cf3) }, + { SPH_C32(0x63157400), SPH_C32(0x9bbd0000), SPH_C32(0x50360000), + SPH_C32(0xabd10000), SPH_C32(0x0e0e7e79), SPH_C32(0xdc4a5cd0), + SPH_C32(0x2edd2c82), SPH_C32(0x68b1f558), SPH_C32(0x88e12400), + SPH_C32(0x093a0000), SPH_C32(0xf3760000), SPH_C32(0x1cf20000), + SPH_C32(0x975b7e29), SPH_C32(0x515de88c), SPH_C32(0x04af54fa), + SPH_C32(0x9944eaec) }, + { SPH_C32(0x9cbb1800), SPH_C32(0xb0d30000), SPH_C32(0x92510000), + SPH_C32(0xed930000), SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), + SPH_C32(0x430633da), SPH_C32(0x78cace29), SPH_C32(0xc8934400), + SPH_C32(0x5a3e0000), SPH_C32(0x57870000), SPH_C32(0x4c560000), + SPH_C32(0xea982435), SPH_C32(0x75b11115), SPH_C32(0x28b67247), + SPH_C32(0x2dd1f9ab) }, + { SPH_C32(0x88e12400), SPH_C32(0x093a0000), SPH_C32(0xf3760000), + SPH_C32(0x1cf20000), SPH_C32(0x975b7e29), SPH_C32(0x515de88c), + SPH_C32(0x04af54fa), SPH_C32(0x9944eaec), SPH_C32(0xebf45000), + SPH_C32(0x92870000), SPH_C32(0xa3400000), SPH_C32(0xb7230000), + SPH_C32(0x99550050), SPH_C32(0x8d17b45c), SPH_C32(0x2a727878), + SPH_C32(0xf1f51fb4) }, + { SPH_C32(0xbfdc0c00), SPH_C32(0x786a0000), SPH_C32(0x66960000), + SPH_C32(0x16e60000), SPH_C32(0x2af76720), SPH_C32(0x19b270bd), + SPH_C32(0x41c239e5), SPH_C32(0xa4ee2836), SPH_C32(0xffae6c00), + SPH_C32(0x2b6e0000), SPH_C32(0xc2670000), SPH_C32(0x46420000), + SPH_C32(0x57343d3c), SPH_C32(0x3d5e8924), SPH_C32(0x6ddb1f58), + SPH_C32(0x107b3b71) }, + { SPH_C32(0xab863000), SPH_C32(0xc1830000), SPH_C32(0x07b10000), + SPH_C32(0xe7870000), SPH_C32(0xe4965a4c), SPH_C32(0xa9fb4dc5), + SPH_C32(0x066b5ec5), SPH_C32(0x45600cf3), SPH_C32(0xdcc97800), + SPH_C32(0xe3d70000), SPH_C32(0x36a00000), SPH_C32(0xbd370000), + SPH_C32(0x24f91959), SPH_C32(0xc5f82c6d), SPH_C32(0x6f1f1567), + SPH_C32(0xcc5fdd6e) }, + { SPH_C32(0xc8934400), SPH_C32(0x5a3e0000), SPH_C32(0x57870000), + SPH_C32(0x4c560000), SPH_C32(0xea982435), SPH_C32(0x75b11115), + SPH_C32(0x28b67247), SPH_C32(0x2dd1f9ab), SPH_C32(0x54285c00), + SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), SPH_C32(0xa1c50000), + SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), SPH_C32(0x6bb0419d), + SPH_C32(0x551b3782) }, + { SPH_C32(0xdcc97800), SPH_C32(0xe3d70000), SPH_C32(0x36a00000), + SPH_C32(0xbd370000), SPH_C32(0x24f91959), SPH_C32(0xc5f82c6d), + SPH_C32(0x6f1f1567), SPH_C32(0xcc5fdd6e), SPH_C32(0x774f4800), + SPH_C32(0x22540000), SPH_C32(0x31110000), SPH_C32(0x5ab00000), + SPH_C32(0xc06f4315), SPH_C32(0x6c0361a8), SPH_C32(0x69744ba2), + SPH_C32(0x893fd19d) }, + { SPH_C32(0xebf45000), SPH_C32(0x92870000), SPH_C32(0xa3400000), + SPH_C32(0xb7230000), SPH_C32(0x99550050), SPH_C32(0x8d17b45c), + SPH_C32(0x2a727878), SPH_C32(0xf1f51fb4), SPH_C32(0x63157400), + SPH_C32(0x9bbd0000), SPH_C32(0x50360000), SPH_C32(0xabd10000), + SPH_C32(0x0e0e7e79), SPH_C32(0xdc4a5cd0), SPH_C32(0x2edd2c82), + SPH_C32(0x68b1f558) }, + { SPH_C32(0xffae6c00), SPH_C32(0x2b6e0000), SPH_C32(0xc2670000), + SPH_C32(0x46420000), SPH_C32(0x57343d3c), SPH_C32(0x3d5e8924), + SPH_C32(0x6ddb1f58), SPH_C32(0x107b3b71), SPH_C32(0x40726000), + SPH_C32(0x53040000), SPH_C32(0xa4f10000), SPH_C32(0x50a40000), + SPH_C32(0x7dc35a1c), SPH_C32(0x24ecf999), SPH_C32(0x2c1926bd), + SPH_C32(0xb4951347) }, + { SPH_C32(0x29449c00), SPH_C32(0x64e70000), SPH_C32(0xf24b0000), + SPH_C32(0xc2f30000), SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), + SPH_C32(0xf3e04259), SPH_C32(0x8d0d9ec4), SPH_C32(0x466d0c00), + SPH_C32(0x08620000), SPH_C32(0xdd5d0000), SPH_C32(0xbadd0000), + SPH_C32(0x6a927942), SPH_C32(0x441f2b93), SPH_C32(0x218ace6f), + SPH_C32(0xbf2c0be2) }, + { SPH_C32(0x3d1ea000), SPH_C32(0xdd0e0000), SPH_C32(0x936c0000), + SPH_C32(0x33920000), SPH_C32(0xc0bf73e3), SPH_C32(0xe68b0a3d), + SPH_C32(0xb4492579), SPH_C32(0x6c83ba01), SPH_C32(0x650a1800), + SPH_C32(0xc0db0000), SPH_C32(0x299a0000), SPH_C32(0x41a80000), + SPH_C32(0x195f5d27), SPH_C32(0xbcb98eda), SPH_C32(0x234ec450), + SPH_C32(0x6308edfd) }, + { SPH_C32(0x0a238800), SPH_C32(0xac5e0000), SPH_C32(0x068c0000), + SPH_C32(0x39860000), SPH_C32(0x7d136aea), SPH_C32(0xae64920c), + SPH_C32(0xf1244866), SPH_C32(0x512978db), SPH_C32(0x71502400), + SPH_C32(0x79320000), SPH_C32(0x48bd0000), SPH_C32(0xb0c90000), + SPH_C32(0xd73e604b), SPH_C32(0x0cf0b3a2), SPH_C32(0x64e7a370), + SPH_C32(0x8286c938) }, + { SPH_C32(0x1e79b400), SPH_C32(0x15b70000), SPH_C32(0x67ab0000), + SPH_C32(0xc8e70000), SPH_C32(0xb3725786), SPH_C32(0x1e2daf74), + SPH_C32(0xb68d2f46), SPH_C32(0xb0a75c1e), SPH_C32(0x52373000), + SPH_C32(0xb18b0000), SPH_C32(0xbc7a0000), SPH_C32(0x4bbc0000), + SPH_C32(0xa4f3442e), SPH_C32(0xf45616eb), SPH_C32(0x6623a94f), + SPH_C32(0x5ea22f27) }, + { SPH_C32(0x7d6cc000), SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), + SPH_C32(0x63360000), SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), + SPH_C32(0x985003c4), SPH_C32(0xd816a946), SPH_C32(0xdad61400), + SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), SPH_C32(0x574e0000), + SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), SPH_C32(0x628cfdb5), + SPH_C32(0xc7e6c5cb) }, + { SPH_C32(0x6936fc00), SPH_C32(0x37e30000), SPH_C32(0x56ba0000), + SPH_C32(0x92570000), SPH_C32(0x731d1493), SPH_C32(0x722ecedc), + SPH_C32(0xdff964e4), SPH_C32(0x39988d83), SPH_C32(0xf9b10000), + SPH_C32(0x70080000), SPH_C32(0xbbcb0000), SPH_C32(0xac3b0000), + SPH_C32(0x40651e62), SPH_C32(0x5dad5b2e), SPH_C32(0x6048f78a), + SPH_C32(0x1bc223d4) }, + { SPH_C32(0x5e0bd400), SPH_C32(0x46b30000), SPH_C32(0xc35a0000), + SPH_C32(0x98430000), SPH_C32(0xceb10d9a), SPH_C32(0x3ac156ed), + SPH_C32(0x9a9409fb), SPH_C32(0x04324f59), SPH_C32(0xedeb3c00), + SPH_C32(0xc9e10000), SPH_C32(0xdaec0000), SPH_C32(0x5d5a0000), + SPH_C32(0x8e04230e), SPH_C32(0xede46656), SPH_C32(0x27e190aa), + SPH_C32(0xfa4c0711) }, + { SPH_C32(0x4a51e800), SPH_C32(0xff5a0000), SPH_C32(0xa27d0000), + SPH_C32(0x69220000), SPH_C32(0x00d030f6), SPH_C32(0x8a886b95), + SPH_C32(0xdd3d6edb), SPH_C32(0xe5bc6b9c), SPH_C32(0xce8c2800), + SPH_C32(0x01580000), SPH_C32(0x2e2b0000), SPH_C32(0xa62f0000), + SPH_C32(0xfdc9076b), SPH_C32(0x1542c31f), SPH_C32(0x25259a95), + SPH_C32(0x2668e10e) }, + { SPH_C32(0xb5ff8400), SPH_C32(0xd4340000), SPH_C32(0x601a0000), + SPH_C32(0x2f600000), SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), + SPH_C32(0xb0e67183), SPH_C32(0xf5c750ed), SPH_C32(0x8efe4800), + SPH_C32(0x525c0000), SPH_C32(0x8ada0000), SPH_C32(0xf68b0000), + SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), SPH_C32(0x093cbc28), + SPH_C32(0x92fdf249) }, + { SPH_C32(0xa1a5b800), SPH_C32(0x6ddd0000), SPH_C32(0x013d0000), + SPH_C32(0xde010000), SPH_C32(0x998530a6), SPH_C32(0x079fdfc9), + SPH_C32(0xf74f16a3), SPH_C32(0x14497428), SPH_C32(0xad995c00), + SPH_C32(0x9ae50000), SPH_C32(0x7e1d0000), SPH_C32(0x0dfe0000), + SPH_C32(0xf3c77912), SPH_C32(0xc9089fcf), SPH_C32(0x0bf8b617), + SPH_C32(0x4ed91456) }, + { SPH_C32(0x96989000), SPH_C32(0x1c8d0000), SPH_C32(0x94dd0000), + SPH_C32(0xd4150000), SPH_C32(0x242929af), SPH_C32(0x4f7047f8), + SPH_C32(0xb2227bbc), SPH_C32(0x29e3b6f2), SPH_C32(0xb9c36000), + SPH_C32(0x230c0000), SPH_C32(0x1f3a0000), SPH_C32(0xfc9f0000), + SPH_C32(0x3da6447e), SPH_C32(0x7941a2b7), SPH_C32(0x4c51d137), + SPH_C32(0xaf573093) }, + { SPH_C32(0x82c2ac00), SPH_C32(0xa5640000), SPH_C32(0xf5fa0000), + SPH_C32(0x25740000), SPH_C32(0xea4814c3), SPH_C32(0xff397a80), + SPH_C32(0xf58b1c9c), SPH_C32(0xc86d9237), SPH_C32(0x9aa47400), + SPH_C32(0xebb50000), SPH_C32(0xebfd0000), SPH_C32(0x07ea0000), + SPH_C32(0x4e6b601b), SPH_C32(0x81e707fe), SPH_C32(0x4e95db08), + SPH_C32(0x7373d68c) }, + { SPH_C32(0xe1d7d800), SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), + SPH_C32(0x8ea50000), SPH_C32(0xe4466aba), SPH_C32(0x23732650), + SPH_C32(0xdb56301e), SPH_C32(0xa0dc676f), SPH_C32(0x12455000), + SPH_C32(0xe28f0000), SPH_C32(0x188b0000), SPH_C32(0x1b180000), + SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), SPH_C32(0x4a3a8ff2), + SPH_C32(0xea373c60) }, + { SPH_C32(0xf58de400), SPH_C32(0x87300000), SPH_C32(0xc4eb0000), + SPH_C32(0x7fc40000), SPH_C32(0x2a2757d6), SPH_C32(0x933a1b28), + SPH_C32(0x9cff573e), SPH_C32(0x415243aa), SPH_C32(0x31224400), + SPH_C32(0x2a360000), SPH_C32(0xec4c0000), SPH_C32(0xe06d0000), + SPH_C32(0xaafd3a57), SPH_C32(0x281c4a3b), SPH_C32(0x48fe85cd), + SPH_C32(0x3613da7f) }, + { SPH_C32(0xc2b0cc00), SPH_C32(0xf6600000), SPH_C32(0x510b0000), + SPH_C32(0x75d00000), SPH_C32(0x978b4edf), SPH_C32(0xdbd58319), + SPH_C32(0xd9923a21), SPH_C32(0x7cf88170), SPH_C32(0x25787800), + SPH_C32(0x93df0000), SPH_C32(0x8d6b0000), SPH_C32(0x110c0000), + SPH_C32(0x649c073b), SPH_C32(0x98557743), SPH_C32(0x0f57e2ed), + SPH_C32(0xd79dfeba) }, + { SPH_C32(0xd6eaf000), SPH_C32(0x4f890000), SPH_C32(0x302c0000), + SPH_C32(0x84b10000), SPH_C32(0x59ea73b3), SPH_C32(0x6b9cbe61), + SPH_C32(0x9e3b5d01), SPH_C32(0x9d76a5b5), SPH_C32(0x061f6c00), + SPH_C32(0x5b660000), SPH_C32(0x79ac0000), SPH_C32(0xea790000), + SPH_C32(0x1751235e), SPH_C32(0x60f3d20a), SPH_C32(0x0d93e8d2), + SPH_C32(0x0bb918a5) }, + { SPH_C32(0x466d0c00), SPH_C32(0x08620000), SPH_C32(0xdd5d0000), + SPH_C32(0xbadd0000), SPH_C32(0x6a927942), SPH_C32(0x441f2b93), + SPH_C32(0x218ace6f), SPH_C32(0xbf2c0be2), SPH_C32(0x6f299000), + SPH_C32(0x6c850000), SPH_C32(0x2f160000), SPH_C32(0x782e0000), + SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), SPH_C32(0xd26a8c36), + SPH_C32(0x32219526) }, + { SPH_C32(0x52373000), SPH_C32(0xb18b0000), SPH_C32(0xbc7a0000), + SPH_C32(0x4bbc0000), SPH_C32(0xa4f3442e), SPH_C32(0xf45616eb), + SPH_C32(0x6623a94f), SPH_C32(0x5ea22f27), SPH_C32(0x4c4e8400), + SPH_C32(0xa43c0000), SPH_C32(0xdbd10000), SPH_C32(0x835b0000), + SPH_C32(0x178113a8), SPH_C32(0xea7bb99f), SPH_C32(0xd0ae8609), + SPH_C32(0xee057339) }, + { SPH_C32(0x650a1800), SPH_C32(0xc0db0000), SPH_C32(0x299a0000), + SPH_C32(0x41a80000), SPH_C32(0x195f5d27), SPH_C32(0xbcb98eda), + SPH_C32(0x234ec450), SPH_C32(0x6308edfd), SPH_C32(0x5814b800), + SPH_C32(0x1dd50000), SPH_C32(0xbaf60000), SPH_C32(0x723a0000), + SPH_C32(0xd9e02ec4), SPH_C32(0x5a3284e7), SPH_C32(0x9707e129), + SPH_C32(0x0f8b57fc) }, + { SPH_C32(0x71502400), SPH_C32(0x79320000), SPH_C32(0x48bd0000), + SPH_C32(0xb0c90000), SPH_C32(0xd73e604b), SPH_C32(0x0cf0b3a2), + SPH_C32(0x64e7a370), SPH_C32(0x8286c938), SPH_C32(0x7b73ac00), + SPH_C32(0xd56c0000), SPH_C32(0x4e310000), SPH_C32(0x894f0000), + SPH_C32(0xaa2d0aa1), SPH_C32(0xa29421ae), SPH_C32(0x95c3eb16), + SPH_C32(0xd3afb1e3) }, + { SPH_C32(0x12455000), SPH_C32(0xe28f0000), SPH_C32(0x188b0000), + SPH_C32(0x1b180000), SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), + SPH_C32(0x4a3a8ff2), SPH_C32(0xea373c60), SPH_C32(0xf3928800), + SPH_C32(0xdc560000), SPH_C32(0xbd470000), SPH_C32(0x95bd0000), + SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), SPH_C32(0x916cbfec), + SPH_C32(0x4aeb5b0f) }, + { SPH_C32(0x061f6c00), SPH_C32(0x5b660000), SPH_C32(0x79ac0000), + SPH_C32(0xea790000), SPH_C32(0x1751235e), SPH_C32(0x60f3d20a), + SPH_C32(0x0d93e8d2), SPH_C32(0x0bb918a5), SPH_C32(0xd0f59c00), + SPH_C32(0x14ef0000), SPH_C32(0x49800000), SPH_C32(0x6ec80000), + SPH_C32(0x4ebb50ed), SPH_C32(0x0b6f6c6b), SPH_C32(0x93a8b5d3), + SPH_C32(0x96cfbd10) }, + { SPH_C32(0x31224400), SPH_C32(0x2a360000), SPH_C32(0xec4c0000), + SPH_C32(0xe06d0000), SPH_C32(0xaafd3a57), SPH_C32(0x281c4a3b), + SPH_C32(0x48fe85cd), SPH_C32(0x3613da7f), SPH_C32(0xc4afa000), + SPH_C32(0xad060000), SPH_C32(0x28a70000), SPH_C32(0x9fa90000), + SPH_C32(0x80da6d81), SPH_C32(0xbb265113), SPH_C32(0xd401d2f3), + SPH_C32(0x774199d5) }, + { SPH_C32(0x25787800), SPH_C32(0x93df0000), SPH_C32(0x8d6b0000), + SPH_C32(0x110c0000), SPH_C32(0x649c073b), SPH_C32(0x98557743), + SPH_C32(0x0f57e2ed), SPH_C32(0xd79dfeba), SPH_C32(0xe7c8b400), + SPH_C32(0x65bf0000), SPH_C32(0xdc600000), SPH_C32(0x64dc0000), + SPH_C32(0xf31749e4), SPH_C32(0x4380f45a), SPH_C32(0xd6c5d8cc), + SPH_C32(0xab657fca) }, + { SPH_C32(0xdad61400), SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), + SPH_C32(0x574e0000), SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), + SPH_C32(0x628cfdb5), SPH_C32(0xc7e6c5cb), SPH_C32(0xa7bad400), + SPH_C32(0x36bb0000), SPH_C32(0x78910000), SPH_C32(0x34780000), + SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), SPH_C32(0xfadcfe71), + SPH_C32(0x1ff06c8d) }, + { SPH_C32(0xce8c2800), SPH_C32(0x01580000), SPH_C32(0x2e2b0000), + SPH_C32(0xa62f0000), SPH_C32(0xfdc9076b), SPH_C32(0x1542c31f), + SPH_C32(0x25259a95), SPH_C32(0x2668e10e), SPH_C32(0x84ddc000), + SPH_C32(0xfe020000), SPH_C32(0x8c560000), SPH_C32(0xcf0d0000), + SPH_C32(0xfd19379d), SPH_C32(0x9fcaa88a), SPH_C32(0xf818f44e), + SPH_C32(0xc3d48a92) }, + { SPH_C32(0xf9b10000), SPH_C32(0x70080000), SPH_C32(0xbbcb0000), + SPH_C32(0xac3b0000), SPH_C32(0x40651e62), SPH_C32(0x5dad5b2e), + SPH_C32(0x6048f78a), SPH_C32(0x1bc223d4), SPH_C32(0x9087fc00), + SPH_C32(0x47eb0000), SPH_C32(0xed710000), SPH_C32(0x3e6c0000), + SPH_C32(0x33780af1), SPH_C32(0x2f8395f2), SPH_C32(0xbfb1936e), + SPH_C32(0x225aae57) }, + { SPH_C32(0xedeb3c00), SPH_C32(0xc9e10000), SPH_C32(0xdaec0000), + SPH_C32(0x5d5a0000), SPH_C32(0x8e04230e), SPH_C32(0xede46656), + SPH_C32(0x27e190aa), SPH_C32(0xfa4c0711), SPH_C32(0xb3e0e800), + SPH_C32(0x8f520000), SPH_C32(0x19b60000), SPH_C32(0xc5190000), + SPH_C32(0x40b52e94), SPH_C32(0xd72530bb), SPH_C32(0xbd759951), + SPH_C32(0xfe7e4848) }, + { SPH_C32(0x8efe4800), SPH_C32(0x525c0000), SPH_C32(0x8ada0000), + SPH_C32(0xf68b0000), SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), + SPH_C32(0x093cbc28), SPH_C32(0x92fdf249), SPH_C32(0x3b01cc00), + SPH_C32(0x86680000), SPH_C32(0xeac00000), SPH_C32(0xd9eb0000), + SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), SPH_C32(0xb9dacdab), + SPH_C32(0x673aa2a4) }, + { SPH_C32(0x9aa47400), SPH_C32(0xebb50000), SPH_C32(0xebfd0000), + SPH_C32(0x07ea0000), SPH_C32(0x4e6b601b), SPH_C32(0x81e707fe), + SPH_C32(0x4e95db08), SPH_C32(0x7373d68c), SPH_C32(0x1866d800), + SPH_C32(0x4ed10000), SPH_C32(0x1e070000), SPH_C32(0x229e0000), + SPH_C32(0xa42374d8), SPH_C32(0x7ede7d7e), SPH_C32(0xbb1ec794), + SPH_C32(0xbb1e44bb) }, + { SPH_C32(0xad995c00), SPH_C32(0x9ae50000), SPH_C32(0x7e1d0000), + SPH_C32(0x0dfe0000), SPH_C32(0xf3c77912), SPH_C32(0xc9089fcf), + SPH_C32(0x0bf8b617), SPH_C32(0x4ed91456), SPH_C32(0x0c3ce400), + SPH_C32(0xf7380000), SPH_C32(0x7f200000), SPH_C32(0xd3ff0000), + SPH_C32(0x6a4249b4), SPH_C32(0xce974006), SPH_C32(0xfcb7a0b4), + SPH_C32(0x5a90607e) }, + { SPH_C32(0xb9c36000), SPH_C32(0x230c0000), SPH_C32(0x1f3a0000), + SPH_C32(0xfc9f0000), SPH_C32(0x3da6447e), SPH_C32(0x7941a2b7), + SPH_C32(0x4c51d137), SPH_C32(0xaf573093), SPH_C32(0x2f5bf000), + SPH_C32(0x3f810000), SPH_C32(0x8be70000), SPH_C32(0x288a0000), + SPH_C32(0x198f6dd1), SPH_C32(0x3631e54f), SPH_C32(0xfe73aa8b), + SPH_C32(0x86b48661) }, + { SPH_C32(0x6f299000), SPH_C32(0x6c850000), SPH_C32(0x2f160000), + SPH_C32(0x782e0000), SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), + SPH_C32(0xd26a8c36), SPH_C32(0x32219526), SPH_C32(0x29449c00), + SPH_C32(0x64e70000), SPH_C32(0xf24b0000), SPH_C32(0xc2f30000), + SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), SPH_C32(0xf3e04259), + SPH_C32(0x8d0d9ec4) }, + { SPH_C32(0x7b73ac00), SPH_C32(0xd56c0000), SPH_C32(0x4e310000), + SPH_C32(0x894f0000), SPH_C32(0xaa2d0aa1), SPH_C32(0xa29421ae), + SPH_C32(0x95c3eb16), SPH_C32(0xd3afb1e3), SPH_C32(0x0a238800), + SPH_C32(0xac5e0000), SPH_C32(0x068c0000), SPH_C32(0x39860000), + SPH_C32(0x7d136aea), SPH_C32(0xae64920c), SPH_C32(0xf1244866), + SPH_C32(0x512978db) }, + { SPH_C32(0x4c4e8400), SPH_C32(0xa43c0000), SPH_C32(0xdbd10000), + SPH_C32(0x835b0000), SPH_C32(0x178113a8), SPH_C32(0xea7bb99f), + SPH_C32(0xd0ae8609), SPH_C32(0xee057339), SPH_C32(0x1e79b400), + SPH_C32(0x15b70000), SPH_C32(0x67ab0000), SPH_C32(0xc8e70000), + SPH_C32(0xb3725786), SPH_C32(0x1e2daf74), SPH_C32(0xb68d2f46), + SPH_C32(0xb0a75c1e) }, + { SPH_C32(0x5814b800), SPH_C32(0x1dd50000), SPH_C32(0xbaf60000), + SPH_C32(0x723a0000), SPH_C32(0xd9e02ec4), SPH_C32(0x5a3284e7), + SPH_C32(0x9707e129), SPH_C32(0x0f8b57fc), SPH_C32(0x3d1ea000), + SPH_C32(0xdd0e0000), SPH_C32(0x936c0000), SPH_C32(0x33920000), + SPH_C32(0xc0bf73e3), SPH_C32(0xe68b0a3d), SPH_C32(0xb4492579), + SPH_C32(0x6c83ba01) }, + { SPH_C32(0x3b01cc00), SPH_C32(0x86680000), SPH_C32(0xeac00000), + SPH_C32(0xd9eb0000), SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), + SPH_C32(0xb9dacdab), SPH_C32(0x673aa2a4), SPH_C32(0xb5ff8400), + SPH_C32(0xd4340000), SPH_C32(0x601a0000), SPH_C32(0x2f600000), + SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), SPH_C32(0xb0e67183), + SPH_C32(0xf5c750ed) }, + { SPH_C32(0x2f5bf000), SPH_C32(0x3f810000), SPH_C32(0x8be70000), + SPH_C32(0x288a0000), SPH_C32(0x198f6dd1), SPH_C32(0x3631e54f), + SPH_C32(0xfe73aa8b), SPH_C32(0x86b48661), SPH_C32(0x96989000), + SPH_C32(0x1c8d0000), SPH_C32(0x94dd0000), SPH_C32(0xd4150000), + SPH_C32(0x242929af), SPH_C32(0x4f7047f8), SPH_C32(0xb2227bbc), + SPH_C32(0x29e3b6f2) }, + { SPH_C32(0x1866d800), SPH_C32(0x4ed10000), SPH_C32(0x1e070000), + SPH_C32(0x229e0000), SPH_C32(0xa42374d8), SPH_C32(0x7ede7d7e), + SPH_C32(0xbb1ec794), SPH_C32(0xbb1e44bb), SPH_C32(0x82c2ac00), + SPH_C32(0xa5640000), SPH_C32(0xf5fa0000), SPH_C32(0x25740000), + SPH_C32(0xea4814c3), SPH_C32(0xff397a80), SPH_C32(0xf58b1c9c), + SPH_C32(0xc86d9237) }, + { SPH_C32(0x0c3ce400), SPH_C32(0xf7380000), SPH_C32(0x7f200000), + SPH_C32(0xd3ff0000), SPH_C32(0x6a4249b4), SPH_C32(0xce974006), + SPH_C32(0xfcb7a0b4), SPH_C32(0x5a90607e), SPH_C32(0xa1a5b800), + SPH_C32(0x6ddd0000), SPH_C32(0x013d0000), SPH_C32(0xde010000), + SPH_C32(0x998530a6), SPH_C32(0x079fdfc9), SPH_C32(0xf74f16a3), + SPH_C32(0x14497428) }, + { SPH_C32(0xf3928800), SPH_C32(0xdc560000), SPH_C32(0xbd470000), + SPH_C32(0x95bd0000), SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), + SPH_C32(0x916cbfec), SPH_C32(0x4aeb5b0f), SPH_C32(0xe1d7d800), + SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), SPH_C32(0x8ea50000), + SPH_C32(0xe4466aba), SPH_C32(0x23732650), SPH_C32(0xdb56301e), + SPH_C32(0xa0dc676f) }, + { SPH_C32(0xe7c8b400), SPH_C32(0x65bf0000), SPH_C32(0xdc600000), + SPH_C32(0x64dc0000), SPH_C32(0xf31749e4), SPH_C32(0x4380f45a), + SPH_C32(0xd6c5d8cc), SPH_C32(0xab657fca), SPH_C32(0xc2b0cc00), + SPH_C32(0xf6600000), SPH_C32(0x510b0000), SPH_C32(0x75d00000), + SPH_C32(0x978b4edf), SPH_C32(0xdbd58319), SPH_C32(0xd9923a21), + SPH_C32(0x7cf88170) }, + { SPH_C32(0xd0f59c00), SPH_C32(0x14ef0000), SPH_C32(0x49800000), + SPH_C32(0x6ec80000), SPH_C32(0x4ebb50ed), SPH_C32(0x0b6f6c6b), + SPH_C32(0x93a8b5d3), SPH_C32(0x96cfbd10), SPH_C32(0xd6eaf000), + SPH_C32(0x4f890000), SPH_C32(0x302c0000), SPH_C32(0x84b10000), + SPH_C32(0x59ea73b3), SPH_C32(0x6b9cbe61), SPH_C32(0x9e3b5d01), + SPH_C32(0x9d76a5b5) }, + { SPH_C32(0xc4afa000), SPH_C32(0xad060000), SPH_C32(0x28a70000), + SPH_C32(0x9fa90000), SPH_C32(0x80da6d81), SPH_C32(0xbb265113), + SPH_C32(0xd401d2f3), SPH_C32(0x774199d5), SPH_C32(0xf58de400), + SPH_C32(0x87300000), SPH_C32(0xc4eb0000), SPH_C32(0x7fc40000), + SPH_C32(0x2a2757d6), SPH_C32(0x933a1b28), SPH_C32(0x9cff573e), + SPH_C32(0x415243aa) }, + { SPH_C32(0xa7bad400), SPH_C32(0x36bb0000), SPH_C32(0x78910000), + SPH_C32(0x34780000), SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), + SPH_C32(0xfadcfe71), SPH_C32(0x1ff06c8d), SPH_C32(0x7d6cc000), + SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), SPH_C32(0x63360000), + SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), SPH_C32(0x985003c4), + SPH_C32(0xd816a946) }, + { SPH_C32(0xb3e0e800), SPH_C32(0x8f520000), SPH_C32(0x19b60000), + SPH_C32(0xc5190000), SPH_C32(0x40b52e94), SPH_C32(0xd72530bb), + SPH_C32(0xbd759951), SPH_C32(0xfe7e4848), SPH_C32(0x5e0bd400), + SPH_C32(0x46b30000), SPH_C32(0xc35a0000), SPH_C32(0x98430000), + SPH_C32(0xceb10d9a), SPH_C32(0x3ac156ed), SPH_C32(0x9a9409fb), + SPH_C32(0x04324f59) }, + { SPH_C32(0x84ddc000), SPH_C32(0xfe020000), SPH_C32(0x8c560000), + SPH_C32(0xcf0d0000), SPH_C32(0xfd19379d), SPH_C32(0x9fcaa88a), + SPH_C32(0xf818f44e), SPH_C32(0xc3d48a92), SPH_C32(0x4a51e800), + SPH_C32(0xff5a0000), SPH_C32(0xa27d0000), SPH_C32(0x69220000), + SPH_C32(0x00d030f6), SPH_C32(0x8a886b95), SPH_C32(0xdd3d6edb), + SPH_C32(0xe5bc6b9c) }, + { SPH_C32(0x9087fc00), SPH_C32(0x47eb0000), SPH_C32(0xed710000), + SPH_C32(0x3e6c0000), SPH_C32(0x33780af1), SPH_C32(0x2f8395f2), + SPH_C32(0xbfb1936e), SPH_C32(0x225aae57), SPH_C32(0x6936fc00), + SPH_C32(0x37e30000), SPH_C32(0x56ba0000), SPH_C32(0x92570000), + SPH_C32(0x731d1493), SPH_C32(0x722ecedc), SPH_C32(0xdff964e4), + SPH_C32(0x39988d83) } +}; + +static const sph_u32 T512_6[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x774400f0), SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), + SPH_C32(0x34140000), SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), + SPH_C32(0x0bc3cd1e), SPH_C32(0xcf3775cb), SPH_C32(0xf46c0050), + SPH_C32(0x96180000), SPH_C32(0x14a50000), SPH_C32(0x031f0000), + SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), SPH_C32(0x9ca470d2), + SPH_C32(0x8a341574) }, + { SPH_C32(0xf46c0050), SPH_C32(0x96180000), SPH_C32(0x14a50000), + SPH_C32(0x031f0000), SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), + SPH_C32(0x9ca470d2), SPH_C32(0x8a341574), SPH_C32(0x832800a0), + SPH_C32(0x67420000), SPH_C32(0xe1170000), SPH_C32(0x370b0000), + SPH_C32(0xcba30034), SPH_C32(0x3c34923c), SPH_C32(0x9767bdcc), + SPH_C32(0x450360bf) }, + { SPH_C32(0x832800a0), SPH_C32(0x67420000), SPH_C32(0xe1170000), + SPH_C32(0x370b0000), SPH_C32(0xcba30034), SPH_C32(0x3c34923c), + SPH_C32(0x9767bdcc), SPH_C32(0x450360bf), SPH_C32(0x774400f0), + SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), SPH_C32(0x34140000), + SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), SPH_C32(0x0bc3cd1e), + SPH_C32(0xcf3775cb) }, + { SPH_C32(0xe8870170), SPH_C32(0x9d720000), SPH_C32(0x12db0000), + SPH_C32(0xd4220000), SPH_C32(0xf2886b27), SPH_C32(0xa921e543), + SPH_C32(0x4ef8b518), SPH_C32(0x618813b1), SPH_C32(0xb4370060), + SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), SPH_C32(0x5cae0000), + SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), SPH_C32(0x1b365f3d), + SPH_C32(0xf3d45758) }, + { SPH_C32(0x9fc30180), SPH_C32(0x6c280000), SPH_C32(0xe7690000), + SPH_C32(0xe0360000), SPH_C32(0x7bbf15ab), SPH_C32(0xf3aa0966), + SPH_C32(0x453b7806), SPH_C32(0xaebf667a), SPH_C32(0x405b0030), + SPH_C32(0x9a540000), SPH_C32(0x42670000), SPH_C32(0x5fb10000), + SPH_C32(0xd6c06187), SPH_C32(0x5d81863c), SPH_C32(0x87922fef), + SPH_C32(0x79e0422c) }, + { SPH_C32(0x1ceb0120), SPH_C32(0x0b6a0000), SPH_C32(0x067e0000), + SPH_C32(0xd73d0000), SPH_C32(0xb01c159f), SPH_C32(0xcf9e9b5a), + SPH_C32(0xd25cc5ca), SPH_C32(0xebbc06c5), SPH_C32(0x371f00c0), + SPH_C32(0x6b0e0000), SPH_C32(0xb7d50000), SPH_C32(0x6ba50000), + SPH_C32(0x5ff71f0b), SPH_C32(0x070a6a19), SPH_C32(0x8c51e2f1), + SPH_C32(0xb6d737e7) }, + { SPH_C32(0x6baf01d0), SPH_C32(0xfa300000), SPH_C32(0xf3cc0000), + SPH_C32(0xe3290000), SPH_C32(0x392b6b13), SPH_C32(0x9515777f), + SPH_C32(0xd99f08d4), SPH_C32(0x248b730e), SPH_C32(0xc3730090), + SPH_C32(0xfd160000), SPH_C32(0xa3700000), SPH_C32(0x68ba0000), + SPH_C32(0x1d6361b3), SPH_C32(0x61b51400), SPH_C32(0x10f59223), + SPH_C32(0x3ce32293) }, + { SPH_C32(0xb4370060), SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), + SPH_C32(0x5cae0000), SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), + SPH_C32(0x1b365f3d), SPH_C32(0xf3d45758), SPH_C32(0x5cb00110), + SPH_C32(0x913e0000), SPH_C32(0x44190000), SPH_C32(0x888c0000), + SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), SPH_C32(0x55ceea25), + SPH_C32(0x925c44e9) }, + { SPH_C32(0xc3730090), SPH_C32(0xfd160000), SPH_C32(0xa3700000), + SPH_C32(0x68ba0000), SPH_C32(0x1d6361b3), SPH_C32(0x61b51400), + SPH_C32(0x10f59223), SPH_C32(0x3ce32293), SPH_C32(0xa8dc0140), + SPH_C32(0x07260000), SPH_C32(0x50bc0000), SPH_C32(0x8b930000), + SPH_C32(0x24480aa0), SPH_C32(0xf4a0637f), SPH_C32(0xc96a9af7), + SPH_C32(0x1868519d) }, + { SPH_C32(0x405b0030), SPH_C32(0x9a540000), SPH_C32(0x42670000), + SPH_C32(0x5fb10000), SPH_C32(0xd6c06187), SPH_C32(0x5d81863c), + SPH_C32(0x87922fef), SPH_C32(0x79e0422c), SPH_C32(0xdf9801b0), + SPH_C32(0xf67c0000), SPH_C32(0xa50e0000), SPH_C32(0xbf870000), + SPH_C32(0xad7f742c), SPH_C32(0xae2b8f5a), SPH_C32(0xc2a957e9), + SPH_C32(0xd75f2456) }, + { SPH_C32(0x371f00c0), SPH_C32(0x6b0e0000), SPH_C32(0xb7d50000), + SPH_C32(0x6ba50000), SPH_C32(0x5ff71f0b), SPH_C32(0x070a6a19), + SPH_C32(0x8c51e2f1), SPH_C32(0xb6d737e7), SPH_C32(0x2bf401e0), + SPH_C32(0x60640000), SPH_C32(0xb1ab0000), SPH_C32(0xbc980000), + SPH_C32(0xefeb0a94), SPH_C32(0xc894f143), SPH_C32(0x5e0d273b), + SPH_C32(0x5d6b3122) }, + { SPH_C32(0x5cb00110), SPH_C32(0x913e0000), SPH_C32(0x44190000), + SPH_C32(0x888c0000), SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), + SPH_C32(0x55ceea25), SPH_C32(0x925c44e9), SPH_C32(0xe8870170), + SPH_C32(0x9d720000), SPH_C32(0x12db0000), SPH_C32(0xd4220000), + SPH_C32(0xf2886b27), SPH_C32(0xa921e543), SPH_C32(0x4ef8b518), + SPH_C32(0x618813b1) }, + { SPH_C32(0x2bf401e0), SPH_C32(0x60640000), SPH_C32(0xb1ab0000), + SPH_C32(0xbc980000), SPH_C32(0xefeb0a94), SPH_C32(0xc894f143), + SPH_C32(0x5e0d273b), SPH_C32(0x5d6b3122), SPH_C32(0x1ceb0120), + SPH_C32(0x0b6a0000), SPH_C32(0x067e0000), SPH_C32(0xd73d0000), + SPH_C32(0xb01c159f), SPH_C32(0xcf9e9b5a), SPH_C32(0xd25cc5ca), + SPH_C32(0xebbc06c5) }, + { SPH_C32(0xa8dc0140), SPH_C32(0x07260000), SPH_C32(0x50bc0000), + SPH_C32(0x8b930000), SPH_C32(0x24480aa0), SPH_C32(0xf4a0637f), + SPH_C32(0xc96a9af7), SPH_C32(0x1868519d), SPH_C32(0x6baf01d0), + SPH_C32(0xfa300000), SPH_C32(0xf3cc0000), SPH_C32(0xe3290000), + SPH_C32(0x392b6b13), SPH_C32(0x9515777f), SPH_C32(0xd99f08d4), + SPH_C32(0x248b730e) }, + { SPH_C32(0xdf9801b0), SPH_C32(0xf67c0000), SPH_C32(0xa50e0000), + SPH_C32(0xbf870000), SPH_C32(0xad7f742c), SPH_C32(0xae2b8f5a), + SPH_C32(0xc2a957e9), SPH_C32(0xd75f2456), SPH_C32(0x9fc30180), + SPH_C32(0x6c280000), SPH_C32(0xe7690000), SPH_C32(0xe0360000), + SPH_C32(0x7bbf15ab), SPH_C32(0xf3aa0966), SPH_C32(0x453b7806), + SPH_C32(0xaebf667a) }, + { SPH_C32(0xef0b0270), SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), + SPH_C32(0x69490000), SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), + SPH_C32(0x66140a51), SPH_C32(0x924f5d0a), SPH_C32(0xc96b0030), + SPH_C32(0xe7250000), SPH_C32(0x2f840000), SPH_C32(0x264f0000), + SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), SPH_C32(0x509f6984), + SPH_C32(0x9e69af68) }, + { SPH_C32(0x984f0280), SPH_C32(0xcba70000), SPH_C32(0xa81c0000), + SPH_C32(0x5d5d0000), SPH_C32(0x1238428a), SPH_C32(0x1e8e59dc), + SPH_C32(0x6dd7c74f), SPH_C32(0x5d7828c1), SPH_C32(0x3d070060), + SPH_C32(0x713d0000), SPH_C32(0x3b210000), SPH_C32(0x25500000), + SPH_C32(0x4afd2541), SPH_C32(0x0b438f2e), SPH_C32(0xcc3b1956), + SPH_C32(0x145dba1c) }, + { SPH_C32(0x1b670220), SPH_C32(0xace50000), SPH_C32(0x490b0000), + SPH_C32(0x6a560000), SPH_C32(0xd99b42be), SPH_C32(0x22bacbe0), + SPH_C32(0xfab07a83), SPH_C32(0x187b487e), SPH_C32(0x4a430090), + SPH_C32(0x80670000), SPH_C32(0xce930000), SPH_C32(0x11440000), + SPH_C32(0xc3ca5bcd), SPH_C32(0x51c8630b), SPH_C32(0xc7f8d448), + SPH_C32(0xdb6acfd7) }, + { SPH_C32(0x6c2302d0), SPH_C32(0x5dbf0000), SPH_C32(0xbcb90000), + SPH_C32(0x5e420000), SPH_C32(0x50ac3c32), SPH_C32(0x783127c5), + SPH_C32(0xf173b79d), SPH_C32(0xd74c3db5), SPH_C32(0xbe2f00c0), + SPH_C32(0x167f0000), SPH_C32(0xda360000), SPH_C32(0x125b0000), + SPH_C32(0x815e2575), SPH_C32(0x37771d12), SPH_C32(0x5b5ca49a), + SPH_C32(0x515edaa3) }, + { SPH_C32(0x078c0300), SPH_C32(0xa78f0000), SPH_C32(0x4f750000), + SPH_C32(0xbd6b0000), SPH_C32(0x69875721), SPH_C32(0xed2450ba), + SPH_C32(0x28ecbf49), SPH_C32(0xf3c74ebb), SPH_C32(0x7d5c0050), + SPH_C32(0xeb690000), SPH_C32(0x79460000), SPH_C32(0x7ae10000), + SPH_C32(0x9c3d44c6), SPH_C32(0x56c20912), SPH_C32(0x4ba936b9), + SPH_C32(0x6dbdf830) }, + { SPH_C32(0x70c803f0), SPH_C32(0x56d50000), SPH_C32(0xbac70000), + SPH_C32(0x897f0000), SPH_C32(0xe0b029ad), SPH_C32(0xb7afbc9f), + SPH_C32(0x232f7257), SPH_C32(0x3cf03b70), SPH_C32(0x89300000), + SPH_C32(0x7d710000), SPH_C32(0x6de30000), SPH_C32(0x79fe0000), + SPH_C32(0xdea93a7e), SPH_C32(0x307d770b), SPH_C32(0xd70d466b), + SPH_C32(0xe789ed44) }, + { SPH_C32(0xf3e00350), SPH_C32(0x31970000), SPH_C32(0x5bd00000), + SPH_C32(0xbe740000), SPH_C32(0x2b132999), SPH_C32(0x8b9b2ea3), + SPH_C32(0xb448cf9b), SPH_C32(0x79f35bcf), SPH_C32(0xfe7400f0), + SPH_C32(0x8c2b0000), SPH_C32(0x98510000), SPH_C32(0x4dea0000), + SPH_C32(0x579e44f2), SPH_C32(0x6af69b2e), SPH_C32(0xdcce8b75), + SPH_C32(0x28be988f) }, + { SPH_C32(0x84a403a0), SPH_C32(0xc0cd0000), SPH_C32(0xae620000), + SPH_C32(0x8a600000), SPH_C32(0xa2245715), SPH_C32(0xd110c286), + SPH_C32(0xbf8b0285), SPH_C32(0xb6c42e04), SPH_C32(0x0a1800a0), + SPH_C32(0x1a330000), SPH_C32(0x8cf40000), SPH_C32(0x4ef50000), + SPH_C32(0x150a3a4a), SPH_C32(0x0c49e537), SPH_C32(0x406afba7), + SPH_C32(0xa28a8dfb) }, + { SPH_C32(0x5b3c0210), SPH_C32(0x36b10000), SPH_C32(0x0b6c0000), + SPH_C32(0x35e70000), SPH_C32(0x0f5b2339), SPH_C32(0x7f3b4ddc), + SPH_C32(0x7d22556c), SPH_C32(0x619b0a52), SPH_C32(0x95db0120), + SPH_C32(0x761b0000), SPH_C32(0x6b9d0000), SPH_C32(0xaec30000), + SPH_C32(0x6eb52fe1), SPH_C32(0xffe3ec51), SPH_C32(0x055183a1), + SPH_C32(0x0c35eb81) }, + { SPH_C32(0x2c7802e0), SPH_C32(0xc7eb0000), SPH_C32(0xfede0000), + SPH_C32(0x01f30000), SPH_C32(0x866c5db5), SPH_C32(0x25b0a1f9), + SPH_C32(0x76e19872), SPH_C32(0xaeac7f99), SPH_C32(0x61b70170), + SPH_C32(0xe0030000), SPH_C32(0x7f380000), SPH_C32(0xaddc0000), + SPH_C32(0x2c215159), SPH_C32(0x995c9248), SPH_C32(0x99f5f373), + SPH_C32(0x8601fef5) }, + { SPH_C32(0xaf500240), SPH_C32(0xa0a90000), SPH_C32(0x1fc90000), + SPH_C32(0x36f80000), SPH_C32(0x4dcf5d81), SPH_C32(0x198433c5), + SPH_C32(0xe18625be), SPH_C32(0xebaf1f26), SPH_C32(0x16f30180), + SPH_C32(0x11590000), SPH_C32(0x8a8a0000), SPH_C32(0x99c80000), + SPH_C32(0xa5162fd5), SPH_C32(0xc3d77e6d), SPH_C32(0x92363e6d), + SPH_C32(0x49368b3e) }, + { SPH_C32(0xd81402b0), SPH_C32(0x51f30000), SPH_C32(0xea7b0000), + SPH_C32(0x02ec0000), SPH_C32(0xc4f8230d), SPH_C32(0x430fdfe0), + SPH_C32(0xea45e8a0), SPH_C32(0x24986aed), SPH_C32(0xe29f01d0), + SPH_C32(0x87410000), SPH_C32(0x9e2f0000), SPH_C32(0x9ad70000), + SPH_C32(0xe782516d), SPH_C32(0xa5680074), SPH_C32(0x0e924ebf), + SPH_C32(0xc3029e4a) }, + { SPH_C32(0xb3bb0360), SPH_C32(0xabc30000), SPH_C32(0x19b70000), + SPH_C32(0xe1c50000), SPH_C32(0xfdd3481e), SPH_C32(0xd61aa89f), + SPH_C32(0x33dae074), SPH_C32(0x001319e3), SPH_C32(0x21ec0140), + SPH_C32(0x7a570000), SPH_C32(0x3d5f0000), SPH_C32(0xf26d0000), + SPH_C32(0xfae130de), SPH_C32(0xc4dd1474), SPH_C32(0x1e67dc9c), + SPH_C32(0xffe1bcd9) }, + { SPH_C32(0xc4ff0390), SPH_C32(0x5a990000), SPH_C32(0xec050000), + SPH_C32(0xd5d10000), SPH_C32(0x74e43692), SPH_C32(0x8c9144ba), + SPH_C32(0x38192d6a), SPH_C32(0xcf246c28), SPH_C32(0xd5800110), + SPH_C32(0xec4f0000), SPH_C32(0x29fa0000), SPH_C32(0xf1720000), + SPH_C32(0xb8754e66), SPH_C32(0xa2626a6d), SPH_C32(0x82c3ac4e), + SPH_C32(0x75d5a9ad) }, + { SPH_C32(0x47d70330), SPH_C32(0x3ddb0000), SPH_C32(0x0d120000), + SPH_C32(0xe2da0000), SPH_C32(0xbf4736a6), SPH_C32(0xb0a5d686), + SPH_C32(0xaf7e90a6), SPH_C32(0x8a270c97), SPH_C32(0xa2c401e0), + SPH_C32(0x1d150000), SPH_C32(0xdc480000), SPH_C32(0xc5660000), + SPH_C32(0x314230ea), SPH_C32(0xf8e98648), SPH_C32(0x89006150), + SPH_C32(0xbae2dc66) }, + { SPH_C32(0x309303c0), SPH_C32(0xcc810000), SPH_C32(0xf8a00000), + SPH_C32(0xd6ce0000), SPH_C32(0x3670482a), SPH_C32(0xea2e3aa3), + SPH_C32(0xa4bd5db8), SPH_C32(0x4510795c), SPH_C32(0x56a801b0), + SPH_C32(0x8b0d0000), SPH_C32(0xc8ed0000), SPH_C32(0xc6790000), + SPH_C32(0x73d64e52), SPH_C32(0x9e56f851), SPH_C32(0x15a41182), + SPH_C32(0x30d6c912) }, + { SPH_C32(0xc96b0030), SPH_C32(0xe7250000), SPH_C32(0x2f840000), + SPH_C32(0x264f0000), SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), + SPH_C32(0x509f6984), SPH_C32(0x9e69af68), SPH_C32(0x26600240), + SPH_C32(0xddd80000), SPH_C32(0x722a0000), SPH_C32(0x4f060000), + SPH_C32(0x936667ff), SPH_C32(0x29f944ce), SPH_C32(0x368b63d5), + SPH_C32(0x0c26f262) }, + { SPH_C32(0xbe2f00c0), SPH_C32(0x167f0000), SPH_C32(0xda360000), + SPH_C32(0x125b0000), SPH_C32(0x815e2575), SPH_C32(0x37771d12), + SPH_C32(0x5b5ca49a), SPH_C32(0x515edaa3), SPH_C32(0xd20c0210), + SPH_C32(0x4bc00000), SPH_C32(0x668f0000), SPH_C32(0x4c190000), + SPH_C32(0xd1f21947), SPH_C32(0x4f463ad7), SPH_C32(0xaa2f1307), + SPH_C32(0x8612e716) }, + { SPH_C32(0x3d070060), SPH_C32(0x713d0000), SPH_C32(0x3b210000), + SPH_C32(0x25500000), SPH_C32(0x4afd2541), SPH_C32(0x0b438f2e), + SPH_C32(0xcc3b1956), SPH_C32(0x145dba1c), SPH_C32(0xa54802e0), + SPH_C32(0xba9a0000), SPH_C32(0x933d0000), SPH_C32(0x780d0000), + SPH_C32(0x58c567cb), SPH_C32(0x15cdd6f2), SPH_C32(0xa1ecde19), + SPH_C32(0x492592dd) }, + { SPH_C32(0x4a430090), SPH_C32(0x80670000), SPH_C32(0xce930000), + SPH_C32(0x11440000), SPH_C32(0xc3ca5bcd), SPH_C32(0x51c8630b), + SPH_C32(0xc7f8d448), SPH_C32(0xdb6acfd7), SPH_C32(0x512402b0), + SPH_C32(0x2c820000), SPH_C32(0x87980000), SPH_C32(0x7b120000), + SPH_C32(0x1a511973), SPH_C32(0x7372a8eb), SPH_C32(0x3d48aecb), + SPH_C32(0xc31187a9) }, + { SPH_C32(0x21ec0140), SPH_C32(0x7a570000), SPH_C32(0x3d5f0000), + SPH_C32(0xf26d0000), SPH_C32(0xfae130de), SPH_C32(0xc4dd1474), + SPH_C32(0x1e67dc9c), SPH_C32(0xffe1bcd9), SPH_C32(0x92570220), + SPH_C32(0xd1940000), SPH_C32(0x24e80000), SPH_C32(0x13a80000), + SPH_C32(0x073278c0), SPH_C32(0x12c7bceb), SPH_C32(0x2dbd3ce8), + SPH_C32(0xfff2a53a) }, + { SPH_C32(0x56a801b0), SPH_C32(0x8b0d0000), SPH_C32(0xc8ed0000), + SPH_C32(0xc6790000), SPH_C32(0x73d64e52), SPH_C32(0x9e56f851), + SPH_C32(0x15a41182), SPH_C32(0x30d6c912), SPH_C32(0x663b0270), + SPH_C32(0x478c0000), SPH_C32(0x304d0000), SPH_C32(0x10b70000), + SPH_C32(0x45a60678), SPH_C32(0x7478c2f2), SPH_C32(0xb1194c3a), + SPH_C32(0x75c6b04e) }, + { SPH_C32(0xd5800110), SPH_C32(0xec4f0000), SPH_C32(0x29fa0000), + SPH_C32(0xf1720000), SPH_C32(0xb8754e66), SPH_C32(0xa2626a6d), + SPH_C32(0x82c3ac4e), SPH_C32(0x75d5a9ad), SPH_C32(0x117f0280), + SPH_C32(0xb6d60000), SPH_C32(0xc5ff0000), SPH_C32(0x24a30000), + SPH_C32(0xcc9178f4), SPH_C32(0x2ef32ed7), SPH_C32(0xbada8124), + SPH_C32(0xbaf1c585) }, + { SPH_C32(0xa2c401e0), SPH_C32(0x1d150000), SPH_C32(0xdc480000), + SPH_C32(0xc5660000), SPH_C32(0x314230ea), SPH_C32(0xf8e98648), + SPH_C32(0x89006150), SPH_C32(0xbae2dc66), SPH_C32(0xe51302d0), + SPH_C32(0x20ce0000), SPH_C32(0xd15a0000), SPH_C32(0x27bc0000), + SPH_C32(0x8e05064c), SPH_C32(0x484c50ce), SPH_C32(0x267ef1f6), + SPH_C32(0x30c5d0f1) }, + { SPH_C32(0x7d5c0050), SPH_C32(0xeb690000), SPH_C32(0x79460000), + SPH_C32(0x7ae10000), SPH_C32(0x9c3d44c6), SPH_C32(0x56c20912), + SPH_C32(0x4ba936b9), SPH_C32(0x6dbdf830), SPH_C32(0x7ad00350), + SPH_C32(0x4ce60000), SPH_C32(0x36330000), SPH_C32(0xc78a0000), + SPH_C32(0xf5ba13e7), SPH_C32(0xbbe659a8), SPH_C32(0x634589f0), + SPH_C32(0x9e7ab68b) }, + { SPH_C32(0x0a1800a0), SPH_C32(0x1a330000), SPH_C32(0x8cf40000), + SPH_C32(0x4ef50000), SPH_C32(0x150a3a4a), SPH_C32(0x0c49e537), + SPH_C32(0x406afba7), SPH_C32(0xa28a8dfb), SPH_C32(0x8ebc0300), + SPH_C32(0xdafe0000), SPH_C32(0x22960000), SPH_C32(0xc4950000), + SPH_C32(0xb72e6d5f), SPH_C32(0xdd5927b1), SPH_C32(0xffe1f922), + SPH_C32(0x144ea3ff) }, + { SPH_C32(0x89300000), SPH_C32(0x7d710000), SPH_C32(0x6de30000), + SPH_C32(0x79fe0000), SPH_C32(0xdea93a7e), SPH_C32(0x307d770b), + SPH_C32(0xd70d466b), SPH_C32(0xe789ed44), SPH_C32(0xf9f803f0), + SPH_C32(0x2ba40000), SPH_C32(0xd7240000), SPH_C32(0xf0810000), + SPH_C32(0x3e1913d3), SPH_C32(0x87d2cb94), SPH_C32(0xf422343c), + SPH_C32(0xdb79d634) }, + { SPH_C32(0xfe7400f0), SPH_C32(0x8c2b0000), SPH_C32(0x98510000), + SPH_C32(0x4dea0000), SPH_C32(0x579e44f2), SPH_C32(0x6af69b2e), + SPH_C32(0xdcce8b75), SPH_C32(0x28be988f), SPH_C32(0x0d9403a0), + SPH_C32(0xbdbc0000), SPH_C32(0xc3810000), SPH_C32(0xf39e0000), + SPH_C32(0x7c8d6d6b), SPH_C32(0xe16db58d), SPH_C32(0x688644ee), + SPH_C32(0x514dc340) }, + { SPH_C32(0x95db0120), SPH_C32(0x761b0000), SPH_C32(0x6b9d0000), + SPH_C32(0xaec30000), SPH_C32(0x6eb52fe1), SPH_C32(0xffe3ec51), + SPH_C32(0x055183a1), SPH_C32(0x0c35eb81), SPH_C32(0xcee70330), + SPH_C32(0x40aa0000), SPH_C32(0x60f10000), SPH_C32(0x9b240000), + SPH_C32(0x61ee0cd8), SPH_C32(0x80d8a18d), SPH_C32(0x7873d6cd), + SPH_C32(0x6daee1d3) }, + { SPH_C32(0xe29f01d0), SPH_C32(0x87410000), SPH_C32(0x9e2f0000), + SPH_C32(0x9ad70000), SPH_C32(0xe782516d), SPH_C32(0xa5680074), + SPH_C32(0x0e924ebf), SPH_C32(0xc3029e4a), SPH_C32(0x3a8b0360), + SPH_C32(0xd6b20000), SPH_C32(0x74540000), SPH_C32(0x983b0000), + SPH_C32(0x237a7260), SPH_C32(0xe667df94), SPH_C32(0xe4d7a61f), + SPH_C32(0xe79af4a7) }, + { SPH_C32(0x61b70170), SPH_C32(0xe0030000), SPH_C32(0x7f380000), + SPH_C32(0xaddc0000), SPH_C32(0x2c215159), SPH_C32(0x995c9248), + SPH_C32(0x99f5f373), SPH_C32(0x8601fef5), SPH_C32(0x4dcf0390), + SPH_C32(0x27e80000), SPH_C32(0x81e60000), SPH_C32(0xac2f0000), + SPH_C32(0xaa4d0cec), SPH_C32(0xbcec33b1), SPH_C32(0xef146b01), + SPH_C32(0x28ad816c) }, + { SPH_C32(0x16f30180), SPH_C32(0x11590000), SPH_C32(0x8a8a0000), + SPH_C32(0x99c80000), SPH_C32(0xa5162fd5), SPH_C32(0xc3d77e6d), + SPH_C32(0x92363e6d), SPH_C32(0x49368b3e), SPH_C32(0xb9a303c0), + SPH_C32(0xb1f00000), SPH_C32(0x95430000), SPH_C32(0xaf300000), + SPH_C32(0xe8d97254), SPH_C32(0xda534da8), SPH_C32(0x73b01bd3), + SPH_C32(0xa2999418) }, + { SPH_C32(0x26600240), SPH_C32(0xddd80000), SPH_C32(0x722a0000), + SPH_C32(0x4f060000), SPH_C32(0x936667ff), SPH_C32(0x29f944ce), + SPH_C32(0x368b63d5), SPH_C32(0x0c26f262), SPH_C32(0xef0b0270), + SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), SPH_C32(0x69490000), + SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), SPH_C32(0x66140a51), + SPH_C32(0x924f5d0a) }, + { SPH_C32(0x512402b0), SPH_C32(0x2c820000), SPH_C32(0x87980000), + SPH_C32(0x7b120000), SPH_C32(0x1a511973), SPH_C32(0x7372a8eb), + SPH_C32(0x3d48aecb), SPH_C32(0xc31187a9), SPH_C32(0x1b670220), + SPH_C32(0xace50000), SPH_C32(0x490b0000), SPH_C32(0x6a560000), + SPH_C32(0xd99b42be), SPH_C32(0x22bacbe0), SPH_C32(0xfab07a83), + SPH_C32(0x187b487e) }, + { SPH_C32(0xd20c0210), SPH_C32(0x4bc00000), SPH_C32(0x668f0000), + SPH_C32(0x4c190000), SPH_C32(0xd1f21947), SPH_C32(0x4f463ad7), + SPH_C32(0xaa2f1307), SPH_C32(0x8612e716), SPH_C32(0x6c2302d0), + SPH_C32(0x5dbf0000), SPH_C32(0xbcb90000), SPH_C32(0x5e420000), + SPH_C32(0x50ac3c32), SPH_C32(0x783127c5), SPH_C32(0xf173b79d), + SPH_C32(0xd74c3db5) }, + { SPH_C32(0xa54802e0), SPH_C32(0xba9a0000), SPH_C32(0x933d0000), + SPH_C32(0x780d0000), SPH_C32(0x58c567cb), SPH_C32(0x15cdd6f2), + SPH_C32(0xa1ecde19), SPH_C32(0x492592dd), SPH_C32(0x984f0280), + SPH_C32(0xcba70000), SPH_C32(0xa81c0000), SPH_C32(0x5d5d0000), + SPH_C32(0x1238428a), SPH_C32(0x1e8e59dc), SPH_C32(0x6dd7c74f), + SPH_C32(0x5d7828c1) }, + { SPH_C32(0xcee70330), SPH_C32(0x40aa0000), SPH_C32(0x60f10000), + SPH_C32(0x9b240000), SPH_C32(0x61ee0cd8), SPH_C32(0x80d8a18d), + SPH_C32(0x7873d6cd), SPH_C32(0x6daee1d3), SPH_C32(0x5b3c0210), + SPH_C32(0x36b10000), SPH_C32(0x0b6c0000), SPH_C32(0x35e70000), + SPH_C32(0x0f5b2339), SPH_C32(0x7f3b4ddc), SPH_C32(0x7d22556c), + SPH_C32(0x619b0a52) }, + { SPH_C32(0xb9a303c0), SPH_C32(0xb1f00000), SPH_C32(0x95430000), + SPH_C32(0xaf300000), SPH_C32(0xe8d97254), SPH_C32(0xda534da8), + SPH_C32(0x73b01bd3), SPH_C32(0xa2999418), SPH_C32(0xaf500240), + SPH_C32(0xa0a90000), SPH_C32(0x1fc90000), SPH_C32(0x36f80000), + SPH_C32(0x4dcf5d81), SPH_C32(0x198433c5), SPH_C32(0xe18625be), + SPH_C32(0xebaf1f26) }, + { SPH_C32(0x3a8b0360), SPH_C32(0xd6b20000), SPH_C32(0x74540000), + SPH_C32(0x983b0000), SPH_C32(0x237a7260), SPH_C32(0xe667df94), + SPH_C32(0xe4d7a61f), SPH_C32(0xe79af4a7), SPH_C32(0xd81402b0), + SPH_C32(0x51f30000), SPH_C32(0xea7b0000), SPH_C32(0x02ec0000), + SPH_C32(0xc4f8230d), SPH_C32(0x430fdfe0), SPH_C32(0xea45e8a0), + SPH_C32(0x24986aed) }, + { SPH_C32(0x4dcf0390), SPH_C32(0x27e80000), SPH_C32(0x81e60000), + SPH_C32(0xac2f0000), SPH_C32(0xaa4d0cec), SPH_C32(0xbcec33b1), + SPH_C32(0xef146b01), SPH_C32(0x28ad816c), SPH_C32(0x2c7802e0), + SPH_C32(0xc7eb0000), SPH_C32(0xfede0000), SPH_C32(0x01f30000), + SPH_C32(0x866c5db5), SPH_C32(0x25b0a1f9), SPH_C32(0x76e19872), + SPH_C32(0xaeac7f99) }, + { SPH_C32(0x92570220), SPH_C32(0xd1940000), SPH_C32(0x24e80000), + SPH_C32(0x13a80000), SPH_C32(0x073278c0), SPH_C32(0x12c7bceb), + SPH_C32(0x2dbd3ce8), SPH_C32(0xfff2a53a), SPH_C32(0xb3bb0360), + SPH_C32(0xabc30000), SPH_C32(0x19b70000), SPH_C32(0xe1c50000), + SPH_C32(0xfdd3481e), SPH_C32(0xd61aa89f), SPH_C32(0x33dae074), + SPH_C32(0x001319e3) }, + { SPH_C32(0xe51302d0), SPH_C32(0x20ce0000), SPH_C32(0xd15a0000), + SPH_C32(0x27bc0000), SPH_C32(0x8e05064c), SPH_C32(0x484c50ce), + SPH_C32(0x267ef1f6), SPH_C32(0x30c5d0f1), SPH_C32(0x47d70330), + SPH_C32(0x3ddb0000), SPH_C32(0x0d120000), SPH_C32(0xe2da0000), + SPH_C32(0xbf4736a6), SPH_C32(0xb0a5d686), SPH_C32(0xaf7e90a6), + SPH_C32(0x8a270c97) }, + { SPH_C32(0x663b0270), SPH_C32(0x478c0000), SPH_C32(0x304d0000), + SPH_C32(0x10b70000), SPH_C32(0x45a60678), SPH_C32(0x7478c2f2), + SPH_C32(0xb1194c3a), SPH_C32(0x75c6b04e), SPH_C32(0x309303c0), + SPH_C32(0xcc810000), SPH_C32(0xf8a00000), SPH_C32(0xd6ce0000), + SPH_C32(0x3670482a), SPH_C32(0xea2e3aa3), SPH_C32(0xa4bd5db8), + SPH_C32(0x4510795c) }, + { SPH_C32(0x117f0280), SPH_C32(0xb6d60000), SPH_C32(0xc5ff0000), + SPH_C32(0x24a30000), SPH_C32(0xcc9178f4), SPH_C32(0x2ef32ed7), + SPH_C32(0xbada8124), SPH_C32(0xbaf1c585), SPH_C32(0xc4ff0390), + SPH_C32(0x5a990000), SPH_C32(0xec050000), SPH_C32(0xd5d10000), + SPH_C32(0x74e43692), SPH_C32(0x8c9144ba), SPH_C32(0x38192d6a), + SPH_C32(0xcf246c28) }, + { SPH_C32(0x7ad00350), SPH_C32(0x4ce60000), SPH_C32(0x36330000), + SPH_C32(0xc78a0000), SPH_C32(0xf5ba13e7), SPH_C32(0xbbe659a8), + SPH_C32(0x634589f0), SPH_C32(0x9e7ab68b), SPH_C32(0x078c0300), + SPH_C32(0xa78f0000), SPH_C32(0x4f750000), SPH_C32(0xbd6b0000), + SPH_C32(0x69875721), SPH_C32(0xed2450ba), SPH_C32(0x28ecbf49), + SPH_C32(0xf3c74ebb) }, + { SPH_C32(0x0d9403a0), SPH_C32(0xbdbc0000), SPH_C32(0xc3810000), + SPH_C32(0xf39e0000), SPH_C32(0x7c8d6d6b), SPH_C32(0xe16db58d), + SPH_C32(0x688644ee), SPH_C32(0x514dc340), SPH_C32(0xf3e00350), + SPH_C32(0x31970000), SPH_C32(0x5bd00000), SPH_C32(0xbe740000), + SPH_C32(0x2b132999), SPH_C32(0x8b9b2ea3), SPH_C32(0xb448cf9b), + SPH_C32(0x79f35bcf) }, + { SPH_C32(0x8ebc0300), SPH_C32(0xdafe0000), SPH_C32(0x22960000), + SPH_C32(0xc4950000), SPH_C32(0xb72e6d5f), SPH_C32(0xdd5927b1), + SPH_C32(0xffe1f922), SPH_C32(0x144ea3ff), SPH_C32(0x84a403a0), + SPH_C32(0xc0cd0000), SPH_C32(0xae620000), SPH_C32(0x8a600000), + SPH_C32(0xa2245715), SPH_C32(0xd110c286), SPH_C32(0xbf8b0285), + SPH_C32(0xb6c42e04) }, + { SPH_C32(0xf9f803f0), SPH_C32(0x2ba40000), SPH_C32(0xd7240000), + SPH_C32(0xf0810000), SPH_C32(0x3e1913d3), SPH_C32(0x87d2cb94), + SPH_C32(0xf422343c), SPH_C32(0xdb79d634), SPH_C32(0x70c803f0), + SPH_C32(0x56d50000), SPH_C32(0xbac70000), SPH_C32(0x897f0000), + SPH_C32(0xe0b029ad), SPH_C32(0xb7afbc9f), SPH_C32(0x232f7257), + SPH_C32(0x3cf03b70) } +}; + +static const sph_u32 T512_12[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x75c90003), SPH_C32(0x0e10c000), SPH_C32(0xd1200000), + SPH_C32(0xbaea0000), SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), + SPH_C32(0xbb28761d), SPH_C32(0x00b72e2b), SPH_C32(0xeecf0001), + SPH_C32(0x6f564000), SPH_C32(0xf33e0000), SPH_C32(0xa79e0000), + SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), SPH_C32(0x4a3b40ba), + SPH_C32(0xfeabf254) }, + { SPH_C32(0xeecf0001), SPH_C32(0x6f564000), SPH_C32(0xf33e0000), + SPH_C32(0xa79e0000), SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), + SPH_C32(0x4a3b40ba), SPH_C32(0xfeabf254), SPH_C32(0x9b060002), + SPH_C32(0x61468000), SPH_C32(0x221e0000), SPH_C32(0x1d740000), + SPH_C32(0x36715d27), SPH_C32(0x30495c92), SPH_C32(0xf11336a7), + SPH_C32(0xfe1cdc7f) }, + { SPH_C32(0x9b060002), SPH_C32(0x61468000), SPH_C32(0x221e0000), + SPH_C32(0x1d740000), SPH_C32(0x36715d27), SPH_C32(0x30495c92), + SPH_C32(0xf11336a7), SPH_C32(0xfe1cdc7f), SPH_C32(0x75c90003), + SPH_C32(0x0e10c000), SPH_C32(0xd1200000), SPH_C32(0xbaea0000), + SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), SPH_C32(0xbb28761d), + SPH_C32(0x00b72e2b) }, + { SPH_C32(0xf6800005), SPH_C32(0x3443c000), SPH_C32(0x24070000), + SPH_C32(0x8f3d0000), SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), + SPH_C32(0xcdc58b19), SPH_C32(0xd795ba31), SPH_C32(0xa67f0001), + SPH_C32(0x71378000), SPH_C32(0x19fc0000), SPH_C32(0x96db0000), + SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), SPH_C32(0x2c6d478f), + SPH_C32(0xac8e6c88) }, + { SPH_C32(0x83490006), SPH_C32(0x3a530000), SPH_C32(0xf5270000), + SPH_C32(0x35d70000), SPH_C32(0xaaf314c5), SPH_C32(0x8de062f9), + SPH_C32(0x76edfd04), SPH_C32(0xd722941a), SPH_C32(0x48b00000), + SPH_C32(0x1e61c000), SPH_C32(0xeac20000), SPH_C32(0x31450000), + SPH_C32(0x873e1fe4), SPH_C32(0x5cdb4536), SPH_C32(0x66560735), + SPH_C32(0x52259edc) }, + { SPH_C32(0x184f0004), SPH_C32(0x5b158000), SPH_C32(0xd7390000), + SPH_C32(0x28a30000), SPH_C32(0x9c8249e2), SPH_C32(0xbda93e6b), + SPH_C32(0x87fecba3), SPH_C32(0x293e4865), SPH_C32(0x3d790003), + SPH_C32(0x10710000), SPH_C32(0x3be20000), SPH_C32(0x8baf0000), + SPH_C32(0x0cfa30da), SPH_C32(0xdb83f261), SPH_C32(0xdd7e7128), + SPH_C32(0x5292b0f7) }, + { SPH_C32(0x6d860007), SPH_C32(0x55054000), SPH_C32(0x06190000), + SPH_C32(0x92490000), SPH_C32(0x174666dc), SPH_C32(0x3af1893c), + SPH_C32(0x3cd6bdbe), SPH_C32(0x2989664e), SPH_C32(0xd3b60002), + SPH_C32(0x7f274000), SPH_C32(0xc8dc0000), SPH_C32(0x2c310000), + SPH_C32(0xb14f42c3), SPH_C32(0x6c9219a4), SPH_C32(0x97453192), + SPH_C32(0xac3942a3) }, + { SPH_C32(0xa67f0001), SPH_C32(0x71378000), SPH_C32(0x19fc0000), + SPH_C32(0x96db0000), SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), + SPH_C32(0x2c6d478f), SPH_C32(0xac8e6c88), SPH_C32(0x50ff0004), + SPH_C32(0x45744000), SPH_C32(0x3dfb0000), SPH_C32(0x19e60000), + SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), SPH_C32(0xe1a8cc96), + SPH_C32(0x7b1bd6b9) }, + { SPH_C32(0xd3b60002), SPH_C32(0x7f274000), SPH_C32(0xc8dc0000), + SPH_C32(0x2c310000), SPH_C32(0xb14f42c3), SPH_C32(0x6c9219a4), + SPH_C32(0x97453192), SPH_C32(0xac3942a3), SPH_C32(0xbe300005), + SPH_C32(0x2a220000), SPH_C32(0xcec50000), SPH_C32(0xbe780000), + SPH_C32(0xa609241f), SPH_C32(0x56639098), SPH_C32(0xab938c2c), + SPH_C32(0x85b024ed) }, + { SPH_C32(0x48b00000), SPH_C32(0x1e61c000), SPH_C32(0xeac20000), + SPH_C32(0x31450000), SPH_C32(0x873e1fe4), SPH_C32(0x5cdb4536), + SPH_C32(0x66560735), SPH_C32(0x52259edc), SPH_C32(0xcbf90006), + SPH_C32(0x2432c000), SPH_C32(0x1fe50000), SPH_C32(0x04920000), + SPH_C32(0x2dcd0b21), SPH_C32(0xd13b27cf), SPH_C32(0x10bbfa31), + SPH_C32(0x85070ac6) }, + { SPH_C32(0x3d790003), SPH_C32(0x10710000), SPH_C32(0x3be20000), + SPH_C32(0x8baf0000), SPH_C32(0x0cfa30da), SPH_C32(0xdb83f261), + SPH_C32(0xdd7e7128), SPH_C32(0x5292b0f7), SPH_C32(0x25360007), + SPH_C32(0x4b648000), SPH_C32(0xecdb0000), SPH_C32(0xa30c0000), + SPH_C32(0x90787938), SPH_C32(0x662acc0a), SPH_C32(0x5a80ba8b), + SPH_C32(0x7bacf892) }, + { SPH_C32(0x50ff0004), SPH_C32(0x45744000), SPH_C32(0x3dfb0000), + SPH_C32(0x19e60000), SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), + SPH_C32(0xe1a8cc96), SPH_C32(0x7b1bd6b9), SPH_C32(0xf6800005), + SPH_C32(0x3443c000), SPH_C32(0x24070000), SPH_C32(0x8f3d0000), + SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), SPH_C32(0xcdc58b19), + SPH_C32(0xd795ba31) }, + { SPH_C32(0x25360007), SPH_C32(0x4b648000), SPH_C32(0xecdb0000), + SPH_C32(0xa30c0000), SPH_C32(0x90787938), SPH_C32(0x662acc0a), + SPH_C32(0x5a80ba8b), SPH_C32(0x7bacf892), SPH_C32(0x184f0004), + SPH_C32(0x5b158000), SPH_C32(0xd7390000), SPH_C32(0x28a30000), + SPH_C32(0x9c8249e2), SPH_C32(0xbda93e6b), SPH_C32(0x87fecba3), + SPH_C32(0x293e4865) }, + { SPH_C32(0xbe300005), SPH_C32(0x2a220000), SPH_C32(0xcec50000), + SPH_C32(0xbe780000), SPH_C32(0xa609241f), SPH_C32(0x56639098), + SPH_C32(0xab938c2c), SPH_C32(0x85b024ed), SPH_C32(0x6d860007), + SPH_C32(0x55054000), SPH_C32(0x06190000), SPH_C32(0x92490000), + SPH_C32(0x174666dc), SPH_C32(0x3af1893c), SPH_C32(0x3cd6bdbe), + SPH_C32(0x2989664e) }, + { SPH_C32(0xcbf90006), SPH_C32(0x2432c000), SPH_C32(0x1fe50000), + SPH_C32(0x04920000), SPH_C32(0x2dcd0b21), SPH_C32(0xd13b27cf), + SPH_C32(0x10bbfa31), SPH_C32(0x85070ac6), SPH_C32(0x83490006), + SPH_C32(0x3a530000), SPH_C32(0xf5270000), SPH_C32(0x35d70000), + SPH_C32(0xaaf314c5), SPH_C32(0x8de062f9), SPH_C32(0x76edfd04), + SPH_C32(0xd722941a) }, + { SPH_C32(0xf7750009), SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), + SPH_C32(0x04920000), SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), + SPH_C32(0x7a87f14e), SPH_C32(0x9e16981a), SPH_C32(0xd46a0000), + SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), SPH_C32(0x4a290000), + SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), SPH_C32(0x98369604), + SPH_C32(0xf746c320) }, + { SPH_C32(0x82bc000a), SPH_C32(0xc12c0000), SPH_C32(0x12f60000), + SPH_C32(0xbe780000), SPH_C32(0x89513697), SPH_C32(0x7fb081ed), + SPH_C32(0xc1af8753), SPH_C32(0x9ea1b631), SPH_C32(0x3aa50001), + SPH_C32(0xe29e8000), SPH_C32(0x56910000), SPH_C32(0xedb70000), + SPH_C32(0x41fb3063), SPH_C32(0x7ea56da9), SPH_C32(0xd20dd6be), + SPH_C32(0x09ed3174) }, + { SPH_C32(0x19ba0008), SPH_C32(0xa06a8000), SPH_C32(0x30e80000), + SPH_C32(0xa30c0000), SPH_C32(0xbf206bb0), SPH_C32(0x4ff9dd7f), + SPH_C32(0x30bcb1f4), SPH_C32(0x60bd6a4e), SPH_C32(0x4f6c0002), + SPH_C32(0xec8e4000), SPH_C32(0x87b10000), SPH_C32(0x575d0000), + SPH_C32(0xca3f1f5d), SPH_C32(0xf9fddafe), SPH_C32(0x6925a0a3), + SPH_C32(0x095a1f5f) }, + { SPH_C32(0x6c73000b), SPH_C32(0xae7a4000), SPH_C32(0xe1c80000), + SPH_C32(0x19e60000), SPH_C32(0x34e4448e), SPH_C32(0xc8a16a28), + SPH_C32(0x8b94c7e9), SPH_C32(0x600a4465), SPH_C32(0xa1a30003), + SPH_C32(0x83d80000), SPH_C32(0x748f0000), SPH_C32(0xf0c30000), + SPH_C32(0x778a6d44), SPH_C32(0x4eec313b), SPH_C32(0x231ee019), + SPH_C32(0xf7f1ed0b) }, + { SPH_C32(0x01f5000c), SPH_C32(0xfb7f0000), SPH_C32(0xe7d10000), + SPH_C32(0x8baf0000), SPH_C32(0x23a22252), SPH_C32(0xf250e314), + SPH_C32(0xb7427a57), SPH_C32(0x4983222b), SPH_C32(0x72150001), + SPH_C32(0xfcff4000), SPH_C32(0xbc530000), SPH_C32(0xdcf20000), + SPH_C32(0xc6c52f87), SPH_C32(0x227e289f), SPH_C32(0xb45bd18b), + SPH_C32(0x5bc8afa8) }, + { SPH_C32(0x743c000f), SPH_C32(0xf56fc000), SPH_C32(0x36f10000), + SPH_C32(0x31450000), SPH_C32(0xa8660d6c), SPH_C32(0x75085443), + SPH_C32(0x0c6a0c4a), SPH_C32(0x49340c00), SPH_C32(0x9cda0000), + SPH_C32(0x93a90000), SPH_C32(0x4f6d0000), SPH_C32(0x7b6c0000), + SPH_C32(0x7b705d9e), SPH_C32(0x956fc35a), SPH_C32(0xfe609131), + SPH_C32(0xa5635dfc) }, + { SPH_C32(0xef3a000d), SPH_C32(0x94294000), SPH_C32(0x14ef0000), + SPH_C32(0x2c310000), SPH_C32(0x9e17504b), SPH_C32(0x454108d1), + SPH_C32(0xfd793aed), SPH_C32(0xb728d07f), SPH_C32(0xe9130003), + SPH_C32(0x9db9c000), SPH_C32(0x9e4d0000), SPH_C32(0xc1860000), + SPH_C32(0xf0b472a0), SPH_C32(0x1237740d), SPH_C32(0x4548e72c), + SPH_C32(0xa5d473d7) }, + { SPH_C32(0x9af3000e), SPH_C32(0x9a398000), SPH_C32(0xc5cf0000), + SPH_C32(0x96db0000), SPH_C32(0x15d37f75), SPH_C32(0xc219bf86), + SPH_C32(0x46514cf0), SPH_C32(0xb79ffe54), SPH_C32(0x07dc0002), + SPH_C32(0xf2ef8000), SPH_C32(0x6d730000), SPH_C32(0x66180000), + SPH_C32(0x4d0100b9), SPH_C32(0xa5269fc8), SPH_C32(0x0f73a796), + SPH_C32(0x5b7f8183) }, + { SPH_C32(0x510a0008), SPH_C32(0xbe0b4000), SPH_C32(0xda2a0000), + SPH_C32(0x92490000), SPH_C32(0x381e7454), SPH_C32(0x13229849), + SPH_C32(0x56eab6c1), SPH_C32(0x3298f492), SPH_C32(0x84950004), + SPH_C32(0xc8bc8000), SPH_C32(0x98540000), SPH_C32(0x53cf0000), + SPH_C32(0xe7f2147c), SPH_C32(0x28c6fd31), SPH_C32(0x799e5a92), + SPH_C32(0x8c5d1599) }, + { SPH_C32(0x24c3000b), SPH_C32(0xb01b8000), SPH_C32(0x0b0a0000), + SPH_C32(0x28a30000), SPH_C32(0xb3da5b6a), SPH_C32(0x947a2f1e), + SPH_C32(0xedc2c0dc), SPH_C32(0x322fdab9), SPH_C32(0x6a5a0005), + SPH_C32(0xa7eac000), SPH_C32(0x6b6a0000), SPH_C32(0xf4510000), + SPH_C32(0x5a476665), SPH_C32(0x9fd716f4), SPH_C32(0x33a51a28), + SPH_C32(0x72f6e7cd) }, + { SPH_C32(0xbfc50009), SPH_C32(0xd15d0000), SPH_C32(0x29140000), + SPH_C32(0x35d70000), SPH_C32(0x85ab064d), SPH_C32(0xa433738c), + SPH_C32(0x1cd1f67b), SPH_C32(0xcc3306c6), SPH_C32(0x1f930006), + SPH_C32(0xa9fa0000), SPH_C32(0xba4a0000), SPH_C32(0x4ebb0000), + SPH_C32(0xd183495b), SPH_C32(0x188fa1a3), SPH_C32(0x888d6c35), + SPH_C32(0x7241c9e6) }, + { SPH_C32(0xca0c000a), SPH_C32(0xdf4dc000), SPH_C32(0xf8340000), + SPH_C32(0x8f3d0000), SPH_C32(0x0e6f2973), SPH_C32(0x236bc4db), + SPH_C32(0xa7f98066), SPH_C32(0xcc8428ed), SPH_C32(0xf15c0007), + SPH_C32(0xc6ac4000), SPH_C32(0x49740000), SPH_C32(0xe9250000), + SPH_C32(0x6c363b42), SPH_C32(0xaf9e4a66), SPH_C32(0xc2b62c8f), + SPH_C32(0x8cea3bb2) }, + { SPH_C32(0xa78a000d), SPH_C32(0x8a488000), SPH_C32(0xfe2d0000), + SPH_C32(0x1d740000), SPH_C32(0x19294faf), SPH_C32(0x199a4de7), + SPH_C32(0x9b2f3dd8), SPH_C32(0xe50d4ea3), SPH_C32(0x22ea0005), + SPH_C32(0xb98b0000), SPH_C32(0x81a80000), SPH_C32(0xc5140000), + SPH_C32(0xdd797981), SPH_C32(0xc30c53c2), SPH_C32(0x55f31d1d), + SPH_C32(0x20d37911) }, + { SPH_C32(0xd243000e), SPH_C32(0x84584000), SPH_C32(0x2f0d0000), + SPH_C32(0xa79e0000), SPH_C32(0x92ed6091), SPH_C32(0x9ec2fab0), + SPH_C32(0x20074bc5), SPH_C32(0xe5ba6088), SPH_C32(0xcc250004), + SPH_C32(0xd6dd4000), SPH_C32(0x72960000), SPH_C32(0x628a0000), + SPH_C32(0x60cc0b98), SPH_C32(0x741db807), SPH_C32(0x1fc85da7), + SPH_C32(0xde788b45) }, + { SPH_C32(0x4945000c), SPH_C32(0xe51ec000), SPH_C32(0x0d130000), + SPH_C32(0xbaea0000), SPH_C32(0xa49c3db6), SPH_C32(0xae8ba622), + SPH_C32(0xd1147d62), SPH_C32(0x1ba6bcf7), SPH_C32(0xb9ec0007), + SPH_C32(0xd8cd8000), SPH_C32(0xa3b60000), SPH_C32(0xd8600000), + SPH_C32(0xeb0824a6), SPH_C32(0xf3450f50), SPH_C32(0xa4e02bba), + SPH_C32(0xdecfa56e) }, + { SPH_C32(0x3c8c000f), SPH_C32(0xeb0e0000), SPH_C32(0xdc330000), + SPH_C32(0x00000000), SPH_C32(0x2f581288), SPH_C32(0x29d31175), + SPH_C32(0x6a3c0b7f), SPH_C32(0x1b1192dc), SPH_C32(0x57230006), + SPH_C32(0xb79bc000), SPH_C32(0x50880000), SPH_C32(0x7ffe0000), + SPH_C32(0x56bd56bf), SPH_C32(0x4454e495), SPH_C32(0xeedb6b00), + SPH_C32(0x2064573a) }, + { SPH_C32(0xd46a0000), SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), + SPH_C32(0x4a290000), SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), + SPH_C32(0x98369604), SPH_C32(0xf746c320), SPH_C32(0x231f0009), + SPH_C32(0x42f40000), SPH_C32(0x66790000), SPH_C32(0x4ebb0000), + SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), SPH_C32(0xe2b1674a), + SPH_C32(0x69505b3a) }, + { SPH_C32(0xa1a30003), SPH_C32(0x83d80000), SPH_C32(0x748f0000), + SPH_C32(0xf0c30000), SPH_C32(0x778a6d44), SPH_C32(0x4eec313b), + SPH_C32(0x231ee019), SPH_C32(0xf7f1ed0b), SPH_C32(0xcdd00008), + SPH_C32(0x2da24000), SPH_C32(0x95470000), SPH_C32(0xe9250000), + SPH_C32(0x436e29ca), SPH_C32(0x864d5b13), SPH_C32(0xa88a27f0), + SPH_C32(0x97fba96e) }, + { SPH_C32(0x3aa50001), SPH_C32(0xe29e8000), SPH_C32(0x56910000), + SPH_C32(0xedb70000), SPH_C32(0x41fb3063), SPH_C32(0x7ea56da9), + SPH_C32(0xd20dd6be), SPH_C32(0x09ed3174), SPH_C32(0xb819000b), + SPH_C32(0x23b28000), SPH_C32(0x44670000), SPH_C32(0x53cf0000), + SPH_C32(0xc8aa06f4), SPH_C32(0x0115ec44), SPH_C32(0x13a251ed), + SPH_C32(0x974c8745) }, + { SPH_C32(0x4f6c0002), SPH_C32(0xec8e4000), SPH_C32(0x87b10000), + SPH_C32(0x575d0000), SPH_C32(0xca3f1f5d), SPH_C32(0xf9fddafe), + SPH_C32(0x6925a0a3), SPH_C32(0x095a1f5f), SPH_C32(0x56d6000a), + SPH_C32(0x4ce4c000), SPH_C32(0xb7590000), SPH_C32(0xf4510000), + SPH_C32(0x751f74ed), SPH_C32(0xb6040781), SPH_C32(0x59991157), + SPH_C32(0x69e77511) }, + { SPH_C32(0x22ea0005), SPH_C32(0xb98b0000), SPH_C32(0x81a80000), + SPH_C32(0xc5140000), SPH_C32(0xdd797981), SPH_C32(0xc30c53c2), + SPH_C32(0x55f31d1d), SPH_C32(0x20d37911), SPH_C32(0x85600008), + SPH_C32(0x33c38000), SPH_C32(0x7f850000), SPH_C32(0xd8600000), + SPH_C32(0xc450362e), SPH_C32(0xda961e25), SPH_C32(0xcedc20c5), + SPH_C32(0xc5de37b2) }, + { SPH_C32(0x57230006), SPH_C32(0xb79bc000), SPH_C32(0x50880000), + SPH_C32(0x7ffe0000), SPH_C32(0x56bd56bf), SPH_C32(0x4454e495), + SPH_C32(0xeedb6b00), SPH_C32(0x2064573a), SPH_C32(0x6baf0009), + SPH_C32(0x5c95c000), SPH_C32(0x8cbb0000), SPH_C32(0x7ffe0000), + SPH_C32(0x79e54437), SPH_C32(0x6d87f5e0), SPH_C32(0x84e7607f), + SPH_C32(0x3b75c5e6) }, + { SPH_C32(0xcc250004), SPH_C32(0xd6dd4000), SPH_C32(0x72960000), + SPH_C32(0x628a0000), SPH_C32(0x60cc0b98), SPH_C32(0x741db807), + SPH_C32(0x1fc85da7), SPH_C32(0xde788b45), SPH_C32(0x1e66000a), + SPH_C32(0x52850000), SPH_C32(0x5d9b0000), SPH_C32(0xc5140000), + SPH_C32(0xf2216b09), SPH_C32(0xeadf42b7), SPH_C32(0x3fcf1662), + SPH_C32(0x3bc2ebcd) }, + { SPH_C32(0xb9ec0007), SPH_C32(0xd8cd8000), SPH_C32(0xa3b60000), + SPH_C32(0xd8600000), SPH_C32(0xeb0824a6), SPH_C32(0xf3450f50), + SPH_C32(0xa4e02bba), SPH_C32(0xdecfa56e), SPH_C32(0xf0a9000b), + SPH_C32(0x3dd34000), SPH_C32(0xaea50000), SPH_C32(0x628a0000), + SPH_C32(0x4f941910), SPH_C32(0x5dcea972), SPH_C32(0x75f456d8), + SPH_C32(0xc5691999) }, + { SPH_C32(0x72150001), SPH_C32(0xfcff4000), SPH_C32(0xbc530000), + SPH_C32(0xdcf20000), SPH_C32(0xc6c52f87), SPH_C32(0x227e289f), + SPH_C32(0xb45bd18b), SPH_C32(0x5bc8afa8), SPH_C32(0x73e0000d), + SPH_C32(0x07804000), SPH_C32(0x5b820000), SPH_C32(0x575d0000), + SPH_C32(0xe5670dd5), SPH_C32(0xd02ecb8b), SPH_C32(0x0319abdc), + SPH_C32(0x124b8d83) }, + { SPH_C32(0x07dc0002), SPH_C32(0xf2ef8000), SPH_C32(0x6d730000), + SPH_C32(0x66180000), SPH_C32(0x4d0100b9), SPH_C32(0xa5269fc8), + SPH_C32(0x0f73a796), SPH_C32(0x5b7f8183), SPH_C32(0x9d2f000c), + SPH_C32(0x68d60000), SPH_C32(0xa8bc0000), SPH_C32(0xf0c30000), + SPH_C32(0x58d27fcc), SPH_C32(0x673f204e), SPH_C32(0x4922eb66), + SPH_C32(0xece07fd7) }, + { SPH_C32(0x9cda0000), SPH_C32(0x93a90000), SPH_C32(0x4f6d0000), + SPH_C32(0x7b6c0000), SPH_C32(0x7b705d9e), SPH_C32(0x956fc35a), + SPH_C32(0xfe609131), SPH_C32(0xa5635dfc), SPH_C32(0xe8e6000f), + SPH_C32(0x66c6c000), SPH_C32(0x799c0000), SPH_C32(0x4a290000), + SPH_C32(0xd31650f2), SPH_C32(0xe0679719), SPH_C32(0xf20a9d7b), + SPH_C32(0xec5751fc) }, + { SPH_C32(0xe9130003), SPH_C32(0x9db9c000), SPH_C32(0x9e4d0000), + SPH_C32(0xc1860000), SPH_C32(0xf0b472a0), SPH_C32(0x1237740d), + SPH_C32(0x4548e72c), SPH_C32(0xa5d473d7), SPH_C32(0x0629000e), + SPH_C32(0x09908000), SPH_C32(0x8aa20000), SPH_C32(0xedb70000), + SPH_C32(0x6ea322eb), SPH_C32(0x57767cdc), SPH_C32(0xb831ddc1), + SPH_C32(0x12fca3a8) }, + { SPH_C32(0x84950004), SPH_C32(0xc8bc8000), SPH_C32(0x98540000), + SPH_C32(0x53cf0000), SPH_C32(0xe7f2147c), SPH_C32(0x28c6fd31), + SPH_C32(0x799e5a92), SPH_C32(0x8c5d1599), SPH_C32(0xd59f000c), + SPH_C32(0x76b7c000), SPH_C32(0x427e0000), SPH_C32(0xc1860000), + SPH_C32(0xdfec6028), SPH_C32(0x3be46578), SPH_C32(0x2f74ec53), + SPH_C32(0xbec5e10b) }, + { SPH_C32(0xf15c0007), SPH_C32(0xc6ac4000), SPH_C32(0x49740000), + SPH_C32(0xe9250000), SPH_C32(0x6c363b42), SPH_C32(0xaf9e4a66), + SPH_C32(0xc2b62c8f), SPH_C32(0x8cea3bb2), SPH_C32(0x3b50000d), + SPH_C32(0x19e18000), SPH_C32(0xb1400000), SPH_C32(0x66180000), + SPH_C32(0x62591231), SPH_C32(0x8cf58ebd), SPH_C32(0x654face9), + SPH_C32(0x406e135f) }, + { SPH_C32(0x6a5a0005), SPH_C32(0xa7eac000), SPH_C32(0x6b6a0000), + SPH_C32(0xf4510000), SPH_C32(0x5a476665), SPH_C32(0x9fd716f4), + SPH_C32(0x33a51a28), SPH_C32(0x72f6e7cd), SPH_C32(0x4e99000e), + SPH_C32(0x17f14000), SPH_C32(0x60600000), SPH_C32(0xdcf20000), + SPH_C32(0xe99d3d0f), SPH_C32(0x0bad39ea), SPH_C32(0xde67daf4), + SPH_C32(0x40d93d74) }, + { SPH_C32(0x1f930006), SPH_C32(0xa9fa0000), SPH_C32(0xba4a0000), + SPH_C32(0x4ebb0000), SPH_C32(0xd183495b), SPH_C32(0x188fa1a3), + SPH_C32(0x888d6c35), SPH_C32(0x7241c9e6), SPH_C32(0xa056000f), + SPH_C32(0x78a70000), SPH_C32(0x935e0000), SPH_C32(0x7b6c0000), + SPH_C32(0x54284f16), SPH_C32(0xbcbcd22f), SPH_C32(0x945c9a4e), + SPH_C32(0xbe72cf20) }, + { SPH_C32(0x231f0009), SPH_C32(0x42f40000), SPH_C32(0x66790000), + SPH_C32(0x4ebb0000), SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), + SPH_C32(0xe2b1674a), SPH_C32(0x69505b3a), SPH_C32(0xf7750009), + SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), SPH_C32(0x04920000), + SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), SPH_C32(0x7a87f14e), + SPH_C32(0x9e16981a) }, + { SPH_C32(0x56d6000a), SPH_C32(0x4ce4c000), SPH_C32(0xb7590000), + SPH_C32(0xf4510000), SPH_C32(0x751f74ed), SPH_C32(0xb6040781), + SPH_C32(0x59991157), SPH_C32(0x69e77511), SPH_C32(0x19ba0008), + SPH_C32(0xa06a8000), SPH_C32(0x30e80000), SPH_C32(0xa30c0000), + SPH_C32(0xbf206bb0), SPH_C32(0x4ff9dd7f), SPH_C32(0x30bcb1f4), + SPH_C32(0x60bd6a4e) }, + { SPH_C32(0xcdd00008), SPH_C32(0x2da24000), SPH_C32(0x95470000), + SPH_C32(0xe9250000), SPH_C32(0x436e29ca), SPH_C32(0x864d5b13), + SPH_C32(0xa88a27f0), SPH_C32(0x97fba96e), SPH_C32(0x6c73000b), + SPH_C32(0xae7a4000), SPH_C32(0xe1c80000), SPH_C32(0x19e60000), + SPH_C32(0x34e4448e), SPH_C32(0xc8a16a28), SPH_C32(0x8b94c7e9), + SPH_C32(0x600a4465) }, + { SPH_C32(0xb819000b), SPH_C32(0x23b28000), SPH_C32(0x44670000), + SPH_C32(0x53cf0000), SPH_C32(0xc8aa06f4), SPH_C32(0x0115ec44), + SPH_C32(0x13a251ed), SPH_C32(0x974c8745), SPH_C32(0x82bc000a), + SPH_C32(0xc12c0000), SPH_C32(0x12f60000), SPH_C32(0xbe780000), + SPH_C32(0x89513697), SPH_C32(0x7fb081ed), SPH_C32(0xc1af8753), + SPH_C32(0x9ea1b631) }, + { SPH_C32(0xd59f000c), SPH_C32(0x76b7c000), SPH_C32(0x427e0000), + SPH_C32(0xc1860000), SPH_C32(0xdfec6028), SPH_C32(0x3be46578), + SPH_C32(0x2f74ec53), SPH_C32(0xbec5e10b), SPH_C32(0x510a0008), + SPH_C32(0xbe0b4000), SPH_C32(0xda2a0000), SPH_C32(0x92490000), + SPH_C32(0x381e7454), SPH_C32(0x13229849), SPH_C32(0x56eab6c1), + SPH_C32(0x3298f492) }, + { SPH_C32(0xa056000f), SPH_C32(0x78a70000), SPH_C32(0x935e0000), + SPH_C32(0x7b6c0000), SPH_C32(0x54284f16), SPH_C32(0xbcbcd22f), + SPH_C32(0x945c9a4e), SPH_C32(0xbe72cf20), SPH_C32(0xbfc50009), + SPH_C32(0xd15d0000), SPH_C32(0x29140000), SPH_C32(0x35d70000), + SPH_C32(0x85ab064d), SPH_C32(0xa433738c), SPH_C32(0x1cd1f67b), + SPH_C32(0xcc3306c6) }, + { SPH_C32(0x3b50000d), SPH_C32(0x19e18000), SPH_C32(0xb1400000), + SPH_C32(0x66180000), SPH_C32(0x62591231), SPH_C32(0x8cf58ebd), + SPH_C32(0x654face9), SPH_C32(0x406e135f), SPH_C32(0xca0c000a), + SPH_C32(0xdf4dc000), SPH_C32(0xf8340000), SPH_C32(0x8f3d0000), + SPH_C32(0x0e6f2973), SPH_C32(0x236bc4db), SPH_C32(0xa7f98066), + SPH_C32(0xcc8428ed) }, + { SPH_C32(0x4e99000e), SPH_C32(0x17f14000), SPH_C32(0x60600000), + SPH_C32(0xdcf20000), SPH_C32(0xe99d3d0f), SPH_C32(0x0bad39ea), + SPH_C32(0xde67daf4), SPH_C32(0x40d93d74), SPH_C32(0x24c3000b), + SPH_C32(0xb01b8000), SPH_C32(0x0b0a0000), SPH_C32(0x28a30000), + SPH_C32(0xb3da5b6a), SPH_C32(0x947a2f1e), SPH_C32(0xedc2c0dc), + SPH_C32(0x322fdab9) }, + { SPH_C32(0x85600008), SPH_C32(0x33c38000), SPH_C32(0x7f850000), + SPH_C32(0xd8600000), SPH_C32(0xc450362e), SPH_C32(0xda961e25), + SPH_C32(0xcedc20c5), SPH_C32(0xc5de37b2), SPH_C32(0xa78a000d), + SPH_C32(0x8a488000), SPH_C32(0xfe2d0000), SPH_C32(0x1d740000), + SPH_C32(0x19294faf), SPH_C32(0x199a4de7), SPH_C32(0x9b2f3dd8), + SPH_C32(0xe50d4ea3) }, + { SPH_C32(0xf0a9000b), SPH_C32(0x3dd34000), SPH_C32(0xaea50000), + SPH_C32(0x628a0000), SPH_C32(0x4f941910), SPH_C32(0x5dcea972), + SPH_C32(0x75f456d8), SPH_C32(0xc5691999), SPH_C32(0x4945000c), + SPH_C32(0xe51ec000), SPH_C32(0x0d130000), SPH_C32(0xbaea0000), + SPH_C32(0xa49c3db6), SPH_C32(0xae8ba622), SPH_C32(0xd1147d62), + SPH_C32(0x1ba6bcf7) }, + { SPH_C32(0x6baf0009), SPH_C32(0x5c95c000), SPH_C32(0x8cbb0000), + SPH_C32(0x7ffe0000), SPH_C32(0x79e54437), SPH_C32(0x6d87f5e0), + SPH_C32(0x84e7607f), SPH_C32(0x3b75c5e6), SPH_C32(0x3c8c000f), + SPH_C32(0xeb0e0000), SPH_C32(0xdc330000), SPH_C32(0x00000000), + SPH_C32(0x2f581288), SPH_C32(0x29d31175), SPH_C32(0x6a3c0b7f), + SPH_C32(0x1b1192dc) }, + { SPH_C32(0x1e66000a), SPH_C32(0x52850000), SPH_C32(0x5d9b0000), + SPH_C32(0xc5140000), SPH_C32(0xf2216b09), SPH_C32(0xeadf42b7), + SPH_C32(0x3fcf1662), SPH_C32(0x3bc2ebcd), SPH_C32(0xd243000e), + SPH_C32(0x84584000), SPH_C32(0x2f0d0000), SPH_C32(0xa79e0000), + SPH_C32(0x92ed6091), SPH_C32(0x9ec2fab0), SPH_C32(0x20074bc5), + SPH_C32(0xe5ba6088) }, + { SPH_C32(0x73e0000d), SPH_C32(0x07804000), SPH_C32(0x5b820000), + SPH_C32(0x575d0000), SPH_C32(0xe5670dd5), SPH_C32(0xd02ecb8b), + SPH_C32(0x0319abdc), SPH_C32(0x124b8d83), SPH_C32(0x01f5000c), + SPH_C32(0xfb7f0000), SPH_C32(0xe7d10000), SPH_C32(0x8baf0000), + SPH_C32(0x23a22252), SPH_C32(0xf250e314), SPH_C32(0xb7427a57), + SPH_C32(0x4983222b) }, + { SPH_C32(0x0629000e), SPH_C32(0x09908000), SPH_C32(0x8aa20000), + SPH_C32(0xedb70000), SPH_C32(0x6ea322eb), SPH_C32(0x57767cdc), + SPH_C32(0xb831ddc1), SPH_C32(0x12fca3a8), SPH_C32(0xef3a000d), + SPH_C32(0x94294000), SPH_C32(0x14ef0000), SPH_C32(0x2c310000), + SPH_C32(0x9e17504b), SPH_C32(0x454108d1), SPH_C32(0xfd793aed), + SPH_C32(0xb728d07f) }, + { SPH_C32(0x9d2f000c), SPH_C32(0x68d60000), SPH_C32(0xa8bc0000), + SPH_C32(0xf0c30000), SPH_C32(0x58d27fcc), SPH_C32(0x673f204e), + SPH_C32(0x4922eb66), SPH_C32(0xece07fd7), SPH_C32(0x9af3000e), + SPH_C32(0x9a398000), SPH_C32(0xc5cf0000), SPH_C32(0x96db0000), + SPH_C32(0x15d37f75), SPH_C32(0xc219bf86), SPH_C32(0x46514cf0), + SPH_C32(0xb79ffe54) }, + { SPH_C32(0xe8e6000f), SPH_C32(0x66c6c000), SPH_C32(0x799c0000), + SPH_C32(0x4a290000), SPH_C32(0xd31650f2), SPH_C32(0xe0679719), + SPH_C32(0xf20a9d7b), SPH_C32(0xec5751fc), SPH_C32(0x743c000f), + SPH_C32(0xf56fc000), SPH_C32(0x36f10000), SPH_C32(0x31450000), + SPH_C32(0xa8660d6c), SPH_C32(0x75085443), SPH_C32(0x0c6a0c4a), + SPH_C32(0x49340c00) } +}; + +static const sph_u32 T512_18[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x0c720000), SPH_C32(0x49e50f00), SPH_C32(0x42790000), + SPH_C32(0x5cea0000), SPH_C32(0x33aa301a), SPH_C32(0x15822514), + SPH_C32(0x95a34b7b), SPH_C32(0xb44b0090), SPH_C32(0xfe220000), + SPH_C32(0xa7580500), SPH_C32(0x25d10000), SPH_C32(0xf7600000), + SPH_C32(0x893178da), SPH_C32(0x1fd4f860), SPH_C32(0x4ed0a315), + SPH_C32(0xa123ff9f) }, + { SPH_C32(0xfe220000), SPH_C32(0xa7580500), SPH_C32(0x25d10000), + SPH_C32(0xf7600000), SPH_C32(0x893178da), SPH_C32(0x1fd4f860), + SPH_C32(0x4ed0a315), SPH_C32(0xa123ff9f), SPH_C32(0xf2500000), + SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), SPH_C32(0xab8a0000), + SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), SPH_C32(0xdb73e86e), + SPH_C32(0x1568ff0f) }, + { SPH_C32(0xf2500000), SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), + SPH_C32(0xab8a0000), SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), + SPH_C32(0xdb73e86e), SPH_C32(0x1568ff0f), SPH_C32(0x0c720000), + SPH_C32(0x49e50f00), SPH_C32(0x42790000), SPH_C32(0x5cea0000), + SPH_C32(0x33aa301a), SPH_C32(0x15822514), SPH_C32(0x95a34b7b), + SPH_C32(0xb44b0090) }, + { SPH_C32(0x45180000), SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), + SPH_C32(0x3b480000), SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), + SPH_C32(0x16bca6b0), SPH_C32(0xdf33f4df), SPH_C32(0xb83d0000), + SPH_C32(0x16710600), SPH_C32(0x379a0000), SPH_C32(0xf5b10000), + SPH_C32(0x228161ac), SPH_C32(0xae48f145), SPH_C32(0x66241616), + SPH_C32(0xc5c1eb3e) }, + { SPH_C32(0x496a0000), SPH_C32(0xec501800), SPH_C32(0xbb130000), + SPH_C32(0x67a20000), SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), + SPH_C32(0x831fedcb), SPH_C32(0x6b78f44f), SPH_C32(0x461f0000), + SPH_C32(0xb1290300), SPH_C32(0x124b0000), SPH_C32(0x02d10000), + SPH_C32(0xabb01976), SPH_C32(0xb19c0925), SPH_C32(0x28f4b503), + SPH_C32(0x64e214a1) }, + { SPH_C32(0xbb3a0000), SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), + SPH_C32(0xcc280000), SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), + SPH_C32(0x586c05a5), SPH_C32(0x7e100b40), SPH_C32(0x4a6d0000), + SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), SPH_C32(0x5e3b0000), + SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), SPH_C32(0xbd57fe78), + SPH_C32(0xd0a91431) }, + { SPH_C32(0xb7480000), SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), + SPH_C32(0x90c20000), SPH_C32(0xa4575cec), SPH_C32(0x294548a2), + SPH_C32(0xcdcf4ede), SPH_C32(0xca5b0bd0), SPH_C32(0xb44f0000), + SPH_C32(0x5f940900), SPH_C32(0x75e30000), SPH_C32(0xa95b0000), + SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), SPH_C32(0xf3875d6d), + SPH_C32(0x718aebae) }, + { SPH_C32(0xb83d0000), SPH_C32(0x16710600), SPH_C32(0x379a0000), + SPH_C32(0xf5b10000), SPH_C32(0x228161ac), SPH_C32(0xae48f145), + SPH_C32(0x66241616), SPH_C32(0xc5c1eb3e), SPH_C32(0xfd250000), + SPH_C32(0xb3c41100), SPH_C32(0xcef00000), SPH_C32(0xcef90000), + SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), SPH_C32(0x7098b0a6), + SPH_C32(0x1af21fe1) }, + { SPH_C32(0xb44f0000), SPH_C32(0x5f940900), SPH_C32(0x75e30000), + SPH_C32(0xa95b0000), SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), + SPH_C32(0xf3875d6d), SPH_C32(0x718aebae), SPH_C32(0x03070000), + SPH_C32(0x149c1400), SPH_C32(0xeb210000), SPH_C32(0x39990000), + SPH_C32(0xb57c0d5a), SPH_C32(0x928f9cf3), SPH_C32(0x3e4813b3), + SPH_C32(0xbbd1e07e) }, + { SPH_C32(0x461f0000), SPH_C32(0xb1290300), SPH_C32(0x124b0000), + SPH_C32(0x02d10000), SPH_C32(0xabb01976), SPH_C32(0xb19c0925), + SPH_C32(0x28f4b503), SPH_C32(0x64e214a1), SPH_C32(0x0f750000), + SPH_C32(0x5d791b00), SPH_C32(0xa9580000), SPH_C32(0x65730000), + SPH_C32(0x86d63d40), SPH_C32(0x870db9e7), SPH_C32(0xabeb58c8), + SPH_C32(0x0f9ae0ee) }, + { SPH_C32(0x4a6d0000), SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), + SPH_C32(0x5e3b0000), SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), + SPH_C32(0xbd57fe78), SPH_C32(0xd0a91431), SPH_C32(0xf1570000), + SPH_C32(0xfa211e00), SPH_C32(0x8c890000), SPH_C32(0x92130000), + SPH_C32(0x0fe7459a), SPH_C32(0x98d94187), SPH_C32(0xe53bfbdd), + SPH_C32(0xaeb91f71) }, + { SPH_C32(0xfd250000), SPH_C32(0xb3c41100), SPH_C32(0xcef00000), + SPH_C32(0xcef90000), SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), + SPH_C32(0x7098b0a6), SPH_C32(0x1af21fe1), SPH_C32(0x45180000), + SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), SPH_C32(0x3b480000), + SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), SPH_C32(0x16bca6b0), + SPH_C32(0xdf33f4df) }, + { SPH_C32(0xf1570000), SPH_C32(0xfa211e00), SPH_C32(0x8c890000), + SPH_C32(0x92130000), SPH_C32(0x0fe7459a), SPH_C32(0x98d94187), + SPH_C32(0xe53bfbdd), SPH_C32(0xaeb91f71), SPH_C32(0xbb3a0000), + SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), SPH_C32(0xcc280000), + SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), SPH_C32(0x586c05a5), + SPH_C32(0x7e100b40) }, + { SPH_C32(0x03070000), SPH_C32(0x149c1400), SPH_C32(0xeb210000), + SPH_C32(0x39990000), SPH_C32(0xb57c0d5a), SPH_C32(0x928f9cf3), + SPH_C32(0x3e4813b3), SPH_C32(0xbbd1e07e), SPH_C32(0xb7480000), + SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), SPH_C32(0x90c20000), + SPH_C32(0xa4575cec), SPH_C32(0x294548a2), SPH_C32(0xcdcf4ede), + SPH_C32(0xca5b0bd0) }, + { SPH_C32(0x0f750000), SPH_C32(0x5d791b00), SPH_C32(0xa9580000), + SPH_C32(0x65730000), SPH_C32(0x86d63d40), SPH_C32(0x870db9e7), + SPH_C32(0xabeb58c8), SPH_C32(0x0f9ae0ee), SPH_C32(0x496a0000), + SPH_C32(0xec501800), SPH_C32(0xbb130000), SPH_C32(0x67a20000), + SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), SPH_C32(0x831fedcb), + SPH_C32(0x6b78f44f) }, + { SPH_C32(0x75a40000), SPH_C32(0xc28b2700), SPH_C32(0x94a40000), + SPH_C32(0x90f50000), SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), + SPH_C32(0x1767c483), SPH_C32(0xaedf667e), SPH_C32(0xd1660000), + SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), SPH_C32(0xf6940000), + SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), SPH_C32(0xb4431b17), + SPH_C32(0x857f3c2b) }, + { SPH_C32(0x79d60000), SPH_C32(0x8b6e2800), SPH_C32(0xd6dd0000), + SPH_C32(0xcc1f0000), SPH_C32(0xc8d267fa), SPH_C32(0x5c4c2eba), + SPH_C32(0x82c48ff8), SPH_C32(0x1a9466ee), SPH_C32(0x2f440000), + SPH_C32(0xbce40600), SPH_C32(0xbb3d0000), SPH_C32(0x01f40000), + SPH_C32(0x8a333dfd), SPH_C32(0xd0a40492), SPH_C32(0xfa93b802), + SPH_C32(0x245cc3b4) }, + { SPH_C32(0x8b860000), SPH_C32(0x65d32200), SPH_C32(0xb1750000), + SPH_C32(0x67950000), SPH_C32(0x72492f3a), SPH_C32(0x561af3ce), + SPH_C32(0x59b76796), SPH_C32(0x0ffc99e1), SPH_C32(0x23360000), + SPH_C32(0xf5010900), SPH_C32(0xf9440000), SPH_C32(0x5d1e0000), + SPH_C32(0xb9990de7), SPH_C32(0xc5262186), SPH_C32(0x6f30f379), + SPH_C32(0x9017c324) }, + { SPH_C32(0x87f40000), SPH_C32(0x2c362d00), SPH_C32(0xf30c0000), + SPH_C32(0x3b7f0000), SPH_C32(0x41e31f20), SPH_C32(0x4398d6da), + SPH_C32(0xcc142ced), SPH_C32(0xbbb79971), SPH_C32(0xdd140000), + SPH_C32(0x52590c00), SPH_C32(0xdc950000), SPH_C32(0xaa7e0000), + SPH_C32(0x30a8753d), SPH_C32(0xdaf2d9e6), SPH_C32(0x21e0506c), + SPH_C32(0x31343cbb) }, + { SPH_C32(0x30bc0000), SPH_C32(0x673e3000), SPH_C32(0x6dce0000), + SPH_C32(0xabbd0000), SPH_C32(0xe5b443cc), SPH_C32(0x6add9e78), + SPH_C32(0x01db6233), SPH_C32(0x71ec92a1), SPH_C32(0x695b0000), + SPH_C32(0x0dcd0500), SPH_C32(0xa9760000), SPH_C32(0x03250000), + SPH_C32(0x2183248b), SPH_C32(0x61380db7), SPH_C32(0xd2670d01), + SPH_C32(0x40bed715) }, + { SPH_C32(0x3cce0000), SPH_C32(0x2edb3f00), SPH_C32(0x2fb70000), + SPH_C32(0xf7570000), SPH_C32(0xd61e73d6), SPH_C32(0x7f5fbb6c), + SPH_C32(0x94782948), SPH_C32(0xc5a79231), SPH_C32(0x97790000), + SPH_C32(0xaa950000), SPH_C32(0x8ca70000), SPH_C32(0xf4450000), + SPH_C32(0xa8b25c51), SPH_C32(0x7eecf5d7), SPH_C32(0x9cb7ae14), + SPH_C32(0xe19d288a) }, + { SPH_C32(0xce9e0000), SPH_C32(0xc0663500), SPH_C32(0x481f0000), + SPH_C32(0x5cdd0000), SPH_C32(0x6c853b16), SPH_C32(0x75096618), + SPH_C32(0x4f0bc126), SPH_C32(0xd0cf6d3e), SPH_C32(0x9b0b0000), + SPH_C32(0xe3700f00), SPH_C32(0xcede0000), SPH_C32(0xa8af0000), + SPH_C32(0x9b186c4b), SPH_C32(0x6b6ed0c3), SPH_C32(0x0914e56f), + SPH_C32(0x55d6281a) }, + { SPH_C32(0xc2ec0000), SPH_C32(0x89833a00), SPH_C32(0x0a660000), + SPH_C32(0x00370000), SPH_C32(0x5f2f0b0c), SPH_C32(0x608b430c), + SPH_C32(0xdaa88a5d), SPH_C32(0x64846dae), SPH_C32(0x65290000), + SPH_C32(0x44280a00), SPH_C32(0xeb0f0000), SPH_C32(0x5fcf0000), + SPH_C32(0x12291491), SPH_C32(0x74ba28a3), SPH_C32(0x47c4467a), + SPH_C32(0xf4f5d785) }, + { SPH_C32(0xcd990000), SPH_C32(0xd4fa2100), SPH_C32(0xa33e0000), + SPH_C32(0x65440000), SPH_C32(0xd9f9364c), SPH_C32(0xe786faeb), + SPH_C32(0x7143d295), SPH_C32(0x6b1e8d40), SPH_C32(0x2c430000), + SPH_C32(0xa8781200), SPH_C32(0x501c0000), SPH_C32(0x386d0000), + SPH_C32(0x3f4f30a7), SPH_C32(0x422b9861), SPH_C32(0xc4dbabb1), + SPH_C32(0x9f8d23ca) }, + { SPH_C32(0xc1eb0000), SPH_C32(0x9d1f2e00), SPH_C32(0xe1470000), + SPH_C32(0x39ae0000), SPH_C32(0xea530656), SPH_C32(0xf204dfff), + SPH_C32(0xe4e099ee), SPH_C32(0xdf558dd0), SPH_C32(0xd2610000), + SPH_C32(0x0f201700), SPH_C32(0x75cd0000), SPH_C32(0xcf0d0000), + SPH_C32(0xb67e487d), SPH_C32(0x5dff6001), SPH_C32(0x8a0b08a4), + SPH_C32(0x3eaedc55) }, + { SPH_C32(0x33bb0000), SPH_C32(0x73a22400), SPH_C32(0x86ef0000), + SPH_C32(0x92240000), SPH_C32(0x50c84e96), SPH_C32(0xf852028b), + SPH_C32(0x3f937180), SPH_C32(0xca3d72df), SPH_C32(0xde130000), + SPH_C32(0x46c51800), SPH_C32(0x37b40000), SPH_C32(0x93e70000), + SPH_C32(0x85d47867), SPH_C32(0x487d4515), SPH_C32(0x1fa843df), + SPH_C32(0x8ae5dcc5) }, + { SPH_C32(0x3fc90000), SPH_C32(0x3a472b00), SPH_C32(0xc4960000), + SPH_C32(0xcece0000), SPH_C32(0x63627e8c), SPH_C32(0xedd0279f), + SPH_C32(0xaa303afb), SPH_C32(0x7e76724f), SPH_C32(0x20310000), + SPH_C32(0xe19d1d00), SPH_C32(0x12650000), SPH_C32(0x64870000), + SPH_C32(0x0ce500bd), SPH_C32(0x57a9bd75), SPH_C32(0x5178e0ca), + SPH_C32(0x2bc6235a) }, + { SPH_C32(0x88810000), SPH_C32(0x714f3600), SPH_C32(0x5a540000), + SPH_C32(0x5e0c0000), SPH_C32(0xc7352260), SPH_C32(0xc4956f3d), + SPH_C32(0x67ff7425), SPH_C32(0xb42d799f), SPH_C32(0x947e0000), + SPH_C32(0xbe091400), SPH_C32(0x67860000), SPH_C32(0xcddc0000), + SPH_C32(0x1dce510b), SPH_C32(0xec636924), SPH_C32(0xa2ffbda7), + SPH_C32(0x5a4cc8f4) }, + { SPH_C32(0x84f30000), SPH_C32(0x38aa3900), SPH_C32(0x182d0000), + SPH_C32(0x02e60000), SPH_C32(0xf49f127a), SPH_C32(0xd1174a29), + SPH_C32(0xf25c3f5e), SPH_C32(0x0066790f), SPH_C32(0x6a5c0000), + SPH_C32(0x19511100), SPH_C32(0x42570000), SPH_C32(0x3abc0000), + SPH_C32(0x94ff29d1), SPH_C32(0xf3b79144), SPH_C32(0xec2f1eb2), + SPH_C32(0xfb6f376b) }, + { SPH_C32(0x76a30000), SPH_C32(0xd6173300), SPH_C32(0x7f850000), + SPH_C32(0xa96c0000), SPH_C32(0x4e045aba), SPH_C32(0xdb41975d), + SPH_C32(0x292fd730), SPH_C32(0x150e8600), SPH_C32(0x662e0000), + SPH_C32(0x50b41e00), SPH_C32(0x002e0000), SPH_C32(0x66560000), + SPH_C32(0xa75519cb), SPH_C32(0xe635b450), SPH_C32(0x798c55c9), + SPH_C32(0x4f2437fb) }, + { SPH_C32(0x7ad10000), SPH_C32(0x9ff23c00), SPH_C32(0x3dfc0000), + SPH_C32(0xf5860000), SPH_C32(0x7dae6aa0), SPH_C32(0xcec3b249), + SPH_C32(0xbc8c9c4b), SPH_C32(0xa1458690), SPH_C32(0x980c0000), + SPH_C32(0xf7ec1b00), SPH_C32(0x25ff0000), SPH_C32(0x91360000), + SPH_C32(0x2e646111), SPH_C32(0xf9e14c30), SPH_C32(0x375cf6dc), + SPH_C32(0xee07c864) }, + { SPH_C32(0xd1660000), SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), + SPH_C32(0xf6940000), SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), + SPH_C32(0xb4431b17), SPH_C32(0x857f3c2b), SPH_C32(0xa4c20000), + SPH_C32(0xd9372400), SPH_C32(0x0a480000), SPH_C32(0x66610000), + SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), SPH_C32(0xa324df94), + SPH_C32(0x2ba05a55) }, + { SPH_C32(0xdd140000), SPH_C32(0x52590c00), SPH_C32(0xdc950000), + SPH_C32(0xaa7e0000), SPH_C32(0x30a8753d), SPH_C32(0xdaf2d9e6), + SPH_C32(0x21e0506c), SPH_C32(0x31343cbb), SPH_C32(0x5ae00000), + SPH_C32(0x7e6f2100), SPH_C32(0x2f990000), SPH_C32(0x91010000), + SPH_C32(0x714b6a1d), SPH_C32(0x996a0f3c), SPH_C32(0xedf47c81), + SPH_C32(0x8a83a5ca) }, + { SPH_C32(0x2f440000), SPH_C32(0xbce40600), SPH_C32(0xbb3d0000), + SPH_C32(0x01f40000), SPH_C32(0x8a333dfd), SPH_C32(0xd0a40492), + SPH_C32(0xfa93b802), SPH_C32(0x245cc3b4), SPH_C32(0x56920000), + SPH_C32(0x378a2e00), SPH_C32(0x6de00000), SPH_C32(0xcdeb0000), + SPH_C32(0x42e15a07), SPH_C32(0x8ce82a28), SPH_C32(0x785737fa), + SPH_C32(0x3ec8a55a) }, + { SPH_C32(0x23360000), SPH_C32(0xf5010900), SPH_C32(0xf9440000), + SPH_C32(0x5d1e0000), SPH_C32(0xb9990de7), SPH_C32(0xc5262186), + SPH_C32(0x6f30f379), SPH_C32(0x9017c324), SPH_C32(0xa8b00000), + SPH_C32(0x90d22b00), SPH_C32(0x48310000), SPH_C32(0x3a8b0000), + SPH_C32(0xcbd022dd), SPH_C32(0x933cd248), SPH_C32(0x368794ef), + SPH_C32(0x9feb5ac5) }, + { SPH_C32(0x947e0000), SPH_C32(0xbe091400), SPH_C32(0x67860000), + SPH_C32(0xcddc0000), SPH_C32(0x1dce510b), SPH_C32(0xec636924), + SPH_C32(0xa2ffbda7), SPH_C32(0x5a4cc8f4), SPH_C32(0x1cff0000), + SPH_C32(0xcf462200), SPH_C32(0x3dd20000), SPH_C32(0x93d00000), + SPH_C32(0xdafb736b), SPH_C32(0x28f60619), SPH_C32(0xc500c982), + SPH_C32(0xee61b16b) }, + { SPH_C32(0x980c0000), SPH_C32(0xf7ec1b00), SPH_C32(0x25ff0000), + SPH_C32(0x91360000), SPH_C32(0x2e646111), SPH_C32(0xf9e14c30), + SPH_C32(0x375cf6dc), SPH_C32(0xee07c864), SPH_C32(0xe2dd0000), + SPH_C32(0x681e2700), SPH_C32(0x18030000), SPH_C32(0x64b00000), + SPH_C32(0x53ca0bb1), SPH_C32(0x3722fe79), SPH_C32(0x8bd06a97), + SPH_C32(0x4f424ef4) }, + { SPH_C32(0x6a5c0000), SPH_C32(0x19511100), SPH_C32(0x42570000), + SPH_C32(0x3abc0000), SPH_C32(0x94ff29d1), SPH_C32(0xf3b79144), + SPH_C32(0xec2f1eb2), SPH_C32(0xfb6f376b), SPH_C32(0xeeaf0000), + SPH_C32(0x21fb2800), SPH_C32(0x5a7a0000), SPH_C32(0x385a0000), + SPH_C32(0x60603bab), SPH_C32(0x22a0db6d), SPH_C32(0x1e7321ec), + SPH_C32(0xfb094e64) }, + { SPH_C32(0x662e0000), SPH_C32(0x50b41e00), SPH_C32(0x002e0000), + SPH_C32(0x66560000), SPH_C32(0xa75519cb), SPH_C32(0xe635b450), + SPH_C32(0x798c55c9), SPH_C32(0x4f2437fb), SPH_C32(0x108d0000), + SPH_C32(0x86a32d00), SPH_C32(0x7fab0000), SPH_C32(0xcf3a0000), + SPH_C32(0xe9514371), SPH_C32(0x3d74230d), SPH_C32(0x50a382f9), + SPH_C32(0x5a2ab1fb) }, + { SPH_C32(0x695b0000), SPH_C32(0x0dcd0500), SPH_C32(0xa9760000), + SPH_C32(0x03250000), SPH_C32(0x2183248b), SPH_C32(0x61380db7), + SPH_C32(0xd2670d01), SPH_C32(0x40bed715), SPH_C32(0x59e70000), + SPH_C32(0x6af33500), SPH_C32(0xc4b80000), SPH_C32(0xa8980000), + SPH_C32(0xc4376747), SPH_C32(0x0be593cf), SPH_C32(0xd3bc6f32), + SPH_C32(0x315245b4) }, + { SPH_C32(0x65290000), SPH_C32(0x44280a00), SPH_C32(0xeb0f0000), + SPH_C32(0x5fcf0000), SPH_C32(0x12291491), SPH_C32(0x74ba28a3), + SPH_C32(0x47c4467a), SPH_C32(0xf4f5d785), SPH_C32(0xa7c50000), + SPH_C32(0xcdab3000), SPH_C32(0xe1690000), SPH_C32(0x5ff80000), + SPH_C32(0x4d061f9d), SPH_C32(0x14316baf), SPH_C32(0x9d6ccc27), + SPH_C32(0x9071ba2b) }, + { SPH_C32(0x97790000), SPH_C32(0xaa950000), SPH_C32(0x8ca70000), + SPH_C32(0xf4450000), SPH_C32(0xa8b25c51), SPH_C32(0x7eecf5d7), + SPH_C32(0x9cb7ae14), SPH_C32(0xe19d288a), SPH_C32(0xabb70000), + SPH_C32(0x844e3f00), SPH_C32(0xa3100000), SPH_C32(0x03120000), + SPH_C32(0x7eac2f87), SPH_C32(0x01b34ebb), SPH_C32(0x08cf875c), + SPH_C32(0x243ababb) }, + { SPH_C32(0x9b0b0000), SPH_C32(0xe3700f00), SPH_C32(0xcede0000), + SPH_C32(0xa8af0000), SPH_C32(0x9b186c4b), SPH_C32(0x6b6ed0c3), + SPH_C32(0x0914e56f), SPH_C32(0x55d6281a), SPH_C32(0x55950000), + SPH_C32(0x23163a00), SPH_C32(0x86c10000), SPH_C32(0xf4720000), + SPH_C32(0xf79d575d), SPH_C32(0x1e67b6db), SPH_C32(0x461f2449), + SPH_C32(0x85194524) }, + { SPH_C32(0x2c430000), SPH_C32(0xa8781200), SPH_C32(0x501c0000), + SPH_C32(0x386d0000), SPH_C32(0x3f4f30a7), SPH_C32(0x422b9861), + SPH_C32(0xc4dbabb1), SPH_C32(0x9f8d23ca), SPH_C32(0xe1da0000), + SPH_C32(0x7c823300), SPH_C32(0xf3220000), SPH_C32(0x5d290000), + SPH_C32(0xe6b606eb), SPH_C32(0xa5ad628a), SPH_C32(0xb5987924), + SPH_C32(0xf493ae8a) }, + { SPH_C32(0x20310000), SPH_C32(0xe19d1d00), SPH_C32(0x12650000), + SPH_C32(0x64870000), SPH_C32(0x0ce500bd), SPH_C32(0x57a9bd75), + SPH_C32(0x5178e0ca), SPH_C32(0x2bc6235a), SPH_C32(0x1ff80000), + SPH_C32(0xdbda3600), SPH_C32(0xd6f30000), SPH_C32(0xaa490000), + SPH_C32(0x6f877e31), SPH_C32(0xba799aea), SPH_C32(0xfb48da31), + SPH_C32(0x55b05115) }, + { SPH_C32(0xd2610000), SPH_C32(0x0f201700), SPH_C32(0x75cd0000), + SPH_C32(0xcf0d0000), SPH_C32(0xb67e487d), SPH_C32(0x5dff6001), + SPH_C32(0x8a0b08a4), SPH_C32(0x3eaedc55), SPH_C32(0x138a0000), + SPH_C32(0x923f3900), SPH_C32(0x948a0000), SPH_C32(0xf6a30000), + SPH_C32(0x5c2d4e2b), SPH_C32(0xaffbbffe), SPH_C32(0x6eeb914a), + SPH_C32(0xe1fb5185) }, + { SPH_C32(0xde130000), SPH_C32(0x46c51800), SPH_C32(0x37b40000), + SPH_C32(0x93e70000), SPH_C32(0x85d47867), SPH_C32(0x487d4515), + SPH_C32(0x1fa843df), SPH_C32(0x8ae5dcc5), SPH_C32(0xeda80000), + SPH_C32(0x35673c00), SPH_C32(0xb15b0000), SPH_C32(0x01c30000), + SPH_C32(0xd51c36f1), SPH_C32(0xb02f479e), SPH_C32(0x203b325f), + SPH_C32(0x40d8ae1a) }, + { SPH_C32(0xa4c20000), SPH_C32(0xd9372400), SPH_C32(0x0a480000), + SPH_C32(0x66610000), SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), + SPH_C32(0xa324df94), SPH_C32(0x2ba05a55), SPH_C32(0x75a40000), + SPH_C32(0xc28b2700), SPH_C32(0x94a40000), SPH_C32(0x90f50000), + SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), SPH_C32(0x1767c483), + SPH_C32(0xaedf667e) }, + { SPH_C32(0xa8b00000), SPH_C32(0x90d22b00), SPH_C32(0x48310000), + SPH_C32(0x3a8b0000), SPH_C32(0xcbd022dd), SPH_C32(0x933cd248), + SPH_C32(0x368794ef), SPH_C32(0x9feb5ac5), SPH_C32(0x8b860000), + SPH_C32(0x65d32200), SPH_C32(0xb1750000), SPH_C32(0x67950000), + SPH_C32(0x72492f3a), SPH_C32(0x561af3ce), SPH_C32(0x59b76796), + SPH_C32(0x0ffc99e1) }, + { SPH_C32(0x5ae00000), SPH_C32(0x7e6f2100), SPH_C32(0x2f990000), + SPH_C32(0x91010000), SPH_C32(0x714b6a1d), SPH_C32(0x996a0f3c), + SPH_C32(0xedf47c81), SPH_C32(0x8a83a5ca), SPH_C32(0x87f40000), + SPH_C32(0x2c362d00), SPH_C32(0xf30c0000), SPH_C32(0x3b7f0000), + SPH_C32(0x41e31f20), SPH_C32(0x4398d6da), SPH_C32(0xcc142ced), + SPH_C32(0xbbb79971) }, + { SPH_C32(0x56920000), SPH_C32(0x378a2e00), SPH_C32(0x6de00000), + SPH_C32(0xcdeb0000), SPH_C32(0x42e15a07), SPH_C32(0x8ce82a28), + SPH_C32(0x785737fa), SPH_C32(0x3ec8a55a), SPH_C32(0x79d60000), + SPH_C32(0x8b6e2800), SPH_C32(0xd6dd0000), SPH_C32(0xcc1f0000), + SPH_C32(0xc8d267fa), SPH_C32(0x5c4c2eba), SPH_C32(0x82c48ff8), + SPH_C32(0x1a9466ee) }, + { SPH_C32(0xe1da0000), SPH_C32(0x7c823300), SPH_C32(0xf3220000), + SPH_C32(0x5d290000), SPH_C32(0xe6b606eb), SPH_C32(0xa5ad628a), + SPH_C32(0xb5987924), SPH_C32(0xf493ae8a), SPH_C32(0xcd990000), + SPH_C32(0xd4fa2100), SPH_C32(0xa33e0000), SPH_C32(0x65440000), + SPH_C32(0xd9f9364c), SPH_C32(0xe786faeb), SPH_C32(0x7143d295), + SPH_C32(0x6b1e8d40) }, + { SPH_C32(0xeda80000), SPH_C32(0x35673c00), SPH_C32(0xb15b0000), + SPH_C32(0x01c30000), SPH_C32(0xd51c36f1), SPH_C32(0xb02f479e), + SPH_C32(0x203b325f), SPH_C32(0x40d8ae1a), SPH_C32(0x33bb0000), + SPH_C32(0x73a22400), SPH_C32(0x86ef0000), SPH_C32(0x92240000), + SPH_C32(0x50c84e96), SPH_C32(0xf852028b), SPH_C32(0x3f937180), + SPH_C32(0xca3d72df) }, + { SPH_C32(0x1ff80000), SPH_C32(0xdbda3600), SPH_C32(0xd6f30000), + SPH_C32(0xaa490000), SPH_C32(0x6f877e31), SPH_C32(0xba799aea), + SPH_C32(0xfb48da31), SPH_C32(0x55b05115), SPH_C32(0x3fc90000), + SPH_C32(0x3a472b00), SPH_C32(0xc4960000), SPH_C32(0xcece0000), + SPH_C32(0x63627e8c), SPH_C32(0xedd0279f), SPH_C32(0xaa303afb), + SPH_C32(0x7e76724f) }, + { SPH_C32(0x138a0000), SPH_C32(0x923f3900), SPH_C32(0x948a0000), + SPH_C32(0xf6a30000), SPH_C32(0x5c2d4e2b), SPH_C32(0xaffbbffe), + SPH_C32(0x6eeb914a), SPH_C32(0xe1fb5185), SPH_C32(0xc1eb0000), + SPH_C32(0x9d1f2e00), SPH_C32(0xe1470000), SPH_C32(0x39ae0000), + SPH_C32(0xea530656), SPH_C32(0xf204dfff), SPH_C32(0xe4e099ee), + SPH_C32(0xdf558dd0) }, + { SPH_C32(0x1cff0000), SPH_C32(0xcf462200), SPH_C32(0x3dd20000), + SPH_C32(0x93d00000), SPH_C32(0xdafb736b), SPH_C32(0x28f60619), + SPH_C32(0xc500c982), SPH_C32(0xee61b16b), SPH_C32(0x88810000), + SPH_C32(0x714f3600), SPH_C32(0x5a540000), SPH_C32(0x5e0c0000), + SPH_C32(0xc7352260), SPH_C32(0xc4956f3d), SPH_C32(0x67ff7425), + SPH_C32(0xb42d799f) }, + { SPH_C32(0x108d0000), SPH_C32(0x86a32d00), SPH_C32(0x7fab0000), + SPH_C32(0xcf3a0000), SPH_C32(0xe9514371), SPH_C32(0x3d74230d), + SPH_C32(0x50a382f9), SPH_C32(0x5a2ab1fb), SPH_C32(0x76a30000), + SPH_C32(0xd6173300), SPH_C32(0x7f850000), SPH_C32(0xa96c0000), + SPH_C32(0x4e045aba), SPH_C32(0xdb41975d), SPH_C32(0x292fd730), + SPH_C32(0x150e8600) }, + { SPH_C32(0xe2dd0000), SPH_C32(0x681e2700), SPH_C32(0x18030000), + SPH_C32(0x64b00000), SPH_C32(0x53ca0bb1), SPH_C32(0x3722fe79), + SPH_C32(0x8bd06a97), SPH_C32(0x4f424ef4), SPH_C32(0x7ad10000), + SPH_C32(0x9ff23c00), SPH_C32(0x3dfc0000), SPH_C32(0xf5860000), + SPH_C32(0x7dae6aa0), SPH_C32(0xcec3b249), SPH_C32(0xbc8c9c4b), + SPH_C32(0xa1458690) }, + { SPH_C32(0xeeaf0000), SPH_C32(0x21fb2800), SPH_C32(0x5a7a0000), + SPH_C32(0x385a0000), SPH_C32(0x60603bab), SPH_C32(0x22a0db6d), + SPH_C32(0x1e7321ec), SPH_C32(0xfb094e64), SPH_C32(0x84f30000), + SPH_C32(0x38aa3900), SPH_C32(0x182d0000), SPH_C32(0x02e60000), + SPH_C32(0xf49f127a), SPH_C32(0xd1174a29), SPH_C32(0xf25c3f5e), + SPH_C32(0x0066790f) }, + { SPH_C32(0x59e70000), SPH_C32(0x6af33500), SPH_C32(0xc4b80000), + SPH_C32(0xa8980000), SPH_C32(0xc4376747), SPH_C32(0x0be593cf), + SPH_C32(0xd3bc6f32), SPH_C32(0x315245b4), SPH_C32(0x30bc0000), + SPH_C32(0x673e3000), SPH_C32(0x6dce0000), SPH_C32(0xabbd0000), + SPH_C32(0xe5b443cc), SPH_C32(0x6add9e78), SPH_C32(0x01db6233), + SPH_C32(0x71ec92a1) }, + { SPH_C32(0x55950000), SPH_C32(0x23163a00), SPH_C32(0x86c10000), + SPH_C32(0xf4720000), SPH_C32(0xf79d575d), SPH_C32(0x1e67b6db), + SPH_C32(0x461f2449), SPH_C32(0x85194524), SPH_C32(0xce9e0000), + SPH_C32(0xc0663500), SPH_C32(0x481f0000), SPH_C32(0x5cdd0000), + SPH_C32(0x6c853b16), SPH_C32(0x75096618), SPH_C32(0x4f0bc126), + SPH_C32(0xd0cf6d3e) }, + { SPH_C32(0xa7c50000), SPH_C32(0xcdab3000), SPH_C32(0xe1690000), + SPH_C32(0x5ff80000), SPH_C32(0x4d061f9d), SPH_C32(0x14316baf), + SPH_C32(0x9d6ccc27), SPH_C32(0x9071ba2b), SPH_C32(0xc2ec0000), + SPH_C32(0x89833a00), SPH_C32(0x0a660000), SPH_C32(0x00370000), + SPH_C32(0x5f2f0b0c), SPH_C32(0x608b430c), SPH_C32(0xdaa88a5d), + SPH_C32(0x64846dae) }, + { SPH_C32(0xabb70000), SPH_C32(0x844e3f00), SPH_C32(0xa3100000), + SPH_C32(0x03120000), SPH_C32(0x7eac2f87), SPH_C32(0x01b34ebb), + SPH_C32(0x08cf875c), SPH_C32(0x243ababb), SPH_C32(0x3cce0000), + SPH_C32(0x2edb3f00), SPH_C32(0x2fb70000), SPH_C32(0xf7570000), + SPH_C32(0xd61e73d6), SPH_C32(0x7f5fbb6c), SPH_C32(0x94782948), + SPH_C32(0xc5a79231) } +}; + +static const sph_u32 T512_24[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x14190000), SPH_C32(0x23ca003c), SPH_C32(0x50df0000), + SPH_C32(0x44b60000), SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), + SPH_C32(0x61e610b0), SPH_C32(0xdbcadb80), SPH_C32(0xe3430000), + SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), SPH_C32(0xaa4e0000), + SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), SPH_C32(0x123db156), + SPH_C32(0x3a4e99d7) }, + { SPH_C32(0xe3430000), SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), + SPH_C32(0xaa4e0000), SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), + SPH_C32(0x123db156), SPH_C32(0x3a4e99d7), SPH_C32(0xf75a0000), + SPH_C32(0x19840028), SPH_C32(0xa2190000), SPH_C32(0xeef80000), + SPH_C32(0xc0722516), SPH_C32(0x19981260), SPH_C32(0x73dba1e6), + SPH_C32(0xe1844257) }, + { SPH_C32(0xf75a0000), SPH_C32(0x19840028), SPH_C32(0xa2190000), + SPH_C32(0xeef80000), SPH_C32(0xc0722516), SPH_C32(0x19981260), + SPH_C32(0x73dba1e6), SPH_C32(0xe1844257), SPH_C32(0x14190000), + SPH_C32(0x23ca003c), SPH_C32(0x50df0000), SPH_C32(0x44b60000), + SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), SPH_C32(0x61e610b0), + SPH_C32(0xdbcadb80) }, + { SPH_C32(0x54500000), SPH_C32(0x0671005c), SPH_C32(0x25ae0000), + SPH_C32(0x6a1e0000), SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), + SPH_C32(0xbfba18c3), SPH_C32(0x7e715d17), SPH_C32(0xbc8d0000), + SPH_C32(0xfc3b0018), SPH_C32(0x19830000), SPH_C32(0xd10b0000), + SPH_C32(0xae1878c4), SPH_C32(0x42a69856), SPH_C32(0x0012da37), + SPH_C32(0x2c3b504e) }, + { SPH_C32(0x40490000), SPH_C32(0x25bb0060), SPH_C32(0x75710000), + SPH_C32(0x2ea80000), SPH_C32(0x35c9296f), SPH_C32(0x5abd2967), + SPH_C32(0xde5c0873), SPH_C32(0xa5bb8697), SPH_C32(0x5fce0000), + SPH_C32(0xc675000c), SPH_C32(0xeb450000), SPH_C32(0x7b450000), + SPH_C32(0x75063a62), SPH_C32(0x67cd2643), SPH_C32(0x122f6b61), + SPH_C32(0x1675c999) }, + { SPH_C32(0xb7130000), SPH_C32(0x3c3f0048), SPH_C32(0xd7680000), + SPH_C32(0xc0500000), SPH_C32(0xf5bb0c79), SPH_C32(0x43253b07), + SPH_C32(0xad87a995), SPH_C32(0x443fc4c0), SPH_C32(0x4bd70000), + SPH_C32(0xe5bf0030), SPH_C32(0xbb9a0000), SPH_C32(0x3ff30000), + SPH_C32(0x6e6a5dd2), SPH_C32(0x5b3e8a36), SPH_C32(0x73c97bd1), + SPH_C32(0xcdbf1219) }, + { SPH_C32(0xa30a0000), SPH_C32(0x1ff50074), SPH_C32(0x87b70000), + SPH_C32(0x84e60000), SPH_C32(0xeed76bc9), SPH_C32(0x7fd69772), + SPH_C32(0xcc61b925), SPH_C32(0x9ff51f40), SPH_C32(0xa8940000), + SPH_C32(0xdff10024), SPH_C32(0x495c0000), SPH_C32(0x95bd0000), + SPH_C32(0xb5741f74), SPH_C32(0x7e553423), SPH_C32(0x61f4ca87), + SPH_C32(0xf7f18bce) }, + { SPH_C32(0xbc8d0000), SPH_C32(0xfc3b0018), SPH_C32(0x19830000), + SPH_C32(0xd10b0000), SPH_C32(0xae1878c4), SPH_C32(0x42a69856), + SPH_C32(0x0012da37), SPH_C32(0x2c3b504e), SPH_C32(0xe8dd0000), + SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), SPH_C32(0xbb150000), + SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), SPH_C32(0xbfa8c2f4), + SPH_C32(0x524a0d59) }, + { SPH_C32(0xa8940000), SPH_C32(0xdff10024), SPH_C32(0x495c0000), + SPH_C32(0x95bd0000), SPH_C32(0xb5741f74), SPH_C32(0x7e553423), + SPH_C32(0x61f4ca87), SPH_C32(0xf7f18bce), SPH_C32(0x0b9e0000), + SPH_C32(0xc0040050), SPH_C32(0xceeb0000), SPH_C32(0x115b0000), + SPH_C32(0x5ba374bd), SPH_C32(0x0183a351), SPH_C32(0xad9573a2), + SPH_C32(0x6804948e) }, + { SPH_C32(0x5fce0000), SPH_C32(0xc675000c), SPH_C32(0xeb450000), + SPH_C32(0x7b450000), SPH_C32(0x75063a62), SPH_C32(0x67cd2643), + SPH_C32(0x122f6b61), SPH_C32(0x1675c999), SPH_C32(0x1f870000), + SPH_C32(0xe3ce006c), SPH_C32(0x9e340000), SPH_C32(0x55ed0000), + SPH_C32(0x40cf130d), SPH_C32(0x3d700f24), SPH_C32(0xcc736312), + SPH_C32(0xb3ce4f0e) }, + { SPH_C32(0x4bd70000), SPH_C32(0xe5bf0030), SPH_C32(0xbb9a0000), + SPH_C32(0x3ff30000), SPH_C32(0x6e6a5dd2), SPH_C32(0x5b3e8a36), + SPH_C32(0x73c97bd1), SPH_C32(0xcdbf1219), SPH_C32(0xfcc40000), + SPH_C32(0xd9800078), SPH_C32(0x6cf20000), SPH_C32(0xffa30000), + SPH_C32(0x9bd151ab), SPH_C32(0x181bb131), SPH_C32(0xde4ed244), + SPH_C32(0x8980d6d9) }, + { SPH_C32(0xe8dd0000), SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), + SPH_C32(0xbb150000), SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), + SPH_C32(0xbfa8c2f4), SPH_C32(0x524a0d59), SPH_C32(0x54500000), + SPH_C32(0x0671005c), SPH_C32(0x25ae0000), SPH_C32(0x6a1e0000), + SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), SPH_C32(0xbfba18c3), + SPH_C32(0x7e715d17) }, + { SPH_C32(0xfcc40000), SPH_C32(0xd9800078), SPH_C32(0x6cf20000), + SPH_C32(0xffa30000), SPH_C32(0x9bd151ab), SPH_C32(0x181bb131), + SPH_C32(0xde4ed244), SPH_C32(0x8980d6d9), SPH_C32(0xb7130000), + SPH_C32(0x3c3f0048), SPH_C32(0xd7680000), SPH_C32(0xc0500000), + SPH_C32(0xf5bb0c79), SPH_C32(0x43253b07), SPH_C32(0xad87a995), + SPH_C32(0x443fc4c0) }, + { SPH_C32(0x0b9e0000), SPH_C32(0xc0040050), SPH_C32(0xceeb0000), + SPH_C32(0x115b0000), SPH_C32(0x5ba374bd), SPH_C32(0x0183a351), + SPH_C32(0xad9573a2), SPH_C32(0x6804948e), SPH_C32(0xa30a0000), + SPH_C32(0x1ff50074), SPH_C32(0x87b70000), SPH_C32(0x84e60000), + SPH_C32(0xeed76bc9), SPH_C32(0x7fd69772), SPH_C32(0xcc61b925), + SPH_C32(0x9ff51f40) }, + { SPH_C32(0x1f870000), SPH_C32(0xe3ce006c), SPH_C32(0x9e340000), + SPH_C32(0x55ed0000), SPH_C32(0x40cf130d), SPH_C32(0x3d700f24), + SPH_C32(0xcc736312), SPH_C32(0xb3ce4f0e), SPH_C32(0x40490000), + SPH_C32(0x25bb0060), SPH_C32(0x75710000), SPH_C32(0x2ea80000), + SPH_C32(0x35c9296f), SPH_C32(0x5abd2967), SPH_C32(0xde5c0873), + SPH_C32(0xa5bb8697) }, + { SPH_C32(0x69510000), SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), + SPH_C32(0xac2f0000), SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), + SPH_C32(0x87ec287c), SPH_C32(0xbce1a3ce), SPH_C32(0xc6730000), + SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), SPH_C32(0x218d0000), + SPH_C32(0x23111587), SPH_C32(0x7913512f), SPH_C32(0x1d28ac88), + SPH_C32(0x378dd173) }, + { SPH_C32(0x7d480000), SPH_C32(0xf72b00a0), SPH_C32(0x93fc0000), + SPH_C32(0xe8990000), SPH_C32(0xfff96c1e), SPH_C32(0xf257b9a9), + SPH_C32(0xe60a38cc), SPH_C32(0x672b784e), SPH_C32(0x25300000), + SPH_C32(0x95c30018), SPH_C32(0x56070000), SPH_C32(0x8bc30000), + SPH_C32(0xf80f5721), SPH_C32(0x5c78ef3a), SPH_C32(0x0f151dde), + SPH_C32(0x0dc348a4) }, + { SPH_C32(0x8a120000), SPH_C32(0xeeaf0088), SPH_C32(0x31e50000), + SPH_C32(0x06610000), SPH_C32(0x3f8b4908), SPH_C32(0xebcfabc9), + SPH_C32(0x95d1992a), SPH_C32(0x86af3a19), SPH_C32(0x31290000), + SPH_C32(0xb6090024), SPH_C32(0x06d80000), SPH_C32(0xcf750000), + SPH_C32(0xe3633091), SPH_C32(0x608b434f), SPH_C32(0x6ef30d6e), + SPH_C32(0xd6099324) }, + { SPH_C32(0x9e0b0000), SPH_C32(0xcd6500b4), SPH_C32(0x613a0000), + SPH_C32(0x42d70000), SPH_C32(0x24e72eb8), SPH_C32(0xd73c07bc), + SPH_C32(0xf437899a), SPH_C32(0x5d65e199), SPH_C32(0xd26a0000), + SPH_C32(0x8c470030), SPH_C32(0xf41e0000), SPH_C32(0x653b0000), + SPH_C32(0x387d7237), SPH_C32(0x45e0fd5a), SPH_C32(0x7ccebc38), + SPH_C32(0xec470af3) }, + { SPH_C32(0x3d010000), SPH_C32(0xd29000c0), SPH_C32(0xe68d0000), + SPH_C32(0xc6310000), SPH_C32(0xca304571), SPH_C32(0xa8ea90ce), + SPH_C32(0x385630bf), SPH_C32(0xc290fed9), SPH_C32(0x7afe0000), + SPH_C32(0x53b60014), SPH_C32(0xbd420000), SPH_C32(0xf0860000), + SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), SPH_C32(0x1d3a76bf), + SPH_C32(0x1bb6813d) }, + { SPH_C32(0x29180000), SPH_C32(0xf15a00fc), SPH_C32(0xb6520000), + SPH_C32(0x82870000), SPH_C32(0xd15c22c1), SPH_C32(0x94193cbb), + SPH_C32(0x59b0200f), SPH_C32(0x195a2559), SPH_C32(0x99bd0000), + SPH_C32(0x69f80000), SPH_C32(0x4f840000), SPH_C32(0x5ac80000), + SPH_C32(0x56172fe5), SPH_C32(0x1ede776c), SPH_C32(0x0f07c7e9), + SPH_C32(0x21f818ea) }, + { SPH_C32(0xde420000), SPH_C32(0xe8de00d4), SPH_C32(0x144b0000), + SPH_C32(0x6c7f0000), SPH_C32(0x112e07d7), SPH_C32(0x8d812edb), + SPH_C32(0x2a6b81e9), SPH_C32(0xf8de670e), SPH_C32(0x8da40000), + SPH_C32(0x4a32003c), SPH_C32(0x1f5b0000), SPH_C32(0x1e7e0000), + SPH_C32(0x4d7b4855), SPH_C32(0x222ddb19), SPH_C32(0x6ee1d759), + SPH_C32(0xfa32c36a) }, + { SPH_C32(0xca5b0000), SPH_C32(0xcb1400e8), SPH_C32(0x44940000), + SPH_C32(0x28c90000), SPH_C32(0x0a426067), SPH_C32(0xb17282ae), + SPH_C32(0x4b8d9159), SPH_C32(0x2314bc8e), SPH_C32(0x6ee70000), + SPH_C32(0x707c0028), SPH_C32(0xed9d0000), SPH_C32(0xb4300000), + SPH_C32(0x96650af3), SPH_C32(0x0746650c), SPH_C32(0x7cdc660f), + SPH_C32(0xc07c5abd) }, + { SPH_C32(0xd5dc0000), SPH_C32(0x28da0084), SPH_C32(0xdaa00000), + SPH_C32(0x7d240000), SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), + SPH_C32(0x87fef24b), SPH_C32(0x90daf380), SPH_C32(0x2eae0000), + SPH_C32(0x55c70048), SPH_C32(0x98ec0000), SPH_C32(0x9a980000), + SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), SPH_C32(0xa2806e7c), + SPH_C32(0x65c7dc2a) }, + { SPH_C32(0xc1c50000), SPH_C32(0x0b1000b8), SPH_C32(0x8a7f0000), + SPH_C32(0x39920000), SPH_C32(0x51e114da), SPH_C32(0xb0f121ff), + SPH_C32(0xe618e2fb), SPH_C32(0x4b102800), SPH_C32(0xcded0000), + SPH_C32(0x6f89005c), SPH_C32(0x6a2a0000), SPH_C32(0x30d60000), + SPH_C32(0x78b2613a), SPH_C32(0x7890f27e), SPH_C32(0xb0bddf2a), + SPH_C32(0x5f8945fd) }, + { SPH_C32(0x369f0000), SPH_C32(0x12940090), SPH_C32(0x28660000), + SPH_C32(0xd76a0000), SPH_C32(0x919331cc), SPH_C32(0xa969339f), + SPH_C32(0x95c3431d), SPH_C32(0xaa946a57), SPH_C32(0xd9f40000), + SPH_C32(0x4c430060), SPH_C32(0x3af50000), SPH_C32(0x74600000), + SPH_C32(0x63de068a), SPH_C32(0x44635e0b), SPH_C32(0xd15bcf9a), + SPH_C32(0x84439e7d) }, + { SPH_C32(0x22860000), SPH_C32(0x315e00ac), SPH_C32(0x78b90000), + SPH_C32(0x93dc0000), SPH_C32(0x8aff567c), SPH_C32(0x959a9fea), + SPH_C32(0xf42553ad), SPH_C32(0x715eb1d7), SPH_C32(0x3ab70000), + SPH_C32(0x760d0074), SPH_C32(0xc8330000), SPH_C32(0xde2e0000), + SPH_C32(0xb8c0442c), SPH_C32(0x6108e01e), SPH_C32(0xc3667ecc), + SPH_C32(0xbe0d07aa) }, + { SPH_C32(0x818c0000), SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), + SPH_C32(0x173a0000), SPH_C32(0x64283db5), SPH_C32(0xea4c0898), + SPH_C32(0x3844ea88), SPH_C32(0xeeabae97), SPH_C32(0x92230000), + SPH_C32(0xa9fc0050), SPH_C32(0x816f0000), SPH_C32(0x4b930000), + SPH_C32(0x0db45b58), SPH_C32(0x1f5dd43d), SPH_C32(0xa292b44b), + SPH_C32(0x49fc8c64) }, + { SPH_C32(0x95950000), SPH_C32(0x0d6100e4), SPH_C32(0xafd10000), + SPH_C32(0x538c0000), SPH_C32(0x7f445a05), SPH_C32(0xd6bfa4ed), + SPH_C32(0x59a2fa38), SPH_C32(0x35617517), SPH_C32(0x71600000), + SPH_C32(0x93b20044), SPH_C32(0x73a90000), SPH_C32(0xe1dd0000), + SPH_C32(0xd6aa19fe), SPH_C32(0x3a366a28), SPH_C32(0xb0af051d), + SPH_C32(0x73b215b3) }, + { SPH_C32(0x62cf0000), SPH_C32(0x14e500cc), SPH_C32(0x0dc80000), + SPH_C32(0xbd740000), SPH_C32(0xbf367f13), SPH_C32(0xcf27b68d), + SPH_C32(0x2a795bde), SPH_C32(0xd4e53740), SPH_C32(0x65790000), + SPH_C32(0xb0780078), SPH_C32(0x23760000), SPH_C32(0xa56b0000), + SPH_C32(0xcdc67e4e), SPH_C32(0x06c5c65d), SPH_C32(0xd14915ad), + SPH_C32(0xa878ce33) }, + { SPH_C32(0x76d60000), SPH_C32(0x372f00f0), SPH_C32(0x5d170000), + SPH_C32(0xf9c20000), SPH_C32(0xa45a18a3), SPH_C32(0xf3d41af8), + SPH_C32(0x4b9f4b6e), SPH_C32(0x0f2fecc0), SPH_C32(0x863a0000), + SPH_C32(0x8a36006c), SPH_C32(0xd1b00000), SPH_C32(0x0f250000), + SPH_C32(0x16d83ce8), SPH_C32(0x23ae7848), SPH_C32(0xc374a4fb), + SPH_C32(0x923657e4) }, + { SPH_C32(0xc6730000), SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), + SPH_C32(0x218d0000), SPH_C32(0x23111587), SPH_C32(0x7913512f), + SPH_C32(0x1d28ac88), SPH_C32(0x378dd173), SPH_C32(0xaf220000), + SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), SPH_C32(0x8da20000), + SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), SPH_C32(0x9ac484f4), + SPH_C32(0x8b6c72bd) }, + { SPH_C32(0xd26a0000), SPH_C32(0x8c470030), SPH_C32(0xf41e0000), + SPH_C32(0x653b0000), SPH_C32(0x387d7237), SPH_C32(0x45e0fd5a), + SPH_C32(0x7ccebc38), SPH_C32(0xec470af3), SPH_C32(0x4c610000), + SPH_C32(0x41220084), SPH_C32(0x95240000), SPH_C32(0x27ec0000), + SPH_C32(0x1c9a5c8f), SPH_C32(0x92dcfae6), SPH_C32(0x88f935a2), + SPH_C32(0xb122eb6a) }, + { SPH_C32(0x25300000), SPH_C32(0x95c30018), SPH_C32(0x56070000), + SPH_C32(0x8bc30000), SPH_C32(0xf80f5721), SPH_C32(0x5c78ef3a), + SPH_C32(0x0f151dde), SPH_C32(0x0dc348a4), SPH_C32(0x58780000), + SPH_C32(0x62e800b8), SPH_C32(0xc5fb0000), SPH_C32(0x635a0000), + SPH_C32(0x07f63b3f), SPH_C32(0xae2f5693), SPH_C32(0xe91f2512), + SPH_C32(0x6ae830ea) }, + { SPH_C32(0x31290000), SPH_C32(0xb6090024), SPH_C32(0x06d80000), + SPH_C32(0xcf750000), SPH_C32(0xe3633091), SPH_C32(0x608b434f), + SPH_C32(0x6ef30d6e), SPH_C32(0xd6099324), SPH_C32(0xbb3b0000), + SPH_C32(0x58a600ac), SPH_C32(0x373d0000), SPH_C32(0xc9140000), + SPH_C32(0xdce87999), SPH_C32(0x8b44e886), SPH_C32(0xfb229444), + SPH_C32(0x50a6a93d) }, + { SPH_C32(0x92230000), SPH_C32(0xa9fc0050), SPH_C32(0x816f0000), + SPH_C32(0x4b930000), SPH_C32(0x0db45b58), SPH_C32(0x1f5dd43d), + SPH_C32(0xa292b44b), SPH_C32(0x49fc8c64), SPH_C32(0x13af0000), + SPH_C32(0x87570088), SPH_C32(0x7e610000), SPH_C32(0x5ca90000), + SPH_C32(0x699c66ed), SPH_C32(0xf511dca5), SPH_C32(0x9ad65ec3), + SPH_C32(0xa75722f3) }, + { SPH_C32(0x863a0000), SPH_C32(0x8a36006c), SPH_C32(0xd1b00000), + SPH_C32(0x0f250000), SPH_C32(0x16d83ce8), SPH_C32(0x23ae7848), + SPH_C32(0xc374a4fb), SPH_C32(0x923657e4), SPH_C32(0xf0ec0000), + SPH_C32(0xbd19009c), SPH_C32(0x8ca70000), SPH_C32(0xf6e70000), + SPH_C32(0xb282244b), SPH_C32(0xd07a62b0), SPH_C32(0x88ebef95), + SPH_C32(0x9d19bb24) }, + { SPH_C32(0x71600000), SPH_C32(0x93b20044), SPH_C32(0x73a90000), + SPH_C32(0xe1dd0000), SPH_C32(0xd6aa19fe), SPH_C32(0x3a366a28), + SPH_C32(0xb0af051d), SPH_C32(0x73b215b3), SPH_C32(0xe4f50000), + SPH_C32(0x9ed300a0), SPH_C32(0xdc780000), SPH_C32(0xb2510000), + SPH_C32(0xa9ee43fb), SPH_C32(0xec89cec5), SPH_C32(0xe90dff25), + SPH_C32(0x46d360a4) }, + { SPH_C32(0x65790000), SPH_C32(0xb0780078), SPH_C32(0x23760000), + SPH_C32(0xa56b0000), SPH_C32(0xcdc67e4e), SPH_C32(0x06c5c65d), + SPH_C32(0xd14915ad), SPH_C32(0xa878ce33), SPH_C32(0x07b60000), + SPH_C32(0xa49d00b4), SPH_C32(0x2ebe0000), SPH_C32(0x181f0000), + SPH_C32(0x72f0015d), SPH_C32(0xc9e270d0), SPH_C32(0xfb304e73), + SPH_C32(0x7c9df973) }, + { SPH_C32(0x7afe0000), SPH_C32(0x53b60014), SPH_C32(0xbd420000), + SPH_C32(0xf0860000), SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), + SPH_C32(0x1d3a76bf), SPH_C32(0x1bb6813d), SPH_C32(0x47ff0000), + SPH_C32(0x812600d4), SPH_C32(0x5bcf0000), SPH_C32(0x36b70000), + SPH_C32(0x47392832), SPH_C32(0x935f59b7), SPH_C32(0x256c4600), + SPH_C32(0xd9267fe4) }, + { SPH_C32(0x6ee70000), SPH_C32(0x707c0028), SPH_C32(0xed9d0000), + SPH_C32(0xb4300000), SPH_C32(0x96650af3), SPH_C32(0x0746650c), + SPH_C32(0x7cdc660f), SPH_C32(0xc07c5abd), SPH_C32(0xa4bc0000), + SPH_C32(0xbb6800c0), SPH_C32(0xa9090000), SPH_C32(0x9cf90000), + SPH_C32(0x9c276a94), SPH_C32(0xb634e7a2), SPH_C32(0x3751f756), + SPH_C32(0xe368e633) }, + { SPH_C32(0x99bd0000), SPH_C32(0x69f80000), SPH_C32(0x4f840000), + SPH_C32(0x5ac80000), SPH_C32(0x56172fe5), SPH_C32(0x1ede776c), + SPH_C32(0x0f07c7e9), SPH_C32(0x21f818ea), SPH_C32(0xb0a50000), + SPH_C32(0x98a200fc), SPH_C32(0xf9d60000), SPH_C32(0xd84f0000), + SPH_C32(0x874b0d24), SPH_C32(0x8ac74bd7), SPH_C32(0x56b7e7e6), + SPH_C32(0x38a23db3) }, + { SPH_C32(0x8da40000), SPH_C32(0x4a32003c), SPH_C32(0x1f5b0000), + SPH_C32(0x1e7e0000), SPH_C32(0x4d7b4855), SPH_C32(0x222ddb19), + SPH_C32(0x6ee1d759), SPH_C32(0xfa32c36a), SPH_C32(0x53e60000), + SPH_C32(0xa2ec00e8), SPH_C32(0x0b100000), SPH_C32(0x72010000), + SPH_C32(0x5c554f82), SPH_C32(0xafacf5c2), SPH_C32(0x448a56b0), + SPH_C32(0x02eca464) }, + { SPH_C32(0x2eae0000), SPH_C32(0x55c70048), SPH_C32(0x98ec0000), + SPH_C32(0x9a980000), SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), + SPH_C32(0xa2806e7c), SPH_C32(0x65c7dc2a), SPH_C32(0xfb720000), + SPH_C32(0x7d1d00cc), SPH_C32(0x424c0000), SPH_C32(0xe7bc0000), + SPH_C32(0xe92150f6), SPH_C32(0xd1f9c1e1), SPH_C32(0x257e9c37), + SPH_C32(0xf51d2faa) }, + { SPH_C32(0x3ab70000), SPH_C32(0x760d0074), SPH_C32(0xc8330000), + SPH_C32(0xde2e0000), SPH_C32(0xb8c0442c), SPH_C32(0x6108e01e), + SPH_C32(0xc3667ecc), SPH_C32(0xbe0d07aa), SPH_C32(0x18310000), + SPH_C32(0x475300d8), SPH_C32(0xb08a0000), SPH_C32(0x4df20000), + SPH_C32(0x323f1250), SPH_C32(0xf4927ff4), SPH_C32(0x37432d61), + SPH_C32(0xcf53b67d) }, + { SPH_C32(0xcded0000), SPH_C32(0x6f89005c), SPH_C32(0x6a2a0000), + SPH_C32(0x30d60000), SPH_C32(0x78b2613a), SPH_C32(0x7890f27e), + SPH_C32(0xb0bddf2a), SPH_C32(0x5f8945fd), SPH_C32(0x0c280000), + SPH_C32(0x649900e4), SPH_C32(0xe0550000), SPH_C32(0x09440000), + SPH_C32(0x295375e0), SPH_C32(0xc861d381), SPH_C32(0x56a53dd1), + SPH_C32(0x14996dfd) }, + { SPH_C32(0xd9f40000), SPH_C32(0x4c430060), SPH_C32(0x3af50000), + SPH_C32(0x74600000), SPH_C32(0x63de068a), SPH_C32(0x44635e0b), + SPH_C32(0xd15bcf9a), SPH_C32(0x84439e7d), SPH_C32(0xef6b0000), + SPH_C32(0x5ed700f0), SPH_C32(0x12930000), SPH_C32(0xa30a0000), + SPH_C32(0xf24d3746), SPH_C32(0xed0a6d94), SPH_C32(0x44988c87), + SPH_C32(0x2ed7f42a) }, + { SPH_C32(0xaf220000), SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), + SPH_C32(0x8da20000), SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), + SPH_C32(0x9ac484f4), SPH_C32(0x8b6c72bd), SPH_C32(0x69510000), + SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), SPH_C32(0xac2f0000), + SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), SPH_C32(0x87ec287c), + SPH_C32(0xbce1a3ce) }, + { SPH_C32(0xbb3b0000), SPH_C32(0x58a600ac), SPH_C32(0x373d0000), + SPH_C32(0xc9140000), SPH_C32(0xdce87999), SPH_C32(0x8b44e886), + SPH_C32(0xfb229444), SPH_C32(0x50a6a93d), SPH_C32(0x8a120000), + SPH_C32(0xeeaf0088), SPH_C32(0x31e50000), SPH_C32(0x06610000), + SPH_C32(0x3f8b4908), SPH_C32(0xebcfabc9), SPH_C32(0x95d1992a), + SPH_C32(0x86af3a19) }, + { SPH_C32(0x4c610000), SPH_C32(0x41220084), SPH_C32(0x95240000), + SPH_C32(0x27ec0000), SPH_C32(0x1c9a5c8f), SPH_C32(0x92dcfae6), + SPH_C32(0x88f935a2), SPH_C32(0xb122eb6a), SPH_C32(0x9e0b0000), + SPH_C32(0xcd6500b4), SPH_C32(0x613a0000), SPH_C32(0x42d70000), + SPH_C32(0x24e72eb8), SPH_C32(0xd73c07bc), SPH_C32(0xf437899a), + SPH_C32(0x5d65e199) }, + { SPH_C32(0x58780000), SPH_C32(0x62e800b8), SPH_C32(0xc5fb0000), + SPH_C32(0x635a0000), SPH_C32(0x07f63b3f), SPH_C32(0xae2f5693), + SPH_C32(0xe91f2512), SPH_C32(0x6ae830ea), SPH_C32(0x7d480000), + SPH_C32(0xf72b00a0), SPH_C32(0x93fc0000), SPH_C32(0xe8990000), + SPH_C32(0xfff96c1e), SPH_C32(0xf257b9a9), SPH_C32(0xe60a38cc), + SPH_C32(0x672b784e) }, + { SPH_C32(0xfb720000), SPH_C32(0x7d1d00cc), SPH_C32(0x424c0000), + SPH_C32(0xe7bc0000), SPH_C32(0xe92150f6), SPH_C32(0xd1f9c1e1), + SPH_C32(0x257e9c37), SPH_C32(0xf51d2faa), SPH_C32(0xd5dc0000), + SPH_C32(0x28da0084), SPH_C32(0xdaa00000), SPH_C32(0x7d240000), + SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), SPH_C32(0x87fef24b), + SPH_C32(0x90daf380) }, + { SPH_C32(0xef6b0000), SPH_C32(0x5ed700f0), SPH_C32(0x12930000), + SPH_C32(0xa30a0000), SPH_C32(0xf24d3746), SPH_C32(0xed0a6d94), + SPH_C32(0x44988c87), SPH_C32(0x2ed7f42a), SPH_C32(0x369f0000), + SPH_C32(0x12940090), SPH_C32(0x28660000), SPH_C32(0xd76a0000), + SPH_C32(0x919331cc), SPH_C32(0xa969339f), SPH_C32(0x95c3431d), + SPH_C32(0xaa946a57) }, + { SPH_C32(0x18310000), SPH_C32(0x475300d8), SPH_C32(0xb08a0000), + SPH_C32(0x4df20000), SPH_C32(0x323f1250), SPH_C32(0xf4927ff4), + SPH_C32(0x37432d61), SPH_C32(0xcf53b67d), SPH_C32(0x22860000), + SPH_C32(0x315e00ac), SPH_C32(0x78b90000), SPH_C32(0x93dc0000), + SPH_C32(0x8aff567c), SPH_C32(0x959a9fea), SPH_C32(0xf42553ad), + SPH_C32(0x715eb1d7) }, + { SPH_C32(0x0c280000), SPH_C32(0x649900e4), SPH_C32(0xe0550000), + SPH_C32(0x09440000), SPH_C32(0x295375e0), SPH_C32(0xc861d381), + SPH_C32(0x56a53dd1), SPH_C32(0x14996dfd), SPH_C32(0xc1c50000), + SPH_C32(0x0b1000b8), SPH_C32(0x8a7f0000), SPH_C32(0x39920000), + SPH_C32(0x51e114da), SPH_C32(0xb0f121ff), SPH_C32(0xe618e2fb), + SPH_C32(0x4b102800) }, + { SPH_C32(0x13af0000), SPH_C32(0x87570088), SPH_C32(0x7e610000), + SPH_C32(0x5ca90000), SPH_C32(0x699c66ed), SPH_C32(0xf511dca5), + SPH_C32(0x9ad65ec3), SPH_C32(0xa75722f3), SPH_C32(0x818c0000), + SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), SPH_C32(0x173a0000), + SPH_C32(0x64283db5), SPH_C32(0xea4c0898), SPH_C32(0x3844ea88), + SPH_C32(0xeeabae97) }, + { SPH_C32(0x07b60000), SPH_C32(0xa49d00b4), SPH_C32(0x2ebe0000), + SPH_C32(0x181f0000), SPH_C32(0x72f0015d), SPH_C32(0xc9e270d0), + SPH_C32(0xfb304e73), SPH_C32(0x7c9df973), SPH_C32(0x62cf0000), + SPH_C32(0x14e500cc), SPH_C32(0x0dc80000), SPH_C32(0xbd740000), + SPH_C32(0xbf367f13), SPH_C32(0xcf27b68d), SPH_C32(0x2a795bde), + SPH_C32(0xd4e53740) }, + { SPH_C32(0xf0ec0000), SPH_C32(0xbd19009c), SPH_C32(0x8ca70000), + SPH_C32(0xf6e70000), SPH_C32(0xb282244b), SPH_C32(0xd07a62b0), + SPH_C32(0x88ebef95), SPH_C32(0x9d19bb24), SPH_C32(0x76d60000), + SPH_C32(0x372f00f0), SPH_C32(0x5d170000), SPH_C32(0xf9c20000), + SPH_C32(0xa45a18a3), SPH_C32(0xf3d41af8), SPH_C32(0x4b9f4b6e), + SPH_C32(0x0f2fecc0) }, + { SPH_C32(0xe4f50000), SPH_C32(0x9ed300a0), SPH_C32(0xdc780000), + SPH_C32(0xb2510000), SPH_C32(0xa9ee43fb), SPH_C32(0xec89cec5), + SPH_C32(0xe90dff25), SPH_C32(0x46d360a4), SPH_C32(0x95950000), + SPH_C32(0x0d6100e4), SPH_C32(0xafd10000), SPH_C32(0x538c0000), + SPH_C32(0x7f445a05), SPH_C32(0xd6bfa4ed), SPH_C32(0x59a2fa38), + SPH_C32(0x35617517) }, + { SPH_C32(0x47ff0000), SPH_C32(0x812600d4), SPH_C32(0x5bcf0000), + SPH_C32(0x36b70000), SPH_C32(0x47392832), SPH_C32(0x935f59b7), + SPH_C32(0x256c4600), SPH_C32(0xd9267fe4), SPH_C32(0x3d010000), + SPH_C32(0xd29000c0), SPH_C32(0xe68d0000), SPH_C32(0xc6310000), + SPH_C32(0xca304571), SPH_C32(0xa8ea90ce), SPH_C32(0x385630bf), + SPH_C32(0xc290fed9) }, + { SPH_C32(0x53e60000), SPH_C32(0xa2ec00e8), SPH_C32(0x0b100000), + SPH_C32(0x72010000), SPH_C32(0x5c554f82), SPH_C32(0xafacf5c2), + SPH_C32(0x448a56b0), SPH_C32(0x02eca464), SPH_C32(0xde420000), + SPH_C32(0xe8de00d4), SPH_C32(0x144b0000), SPH_C32(0x6c7f0000), + SPH_C32(0x112e07d7), SPH_C32(0x8d812edb), SPH_C32(0x2a6b81e9), + SPH_C32(0xf8de670e) }, + { SPH_C32(0xa4bc0000), SPH_C32(0xbb6800c0), SPH_C32(0xa9090000), + SPH_C32(0x9cf90000), SPH_C32(0x9c276a94), SPH_C32(0xb634e7a2), + SPH_C32(0x3751f756), SPH_C32(0xe368e633), SPH_C32(0xca5b0000), + SPH_C32(0xcb1400e8), SPH_C32(0x44940000), SPH_C32(0x28c90000), + SPH_C32(0x0a426067), SPH_C32(0xb17282ae), SPH_C32(0x4b8d9159), + SPH_C32(0x2314bc8e) }, + { SPH_C32(0xb0a50000), SPH_C32(0x98a200fc), SPH_C32(0xf9d60000), + SPH_C32(0xd84f0000), SPH_C32(0x874b0d24), SPH_C32(0x8ac74bd7), + SPH_C32(0x56b7e7e6), SPH_C32(0x38a23db3), SPH_C32(0x29180000), + SPH_C32(0xf15a00fc), SPH_C32(0xb6520000), SPH_C32(0x82870000), + SPH_C32(0xd15c22c1), SPH_C32(0x94193cbb), SPH_C32(0x59b0200f), + SPH_C32(0x195a2559) } +}; + +static const sph_u32 T512_30[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xac480000), SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), + SPH_C32(0x03430000), SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), + SPH_C32(0xfe72c7fe), SPH_C32(0x91e478f6), SPH_C32(0x1e4e0000), + SPH_C32(0xdecf0000), SPH_C32(0x6df80180), SPH_C32(0x77240000), + SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), SPH_C32(0xcda31812), + SPH_C32(0x98aa496e) }, + { SPH_C32(0x1e4e0000), SPH_C32(0xdecf0000), SPH_C32(0x6df80180), + SPH_C32(0x77240000), SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), + SPH_C32(0xcda31812), SPH_C32(0x98aa496e), SPH_C32(0xb2060000), + SPH_C32(0xc5690000), SPH_C32(0x28031200), SPH_C32(0x74670000), + SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), SPH_C32(0x33d1dfec), + SPH_C32(0x094e3198) }, + { SPH_C32(0xb2060000), SPH_C32(0xc5690000), SPH_C32(0x28031200), + SPH_C32(0x74670000), SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), + SPH_C32(0x33d1dfec), SPH_C32(0x094e3198), SPH_C32(0xac480000), + SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), SPH_C32(0x03430000), + SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), SPH_C32(0xfe72c7fe), + SPH_C32(0x91e478f6) }, + { SPH_C32(0xaec30000), SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), + SPH_C32(0x2c150000), SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), + SPH_C32(0xab92f78f), SPH_C32(0xa312567b), SPH_C32(0xdb250000), + SPH_C32(0x09290000), SPH_C32(0x49aac000), SPH_C32(0x81e10000), + SPH_C32(0xcafe6b59), SPH_C32(0x42793431), SPH_C32(0x43566b76), + SPH_C32(0xe86cba2e) }, + { SPH_C32(0x028b0000), SPH_C32(0x87e90001), SPH_C32(0x3c2af380), + SPH_C32(0x2f560000), SPH_C32(0x1f4944d9), SPH_C32(0x79e2e780), + SPH_C32(0x55e03071), SPH_C32(0x32f62e8d), SPH_C32(0xc56b0000), + SPH_C32(0xd7e60000), SPH_C32(0x2452c180), SPH_C32(0xf6c50000), + SPH_C32(0x26b96cc7), SPH_C32(0xb6d95d7f), SPH_C32(0x8ef57364), + SPH_C32(0x70c6f340) }, + { SPH_C32(0xb08d0000), SPH_C32(0x42800001), SPH_C32(0x1429e180), + SPH_C32(0x5b310000), SPH_C32(0xa98b722d), SPH_C32(0x92f0de78), + SPH_C32(0x6631ef9d), SPH_C32(0x3bb81f15), SPH_C32(0x69230000), + SPH_C32(0xcc400000), SPH_C32(0x61a9d200), SPH_C32(0xf5860000), + SPH_C32(0x7c3c5dad), SPH_C32(0xa96b0dc9), SPH_C32(0x7087b49a), + SPH_C32(0xe1228bb6) }, + { SPH_C32(0x1cc50000), SPH_C32(0x59260001), SPH_C32(0x51d2f200), + SPH_C32(0x58720000), SPH_C32(0xf30e4347), SPH_C32(0x8d428ece), + SPH_C32(0x98432863), SPH_C32(0xaa5c67e3), SPH_C32(0x776d0000), + SPH_C32(0x128f0000), SPH_C32(0x0c51d380), SPH_C32(0x82a20000), + SPH_C32(0x907b5a33), SPH_C32(0x5dcb6487), SPH_C32(0xbd24ac88), + SPH_C32(0x7988c2d8) }, + { SPH_C32(0xdb250000), SPH_C32(0x09290000), SPH_C32(0x49aac000), + SPH_C32(0x81e10000), SPH_C32(0xcafe6b59), SPH_C32(0x42793431), + SPH_C32(0x43566b76), SPH_C32(0xe86cba2e), SPH_C32(0x75e60000), + SPH_C32(0x95660001), SPH_C32(0x307b2000), SPH_C32(0xadf40000), + SPH_C32(0x8f321eea), SPH_C32(0x24298307), SPH_C32(0xe8c49cf9), + SPH_C32(0x4b7eec55) }, + { SPH_C32(0x776d0000), SPH_C32(0x128f0000), SPH_C32(0x0c51d380), + SPH_C32(0x82a20000), SPH_C32(0x907b5a33), SPH_C32(0x5dcb6487), + SPH_C32(0xbd24ac88), SPH_C32(0x7988c2d8), SPH_C32(0x6ba80000), + SPH_C32(0x4ba90001), SPH_C32(0x5d832180), SPH_C32(0xdad00000), + SPH_C32(0x63751974), SPH_C32(0xd089ea49), SPH_C32(0x256784eb), + SPH_C32(0xd3d4a53b) }, + { SPH_C32(0xc56b0000), SPH_C32(0xd7e60000), SPH_C32(0x2452c180), + SPH_C32(0xf6c50000), SPH_C32(0x26b96cc7), SPH_C32(0xb6d95d7f), + SPH_C32(0x8ef57364), SPH_C32(0x70c6f340), SPH_C32(0xc7e00000), + SPH_C32(0x500f0001), SPH_C32(0x18783200), SPH_C32(0xd9930000), + SPH_C32(0x39f0281e), SPH_C32(0xcf3bbaff), SPH_C32(0xdb154315), + SPH_C32(0x4230ddcd) }, + { SPH_C32(0x69230000), SPH_C32(0xcc400000), SPH_C32(0x61a9d200), + SPH_C32(0xf5860000), SPH_C32(0x7c3c5dad), SPH_C32(0xa96b0dc9), + SPH_C32(0x7087b49a), SPH_C32(0xe1228bb6), SPH_C32(0xd9ae0000), + SPH_C32(0x8ec00001), SPH_C32(0x75803380), SPH_C32(0xaeb70000), + SPH_C32(0xd5b72f80), SPH_C32(0x3b9bd3b1), SPH_C32(0x16b65b07), + SPH_C32(0xda9a94a3) }, + { SPH_C32(0x75e60000), SPH_C32(0x95660001), SPH_C32(0x307b2000), + SPH_C32(0xadf40000), SPH_C32(0x8f321eea), SPH_C32(0x24298307), + SPH_C32(0xe8c49cf9), SPH_C32(0x4b7eec55), SPH_C32(0xaec30000), + SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), SPH_C32(0x2c150000), + SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), SPH_C32(0xab92f78f), + SPH_C32(0xa312567b) }, + { SPH_C32(0xd9ae0000), SPH_C32(0x8ec00001), SPH_C32(0x75803380), + SPH_C32(0xaeb70000), SPH_C32(0xd5b72f80), SPH_C32(0x3b9bd3b1), + SPH_C32(0x16b65b07), SPH_C32(0xda9a94a3), SPH_C32(0xb08d0000), + SPH_C32(0x42800001), SPH_C32(0x1429e180), SPH_C32(0x5b310000), + SPH_C32(0xa98b722d), SPH_C32(0x92f0de78), SPH_C32(0x6631ef9d), + SPH_C32(0x3bb81f15) }, + { SPH_C32(0x6ba80000), SPH_C32(0x4ba90001), SPH_C32(0x5d832180), + SPH_C32(0xdad00000), SPH_C32(0x63751974), SPH_C32(0xd089ea49), + SPH_C32(0x256784eb), SPH_C32(0xd3d4a53b), SPH_C32(0x1cc50000), + SPH_C32(0x59260001), SPH_C32(0x51d2f200), SPH_C32(0x58720000), + SPH_C32(0xf30e4347), SPH_C32(0x8d428ece), SPH_C32(0x98432863), + SPH_C32(0xaa5c67e3) }, + { SPH_C32(0xc7e00000), SPH_C32(0x500f0001), SPH_C32(0x18783200), + SPH_C32(0xd9930000), SPH_C32(0x39f0281e), SPH_C32(0xcf3bbaff), + SPH_C32(0xdb154315), SPH_C32(0x4230ddcd), SPH_C32(0x028b0000), + SPH_C32(0x87e90001), SPH_C32(0x3c2af380), SPH_C32(0x2f560000), + SPH_C32(0x1f4944d9), SPH_C32(0x79e2e780), SPH_C32(0x55e03071), + SPH_C32(0x32f62e8d) }, + { SPH_C32(0x86790000), SPH_C32(0x3f390002), SPH_C32(0xe19ae000), + SPH_C32(0x98560000), SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), + SPH_C32(0xd3dd4944), SPH_C32(0x161ddab9), SPH_C32(0x30b70000), + SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), SPH_C32(0x42c40000), + SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), SPH_C32(0x21afa1ea), + SPH_C32(0xb0a51834) }, + { SPH_C32(0x2a310000), SPH_C32(0x249f0002), SPH_C32(0xa461f380), + SPH_C32(0x9b150000), SPH_C32(0xcfe05664), SPH_C32(0x513a985c), + SPH_C32(0x2daf8eba), SPH_C32(0x87f9a24f), SPH_C32(0x2ef90000), + SPH_C32(0x3b1f0000), SPH_C32(0x990c6180), SPH_C32(0x35e00000), + SPH_C32(0x8fff3af4), SPH_C32(0x8c1afd2e), SPH_C32(0xec0cb9f8), + SPH_C32(0x280f515a) }, + { SPH_C32(0x98370000), SPH_C32(0xe1f60002), SPH_C32(0x8c62e180), + SPH_C32(0xef720000), SPH_C32(0x79226090), SPH_C32(0xba28a1a4), + SPH_C32(0x1e7e5156), SPH_C32(0x8eb793d7), SPH_C32(0x82b10000), + SPH_C32(0x20b90000), SPH_C32(0xdcf77200), SPH_C32(0x36a30000), + SPH_C32(0xd57a0b9e), SPH_C32(0x93a8ad98), SPH_C32(0x127e7e06), + SPH_C32(0xb9eb29ac) }, + { SPH_C32(0x347f0000), SPH_C32(0xfa500002), SPH_C32(0xc999f200), + SPH_C32(0xec310000), SPH_C32(0x23a751fa), SPH_C32(0xa59af112), + SPH_C32(0xe00c96a8), SPH_C32(0x1f53eb21), SPH_C32(0x9cff0000), + SPH_C32(0xfe760000), SPH_C32(0xb10f7380), SPH_C32(0x41870000), + SPH_C32(0x393d0c00), SPH_C32(0x6708c4d6), SPH_C32(0xdfdd6614), + SPH_C32(0x214160c2) }, + { SPH_C32(0x28ba0000), SPH_C32(0xa3760003), SPH_C32(0x984b0000), + SPH_C32(0xb4430000), SPH_C32(0xd0a912bd), SPH_C32(0x28d87fdc), + SPH_C32(0x784fbecb), SPH_C32(0xb50f8cc2), SPH_C32(0xeb920000), + SPH_C32(0xecf90000), SPH_C32(0xbd5ea000), SPH_C32(0xc3250000), + SPH_C32(0xa9465633), SPH_C32(0x3ac3a051), SPH_C32(0x62f9ca9c), + SPH_C32(0x58c9a21a) }, + { SPH_C32(0x84f20000), SPH_C32(0xb8d00003), SPH_C32(0xddb01380), + SPH_C32(0xb7000000), SPH_C32(0x8a2c23d7), SPH_C32(0x376a2f6a), + SPH_C32(0x863d7935), SPH_C32(0x24ebf434), SPH_C32(0xf5dc0000), + SPH_C32(0x32360000), SPH_C32(0xd0a6a180), SPH_C32(0xb4010000), + SPH_C32(0x450151ad), SPH_C32(0xce63c91f), SPH_C32(0xaf5ad28e), + SPH_C32(0xc063eb74) }, + { SPH_C32(0x36f40000), SPH_C32(0x7db90003), SPH_C32(0xf5b30180), + SPH_C32(0xc3670000), SPH_C32(0x3cee1523), SPH_C32(0xdc781692), + SPH_C32(0xb5eca6d9), SPH_C32(0x2da5c5ac), SPH_C32(0x59940000), + SPH_C32(0x29900000), SPH_C32(0x955db200), SPH_C32(0xb7420000), + SPH_C32(0x1f8460c7), SPH_C32(0xd1d199a9), SPH_C32(0x51281570), + SPH_C32(0x51879382) }, + { SPH_C32(0x9abc0000), SPH_C32(0x661f0003), SPH_C32(0xb0481200), + SPH_C32(0xc0240000), SPH_C32(0x666b2449), SPH_C32(0xc3ca4624), + SPH_C32(0x4b9e6127), SPH_C32(0xbc41bd5a), SPH_C32(0x47da0000), + SPH_C32(0xf75f0000), SPH_C32(0xf8a5b380), SPH_C32(0xc0660000), + SPH_C32(0xf3c36759), SPH_C32(0x2571f0e7), SPH_C32(0x9c8b0d62), + SPH_C32(0xc92ddaec) }, + { SPH_C32(0x5d5c0000), SPH_C32(0x36100002), SPH_C32(0xa8302000), + SPH_C32(0x19b70000), SPH_C32(0x5f9b0c57), SPH_C32(0x0cf1fcdb), + SPH_C32(0x908b2232), SPH_C32(0xfe716097), SPH_C32(0x45510000), + SPH_C32(0x70b60001), SPH_C32(0xc48f4000), SPH_C32(0xef300000), + SPH_C32(0xec8a2380), SPH_C32(0x5c931767), SPH_C32(0xc96b3d13), + SPH_C32(0xfbdbf461) }, + { SPH_C32(0xf1140000), SPH_C32(0x2db60002), SPH_C32(0xedcb3380), + SPH_C32(0x1af40000), SPH_C32(0x051e3d3d), SPH_C32(0x1343ac6d), + SPH_C32(0x6ef9e5cc), SPH_C32(0x6f951861), SPH_C32(0x5b1f0000), + SPH_C32(0xae790001), SPH_C32(0xa9774180), SPH_C32(0x98140000), + SPH_C32(0x00cd241e), SPH_C32(0xa8337e29), SPH_C32(0x04c82501), + SPH_C32(0x6371bd0f) }, + { SPH_C32(0x43120000), SPH_C32(0xe8df0002), SPH_C32(0xc5c82180), + SPH_C32(0x6e930000), SPH_C32(0xb3dc0bc9), SPH_C32(0xf8519595), + SPH_C32(0x5d283a20), SPH_C32(0x66db29f9), SPH_C32(0xf7570000), + SPH_C32(0xb5df0001), SPH_C32(0xec8c5200), SPH_C32(0x9b570000), + SPH_C32(0x5a481574), SPH_C32(0xb7812e9f), SPH_C32(0xfabae2ff), + SPH_C32(0xf295c5f9) }, + { SPH_C32(0xef5a0000), SPH_C32(0xf3790002), SPH_C32(0x80333200), + SPH_C32(0x6dd00000), SPH_C32(0xe9593aa3), SPH_C32(0xe7e3c523), + SPH_C32(0xa35afdde), SPH_C32(0xf73f510f), SPH_C32(0xe9190000), + SPH_C32(0x6b100001), SPH_C32(0x81745380), SPH_C32(0xec730000), + SPH_C32(0xb60f12ea), SPH_C32(0x432147d1), SPH_C32(0x3719faed), + SPH_C32(0x6a3f8c97) }, + { SPH_C32(0xf39f0000), SPH_C32(0xaa5f0003), SPH_C32(0xd1e1c000), + SPH_C32(0x35a20000), SPH_C32(0x1a5779e4), SPH_C32(0x6aa14bed), + SPH_C32(0x3b19d5bd), SPH_C32(0x5d6336ec), SPH_C32(0x9e740000), + SPH_C32(0x799f0001), SPH_C32(0x8d258000), SPH_C32(0x6ed10000), + SPH_C32(0x267448d9), SPH_C32(0x1eea2356), SPH_C32(0x8a3d5665), + SPH_C32(0x13b74e4f) }, + { SPH_C32(0x5fd70000), SPH_C32(0xb1f90003), SPH_C32(0x941ad380), + SPH_C32(0x36e10000), SPH_C32(0x40d2488e), SPH_C32(0x75131b5b), + SPH_C32(0xc56b1243), SPH_C32(0xcc874e1a), SPH_C32(0x803a0000), + SPH_C32(0xa7500001), SPH_C32(0xe0dd8180), SPH_C32(0x19f50000), + SPH_C32(0xca334f47), SPH_C32(0xea4a4a18), SPH_C32(0x479e4e77), + SPH_C32(0x8b1d0721) }, + { SPH_C32(0xedd10000), SPH_C32(0x74900003), SPH_C32(0xbc19c180), + SPH_C32(0x42860000), SPH_C32(0xf6107e7a), SPH_C32(0x9e0122a3), + SPH_C32(0xf6bacdaf), SPH_C32(0xc5c97f82), SPH_C32(0x2c720000), + SPH_C32(0xbcf60001), SPH_C32(0xa5269200), SPH_C32(0x1ab60000), + SPH_C32(0x90b67e2d), SPH_C32(0xf5f81aae), SPH_C32(0xb9ec8989), + SPH_C32(0x1af97fd7) }, + { SPH_C32(0x41990000), SPH_C32(0x6f360003), SPH_C32(0xf9e2d200), + SPH_C32(0x41c50000), SPH_C32(0xac954f10), SPH_C32(0x81b37215), + SPH_C32(0x08c80a51), SPH_C32(0x542d0774), SPH_C32(0x323c0000), + SPH_C32(0x62390001), SPH_C32(0xc8de9380), SPH_C32(0x6d920000), + SPH_C32(0x7cf179b3), SPH_C32(0x015873e0), SPH_C32(0x744f919b), + SPH_C32(0x825336b9) }, + { SPH_C32(0x30b70000), SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), + SPH_C32(0x42c40000), SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), + SPH_C32(0x21afa1ea), SPH_C32(0xb0a51834), SPH_C32(0xb6ce0000), + SPH_C32(0xdae90002), SPH_C32(0x156e8000), SPH_C32(0xda920000), + SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), SPH_C32(0xf272e8ae), + SPH_C32(0xa6b8c28d) }, + { SPH_C32(0x9cff0000), SPH_C32(0xfe760000), SPH_C32(0xb10f7380), + SPH_C32(0x41870000), SPH_C32(0x393d0c00), SPH_C32(0x6708c4d6), + SPH_C32(0xdfdd6614), SPH_C32(0x214160c2), SPH_C32(0xa8800000), + SPH_C32(0x04260002), SPH_C32(0x78968180), SPH_C32(0xadb60000), + SPH_C32(0x1a9a5dfa), SPH_C32(0xc29235c4), SPH_C32(0x3fd1f0bc), + SPH_C32(0x3e128be3) }, + { SPH_C32(0x2ef90000), SPH_C32(0x3b1f0000), SPH_C32(0x990c6180), + SPH_C32(0x35e00000), SPH_C32(0x8fff3af4), SPH_C32(0x8c1afd2e), + SPH_C32(0xec0cb9f8), SPH_C32(0x280f515a), SPH_C32(0x04c80000), + SPH_C32(0x1f800002), SPH_C32(0x3d6d9200), SPH_C32(0xaef50000), + SPH_C32(0x401f6c90), SPH_C32(0xdd206572), SPH_C32(0xc1a33742), + SPH_C32(0xaff6f315) }, + { SPH_C32(0x82b10000), SPH_C32(0x20b90000), SPH_C32(0xdcf77200), + SPH_C32(0x36a30000), SPH_C32(0xd57a0b9e), SPH_C32(0x93a8ad98), + SPH_C32(0x127e7e06), SPH_C32(0xb9eb29ac), SPH_C32(0x1a860000), + SPH_C32(0xc14f0002), SPH_C32(0x50959380), SPH_C32(0xd9d10000), + SPH_C32(0xac586b0e), SPH_C32(0x29800c3c), SPH_C32(0x0c002f50), + SPH_C32(0x375cba7b) }, + { SPH_C32(0x9e740000), SPH_C32(0x799f0001), SPH_C32(0x8d258000), + SPH_C32(0x6ed10000), SPH_C32(0x267448d9), SPH_C32(0x1eea2356), + SPH_C32(0x8a3d5665), SPH_C32(0x13b74e4f), SPH_C32(0x6deb0000), + SPH_C32(0xd3c00002), SPH_C32(0x5cc44000), SPH_C32(0x5b730000), + SPH_C32(0x3c23313d), SPH_C32(0x744b68bb), SPH_C32(0xb12483d8), + SPH_C32(0x4ed478a3) }, + { SPH_C32(0x323c0000), SPH_C32(0x62390001), SPH_C32(0xc8de9380), + SPH_C32(0x6d920000), SPH_C32(0x7cf179b3), SPH_C32(0x015873e0), + SPH_C32(0x744f919b), SPH_C32(0x825336b9), SPH_C32(0x73a50000), + SPH_C32(0x0d0f0002), SPH_C32(0x313c4180), SPH_C32(0x2c570000), + SPH_C32(0xd06436a3), SPH_C32(0x80eb01f5), SPH_C32(0x7c879bca), + SPH_C32(0xd67e31cd) }, + { SPH_C32(0x803a0000), SPH_C32(0xa7500001), SPH_C32(0xe0dd8180), + SPH_C32(0x19f50000), SPH_C32(0xca334f47), SPH_C32(0xea4a4a18), + SPH_C32(0x479e4e77), SPH_C32(0x8b1d0721), SPH_C32(0xdfed0000), + SPH_C32(0x16a90002), SPH_C32(0x74c75200), SPH_C32(0x2f140000), + SPH_C32(0x8ae107c9), SPH_C32(0x9f595143), SPH_C32(0x82f55c34), + SPH_C32(0x479a493b) }, + { SPH_C32(0x2c720000), SPH_C32(0xbcf60001), SPH_C32(0xa5269200), + SPH_C32(0x1ab60000), SPH_C32(0x90b67e2d), SPH_C32(0xf5f81aae), + SPH_C32(0xb9ec8989), SPH_C32(0x1af97fd7), SPH_C32(0xc1a30000), + SPH_C32(0xc8660002), SPH_C32(0x193f5380), SPH_C32(0x58300000), + SPH_C32(0x66a60057), SPH_C32(0x6bf9380d), SPH_C32(0x4f564426), + SPH_C32(0xdf300055) }, + { SPH_C32(0xeb920000), SPH_C32(0xecf90000), SPH_C32(0xbd5ea000), + SPH_C32(0xc3250000), SPH_C32(0xa9465633), SPH_C32(0x3ac3a051), + SPH_C32(0x62f9ca9c), SPH_C32(0x58c9a21a), SPH_C32(0xc3280000), + SPH_C32(0x4f8f0003), SPH_C32(0x2515a000), SPH_C32(0x77660000), + SPH_C32(0x79ef448e), SPH_C32(0x121bdf8d), SPH_C32(0x1ab67457), + SPH_C32(0xedc62ed8) }, + { SPH_C32(0x47da0000), SPH_C32(0xf75f0000), SPH_C32(0xf8a5b380), + SPH_C32(0xc0660000), SPH_C32(0xf3c36759), SPH_C32(0x2571f0e7), + SPH_C32(0x9c8b0d62), SPH_C32(0xc92ddaec), SPH_C32(0xdd660000), + SPH_C32(0x91400003), SPH_C32(0x48eda180), SPH_C32(0x00420000), + SPH_C32(0x95a84310), SPH_C32(0xe6bbb6c3), SPH_C32(0xd7156c45), + SPH_C32(0x756c67b6) }, + { SPH_C32(0xf5dc0000), SPH_C32(0x32360000), SPH_C32(0xd0a6a180), + SPH_C32(0xb4010000), SPH_C32(0x450151ad), SPH_C32(0xce63c91f), + SPH_C32(0xaf5ad28e), SPH_C32(0xc063eb74), SPH_C32(0x712e0000), + SPH_C32(0x8ae60003), SPH_C32(0x0d16b200), SPH_C32(0x03010000), + SPH_C32(0xcf2d727a), SPH_C32(0xf909e675), SPH_C32(0x2967abbb), + SPH_C32(0xe4881f40) }, + { SPH_C32(0x59940000), SPH_C32(0x29900000), SPH_C32(0x955db200), + SPH_C32(0xb7420000), SPH_C32(0x1f8460c7), SPH_C32(0xd1d199a9), + SPH_C32(0x51281570), SPH_C32(0x51879382), SPH_C32(0x6f600000), + SPH_C32(0x54290003), SPH_C32(0x60eeb380), SPH_C32(0x74250000), + SPH_C32(0x236a75e4), SPH_C32(0x0da98f3b), SPH_C32(0xe4c4b3a9), + SPH_C32(0x7c22562e) }, + { SPH_C32(0x45510000), SPH_C32(0x70b60001), SPH_C32(0xc48f4000), + SPH_C32(0xef300000), SPH_C32(0xec8a2380), SPH_C32(0x5c931767), + SPH_C32(0xc96b3d13), SPH_C32(0xfbdbf461), SPH_C32(0x180d0000), + SPH_C32(0x46a60003), SPH_C32(0x6cbf6000), SPH_C32(0xf6870000), + SPH_C32(0xb3112fd7), SPH_C32(0x5062ebbc), SPH_C32(0x59e01f21), + SPH_C32(0x05aa94f6) }, + { SPH_C32(0xe9190000), SPH_C32(0x6b100001), SPH_C32(0x81745380), + SPH_C32(0xec730000), SPH_C32(0xb60f12ea), SPH_C32(0x432147d1), + SPH_C32(0x3719faed), SPH_C32(0x6a3f8c97), SPH_C32(0x06430000), + SPH_C32(0x98690003), SPH_C32(0x01476180), SPH_C32(0x81a30000), + SPH_C32(0x5f562849), SPH_C32(0xa4c282f2), SPH_C32(0x94430733), + SPH_C32(0x9d00dd98) }, + { SPH_C32(0x5b1f0000), SPH_C32(0xae790001), SPH_C32(0xa9774180), + SPH_C32(0x98140000), SPH_C32(0x00cd241e), SPH_C32(0xa8337e29), + SPH_C32(0x04c82501), SPH_C32(0x6371bd0f), SPH_C32(0xaa0b0000), + SPH_C32(0x83cf0003), SPH_C32(0x44bc7200), SPH_C32(0x82e00000), + SPH_C32(0x05d31923), SPH_C32(0xbb70d244), SPH_C32(0x6a31c0cd), + SPH_C32(0x0ce4a56e) }, + { SPH_C32(0xf7570000), SPH_C32(0xb5df0001), SPH_C32(0xec8c5200), + SPH_C32(0x9b570000), SPH_C32(0x5a481574), SPH_C32(0xb7812e9f), + SPH_C32(0xfabae2ff), SPH_C32(0xf295c5f9), SPH_C32(0xb4450000), + SPH_C32(0x5d000003), SPH_C32(0x29447380), SPH_C32(0xf5c40000), + SPH_C32(0xe9941ebd), SPH_C32(0x4fd0bb0a), SPH_C32(0xa792d8df), + SPH_C32(0x944eec00) }, + { SPH_C32(0xb6ce0000), SPH_C32(0xdae90002), SPH_C32(0x156e8000), + SPH_C32(0xda920000), SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), + SPH_C32(0xf272e8ae), SPH_C32(0xa6b8c28d), SPH_C32(0x86790000), + SPH_C32(0x3f390002), SPH_C32(0xe19ae000), SPH_C32(0x98560000), + SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), SPH_C32(0xd3dd4944), + SPH_C32(0x161ddab9) }, + { SPH_C32(0x1a860000), SPH_C32(0xc14f0002), SPH_C32(0x50959380), + SPH_C32(0xd9d10000), SPH_C32(0xac586b0e), SPH_C32(0x29800c3c), + SPH_C32(0x0c002f50), SPH_C32(0x375cba7b), SPH_C32(0x98370000), + SPH_C32(0xe1f60002), SPH_C32(0x8c62e180), SPH_C32(0xef720000), + SPH_C32(0x79226090), SPH_C32(0xba28a1a4), SPH_C32(0x1e7e5156), + SPH_C32(0x8eb793d7) }, + { SPH_C32(0xa8800000), SPH_C32(0x04260002), SPH_C32(0x78968180), + SPH_C32(0xadb60000), SPH_C32(0x1a9a5dfa), SPH_C32(0xc29235c4), + SPH_C32(0x3fd1f0bc), SPH_C32(0x3e128be3), SPH_C32(0x347f0000), + SPH_C32(0xfa500002), SPH_C32(0xc999f200), SPH_C32(0xec310000), + SPH_C32(0x23a751fa), SPH_C32(0xa59af112), SPH_C32(0xe00c96a8), + SPH_C32(0x1f53eb21) }, + { SPH_C32(0x04c80000), SPH_C32(0x1f800002), SPH_C32(0x3d6d9200), + SPH_C32(0xaef50000), SPH_C32(0x401f6c90), SPH_C32(0xdd206572), + SPH_C32(0xc1a33742), SPH_C32(0xaff6f315), SPH_C32(0x2a310000), + SPH_C32(0x249f0002), SPH_C32(0xa461f380), SPH_C32(0x9b150000), + SPH_C32(0xcfe05664), SPH_C32(0x513a985c), SPH_C32(0x2daf8eba), + SPH_C32(0x87f9a24f) }, + { SPH_C32(0x180d0000), SPH_C32(0x46a60003), SPH_C32(0x6cbf6000), + SPH_C32(0xf6870000), SPH_C32(0xb3112fd7), SPH_C32(0x5062ebbc), + SPH_C32(0x59e01f21), SPH_C32(0x05aa94f6), SPH_C32(0x5d5c0000), + SPH_C32(0x36100002), SPH_C32(0xa8302000), SPH_C32(0x19b70000), + SPH_C32(0x5f9b0c57), SPH_C32(0x0cf1fcdb), SPH_C32(0x908b2232), + SPH_C32(0xfe716097) }, + { SPH_C32(0xb4450000), SPH_C32(0x5d000003), SPH_C32(0x29447380), + SPH_C32(0xf5c40000), SPH_C32(0xe9941ebd), SPH_C32(0x4fd0bb0a), + SPH_C32(0xa792d8df), SPH_C32(0x944eec00), SPH_C32(0x43120000), + SPH_C32(0xe8df0002), SPH_C32(0xc5c82180), SPH_C32(0x6e930000), + SPH_C32(0xb3dc0bc9), SPH_C32(0xf8519595), SPH_C32(0x5d283a20), + SPH_C32(0x66db29f9) }, + { SPH_C32(0x06430000), SPH_C32(0x98690003), SPH_C32(0x01476180), + SPH_C32(0x81a30000), SPH_C32(0x5f562849), SPH_C32(0xa4c282f2), + SPH_C32(0x94430733), SPH_C32(0x9d00dd98), SPH_C32(0xef5a0000), + SPH_C32(0xf3790002), SPH_C32(0x80333200), SPH_C32(0x6dd00000), + SPH_C32(0xe9593aa3), SPH_C32(0xe7e3c523), SPH_C32(0xa35afdde), + SPH_C32(0xf73f510f) }, + { SPH_C32(0xaa0b0000), SPH_C32(0x83cf0003), SPH_C32(0x44bc7200), + SPH_C32(0x82e00000), SPH_C32(0x05d31923), SPH_C32(0xbb70d244), + SPH_C32(0x6a31c0cd), SPH_C32(0x0ce4a56e), SPH_C32(0xf1140000), + SPH_C32(0x2db60002), SPH_C32(0xedcb3380), SPH_C32(0x1af40000), + SPH_C32(0x051e3d3d), SPH_C32(0x1343ac6d), SPH_C32(0x6ef9e5cc), + SPH_C32(0x6f951861) }, + { SPH_C32(0x6deb0000), SPH_C32(0xd3c00002), SPH_C32(0x5cc44000), + SPH_C32(0x5b730000), SPH_C32(0x3c23313d), SPH_C32(0x744b68bb), + SPH_C32(0xb12483d8), SPH_C32(0x4ed478a3), SPH_C32(0xf39f0000), + SPH_C32(0xaa5f0003), SPH_C32(0xd1e1c000), SPH_C32(0x35a20000), + SPH_C32(0x1a5779e4), SPH_C32(0x6aa14bed), SPH_C32(0x3b19d5bd), + SPH_C32(0x5d6336ec) }, + { SPH_C32(0xc1a30000), SPH_C32(0xc8660002), SPH_C32(0x193f5380), + SPH_C32(0x58300000), SPH_C32(0x66a60057), SPH_C32(0x6bf9380d), + SPH_C32(0x4f564426), SPH_C32(0xdf300055), SPH_C32(0xedd10000), + SPH_C32(0x74900003), SPH_C32(0xbc19c180), SPH_C32(0x42860000), + SPH_C32(0xf6107e7a), SPH_C32(0x9e0122a3), SPH_C32(0xf6bacdaf), + SPH_C32(0xc5c97f82) }, + { SPH_C32(0x73a50000), SPH_C32(0x0d0f0002), SPH_C32(0x313c4180), + SPH_C32(0x2c570000), SPH_C32(0xd06436a3), SPH_C32(0x80eb01f5), + SPH_C32(0x7c879bca), SPH_C32(0xd67e31cd), SPH_C32(0x41990000), + SPH_C32(0x6f360003), SPH_C32(0xf9e2d200), SPH_C32(0x41c50000), + SPH_C32(0xac954f10), SPH_C32(0x81b37215), SPH_C32(0x08c80a51), + SPH_C32(0x542d0774) }, + { SPH_C32(0xdfed0000), SPH_C32(0x16a90002), SPH_C32(0x74c75200), + SPH_C32(0x2f140000), SPH_C32(0x8ae107c9), SPH_C32(0x9f595143), + SPH_C32(0x82f55c34), SPH_C32(0x479a493b), SPH_C32(0x5fd70000), + SPH_C32(0xb1f90003), SPH_C32(0x941ad380), SPH_C32(0x36e10000), + SPH_C32(0x40d2488e), SPH_C32(0x75131b5b), SPH_C32(0xc56b1243), + SPH_C32(0xcc874e1a) }, + { SPH_C32(0xc3280000), SPH_C32(0x4f8f0003), SPH_C32(0x2515a000), + SPH_C32(0x77660000), SPH_C32(0x79ef448e), SPH_C32(0x121bdf8d), + SPH_C32(0x1ab67457), SPH_C32(0xedc62ed8), SPH_C32(0x28ba0000), + SPH_C32(0xa3760003), SPH_C32(0x984b0000), SPH_C32(0xb4430000), + SPH_C32(0xd0a912bd), SPH_C32(0x28d87fdc), SPH_C32(0x784fbecb), + SPH_C32(0xb50f8cc2) }, + { SPH_C32(0x6f600000), SPH_C32(0x54290003), SPH_C32(0x60eeb380), + SPH_C32(0x74250000), SPH_C32(0x236a75e4), SPH_C32(0x0da98f3b), + SPH_C32(0xe4c4b3a9), SPH_C32(0x7c22562e), SPH_C32(0x36f40000), + SPH_C32(0x7db90003), SPH_C32(0xf5b30180), SPH_C32(0xc3670000), + SPH_C32(0x3cee1523), SPH_C32(0xdc781692), SPH_C32(0xb5eca6d9), + SPH_C32(0x2da5c5ac) }, + { SPH_C32(0xdd660000), SPH_C32(0x91400003), SPH_C32(0x48eda180), + SPH_C32(0x00420000), SPH_C32(0x95a84310), SPH_C32(0xe6bbb6c3), + SPH_C32(0xd7156c45), SPH_C32(0x756c67b6), SPH_C32(0x9abc0000), + SPH_C32(0x661f0003), SPH_C32(0xb0481200), SPH_C32(0xc0240000), + SPH_C32(0x666b2449), SPH_C32(0xc3ca4624), SPH_C32(0x4b9e6127), + SPH_C32(0xbc41bd5a) }, + { SPH_C32(0x712e0000), SPH_C32(0x8ae60003), SPH_C32(0x0d16b200), + SPH_C32(0x03010000), SPH_C32(0xcf2d727a), SPH_C32(0xf909e675), + SPH_C32(0x2967abbb), SPH_C32(0xe4881f40), SPH_C32(0x84f20000), + SPH_C32(0xb8d00003), SPH_C32(0xddb01380), SPH_C32(0xb7000000), + SPH_C32(0x8a2c23d7), SPH_C32(0x376a2f6a), SPH_C32(0x863d7935), + SPH_C32(0x24ebf434) } +}; + +static const sph_u32 T512_36[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x52500000), SPH_C32(0x29540000), SPH_C32(0x6a61004e), + SPH_C32(0xf0ff0000), SPH_C32(0x9a317eec), SPH_C32(0x452341ce), + SPH_C32(0xcf568fe5), SPH_C32(0x5303130f), SPH_C32(0x538d0000), + SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), SPH_C32(0x56ff0000), + SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), SPH_C32(0xa9444018), + SPH_C32(0x7f975691) }, + { SPH_C32(0x538d0000), SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), + SPH_C32(0x56ff0000), SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), + SPH_C32(0xa9444018), SPH_C32(0x7f975691), SPH_C32(0x01dd0000), + SPH_C32(0x80a80000), SPH_C32(0xf4960048), SPH_C32(0xa6000000), + SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), SPH_C32(0x6612cffd), + SPH_C32(0x2c94459e) }, + { SPH_C32(0x01dd0000), SPH_C32(0x80a80000), SPH_C32(0xf4960048), + SPH_C32(0xa6000000), SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), + SPH_C32(0x6612cffd), SPH_C32(0x2c94459e), SPH_C32(0x52500000), + SPH_C32(0x29540000), SPH_C32(0x6a61004e), SPH_C32(0xf0ff0000), + SPH_C32(0x9a317eec), SPH_C32(0x452341ce), SPH_C32(0xcf568fe5), + SPH_C32(0x5303130f) }, + { SPH_C32(0xcc140000), SPH_C32(0xa5630000), SPH_C32(0x5ab90780), + SPH_C32(0x3b500000), SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), + SPH_C32(0x694348c1), SPH_C32(0xca5a87fe), SPH_C32(0x819e0000), + SPH_C32(0xec570000), SPH_C32(0x66320280), SPH_C32(0x95f30000), + SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), SPH_C32(0xe65aa22d), + SPH_C32(0x8e67b7fa) }, + { SPH_C32(0x9e440000), SPH_C32(0x8c370000), SPH_C32(0x30d807ce), + SPH_C32(0xcbaf0000), SPH_C32(0xd1e16d13), SPH_C32(0xc2b875d6), + SPH_C32(0xa615c724), SPH_C32(0x995994f1), SPH_C32(0xd2130000), + SPH_C32(0x45ab0000), SPH_C32(0xf8c50286), SPH_C32(0xc30c0000), + SPH_C32(0x574d284c), SPH_C32(0xda31f145), SPH_C32(0x4f1ee235), + SPH_C32(0xf1f0e16b) }, + { SPH_C32(0x9f990000), SPH_C32(0x0c9f0000), SPH_C32(0xc44e0786), + SPH_C32(0x6daf0000), SPH_C32(0x413413b1), SPH_C32(0x155ef9e1), + SPH_C32(0xc00708d9), SPH_C32(0xb5cdd16f), SPH_C32(0x80430000), + SPH_C32(0x6cff0000), SPH_C32(0x92a402c8), SPH_C32(0x33f30000), + SPH_C32(0xcd7c56a0), SPH_C32(0x9f12b08b), SPH_C32(0x80486dd0), + SPH_C32(0xa2f3f264) }, + { SPH_C32(0xcdc90000), SPH_C32(0x25cb0000), SPH_C32(0xae2f07c8), + SPH_C32(0x9d500000), SPH_C32(0xdb056d5d), SPH_C32(0x507db82f), + SPH_C32(0x0f51873c), SPH_C32(0xe6cec260), SPH_C32(0xd3ce0000), + SPH_C32(0xc5030000), SPH_C32(0x0c5302ce), SPH_C32(0x650c0000), + SPH_C32(0xc79856ee), SPH_C32(0x0dd77d72), SPH_C32(0x290c2dc8), + SPH_C32(0xdd64a4f5) }, + { SPH_C32(0x819e0000), SPH_C32(0xec570000), SPH_C32(0x66320280), + SPH_C32(0x95f30000), SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), + SPH_C32(0xe65aa22d), SPH_C32(0x8e67b7fa), SPH_C32(0x4d8a0000), + SPH_C32(0x49340000), SPH_C32(0x3c8b0500), SPH_C32(0xaea30000), + SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), SPH_C32(0x8f19eaec), + SPH_C32(0x443d3004) }, + { SPH_C32(0xd3ce0000), SPH_C32(0xc5030000), SPH_C32(0x0c5302ce), + SPH_C32(0x650c0000), SPH_C32(0xc79856ee), SPH_C32(0x0dd77d72), + SPH_C32(0x290c2dc8), SPH_C32(0xdd64a4f5), SPH_C32(0x1e070000), + SPH_C32(0xe0c80000), SPH_C32(0xa27c0506), SPH_C32(0xf85c0000), + SPH_C32(0x1c9d3bb3), SPH_C32(0x5daac55d), SPH_C32(0x265daaf4), + SPH_C32(0x3baa6695) }, + { SPH_C32(0xd2130000), SPH_C32(0x45ab0000), SPH_C32(0xf8c50286), + SPH_C32(0xc30c0000), SPH_C32(0x574d284c), SPH_C32(0xda31f145), + SPH_C32(0x4f1ee235), SPH_C32(0xf1f0e16b), SPH_C32(0x4c570000), + SPH_C32(0xc99c0000), SPH_C32(0xc81d0548), SPH_C32(0x08a30000), + SPH_C32(0x86ac455f), SPH_C32(0x18898493), SPH_C32(0xe90b2511), + SPH_C32(0x68a9759a) }, + { SPH_C32(0x80430000), SPH_C32(0x6cff0000), SPH_C32(0x92a402c8), + SPH_C32(0x33f30000), SPH_C32(0xcd7c56a0), SPH_C32(0x9f12b08b), + SPH_C32(0x80486dd0), SPH_C32(0xa2f3f264), SPH_C32(0x1fda0000), + SPH_C32(0x60600000), SPH_C32(0x56ea054e), SPH_C32(0x5e5c0000), + SPH_C32(0x8c484511), SPH_C32(0x8a4c496a), SPH_C32(0x404f6509), + SPH_C32(0x173e230b) }, + { SPH_C32(0x4d8a0000), SPH_C32(0x49340000), SPH_C32(0x3c8b0500), + SPH_C32(0xaea30000), SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), + SPH_C32(0x8f19eaec), SPH_C32(0x443d3004), SPH_C32(0xcc140000), + SPH_C32(0xa5630000), SPH_C32(0x5ab90780), SPH_C32(0x3b500000), + SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), SPH_C32(0x694348c1), + SPH_C32(0xca5a87fe) }, + { SPH_C32(0x1fda0000), SPH_C32(0x60600000), SPH_C32(0x56ea054e), + SPH_C32(0x5e5c0000), SPH_C32(0x8c484511), SPH_C32(0x8a4c496a), + SPH_C32(0x404f6509), SPH_C32(0x173e230b), SPH_C32(0x9f990000), + SPH_C32(0x0c9f0000), SPH_C32(0xc44e0786), SPH_C32(0x6daf0000), + SPH_C32(0x413413b1), SPH_C32(0x155ef9e1), SPH_C32(0xc00708d9), + SPH_C32(0xb5cdd16f) }, + { SPH_C32(0x1e070000), SPH_C32(0xe0c80000), SPH_C32(0xa27c0506), + SPH_C32(0xf85c0000), SPH_C32(0x1c9d3bb3), SPH_C32(0x5daac55d), + SPH_C32(0x265daaf4), SPH_C32(0x3baa6695), SPH_C32(0xcdc90000), + SPH_C32(0x25cb0000), SPH_C32(0xae2f07c8), SPH_C32(0x9d500000), + SPH_C32(0xdb056d5d), SPH_C32(0x507db82f), SPH_C32(0x0f51873c), + SPH_C32(0xe6cec260) }, + { SPH_C32(0x4c570000), SPH_C32(0xc99c0000), SPH_C32(0xc81d0548), + SPH_C32(0x08a30000), SPH_C32(0x86ac455f), SPH_C32(0x18898493), + SPH_C32(0xe90b2511), SPH_C32(0x68a9759a), SPH_C32(0x9e440000), + SPH_C32(0x8c370000), SPH_C32(0x30d807ce), SPH_C32(0xcbaf0000), + SPH_C32(0xd1e16d13), SPH_C32(0xc2b875d6), SPH_C32(0xa615c724), + SPH_C32(0x995994f1) }, + { SPH_C32(0x78230000), SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), + SPH_C32(0x90a50000), SPH_C32(0x713e2879), SPH_C32(0x7ee98924), + SPH_C32(0xf08ca062), SPH_C32(0x636f8bab), SPH_C32(0x02af0000), + SPH_C32(0xb7280000), SPH_C32(0xba1c0300), SPH_C32(0x56980000), + SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), SPH_C32(0xa95c149a), + SPH_C32(0xf4f6ea7b) }, + { SPH_C32(0x2a730000), SPH_C32(0x3ba80000), SPH_C32(0xc35b0bce), + SPH_C32(0x605a0000), SPH_C32(0xeb0f5695), SPH_C32(0x3bcac8ea), + SPH_C32(0x3fda2f87), SPH_C32(0x306c98a4), SPH_C32(0x51220000), + SPH_C32(0x1ed40000), SPH_C32(0x24eb0306), SPH_C32(0x00670000), + SPH_C32(0xb069459d), SPH_C32(0x128d0b9e), SPH_C32(0x00185482), + SPH_C32(0x8b61bcea) }, + { SPH_C32(0x2bae0000), SPH_C32(0xbb000000), SPH_C32(0x37cd0b86), + SPH_C32(0xc65a0000), SPH_C32(0x7bda2837), SPH_C32(0xec2c44dd), + SPH_C32(0x59c8e07a), SPH_C32(0x1cf8dd3a), SPH_C32(0x03720000), + SPH_C32(0x37800000), SPH_C32(0x4e8a0348), SPH_C32(0xf0980000), + SPH_C32(0x2a583b71), SPH_C32(0x57ae4a50), SPH_C32(0xcf4edb67), + SPH_C32(0xd862afe5) }, + { SPH_C32(0x79fe0000), SPH_C32(0x92540000), SPH_C32(0x5dac0bc8), + SPH_C32(0x36a50000), SPH_C32(0xe1eb56db), SPH_C32(0xa90f0513), + SPH_C32(0x969e6f9f), SPH_C32(0x4ffbce35), SPH_C32(0x50ff0000), + SPH_C32(0x9e7c0000), SPH_C32(0xd07d034e), SPH_C32(0xa6670000), + SPH_C32(0x20bc3b3f), SPH_C32(0xc56b87a9), SPH_C32(0x660a9b7f), + SPH_C32(0xa7f5f974) }, + { SPH_C32(0xb4370000), SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), + SPH_C32(0xabf50000), SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), + SPH_C32(0x99cfe8a3), SPH_C32(0xa9350c55), SPH_C32(0x83310000), + SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), SPH_C32(0xc36b0000), + SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), SPH_C32(0x4f06b6b7), + SPH_C32(0x7a915d81) }, + { SPH_C32(0xe6670000), SPH_C32(0x9ecb0000), SPH_C32(0x99e20c4e), + SPH_C32(0x5b0a0000), SPH_C32(0xa0df456a), SPH_C32(0xbc51fcf2), + SPH_C32(0x56996746), SPH_C32(0xfa361f5a), SPH_C32(0xd0bc0000), + SPH_C32(0xf2830000), SPH_C32(0x42d90186), SPH_C32(0x95940000), + SPH_C32(0xedc06d9f), SPH_C32(0x5a793722), SPH_C32(0xe642f6af), + SPH_C32(0x05060b10) }, + { SPH_C32(0xe7ba0000), SPH_C32(0x1e630000), SPH_C32(0x6d740c06), + SPH_C32(0xfd0a0000), SPH_C32(0x300a3bc8), SPH_C32(0x6bb770c5), + SPH_C32(0x308ba8bb), SPH_C32(0xd6a25ac4), SPH_C32(0x82ec0000), + SPH_C32(0xdbd70000), SPH_C32(0x28b801c8), SPH_C32(0x656b0000), + SPH_C32(0x77f11373), SPH_C32(0x1f5a76ec), SPH_C32(0x2914794a), + SPH_C32(0x5605181f) }, + { SPH_C32(0xb5ea0000), SPH_C32(0x37370000), SPH_C32(0x07150c48), + SPH_C32(0x0df50000), SPH_C32(0xaa3b4524), SPH_C32(0x2e94310b), + SPH_C32(0xffdd275e), SPH_C32(0x85a149cb), SPH_C32(0xd1610000), + SPH_C32(0x722b0000), SPH_C32(0xb64f01ce), SPH_C32(0x33940000), + SPH_C32(0x7d15133d), SPH_C32(0x8d9fbb15), SPH_C32(0x80503952), + SPH_C32(0x29924e8e) }, + { SPH_C32(0xf9bd0000), SPH_C32(0xfeab0000), SPH_C32(0xcf080900), + SPH_C32(0x05560000), SPH_C32(0x2c97007b), SPH_C32(0x361db598), + SPH_C32(0x16d6024f), SPH_C32(0xed083c51), SPH_C32(0x4f250000), + SPH_C32(0xfe1c0000), SPH_C32(0x86970600), SPH_C32(0xf83b0000), + SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), SPH_C32(0x2645fe76), + SPH_C32(0xb0cbda7f) }, + { SPH_C32(0xabed0000), SPH_C32(0xd7ff0000), SPH_C32(0xa569094e), + SPH_C32(0xf5a90000), SPH_C32(0xb6a67e97), SPH_C32(0x733ef456), + SPH_C32(0xd9808daa), SPH_C32(0xbe0b2f5e), SPH_C32(0x1ca80000), + SPH_C32(0x57e00000), SPH_C32(0x18600606), SPH_C32(0xaec40000), + SPH_C32(0xa6107e60), SPH_C32(0xdde2033a), SPH_C32(0x8f01be6e), + SPH_C32(0xcf5c8cee) }, + { SPH_C32(0xaa300000), SPH_C32(0x57570000), SPH_C32(0x51ff0906), + SPH_C32(0x53a90000), SPH_C32(0x26730035), SPH_C32(0xa4d87861), + SPH_C32(0xbf924257), SPH_C32(0x929f6ac0), SPH_C32(0x4ef80000), + SPH_C32(0x7eb40000), SPH_C32(0x72010648), SPH_C32(0x5e3b0000), + SPH_C32(0x3c21008c), SPH_C32(0x98c142f4), SPH_C32(0x4057318b), + SPH_C32(0x9c5f9fe1) }, + { SPH_C32(0xf8600000), SPH_C32(0x7e030000), SPH_C32(0x3b9e0948), + SPH_C32(0xa3560000), SPH_C32(0xbc427ed9), SPH_C32(0xe1fb39af), + SPH_C32(0x70c4cdb2), SPH_C32(0xc19c79cf), SPH_C32(0x1d750000), + SPH_C32(0xd7480000), SPH_C32(0xecf6064e), SPH_C32(0x08c40000), + SPH_C32(0x36c500c2), SPH_C32(0x0a048f0d), SPH_C32(0xe9137193), + SPH_C32(0xe3c8c970) }, + { SPH_C32(0x35a90000), SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), + SPH_C32(0x3e060000), SPH_C32(0x67471384), SPH_C32(0xb1868180), + SPH_C32(0x7f954a8e), SPH_C32(0x2752bbaf), SPH_C32(0xcebb0000), + SPH_C32(0x124b0000), SPH_C32(0xe0a50480), SPH_C32(0x6dc80000), + SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), SPH_C32(0xc01f5c5b), + SPH_C32(0x3eac6d85) }, + { SPH_C32(0x67f90000), SPH_C32(0x729c0000), SPH_C32(0xffd00ece), + SPH_C32(0xcef90000), SPH_C32(0xfd766d68), SPH_C32(0xf4a5c04e), + SPH_C32(0xb0c3c56b), SPH_C32(0x7451a8a0), SPH_C32(0x9d360000), + SPH_C32(0xbbb70000), SPH_C32(0x7e520486), SPH_C32(0x3b370000), + SPH_C32(0xfbb95662), SPH_C32(0x95163f86), SPH_C32(0x695b1c43), + SPH_C32(0x413b3b14) }, + { SPH_C32(0x66240000), SPH_C32(0xf2340000), SPH_C32(0x0b460e86), + SPH_C32(0x68f90000), SPH_C32(0x6da313ca), SPH_C32(0x23434c79), + SPH_C32(0xd6d10a96), SPH_C32(0x58c5ed3e), SPH_C32(0xcf660000), + SPH_C32(0x92e30000), SPH_C32(0x143304c8), SPH_C32(0xcbc80000), + SPH_C32(0x6188288e), SPH_C32(0xd0357e48), SPH_C32(0xa60d93a6), + SPH_C32(0x1238281b) }, + { SPH_C32(0x34740000), SPH_C32(0xdb600000), SPH_C32(0x61270ec8), + SPH_C32(0x98060000), SPH_C32(0xf7926d26), SPH_C32(0x66600db7), + SPH_C32(0x19878573), SPH_C32(0x0bc6fe31), SPH_C32(0x9ceb0000), + SPH_C32(0x3b1f0000), SPH_C32(0x8ac404ce), SPH_C32(0x9d370000), + SPH_C32(0x6b6c28c0), SPH_C32(0x42f0b3b1), SPH_C32(0x0f49d3be), + SPH_C32(0x6daf7e8a) }, + { SPH_C32(0x02af0000), SPH_C32(0xb7280000), SPH_C32(0xba1c0300), + SPH_C32(0x56980000), SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), + SPH_C32(0xa95c149a), SPH_C32(0xf4f6ea7b), SPH_C32(0x7a8c0000), + SPH_C32(0xa5d40000), SPH_C32(0x13260880), SPH_C32(0xc63d0000), + SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), SPH_C32(0x59d0b4f8), + SPH_C32(0x979961d0) }, + { SPH_C32(0x50ff0000), SPH_C32(0x9e7c0000), SPH_C32(0xd07d034e), + SPH_C32(0xa6670000), SPH_C32(0x20bc3b3f), SPH_C32(0xc56b87a9), + SPH_C32(0x660a9b7f), SPH_C32(0xa7f5f974), SPH_C32(0x29010000), + SPH_C32(0x0c280000), SPH_C32(0x8dd10886), SPH_C32(0x90c20000), + SPH_C32(0xc1576de4), SPH_C32(0x6c6482ba), SPH_C32(0xf094f4e0), + SPH_C32(0xe80e3741) }, + { SPH_C32(0x51220000), SPH_C32(0x1ed40000), SPH_C32(0x24eb0306), + SPH_C32(0x00670000), SPH_C32(0xb069459d), SPH_C32(0x128d0b9e), + SPH_C32(0x00185482), SPH_C32(0x8b61bcea), SPH_C32(0x7b510000), + SPH_C32(0x257c0000), SPH_C32(0xe7b008c8), SPH_C32(0x603d0000), + SPH_C32(0x5b661308), SPH_C32(0x2947c374), SPH_C32(0x3fc27b05), + SPH_C32(0xbb0d244e) }, + { SPH_C32(0x03720000), SPH_C32(0x37800000), SPH_C32(0x4e8a0348), + SPH_C32(0xf0980000), SPH_C32(0x2a583b71), SPH_C32(0x57ae4a50), + SPH_C32(0xcf4edb67), SPH_C32(0xd862afe5), SPH_C32(0x28dc0000), + SPH_C32(0x8c800000), SPH_C32(0x794708ce), SPH_C32(0x36c20000), + SPH_C32(0x51821346), SPH_C32(0xbb820e8d), SPH_C32(0x96863b1d), + SPH_C32(0xc49a72df) }, + { SPH_C32(0xcebb0000), SPH_C32(0x124b0000), SPH_C32(0xe0a50480), + SPH_C32(0x6dc80000), SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), + SPH_C32(0xc01f5c5b), SPH_C32(0x3eac6d85), SPH_C32(0xfb120000), + SPH_C32(0x49830000), SPH_C32(0x75140a00), SPH_C32(0x53ce0000), + SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), SPH_C32(0xbf8a16d5), + SPH_C32(0x19fed62a) }, + { SPH_C32(0x9ceb0000), SPH_C32(0x3b1f0000), SPH_C32(0x8ac404ce), + SPH_C32(0x9d370000), SPH_C32(0x6b6c28c0), SPH_C32(0x42f0b3b1), + SPH_C32(0x0f49d3be), SPH_C32(0x6daf7e8a), SPH_C32(0xa89f0000), + SPH_C32(0xe07f0000), SPH_C32(0xebe30a06), SPH_C32(0x05310000), + SPH_C32(0x9cfe45e6), SPH_C32(0x2490be06), SPH_C32(0x16ce56cd), + SPH_C32(0x666980bb) }, + { SPH_C32(0x9d360000), SPH_C32(0xbbb70000), SPH_C32(0x7e520486), + SPH_C32(0x3b370000), SPH_C32(0xfbb95662), SPH_C32(0x95163f86), + SPH_C32(0x695b1c43), SPH_C32(0x413b3b14), SPH_C32(0xfacf0000), + SPH_C32(0xc92b0000), SPH_C32(0x81820a48), SPH_C32(0xf5ce0000), + SPH_C32(0x06cf3b0a), SPH_C32(0x61b3ffc8), SPH_C32(0xd998d928), + SPH_C32(0x356a93b4) }, + { SPH_C32(0xcf660000), SPH_C32(0x92e30000), SPH_C32(0x143304c8), + SPH_C32(0xcbc80000), SPH_C32(0x6188288e), SPH_C32(0xd0357e48), + SPH_C32(0xa60d93a6), SPH_C32(0x1238281b), SPH_C32(0xa9420000), + SPH_C32(0x60d70000), SPH_C32(0x1f750a4e), SPH_C32(0xa3310000), + SPH_C32(0x0c2b3b44), SPH_C32(0xf3763231), SPH_C32(0x70dc9930), + SPH_C32(0x4afdc525) }, + { SPH_C32(0x83310000), SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), + SPH_C32(0xc36b0000), SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), + SPH_C32(0x4f06b6b7), SPH_C32(0x7a915d81), SPH_C32(0x37060000), + SPH_C32(0xece00000), SPH_C32(0x2fad0d80), SPH_C32(0x689e0000), + SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), SPH_C32(0xd6c95e14), + SPH_C32(0xd3a451d4) }, + { SPH_C32(0xd1610000), SPH_C32(0x722b0000), SPH_C32(0xb64f01ce), + SPH_C32(0x33940000), SPH_C32(0x7d15133d), SPH_C32(0x8d9fbb15), + SPH_C32(0x80503952), SPH_C32(0x29924e8e), SPH_C32(0x648b0000), + SPH_C32(0x451c0000), SPH_C32(0xb15a0d86), SPH_C32(0x3e610000), + SPH_C32(0xd72e5619), SPH_C32(0xa30b8a1e), SPH_C32(0x7f8d1e0c), + SPH_C32(0xac330745) }, + { SPH_C32(0xd0bc0000), SPH_C32(0xf2830000), SPH_C32(0x42d90186), + SPH_C32(0x95940000), SPH_C32(0xedc06d9f), SPH_C32(0x5a793722), + SPH_C32(0xe642f6af), SPH_C32(0x05060b10), SPH_C32(0x36db0000), + SPH_C32(0x6c480000), SPH_C32(0xdb3b0dc8), SPH_C32(0xce9e0000), + SPH_C32(0x4d1f28f5), SPH_C32(0xe628cbd0), SPH_C32(0xb0db91e9), + SPH_C32(0xff30144a) }, + { SPH_C32(0x82ec0000), SPH_C32(0xdbd70000), SPH_C32(0x28b801c8), + SPH_C32(0x656b0000), SPH_C32(0x77f11373), SPH_C32(0x1f5a76ec), + SPH_C32(0x2914794a), SPH_C32(0x5605181f), SPH_C32(0x65560000), + SPH_C32(0xc5b40000), SPH_C32(0x45cc0dce), SPH_C32(0x98610000), + SPH_C32(0x47fb28bb), SPH_C32(0x74ed0629), SPH_C32(0x199fd1f1), + SPH_C32(0x80a742db) }, + { SPH_C32(0x4f250000), SPH_C32(0xfe1c0000), SPH_C32(0x86970600), + SPH_C32(0xf83b0000), SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), + SPH_C32(0x2645fe76), SPH_C32(0xb0cbda7f), SPH_C32(0xb6980000), + SPH_C32(0x00b70000), SPH_C32(0x499f0f00), SPH_C32(0xfd6d0000), + SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), SPH_C32(0x3093fc39), + SPH_C32(0x5dc3e62e) }, + { SPH_C32(0x1d750000), SPH_C32(0xd7480000), SPH_C32(0xecf6064e), + SPH_C32(0x08c40000), SPH_C32(0x36c500c2), SPH_C32(0x0a048f0d), + SPH_C32(0xe9137193), SPH_C32(0xe3c8c970), SPH_C32(0xe5150000), + SPH_C32(0xa94b0000), SPH_C32(0xd7680f06), SPH_C32(0xab920000), + SPH_C32(0x8a877e1b), SPH_C32(0xebffb6a2), SPH_C32(0x99d7bc21), + SPH_C32(0x2254b0bf) }, + { SPH_C32(0x1ca80000), SPH_C32(0x57e00000), SPH_C32(0x18600606), + SPH_C32(0xaec40000), SPH_C32(0xa6107e60), SPH_C32(0xdde2033a), + SPH_C32(0x8f01be6e), SPH_C32(0xcf5c8cee), SPH_C32(0xb7450000), + SPH_C32(0x801f0000), SPH_C32(0xbd090f48), SPH_C32(0x5b6d0000), + SPH_C32(0x10b600f7), SPH_C32(0xaedcf76c), SPH_C32(0x568133c4), + SPH_C32(0x7157a3b0) }, + { SPH_C32(0x4ef80000), SPH_C32(0x7eb40000), SPH_C32(0x72010648), + SPH_C32(0x5e3b0000), SPH_C32(0x3c21008c), SPH_C32(0x98c142f4), + SPH_C32(0x4057318b), SPH_C32(0x9c5f9fe1), SPH_C32(0xe4c80000), + SPH_C32(0x29e30000), SPH_C32(0x23fe0f4e), SPH_C32(0x0d920000), + SPH_C32(0x1a5200b9), SPH_C32(0x3c193a95), SPH_C32(0xffc573dc), + SPH_C32(0x0ec0f521) }, + { SPH_C32(0x7a8c0000), SPH_C32(0xa5d40000), SPH_C32(0x13260880), + SPH_C32(0xc63d0000), SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), + SPH_C32(0x59d0b4f8), SPH_C32(0x979961d0), SPH_C32(0x78230000), + SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), SPH_C32(0x90a50000), + SPH_C32(0x713e2879), SPH_C32(0x7ee98924), SPH_C32(0xf08ca062), + SPH_C32(0x636f8bab) }, + { SPH_C32(0x28dc0000), SPH_C32(0x8c800000), SPH_C32(0x794708ce), + SPH_C32(0x36c20000), SPH_C32(0x51821346), SPH_C32(0xbb820e8d), + SPH_C32(0x96863b1d), SPH_C32(0xc49a72df), SPH_C32(0x2bae0000), + SPH_C32(0xbb000000), SPH_C32(0x37cd0b86), SPH_C32(0xc65a0000), + SPH_C32(0x7bda2837), SPH_C32(0xec2c44dd), SPH_C32(0x59c8e07a), + SPH_C32(0x1cf8dd3a) }, + { SPH_C32(0x29010000), SPH_C32(0x0c280000), SPH_C32(0x8dd10886), + SPH_C32(0x90c20000), SPH_C32(0xc1576de4), SPH_C32(0x6c6482ba), + SPH_C32(0xf094f4e0), SPH_C32(0xe80e3741), SPH_C32(0x79fe0000), + SPH_C32(0x92540000), SPH_C32(0x5dac0bc8), SPH_C32(0x36a50000), + SPH_C32(0xe1eb56db), SPH_C32(0xa90f0513), SPH_C32(0x969e6f9f), + SPH_C32(0x4ffbce35) }, + { SPH_C32(0x7b510000), SPH_C32(0x257c0000), SPH_C32(0xe7b008c8), + SPH_C32(0x603d0000), SPH_C32(0x5b661308), SPH_C32(0x2947c374), + SPH_C32(0x3fc27b05), SPH_C32(0xbb0d244e), SPH_C32(0x2a730000), + SPH_C32(0x3ba80000), SPH_C32(0xc35b0bce), SPH_C32(0x605a0000), + SPH_C32(0xeb0f5695), SPH_C32(0x3bcac8ea), SPH_C32(0x3fda2f87), + SPH_C32(0x306c98a4) }, + { SPH_C32(0xb6980000), SPH_C32(0x00b70000), SPH_C32(0x499f0f00), + SPH_C32(0xfd6d0000), SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), + SPH_C32(0x3093fc39), SPH_C32(0x5dc3e62e), SPH_C32(0xf9bd0000), + SPH_C32(0xfeab0000), SPH_C32(0xcf080900), SPH_C32(0x05560000), + SPH_C32(0x2c97007b), SPH_C32(0x361db598), SPH_C32(0x16d6024f), + SPH_C32(0xed083c51) }, + { SPH_C32(0xe4c80000), SPH_C32(0x29e30000), SPH_C32(0x23fe0f4e), + SPH_C32(0x0d920000), SPH_C32(0x1a5200b9), SPH_C32(0x3c193a95), + SPH_C32(0xffc573dc), SPH_C32(0x0ec0f521), SPH_C32(0xaa300000), + SPH_C32(0x57570000), SPH_C32(0x51ff0906), SPH_C32(0x53a90000), + SPH_C32(0x26730035), SPH_C32(0xa4d87861), SPH_C32(0xbf924257), + SPH_C32(0x929f6ac0) }, + { SPH_C32(0xe5150000), SPH_C32(0xa94b0000), SPH_C32(0xd7680f06), + SPH_C32(0xab920000), SPH_C32(0x8a877e1b), SPH_C32(0xebffb6a2), + SPH_C32(0x99d7bc21), SPH_C32(0x2254b0bf), SPH_C32(0xf8600000), + SPH_C32(0x7e030000), SPH_C32(0x3b9e0948), SPH_C32(0xa3560000), + SPH_C32(0xbc427ed9), SPH_C32(0xe1fb39af), SPH_C32(0x70c4cdb2), + SPH_C32(0xc19c79cf) }, + { SPH_C32(0xb7450000), SPH_C32(0x801f0000), SPH_C32(0xbd090f48), + SPH_C32(0x5b6d0000), SPH_C32(0x10b600f7), SPH_C32(0xaedcf76c), + SPH_C32(0x568133c4), SPH_C32(0x7157a3b0), SPH_C32(0xabed0000), + SPH_C32(0xd7ff0000), SPH_C32(0xa569094e), SPH_C32(0xf5a90000), + SPH_C32(0xb6a67e97), SPH_C32(0x733ef456), SPH_C32(0xd9808daa), + SPH_C32(0xbe0b2f5e) }, + { SPH_C32(0xfb120000), SPH_C32(0x49830000), SPH_C32(0x75140a00), + SPH_C32(0x53ce0000), SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), + SPH_C32(0xbf8a16d5), SPH_C32(0x19fed62a), SPH_C32(0x35a90000), + SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), SPH_C32(0x3e060000), + SPH_C32(0x67471384), SPH_C32(0xb1868180), SPH_C32(0x7f954a8e), + SPH_C32(0x2752bbaf) }, + { SPH_C32(0xa9420000), SPH_C32(0x60d70000), SPH_C32(0x1f750a4e), + SPH_C32(0xa3310000), SPH_C32(0x0c2b3b44), SPH_C32(0xf3763231), + SPH_C32(0x70dc9930), SPH_C32(0x4afdc525), SPH_C32(0x66240000), + SPH_C32(0xf2340000), SPH_C32(0x0b460e86), SPH_C32(0x68f90000), + SPH_C32(0x6da313ca), SPH_C32(0x23434c79), SPH_C32(0xd6d10a96), + SPH_C32(0x58c5ed3e) }, + { SPH_C32(0xa89f0000), SPH_C32(0xe07f0000), SPH_C32(0xebe30a06), + SPH_C32(0x05310000), SPH_C32(0x9cfe45e6), SPH_C32(0x2490be06), + SPH_C32(0x16ce56cd), SPH_C32(0x666980bb), SPH_C32(0x34740000), + SPH_C32(0xdb600000), SPH_C32(0x61270ec8), SPH_C32(0x98060000), + SPH_C32(0xf7926d26), SPH_C32(0x66600db7), SPH_C32(0x19878573), + SPH_C32(0x0bc6fe31) }, + { SPH_C32(0xfacf0000), SPH_C32(0xc92b0000), SPH_C32(0x81820a48), + SPH_C32(0xf5ce0000), SPH_C32(0x06cf3b0a), SPH_C32(0x61b3ffc8), + SPH_C32(0xd998d928), SPH_C32(0x356a93b4), SPH_C32(0x67f90000), + SPH_C32(0x729c0000), SPH_C32(0xffd00ece), SPH_C32(0xcef90000), + SPH_C32(0xfd766d68), SPH_C32(0xf4a5c04e), SPH_C32(0xb0c3c56b), + SPH_C32(0x7451a8a0) }, + { SPH_C32(0x37060000), SPH_C32(0xece00000), SPH_C32(0x2fad0d80), + SPH_C32(0x689e0000), SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), + SPH_C32(0xd6c95e14), SPH_C32(0xd3a451d4), SPH_C32(0xb4370000), + SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), SPH_C32(0xabf50000), + SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), SPH_C32(0x99cfe8a3), + SPH_C32(0xa9350c55) }, + { SPH_C32(0x65560000), SPH_C32(0xc5b40000), SPH_C32(0x45cc0dce), + SPH_C32(0x98610000), SPH_C32(0x47fb28bb), SPH_C32(0x74ed0629), + SPH_C32(0x199fd1f1), SPH_C32(0x80a742db), SPH_C32(0xe7ba0000), + SPH_C32(0x1e630000), SPH_C32(0x6d740c06), SPH_C32(0xfd0a0000), + SPH_C32(0x300a3bc8), SPH_C32(0x6bb770c5), SPH_C32(0x308ba8bb), + SPH_C32(0xd6a25ac4) }, + { SPH_C32(0x648b0000), SPH_C32(0x451c0000), SPH_C32(0xb15a0d86), + SPH_C32(0x3e610000), SPH_C32(0xd72e5619), SPH_C32(0xa30b8a1e), + SPH_C32(0x7f8d1e0c), SPH_C32(0xac330745), SPH_C32(0xb5ea0000), + SPH_C32(0x37370000), SPH_C32(0x07150c48), SPH_C32(0x0df50000), + SPH_C32(0xaa3b4524), SPH_C32(0x2e94310b), SPH_C32(0xffdd275e), + SPH_C32(0x85a149cb) }, + { SPH_C32(0x36db0000), SPH_C32(0x6c480000), SPH_C32(0xdb3b0dc8), + SPH_C32(0xce9e0000), SPH_C32(0x4d1f28f5), SPH_C32(0xe628cbd0), + SPH_C32(0xb0db91e9), SPH_C32(0xff30144a), SPH_C32(0xe6670000), + SPH_C32(0x9ecb0000), SPH_C32(0x99e20c4e), SPH_C32(0x5b0a0000), + SPH_C32(0xa0df456a), SPH_C32(0xbc51fcf2), SPH_C32(0x56996746), + SPH_C32(0xfa361f5a) } +}; + +static const sph_u32 T512_42[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x58430000), SPH_C32(0x807e0000), SPH_C32(0x78330001), + SPH_C32(0xc66b3800), SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), + SPH_C32(0xac73fe6f), SPH_C32(0x3a4479b1), SPH_C32(0x1d5a0000), + SPH_C32(0x2b720000), SPH_C32(0x488d0000), SPH_C32(0xaf611800), + SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), SPH_C32(0x81a20429), + SPH_C32(0x1e7536a6) }, + { SPH_C32(0x1d5a0000), SPH_C32(0x2b720000), SPH_C32(0x488d0000), + SPH_C32(0xaf611800), SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), + SPH_C32(0x81a20429), SPH_C32(0x1e7536a6), SPH_C32(0x45190000), + SPH_C32(0xab0c0000), SPH_C32(0x30be0001), SPH_C32(0x690a2000), + SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), SPH_C32(0x2dd1fa46), + SPH_C32(0x24314f17) }, + { SPH_C32(0x45190000), SPH_C32(0xab0c0000), SPH_C32(0x30be0001), + SPH_C32(0x690a2000), SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), + SPH_C32(0x2dd1fa46), SPH_C32(0x24314f17), SPH_C32(0x58430000), + SPH_C32(0x807e0000), SPH_C32(0x78330001), SPH_C32(0xc66b3800), + SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), SPH_C32(0xac73fe6f), + SPH_C32(0x3a4479b1) }, + { SPH_C32(0xa53b0000), SPH_C32(0x14260000), SPH_C32(0x4e30001e), + SPH_C32(0x7cae0000), SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), + SPH_C32(0xf73168d8), SPH_C32(0x0b1b4946), SPH_C32(0x07ed0000), + SPH_C32(0xb2500000), SPH_C32(0x8774000a), SPH_C32(0x970d0000), + SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), SPH_C32(0xf4786222), + SPH_C32(0x9075b1ce) }, + { SPH_C32(0xfd780000), SPH_C32(0x94580000), SPH_C32(0x3603001f), + SPH_C32(0xbac53800), SPH_C32(0x68a95109), SPH_C32(0x017295e0), + SPH_C32(0x5b4296b7), SPH_C32(0x315f30f7), SPH_C32(0x1ab70000), + SPH_C32(0x99220000), SPH_C32(0xcff9000a), SPH_C32(0x386c1800), + SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), SPH_C32(0x75da660b), + SPH_C32(0x8e008768) }, + { SPH_C32(0xb8610000), SPH_C32(0x3f540000), SPH_C32(0x06bd001e), + SPH_C32(0xd3cf1800), SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), + SPH_C32(0x76936cf1), SPH_C32(0x156e7fe0), SPH_C32(0x42f40000), + SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), SPH_C32(0xfe072000), + SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), SPH_C32(0xd9a99864), + SPH_C32(0xb444fed9) }, + { SPH_C32(0xe0220000), SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), + SPH_C32(0x15a42000), SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), + SPH_C32(0xdae0929e), SPH_C32(0x2f2a0651), SPH_C32(0x5fae0000), + SPH_C32(0x322e0000), SPH_C32(0xff47000b), SPH_C32(0x51663800), + SPH_C32(0xa4457f72), SPH_C32(0x316a5179), SPH_C32(0x580b9c4d), + SPH_C32(0xaa31c87f) }, + { SPH_C32(0x07ed0000), SPH_C32(0xb2500000), SPH_C32(0x8774000a), + SPH_C32(0x970d0000), SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), + SPH_C32(0xf4786222), SPH_C32(0x9075b1ce), SPH_C32(0xa2d60000), + SPH_C32(0xa6760000), SPH_C32(0xc9440014), SPH_C32(0xeba30000), + SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), SPH_C32(0x03490afa), + SPH_C32(0x9b6ef888) }, + { SPH_C32(0x5fae0000), SPH_C32(0x322e0000), SPH_C32(0xff47000b), + SPH_C32(0x51663800), SPH_C32(0xa4457f72), SPH_C32(0x316a5179), + SPH_C32(0x580b9c4d), SPH_C32(0xaa31c87f), SPH_C32(0xbf8c0000), + SPH_C32(0x8d040000), SPH_C32(0x81c90014), SPH_C32(0x44c21800), + SPH_C32(0xe92700be), SPH_C32(0xf8617b49), SPH_C32(0x82eb0ed3), + SPH_C32(0x851bce2e) }, + { SPH_C32(0x1ab70000), SPH_C32(0x99220000), SPH_C32(0xcff9000a), + SPH_C32(0x386c1800), SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), + SPH_C32(0x75da660b), SPH_C32(0x8e008768), SPH_C32(0xe7cf0000), + SPH_C32(0x0d7a0000), SPH_C32(0xf9fa0015), SPH_C32(0x82a92000), + SPH_C32(0x0e105c62), SPH_C32(0x81cc4494), SPH_C32(0x2e98f0bc), + SPH_C32(0xbf5fb79f) }, + { SPH_C32(0x42f40000), SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), + SPH_C32(0xfe072000), SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), + SPH_C32(0xd9a99864), SPH_C32(0xb444fed9), SPH_C32(0xfa950000), + SPH_C32(0x26080000), SPH_C32(0xb1770015), SPH_C32(0x2dc83800), + SPH_C32(0x2bdb72a7), SPH_C32(0x49b5fb44), SPH_C32(0xaf3af495), + SPH_C32(0xa12a8139) }, + { SPH_C32(0xa2d60000), SPH_C32(0xa6760000), SPH_C32(0xc9440014), + SPH_C32(0xeba30000), SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), + SPH_C32(0x03490afa), SPH_C32(0x9b6ef888), SPH_C32(0xa53b0000), + SPH_C32(0x14260000), SPH_C32(0x4e30001e), SPH_C32(0x7cae0000), + SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), SPH_C32(0xf73168d8), + SPH_C32(0x0b1b4946) }, + { SPH_C32(0xfa950000), SPH_C32(0x26080000), SPH_C32(0xb1770015), + SPH_C32(0x2dc83800), SPH_C32(0x2bdb72a7), SPH_C32(0x49b5fb44), + SPH_C32(0xaf3af495), SPH_C32(0xa12a8139), SPH_C32(0xb8610000), + SPH_C32(0x3f540000), SPH_C32(0x06bd001e), SPH_C32(0xd3cf1800), + SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), SPH_C32(0x76936cf1), + SPH_C32(0x156e7fe0) }, + { SPH_C32(0xbf8c0000), SPH_C32(0x8d040000), SPH_C32(0x81c90014), + SPH_C32(0x44c21800), SPH_C32(0xe92700be), SPH_C32(0xf8617b49), + SPH_C32(0x82eb0ed3), SPH_C32(0x851bce2e), SPH_C32(0xe0220000), + SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), SPH_C32(0x15a42000), + SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), SPH_C32(0xdae0929e), + SPH_C32(0x2f2a0651) }, + { SPH_C32(0xe7cf0000), SPH_C32(0x0d7a0000), SPH_C32(0xf9fa0015), + SPH_C32(0x82a92000), SPH_C32(0x0e105c62), SPH_C32(0x81cc4494), + SPH_C32(0x2e98f0bc), SPH_C32(0xbf5fb79f), SPH_C32(0xfd780000), + SPH_C32(0x94580000), SPH_C32(0x3603001f), SPH_C32(0xbac53800), + SPH_C32(0x68a95109), SPH_C32(0x017295e0), SPH_C32(0x5b4296b7), + SPH_C32(0x315f30f7) }, + { SPH_C32(0x88980000), SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), + SPH_C32(0xfb4e0000), SPH_C32(0xf158079a), SPH_C32(0x61ae9167), + SPH_C32(0xa895706c), SPH_C32(0xe6107494), SPH_C32(0x0bc20000), + SPH_C32(0xdb630000), SPH_C32(0x7e88000c), SPH_C32(0x15860000), + SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), SPH_C32(0xf460449e), + SPH_C32(0xd8b61463) }, + { SPH_C32(0xd0db0000), SPH_C32(0x9fea0000), SPH_C32(0x07fc002f), + SPH_C32(0x3d253800), SPH_C32(0x166f5b46), SPH_C32(0x1803aeba), + SPH_C32(0x04e68e03), SPH_C32(0xdc540d25), SPH_C32(0x16980000), + SPH_C32(0xf0110000), SPH_C32(0x3605000c), SPH_C32(0xbae71800), + SPH_C32(0xb4366636), SPH_C32(0xbdf80493), SPH_C32(0x75c240b7), + SPH_C32(0xc6c322c5) }, + { SPH_C32(0x95c20000), SPH_C32(0x34e60000), SPH_C32(0x3742002e), + SPH_C32(0x542f1800), SPH_C32(0xd493295f), SPH_C32(0xa9d72eb7), + SPH_C32(0x29377445), SPH_C32(0xf8654232), SPH_C32(0x4edb0000), + SPH_C32(0x706f0000), SPH_C32(0x4e36000d), SPH_C32(0x7c8c2000), + SPH_C32(0x53013aea), SPH_C32(0xc4553b4e), SPH_C32(0xd9b1bed8), + SPH_C32(0xfc875b74) }, + { SPH_C32(0xcd810000), SPH_C32(0xb4980000), SPH_C32(0x4f71002f), + SPH_C32(0x92442000), SPH_C32(0x33a47583), SPH_C32(0xd07a116a), + SPH_C32(0x85448a2a), SPH_C32(0xc2213b83), SPH_C32(0x53810000), + SPH_C32(0x5b1d0000), SPH_C32(0x06bb000d), SPH_C32(0xd3ed3800), + SPH_C32(0x76ca142f), SPH_C32(0x0c2c849e), SPH_C32(0x5813baf1), + SPH_C32(0xe2f26dd2) }, + { SPH_C32(0x2da30000), SPH_C32(0x0bb20000), SPH_C32(0x31ff0030), + SPH_C32(0x87e00000), SPH_C32(0x7ec60a4f), SPH_C32(0x19713b5a), + SPH_C32(0x5fa418b4), SPH_C32(0xed0b3dd2), SPH_C32(0x0c2f0000), + SPH_C32(0x69330000), SPH_C32(0xf9fc0006), SPH_C32(0x828b0000), + SPH_C32(0xd28f6b5d), SPH_C32(0x3d46d5e7), SPH_C32(0x001826bc), + SPH_C32(0x48c3a5ad) }, + { SPH_C32(0x75e00000), SPH_C32(0x8bcc0000), SPH_C32(0x49cc0031), + SPH_C32(0x418b3800), SPH_C32(0x99f15693), SPH_C32(0x60dc0487), + SPH_C32(0xf3d7e6db), SPH_C32(0xd74f4463), SPH_C32(0x11750000), + SPH_C32(0x42410000), SPH_C32(0xb1710006), SPH_C32(0x2dea1800), + SPH_C32(0xf7444598), SPH_C32(0xf53f6a37), SPH_C32(0x81ba2295), + SPH_C32(0x56b6930b) }, + { SPH_C32(0x30f90000), SPH_C32(0x20c00000), SPH_C32(0x79720030), + SPH_C32(0x28811800), SPH_C32(0x5b0d248a), SPH_C32(0xd108848a), + SPH_C32(0xde061c9d), SPH_C32(0xf37e0b74), SPH_C32(0x49360000), + SPH_C32(0xc23f0000), SPH_C32(0xc9420007), SPH_C32(0xeb812000), + SPH_C32(0x10731944), SPH_C32(0x8c9255ea), SPH_C32(0x2dc9dcfa), + SPH_C32(0x6cf2eaba) }, + { SPH_C32(0x68ba0000), SPH_C32(0xa0be0000), SPH_C32(0x01410031), + SPH_C32(0xeeea2000), SPH_C32(0xbc3a7856), SPH_C32(0xa8a5bb57), + SPH_C32(0x7275e2f2), SPH_C32(0xc93a72c5), SPH_C32(0x546c0000), + SPH_C32(0xe94d0000), SPH_C32(0x81cf0007), SPH_C32(0x44e03800), + SPH_C32(0x35b83781), SPH_C32(0x44ebea3a), SPH_C32(0xac6bd8d3), + SPH_C32(0x7287dc1c) }, + { SPH_C32(0x8f750000), SPH_C32(0xadc40000), SPH_C32(0xf8bb0024), + SPH_C32(0x6c430000), SPH_C32(0xb22a2434), SPH_C32(0x2969ffc3), + SPH_C32(0x5ced124e), SPH_C32(0x7665c55a), SPH_C32(0xa9140000), + SPH_C32(0x7d150000), SPH_C32(0xb7cc0018), SPH_C32(0xfe250000), + SPH_C32(0x5d116688), SPH_C32(0x45997fda), SPH_C32(0xf7294e64), + SPH_C32(0x43d8eceb) }, + { SPH_C32(0xd7360000), SPH_C32(0x2dba0000), SPH_C32(0x80880025), + SPH_C32(0xaa283800), SPH_C32(0x551d78e8), SPH_C32(0x50c4c01e), + SPH_C32(0xf09eec21), SPH_C32(0x4c21bceb), SPH_C32(0xb44e0000), + SPH_C32(0x56670000), SPH_C32(0xff410018), SPH_C32(0x51441800), + SPH_C32(0x78da484d), SPH_C32(0x8de0c00a), SPH_C32(0x768b4a4d), + SPH_C32(0x5dadda4d) }, + { SPH_C32(0x922f0000), SPH_C32(0x86b60000), SPH_C32(0xb0360024), + SPH_C32(0xc3221800), SPH_C32(0x97e10af1), SPH_C32(0xe1104013), + SPH_C32(0xdd4f1667), SPH_C32(0x6810f3fc), SPH_C32(0xec0d0000), + SPH_C32(0xd6190000), SPH_C32(0x87720019), SPH_C32(0x972f2000), + SPH_C32(0x9fed1491), SPH_C32(0xf44dffd7), SPH_C32(0xdaf8b422), + SPH_C32(0x67e9a3fc) }, + { SPH_C32(0xca6c0000), SPH_C32(0x06c80000), SPH_C32(0xc8050025), + SPH_C32(0x05492000), SPH_C32(0x70d6562d), SPH_C32(0x98bd7fce), + SPH_C32(0x713ce808), SPH_C32(0x52548a4d), SPH_C32(0xf1570000), + SPH_C32(0xfd6b0000), SPH_C32(0xcfff0019), SPH_C32(0x384e3800), + SPH_C32(0xba263a54), SPH_C32(0x3c344007), SPH_C32(0x5b5ab00b), + SPH_C32(0x799c955a) }, + { SPH_C32(0x2a4e0000), SPH_C32(0xb9e20000), SPH_C32(0xb68b003a), + SPH_C32(0x10ed0000), SPH_C32(0x3db429e1), SPH_C32(0x51b655fe), + SPH_C32(0xabdc7a96), SPH_C32(0x7d7e8c1c), SPH_C32(0xaef90000), + SPH_C32(0xcf450000), SPH_C32(0x30b80012), SPH_C32(0x69280000), + SPH_C32(0x1e634526), SPH_C32(0x0d5e117e), SPH_C32(0x03512c46), + SPH_C32(0xd3ad5d25) }, + { SPH_C32(0x720d0000), SPH_C32(0x399c0000), SPH_C32(0xceb8003b), + SPH_C32(0xd6863800), SPH_C32(0xda83753d), SPH_C32(0x281b6a23), + SPH_C32(0x07af84f9), SPH_C32(0x473af5ad), SPH_C32(0xb3a30000), + SPH_C32(0xe4370000), SPH_C32(0x78350012), SPH_C32(0xc6491800), + SPH_C32(0x3ba86be3), SPH_C32(0xc527aeae), SPH_C32(0x82f3286f), + SPH_C32(0xcdd86b83) }, + { SPH_C32(0x37140000), SPH_C32(0x92900000), SPH_C32(0xfe06003a), + SPH_C32(0xbf8c1800), SPH_C32(0x187f0724), SPH_C32(0x99cfea2e), + SPH_C32(0x2a7e7ebf), SPH_C32(0x630bbaba), SPH_C32(0xebe00000), + SPH_C32(0x64490000), SPH_C32(0x00060013), SPH_C32(0x00222000), + SPH_C32(0xdc9f373f), SPH_C32(0xbc8a9173), SPH_C32(0x2e80d600), + SPH_C32(0xf79c1232) }, + { SPH_C32(0x6f570000), SPH_C32(0x12ee0000), SPH_C32(0x8635003b), + SPH_C32(0x79e72000), SPH_C32(0xff485bf8), SPH_C32(0xe062d5f3), + SPH_C32(0x860d80d0), SPH_C32(0x594fc30b), SPH_C32(0xf6ba0000), + SPH_C32(0x4f3b0000), SPH_C32(0x488b0013), SPH_C32(0xaf433800), + SPH_C32(0xf95419fa), SPH_C32(0x74f32ea3), SPH_C32(0xaf22d229), + SPH_C32(0xe9e92494) }, + { SPH_C32(0x0bc20000), SPH_C32(0xdb630000), SPH_C32(0x7e88000c), + SPH_C32(0x15860000), SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), + SPH_C32(0xf460449e), SPH_C32(0xd8b61463), SPH_C32(0x835a0000), + SPH_C32(0xc4f70000), SPH_C32(0x01470022), SPH_C32(0xeec80000), + SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), SPH_C32(0x5cf534f2), + SPH_C32(0x3ea660f7) }, + { SPH_C32(0x53810000), SPH_C32(0x5b1d0000), SPH_C32(0x06bb000d), + SPH_C32(0xd3ed3800), SPH_C32(0x76ca142f), SPH_C32(0x0c2c849e), + SPH_C32(0x5813baf1), SPH_C32(0xe2f26dd2), SPH_C32(0x9e000000), + SPH_C32(0xef850000), SPH_C32(0x49ca0022), SPH_C32(0x41a91800), + SPH_C32(0x456e61ac), SPH_C32(0xdc5695f4), SPH_C32(0xdd5730db), + SPH_C32(0x20d35651) }, + { SPH_C32(0x16980000), SPH_C32(0xf0110000), SPH_C32(0x3605000c), + SPH_C32(0xbae71800), SPH_C32(0xb4366636), SPH_C32(0xbdf80493), + SPH_C32(0x75c240b7), SPH_C32(0xc6c322c5), SPH_C32(0xc6430000), + SPH_C32(0x6ffb0000), SPH_C32(0x31f90023), SPH_C32(0x87c22000), + SPH_C32(0xa2593d70), SPH_C32(0xa5fbaa29), SPH_C32(0x7124ceb4), + SPH_C32(0x1a972fe0) }, + { SPH_C32(0x4edb0000), SPH_C32(0x706f0000), SPH_C32(0x4e36000d), + SPH_C32(0x7c8c2000), SPH_C32(0x53013aea), SPH_C32(0xc4553b4e), + SPH_C32(0xd9b1bed8), SPH_C32(0xfc875b74), SPH_C32(0xdb190000), + SPH_C32(0x44890000), SPH_C32(0x79740023), SPH_C32(0x28a33800), + SPH_C32(0x879213b5), SPH_C32(0x6d8215f9), SPH_C32(0xf086ca9d), + SPH_C32(0x04e21946) }, + { SPH_C32(0xaef90000), SPH_C32(0xcf450000), SPH_C32(0x30b80012), + SPH_C32(0x69280000), SPH_C32(0x1e634526), SPH_C32(0x0d5e117e), + SPH_C32(0x03512c46), SPH_C32(0xd3ad5d25), SPH_C32(0x84b70000), + SPH_C32(0x76a70000), SPH_C32(0x86330028), SPH_C32(0x79c50000), + SPH_C32(0x23d76cc7), SPH_C32(0x5ce84480), SPH_C32(0xa88d56d0), + SPH_C32(0xaed3d139) }, + { SPH_C32(0xf6ba0000), SPH_C32(0x4f3b0000), SPH_C32(0x488b0013), + SPH_C32(0xaf433800), SPH_C32(0xf95419fa), SPH_C32(0x74f32ea3), + SPH_C32(0xaf22d229), SPH_C32(0xe9e92494), SPH_C32(0x99ed0000), + SPH_C32(0x5dd50000), SPH_C32(0xcebe0028), SPH_C32(0xd6a41800), + SPH_C32(0x061c4202), SPH_C32(0x9491fb50), SPH_C32(0x292f52f9), + SPH_C32(0xb0a6e79f) }, + { SPH_C32(0xb3a30000), SPH_C32(0xe4370000), SPH_C32(0x78350012), + SPH_C32(0xc6491800), SPH_C32(0x3ba86be3), SPH_C32(0xc527aeae), + SPH_C32(0x82f3286f), SPH_C32(0xcdd86b83), SPH_C32(0xc1ae0000), + SPH_C32(0xddab0000), SPH_C32(0xb68d0029), SPH_C32(0x10cf2000), + SPH_C32(0xe12b1ede), SPH_C32(0xed3cc48d), SPH_C32(0x855cac96), + SPH_C32(0x8ae29e2e) }, + { SPH_C32(0xebe00000), SPH_C32(0x64490000), SPH_C32(0x00060013), + SPH_C32(0x00222000), SPH_C32(0xdc9f373f), SPH_C32(0xbc8a9173), + SPH_C32(0x2e80d600), SPH_C32(0xf79c1232), SPH_C32(0xdcf40000), + SPH_C32(0xf6d90000), SPH_C32(0xfe000029), SPH_C32(0xbfae3800), + SPH_C32(0xc4e0301b), SPH_C32(0x25457b5d), SPH_C32(0x04fea8bf), + SPH_C32(0x9497a888) }, + { SPH_C32(0x0c2f0000), SPH_C32(0x69330000), SPH_C32(0xf9fc0006), + SPH_C32(0x828b0000), SPH_C32(0xd28f6b5d), SPH_C32(0x3d46d5e7), + SPH_C32(0x001826bc), SPH_C32(0x48c3a5ad), SPH_C32(0x218c0000), + SPH_C32(0x62810000), SPH_C32(0xc8030036), SPH_C32(0x056b0000), + SPH_C32(0xac496112), SPH_C32(0x2437eebd), SPH_C32(0x5fbc3e08), + SPH_C32(0xa5c8987f) }, + { SPH_C32(0x546c0000), SPH_C32(0xe94d0000), SPH_C32(0x81cf0007), + SPH_C32(0x44e03800), SPH_C32(0x35b83781), SPH_C32(0x44ebea3a), + SPH_C32(0xac6bd8d3), SPH_C32(0x7287dc1c), SPH_C32(0x3cd60000), + SPH_C32(0x49f30000), SPH_C32(0x808e0036), SPH_C32(0xaa0a1800), + SPH_C32(0x89824fd7), SPH_C32(0xec4e516d), SPH_C32(0xde1e3a21), + SPH_C32(0xbbbdaed9) }, + { SPH_C32(0x11750000), SPH_C32(0x42410000), SPH_C32(0xb1710006), + SPH_C32(0x2dea1800), SPH_C32(0xf7444598), SPH_C32(0xf53f6a37), + SPH_C32(0x81ba2295), SPH_C32(0x56b6930b), SPH_C32(0x64950000), + SPH_C32(0xc98d0000), SPH_C32(0xf8bd0037), SPH_C32(0x6c612000), + SPH_C32(0x6eb5130b), SPH_C32(0x95e36eb0), SPH_C32(0x726dc44e), + SPH_C32(0x81f9d768) }, + { SPH_C32(0x49360000), SPH_C32(0xc23f0000), SPH_C32(0xc9420007), + SPH_C32(0xeb812000), SPH_C32(0x10731944), SPH_C32(0x8c9255ea), + SPH_C32(0x2dc9dcfa), SPH_C32(0x6cf2eaba), SPH_C32(0x79cf0000), + SPH_C32(0xe2ff0000), SPH_C32(0xb0300037), SPH_C32(0xc3003800), + SPH_C32(0x4b7e3dce), SPH_C32(0x5d9ad160), SPH_C32(0xf3cfc067), + SPH_C32(0x9f8ce1ce) }, + { SPH_C32(0xa9140000), SPH_C32(0x7d150000), SPH_C32(0xb7cc0018), + SPH_C32(0xfe250000), SPH_C32(0x5d116688), SPH_C32(0x45997fda), + SPH_C32(0xf7294e64), SPH_C32(0x43d8eceb), SPH_C32(0x26610000), + SPH_C32(0xd0d10000), SPH_C32(0x4f77003c), SPH_C32(0x92660000), + SPH_C32(0xef3b42bc), SPH_C32(0x6cf08019), SPH_C32(0xabc45c2a), + SPH_C32(0x35bd29b1) }, + { SPH_C32(0xf1570000), SPH_C32(0xfd6b0000), SPH_C32(0xcfff0019), + SPH_C32(0x384e3800), SPH_C32(0xba263a54), SPH_C32(0x3c344007), + SPH_C32(0x5b5ab00b), SPH_C32(0x799c955a), SPH_C32(0x3b3b0000), + SPH_C32(0xfba30000), SPH_C32(0x07fa003c), SPH_C32(0x3d071800), + SPH_C32(0xcaf06c79), SPH_C32(0xa4893fc9), SPH_C32(0x2a665803), + SPH_C32(0x2bc81f17) }, + { SPH_C32(0xb44e0000), SPH_C32(0x56670000), SPH_C32(0xff410018), + SPH_C32(0x51441800), SPH_C32(0x78da484d), SPH_C32(0x8de0c00a), + SPH_C32(0x768b4a4d), SPH_C32(0x5dadda4d), SPH_C32(0x63780000), + SPH_C32(0x7bdd0000), SPH_C32(0x7fc9003d), SPH_C32(0xfb6c2000), + SPH_C32(0x2dc730a5), SPH_C32(0xdd240014), SPH_C32(0x8615a66c), + SPH_C32(0x118c66a6) }, + { SPH_C32(0xec0d0000), SPH_C32(0xd6190000), SPH_C32(0x87720019), + SPH_C32(0x972f2000), SPH_C32(0x9fed1491), SPH_C32(0xf44dffd7), + SPH_C32(0xdaf8b422), SPH_C32(0x67e9a3fc), SPH_C32(0x7e220000), + SPH_C32(0x50af0000), SPH_C32(0x3744003d), SPH_C32(0x540d3800), + SPH_C32(0x080c1e60), SPH_C32(0x155dbfc4), SPH_C32(0x07b7a245), + SPH_C32(0x0ff95000) }, + { SPH_C32(0x835a0000), SPH_C32(0xc4f70000), SPH_C32(0x01470022), + SPH_C32(0xeec80000), SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), + SPH_C32(0x5cf534f2), SPH_C32(0x3ea660f7), SPH_C32(0x88980000), + SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), SPH_C32(0xfb4e0000), + SPH_C32(0xf158079a), SPH_C32(0x61ae9167), SPH_C32(0xa895706c), + SPH_C32(0xe6107494) }, + { SPH_C32(0xdb190000), SPH_C32(0x44890000), SPH_C32(0x79740023), + SPH_C32(0x28a33800), SPH_C32(0x879213b5), SPH_C32(0x6d8215f9), + SPH_C32(0xf086ca9d), SPH_C32(0x04e21946), SPH_C32(0x95c20000), + SPH_C32(0x34e60000), SPH_C32(0x3742002e), SPH_C32(0x542f1800), + SPH_C32(0xd493295f), SPH_C32(0xa9d72eb7), SPH_C32(0x29377445), + SPH_C32(0xf8654232) }, + { SPH_C32(0x9e000000), SPH_C32(0xef850000), SPH_C32(0x49ca0022), + SPH_C32(0x41a91800), SPH_C32(0x456e61ac), SPH_C32(0xdc5695f4), + SPH_C32(0xdd5730db), SPH_C32(0x20d35651), SPH_C32(0xcd810000), + SPH_C32(0xb4980000), SPH_C32(0x4f71002f), SPH_C32(0x92442000), + SPH_C32(0x33a47583), SPH_C32(0xd07a116a), SPH_C32(0x85448a2a), + SPH_C32(0xc2213b83) }, + { SPH_C32(0xc6430000), SPH_C32(0x6ffb0000), SPH_C32(0x31f90023), + SPH_C32(0x87c22000), SPH_C32(0xa2593d70), SPH_C32(0xa5fbaa29), + SPH_C32(0x7124ceb4), SPH_C32(0x1a972fe0), SPH_C32(0xd0db0000), + SPH_C32(0x9fea0000), SPH_C32(0x07fc002f), SPH_C32(0x3d253800), + SPH_C32(0x166f5b46), SPH_C32(0x1803aeba), SPH_C32(0x04e68e03), + SPH_C32(0xdc540d25) }, + { SPH_C32(0x26610000), SPH_C32(0xd0d10000), SPH_C32(0x4f77003c), + SPH_C32(0x92660000), SPH_C32(0xef3b42bc), SPH_C32(0x6cf08019), + SPH_C32(0xabc45c2a), SPH_C32(0x35bd29b1), SPH_C32(0x8f750000), + SPH_C32(0xadc40000), SPH_C32(0xf8bb0024), SPH_C32(0x6c430000), + SPH_C32(0xb22a2434), SPH_C32(0x2969ffc3), SPH_C32(0x5ced124e), + SPH_C32(0x7665c55a) }, + { SPH_C32(0x7e220000), SPH_C32(0x50af0000), SPH_C32(0x3744003d), + SPH_C32(0x540d3800), SPH_C32(0x080c1e60), SPH_C32(0x155dbfc4), + SPH_C32(0x07b7a245), SPH_C32(0x0ff95000), SPH_C32(0x922f0000), + SPH_C32(0x86b60000), SPH_C32(0xb0360024), SPH_C32(0xc3221800), + SPH_C32(0x97e10af1), SPH_C32(0xe1104013), SPH_C32(0xdd4f1667), + SPH_C32(0x6810f3fc) }, + { SPH_C32(0x3b3b0000), SPH_C32(0xfba30000), SPH_C32(0x07fa003c), + SPH_C32(0x3d071800), SPH_C32(0xcaf06c79), SPH_C32(0xa4893fc9), + SPH_C32(0x2a665803), SPH_C32(0x2bc81f17), SPH_C32(0xca6c0000), + SPH_C32(0x06c80000), SPH_C32(0xc8050025), SPH_C32(0x05492000), + SPH_C32(0x70d6562d), SPH_C32(0x98bd7fce), SPH_C32(0x713ce808), + SPH_C32(0x52548a4d) }, + { SPH_C32(0x63780000), SPH_C32(0x7bdd0000), SPH_C32(0x7fc9003d), + SPH_C32(0xfb6c2000), SPH_C32(0x2dc730a5), SPH_C32(0xdd240014), + SPH_C32(0x8615a66c), SPH_C32(0x118c66a6), SPH_C32(0xd7360000), + SPH_C32(0x2dba0000), SPH_C32(0x80880025), SPH_C32(0xaa283800), + SPH_C32(0x551d78e8), SPH_C32(0x50c4c01e), SPH_C32(0xf09eec21), + SPH_C32(0x4c21bceb) }, + { SPH_C32(0x84b70000), SPH_C32(0x76a70000), SPH_C32(0x86330028), + SPH_C32(0x79c50000), SPH_C32(0x23d76cc7), SPH_C32(0x5ce84480), + SPH_C32(0xa88d56d0), SPH_C32(0xaed3d139), SPH_C32(0x2a4e0000), + SPH_C32(0xb9e20000), SPH_C32(0xb68b003a), SPH_C32(0x10ed0000), + SPH_C32(0x3db429e1), SPH_C32(0x51b655fe), SPH_C32(0xabdc7a96), + SPH_C32(0x7d7e8c1c) }, + { SPH_C32(0xdcf40000), SPH_C32(0xf6d90000), SPH_C32(0xfe000029), + SPH_C32(0xbfae3800), SPH_C32(0xc4e0301b), SPH_C32(0x25457b5d), + SPH_C32(0x04fea8bf), SPH_C32(0x9497a888), SPH_C32(0x37140000), + SPH_C32(0x92900000), SPH_C32(0xfe06003a), SPH_C32(0xbf8c1800), + SPH_C32(0x187f0724), SPH_C32(0x99cfea2e), SPH_C32(0x2a7e7ebf), + SPH_C32(0x630bbaba) }, + { SPH_C32(0x99ed0000), SPH_C32(0x5dd50000), SPH_C32(0xcebe0028), + SPH_C32(0xd6a41800), SPH_C32(0x061c4202), SPH_C32(0x9491fb50), + SPH_C32(0x292f52f9), SPH_C32(0xb0a6e79f), SPH_C32(0x6f570000), + SPH_C32(0x12ee0000), SPH_C32(0x8635003b), SPH_C32(0x79e72000), + SPH_C32(0xff485bf8), SPH_C32(0xe062d5f3), SPH_C32(0x860d80d0), + SPH_C32(0x594fc30b) }, + { SPH_C32(0xc1ae0000), SPH_C32(0xddab0000), SPH_C32(0xb68d0029), + SPH_C32(0x10cf2000), SPH_C32(0xe12b1ede), SPH_C32(0xed3cc48d), + SPH_C32(0x855cac96), SPH_C32(0x8ae29e2e), SPH_C32(0x720d0000), + SPH_C32(0x399c0000), SPH_C32(0xceb8003b), SPH_C32(0xd6863800), + SPH_C32(0xda83753d), SPH_C32(0x281b6a23), SPH_C32(0x07af84f9), + SPH_C32(0x473af5ad) }, + { SPH_C32(0x218c0000), SPH_C32(0x62810000), SPH_C32(0xc8030036), + SPH_C32(0x056b0000), SPH_C32(0xac496112), SPH_C32(0x2437eebd), + SPH_C32(0x5fbc3e08), SPH_C32(0xa5c8987f), SPH_C32(0x2da30000), + SPH_C32(0x0bb20000), SPH_C32(0x31ff0030), SPH_C32(0x87e00000), + SPH_C32(0x7ec60a4f), SPH_C32(0x19713b5a), SPH_C32(0x5fa418b4), + SPH_C32(0xed0b3dd2) }, + { SPH_C32(0x79cf0000), SPH_C32(0xe2ff0000), SPH_C32(0xb0300037), + SPH_C32(0xc3003800), SPH_C32(0x4b7e3dce), SPH_C32(0x5d9ad160), + SPH_C32(0xf3cfc067), SPH_C32(0x9f8ce1ce), SPH_C32(0x30f90000), + SPH_C32(0x20c00000), SPH_C32(0x79720030), SPH_C32(0x28811800), + SPH_C32(0x5b0d248a), SPH_C32(0xd108848a), SPH_C32(0xde061c9d), + SPH_C32(0xf37e0b74) }, + { SPH_C32(0x3cd60000), SPH_C32(0x49f30000), SPH_C32(0x808e0036), + SPH_C32(0xaa0a1800), SPH_C32(0x89824fd7), SPH_C32(0xec4e516d), + SPH_C32(0xde1e3a21), SPH_C32(0xbbbdaed9), SPH_C32(0x68ba0000), + SPH_C32(0xa0be0000), SPH_C32(0x01410031), SPH_C32(0xeeea2000), + SPH_C32(0xbc3a7856), SPH_C32(0xa8a5bb57), SPH_C32(0x7275e2f2), + SPH_C32(0xc93a72c5) }, + { SPH_C32(0x64950000), SPH_C32(0xc98d0000), SPH_C32(0xf8bd0037), + SPH_C32(0x6c612000), SPH_C32(0x6eb5130b), SPH_C32(0x95e36eb0), + SPH_C32(0x726dc44e), SPH_C32(0x81f9d768), SPH_C32(0x75e00000), + SPH_C32(0x8bcc0000), SPH_C32(0x49cc0031), SPH_C32(0x418b3800), + SPH_C32(0x99f15693), SPH_C32(0x60dc0487), SPH_C32(0xf3d7e6db), + SPH_C32(0xd74f4463) } +}; + +static const sph_u32 T512_48[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xb4310000), SPH_C32(0x77330000), SPH_C32(0xb15d0000), + SPH_C32(0x7fd004e0), SPH_C32(0x78a26138), SPH_C32(0xd116c35d), + SPH_C32(0xd256d489), SPH_C32(0x4e6f74de), SPH_C32(0xe3060000), + SPH_C32(0xbdc10000), SPH_C32(0x87130000), SPH_C32(0xbff20060), + SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), SPH_C32(0x73c5ab06), + SPH_C32(0x5bd61539) }, + { SPH_C32(0xe3060000), SPH_C32(0xbdc10000), SPH_C32(0x87130000), + SPH_C32(0xbff20060), SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), + SPH_C32(0x73c5ab06), SPH_C32(0x5bd61539), SPH_C32(0x57370000), + SPH_C32(0xcaf20000), SPH_C32(0x364e0000), SPH_C32(0xc0220480), + SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), SPH_C32(0xa1937f8f), + SPH_C32(0x15b961e7) }, + { SPH_C32(0x57370000), SPH_C32(0xcaf20000), SPH_C32(0x364e0000), + SPH_C32(0xc0220480), SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), + SPH_C32(0xa1937f8f), SPH_C32(0x15b961e7), SPH_C32(0xb4310000), + SPH_C32(0x77330000), SPH_C32(0xb15d0000), SPH_C32(0x7fd004e0), + SPH_C32(0x78a26138), SPH_C32(0xd116c35d), SPH_C32(0xd256d489), + SPH_C32(0x4e6f74de) }, + { SPH_C32(0x02f20000), SPH_C32(0xa2810000), SPH_C32(0x873f0000), + SPH_C32(0xe36c7800), SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), + SPH_C32(0xc4c23237), SPH_C32(0x7f32259e), SPH_C32(0xbadd0000), + SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), SPH_C32(0xf7282800), + SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), SPH_C32(0xea5a8d14), + SPH_C32(0x2a2c18f0) }, + { SPH_C32(0xb6c30000), SPH_C32(0xd5b20000), SPH_C32(0x36620000), + SPH_C32(0x9cbc7ce0), SPH_C32(0x66bf15d7), SPH_C32(0xd62be88b), + SPH_C32(0x1694e6be), SPH_C32(0x315d5140), SPH_C32(0x59db0000), + SPH_C32(0xae6c0000), SPH_C32(0x30f40000), SPH_C32(0x48da2860), + SPH_C32(0xf1ff1e57), SPH_C32(0xbbaff46b), SPH_C32(0x999f2612), + SPH_C32(0x71fa0dc9) }, + { SPH_C32(0xe1f40000), SPH_C32(0x1f400000), SPH_C32(0x002c0000), + SPH_C32(0x5c9e7860), SPH_C32(0x30a77ef5), SPH_C32(0x8a881c87), + SPH_C32(0xb7079931), SPH_C32(0x24e430a7), SPH_C32(0xedea0000), + SPH_C32(0xd95f0000), SPH_C32(0x81a90000), SPH_C32(0x370a2c80), + SPH_C32(0x895d7f6f), SPH_C32(0x6ab93736), SPH_C32(0x4bc9f29b), + SPH_C32(0x3f957917) }, + { SPH_C32(0x55c50000), SPH_C32(0x68730000), SPH_C32(0xb1710000), + SPH_C32(0x234e7c80), SPH_C32(0x48051fcd), SPH_C32(0x5b9edfda), + SPH_C32(0x65514db8), SPH_C32(0x6a8b4479), SPH_C32(0x0eec0000), + SPH_C32(0x649e0000), SPH_C32(0x06ba0000), SPH_C32(0x88f82ce0), + SPH_C32(0xa7e77575), SPH_C32(0xe70c0067), SPH_C32(0x380c599d), + SPH_C32(0x64436c2e) }, + { SPH_C32(0xbadd0000), SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), + SPH_C32(0xf7282800), SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), + SPH_C32(0xea5a8d14), SPH_C32(0x2a2c18f0), SPH_C32(0xb82f0000), + SPH_C32(0xb12c0000), SPH_C32(0x30d80000), SPH_C32(0x14445000), + SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), SPH_C32(0x2e98bf23), + SPH_C32(0x551e3d6e) }, + { SPH_C32(0x0eec0000), SPH_C32(0x649e0000), SPH_C32(0x06ba0000), + SPH_C32(0x88f82ce0), SPH_C32(0xa7e77575), SPH_C32(0xe70c0067), + SPH_C32(0x380c599d), SPH_C32(0x64436c2e), SPH_C32(0x5b290000), + SPH_C32(0x0ced0000), SPH_C32(0xb7cb0000), SPH_C32(0xabb65060), + SPH_C32(0xefe26ab8), SPH_C32(0xbc92dfbd), SPH_C32(0x5d5d1425), + SPH_C32(0x0ec82857) }, + { SPH_C32(0x59db0000), SPH_C32(0xae6c0000), SPH_C32(0x30f40000), + SPH_C32(0x48da2860), SPH_C32(0xf1ff1e57), SPH_C32(0xbbaff46b), + SPH_C32(0x999f2612), SPH_C32(0x71fa0dc9), SPH_C32(0xef180000), + SPH_C32(0x7bde0000), SPH_C32(0x06960000), SPH_C32(0xd4665480), + SPH_C32(0x97400b80), SPH_C32(0x6d841ce0), SPH_C32(0x8f0bc0ac), + SPH_C32(0x40a75c89) }, + { SPH_C32(0xedea0000), SPH_C32(0xd95f0000), SPH_C32(0x81a90000), + SPH_C32(0x370a2c80), SPH_C32(0x895d7f6f), SPH_C32(0x6ab93736), + SPH_C32(0x4bc9f29b), SPH_C32(0x3f957917), SPH_C32(0x0c1e0000), + SPH_C32(0xc61f0000), SPH_C32(0x81850000), SPH_C32(0x6b9454e0), + SPH_C32(0xb9fa019a), SPH_C32(0xe0312bb1), SPH_C32(0xfcce6baa), + SPH_C32(0x1b7149b0) }, + { SPH_C32(0xb82f0000), SPH_C32(0xb12c0000), SPH_C32(0x30d80000), + SPH_C32(0x14445000), SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), + SPH_C32(0x2e98bf23), SPH_C32(0x551e3d6e), SPH_C32(0x02f20000), + SPH_C32(0xa2810000), SPH_C32(0x873f0000), SPH_C32(0xe36c7800), + SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), SPH_C32(0xc4c23237), + SPH_C32(0x7f32259e) }, + { SPH_C32(0x0c1e0000), SPH_C32(0xc61f0000), SPH_C32(0x81850000), + SPH_C32(0x6b9454e0), SPH_C32(0xb9fa019a), SPH_C32(0xe0312bb1), + SPH_C32(0xfcce6baa), SPH_C32(0x1b7149b0), SPH_C32(0xe1f40000), + SPH_C32(0x1f400000), SPH_C32(0x002c0000), SPH_C32(0x5c9e7860), + SPH_C32(0x30a77ef5), SPH_C32(0x8a881c87), SPH_C32(0xb7079931), + SPH_C32(0x24e430a7) }, + { SPH_C32(0x5b290000), SPH_C32(0x0ced0000), SPH_C32(0xb7cb0000), + SPH_C32(0xabb65060), SPH_C32(0xefe26ab8), SPH_C32(0xbc92dfbd), + SPH_C32(0x5d5d1425), SPH_C32(0x0ec82857), SPH_C32(0x55c50000), + SPH_C32(0x68730000), SPH_C32(0xb1710000), SPH_C32(0x234e7c80), + SPH_C32(0x48051fcd), SPH_C32(0x5b9edfda), SPH_C32(0x65514db8), + SPH_C32(0x6a8b4479) }, + { SPH_C32(0xef180000), SPH_C32(0x7bde0000), SPH_C32(0x06960000), + SPH_C32(0xd4665480), SPH_C32(0x97400b80), SPH_C32(0x6d841ce0), + SPH_C32(0x8f0bc0ac), SPH_C32(0x40a75c89), SPH_C32(0xb6c30000), + SPH_C32(0xd5b20000), SPH_C32(0x36620000), SPH_C32(0x9cbc7ce0), + SPH_C32(0x66bf15d7), SPH_C32(0xd62be88b), SPH_C32(0x1694e6be), + SPH_C32(0x315d5140) }, + { SPH_C32(0x1e6c0000), SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), + SPH_C32(0xbcb6b800), SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), + SPH_C32(0x6a0c1bc8), SPH_C32(0xb99dc2eb), SPH_C32(0x92560000), + SPH_C32(0x1eda0000), SPH_C32(0xea510000), SPH_C32(0xe8b13000), + SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), SPH_C32(0xb15c2254), + SPH_C32(0x33c5244f) }, + { SPH_C32(0xaa5d0000), SPH_C32(0xb3710000), SPH_C32(0x3b730000), + SPH_C32(0xc366bce0), SPH_C32(0x54e6728e), SPH_C32(0x5aeb1087), + SPH_C32(0xb85acf41), SPH_C32(0xf7f2b635), SPH_C32(0x71500000), + SPH_C32(0xa31b0000), SPH_C32(0x6d420000), SPH_C32(0x57433060), + SPH_C32(0x878f5cbf), SPH_C32(0x664e56c8), SPH_C32(0xc2998952), + SPH_C32(0x68133176) }, + { SPH_C32(0xfd6a0000), SPH_C32(0x79830000), SPH_C32(0x0d3d0000), + SPH_C32(0x0344b860), SPH_C32(0x02fe19ac), SPH_C32(0x0648e48b), + SPH_C32(0x19c9b0ce), SPH_C32(0xe24bd7d2), SPH_C32(0xc5610000), + SPH_C32(0xd4280000), SPH_C32(0xdc1f0000), SPH_C32(0x28933480), + SPH_C32(0xff2d3d87), SPH_C32(0xb7589595), SPH_C32(0x10cf5ddb), + SPH_C32(0x267c45a8) }, + { SPH_C32(0x495b0000), SPH_C32(0x0eb00000), SPH_C32(0xbc600000), + SPH_C32(0x7c94bc80), SPH_C32(0x7a5c7894), SPH_C32(0xd75e27d6), + SPH_C32(0xcb9f6447), SPH_C32(0xac24a30c), SPH_C32(0x26670000), + SPH_C32(0x69e90000), SPH_C32(0x5b0c0000), SPH_C32(0x976134e0), + SPH_C32(0xd197379d), SPH_C32(0x3aeda2c4), SPH_C32(0x630af6dd), + SPH_C32(0x7daa5091) }, + { SPH_C32(0x1c9e0000), SPH_C32(0x66c30000), SPH_C32(0x0d110000), + SPH_C32(0x5fdac000), SPH_C32(0x32596759), SPH_C32(0x8cc0f80c), + SPH_C32(0xaece29ff), SPH_C32(0xc6afe775), SPH_C32(0x288b0000), + SPH_C32(0x0d770000), SPH_C32(0x5db60000), SPH_C32(0x1f991800), + SPH_C32(0x767042e8), SPH_C32(0xdde1a2a3), SPH_C32(0x5b06af40), + SPH_C32(0x19e93cbf) }, + { SPH_C32(0xa8af0000), SPH_C32(0x11f00000), SPH_C32(0xbc4c0000), + SPH_C32(0x200ac4e0), SPH_C32(0x4afb0661), SPH_C32(0x5dd63b51), + SPH_C32(0x7c98fd76), SPH_C32(0x88c093ab), SPH_C32(0xcb8d0000), + SPH_C32(0xb0b60000), SPH_C32(0xdaa50000), SPH_C32(0xa06b1860), + SPH_C32(0x58ca48f2), SPH_C32(0x505495f2), SPH_C32(0x28c30446), + SPH_C32(0x423f2986) }, + { SPH_C32(0xff980000), SPH_C32(0xdb020000), SPH_C32(0x8a020000), + SPH_C32(0xe028c060), SPH_C32(0x1ce36d43), SPH_C32(0x0175cf5d), + SPH_C32(0xdd0b82f9), SPH_C32(0x9d79f24c), SPH_C32(0x7fbc0000), + SPH_C32(0xc7850000), SPH_C32(0x6bf80000), SPH_C32(0xdfbb1c80), + SPH_C32(0x206829ca), SPH_C32(0x814256af), SPH_C32(0xfa95d0cf), + SPH_C32(0x0c505d58) }, + { SPH_C32(0x4ba90000), SPH_C32(0xac310000), SPH_C32(0x3b5f0000), + SPH_C32(0x9ff8c480), SPH_C32(0x64410c7b), SPH_C32(0xd0630c00), + SPH_C32(0x0f5d5670), SPH_C32(0xd3168692), SPH_C32(0x9cba0000), + SPH_C32(0x7a440000), SPH_C32(0xeceb0000), SPH_C32(0x60491ce0), + SPH_C32(0x0ed223d0), SPH_C32(0x0cf761fe), SPH_C32(0x89507bc9), + SPH_C32(0x57864861) }, + { SPH_C32(0xa4b10000), SPH_C32(0xd7ef0000), SPH_C32(0x3dc90000), + SPH_C32(0x4b9e9000), SPH_C32(0xf30107fb), SPH_C32(0xbde710e0), + SPH_C32(0x805696dc), SPH_C32(0x93b1da1b), SPH_C32(0x2a790000), + SPH_C32(0xaff60000), SPH_C32(0xda890000), SPH_C32(0xfcf56000), + SPH_C32(0x686d3607), SPH_C32(0xdadc8975), SPH_C32(0x9fc49d77), + SPH_C32(0x66db1921) }, + { SPH_C32(0x10800000), SPH_C32(0xa0dc0000), SPH_C32(0x8c940000), + SPH_C32(0x344e94e0), SPH_C32(0x8ba366c3), SPH_C32(0x6cf1d3bd), + SPH_C32(0x52004255), SPH_C32(0xdddeaec5), SPH_C32(0xc97f0000), + SPH_C32(0x12370000), SPH_C32(0x5d9a0000), SPH_C32(0x43076060), + SPH_C32(0x46d73c1d), SPH_C32(0x5769be24), SPH_C32(0xec013671), + SPH_C32(0x3d0d0c18) }, + { SPH_C32(0x47b70000), SPH_C32(0x6a2e0000), SPH_C32(0xbada0000), + SPH_C32(0xf46c9060), SPH_C32(0xddbb0de1), SPH_C32(0x305227b1), + SPH_C32(0xf3933dda), SPH_C32(0xc867cf22), SPH_C32(0x7d4e0000), + SPH_C32(0x65040000), SPH_C32(0xecc70000), SPH_C32(0x3cd76480), + SPH_C32(0x3e755d25), SPH_C32(0x867f7d79), SPH_C32(0x3e57e2f8), + SPH_C32(0x736278c6) }, + { SPH_C32(0xf3860000), SPH_C32(0x1d1d0000), SPH_C32(0x0b870000), + SPH_C32(0x8bbc9480), SPH_C32(0xa5196cd9), SPH_C32(0xe144e4ec), + SPH_C32(0x21c5e953), SPH_C32(0x8608bbfc), SPH_C32(0x9e480000), + SPH_C32(0xd8c50000), SPH_C32(0x6bd40000), SPH_C32(0x832564e0), + SPH_C32(0x10cf573f), SPH_C32(0x0bca4a28), SPH_C32(0x4d9249fe), + SPH_C32(0x28b46dff) }, + { SPH_C32(0xa6430000), SPH_C32(0x756e0000), SPH_C32(0xbaf60000), + SPH_C32(0xa8f2e800), SPH_C32(0xed1c7314), SPH_C32(0xbada3b36), + SPH_C32(0x4494a4eb), SPH_C32(0xec83ff85), SPH_C32(0x90a40000), + SPH_C32(0xbc5b0000), SPH_C32(0x6d6e0000), SPH_C32(0x0bdd4800), + SPH_C32(0xb728224a), SPH_C32(0xecc64a4f), SPH_C32(0x759e1063), + SPH_C32(0x4cf701d1) }, + { SPH_C32(0x12720000), SPH_C32(0x025d0000), SPH_C32(0x0bab0000), + SPH_C32(0xd722ece0), SPH_C32(0x95be122c), SPH_C32(0x6bccf86b), + SPH_C32(0x96c27062), SPH_C32(0xa2ec8b5b), SPH_C32(0x73a20000), + SPH_C32(0x019a0000), SPH_C32(0xea7d0000), SPH_C32(0xb42f4860), + SPH_C32(0x99922850), SPH_C32(0x61737d1e), SPH_C32(0x065bbb65), + SPH_C32(0x172114e8) }, + { SPH_C32(0x45450000), SPH_C32(0xc8af0000), SPH_C32(0x3de50000), + SPH_C32(0x1700e860), SPH_C32(0xc3a6790e), SPH_C32(0x376f0c67), + SPH_C32(0x37510fed), SPH_C32(0xb755eabc), SPH_C32(0xc7930000), + SPH_C32(0x76a90000), SPH_C32(0x5b200000), SPH_C32(0xcbff4c80), + SPH_C32(0xe1304968), SPH_C32(0xb065be43), SPH_C32(0xd40d6fec), + SPH_C32(0x594e6036) }, + { SPH_C32(0xf1740000), SPH_C32(0xbf9c0000), SPH_C32(0x8cb80000), + SPH_C32(0x68d0ec80), SPH_C32(0xbb041836), SPH_C32(0xe679cf3a), + SPH_C32(0xe507db64), SPH_C32(0xf93a9e62), SPH_C32(0x24950000), + SPH_C32(0xcb680000), SPH_C32(0xdc330000), SPH_C32(0x740d4ce0), + SPH_C32(0xcf8a4372), SPH_C32(0x3dd08912), SPH_C32(0xa7c8c4ea), + SPH_C32(0x0298750f) }, + { SPH_C32(0x92560000), SPH_C32(0x1eda0000), SPH_C32(0xea510000), + SPH_C32(0xe8b13000), SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), + SPH_C32(0xb15c2254), SPH_C32(0x33c5244f), SPH_C32(0x8c3a0000), + SPH_C32(0xda980000), SPH_C32(0x607f0000), SPH_C32(0x54078800), + SPH_C32(0x85714513), SPH_C32(0x6006b243), SPH_C32(0xdb50399c), + SPH_C32(0x8a58e6a4) }, + { SPH_C32(0x26670000), SPH_C32(0x69e90000), SPH_C32(0x5b0c0000), + SPH_C32(0x976134e0), SPH_C32(0xd197379d), SPH_C32(0x3aeda2c4), + SPH_C32(0x630af6dd), SPH_C32(0x7daa5091), SPH_C32(0x6f3c0000), + SPH_C32(0x67590000), SPH_C32(0xe76c0000), SPH_C32(0xebf58860), + SPH_C32(0xabcb4f09), SPH_C32(0xedb38512), SPH_C32(0xa895929a), + SPH_C32(0xd18ef39d) }, + { SPH_C32(0x71500000), SPH_C32(0xa31b0000), SPH_C32(0x6d420000), + SPH_C32(0x57433060), SPH_C32(0x878f5cbf), SPH_C32(0x664e56c8), + SPH_C32(0xc2998952), SPH_C32(0x68133176), SPH_C32(0xdb0d0000), + SPH_C32(0x106a0000), SPH_C32(0x56310000), SPH_C32(0x94258c80), + SPH_C32(0xd3692e31), SPH_C32(0x3ca5464f), SPH_C32(0x7ac34613), + SPH_C32(0x9fe18743) }, + { SPH_C32(0xc5610000), SPH_C32(0xd4280000), SPH_C32(0xdc1f0000), + SPH_C32(0x28933480), SPH_C32(0xff2d3d87), SPH_C32(0xb7589595), + SPH_C32(0x10cf5ddb), SPH_C32(0x267c45a8), SPH_C32(0x380b0000), + SPH_C32(0xadab0000), SPH_C32(0xd1220000), SPH_C32(0x2bd78ce0), + SPH_C32(0xfdd3242b), SPH_C32(0xb110711e), SPH_C32(0x0906ed15), + SPH_C32(0xc437927a) }, + { SPH_C32(0x90a40000), SPH_C32(0xbc5b0000), SPH_C32(0x6d6e0000), + SPH_C32(0x0bdd4800), SPH_C32(0xb728224a), SPH_C32(0xecc64a4f), + SPH_C32(0x759e1063), SPH_C32(0x4cf701d1), SPH_C32(0x36e70000), + SPH_C32(0xc9350000), SPH_C32(0xd7980000), SPH_C32(0xa32fa000), + SPH_C32(0x5a34515e), SPH_C32(0x561c7179), SPH_C32(0x310ab488), + SPH_C32(0xa074fe54) }, + { SPH_C32(0x24950000), SPH_C32(0xcb680000), SPH_C32(0xdc330000), + SPH_C32(0x740d4ce0), SPH_C32(0xcf8a4372), SPH_C32(0x3dd08912), + SPH_C32(0xa7c8c4ea), SPH_C32(0x0298750f), SPH_C32(0xd5e10000), + SPH_C32(0x74f40000), SPH_C32(0x508b0000), SPH_C32(0x1cdda060), + SPH_C32(0x748e5b44), SPH_C32(0xdba94628), SPH_C32(0x42cf1f8e), + SPH_C32(0xfba2eb6d) }, + { SPH_C32(0x73a20000), SPH_C32(0x019a0000), SPH_C32(0xea7d0000), + SPH_C32(0xb42f4860), SPH_C32(0x99922850), SPH_C32(0x61737d1e), + SPH_C32(0x065bbb65), SPH_C32(0x172114e8), SPH_C32(0x61d00000), + SPH_C32(0x03c70000), SPH_C32(0xe1d60000), SPH_C32(0x630da480), + SPH_C32(0x0c2c3a7c), SPH_C32(0x0abf8575), SPH_C32(0x9099cb07), + SPH_C32(0xb5cd9fb3) }, + { SPH_C32(0xc7930000), SPH_C32(0x76a90000), SPH_C32(0x5b200000), + SPH_C32(0xcbff4c80), SPH_C32(0xe1304968), SPH_C32(0xb065be43), + SPH_C32(0xd40d6fec), SPH_C32(0x594e6036), SPH_C32(0x82d60000), + SPH_C32(0xbe060000), SPH_C32(0x66c50000), SPH_C32(0xdcffa4e0), + SPH_C32(0x22963066), SPH_C32(0x870ab224), SPH_C32(0xe35c6001), + SPH_C32(0xee1b8a8a) }, + { SPH_C32(0x288b0000), SPH_C32(0x0d770000), SPH_C32(0x5db60000), + SPH_C32(0x1f991800), SPH_C32(0x767042e8), SPH_C32(0xdde1a2a3), + SPH_C32(0x5b06af40), SPH_C32(0x19e93cbf), SPH_C32(0x34150000), + SPH_C32(0x6bb40000), SPH_C32(0x50a70000), SPH_C32(0x4043d800), + SPH_C32(0x442925b1), SPH_C32(0x51215aaf), SPH_C32(0xf5c886bf), + SPH_C32(0xdf46dbca) }, + { SPH_C32(0x9cba0000), SPH_C32(0x7a440000), SPH_C32(0xeceb0000), + SPH_C32(0x60491ce0), SPH_C32(0x0ed223d0), SPH_C32(0x0cf761fe), + SPH_C32(0x89507bc9), SPH_C32(0x57864861), SPH_C32(0xd7130000), + SPH_C32(0xd6750000), SPH_C32(0xd7b40000), SPH_C32(0xffb1d860), + SPH_C32(0x6a932fab), SPH_C32(0xdc946dfe), SPH_C32(0x860d2db9), + SPH_C32(0x8490cef3) }, + { SPH_C32(0xcb8d0000), SPH_C32(0xb0b60000), SPH_C32(0xdaa50000), + SPH_C32(0xa06b1860), SPH_C32(0x58ca48f2), SPH_C32(0x505495f2), + SPH_C32(0x28c30446), SPH_C32(0x423f2986), SPH_C32(0x63220000), + SPH_C32(0xa1460000), SPH_C32(0x66e90000), SPH_C32(0x8061dc80), + SPH_C32(0x12314e93), SPH_C32(0x0d82aea3), SPH_C32(0x545bf930), + SPH_C32(0xcaffba2d) }, + { SPH_C32(0x7fbc0000), SPH_C32(0xc7850000), SPH_C32(0x6bf80000), + SPH_C32(0xdfbb1c80), SPH_C32(0x206829ca), SPH_C32(0x814256af), + SPH_C32(0xfa95d0cf), SPH_C32(0x0c505d58), SPH_C32(0x80240000), + SPH_C32(0x1c870000), SPH_C32(0xe1fa0000), SPH_C32(0x3f93dce0), + SPH_C32(0x3c8b4489), SPH_C32(0x803799f2), SPH_C32(0x279e5236), + SPH_C32(0x9129af14) }, + { SPH_C32(0x2a790000), SPH_C32(0xaff60000), SPH_C32(0xda890000), + SPH_C32(0xfcf56000), SPH_C32(0x686d3607), SPH_C32(0xdadc8975), + SPH_C32(0x9fc49d77), SPH_C32(0x66db1921), SPH_C32(0x8ec80000), + SPH_C32(0x78190000), SPH_C32(0xe7400000), SPH_C32(0xb76bf000), + SPH_C32(0x9b6c31fc), SPH_C32(0x673b9995), SPH_C32(0x1f920bab), + SPH_C32(0xf56ac33a) }, + { SPH_C32(0x9e480000), SPH_C32(0xd8c50000), SPH_C32(0x6bd40000), + SPH_C32(0x832564e0), SPH_C32(0x10cf573f), SPH_C32(0x0bca4a28), + SPH_C32(0x4d9249fe), SPH_C32(0x28b46dff), SPH_C32(0x6dce0000), + SPH_C32(0xc5d80000), SPH_C32(0x60530000), SPH_C32(0x0899f060), + SPH_C32(0xb5d63be6), SPH_C32(0xea8eaec4), SPH_C32(0x6c57a0ad), + SPH_C32(0xaebcd603) }, + { SPH_C32(0xc97f0000), SPH_C32(0x12370000), SPH_C32(0x5d9a0000), + SPH_C32(0x43076060), SPH_C32(0x46d73c1d), SPH_C32(0x5769be24), + SPH_C32(0xec013671), SPH_C32(0x3d0d0c18), SPH_C32(0xd9ff0000), + SPH_C32(0xb2eb0000), SPH_C32(0xd10e0000), SPH_C32(0x7749f480), + SPH_C32(0xcd745ade), SPH_C32(0x3b986d99), SPH_C32(0xbe017424), + SPH_C32(0xe0d3a2dd) }, + { SPH_C32(0x7d4e0000), SPH_C32(0x65040000), SPH_C32(0xecc70000), + SPH_C32(0x3cd76480), SPH_C32(0x3e755d25), SPH_C32(0x867f7d79), + SPH_C32(0x3e57e2f8), SPH_C32(0x736278c6), SPH_C32(0x3af90000), + SPH_C32(0x0f2a0000), SPH_C32(0x561d0000), SPH_C32(0xc8bbf4e0), + SPH_C32(0xe3ce50c4), SPH_C32(0xb62d5ac8), SPH_C32(0xcdc4df22), + SPH_C32(0xbb05b7e4) }, + { SPH_C32(0x8c3a0000), SPH_C32(0xda980000), SPH_C32(0x607f0000), + SPH_C32(0x54078800), SPH_C32(0x85714513), SPH_C32(0x6006b243), + SPH_C32(0xdb50399c), SPH_C32(0x8a58e6a4), SPH_C32(0x1e6c0000), + SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), SPH_C32(0xbcb6b800), + SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), SPH_C32(0x6a0c1bc8), + SPH_C32(0xb99dc2eb) }, + { SPH_C32(0x380b0000), SPH_C32(0xadab0000), SPH_C32(0xd1220000), + SPH_C32(0x2bd78ce0), SPH_C32(0xfdd3242b), SPH_C32(0xb110711e), + SPH_C32(0x0906ed15), SPH_C32(0xc437927a), SPH_C32(0xfd6a0000), + SPH_C32(0x79830000), SPH_C32(0x0d3d0000), SPH_C32(0x0344b860), + SPH_C32(0x02fe19ac), SPH_C32(0x0648e48b), SPH_C32(0x19c9b0ce), + SPH_C32(0xe24bd7d2) }, + { SPH_C32(0x6f3c0000), SPH_C32(0x67590000), SPH_C32(0xe76c0000), + SPH_C32(0xebf58860), SPH_C32(0xabcb4f09), SPH_C32(0xedb38512), + SPH_C32(0xa895929a), SPH_C32(0xd18ef39d), SPH_C32(0x495b0000), + SPH_C32(0x0eb00000), SPH_C32(0xbc600000), SPH_C32(0x7c94bc80), + SPH_C32(0x7a5c7894), SPH_C32(0xd75e27d6), SPH_C32(0xcb9f6447), + SPH_C32(0xac24a30c) }, + { SPH_C32(0xdb0d0000), SPH_C32(0x106a0000), SPH_C32(0x56310000), + SPH_C32(0x94258c80), SPH_C32(0xd3692e31), SPH_C32(0x3ca5464f), + SPH_C32(0x7ac34613), SPH_C32(0x9fe18743), SPH_C32(0xaa5d0000), + SPH_C32(0xb3710000), SPH_C32(0x3b730000), SPH_C32(0xc366bce0), + SPH_C32(0x54e6728e), SPH_C32(0x5aeb1087), SPH_C32(0xb85acf41), + SPH_C32(0xf7f2b635) }, + { SPH_C32(0x8ec80000), SPH_C32(0x78190000), SPH_C32(0xe7400000), + SPH_C32(0xb76bf000), SPH_C32(0x9b6c31fc), SPH_C32(0x673b9995), + SPH_C32(0x1f920bab), SPH_C32(0xf56ac33a), SPH_C32(0xa4b10000), + SPH_C32(0xd7ef0000), SPH_C32(0x3dc90000), SPH_C32(0x4b9e9000), + SPH_C32(0xf30107fb), SPH_C32(0xbde710e0), SPH_C32(0x805696dc), + SPH_C32(0x93b1da1b) }, + { SPH_C32(0x3af90000), SPH_C32(0x0f2a0000), SPH_C32(0x561d0000), + SPH_C32(0xc8bbf4e0), SPH_C32(0xe3ce50c4), SPH_C32(0xb62d5ac8), + SPH_C32(0xcdc4df22), SPH_C32(0xbb05b7e4), SPH_C32(0x47b70000), + SPH_C32(0x6a2e0000), SPH_C32(0xbada0000), SPH_C32(0xf46c9060), + SPH_C32(0xddbb0de1), SPH_C32(0x305227b1), SPH_C32(0xf3933dda), + SPH_C32(0xc867cf22) }, + { SPH_C32(0x6dce0000), SPH_C32(0xc5d80000), SPH_C32(0x60530000), + SPH_C32(0x0899f060), SPH_C32(0xb5d63be6), SPH_C32(0xea8eaec4), + SPH_C32(0x6c57a0ad), SPH_C32(0xaebcd603), SPH_C32(0xf3860000), + SPH_C32(0x1d1d0000), SPH_C32(0x0b870000), SPH_C32(0x8bbc9480), + SPH_C32(0xa5196cd9), SPH_C32(0xe144e4ec), SPH_C32(0x21c5e953), + SPH_C32(0x8608bbfc) }, + { SPH_C32(0xd9ff0000), SPH_C32(0xb2eb0000), SPH_C32(0xd10e0000), + SPH_C32(0x7749f480), SPH_C32(0xcd745ade), SPH_C32(0x3b986d99), + SPH_C32(0xbe017424), SPH_C32(0xe0d3a2dd), SPH_C32(0x10800000), + SPH_C32(0xa0dc0000), SPH_C32(0x8c940000), SPH_C32(0x344e94e0), + SPH_C32(0x8ba366c3), SPH_C32(0x6cf1d3bd), SPH_C32(0x52004255), + SPH_C32(0xdddeaec5) }, + { SPH_C32(0x36e70000), SPH_C32(0xc9350000), SPH_C32(0xd7980000), + SPH_C32(0xa32fa000), SPH_C32(0x5a34515e), SPH_C32(0x561c7179), + SPH_C32(0x310ab488), SPH_C32(0xa074fe54), SPH_C32(0xa6430000), + SPH_C32(0x756e0000), SPH_C32(0xbaf60000), SPH_C32(0xa8f2e800), + SPH_C32(0xed1c7314), SPH_C32(0xbada3b36), SPH_C32(0x4494a4eb), + SPH_C32(0xec83ff85) }, + { SPH_C32(0x82d60000), SPH_C32(0xbe060000), SPH_C32(0x66c50000), + SPH_C32(0xdcffa4e0), SPH_C32(0x22963066), SPH_C32(0x870ab224), + SPH_C32(0xe35c6001), SPH_C32(0xee1b8a8a), SPH_C32(0x45450000), + SPH_C32(0xc8af0000), SPH_C32(0x3de50000), SPH_C32(0x1700e860), + SPH_C32(0xc3a6790e), SPH_C32(0x376f0c67), SPH_C32(0x37510fed), + SPH_C32(0xb755eabc) }, + { SPH_C32(0xd5e10000), SPH_C32(0x74f40000), SPH_C32(0x508b0000), + SPH_C32(0x1cdda060), SPH_C32(0x748e5b44), SPH_C32(0xdba94628), + SPH_C32(0x42cf1f8e), SPH_C32(0xfba2eb6d), SPH_C32(0xf1740000), + SPH_C32(0xbf9c0000), SPH_C32(0x8cb80000), SPH_C32(0x68d0ec80), + SPH_C32(0xbb041836), SPH_C32(0xe679cf3a), SPH_C32(0xe507db64), + SPH_C32(0xf93a9e62) }, + { SPH_C32(0x61d00000), SPH_C32(0x03c70000), SPH_C32(0xe1d60000), + SPH_C32(0x630da480), SPH_C32(0x0c2c3a7c), SPH_C32(0x0abf8575), + SPH_C32(0x9099cb07), SPH_C32(0xb5cd9fb3), SPH_C32(0x12720000), + SPH_C32(0x025d0000), SPH_C32(0x0bab0000), SPH_C32(0xd722ece0), + SPH_C32(0x95be122c), SPH_C32(0x6bccf86b), SPH_C32(0x96c27062), + SPH_C32(0xa2ec8b5b) }, + { SPH_C32(0x34150000), SPH_C32(0x6bb40000), SPH_C32(0x50a70000), + SPH_C32(0x4043d800), SPH_C32(0x442925b1), SPH_C32(0x51215aaf), + SPH_C32(0xf5c886bf), SPH_C32(0xdf46dbca), SPH_C32(0x1c9e0000), + SPH_C32(0x66c30000), SPH_C32(0x0d110000), SPH_C32(0x5fdac000), + SPH_C32(0x32596759), SPH_C32(0x8cc0f80c), SPH_C32(0xaece29ff), + SPH_C32(0xc6afe775) }, + { SPH_C32(0x80240000), SPH_C32(0x1c870000), SPH_C32(0xe1fa0000), + SPH_C32(0x3f93dce0), SPH_C32(0x3c8b4489), SPH_C32(0x803799f2), + SPH_C32(0x279e5236), SPH_C32(0x9129af14), SPH_C32(0xff980000), + SPH_C32(0xdb020000), SPH_C32(0x8a020000), SPH_C32(0xe028c060), + SPH_C32(0x1ce36d43), SPH_C32(0x0175cf5d), SPH_C32(0xdd0b82f9), + SPH_C32(0x9d79f24c) }, + { SPH_C32(0xd7130000), SPH_C32(0xd6750000), SPH_C32(0xd7b40000), + SPH_C32(0xffb1d860), SPH_C32(0x6a932fab), SPH_C32(0xdc946dfe), + SPH_C32(0x860d2db9), SPH_C32(0x8490cef3), SPH_C32(0x4ba90000), + SPH_C32(0xac310000), SPH_C32(0x3b5f0000), SPH_C32(0x9ff8c480), + SPH_C32(0x64410c7b), SPH_C32(0xd0630c00), SPH_C32(0x0f5d5670), + SPH_C32(0xd3168692) }, + { SPH_C32(0x63220000), SPH_C32(0xa1460000), SPH_C32(0x66e90000), + SPH_C32(0x8061dc80), SPH_C32(0x12314e93), SPH_C32(0x0d82aea3), + SPH_C32(0x545bf930), SPH_C32(0xcaffba2d), SPH_C32(0xa8af0000), + SPH_C32(0x11f00000), SPH_C32(0xbc4c0000), SPH_C32(0x200ac4e0), + SPH_C32(0x4afb0661), SPH_C32(0x5dd63b51), SPH_C32(0x7c98fd76), + SPH_C32(0x88c093ab) } +}; + +static const sph_u32 T512_54[64][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x5fa80000), SPH_C32(0x56030000), SPH_C32(0x43ae0000), + SPH_C32(0x64f30013), SPH_C32(0x257e86bf), SPH_C32(0x1311944e), + SPH_C32(0x541e95bf), SPH_C32(0x8ea4db69), SPH_C32(0x00440000), + SPH_C32(0x7f480000), SPH_C32(0xda7c0000), SPH_C32(0x2a230001), + SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), SPH_C32(0x030a9e60), + SPH_C32(0xbe0a679e) }, + { SPH_C32(0x00440000), SPH_C32(0x7f480000), SPH_C32(0xda7c0000), + SPH_C32(0x2a230001), SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), + SPH_C32(0x030a9e60), SPH_C32(0xbe0a679e), SPH_C32(0x5fec0000), + SPH_C32(0x294b0000), SPH_C32(0x99d20000), SPH_C32(0x4ed00012), + SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), SPH_C32(0x57140bdf), + SPH_C32(0x30aebcf7) }, + { SPH_C32(0x5fec0000), SPH_C32(0x294b0000), SPH_C32(0x99d20000), + SPH_C32(0x4ed00012), SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), + SPH_C32(0x57140bdf), SPH_C32(0x30aebcf7), SPH_C32(0x5fa80000), + SPH_C32(0x56030000), SPH_C32(0x43ae0000), SPH_C32(0x64f30013), + SPH_C32(0x257e86bf), SPH_C32(0x1311944e), SPH_C32(0x541e95bf), + SPH_C32(0x8ea4db69) }, + { SPH_C32(0xee930000), SPH_C32(0xd6070000), SPH_C32(0x92c10000), + SPH_C32(0x2b9801e0), SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), + SPH_C32(0x45312374), SPH_C32(0x201f6a64), SPH_C32(0x7b280000), + SPH_C32(0x57420000), SPH_C32(0xa9e50000), SPH_C32(0x634300a0), + SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), SPH_C32(0x27f83b03), + SPH_C32(0xc7ff60f0) }, + { SPH_C32(0xb13b0000), SPH_C32(0x80040000), SPH_C32(0xd16f0000), + SPH_C32(0x4f6b01f3), SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), + SPH_C32(0x112fb6cb), SPH_C32(0xaebbb10d), SPH_C32(0x7b6c0000), + SPH_C32(0x280a0000), SPH_C32(0x73990000), SPH_C32(0x496000a1), + SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), SPH_C32(0x24f2a563), + SPH_C32(0x79f5076e) }, + { SPH_C32(0xeed70000), SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), + SPH_C32(0x01bb01e1), SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), + SPH_C32(0x463bbd14), SPH_C32(0x9e150dfa), SPH_C32(0x24c40000), + SPH_C32(0x7e090000), SPH_C32(0x30370000), SPH_C32(0x2d9300b2), + SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), SPH_C32(0x70ec30dc), + SPH_C32(0xf751dc07) }, + { SPH_C32(0xb17f0000), SPH_C32(0xff4c0000), SPH_C32(0x0b130000), + SPH_C32(0x654801f2), SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), + SPH_C32(0x122528ab), SPH_C32(0x10b1d693), SPH_C32(0x24800000), + SPH_C32(0x01410000), SPH_C32(0xea4b0000), SPH_C32(0x07b000b3), + SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), SPH_C32(0x73e6aebc), + SPH_C32(0x495bbb99) }, + { SPH_C32(0x7b280000), SPH_C32(0x57420000), SPH_C32(0xa9e50000), + SPH_C32(0x634300a0), SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), + SPH_C32(0x27f83b03), SPH_C32(0xc7ff60f0), SPH_C32(0x95bb0000), + SPH_C32(0x81450000), SPH_C32(0x3b240000), SPH_C32(0x48db0140), + SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), SPH_C32(0x62c91877), + SPH_C32(0xe7e00a94) }, + { SPH_C32(0x24800000), SPH_C32(0x01410000), SPH_C32(0xea4b0000), + SPH_C32(0x07b000b3), SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), + SPH_C32(0x73e6aebc), SPH_C32(0x495bbb99), SPH_C32(0x95ff0000), + SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), SPH_C32(0x62f80141), + SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), SPH_C32(0x61c38617), + SPH_C32(0x59ea6d0a) }, + { SPH_C32(0x7b6c0000), SPH_C32(0x280a0000), SPH_C32(0x73990000), + SPH_C32(0x496000a1), SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), + SPH_C32(0x24f2a563), SPH_C32(0x79f5076e), SPH_C32(0xca570000), + SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), SPH_C32(0x060b0152), + SPH_C32(0x14592320), SPH_C32(0xec526625), SPH_C32(0x35dd13a8), + SPH_C32(0xd74eb663) }, + { SPH_C32(0x24c40000), SPH_C32(0x7e090000), SPH_C32(0x30370000), + SPH_C32(0x2d9300b2), SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), + SPH_C32(0x70ec30dc), SPH_C32(0xf751dc07), SPH_C32(0xca130000), + SPH_C32(0xd7460000), SPH_C32(0x788a0000), SPH_C32(0x2c280153), + SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), SPH_C32(0x36d78dc8), + SPH_C32(0x6944d1fd) }, + { SPH_C32(0x95bb0000), SPH_C32(0x81450000), SPH_C32(0x3b240000), + SPH_C32(0x48db0140), SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), + SPH_C32(0x62c91877), SPH_C32(0xe7e00a94), SPH_C32(0xee930000), + SPH_C32(0xd6070000), SPH_C32(0x92c10000), SPH_C32(0x2b9801e0), + SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), SPH_C32(0x45312374), + SPH_C32(0x201f6a64) }, + { SPH_C32(0xca130000), SPH_C32(0xd7460000), SPH_C32(0x788a0000), + SPH_C32(0x2c280153), SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), + SPH_C32(0x36d78dc8), SPH_C32(0x6944d1fd), SPH_C32(0xeed70000), + SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), SPH_C32(0x01bb01e1), + SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), SPH_C32(0x463bbd14), + SPH_C32(0x9e150dfa) }, + { SPH_C32(0x95ff0000), SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), + SPH_C32(0x62f80141), SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), + SPH_C32(0x61c38617), SPH_C32(0x59ea6d0a), SPH_C32(0xb17f0000), + SPH_C32(0xff4c0000), SPH_C32(0x0b130000), SPH_C32(0x654801f2), + SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), SPH_C32(0x122528ab), + SPH_C32(0x10b1d693) }, + { SPH_C32(0xca570000), SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), + SPH_C32(0x060b0152), SPH_C32(0x14592320), SPH_C32(0xec526625), + SPH_C32(0x35dd13a8), SPH_C32(0xd74eb663), SPH_C32(0xb13b0000), + SPH_C32(0x80040000), SPH_C32(0xd16f0000), SPH_C32(0x4f6b01f3), + SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), SPH_C32(0x112fb6cb), + SPH_C32(0xaebbb10d) }, + { SPH_C32(0xe6280000), SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), + SPH_C32(0xd3d002e0), SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), + SPH_C32(0x289506b4), SPH_C32(0xd75a4897), SPH_C32(0xf0c50000), + SPH_C32(0x59230000), SPH_C32(0x45820000), SPH_C32(0xe18d00c0), + SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), SPH_C32(0xcbe0fe1c), + SPH_C32(0x56a7b19f) }, + { SPH_C32(0xb9800000), SPH_C32(0x1a480000), SPH_C32(0xebfb0000), + SPH_C32(0xb72302f3), SPH_C32(0xfd1fb607), SPH_C32(0x8bb62494), + SPH_C32(0x7c8b930b), SPH_C32(0x59fe93fe), SPH_C32(0xf0810000), + SPH_C32(0x266b0000), SPH_C32(0x9ffe0000), SPH_C32(0xcbae00c1), + SPH_C32(0x00c0cffd), SPH_C32(0x6b5bca1e), SPH_C32(0xc8ea607c), + SPH_C32(0xe8add601) }, + { SPH_C32(0xe66c0000), SPH_C32(0x33030000), SPH_C32(0x72290000), + SPH_C32(0xf9f302e1), SPH_C32(0xe3ccf974), SPH_C32(0x31112c5d), + SPH_C32(0x2b9f98d4), SPH_C32(0x69502f09), SPH_C32(0xaf290000), + SPH_C32(0x70680000), SPH_C32(0xdc500000), SPH_C32(0xaf5d00d2), + SPH_C32(0x25be4942), SPH_C32(0x784a5e50), SPH_C32(0x9cf4f5c3), + SPH_C32(0x66090d68) }, + { SPH_C32(0xb9c40000), SPH_C32(0x65000000), SPH_C32(0x31870000), + SPH_C32(0x9d0002f2), SPH_C32(0xc6b27fcb), SPH_C32(0x2200b813), + SPH_C32(0x7f810d6b), SPH_C32(0xe7f4f460), SPH_C32(0xaf6d0000), + SPH_C32(0x0f200000), SPH_C32(0x062c0000), SPH_C32(0x857e00d3), + SPH_C32(0x1e13808e), SPH_C32(0xd1fcc2d7), SPH_C32(0x9ffe6ba3), + SPH_C32(0xd8036af6) }, + { SPH_C32(0x08bb0000), SPH_C32(0x9a4c0000), SPH_C32(0x3a940000), + SPH_C32(0xf8480300), SPH_C32(0x4c3018c4), SPH_C32(0xa3cb4b8d), + SPH_C32(0x6da425c0), SPH_C32(0xf74522f3), SPH_C32(0x8bed0000), + SPH_C32(0x0e610000), SPH_C32(0xec670000), SPH_C32(0x82ce0060), + SPH_C32(0xa5b6421e), SPH_C32(0xaf74c322), SPH_C32(0xec18c51f), + SPH_C32(0x9158d16f) }, + { SPH_C32(0x57130000), SPH_C32(0xcc4f0000), SPH_C32(0x793a0000), + SPH_C32(0x9cbb0313), SPH_C32(0x694e9e7b), SPH_C32(0xb0dadfc3), + SPH_C32(0x39bab07f), SPH_C32(0x79e1f99a), SPH_C32(0x8ba90000), + SPH_C32(0x71290000), SPH_C32(0x361b0000), SPH_C32(0xa8ed0061), + SPH_C32(0x9e1b8bd2), SPH_C32(0x06c25fa5), SPH_C32(0xef125b7f), + SPH_C32(0x2f52b6f1) }, + { SPH_C32(0x08ff0000), SPH_C32(0xe5040000), SPH_C32(0xe0e80000), + SPH_C32(0xd26b0301), SPH_C32(0x779dd108), SPH_C32(0x0a7dd70a), + SPH_C32(0x6eaebba0), SPH_C32(0x494f456d), SPH_C32(0xd4010000), + SPH_C32(0x272a0000), SPH_C32(0x75b50000), SPH_C32(0xcc1e0072), + SPH_C32(0xbb650d6d), SPH_C32(0x15d3cbeb), SPH_C32(0xbb0ccec0), + SPH_C32(0xa1f66d98) }, + { SPH_C32(0x57570000), SPH_C32(0xb3070000), SPH_C32(0xa3460000), + SPH_C32(0xb6980312), SPH_C32(0x52e357b7), SPH_C32(0x196c4344), + SPH_C32(0x3ab02e1f), SPH_C32(0xc7eb9e04), SPH_C32(0xd4450000), + SPH_C32(0x58620000), SPH_C32(0xafc90000), SPH_C32(0xe63d0073), + SPH_C32(0x80c8c4a1), SPH_C32(0xbc65576c), SPH_C32(0xb80650a0), + SPH_C32(0x1ffc0a06) }, + { SPH_C32(0x9d000000), SPH_C32(0x1b090000), SPH_C32(0x01b00000), + SPH_C32(0xb0930240), SPH_C32(0x46ba7497), SPH_C32(0xf53e2561), + SPH_C32(0x0f6d3db7), SPH_C32(0x10a52867), SPH_C32(0x657e0000), + SPH_C32(0xd8660000), SPH_C32(0x7ea60000), SPH_C32(0xa9560180), + SPH_C32(0x31e76a62), SPH_C32(0x94183875), SPH_C32(0xa929e66b), + SPH_C32(0xb147bb0b) }, + { SPH_C32(0xc2a80000), SPH_C32(0x4d0a0000), SPH_C32(0x421e0000), + SPH_C32(0xd4600253), SPH_C32(0x63c4f228), SPH_C32(0xe62fb12f), + SPH_C32(0x5b73a808), SPH_C32(0x9e01f30e), SPH_C32(0x653a0000), + SPH_C32(0xa72e0000), SPH_C32(0xa4da0000), SPH_C32(0x83750181), + SPH_C32(0x0a4aa3ae), SPH_C32(0x3daea4f2), SPH_C32(0xaa23780b), + SPH_C32(0x0f4ddc95) }, + { SPH_C32(0x9d440000), SPH_C32(0x64410000), SPH_C32(0xdbcc0000), + SPH_C32(0x9ab00241), SPH_C32(0x7d17bd5b), SPH_C32(0x5c88b9e6), + SPH_C32(0x0c67a3d7), SPH_C32(0xaeaf4ff9), SPH_C32(0x3a920000), + SPH_C32(0xf12d0000), SPH_C32(0xe7740000), SPH_C32(0xe7860192), + SPH_C32(0x2f342511), SPH_C32(0x2ebf30bc), SPH_C32(0xfe3dedb4), + SPH_C32(0x81e907fc) }, + { SPH_C32(0xc2ec0000), SPH_C32(0x32420000), SPH_C32(0x98620000), + SPH_C32(0xfe430252), SPH_C32(0x58693be4), SPH_C32(0x4f992da8), + SPH_C32(0x58793668), SPH_C32(0x200b9490), SPH_C32(0x3ad60000), + SPH_C32(0x8e650000), SPH_C32(0x3d080000), SPH_C32(0xcda50193), + SPH_C32(0x1499ecdd), SPH_C32(0x8709ac3b), SPH_C32(0xfd3773d4), + SPH_C32(0x3fe36062) }, + { SPH_C32(0x73930000), SPH_C32(0xcd0e0000), SPH_C32(0x93710000), + SPH_C32(0x9b0b03a0), SPH_C32(0xd2eb5ceb), SPH_C32(0xce52de36), + SPH_C32(0x4a5c1ec3), SPH_C32(0x30ba4203), SPH_C32(0x1e560000), + SPH_C32(0x8f240000), SPH_C32(0xd7430000), SPH_C32(0xca150120), + SPH_C32(0xaf3c2e4d), SPH_C32(0xf981adce), SPH_C32(0x8ed1dd68), + SPH_C32(0x76b8dbfb) }, + { SPH_C32(0x2c3b0000), SPH_C32(0x9b0d0000), SPH_C32(0xd0df0000), + SPH_C32(0xfff803b3), SPH_C32(0xf795da54), SPH_C32(0xdd434a78), + SPH_C32(0x1e428b7c), SPH_C32(0xbe1e996a), SPH_C32(0x1e120000), + SPH_C32(0xf06c0000), SPH_C32(0x0d3f0000), SPH_C32(0xe0360121), + SPH_C32(0x9491e781), SPH_C32(0x50373149), SPH_C32(0x8ddb4308), + SPH_C32(0xc8b2bc65) }, + { SPH_C32(0x73d70000), SPH_C32(0xb2460000), SPH_C32(0x490d0000), + SPH_C32(0xb12803a1), SPH_C32(0xe9469527), SPH_C32(0x67e442b1), + SPH_C32(0x495680a3), SPH_C32(0x8eb0259d), SPH_C32(0x41ba0000), + SPH_C32(0xa66f0000), SPH_C32(0x4e910000), SPH_C32(0x84c50132), + SPH_C32(0xb1ef613e), SPH_C32(0x4326a507), SPH_C32(0xd9c5d6b7), + SPH_C32(0x4616670c) }, + { SPH_C32(0x2c7f0000), SPH_C32(0xe4450000), SPH_C32(0x0aa30000), + SPH_C32(0xd5db03b2), SPH_C32(0xcc381398), SPH_C32(0x74f5d6ff), + SPH_C32(0x1d48151c), SPH_C32(0x0014fef4), SPH_C32(0x41fe0000), + SPH_C32(0xd9270000), SPH_C32(0x94ed0000), SPH_C32(0xaee60133), + SPH_C32(0x8a42a8f2), SPH_C32(0xea903980), SPH_C32(0xdacf48d7), + SPH_C32(0xf81c0092) }, + { SPH_C32(0xf0c50000), SPH_C32(0x59230000), SPH_C32(0x45820000), + SPH_C32(0xe18d00c0), SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), + SPH_C32(0xcbe0fe1c), SPH_C32(0x56a7b19f), SPH_C32(0x16ed0000), + SPH_C32(0x15680000), SPH_C32(0xedd70000), SPH_C32(0x325d0220), + SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), SPH_C32(0xe375f8a8), + SPH_C32(0x81fdf908) }, + { SPH_C32(0xaf6d0000), SPH_C32(0x0f200000), SPH_C32(0x062c0000), + SPH_C32(0x857e00d3), SPH_C32(0x1e13808e), SPH_C32(0xd1fcc2d7), + SPH_C32(0x9ffe6ba3), SPH_C32(0xd8036af6), SPH_C32(0x16a90000), + SPH_C32(0x6a200000), SPH_C32(0x37ab0000), SPH_C32(0x187e0221), + SPH_C32(0xd8a1ff45), SPH_C32(0xf3fc7ac4), SPH_C32(0xe07f66c8), + SPH_C32(0x3ff79e96) }, + { SPH_C32(0xf0810000), SPH_C32(0x266b0000), SPH_C32(0x9ffe0000), + SPH_C32(0xcbae00c1), SPH_C32(0x00c0cffd), SPH_C32(0x6b5bca1e), + SPH_C32(0xc8ea607c), SPH_C32(0xe8add601), SPH_C32(0x49010000), + SPH_C32(0x3c230000), SPH_C32(0x74050000), SPH_C32(0x7c8d0232), + SPH_C32(0xfddf79fa), SPH_C32(0xe0edee8a), SPH_C32(0xb461f377), + SPH_C32(0xb15345ff) }, + { SPH_C32(0xaf290000), SPH_C32(0x70680000), SPH_C32(0xdc500000), + SPH_C32(0xaf5d00d2), SPH_C32(0x25be4942), SPH_C32(0x784a5e50), + SPH_C32(0x9cf4f5c3), SPH_C32(0x66090d68), SPH_C32(0x49450000), + SPH_C32(0x436b0000), SPH_C32(0xae790000), SPH_C32(0x56ae0233), + SPH_C32(0xc672b036), SPH_C32(0x495b720d), SPH_C32(0xb76b6d17), + SPH_C32(0x0f592261) }, + { SPH_C32(0x1e560000), SPH_C32(0x8f240000), SPH_C32(0xd7430000), + SPH_C32(0xca150120), SPH_C32(0xaf3c2e4d), SPH_C32(0xf981adce), + SPH_C32(0x8ed1dd68), SPH_C32(0x76b8dbfb), SPH_C32(0x6dc50000), + SPH_C32(0x422a0000), SPH_C32(0x44320000), SPH_C32(0x511e0280), + SPH_C32(0x7dd772a6), SPH_C32(0x37d373f8), SPH_C32(0xc48dc3ab), + SPH_C32(0x460299f8) }, + { SPH_C32(0x41fe0000), SPH_C32(0xd9270000), SPH_C32(0x94ed0000), + SPH_C32(0xaee60133), SPH_C32(0x8a42a8f2), SPH_C32(0xea903980), + SPH_C32(0xdacf48d7), SPH_C32(0xf81c0092), SPH_C32(0x6d810000), + SPH_C32(0x3d620000), SPH_C32(0x9e4e0000), SPH_C32(0x7b3d0281), + SPH_C32(0x467abb6a), SPH_C32(0x9e65ef7f), SPH_C32(0xc7875dcb), + SPH_C32(0xf808fe66) }, + { SPH_C32(0x1e120000), SPH_C32(0xf06c0000), SPH_C32(0x0d3f0000), + SPH_C32(0xe0360121), SPH_C32(0x9491e781), SPH_C32(0x50373149), + SPH_C32(0x8ddb4308), SPH_C32(0xc8b2bc65), SPH_C32(0x32290000), + SPH_C32(0x6b610000), SPH_C32(0xdde00000), SPH_C32(0x1fce0292), + SPH_C32(0x63043dd5), SPH_C32(0x8d747b31), SPH_C32(0x9399c874), + SPH_C32(0x76ac250f) }, + { SPH_C32(0x41ba0000), SPH_C32(0xa66f0000), SPH_C32(0x4e910000), + SPH_C32(0x84c50132), SPH_C32(0xb1ef613e), SPH_C32(0x4326a507), + SPH_C32(0xd9c5d6b7), SPH_C32(0x4616670c), SPH_C32(0x326d0000), + SPH_C32(0x14290000), SPH_C32(0x079c0000), SPH_C32(0x35ed0293), + SPH_C32(0x58a9f419), SPH_C32(0x24c2e7b6), SPH_C32(0x90935614), + SPH_C32(0xc8a64291) }, + { SPH_C32(0x8bed0000), SPH_C32(0x0e610000), SPH_C32(0xec670000), + SPH_C32(0x82ce0060), SPH_C32(0xa5b6421e), SPH_C32(0xaf74c322), + SPH_C32(0xec18c51f), SPH_C32(0x9158d16f), SPH_C32(0x83560000), + SPH_C32(0x942d0000), SPH_C32(0xd6f30000), SPH_C32(0x7a860360), + SPH_C32(0xe9865ada), SPH_C32(0x0cbf88af), SPH_C32(0x81bce0df), + SPH_C32(0x661df39c) }, + { SPH_C32(0xd4450000), SPH_C32(0x58620000), SPH_C32(0xafc90000), + SPH_C32(0xe63d0073), SPH_C32(0x80c8c4a1), SPH_C32(0xbc65576c), + SPH_C32(0xb80650a0), SPH_C32(0x1ffc0a06), SPH_C32(0x83120000), + SPH_C32(0xeb650000), SPH_C32(0x0c8f0000), SPH_C32(0x50a50361), + SPH_C32(0xd22b9316), SPH_C32(0xa5091428), SPH_C32(0x82b67ebf), + SPH_C32(0xd8179402) }, + { SPH_C32(0x8ba90000), SPH_C32(0x71290000), SPH_C32(0x361b0000), + SPH_C32(0xa8ed0061), SPH_C32(0x9e1b8bd2), SPH_C32(0x06c25fa5), + SPH_C32(0xef125b7f), SPH_C32(0x2f52b6f1), SPH_C32(0xdcba0000), + SPH_C32(0xbd660000), SPH_C32(0x4f210000), SPH_C32(0x34560372), + SPH_C32(0xf75515a9), SPH_C32(0xb6188066), SPH_C32(0xd6a8eb00), + SPH_C32(0x56b34f6b) }, + { SPH_C32(0xd4010000), SPH_C32(0x272a0000), SPH_C32(0x75b50000), + SPH_C32(0xcc1e0072), SPH_C32(0xbb650d6d), SPH_C32(0x15d3cbeb), + SPH_C32(0xbb0ccec0), SPH_C32(0xa1f66d98), SPH_C32(0xdcfe0000), + SPH_C32(0xc22e0000), SPH_C32(0x955d0000), SPH_C32(0x1e750373), + SPH_C32(0xccf8dc65), SPH_C32(0x1fae1ce1), SPH_C32(0xd5a27560), + SPH_C32(0xe8b928f5) }, + { SPH_C32(0x657e0000), SPH_C32(0xd8660000), SPH_C32(0x7ea60000), + SPH_C32(0xa9560180), SPH_C32(0x31e76a62), SPH_C32(0x94183875), + SPH_C32(0xa929e66b), SPH_C32(0xb147bb0b), SPH_C32(0xf87e0000), + SPH_C32(0xc36f0000), SPH_C32(0x7f160000), SPH_C32(0x19c503c0), + SPH_C32(0x775d1ef5), SPH_C32(0x61261d14), SPH_C32(0xa644dbdc), + SPH_C32(0xa1e2936c) }, + { SPH_C32(0x3ad60000), SPH_C32(0x8e650000), SPH_C32(0x3d080000), + SPH_C32(0xcda50193), SPH_C32(0x1499ecdd), SPH_C32(0x8709ac3b), + SPH_C32(0xfd3773d4), SPH_C32(0x3fe36062), SPH_C32(0xf83a0000), + SPH_C32(0xbc270000), SPH_C32(0xa56a0000), SPH_C32(0x33e603c1), + SPH_C32(0x4cf0d739), SPH_C32(0xc8908193), SPH_C32(0xa54e45bc), + SPH_C32(0x1fe8f4f2) }, + { SPH_C32(0x653a0000), SPH_C32(0xa72e0000), SPH_C32(0xa4da0000), + SPH_C32(0x83750181), SPH_C32(0x0a4aa3ae), SPH_C32(0x3daea4f2), + SPH_C32(0xaa23780b), SPH_C32(0x0f4ddc95), SPH_C32(0xa7920000), + SPH_C32(0xea240000), SPH_C32(0xe6c40000), SPH_C32(0x571503d2), + SPH_C32(0x698e5186), SPH_C32(0xdb8115dd), SPH_C32(0xf150d003), + SPH_C32(0x914c2f9b) }, + { SPH_C32(0x3a920000), SPH_C32(0xf12d0000), SPH_C32(0xe7740000), + SPH_C32(0xe7860192), SPH_C32(0x2f342511), SPH_C32(0x2ebf30bc), + SPH_C32(0xfe3dedb4), SPH_C32(0x81e907fc), SPH_C32(0xa7d60000), + SPH_C32(0x956c0000), SPH_C32(0x3cb80000), SPH_C32(0x7d3603d3), + SPH_C32(0x5223984a), SPH_C32(0x7237895a), SPH_C32(0xf25a4e63), + SPH_C32(0x2f464805) }, + { SPH_C32(0x16ed0000), SPH_C32(0x15680000), SPH_C32(0xedd70000), + SPH_C32(0x325d0220), SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), + SPH_C32(0xe375f8a8), SPH_C32(0x81fdf908), SPH_C32(0xe6280000), + SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), SPH_C32(0xd3d002e0), + SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), SPH_C32(0x289506b4), + SPH_C32(0xd75a4897) }, + { SPH_C32(0x49450000), SPH_C32(0x436b0000), SPH_C32(0xae790000), + SPH_C32(0x56ae0233), SPH_C32(0xc672b036), SPH_C32(0x495b720d), + SPH_C32(0xb76b6d17), SPH_C32(0x0f592261), SPH_C32(0xe66c0000), + SPH_C32(0x33030000), SPH_C32(0x72290000), SPH_C32(0xf9f302e1), + SPH_C32(0xe3ccf974), SPH_C32(0x31112c5d), SPH_C32(0x2b9f98d4), + SPH_C32(0x69502f09) }, + { SPH_C32(0x16a90000), SPH_C32(0x6a200000), SPH_C32(0x37ab0000), + SPH_C32(0x187e0221), SPH_C32(0xd8a1ff45), SPH_C32(0xf3fc7ac4), + SPH_C32(0xe07f66c8), SPH_C32(0x3ff79e96), SPH_C32(0xb9c40000), + SPH_C32(0x65000000), SPH_C32(0x31870000), SPH_C32(0x9d0002f2), + SPH_C32(0xc6b27fcb), SPH_C32(0x2200b813), SPH_C32(0x7f810d6b), + SPH_C32(0xe7f4f460) }, + { SPH_C32(0x49010000), SPH_C32(0x3c230000), SPH_C32(0x74050000), + SPH_C32(0x7c8d0232), SPH_C32(0xfddf79fa), SPH_C32(0xe0edee8a), + SPH_C32(0xb461f377), SPH_C32(0xb15345ff), SPH_C32(0xb9800000), + SPH_C32(0x1a480000), SPH_C32(0xebfb0000), SPH_C32(0xb72302f3), + SPH_C32(0xfd1fb607), SPH_C32(0x8bb62494), SPH_C32(0x7c8b930b), + SPH_C32(0x59fe93fe) }, + { SPH_C32(0xf87e0000), SPH_C32(0xc36f0000), SPH_C32(0x7f160000), + SPH_C32(0x19c503c0), SPH_C32(0x775d1ef5), SPH_C32(0x61261d14), + SPH_C32(0xa644dbdc), SPH_C32(0xa1e2936c), SPH_C32(0x9d000000), + SPH_C32(0x1b090000), SPH_C32(0x01b00000), SPH_C32(0xb0930240), + SPH_C32(0x46ba7497), SPH_C32(0xf53e2561), SPH_C32(0x0f6d3db7), + SPH_C32(0x10a52867) }, + { SPH_C32(0xa7d60000), SPH_C32(0x956c0000), SPH_C32(0x3cb80000), + SPH_C32(0x7d3603d3), SPH_C32(0x5223984a), SPH_C32(0x7237895a), + SPH_C32(0xf25a4e63), SPH_C32(0x2f464805), SPH_C32(0x9d440000), + SPH_C32(0x64410000), SPH_C32(0xdbcc0000), SPH_C32(0x9ab00241), + SPH_C32(0x7d17bd5b), SPH_C32(0x5c88b9e6), SPH_C32(0x0c67a3d7), + SPH_C32(0xaeaf4ff9) }, + { SPH_C32(0xf83a0000), SPH_C32(0xbc270000), SPH_C32(0xa56a0000), + SPH_C32(0x33e603c1), SPH_C32(0x4cf0d739), SPH_C32(0xc8908193), + SPH_C32(0xa54e45bc), SPH_C32(0x1fe8f4f2), SPH_C32(0xc2ec0000), + SPH_C32(0x32420000), SPH_C32(0x98620000), SPH_C32(0xfe430252), + SPH_C32(0x58693be4), SPH_C32(0x4f992da8), SPH_C32(0x58793668), + SPH_C32(0x200b9490) }, + { SPH_C32(0xa7920000), SPH_C32(0xea240000), SPH_C32(0xe6c40000), + SPH_C32(0x571503d2), SPH_C32(0x698e5186), SPH_C32(0xdb8115dd), + SPH_C32(0xf150d003), SPH_C32(0x914c2f9b), SPH_C32(0xc2a80000), + SPH_C32(0x4d0a0000), SPH_C32(0x421e0000), SPH_C32(0xd4600253), + SPH_C32(0x63c4f228), SPH_C32(0xe62fb12f), SPH_C32(0x5b73a808), + SPH_C32(0x9e01f30e) }, + { SPH_C32(0x6dc50000), SPH_C32(0x422a0000), SPH_C32(0x44320000), + SPH_C32(0x511e0280), SPH_C32(0x7dd772a6), SPH_C32(0x37d373f8), + SPH_C32(0xc48dc3ab), SPH_C32(0x460299f8), SPH_C32(0x73930000), + SPH_C32(0xcd0e0000), SPH_C32(0x93710000), SPH_C32(0x9b0b03a0), + SPH_C32(0xd2eb5ceb), SPH_C32(0xce52de36), SPH_C32(0x4a5c1ec3), + SPH_C32(0x30ba4203) }, + { SPH_C32(0x326d0000), SPH_C32(0x14290000), SPH_C32(0x079c0000), + SPH_C32(0x35ed0293), SPH_C32(0x58a9f419), SPH_C32(0x24c2e7b6), + SPH_C32(0x90935614), SPH_C32(0xc8a64291), SPH_C32(0x73d70000), + SPH_C32(0xb2460000), SPH_C32(0x490d0000), SPH_C32(0xb12803a1), + SPH_C32(0xe9469527), SPH_C32(0x67e442b1), SPH_C32(0x495680a3), + SPH_C32(0x8eb0259d) }, + { SPH_C32(0x6d810000), SPH_C32(0x3d620000), SPH_C32(0x9e4e0000), + SPH_C32(0x7b3d0281), SPH_C32(0x467abb6a), SPH_C32(0x9e65ef7f), + SPH_C32(0xc7875dcb), SPH_C32(0xf808fe66), SPH_C32(0x2c7f0000), + SPH_C32(0xe4450000), SPH_C32(0x0aa30000), SPH_C32(0xd5db03b2), + SPH_C32(0xcc381398), SPH_C32(0x74f5d6ff), SPH_C32(0x1d48151c), + SPH_C32(0x0014fef4) }, + { SPH_C32(0x32290000), SPH_C32(0x6b610000), SPH_C32(0xdde00000), + SPH_C32(0x1fce0292), SPH_C32(0x63043dd5), SPH_C32(0x8d747b31), + SPH_C32(0x9399c874), SPH_C32(0x76ac250f), SPH_C32(0x2c3b0000), + SPH_C32(0x9b0d0000), SPH_C32(0xd0df0000), SPH_C32(0xfff803b3), + SPH_C32(0xf795da54), SPH_C32(0xdd434a78), SPH_C32(0x1e428b7c), + SPH_C32(0xbe1e996a) }, + { SPH_C32(0x83560000), SPH_C32(0x942d0000), SPH_C32(0xd6f30000), + SPH_C32(0x7a860360), SPH_C32(0xe9865ada), SPH_C32(0x0cbf88af), + SPH_C32(0x81bce0df), SPH_C32(0x661df39c), SPH_C32(0x08bb0000), + SPH_C32(0x9a4c0000), SPH_C32(0x3a940000), SPH_C32(0xf8480300), + SPH_C32(0x4c3018c4), SPH_C32(0xa3cb4b8d), SPH_C32(0x6da425c0), + SPH_C32(0xf74522f3) }, + { SPH_C32(0xdcfe0000), SPH_C32(0xc22e0000), SPH_C32(0x955d0000), + SPH_C32(0x1e750373), SPH_C32(0xccf8dc65), SPH_C32(0x1fae1ce1), + SPH_C32(0xd5a27560), SPH_C32(0xe8b928f5), SPH_C32(0x08ff0000), + SPH_C32(0xe5040000), SPH_C32(0xe0e80000), SPH_C32(0xd26b0301), + SPH_C32(0x779dd108), SPH_C32(0x0a7dd70a), SPH_C32(0x6eaebba0), + SPH_C32(0x494f456d) }, + { SPH_C32(0x83120000), SPH_C32(0xeb650000), SPH_C32(0x0c8f0000), + SPH_C32(0x50a50361), SPH_C32(0xd22b9316), SPH_C32(0xa5091428), + SPH_C32(0x82b67ebf), SPH_C32(0xd8179402), SPH_C32(0x57570000), + SPH_C32(0xb3070000), SPH_C32(0xa3460000), SPH_C32(0xb6980312), + SPH_C32(0x52e357b7), SPH_C32(0x196c4344), SPH_C32(0x3ab02e1f), + SPH_C32(0xc7eb9e04) }, + { SPH_C32(0xdcba0000), SPH_C32(0xbd660000), SPH_C32(0x4f210000), + SPH_C32(0x34560372), SPH_C32(0xf75515a9), SPH_C32(0xb6188066), + SPH_C32(0xd6a8eb00), SPH_C32(0x56b34f6b), SPH_C32(0x57130000), + SPH_C32(0xcc4f0000), SPH_C32(0x793a0000), SPH_C32(0x9cbb0313), + SPH_C32(0x694e9e7b), SPH_C32(0xb0dadfc3), SPH_C32(0x39bab07f), + SPH_C32(0x79e1f99a) } +}; + +static const sph_u32 T512_60[16][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x033d0000), SPH_C32(0x08b30000), SPH_C32(0xf33a0000), + SPH_C32(0x3ac20007), SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), + SPH_C32(0x0ea5cfe3), SPH_C32(0xe6da7ffe), SPH_C32(0xa8da0000), + SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), SPH_C32(0x07da0002), + SPH_C32(0x7d669583), SPH_C32(0x1f98708a), SPH_C32(0xbb668808), + SPH_C32(0xda878000) }, + { SPH_C32(0xa8da0000), SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), + SPH_C32(0x07da0002), SPH_C32(0x7d669583), SPH_C32(0x1f98708a), + SPH_C32(0xbb668808), SPH_C32(0xda878000), SPH_C32(0xabe70000), + SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), SPH_C32(0x3d180005), + SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), SPH_C32(0xb5c347eb), + SPH_C32(0x3c5dfffe) }, + { SPH_C32(0xabe70000), SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), + SPH_C32(0x3d180005), SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), + SPH_C32(0xb5c347eb), SPH_C32(0x3c5dfffe), SPH_C32(0x033d0000), + SPH_C32(0x08b30000), SPH_C32(0xf33a0000), SPH_C32(0x3ac20007), + SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), SPH_C32(0x0ea5cfe3), + SPH_C32(0xe6da7ffe) }, + { SPH_C32(0x01930000), SPH_C32(0xe7820000), SPH_C32(0xedfb0000), + SPH_C32(0xcf0c000b), SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), + SPH_C32(0x063661e1), SPH_C32(0x536f9e7b), SPH_C32(0x92280000), + SPH_C32(0xdc850000), SPH_C32(0x57fa0000), SPH_C32(0x56dc0003), + SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), SPH_C32(0x90cef752), + SPH_C32(0x7b1675d7) }, + { SPH_C32(0x02ae0000), SPH_C32(0xef310000), SPH_C32(0x1ec10000), + SPH_C32(0xf5ce000c), SPH_C32(0xdcf90708), SPH_C32(0xd7cdd231), + SPH_C32(0x0893ae02), SPH_C32(0xb5b5e185), SPH_C32(0x3af20000), + SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), SPH_C32(0x51060001), + SPH_C32(0xc78fb695), SPH_C32(0x4577d386), SPH_C32(0x2ba87f5a), + SPH_C32(0xa191f5d7) }, + { SPH_C32(0xa9490000), SPH_C32(0x713c0000), SPH_C32(0xb1e60000), + SPH_C32(0xc8d60009), SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), + SPH_C32(0xbd50e9e9), SPH_C32(0x89e81e7b), SPH_C32(0x39cf0000), + SPH_C32(0x42880000), SPH_C32(0xf8dd0000), SPH_C32(0x6bc40006), + SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), SPH_C32(0x250db0b9), + SPH_C32(0x474b8a29) }, + { SPH_C32(0xaa740000), SPH_C32(0x798f0000), SPH_C32(0x42dc0000), + SPH_C32(0xf214000e), SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), + SPH_C32(0xb3f5260a), SPH_C32(0x6f326185), SPH_C32(0x91150000), + SPH_C32(0xd4360000), SPH_C32(0xa4c00000), SPH_C32(0x6c1e0004), + SPH_C32(0xebc0a946), SPH_C32(0x3181c513), SPH_C32(0x9e6b38b1), + SPH_C32(0x9dcc0a29) }, + { SPH_C32(0x92280000), SPH_C32(0xdc850000), SPH_C32(0x57fa0000), + SPH_C32(0x56dc0003), SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), + SPH_C32(0x90cef752), SPH_C32(0x7b1675d7), SPH_C32(0x93bb0000), + SPH_C32(0x3b070000), SPH_C32(0xba010000), SPH_C32(0x99d00008), + SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), SPH_C32(0x96f896b3), + SPH_C32(0x2879ebac) }, + { SPH_C32(0x91150000), SPH_C32(0xd4360000), SPH_C32(0xa4c00000), + SPH_C32(0x6c1e0004), SPH_C32(0xebc0a946), SPH_C32(0x3181c513), + SPH_C32(0x9e6b38b1), SPH_C32(0x9dcc0a29), SPH_C32(0x3b610000), + SPH_C32(0xadb90000), SPH_C32(0xe61c0000), SPH_C32(0x9e0a000a), + SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), SPH_C32(0x2d9e1ebb), + SPH_C32(0xf2fe6bac) }, + { SPH_C32(0x3af20000), SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), + SPH_C32(0x51060001), SPH_C32(0xc78fb695), SPH_C32(0x4577d386), + SPH_C32(0x2ba87f5a), SPH_C32(0xa191f5d7), SPH_C32(0x385c0000), + SPH_C32(0xa50a0000), SPH_C32(0x15260000), SPH_C32(0xa4c8000d), + SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), SPH_C32(0x233bd158), + SPH_C32(0x14241452) }, + { SPH_C32(0x39cf0000), SPH_C32(0x42880000), SPH_C32(0xf8dd0000), + SPH_C32(0x6bc40006), SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), + SPH_C32(0x250db0b9), SPH_C32(0x474b8a29), SPH_C32(0x90860000), + SPH_C32(0x33b40000), SPH_C32(0x493b0000), SPH_C32(0xa312000f), + SPH_C32(0x6610241e), SPH_C32(0x8d22713d), SPH_C32(0x985d5950), + SPH_C32(0xcea39452) }, + { SPH_C32(0x93bb0000), SPH_C32(0x3b070000), SPH_C32(0xba010000), + SPH_C32(0x99d00008), SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), + SPH_C32(0x96f896b3), SPH_C32(0x2879ebac), SPH_C32(0x01930000), + SPH_C32(0xe7820000), SPH_C32(0xedfb0000), SPH_C32(0xcf0c000b), + SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), SPH_C32(0x063661e1), + SPH_C32(0x536f9e7b) }, + { SPH_C32(0x90860000), SPH_C32(0x33b40000), SPH_C32(0x493b0000), + SPH_C32(0xa312000f), SPH_C32(0x6610241e), SPH_C32(0x8d22713d), + SPH_C32(0x985d5950), SPH_C32(0xcea39452), SPH_C32(0xa9490000), + SPH_C32(0x713c0000), SPH_C32(0xb1e60000), SPH_C32(0xc8d60009), + SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), SPH_C32(0xbd50e9e9), + SPH_C32(0x89e81e7b) }, + { SPH_C32(0x3b610000), SPH_C32(0xadb90000), SPH_C32(0xe61c0000), + SPH_C32(0x9e0a000a), SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), + SPH_C32(0x2d9e1ebb), SPH_C32(0xf2fe6bac), SPH_C32(0xaa740000), + SPH_C32(0x798f0000), SPH_C32(0x42dc0000), SPH_C32(0xf214000e), + SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), SPH_C32(0xb3f5260a), + SPH_C32(0x6f326185) }, + { SPH_C32(0x385c0000), SPH_C32(0xa50a0000), SPH_C32(0x15260000), + SPH_C32(0xa4c8000d), SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), + SPH_C32(0x233bd158), SPH_C32(0x14241452), SPH_C32(0x02ae0000), + SPH_C32(0xef310000), SPH_C32(0x1ec10000), SPH_C32(0xf5ce000c), + SPH_C32(0xdcf90708), SPH_C32(0xd7cdd231), SPH_C32(0x0893ae02), + SPH_C32(0xb5b5e185) } +}; + +#define INPUT_BIG do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T512_0[acc >> 2][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + m8 = rp[8]; \ + m9 = rp[9]; \ + mA = rp[10]; \ + mB = rp[11]; \ + mC = rp[12]; \ + mD = rp[13]; \ + mE = rp[14]; \ + mF = rp[15]; \ + acc = (acc << 8) | buf[1]; \ + rp = &T512_6[(acc >> 4) & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[2]; \ + rp = &T512_12[(acc >> 6) & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_18[acc & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[3]; \ + rp = &T512_24[acc >> 2][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[4]; \ + rp = &T512_30[(acc >> 4) & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[5]; \ + rp = &T512_36[(acc >> 6) & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_42[acc & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[6]; \ + rp = &T512_48[acc >> 2][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[7]; \ + rp = &T512_54[(acc >> 4) & 0x3f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_60[acc & 0x0f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_BIG == 7 + +static const sph_u32 T512_0[128][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xc96b0030), SPH_C32(0xe7250000), SPH_C32(0x2f840000), + SPH_C32(0x264f0000), SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), + SPH_C32(0x509f6984), SPH_C32(0x9e69af68), SPH_C32(0x26600240), + SPH_C32(0xddd80000), SPH_C32(0x722a0000), SPH_C32(0x4f060000), + SPH_C32(0x936667ff), SPH_C32(0x29f944ce), SPH_C32(0x368b63d5), + SPH_C32(0x0c26f262) }, + { SPH_C32(0x145a3c00), SPH_C32(0xb9e90000), SPH_C32(0x61270000), + SPH_C32(0xf1610000), SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), + SPH_C32(0x47a96720), SPH_C32(0xe18e24c5), SPH_C32(0x23671400), + SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), SPH_C32(0xfb750000), + SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), SPH_C32(0x02c40a3f), + SPH_C32(0xdc24e61f) }, + { SPH_C32(0xdd313c30), SPH_C32(0x5ecc0000), SPH_C32(0x4ea30000), + SPH_C32(0xd72e0000), SPH_C32(0xc6086695), SPH_C32(0xddb5cc4f), + SPH_C32(0x17360ea4), SPH_C32(0x7fe78bad), SPH_C32(0x05071640), + SPH_C32(0x15610000), SPH_C32(0x86ed0000), SPH_C32(0xb4730000), + SPH_C32(0xe0ab439a), SPH_C32(0xd15fe187), SPH_C32(0x344f69ea), + SPH_C32(0xd002147d) }, + { SPH_C32(0x23671400), SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), + SPH_C32(0xfb750000), SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), + SPH_C32(0x02c40a3f), SPH_C32(0xdc24e61f), SPH_C32(0x373d2800), + SPH_C32(0x71500000), SPH_C32(0x95e00000), SPH_C32(0x0a140000), + SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), SPH_C32(0x456d6d1f), + SPH_C32(0x3daac2da) }, + { SPH_C32(0xea0c1430), SPH_C32(0x2f9c0000), SPH_C32(0xdb430000), + SPH_C32(0xdd3a0000), SPH_C32(0x7ba47f9c), SPH_C32(0x955a547e), + SPH_C32(0x525b63bb), SPH_C32(0x424d4977), SPH_C32(0x115d2a40), + SPH_C32(0xac880000), SPH_C32(0xe7ca0000), SPH_C32(0x45120000), + SPH_C32(0x2eca7ef6), SPH_C32(0x6116dcff), SPH_C32(0x73e60eca), + SPH_C32(0x318c30b8) }, + { SPH_C32(0x373d2800), SPH_C32(0x71500000), SPH_C32(0x95e00000), + SPH_C32(0x0a140000), SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), + SPH_C32(0x456d6d1f), SPH_C32(0x3daac2da), SPH_C32(0x145a3c00), + SPH_C32(0xb9e90000), SPH_C32(0x61270000), SPH_C32(0xf1610000), + SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), SPH_C32(0x47a96720), + SPH_C32(0xe18e24c5) }, + { SPH_C32(0xfe562830), SPH_C32(0x96750000), SPH_C32(0xba640000), + SPH_C32(0x2c5b0000), SPH_C32(0xb5c542f0), SPH_C32(0x25136906), + SPH_C32(0x15f2049b), SPH_C32(0xa3c36db2), SPH_C32(0x323a3e40), + SPH_C32(0x64310000), SPH_C32(0x130d0000), SPH_C32(0xbe670000), + SPH_C32(0x5d075a93), SPH_C32(0x99b079b6), SPH_C32(0x712204f5), + SPH_C32(0xeda8d6a7) }, + { SPH_C32(0x54285c00), SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), + SPH_C32(0xa1c50000), SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), + SPH_C32(0x6bb0419d), SPH_C32(0x551b3782), SPH_C32(0x9cbb1800), + SPH_C32(0xb0d30000), SPH_C32(0x92510000), SPH_C32(0xed930000), + SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), SPH_C32(0x430633da), + SPH_C32(0x78cace29) }, + { SPH_C32(0x9d435c30), SPH_C32(0x0dc80000), SPH_C32(0xea520000), + SPH_C32(0x878a0000), SPH_C32(0xbbcb3c89), SPH_C32(0xf95935d6), + SPH_C32(0x3b2f2819), SPH_C32(0xcb7298ea), SPH_C32(0xbadb1a40), + SPH_C32(0x6d0b0000), SPH_C32(0xe07b0000), SPH_C32(0xa2950000), + SPH_C32(0xca5c24ba), SPH_C32(0xc8ed913a), SPH_C32(0x758d500f), + SPH_C32(0x74ec3c4b) }, + { SPH_C32(0x40726000), SPH_C32(0x53040000), SPH_C32(0xa4f10000), + SPH_C32(0x50a40000), SPH_C32(0x7dc35a1c), SPH_C32(0x24ecf999), + SPH_C32(0x2c1926bd), SPH_C32(0xb4951347), SPH_C32(0xbfdc0c00), + SPH_C32(0x786a0000), SPH_C32(0x66960000), SPH_C32(0x16e60000), + SPH_C32(0x2af76720), SPH_C32(0x19b270bd), SPH_C32(0x41c239e5), + SPH_C32(0xa4ee2836) }, + { SPH_C32(0x89196030), SPH_C32(0xb4210000), SPH_C32(0x8b750000), + SPH_C32(0x76eb0000), SPH_C32(0x75aa01e5), SPH_C32(0x491008ae), + SPH_C32(0x7c864f39), SPH_C32(0x2afcbc2f), SPH_C32(0x99bc0e40), + SPH_C32(0xa5b20000), SPH_C32(0x14bc0000), SPH_C32(0x59e00000), + SPH_C32(0xb99100df), SPH_C32(0x304b3473), SPH_C32(0x77495a30), + SPH_C32(0xa8c8da54) }, + { SPH_C32(0x774f4800), SPH_C32(0x22540000), SPH_C32(0x31110000), + SPH_C32(0x5ab00000), SPH_C32(0xc06f4315), SPH_C32(0x6c0361a8), + SPH_C32(0x69744ba2), SPH_C32(0x893fd19d), SPH_C32(0xab863000), + SPH_C32(0xc1830000), SPH_C32(0x07b10000), SPH_C32(0xe7870000), + SPH_C32(0xe4965a4c), SPH_C32(0xa9fb4dc5), SPH_C32(0x066b5ec5), + SPH_C32(0x45600cf3) }, + { SPH_C32(0xbe244830), SPH_C32(0xc5710000), SPH_C32(0x1e950000), + SPH_C32(0x7cff0000), SPH_C32(0xc80618ec), SPH_C32(0x01ff909f), + SPH_C32(0x39eb2226), SPH_C32(0x17567ef5), SPH_C32(0x8de63240), + SPH_C32(0x1c5b0000), SPH_C32(0x759b0000), SPH_C32(0xa8810000), + SPH_C32(0x77f03db3), SPH_C32(0x8002090b), SPH_C32(0x30e03d10), + SPH_C32(0x4946fe91) }, + { SPH_C32(0x63157400), SPH_C32(0x9bbd0000), SPH_C32(0x50360000), + SPH_C32(0xabd10000), SPH_C32(0x0e0e7e79), SPH_C32(0xdc4a5cd0), + SPH_C32(0x2edd2c82), SPH_C32(0x68b1f558), SPH_C32(0x88e12400), + SPH_C32(0x093a0000), SPH_C32(0xf3760000), SPH_C32(0x1cf20000), + SPH_C32(0x975b7e29), SPH_C32(0x515de88c), SPH_C32(0x04af54fa), + SPH_C32(0x9944eaec) }, + { SPH_C32(0xaa7e7430), SPH_C32(0x7c980000), SPH_C32(0x7fb20000), + SPH_C32(0x8d9e0000), SPH_C32(0x06672580), SPH_C32(0xb1b6ade7), + SPH_C32(0x7e424506), SPH_C32(0xf6d85a30), SPH_C32(0xae812640), + SPH_C32(0xd4e20000), SPH_C32(0x815c0000), SPH_C32(0x53f40000), + SPH_C32(0x043d19d6), SPH_C32(0x78a4ac42), SPH_C32(0x3224372f), + SPH_C32(0x9562188e) }, + { SPH_C32(0x9cbb1800), SPH_C32(0xb0d30000), SPH_C32(0x92510000), + SPH_C32(0xed930000), SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), + SPH_C32(0x430633da), SPH_C32(0x78cace29), SPH_C32(0xc8934400), + SPH_C32(0x5a3e0000), SPH_C32(0x57870000), SPH_C32(0x4c560000), + SPH_C32(0xea982435), SPH_C32(0x75b11115), SPH_C32(0x28b67247), + SPH_C32(0x2dd1f9ab) }, + { SPH_C32(0x55d01830), SPH_C32(0x57f60000), SPH_C32(0xbdd50000), + SPH_C32(0xcbdc0000), SPH_C32(0x515318bc), SPH_C32(0x8ce824c3), + SPH_C32(0x13995a5e), SPH_C32(0xe6a36141), SPH_C32(0xeef34640), + SPH_C32(0x87e60000), SPH_C32(0x25ad0000), SPH_C32(0x03500000), + SPH_C32(0x79fe43ca), SPH_C32(0x5c4855db), SPH_C32(0x1e3d1192), + SPH_C32(0x21f70bc9) }, + { SPH_C32(0x88e12400), SPH_C32(0x093a0000), SPH_C32(0xf3760000), + SPH_C32(0x1cf20000), SPH_C32(0x975b7e29), SPH_C32(0x515de88c), + SPH_C32(0x04af54fa), SPH_C32(0x9944eaec), SPH_C32(0xebf45000), + SPH_C32(0x92870000), SPH_C32(0xa3400000), SPH_C32(0xb7230000), + SPH_C32(0x99550050), SPH_C32(0x8d17b45c), SPH_C32(0x2a727878), + SPH_C32(0xf1f51fb4) }, + { SPH_C32(0x418a2430), SPH_C32(0xee1f0000), SPH_C32(0xdcf20000), + SPH_C32(0x3abd0000), SPH_C32(0x9f3225d0), SPH_C32(0x3ca119bb), + SPH_C32(0x54303d7e), SPH_C32(0x072d4584), SPH_C32(0xcd945240), + SPH_C32(0x4f5f0000), SPH_C32(0xd16a0000), SPH_C32(0xf8250000), + SPH_C32(0x0a3367af), SPH_C32(0xa4eef092), SPH_C32(0x1cf91bad), + SPH_C32(0xfdd3edd6) }, + { SPH_C32(0xbfdc0c00), SPH_C32(0x786a0000), SPH_C32(0x66960000), + SPH_C32(0x16e60000), SPH_C32(0x2af76720), SPH_C32(0x19b270bd), + SPH_C32(0x41c239e5), SPH_C32(0xa4ee2836), SPH_C32(0xffae6c00), + SPH_C32(0x2b6e0000), SPH_C32(0xc2670000), SPH_C32(0x46420000), + SPH_C32(0x57343d3c), SPH_C32(0x3d5e8924), SPH_C32(0x6ddb1f58), + SPH_C32(0x107b3b71) }, + { SPH_C32(0x76b70c30), SPH_C32(0x9f4f0000), SPH_C32(0x49120000), + SPH_C32(0x30a90000), SPH_C32(0x229e3cd9), SPH_C32(0x744e818a), + SPH_C32(0x115d5061), SPH_C32(0x3a87875e), SPH_C32(0xd9ce6e40), + SPH_C32(0xf6b60000), SPH_C32(0xb04d0000), SPH_C32(0x09440000), + SPH_C32(0xc4525ac3), SPH_C32(0x14a7cdea), SPH_C32(0x5b507c8d), + SPH_C32(0x1c5dc913) }, + { SPH_C32(0xab863000), SPH_C32(0xc1830000), SPH_C32(0x07b10000), + SPH_C32(0xe7870000), SPH_C32(0xe4965a4c), SPH_C32(0xa9fb4dc5), + SPH_C32(0x066b5ec5), SPH_C32(0x45600cf3), SPH_C32(0xdcc97800), + SPH_C32(0xe3d70000), SPH_C32(0x36a00000), SPH_C32(0xbd370000), + SPH_C32(0x24f91959), SPH_C32(0xc5f82c6d), SPH_C32(0x6f1f1567), + SPH_C32(0xcc5fdd6e) }, + { SPH_C32(0x62ed3030), SPH_C32(0x26a60000), SPH_C32(0x28350000), + SPH_C32(0xc1c80000), SPH_C32(0xecff01b5), SPH_C32(0xc407bcf2), + SPH_C32(0x56f43741), SPH_C32(0xdb09a39b), SPH_C32(0xfaa97a40), + SPH_C32(0x3e0f0000), SPH_C32(0x448a0000), SPH_C32(0xf2310000), + SPH_C32(0xb79f7ea6), SPH_C32(0xec0168a3), SPH_C32(0x599476b2), + SPH_C32(0xc0792f0c) }, + { SPH_C32(0xc8934400), SPH_C32(0x5a3e0000), SPH_C32(0x57870000), + SPH_C32(0x4c560000), SPH_C32(0xea982435), SPH_C32(0x75b11115), + SPH_C32(0x28b67247), SPH_C32(0x2dd1f9ab), SPH_C32(0x54285c00), + SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), SPH_C32(0xa1c50000), + SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), SPH_C32(0x6bb0419d), + SPH_C32(0x551b3782) }, + { SPH_C32(0x01f84430), SPH_C32(0xbd1b0000), SPH_C32(0x78030000), + SPH_C32(0x6a190000), SPH_C32(0xe2f17fcc), SPH_C32(0x184de022), + SPH_C32(0x78291bc3), SPH_C32(0xb3b856c3), SPH_C32(0x72485e40), + SPH_C32(0x37350000), SPH_C32(0xb7fc0000), SPH_C32(0xeec30000), + SPH_C32(0x20c4008f), SPH_C32(0xbd5c802f), SPH_C32(0x5d3b2248), + SPH_C32(0x593dc5e0) }, + { SPH_C32(0xdcc97800), SPH_C32(0xe3d70000), SPH_C32(0x36a00000), + SPH_C32(0xbd370000), SPH_C32(0x24f91959), SPH_C32(0xc5f82c6d), + SPH_C32(0x6f1f1567), SPH_C32(0xcc5fdd6e), SPH_C32(0x774f4800), + SPH_C32(0x22540000), SPH_C32(0x31110000), SPH_C32(0x5ab00000), + SPH_C32(0xc06f4315), SPH_C32(0x6c0361a8), SPH_C32(0x69744ba2), + SPH_C32(0x893fd19d) }, + { SPH_C32(0x15a27830), SPH_C32(0x04f20000), SPH_C32(0x19240000), + SPH_C32(0x9b780000), SPH_C32(0x2c9042a0), SPH_C32(0xa804dd5a), + SPH_C32(0x3f807ce3), SPH_C32(0x52367206), SPH_C32(0x512f4a40), + SPH_C32(0xff8c0000), SPH_C32(0x433b0000), SPH_C32(0x15b60000), + SPH_C32(0x530924ea), SPH_C32(0x45fa2566), SPH_C32(0x5fff2877), + SPH_C32(0x851923ff) }, + { SPH_C32(0xebf45000), SPH_C32(0x92870000), SPH_C32(0xa3400000), + SPH_C32(0xb7230000), SPH_C32(0x99550050), SPH_C32(0x8d17b45c), + SPH_C32(0x2a727878), SPH_C32(0xf1f51fb4), SPH_C32(0x63157400), + SPH_C32(0x9bbd0000), SPH_C32(0x50360000), SPH_C32(0xabd10000), + SPH_C32(0x0e0e7e79), SPH_C32(0xdc4a5cd0), SPH_C32(0x2edd2c82), + SPH_C32(0x68b1f558) }, + { SPH_C32(0x229f5030), SPH_C32(0x75a20000), SPH_C32(0x8cc40000), + SPH_C32(0x916c0000), SPH_C32(0x913c5ba9), SPH_C32(0xe0eb456b), + SPH_C32(0x7aed11fc), SPH_C32(0x6f9cb0dc), SPH_C32(0x45757640), + SPH_C32(0x46650000), SPH_C32(0x221c0000), SPH_C32(0xe4d70000), + SPH_C32(0x9d681986), SPH_C32(0xf5b3181e), SPH_C32(0x18564f57), + SPH_C32(0x6497073a) }, + { SPH_C32(0xffae6c00), SPH_C32(0x2b6e0000), SPH_C32(0xc2670000), + SPH_C32(0x46420000), SPH_C32(0x57343d3c), SPH_C32(0x3d5e8924), + SPH_C32(0x6ddb1f58), SPH_C32(0x107b3b71), SPH_C32(0x40726000), + SPH_C32(0x53040000), SPH_C32(0xa4f10000), SPH_C32(0x50a40000), + SPH_C32(0x7dc35a1c), SPH_C32(0x24ecf999), SPH_C32(0x2c1926bd), + SPH_C32(0xb4951347) }, + { SPH_C32(0x36c56c30), SPH_C32(0xcc4b0000), SPH_C32(0xede30000), + SPH_C32(0x600d0000), SPH_C32(0x5f5d66c5), SPH_C32(0x50a27813), + SPH_C32(0x3d4476dc), SPH_C32(0x8e129419), SPH_C32(0x66126240), + SPH_C32(0x8edc0000), SPH_C32(0xd6db0000), SPH_C32(0x1fa20000), + SPH_C32(0xeea53de3), SPH_C32(0x0d15bd57), SPH_C32(0x1a924568), + SPH_C32(0xb8b3e125) }, + { SPH_C32(0x29449c00), SPH_C32(0x64e70000), SPH_C32(0xf24b0000), + SPH_C32(0xc2f30000), SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), + SPH_C32(0xf3e04259), SPH_C32(0x8d0d9ec4), SPH_C32(0x466d0c00), + SPH_C32(0x08620000), SPH_C32(0xdd5d0000), SPH_C32(0xbadd0000), + SPH_C32(0x6a927942), SPH_C32(0x441f2b93), SPH_C32(0x218ace6f), + SPH_C32(0xbf2c0be2) }, + { SPH_C32(0xe02f9c30), SPH_C32(0x83c20000), SPH_C32(0xddcf0000), + SPH_C32(0xe4bc0000), SPH_C32(0x06b71576), SPH_C32(0x3b3ec672), + SPH_C32(0xa37f2bdd), SPH_C32(0x136431ac), SPH_C32(0x600d0e40), + SPH_C32(0xd5ba0000), SPH_C32(0xaf770000), SPH_C32(0xf5db0000), + SPH_C32(0xf9f41ebd), SPH_C32(0x6de66f5d), SPH_C32(0x1701adba), + SPH_C32(0xb30af980) }, + { SPH_C32(0x3d1ea000), SPH_C32(0xdd0e0000), SPH_C32(0x936c0000), + SPH_C32(0x33920000), SPH_C32(0xc0bf73e3), SPH_C32(0xe68b0a3d), + SPH_C32(0xb4492579), SPH_C32(0x6c83ba01), SPH_C32(0x650a1800), + SPH_C32(0xc0db0000), SPH_C32(0x299a0000), SPH_C32(0x41a80000), + SPH_C32(0x195f5d27), SPH_C32(0xbcb98eda), SPH_C32(0x234ec450), + SPH_C32(0x6308edfd) }, + { SPH_C32(0xf475a030), SPH_C32(0x3a2b0000), SPH_C32(0xbce80000), + SPH_C32(0x15dd0000), SPH_C32(0xc8d6281a), SPH_C32(0x8b77fb0a), + SPH_C32(0xe4d64cfd), SPH_C32(0xf2ea1569), SPH_C32(0x436a1a40), + SPH_C32(0x1d030000), SPH_C32(0x5bb00000), SPH_C32(0x0eae0000), + SPH_C32(0x8a393ad8), SPH_C32(0x9540ca14), SPH_C32(0x15c5a785), + SPH_C32(0x6f2e1f9f) }, + { SPH_C32(0x0a238800), SPH_C32(0xac5e0000), SPH_C32(0x068c0000), + SPH_C32(0x39860000), SPH_C32(0x7d136aea), SPH_C32(0xae64920c), + SPH_C32(0xf1244866), SPH_C32(0x512978db), SPH_C32(0x71502400), + SPH_C32(0x79320000), SPH_C32(0x48bd0000), SPH_C32(0xb0c90000), + SPH_C32(0xd73e604b), SPH_C32(0x0cf0b3a2), SPH_C32(0x64e7a370), + SPH_C32(0x8286c938) }, + { SPH_C32(0xc3488830), SPH_C32(0x4b7b0000), SPH_C32(0x29080000), + SPH_C32(0x1fc90000), SPH_C32(0x757a3113), SPH_C32(0xc398633b), + SPH_C32(0xa1bb21e2), SPH_C32(0xcf40d7b3), SPH_C32(0x57302640), + SPH_C32(0xa4ea0000), SPH_C32(0x3a970000), SPH_C32(0xffcf0000), + SPH_C32(0x445807b4), SPH_C32(0x2509f76c), SPH_C32(0x526cc0a5), + SPH_C32(0x8ea03b5a) }, + { SPH_C32(0x1e79b400), SPH_C32(0x15b70000), SPH_C32(0x67ab0000), + SPH_C32(0xc8e70000), SPH_C32(0xb3725786), SPH_C32(0x1e2daf74), + SPH_C32(0xb68d2f46), SPH_C32(0xb0a75c1e), SPH_C32(0x52373000), + SPH_C32(0xb18b0000), SPH_C32(0xbc7a0000), SPH_C32(0x4bbc0000), + SPH_C32(0xa4f3442e), SPH_C32(0xf45616eb), SPH_C32(0x6623a94f), + SPH_C32(0x5ea22f27) }, + { SPH_C32(0xd712b430), SPH_C32(0xf2920000), SPH_C32(0x482f0000), + SPH_C32(0xeea80000), SPH_C32(0xbb1b0c7f), SPH_C32(0x73d15e43), + SPH_C32(0xe61246c2), SPH_C32(0x2ecef376), SPH_C32(0x74573240), + SPH_C32(0x6c530000), SPH_C32(0xce500000), SPH_C32(0x04ba0000), + SPH_C32(0x379523d1), SPH_C32(0xddaf5225), SPH_C32(0x50a8ca9a), + SPH_C32(0x5284dd45) }, + { SPH_C32(0x7d6cc000), SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), + SPH_C32(0x63360000), SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), + SPH_C32(0x985003c4), SPH_C32(0xd816a946), SPH_C32(0xdad61400), + SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), SPH_C32(0x574e0000), + SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), SPH_C32(0x628cfdb5), + SPH_C32(0xc7e6c5cb) }, + { SPH_C32(0xb407c030), SPH_C32(0x692f0000), SPH_C32(0x18190000), + SPH_C32(0x45790000), SPH_C32(0xb5157206), SPH_C32(0xaf9b0293), + SPH_C32(0xc8cf6a40), SPH_C32(0x467f062e), SPH_C32(0xfcb61640), + SPH_C32(0x65690000), SPH_C32(0x3d260000), SPH_C32(0x18480000), + SPH_C32(0xa0ce5df8), SPH_C32(0x8cf2baa9), SPH_C32(0x54079e60), + SPH_C32(0xcbc037a9) }, + { SPH_C32(0x6936fc00), SPH_C32(0x37e30000), SPH_C32(0x56ba0000), + SPH_C32(0x92570000), SPH_C32(0x731d1493), SPH_C32(0x722ecedc), + SPH_C32(0xdff964e4), SPH_C32(0x39988d83), SPH_C32(0xf9b10000), + SPH_C32(0x70080000), SPH_C32(0xbbcb0000), SPH_C32(0xac3b0000), + SPH_C32(0x40651e62), SPH_C32(0x5dad5b2e), SPH_C32(0x6048f78a), + SPH_C32(0x1bc223d4) }, + { SPH_C32(0xa05dfc30), SPH_C32(0xd0c60000), SPH_C32(0x793e0000), + SPH_C32(0xb4180000), SPH_C32(0x7b744f6a), SPH_C32(0x1fd23feb), + SPH_C32(0x8f660d60), SPH_C32(0xa7f122eb), SPH_C32(0xdfd10240), + SPH_C32(0xadd00000), SPH_C32(0xc9e10000), SPH_C32(0xe33d0000), + SPH_C32(0xd303799d), SPH_C32(0x74541fe0), SPH_C32(0x56c3945f), + SPH_C32(0x17e4d1b6) }, + { SPH_C32(0x5e0bd400), SPH_C32(0x46b30000), SPH_C32(0xc35a0000), + SPH_C32(0x98430000), SPH_C32(0xceb10d9a), SPH_C32(0x3ac156ed), + SPH_C32(0x9a9409fb), SPH_C32(0x04324f59), SPH_C32(0xedeb3c00), + SPH_C32(0xc9e10000), SPH_C32(0xdaec0000), SPH_C32(0x5d5a0000), + SPH_C32(0x8e04230e), SPH_C32(0xede46656), SPH_C32(0x27e190aa), + SPH_C32(0xfa4c0711) }, + { SPH_C32(0x9760d430), SPH_C32(0xa1960000), SPH_C32(0xecde0000), + SPH_C32(0xbe0c0000), SPH_C32(0xc6d85663), SPH_C32(0x573da7da), + SPH_C32(0xca0b607f), SPH_C32(0x9a5be031), SPH_C32(0xcb8b3e40), + SPH_C32(0x14390000), SPH_C32(0xa8c60000), SPH_C32(0x125c0000), + SPH_C32(0x1d6244f1), SPH_C32(0xc41d2298), SPH_C32(0x116af37f), + SPH_C32(0xf66af573) }, + { SPH_C32(0x4a51e800), SPH_C32(0xff5a0000), SPH_C32(0xa27d0000), + SPH_C32(0x69220000), SPH_C32(0x00d030f6), SPH_C32(0x8a886b95), + SPH_C32(0xdd3d6edb), SPH_C32(0xe5bc6b9c), SPH_C32(0xce8c2800), + SPH_C32(0x01580000), SPH_C32(0x2e2b0000), SPH_C32(0xa62f0000), + SPH_C32(0xfdc9076b), SPH_C32(0x1542c31f), SPH_C32(0x25259a95), + SPH_C32(0x2668e10e) }, + { SPH_C32(0x833ae830), SPH_C32(0x187f0000), SPH_C32(0x8df90000), + SPH_C32(0x4f6d0000), SPH_C32(0x08b96b0f), SPH_C32(0xe7749aa2), + SPH_C32(0x8da2075f), SPH_C32(0x7bd5c4f4), SPH_C32(0xe8ec2a40), + SPH_C32(0xdc800000), SPH_C32(0x5c010000), SPH_C32(0xe9290000), + SPH_C32(0x6eaf6094), SPH_C32(0x3cbb87d1), SPH_C32(0x13aef940), + SPH_C32(0x2a4e136c) }, + { SPH_C32(0xb5ff8400), SPH_C32(0xd4340000), SPH_C32(0x601a0000), + SPH_C32(0x2f600000), SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), + SPH_C32(0xb0e67183), SPH_C32(0xf5c750ed), SPH_C32(0x8efe4800), + SPH_C32(0x525c0000), SPH_C32(0x8ada0000), SPH_C32(0xf68b0000), + SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), SPH_C32(0x093cbc28), + SPH_C32(0x92fdf249) }, + { SPH_C32(0x7c948430), SPH_C32(0x33110000), SPH_C32(0x4f9e0000), + SPH_C32(0x092f0000), SPH_C32(0x5f8d5633), SPH_C32(0xda2a1386), + SPH_C32(0xe0791807), SPH_C32(0x6baeff85), SPH_C32(0xa89e4a40), + SPH_C32(0x8f840000), SPH_C32(0xf8f00000), SPH_C32(0xb98d0000), + SPH_C32(0x136c3a88), SPH_C32(0x18577e48), SPH_C32(0x3fb7dffd), + SPH_C32(0x9edb002b) }, + { SPH_C32(0xa1a5b800), SPH_C32(0x6ddd0000), SPH_C32(0x013d0000), + SPH_C32(0xde010000), SPH_C32(0x998530a6), SPH_C32(0x079fdfc9), + SPH_C32(0xf74f16a3), SPH_C32(0x14497428), SPH_C32(0xad995c00), + SPH_C32(0x9ae50000), SPH_C32(0x7e1d0000), SPH_C32(0x0dfe0000), + SPH_C32(0xf3c77912), SPH_C32(0xc9089fcf), SPH_C32(0x0bf8b617), + SPH_C32(0x4ed91456) }, + { SPH_C32(0x68ceb830), SPH_C32(0x8af80000), SPH_C32(0x2eb90000), + SPH_C32(0xf84e0000), SPH_C32(0x91ec6b5f), SPH_C32(0x6a632efe), + SPH_C32(0xa7d07f27), SPH_C32(0x8a20db40), SPH_C32(0x8bf95e40), + SPH_C32(0x473d0000), SPH_C32(0x0c370000), SPH_C32(0x42f80000), + SPH_C32(0x60a11eed), SPH_C32(0xe0f1db01), SPH_C32(0x3d73d5c2), + SPH_C32(0x42ffe634) }, + { SPH_C32(0x96989000), SPH_C32(0x1c8d0000), SPH_C32(0x94dd0000), + SPH_C32(0xd4150000), SPH_C32(0x242929af), SPH_C32(0x4f7047f8), + SPH_C32(0xb2227bbc), SPH_C32(0x29e3b6f2), SPH_C32(0xb9c36000), + SPH_C32(0x230c0000), SPH_C32(0x1f3a0000), SPH_C32(0xfc9f0000), + SPH_C32(0x3da6447e), SPH_C32(0x7941a2b7), SPH_C32(0x4c51d137), + SPH_C32(0xaf573093) }, + { SPH_C32(0x5ff39030), SPH_C32(0xfba80000), SPH_C32(0xbb590000), + SPH_C32(0xf25a0000), SPH_C32(0x2c407256), SPH_C32(0x228cb6cf), + SPH_C32(0xe2bd1238), SPH_C32(0xb78a199a), SPH_C32(0x9fa36240), + SPH_C32(0xfed40000), SPH_C32(0x6d100000), SPH_C32(0xb3990000), + SPH_C32(0xaec02381), SPH_C32(0x50b8e679), SPH_C32(0x7adab2e2), + SPH_C32(0xa371c2f1) }, + { SPH_C32(0x82c2ac00), SPH_C32(0xa5640000), SPH_C32(0xf5fa0000), + SPH_C32(0x25740000), SPH_C32(0xea4814c3), SPH_C32(0xff397a80), + SPH_C32(0xf58b1c9c), SPH_C32(0xc86d9237), SPH_C32(0x9aa47400), + SPH_C32(0xebb50000), SPH_C32(0xebfd0000), SPH_C32(0x07ea0000), + SPH_C32(0x4e6b601b), SPH_C32(0x81e707fe), SPH_C32(0x4e95db08), + SPH_C32(0x7373d68c) }, + { SPH_C32(0x4ba9ac30), SPH_C32(0x42410000), SPH_C32(0xda7e0000), + SPH_C32(0x033b0000), SPH_C32(0xe2214f3a), SPH_C32(0x92c58bb7), + SPH_C32(0xa5147518), SPH_C32(0x56043d5f), SPH_C32(0xbcc47640), + SPH_C32(0x366d0000), SPH_C32(0x99d70000), SPH_C32(0x48ec0000), + SPH_C32(0xdd0d07e4), SPH_C32(0xa81e4330), SPH_C32(0x781eb8dd), + SPH_C32(0x7f5524ee) }, + { SPH_C32(0xe1d7d800), SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), + SPH_C32(0x8ea50000), SPH_C32(0xe4466aba), SPH_C32(0x23732650), + SPH_C32(0xdb56301e), SPH_C32(0xa0dc676f), SPH_C32(0x12455000), + SPH_C32(0xe28f0000), SPH_C32(0x188b0000), SPH_C32(0x1b180000), + SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), SPH_C32(0x4a3a8ff2), + SPH_C32(0xea373c60) }, + { SPH_C32(0x28bcd830), SPH_C32(0xd9fc0000), SPH_C32(0x8a480000), + SPH_C32(0xa8ea0000), SPH_C32(0xec2f3143), SPH_C32(0x4e8fd767), + SPH_C32(0x8bc9599a), SPH_C32(0x3eb5c807), SPH_C32(0x34255240), + SPH_C32(0x3f570000), SPH_C32(0x6aa10000), SPH_C32(0x541e0000), + SPH_C32(0x4a5679cd), SPH_C32(0xf943abbc), SPH_C32(0x7cb1ec27), + SPH_C32(0xe611ce02) }, + { SPH_C32(0xf58de400), SPH_C32(0x87300000), SPH_C32(0xc4eb0000), + SPH_C32(0x7fc40000), SPH_C32(0x2a2757d6), SPH_C32(0x933a1b28), + SPH_C32(0x9cff573e), SPH_C32(0x415243aa), SPH_C32(0x31224400), + SPH_C32(0x2a360000), SPH_C32(0xec4c0000), SPH_C32(0xe06d0000), + SPH_C32(0xaafd3a57), SPH_C32(0x281c4a3b), SPH_C32(0x48fe85cd), + SPH_C32(0x3613da7f) }, + { SPH_C32(0x3ce6e430), SPH_C32(0x60150000), SPH_C32(0xeb6f0000), + SPH_C32(0x598b0000), SPH_C32(0x224e0c2f), SPH_C32(0xfec6ea1f), + SPH_C32(0xcc603eba), SPH_C32(0xdf3becc2), SPH_C32(0x17424640), + SPH_C32(0xf7ee0000), SPH_C32(0x9e660000), SPH_C32(0xaf6b0000), + SPH_C32(0x399b5da8), SPH_C32(0x01e50ef5), SPH_C32(0x7e75e618), + SPH_C32(0x3a35281d) }, + { SPH_C32(0xc2b0cc00), SPH_C32(0xf6600000), SPH_C32(0x510b0000), + SPH_C32(0x75d00000), SPH_C32(0x978b4edf), SPH_C32(0xdbd58319), + SPH_C32(0xd9923a21), SPH_C32(0x7cf88170), SPH_C32(0x25787800), + SPH_C32(0x93df0000), SPH_C32(0x8d6b0000), SPH_C32(0x110c0000), + SPH_C32(0x649c073b), SPH_C32(0x98557743), SPH_C32(0x0f57e2ed), + SPH_C32(0xd79dfeba) }, + { SPH_C32(0x0bdbcc30), SPH_C32(0x11450000), SPH_C32(0x7e8f0000), + SPH_C32(0x539f0000), SPH_C32(0x9fe21526), SPH_C32(0xb629722e), + SPH_C32(0x890d53a5), SPH_C32(0xe2912e18), SPH_C32(0x03187a40), + SPH_C32(0x4e070000), SPH_C32(0xff410000), SPH_C32(0x5e0a0000), + SPH_C32(0xf7fa60c4), SPH_C32(0xb1ac338d), SPH_C32(0x39dc8138), + SPH_C32(0xdbbb0cd8) }, + { SPH_C32(0xd6eaf000), SPH_C32(0x4f890000), SPH_C32(0x302c0000), + SPH_C32(0x84b10000), SPH_C32(0x59ea73b3), SPH_C32(0x6b9cbe61), + SPH_C32(0x9e3b5d01), SPH_C32(0x9d76a5b5), SPH_C32(0x061f6c00), + SPH_C32(0x5b660000), SPH_C32(0x79ac0000), SPH_C32(0xea790000), + SPH_C32(0x1751235e), SPH_C32(0x60f3d20a), SPH_C32(0x0d93e8d2), + SPH_C32(0x0bb918a5) }, + { SPH_C32(0x1f81f030), SPH_C32(0xa8ac0000), SPH_C32(0x1fa80000), + SPH_C32(0xa2fe0000), SPH_C32(0x5183284a), SPH_C32(0x06604f56), + SPH_C32(0xcea43485), SPH_C32(0x031f0add), SPH_C32(0x207f6e40), + SPH_C32(0x86be0000), SPH_C32(0x0b860000), SPH_C32(0xa57f0000), + SPH_C32(0x843744a1), SPH_C32(0x490a96c4), SPH_C32(0x3b188b07), + SPH_C32(0x079feac7) }, + { SPH_C32(0x466d0c00), SPH_C32(0x08620000), SPH_C32(0xdd5d0000), + SPH_C32(0xbadd0000), SPH_C32(0x6a927942), SPH_C32(0x441f2b93), + SPH_C32(0x218ace6f), SPH_C32(0xbf2c0be2), SPH_C32(0x6f299000), + SPH_C32(0x6c850000), SPH_C32(0x2f160000), SPH_C32(0x782e0000), + SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), SPH_C32(0xd26a8c36), + SPH_C32(0x32219526) }, + { SPH_C32(0x8f060c30), SPH_C32(0xef470000), SPH_C32(0xf2d90000), + SPH_C32(0x9c920000), SPH_C32(0x62fb22bb), SPH_C32(0x29e3daa4), + SPH_C32(0x7115a7eb), SPH_C32(0x2145a48a), SPH_C32(0x49499240), + SPH_C32(0xb15d0000), SPH_C32(0x5d3c0000), SPH_C32(0x37280000), + SPH_C32(0xf72a5032), SPH_C32(0x3b245818), SPH_C32(0xe4e1efe3), + SPH_C32(0x3e076744) }, + { SPH_C32(0x52373000), SPH_C32(0xb18b0000), SPH_C32(0xbc7a0000), + SPH_C32(0x4bbc0000), SPH_C32(0xa4f3442e), SPH_C32(0xf45616eb), + SPH_C32(0x6623a94f), SPH_C32(0x5ea22f27), SPH_C32(0x4c4e8400), + SPH_C32(0xa43c0000), SPH_C32(0xdbd10000), SPH_C32(0x835b0000), + SPH_C32(0x178113a8), SPH_C32(0xea7bb99f), SPH_C32(0xd0ae8609), + SPH_C32(0xee057339) }, + { SPH_C32(0x9b5c3030), SPH_C32(0x56ae0000), SPH_C32(0x93fe0000), + SPH_C32(0x6df30000), SPH_C32(0xac9a1fd7), SPH_C32(0x99aae7dc), + SPH_C32(0x36bcc0cb), SPH_C32(0xc0cb804f), SPH_C32(0x6a2e8640), + SPH_C32(0x79e40000), SPH_C32(0xa9fb0000), SPH_C32(0xcc5d0000), + SPH_C32(0x84e77457), SPH_C32(0xc382fd51), SPH_C32(0xe625e5dc), + SPH_C32(0xe223815b) }, + { SPH_C32(0x650a1800), SPH_C32(0xc0db0000), SPH_C32(0x299a0000), + SPH_C32(0x41a80000), SPH_C32(0x195f5d27), SPH_C32(0xbcb98eda), + SPH_C32(0x234ec450), SPH_C32(0x6308edfd), SPH_C32(0x5814b800), + SPH_C32(0x1dd50000), SPH_C32(0xbaf60000), SPH_C32(0x723a0000), + SPH_C32(0xd9e02ec4), SPH_C32(0x5a3284e7), SPH_C32(0x9707e129), + SPH_C32(0x0f8b57fc) }, + { SPH_C32(0xac611830), SPH_C32(0x27fe0000), SPH_C32(0x061e0000), + SPH_C32(0x67e70000), SPH_C32(0x113606de), SPH_C32(0xd1457fed), + SPH_C32(0x73d1add4), SPH_C32(0xfd614295), SPH_C32(0x7e74ba40), + SPH_C32(0xc00d0000), SPH_C32(0xc8dc0000), SPH_C32(0x3d3c0000), + SPH_C32(0x4a86493b), SPH_C32(0x73cbc029), SPH_C32(0xa18c82fc), + SPH_C32(0x03ada59e) }, + { SPH_C32(0x71502400), SPH_C32(0x79320000), SPH_C32(0x48bd0000), + SPH_C32(0xb0c90000), SPH_C32(0xd73e604b), SPH_C32(0x0cf0b3a2), + SPH_C32(0x64e7a370), SPH_C32(0x8286c938), SPH_C32(0x7b73ac00), + SPH_C32(0xd56c0000), SPH_C32(0x4e310000), SPH_C32(0x894f0000), + SPH_C32(0xaa2d0aa1), SPH_C32(0xa29421ae), SPH_C32(0x95c3eb16), + SPH_C32(0xd3afb1e3) }, + { SPH_C32(0xb83b2430), SPH_C32(0x9e170000), SPH_C32(0x67390000), + SPH_C32(0x96860000), SPH_C32(0xdf573bb2), SPH_C32(0x610c4295), + SPH_C32(0x3478caf4), SPH_C32(0x1cef6650), SPH_C32(0x5d13ae40), + SPH_C32(0x08b40000), SPH_C32(0x3c1b0000), SPH_C32(0xc6490000), + SPH_C32(0x394b6d5e), SPH_C32(0x8b6d6560), SPH_C32(0xa34888c3), + SPH_C32(0xdf894381) }, + { SPH_C32(0x12455000), SPH_C32(0xe28f0000), SPH_C32(0x188b0000), + SPH_C32(0x1b180000), SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), + SPH_C32(0x4a3a8ff2), SPH_C32(0xea373c60), SPH_C32(0xf3928800), + SPH_C32(0xdc560000), SPH_C32(0xbd470000), SPH_C32(0x95bd0000), + SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), SPH_C32(0x916cbfec), + SPH_C32(0x4aeb5b0f) }, + { SPH_C32(0xdb2e5030), SPH_C32(0x05aa0000), SPH_C32(0x370f0000), + SPH_C32(0x3d570000), SPH_C32(0xd15945cb), SPH_C32(0xbd461e45), + SPH_C32(0x1aa5e676), SPH_C32(0x745e9308), SPH_C32(0xd5f28a40), + SPH_C32(0x018e0000), SPH_C32(0xcf6d0000), SPH_C32(0xdabb0000), + SPH_C32(0xae101377), SPH_C32(0xda308dec), SPH_C32(0xa7e7dc39), + SPH_C32(0x46cda96d) }, + { SPH_C32(0x061f6c00), SPH_C32(0x5b660000), SPH_C32(0x79ac0000), + SPH_C32(0xea790000), SPH_C32(0x1751235e), SPH_C32(0x60f3d20a), + SPH_C32(0x0d93e8d2), SPH_C32(0x0bb918a5), SPH_C32(0xd0f59c00), + SPH_C32(0x14ef0000), SPH_C32(0x49800000), SPH_C32(0x6ec80000), + SPH_C32(0x4ebb50ed), SPH_C32(0x0b6f6c6b), SPH_C32(0x93a8b5d3), + SPH_C32(0x96cfbd10) }, + { SPH_C32(0xcf746c30), SPH_C32(0xbc430000), SPH_C32(0x56280000), + SPH_C32(0xcc360000), SPH_C32(0x1f3878a7), SPH_C32(0x0d0f233d), + SPH_C32(0x5d0c8156), SPH_C32(0x95d0b7cd), SPH_C32(0xf6959e40), + SPH_C32(0xc9370000), SPH_C32(0x3baa0000), SPH_C32(0x21ce0000), + SPH_C32(0xdddd3712), SPH_C32(0x229628a5), SPH_C32(0xa523d606), + SPH_C32(0x9ae94f72) }, + { SPH_C32(0x31224400), SPH_C32(0x2a360000), SPH_C32(0xec4c0000), + SPH_C32(0xe06d0000), SPH_C32(0xaafd3a57), SPH_C32(0x281c4a3b), + SPH_C32(0x48fe85cd), SPH_C32(0x3613da7f), SPH_C32(0xc4afa000), + SPH_C32(0xad060000), SPH_C32(0x28a70000), SPH_C32(0x9fa90000), + SPH_C32(0x80da6d81), SPH_C32(0xbb265113), SPH_C32(0xd401d2f3), + SPH_C32(0x774199d5) }, + { SPH_C32(0xf8494430), SPH_C32(0xcd130000), SPH_C32(0xc3c80000), + SPH_C32(0xc6220000), SPH_C32(0xa29461ae), SPH_C32(0x45e0bb0c), + SPH_C32(0x1861ec49), SPH_C32(0xa87a7517), SPH_C32(0xe2cfa240), + SPH_C32(0x70de0000), SPH_C32(0x5a8d0000), SPH_C32(0xd0af0000), + SPH_C32(0x13bc0a7e), SPH_C32(0x92df15dd), SPH_C32(0xe28ab126), + SPH_C32(0x7b676bb7) }, + { SPH_C32(0x25787800), SPH_C32(0x93df0000), SPH_C32(0x8d6b0000), + SPH_C32(0x110c0000), SPH_C32(0x649c073b), SPH_C32(0x98557743), + SPH_C32(0x0f57e2ed), SPH_C32(0xd79dfeba), SPH_C32(0xe7c8b400), + SPH_C32(0x65bf0000), SPH_C32(0xdc600000), SPH_C32(0x64dc0000), + SPH_C32(0xf31749e4), SPH_C32(0x4380f45a), SPH_C32(0xd6c5d8cc), + SPH_C32(0xab657fca) }, + { SPH_C32(0xec137830), SPH_C32(0x74fa0000), SPH_C32(0xa2ef0000), + SPH_C32(0x37430000), SPH_C32(0x6cf55cc2), SPH_C32(0xf5a98674), + SPH_C32(0x5fc88b69), SPH_C32(0x49f451d2), SPH_C32(0xc1a8b640), + SPH_C32(0xb8670000), SPH_C32(0xae4a0000), SPH_C32(0x2bda0000), + SPH_C32(0x60712e1b), SPH_C32(0x6a79b094), SPH_C32(0xe04ebb19), + SPH_C32(0xa7438da8) }, + { SPH_C32(0xdad61400), SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), + SPH_C32(0x574e0000), SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), + SPH_C32(0x628cfdb5), SPH_C32(0xc7e6c5cb), SPH_C32(0xa7bad400), + SPH_C32(0x36bb0000), SPH_C32(0x78910000), SPH_C32(0x34780000), + SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), SPH_C32(0xfadcfe71), + SPH_C32(0x1ff06c8d) }, + { SPH_C32(0x13bd1430), SPH_C32(0x5f940000), SPH_C32(0x60880000), + SPH_C32(0x71010000), SPH_C32(0x3bc161fe), SPH_C32(0xc8f70f50), + SPH_C32(0x32139431), SPH_C32(0x598f6aa3), SPH_C32(0x81dad640), + SPH_C32(0xeb630000), SPH_C32(0x0abb0000), SPH_C32(0x7b7e0000), + SPH_C32(0x1db27407), SPH_C32(0x4e95490d), SPH_C32(0xcc579da4), + SPH_C32(0x13d69eef) }, + { SPH_C32(0xce8c2800), SPH_C32(0x01580000), SPH_C32(0x2e2b0000), + SPH_C32(0xa62f0000), SPH_C32(0xfdc9076b), SPH_C32(0x1542c31f), + SPH_C32(0x25259a95), SPH_C32(0x2668e10e), SPH_C32(0x84ddc000), + SPH_C32(0xfe020000), SPH_C32(0x8c560000), SPH_C32(0xcf0d0000), + SPH_C32(0xfd19379d), SPH_C32(0x9fcaa88a), SPH_C32(0xf818f44e), + SPH_C32(0xc3d48a92) }, + { SPH_C32(0x07e72830), SPH_C32(0xe67d0000), SPH_C32(0x01af0000), + SPH_C32(0x80600000), SPH_C32(0xf5a05c92), SPH_C32(0x78be3228), + SPH_C32(0x75baf311), SPH_C32(0xb8014e66), SPH_C32(0xa2bdc240), + SPH_C32(0x23da0000), SPH_C32(0xfe7c0000), SPH_C32(0x800b0000), + SPH_C32(0x6e7f5062), SPH_C32(0xb633ec44), SPH_C32(0xce93979b), + SPH_C32(0xcff278f0) }, + { SPH_C32(0xf9b10000), SPH_C32(0x70080000), SPH_C32(0xbbcb0000), + SPH_C32(0xac3b0000), SPH_C32(0x40651e62), SPH_C32(0x5dad5b2e), + SPH_C32(0x6048f78a), SPH_C32(0x1bc223d4), SPH_C32(0x9087fc00), + SPH_C32(0x47eb0000), SPH_C32(0xed710000), SPH_C32(0x3e6c0000), + SPH_C32(0x33780af1), SPH_C32(0x2f8395f2), SPH_C32(0xbfb1936e), + SPH_C32(0x225aae57) }, + { SPH_C32(0x30da0030), SPH_C32(0x972d0000), SPH_C32(0x944f0000), + SPH_C32(0x8a740000), SPH_C32(0x480c459b), SPH_C32(0x3051aa19), + SPH_C32(0x30d79e0e), SPH_C32(0x85ab8cbc), SPH_C32(0xb6e7fe40), + SPH_C32(0x9a330000), SPH_C32(0x9f5b0000), SPH_C32(0x716a0000), + SPH_C32(0xa01e6d0e), SPH_C32(0x067ad13c), SPH_C32(0x893af0bb), + SPH_C32(0x2e7c5c35) }, + { SPH_C32(0xedeb3c00), SPH_C32(0xc9e10000), SPH_C32(0xdaec0000), + SPH_C32(0x5d5a0000), SPH_C32(0x8e04230e), SPH_C32(0xede46656), + SPH_C32(0x27e190aa), SPH_C32(0xfa4c0711), SPH_C32(0xb3e0e800), + SPH_C32(0x8f520000), SPH_C32(0x19b60000), SPH_C32(0xc5190000), + SPH_C32(0x40b52e94), SPH_C32(0xd72530bb), SPH_C32(0xbd759951), + SPH_C32(0xfe7e4848) }, + { SPH_C32(0x24803c30), SPH_C32(0x2ec40000), SPH_C32(0xf5680000), + SPH_C32(0x7b150000), SPH_C32(0x866d78f7), SPH_C32(0x80189761), + SPH_C32(0x777ef92e), SPH_C32(0x6425a879), SPH_C32(0x9580ea40), + SPH_C32(0x528a0000), SPH_C32(0x6b9c0000), SPH_C32(0x8a1f0000), + SPH_C32(0xd3d3496b), SPH_C32(0xfedc7475), SPH_C32(0x8bfefa84), + SPH_C32(0xf258ba2a) }, + { SPH_C32(0x8efe4800), SPH_C32(0x525c0000), SPH_C32(0x8ada0000), + SPH_C32(0xf68b0000), SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), + SPH_C32(0x093cbc28), SPH_C32(0x92fdf249), SPH_C32(0x3b01cc00), + SPH_C32(0x86680000), SPH_C32(0xeac00000), SPH_C32(0xd9eb0000), + SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), SPH_C32(0xb9dacdab), + SPH_C32(0x673aa2a4) }, + { SPH_C32(0x47954830), SPH_C32(0xb5790000), SPH_C32(0xa55e0000), + SPH_C32(0xd0c40000), SPH_C32(0x8863068e), SPH_C32(0x5c52cbb1), + SPH_C32(0x59a3d5ac), SPH_C32(0x0c945d21), SPH_C32(0x1d61ce40), + SPH_C32(0x5bb00000), SPH_C32(0x98ea0000), SPH_C32(0x96ed0000), + SPH_C32(0x44883742), SPH_C32(0xaf819cf9), SPH_C32(0x8f51ae7e), + SPH_C32(0x6b1c50c6) }, + { SPH_C32(0x9aa47400), SPH_C32(0xebb50000), SPH_C32(0xebfd0000), + SPH_C32(0x07ea0000), SPH_C32(0x4e6b601b), SPH_C32(0x81e707fe), + SPH_C32(0x4e95db08), SPH_C32(0x7373d68c), SPH_C32(0x1866d800), + SPH_C32(0x4ed10000), SPH_C32(0x1e070000), SPH_C32(0x229e0000), + SPH_C32(0xa42374d8), SPH_C32(0x7ede7d7e), SPH_C32(0xbb1ec794), + SPH_C32(0xbb1e44bb) }, + { SPH_C32(0x53cf7430), SPH_C32(0x0c900000), SPH_C32(0xc4790000), + SPH_C32(0x21a50000), SPH_C32(0x46023be2), SPH_C32(0xec1bf6c9), + SPH_C32(0x1e0ab28c), SPH_C32(0xed1a79e4), SPH_C32(0x3e06da40), + SPH_C32(0x93090000), SPH_C32(0x6c2d0000), SPH_C32(0x6d980000), + SPH_C32(0x37451327), SPH_C32(0x572739b0), SPH_C32(0x8d95a441), + SPH_C32(0xb738b6d9) }, + { SPH_C32(0xad995c00), SPH_C32(0x9ae50000), SPH_C32(0x7e1d0000), + SPH_C32(0x0dfe0000), SPH_C32(0xf3c77912), SPH_C32(0xc9089fcf), + SPH_C32(0x0bf8b617), SPH_C32(0x4ed91456), SPH_C32(0x0c3ce400), + SPH_C32(0xf7380000), SPH_C32(0x7f200000), SPH_C32(0xd3ff0000), + SPH_C32(0x6a4249b4), SPH_C32(0xce974006), SPH_C32(0xfcb7a0b4), + SPH_C32(0x5a90607e) }, + { SPH_C32(0x64f25c30), SPH_C32(0x7dc00000), SPH_C32(0x51990000), + SPH_C32(0x2bb10000), SPH_C32(0xfbae22eb), SPH_C32(0xa4f46ef8), + SPH_C32(0x5b67df93), SPH_C32(0xd0b0bb3e), SPH_C32(0x2a5ce640), + SPH_C32(0x2ae00000), SPH_C32(0x0d0a0000), SPH_C32(0x9cf90000), + SPH_C32(0xf9242e4b), SPH_C32(0xe76e04c8), SPH_C32(0xca3cc361), + SPH_C32(0x56b6921c) }, + { SPH_C32(0xb9c36000), SPH_C32(0x230c0000), SPH_C32(0x1f3a0000), + SPH_C32(0xfc9f0000), SPH_C32(0x3da6447e), SPH_C32(0x7941a2b7), + SPH_C32(0x4c51d137), SPH_C32(0xaf573093), SPH_C32(0x2f5bf000), + SPH_C32(0x3f810000), SPH_C32(0x8be70000), SPH_C32(0x288a0000), + SPH_C32(0x198f6dd1), SPH_C32(0x3631e54f), SPH_C32(0xfe73aa8b), + SPH_C32(0x86b48661) }, + { SPH_C32(0x70a86030), SPH_C32(0xc4290000), SPH_C32(0x30be0000), + SPH_C32(0xdad00000), SPH_C32(0x35cf1f87), SPH_C32(0x14bd5380), + SPH_C32(0x1cceb8b3), SPH_C32(0x313e9ffb), SPH_C32(0x093bf240), + SPH_C32(0xe2590000), SPH_C32(0xf9cd0000), SPH_C32(0x678c0000), + SPH_C32(0x8ae90a2e), SPH_C32(0x1fc8a181), SPH_C32(0xc8f8c95e), + SPH_C32(0x8a927403) }, + { SPH_C32(0x6f299000), SPH_C32(0x6c850000), SPH_C32(0x2f160000), + SPH_C32(0x782e0000), SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), + SPH_C32(0xd26a8c36), SPH_C32(0x32219526), SPH_C32(0x29449c00), + SPH_C32(0x64e70000), SPH_C32(0xf24b0000), SPH_C32(0xc2f30000), + SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), SPH_C32(0xf3e04259), + SPH_C32(0x8d0d9ec4) }, + { SPH_C32(0xa6429030), SPH_C32(0x8ba00000), SPH_C32(0x00920000), + SPH_C32(0x5e610000), SPH_C32(0x6c256c34), SPH_C32(0x7f21ede1), + SPH_C32(0x82f5e5b2), SPH_C32(0xac483a4e), SPH_C32(0x0f249e40), + SPH_C32(0xb93f0000), SPH_C32(0x80610000), SPH_C32(0x8df50000), + SPH_C32(0x9db82970), SPH_C32(0x7f3b738b), SPH_C32(0xc56b218c), + SPH_C32(0x812b6ca6) }, + { SPH_C32(0x7b73ac00), SPH_C32(0xd56c0000), SPH_C32(0x4e310000), + SPH_C32(0x894f0000), SPH_C32(0xaa2d0aa1), SPH_C32(0xa29421ae), + SPH_C32(0x95c3eb16), SPH_C32(0xd3afb1e3), SPH_C32(0x0a238800), + SPH_C32(0xac5e0000), SPH_C32(0x068c0000), SPH_C32(0x39860000), + SPH_C32(0x7d136aea), SPH_C32(0xae64920c), SPH_C32(0xf1244866), + SPH_C32(0x512978db) }, + { SPH_C32(0xb218ac30), SPH_C32(0x32490000), SPH_C32(0x61b50000), + SPH_C32(0xaf000000), SPH_C32(0xa2445158), SPH_C32(0xcf68d099), + SPH_C32(0xc55c8292), SPH_C32(0x4dc61e8b), SPH_C32(0x2c438a40), + SPH_C32(0x71860000), SPH_C32(0x74a60000), SPH_C32(0x76800000), + SPH_C32(0xee750d15), SPH_C32(0x879dd6c2), SPH_C32(0xc7af2bb3), + SPH_C32(0x5d0f8ab9) }, + { SPH_C32(0x4c4e8400), SPH_C32(0xa43c0000), SPH_C32(0xdbd10000), + SPH_C32(0x835b0000), SPH_C32(0x178113a8), SPH_C32(0xea7bb99f), + SPH_C32(0xd0ae8609), SPH_C32(0xee057339), SPH_C32(0x1e79b400), + SPH_C32(0x15b70000), SPH_C32(0x67ab0000), SPH_C32(0xc8e70000), + SPH_C32(0xb3725786), SPH_C32(0x1e2daf74), SPH_C32(0xb68d2f46), + SPH_C32(0xb0a75c1e) }, + { SPH_C32(0x85258430), SPH_C32(0x43190000), SPH_C32(0xf4550000), + SPH_C32(0xa5140000), SPH_C32(0x1fe84851), SPH_C32(0x878748a8), + SPH_C32(0x8031ef8d), SPH_C32(0x706cdc51), SPH_C32(0x3819b640), + SPH_C32(0xc86f0000), SPH_C32(0x15810000), SPH_C32(0x87e10000), + SPH_C32(0x20143079), SPH_C32(0x37d4ebba), SPH_C32(0x80064c93), + SPH_C32(0xbc81ae7c) }, + { SPH_C32(0x5814b800), SPH_C32(0x1dd50000), SPH_C32(0xbaf60000), + SPH_C32(0x723a0000), SPH_C32(0xd9e02ec4), SPH_C32(0x5a3284e7), + SPH_C32(0x9707e129), SPH_C32(0x0f8b57fc), SPH_C32(0x3d1ea000), + SPH_C32(0xdd0e0000), SPH_C32(0x936c0000), SPH_C32(0x33920000), + SPH_C32(0xc0bf73e3), SPH_C32(0xe68b0a3d), SPH_C32(0xb4492579), + SPH_C32(0x6c83ba01) }, + { SPH_C32(0x917fb830), SPH_C32(0xfaf00000), SPH_C32(0x95720000), + SPH_C32(0x54750000), SPH_C32(0xd189753d), SPH_C32(0x37ce75d0), + SPH_C32(0xc79888ad), SPH_C32(0x91e2f894), SPH_C32(0x1b7ea240), + SPH_C32(0x00d60000), SPH_C32(0xe1460000), SPH_C32(0x7c940000), + SPH_C32(0x53d9141c), SPH_C32(0xcf724ef3), SPH_C32(0x82c246ac), + SPH_C32(0x60a54863) }, + { SPH_C32(0x3b01cc00), SPH_C32(0x86680000), SPH_C32(0xeac00000), + SPH_C32(0xd9eb0000), SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), + SPH_C32(0xb9dacdab), SPH_C32(0x673aa2a4), SPH_C32(0xb5ff8400), + SPH_C32(0xd4340000), SPH_C32(0x601a0000), SPH_C32(0x2f600000), + SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), SPH_C32(0xb0e67183), + SPH_C32(0xf5c750ed) }, + { SPH_C32(0xf26acc30), SPH_C32(0x614d0000), SPH_C32(0xc5440000), + SPH_C32(0xffa40000), SPH_C32(0xdf870b44), SPH_C32(0xeb842900), + SPH_C32(0xe945a42f), SPH_C32(0xf9530dcc), SPH_C32(0x939f8640), + SPH_C32(0x09ec0000), SPH_C32(0x12300000), SPH_C32(0x60660000), + SPH_C32(0xc4826a35), SPH_C32(0x9e2fa67f), SPH_C32(0x866d1256), + SPH_C32(0xf9e1a28f) }, + { SPH_C32(0x2f5bf000), SPH_C32(0x3f810000), SPH_C32(0x8be70000), + SPH_C32(0x288a0000), SPH_C32(0x198f6dd1), SPH_C32(0x3631e54f), + SPH_C32(0xfe73aa8b), SPH_C32(0x86b48661), SPH_C32(0x96989000), + SPH_C32(0x1c8d0000), SPH_C32(0x94dd0000), SPH_C32(0xd4150000), + SPH_C32(0x242929af), SPH_C32(0x4f7047f8), SPH_C32(0xb2227bbc), + SPH_C32(0x29e3b6f2) }, + { SPH_C32(0xe630f030), SPH_C32(0xd8a40000), SPH_C32(0xa4630000), + SPH_C32(0x0ec50000), SPH_C32(0x11e63628), SPH_C32(0x5bcd1478), + SPH_C32(0xaeecc30f), SPH_C32(0x18dd2909), SPH_C32(0xb0f89240), + SPH_C32(0xc1550000), SPH_C32(0xe6f70000), SPH_C32(0x9b130000), + SPH_C32(0xb74f4e50), SPH_C32(0x66890336), SPH_C32(0x84a91869), + SPH_C32(0x25c54490) }, + { SPH_C32(0x1866d800), SPH_C32(0x4ed10000), SPH_C32(0x1e070000), + SPH_C32(0x229e0000), SPH_C32(0xa42374d8), SPH_C32(0x7ede7d7e), + SPH_C32(0xbb1ec794), SPH_C32(0xbb1e44bb), SPH_C32(0x82c2ac00), + SPH_C32(0xa5640000), SPH_C32(0xf5fa0000), SPH_C32(0x25740000), + SPH_C32(0xea4814c3), SPH_C32(0xff397a80), SPH_C32(0xf58b1c9c), + SPH_C32(0xc86d9237) }, + { SPH_C32(0xd10dd830), SPH_C32(0xa9f40000), SPH_C32(0x31830000), + SPH_C32(0x04d10000), SPH_C32(0xac4a2f21), SPH_C32(0x13228c49), + SPH_C32(0xeb81ae10), SPH_C32(0x2577ebd3), SPH_C32(0xa4a2ae40), + SPH_C32(0x78bc0000), SPH_C32(0x87d00000), SPH_C32(0x6a720000), + SPH_C32(0x792e733c), SPH_C32(0xd6c03e4e), SPH_C32(0xc3007f49), + SPH_C32(0xc44b6055) }, + { SPH_C32(0x0c3ce400), SPH_C32(0xf7380000), SPH_C32(0x7f200000), + SPH_C32(0xd3ff0000), SPH_C32(0x6a4249b4), SPH_C32(0xce974006), + SPH_C32(0xfcb7a0b4), SPH_C32(0x5a90607e), SPH_C32(0xa1a5b800), + SPH_C32(0x6ddd0000), SPH_C32(0x013d0000), SPH_C32(0xde010000), + SPH_C32(0x998530a6), SPH_C32(0x079fdfc9), SPH_C32(0xf74f16a3), + SPH_C32(0x14497428) }, + { SPH_C32(0xc557e430), SPH_C32(0x101d0000), SPH_C32(0x50a40000), + SPH_C32(0xf5b00000), SPH_C32(0x622b124d), SPH_C32(0xa36bb131), + SPH_C32(0xac28c930), SPH_C32(0xc4f9cf16), SPH_C32(0x87c5ba40), + SPH_C32(0xb0050000), SPH_C32(0x73170000), SPH_C32(0x91070000), + SPH_C32(0x0ae35759), SPH_C32(0x2e669b07), SPH_C32(0xc1c47576), + SPH_C32(0x186f864a) }, + { SPH_C32(0xf3928800), SPH_C32(0xdc560000), SPH_C32(0xbd470000), + SPH_C32(0x95bd0000), SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), + SPH_C32(0x916cbfec), SPH_C32(0x4aeb5b0f), SPH_C32(0xe1d7d800), + SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), SPH_C32(0x8ea50000), + SPH_C32(0xe4466aba), SPH_C32(0x23732650), SPH_C32(0xdb56301e), + SPH_C32(0xa0dc676f) }, + { SPH_C32(0x3af98830), SPH_C32(0x3b730000), SPH_C32(0x92c30000), + SPH_C32(0xb3f20000), SPH_C32(0x351f2f71), SPH_C32(0x9e353815), + SPH_C32(0xc1f3d668), SPH_C32(0xd482f467), SPH_C32(0xc7b7da40), + SPH_C32(0xe3010000), SPH_C32(0xd7e60000), SPH_C32(0xc1a30000), + SPH_C32(0x77200d45), SPH_C32(0x0a8a629e), SPH_C32(0xeddd53cb), + SPH_C32(0xacfa950d) }, + { SPH_C32(0xe7c8b400), SPH_C32(0x65bf0000), SPH_C32(0xdc600000), + SPH_C32(0x64dc0000), SPH_C32(0xf31749e4), SPH_C32(0x4380f45a), + SPH_C32(0xd6c5d8cc), SPH_C32(0xab657fca), SPH_C32(0xc2b0cc00), + SPH_C32(0xf6600000), SPH_C32(0x510b0000), SPH_C32(0x75d00000), + SPH_C32(0x978b4edf), SPH_C32(0xdbd58319), SPH_C32(0xd9923a21), + SPH_C32(0x7cf88170) }, + { SPH_C32(0x2ea3b430), SPH_C32(0x829a0000), SPH_C32(0xf3e40000), + SPH_C32(0x42930000), SPH_C32(0xfb7e121d), SPH_C32(0x2e7c056d), + SPH_C32(0x865ab148), SPH_C32(0x350cd0a2), SPH_C32(0xe4d0ce40), + SPH_C32(0x2bb80000), SPH_C32(0x23210000), SPH_C32(0x3ad60000), + SPH_C32(0x04ed2920), SPH_C32(0xf22cc7d7), SPH_C32(0xef1959f4), + SPH_C32(0x70de7312) }, + { SPH_C32(0xd0f59c00), SPH_C32(0x14ef0000), SPH_C32(0x49800000), + SPH_C32(0x6ec80000), SPH_C32(0x4ebb50ed), SPH_C32(0x0b6f6c6b), + SPH_C32(0x93a8b5d3), SPH_C32(0x96cfbd10), SPH_C32(0xd6eaf000), + SPH_C32(0x4f890000), SPH_C32(0x302c0000), SPH_C32(0x84b10000), + SPH_C32(0x59ea73b3), SPH_C32(0x6b9cbe61), SPH_C32(0x9e3b5d01), + SPH_C32(0x9d76a5b5) }, + { SPH_C32(0x199e9c30), SPH_C32(0xf3ca0000), SPH_C32(0x66040000), + SPH_C32(0x48870000), SPH_C32(0x46d20b14), SPH_C32(0x66939d5c), + SPH_C32(0xc337dc57), SPH_C32(0x08a61278), SPH_C32(0xf08af240), + SPH_C32(0x92510000), SPH_C32(0x42060000), SPH_C32(0xcbb70000), + SPH_C32(0xca8c144c), SPH_C32(0x4265faaf), SPH_C32(0xa8b03ed4), + SPH_C32(0x915057d7) }, + { SPH_C32(0xc4afa000), SPH_C32(0xad060000), SPH_C32(0x28a70000), + SPH_C32(0x9fa90000), SPH_C32(0x80da6d81), SPH_C32(0xbb265113), + SPH_C32(0xd401d2f3), SPH_C32(0x774199d5), SPH_C32(0xf58de400), + SPH_C32(0x87300000), SPH_C32(0xc4eb0000), SPH_C32(0x7fc40000), + SPH_C32(0x2a2757d6), SPH_C32(0x933a1b28), SPH_C32(0x9cff573e), + SPH_C32(0x415243aa) }, + { SPH_C32(0x0dc4a030), SPH_C32(0x4a230000), SPH_C32(0x07230000), + SPH_C32(0xb9e60000), SPH_C32(0x88b33678), SPH_C32(0xd6daa024), + SPH_C32(0x849ebb77), SPH_C32(0xe92836bd), SPH_C32(0xd3ede640), + SPH_C32(0x5ae80000), SPH_C32(0xb6c10000), SPH_C32(0x30c20000), + SPH_C32(0xb9413029), SPH_C32(0xbac35fe6), SPH_C32(0xaa7434eb), + SPH_C32(0x4d74b1c8) }, + { SPH_C32(0xa7bad400), SPH_C32(0x36bb0000), SPH_C32(0x78910000), + SPH_C32(0x34780000), SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), + SPH_C32(0xfadcfe71), SPH_C32(0x1ff06c8d), SPH_C32(0x7d6cc000), + SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), SPH_C32(0x63360000), + SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), SPH_C32(0x985003c4), + SPH_C32(0xd816a946) }, + { SPH_C32(0x6ed1d430), SPH_C32(0xd19e0000), SPH_C32(0x57150000), + SPH_C32(0x12370000), SPH_C32(0x86bd4801), SPH_C32(0x0a90fcf4), + SPH_C32(0xaa4397f5), SPH_C32(0x8199c3e5), SPH_C32(0x5b0cc240), + SPH_C32(0x53d20000), SPH_C32(0x45b70000), SPH_C32(0x2c300000), + SPH_C32(0x2e1a4e00), SPH_C32(0xeb9eb76a), SPH_C32(0xaedb6011), + SPH_C32(0xd4305b24) }, + { SPH_C32(0xb3e0e800), SPH_C32(0x8f520000), SPH_C32(0x19b60000), + SPH_C32(0xc5190000), SPH_C32(0x40b52e94), SPH_C32(0xd72530bb), + SPH_C32(0xbd759951), SPH_C32(0xfe7e4848), SPH_C32(0x5e0bd400), + SPH_C32(0x46b30000), SPH_C32(0xc35a0000), SPH_C32(0x98430000), + SPH_C32(0xceb10d9a), SPH_C32(0x3ac156ed), SPH_C32(0x9a9409fb), + SPH_C32(0x04324f59) }, + { SPH_C32(0x7a8be830), SPH_C32(0x68770000), SPH_C32(0x36320000), + SPH_C32(0xe3560000), SPH_C32(0x48dc756d), SPH_C32(0xbad9c18c), + SPH_C32(0xedeaf0d5), SPH_C32(0x6017e720), SPH_C32(0x786bd640), + SPH_C32(0x9b6b0000), SPH_C32(0xb1700000), SPH_C32(0xd7450000), + SPH_C32(0x5dd76a65), SPH_C32(0x13381223), SPH_C32(0xac1f6a2e), + SPH_C32(0x0814bd3b) }, + { SPH_C32(0x84ddc000), SPH_C32(0xfe020000), SPH_C32(0x8c560000), + SPH_C32(0xcf0d0000), SPH_C32(0xfd19379d), SPH_C32(0x9fcaa88a), + SPH_C32(0xf818f44e), SPH_C32(0xc3d48a92), SPH_C32(0x4a51e800), + SPH_C32(0xff5a0000), SPH_C32(0xa27d0000), SPH_C32(0x69220000), + SPH_C32(0x00d030f6), SPH_C32(0x8a886b95), SPH_C32(0xdd3d6edb), + SPH_C32(0xe5bc6b9c) }, + { SPH_C32(0x4db6c030), SPH_C32(0x19270000), SPH_C32(0xa3d20000), + SPH_C32(0xe9420000), SPH_C32(0xf5706c64), SPH_C32(0xf23659bd), + SPH_C32(0xa8879dca), SPH_C32(0x5dbd25fa), SPH_C32(0x6c31ea40), + SPH_C32(0x22820000), SPH_C32(0xd0570000), SPH_C32(0x26240000), + SPH_C32(0x93b65709), SPH_C32(0xa3712f5b), SPH_C32(0xebb60d0e), + SPH_C32(0xe99a99fe) }, + { SPH_C32(0x9087fc00), SPH_C32(0x47eb0000), SPH_C32(0xed710000), + SPH_C32(0x3e6c0000), SPH_C32(0x33780af1), SPH_C32(0x2f8395f2), + SPH_C32(0xbfb1936e), SPH_C32(0x225aae57), SPH_C32(0x6936fc00), + SPH_C32(0x37e30000), SPH_C32(0x56ba0000), SPH_C32(0x92570000), + SPH_C32(0x731d1493), SPH_C32(0x722ecedc), SPH_C32(0xdff964e4), + SPH_C32(0x39988d83) }, + { SPH_C32(0x59ecfc30), SPH_C32(0xa0ce0000), SPH_C32(0xc2f50000), + SPH_C32(0x18230000), SPH_C32(0x3b115108), SPH_C32(0x427f64c5), + SPH_C32(0xef2efaea), SPH_C32(0xbc33013f), SPH_C32(0x4f56fe40), + SPH_C32(0xea3b0000), SPH_C32(0x24900000), SPH_C32(0xdd510000), + SPH_C32(0xe07b736c), SPH_C32(0x5bd78a12), SPH_C32(0xe9720731), + SPH_C32(0x35be7fe1) } +}; + +static const sph_u32 T512_7[128][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xf7750009), SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), + SPH_C32(0x04920000), SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), + SPH_C32(0x7a87f14e), SPH_C32(0x9e16981a), SPH_C32(0xd46a0000), + SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), SPH_C32(0x4a290000), + SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), SPH_C32(0x98369604), + SPH_C32(0xf746c320) }, + { SPH_C32(0xd46a0000), SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), + SPH_C32(0x4a290000), SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), + SPH_C32(0x98369604), SPH_C32(0xf746c320), SPH_C32(0x231f0009), + SPH_C32(0x42f40000), SPH_C32(0x66790000), SPH_C32(0x4ebb0000), + SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), SPH_C32(0xe2b1674a), + SPH_C32(0x69505b3a) }, + { SPH_C32(0x231f0009), SPH_C32(0x42f40000), SPH_C32(0x66790000), + SPH_C32(0x4ebb0000), SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), + SPH_C32(0xe2b1674a), SPH_C32(0x69505b3a), SPH_C32(0xf7750009), + SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), SPH_C32(0x04920000), + SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), SPH_C32(0x7a87f14e), + SPH_C32(0x9e16981a) }, + { SPH_C32(0x774400f0), SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), + SPH_C32(0x34140000), SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), + SPH_C32(0x0bc3cd1e), SPH_C32(0xcf3775cb), SPH_C32(0xf46c0050), + SPH_C32(0x96180000), SPH_C32(0x14a50000), SPH_C32(0x031f0000), + SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), SPH_C32(0x9ca470d2), + SPH_C32(0x8a341574) }, + { SPH_C32(0x803100f9), SPH_C32(0x3e66c000), SPH_C32(0x36640000), + SPH_C32(0x30860000), SPH_C32(0x8ba26725), SPH_C32(0xa263da9f), + SPH_C32(0x71443c50), SPH_C32(0x5121edd1), SPH_C32(0x20060050), + SPH_C32(0x1bd0c000), SPH_C32(0xb10a0000), SPH_C32(0x49360000), + SPH_C32(0xbeda3cc2), SPH_C32(0xaf0bf875), SPH_C32(0x0492e6d6), + SPH_C32(0x7d72d654) }, + { SPH_C32(0xa32e00f0), SPH_C32(0x7c92c000), SPH_C32(0x501d0000), + SPH_C32(0x7e3d0000), SPH_C32(0x75793cf6), SPH_C32(0x933f6a49), + SPH_C32(0x93f55b1a), SPH_C32(0x3871b6eb), SPH_C32(0xd7730059), + SPH_C32(0xd4ec0000), SPH_C32(0x72dc0000), SPH_C32(0x4da40000), + SPH_C32(0xbc4f256b), SPH_C32(0x57e3cecf), SPH_C32(0x7e151798), + SPH_C32(0xe3644e4e) }, + { SPH_C32(0x545b00f9), SPH_C32(0xb3ae0000), SPH_C32(0x93cb0000), + SPH_C32(0x7aaf0000), SPH_C32(0x77ec255f), SPH_C32(0x6bd75cf3), + SPH_C32(0xe972aa54), SPH_C32(0xa6672ef1), SPH_C32(0x03190059), + SPH_C32(0x5924c000), SPH_C32(0xd7730000), SPH_C32(0x078d0000), + SPH_C32(0x40016711), SPH_C32(0x9e5748a3), SPH_C32(0xe623819c), + SPH_C32(0x14228d6e) }, + { SPH_C32(0xf46c0050), SPH_C32(0x96180000), SPH_C32(0x14a50000), + SPH_C32(0x031f0000), SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), + SPH_C32(0x9ca470d2), SPH_C32(0x8a341574), SPH_C32(0x832800a0), + SPH_C32(0x67420000), SPH_C32(0xe1170000), SPH_C32(0x370b0000), + SPH_C32(0xcba30034), SPH_C32(0x3c34923c), SPH_C32(0x9767bdcc), + SPH_C32(0x450360bf) }, + { SPH_C32(0x03190059), SPH_C32(0x5924c000), SPH_C32(0xd7730000), + SPH_C32(0x078d0000), SPH_C32(0x40016711), SPH_C32(0x9e5748a3), + SPH_C32(0xe623819c), SPH_C32(0x14228d6e), SPH_C32(0x574200a0), + SPH_C32(0xea8ac000), SPH_C32(0x44b80000), SPH_C32(0x7d220000), + SPH_C32(0x37ed424e), SPH_C32(0xf5801450), SPH_C32(0x0f512bc8), + SPH_C32(0xb245a39f) }, + { SPH_C32(0x20060050), SPH_C32(0x1bd0c000), SPH_C32(0xb10a0000), + SPH_C32(0x49360000), SPH_C32(0xbeda3cc2), SPH_C32(0xaf0bf875), + SPH_C32(0x0492e6d6), SPH_C32(0x7d72d654), SPH_C32(0xa03700a9), + SPH_C32(0x25b60000), SPH_C32(0x876e0000), SPH_C32(0x79b00000), + SPH_C32(0x35785be7), SPH_C32(0x0d6822ea), SPH_C32(0x75d6da86), + SPH_C32(0x2c533b85) }, + { SPH_C32(0xd7730059), SPH_C32(0xd4ec0000), SPH_C32(0x72dc0000), + SPH_C32(0x4da40000), SPH_C32(0xbc4f256b), SPH_C32(0x57e3cecf), + SPH_C32(0x7e151798), SPH_C32(0xe3644e4e), SPH_C32(0x745d00a9), + SPH_C32(0xa87ec000), SPH_C32(0x22c10000), SPH_C32(0x33990000), + SPH_C32(0xc936199d), SPH_C32(0xc4dca486), SPH_C32(0xede04c82), + SPH_C32(0xdb15f8a5) }, + { SPH_C32(0x832800a0), SPH_C32(0x67420000), SPH_C32(0xe1170000), + SPH_C32(0x370b0000), SPH_C32(0xcba30034), SPH_C32(0x3c34923c), + SPH_C32(0x9767bdcc), SPH_C32(0x450360bf), SPH_C32(0x774400f0), + SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), SPH_C32(0x34140000), + SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), SPH_C32(0x0bc3cd1e), + SPH_C32(0xcf3775cb) }, + { SPH_C32(0x745d00a9), SPH_C32(0xa87ec000), SPH_C32(0x22c10000), + SPH_C32(0x33990000), SPH_C32(0xc936199d), SPH_C32(0xc4dca486), + SPH_C32(0xede04c82), SPH_C32(0xdb15f8a5), SPH_C32(0xa32e00f0), + SPH_C32(0x7c92c000), SPH_C32(0x501d0000), SPH_C32(0x7e3d0000), + SPH_C32(0x75793cf6), SPH_C32(0x933f6a49), SPH_C32(0x93f55b1a), + SPH_C32(0x3871b6eb) }, + { SPH_C32(0x574200a0), SPH_C32(0xea8ac000), SPH_C32(0x44b80000), + SPH_C32(0x7d220000), SPH_C32(0x37ed424e), SPH_C32(0xf5801450), + SPH_C32(0x0f512bc8), SPH_C32(0xb245a39f), SPH_C32(0x545b00f9), + SPH_C32(0xb3ae0000), SPH_C32(0x93cb0000), SPH_C32(0x7aaf0000), + SPH_C32(0x77ec255f), SPH_C32(0x6bd75cf3), SPH_C32(0xe972aa54), + SPH_C32(0xa6672ef1) }, + { SPH_C32(0xa03700a9), SPH_C32(0x25b60000), SPH_C32(0x876e0000), + SPH_C32(0x79b00000), SPH_C32(0x35785be7), SPH_C32(0x0d6822ea), + SPH_C32(0x75d6da86), SPH_C32(0x2c533b85), SPH_C32(0x803100f9), + SPH_C32(0x3e66c000), SPH_C32(0x36640000), SPH_C32(0x30860000), + SPH_C32(0x8ba26725), SPH_C32(0xa263da9f), SPH_C32(0x71443c50), + SPH_C32(0x5121edd1) }, + { SPH_C32(0xe8870170), SPH_C32(0x9d720000), SPH_C32(0x12db0000), + SPH_C32(0xd4220000), SPH_C32(0xf2886b27), SPH_C32(0xa921e543), + SPH_C32(0x4ef8b518), SPH_C32(0x618813b1), SPH_C32(0xb4370060), + SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), SPH_C32(0x5cae0000), + SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), SPH_C32(0x1b365f3d), + SPH_C32(0xf3d45758) }, + { SPH_C32(0x1ff20179), SPH_C32(0x524ec000), SPH_C32(0xd10d0000), + SPH_C32(0xd0b00000), SPH_C32(0xf01d728e), SPH_C32(0x51c9d3f9), + SPH_C32(0x347f4456), SPH_C32(0xff9e8bab), SPH_C32(0x605d0060), + SPH_C32(0x8184c000), SPH_C32(0xf36d0000), SPH_C32(0x16870000), + SPH_C32(0x681a5d45), SPH_C32(0xf28a7e49), SPH_C32(0x8300c939), + SPH_C32(0x04929478) }, + { SPH_C32(0x3ced0170), SPH_C32(0x10bac000), SPH_C32(0xb7740000), + SPH_C32(0x9e0b0000), SPH_C32(0x0ec6295d), SPH_C32(0x6095632f), + SPH_C32(0xd6ce231c), SPH_C32(0x96ced091), SPH_C32(0x97280069), + SPH_C32(0x4eb80000), SPH_C32(0x30bb0000), SPH_C32(0x12150000), + SPH_C32(0x6a8f44ec), SPH_C32(0x0a6248f3), SPH_C32(0xf9873877), + SPH_C32(0x9a840c62) }, + { SPH_C32(0xcb980179), SPH_C32(0xdf860000), SPH_C32(0x74a20000), + SPH_C32(0x9a990000), SPH_C32(0x0c5330f4), SPH_C32(0x987d5595), + SPH_C32(0xac49d252), SPH_C32(0x08d8488b), SPH_C32(0x43420069), + SPH_C32(0xc370c000), SPH_C32(0x95140000), SPH_C32(0x583c0000), + SPH_C32(0x96c10696), SPH_C32(0xc3d6ce9f), SPH_C32(0x61b1ae73), + SPH_C32(0x6dc2cf42) }, + { SPH_C32(0x9fc30180), SPH_C32(0x6c280000), SPH_C32(0xe7690000), + SPH_C32(0xe0360000), SPH_C32(0x7bbf15ab), SPH_C32(0xf3aa0966), + SPH_C32(0x453b7806), SPH_C32(0xaebf667a), SPH_C32(0x405b0030), + SPH_C32(0x9a540000), SPH_C32(0x42670000), SPH_C32(0x5fb10000), + SPH_C32(0xd6c06187), SPH_C32(0x5d81863c), SPH_C32(0x87922fef), + SPH_C32(0x79e0422c) }, + { SPH_C32(0x68b60189), SPH_C32(0xa314c000), SPH_C32(0x24bf0000), + SPH_C32(0xe4a40000), SPH_C32(0x792a0c02), SPH_C32(0x0b423fdc), + SPH_C32(0x3fbc8948), SPH_C32(0x30a9fe60), SPH_C32(0x94310030), + SPH_C32(0x179cc000), SPH_C32(0xe7c80000), SPH_C32(0x15980000), + SPH_C32(0x2a8e23fd), SPH_C32(0x94350050), SPH_C32(0x1fa4b9eb), + SPH_C32(0x8ea6810c) }, + { SPH_C32(0x4ba90180), SPH_C32(0xe1e0c000), SPH_C32(0x42c60000), + SPH_C32(0xaa1f0000), SPH_C32(0x87f157d1), SPH_C32(0x3a1e8f0a), + SPH_C32(0xdd0dee02), SPH_C32(0x59f9a55a), SPH_C32(0x63440039), + SPH_C32(0xd8a00000), SPH_C32(0x241e0000), SPH_C32(0x110a0000), + SPH_C32(0x281b3a54), SPH_C32(0x6cdd36ea), SPH_C32(0x652348a5), + SPH_C32(0x10b01916) }, + { SPH_C32(0xbcdc0189), SPH_C32(0x2edc0000), SPH_C32(0x81100000), + SPH_C32(0xae8d0000), SPH_C32(0x85644e78), SPH_C32(0xc2f6b9b0), + SPH_C32(0xa78a1f4c), SPH_C32(0xc7ef3d40), SPH_C32(0xb72e0039), + SPH_C32(0x5568c000), SPH_C32(0x81b10000), SPH_C32(0x5b230000), + SPH_C32(0xd455782e), SPH_C32(0xa569b086), SPH_C32(0xfd15dea1), + SPH_C32(0xe7f6da36) }, + { SPH_C32(0x1ceb0120), SPH_C32(0x0b6a0000), SPH_C32(0x067e0000), + SPH_C32(0xd73d0000), SPH_C32(0xb01c159f), SPH_C32(0xcf9e9b5a), + SPH_C32(0xd25cc5ca), SPH_C32(0xebbc06c5), SPH_C32(0x371f00c0), + SPH_C32(0x6b0e0000), SPH_C32(0xb7d50000), SPH_C32(0x6ba50000), + SPH_C32(0x5ff71f0b), SPH_C32(0x070a6a19), SPH_C32(0x8c51e2f1), + SPH_C32(0xb6d737e7) }, + { SPH_C32(0xeb9e0129), SPH_C32(0xc456c000), SPH_C32(0xc5a80000), + SPH_C32(0xd3af0000), SPH_C32(0xb2890c36), SPH_C32(0x3776ade0), + SPH_C32(0xa8db3484), SPH_C32(0x75aa9edf), SPH_C32(0xe37500c0), + SPH_C32(0xe6c6c000), SPH_C32(0x127a0000), SPH_C32(0x218c0000), + SPH_C32(0xa3b95d71), SPH_C32(0xcebeec75), SPH_C32(0x146774f5), + SPH_C32(0x4191f4c7) }, + { SPH_C32(0xc8810120), SPH_C32(0x86a2c000), SPH_C32(0xa3d10000), + SPH_C32(0x9d140000), SPH_C32(0x4c5257e5), SPH_C32(0x062a1d36), + SPH_C32(0x4a6a53ce), SPH_C32(0x1cfac5e5), SPH_C32(0x140000c9), + SPH_C32(0x29fa0000), SPH_C32(0xd1ac0000), SPH_C32(0x251e0000), + SPH_C32(0xa12c44d8), SPH_C32(0x3656dacf), SPH_C32(0x6ee085bb), + SPH_C32(0xdf876cdd) }, + { SPH_C32(0x3ff40129), SPH_C32(0x499e0000), SPH_C32(0x60070000), + SPH_C32(0x99860000), SPH_C32(0x4ec74e4c), SPH_C32(0xfec22b8c), + SPH_C32(0x30eda280), SPH_C32(0x82ec5dff), SPH_C32(0xc06a00c9), + SPH_C32(0xa432c000), SPH_C32(0x74030000), SPH_C32(0x6f370000), + SPH_C32(0x5d6206a2), SPH_C32(0xffe25ca3), SPH_C32(0xf6d613bf), + SPH_C32(0x28c1affd) }, + { SPH_C32(0x6baf01d0), SPH_C32(0xfa300000), SPH_C32(0xf3cc0000), + SPH_C32(0xe3290000), SPH_C32(0x392b6b13), SPH_C32(0x9515777f), + SPH_C32(0xd99f08d4), SPH_C32(0x248b730e), SPH_C32(0xc3730090), + SPH_C32(0xfd160000), SPH_C32(0xa3700000), SPH_C32(0x68ba0000), + SPH_C32(0x1d6361b3), SPH_C32(0x61b51400), SPH_C32(0x10f59223), + SPH_C32(0x3ce32293) }, + { SPH_C32(0x9cda01d9), SPH_C32(0x350cc000), SPH_C32(0x301a0000), + SPH_C32(0xe7bb0000), SPH_C32(0x3bbe72ba), SPH_C32(0x6dfd41c5), + SPH_C32(0xa318f99a), SPH_C32(0xba9deb14), SPH_C32(0x17190090), + SPH_C32(0x70dec000), SPH_C32(0x06df0000), SPH_C32(0x22930000), + SPH_C32(0xe12d23c9), SPH_C32(0xa801926c), SPH_C32(0x88c30427), + SPH_C32(0xcba5e1b3) }, + { SPH_C32(0xbfc501d0), SPH_C32(0x77f8c000), SPH_C32(0x56630000), + SPH_C32(0xa9000000), SPH_C32(0xc5652969), SPH_C32(0x5ca1f113), + SPH_C32(0x41a99ed0), SPH_C32(0xd3cdb02e), SPH_C32(0xe06c0099), + SPH_C32(0xbfe20000), SPH_C32(0xc5090000), SPH_C32(0x26010000), + SPH_C32(0xe3b83a60), SPH_C32(0x50e9a4d6), SPH_C32(0xf244f569), + SPH_C32(0x55b379a9) }, + { SPH_C32(0x48b001d9), SPH_C32(0xb8c40000), SPH_C32(0x95b50000), + SPH_C32(0xad920000), SPH_C32(0xc7f030c0), SPH_C32(0xa449c7a9), + SPH_C32(0x3b2e6f9e), SPH_C32(0x4ddb2834), SPH_C32(0x34060099), + SPH_C32(0x322ac000), SPH_C32(0x60a60000), SPH_C32(0x6c280000), + SPH_C32(0x1ff6781a), SPH_C32(0x995d22ba), SPH_C32(0x6a72636d), + SPH_C32(0xa2f5ba89) }, + { SPH_C32(0xb4370060), SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), + SPH_C32(0x5cae0000), SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), + SPH_C32(0x1b365f3d), SPH_C32(0xf3d45758), SPH_C32(0x5cb00110), + SPH_C32(0x913e0000), SPH_C32(0x44190000), SPH_C32(0x888c0000), + SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), SPH_C32(0x55ceea25), + SPH_C32(0x925c44e9) }, + { SPH_C32(0x43420069), SPH_C32(0xc370c000), SPH_C32(0x95140000), + SPH_C32(0x583c0000), SPH_C32(0x96c10696), SPH_C32(0xc3d6ce9f), + SPH_C32(0x61b1ae73), SPH_C32(0x6dc2cf42), SPH_C32(0x88da0110), + SPH_C32(0x1cf6c000), SPH_C32(0xe1b60000), SPH_C32(0xc2a50000), + SPH_C32(0x9a923662), SPH_C32(0x5bab9b0a), SPH_C32(0xcdf87c21), + SPH_C32(0x651a87c9) }, + { SPH_C32(0x605d0060), SPH_C32(0x8184c000), SPH_C32(0xf36d0000), + SPH_C32(0x16870000), SPH_C32(0x681a5d45), SPH_C32(0xf28a7e49), + SPH_C32(0x8300c939), SPH_C32(0x04929478), SPH_C32(0x7faf0119), + SPH_C32(0xd3ca0000), SPH_C32(0x22600000), SPH_C32(0xc6370000), + SPH_C32(0x98072fcb), SPH_C32(0xa343adb0), SPH_C32(0xb77f8d6f), + SPH_C32(0xfb0c1fd3) }, + { SPH_C32(0x97280069), SPH_C32(0x4eb80000), SPH_C32(0x30bb0000), + SPH_C32(0x12150000), SPH_C32(0x6a8f44ec), SPH_C32(0x0a6248f3), + SPH_C32(0xf9873877), SPH_C32(0x9a840c62), SPH_C32(0xabc50119), + SPH_C32(0x5e02c000), SPH_C32(0x87cf0000), SPH_C32(0x8c1e0000), + SPH_C32(0x64496db1), SPH_C32(0x6af72bdc), SPH_C32(0x2f491b6b), + SPH_C32(0x0c4adcf3) }, + { SPH_C32(0xc3730090), SPH_C32(0xfd160000), SPH_C32(0xa3700000), + SPH_C32(0x68ba0000), SPH_C32(0x1d6361b3), SPH_C32(0x61b51400), + SPH_C32(0x10f59223), SPH_C32(0x3ce32293), SPH_C32(0xa8dc0140), + SPH_C32(0x07260000), SPH_C32(0x50bc0000), SPH_C32(0x8b930000), + SPH_C32(0x24480aa0), SPH_C32(0xf4a0637f), SPH_C32(0xc96a9af7), + SPH_C32(0x1868519d) }, + { SPH_C32(0x34060099), SPH_C32(0x322ac000), SPH_C32(0x60a60000), + SPH_C32(0x6c280000), SPH_C32(0x1ff6781a), SPH_C32(0x995d22ba), + SPH_C32(0x6a72636d), SPH_C32(0xa2f5ba89), SPH_C32(0x7cb60140), + SPH_C32(0x8aeec000), SPH_C32(0xf5130000), SPH_C32(0xc1ba0000), + SPH_C32(0xd80648da), SPH_C32(0x3d14e513), SPH_C32(0x515c0cf3), + SPH_C32(0xef2e92bd) }, + { SPH_C32(0x17190090), SPH_C32(0x70dec000), SPH_C32(0x06df0000), + SPH_C32(0x22930000), SPH_C32(0xe12d23c9), SPH_C32(0xa801926c), + SPH_C32(0x88c30427), SPH_C32(0xcba5e1b3), SPH_C32(0x8bc30149), + SPH_C32(0x45d20000), SPH_C32(0x36c50000), SPH_C32(0xc5280000), + SPH_C32(0xda935173), SPH_C32(0xc5fcd3a9), SPH_C32(0x2bdbfdbd), + SPH_C32(0x71380aa7) }, + { SPH_C32(0xe06c0099), SPH_C32(0xbfe20000), SPH_C32(0xc5090000), + SPH_C32(0x26010000), SPH_C32(0xe3b83a60), SPH_C32(0x50e9a4d6), + SPH_C32(0xf244f569), SPH_C32(0x55b379a9), SPH_C32(0x5fa90149), + SPH_C32(0xc81ac000), SPH_C32(0x936a0000), SPH_C32(0x8f010000), + SPH_C32(0x26dd1309), SPH_C32(0x0c4855c5), SPH_C32(0xb3ed6bb9), + SPH_C32(0x867ec987) }, + { SPH_C32(0x405b0030), SPH_C32(0x9a540000), SPH_C32(0x42670000), + SPH_C32(0x5fb10000), SPH_C32(0xd6c06187), SPH_C32(0x5d81863c), + SPH_C32(0x87922fef), SPH_C32(0x79e0422c), SPH_C32(0xdf9801b0), + SPH_C32(0xf67c0000), SPH_C32(0xa50e0000), SPH_C32(0xbf870000), + SPH_C32(0xad7f742c), SPH_C32(0xae2b8f5a), SPH_C32(0xc2a957e9), + SPH_C32(0xd75f2456) }, + { SPH_C32(0xb72e0039), SPH_C32(0x5568c000), SPH_C32(0x81b10000), + SPH_C32(0x5b230000), SPH_C32(0xd455782e), SPH_C32(0xa569b086), + SPH_C32(0xfd15dea1), SPH_C32(0xe7f6da36), SPH_C32(0x0bf201b0), + SPH_C32(0x7bb4c000), SPH_C32(0x00a10000), SPH_C32(0xf5ae0000), + SPH_C32(0x51313656), SPH_C32(0x679f0936), SPH_C32(0x5a9fc1ed), + SPH_C32(0x2019e776) }, + { SPH_C32(0x94310030), SPH_C32(0x179cc000), SPH_C32(0xe7c80000), + SPH_C32(0x15980000), SPH_C32(0x2a8e23fd), SPH_C32(0x94350050), + SPH_C32(0x1fa4b9eb), SPH_C32(0x8ea6810c), SPH_C32(0xfc8701b9), + SPH_C32(0xb4880000), SPH_C32(0xc3770000), SPH_C32(0xf13c0000), + SPH_C32(0x53a42fff), SPH_C32(0x9f773f8c), SPH_C32(0x201830a3), + SPH_C32(0xbe0f7f6c) }, + { SPH_C32(0x63440039), SPH_C32(0xd8a00000), SPH_C32(0x241e0000), + SPH_C32(0x110a0000), SPH_C32(0x281b3a54), SPH_C32(0x6cdd36ea), + SPH_C32(0x652348a5), SPH_C32(0x10b01916), SPH_C32(0x28ed01b9), + SPH_C32(0x3940c000), SPH_C32(0x66d80000), SPH_C32(0xbb150000), + SPH_C32(0xafea6d85), SPH_C32(0x56c3b9e0), SPH_C32(0xb82ea6a7), + SPH_C32(0x4949bc4c) }, + { SPH_C32(0x371f00c0), SPH_C32(0x6b0e0000), SPH_C32(0xb7d50000), + SPH_C32(0x6ba50000), SPH_C32(0x5ff71f0b), SPH_C32(0x070a6a19), + SPH_C32(0x8c51e2f1), SPH_C32(0xb6d737e7), SPH_C32(0x2bf401e0), + SPH_C32(0x60640000), SPH_C32(0xb1ab0000), SPH_C32(0xbc980000), + SPH_C32(0xefeb0a94), SPH_C32(0xc894f143), SPH_C32(0x5e0d273b), + SPH_C32(0x5d6b3122) }, + { SPH_C32(0xc06a00c9), SPH_C32(0xa432c000), SPH_C32(0x74030000), + SPH_C32(0x6f370000), SPH_C32(0x5d6206a2), SPH_C32(0xffe25ca3), + SPH_C32(0xf6d613bf), SPH_C32(0x28c1affd), SPH_C32(0xff9e01e0), + SPH_C32(0xedacc000), SPH_C32(0x14040000), SPH_C32(0xf6b10000), + SPH_C32(0x13a548ee), SPH_C32(0x0120772f), SPH_C32(0xc63bb13f), + SPH_C32(0xaa2df202) }, + { SPH_C32(0xe37500c0), SPH_C32(0xe6c6c000), SPH_C32(0x127a0000), + SPH_C32(0x218c0000), SPH_C32(0xa3b95d71), SPH_C32(0xcebeec75), + SPH_C32(0x146774f5), SPH_C32(0x4191f4c7), SPH_C32(0x08eb01e9), + SPH_C32(0x22900000), SPH_C32(0xd7d20000), SPH_C32(0xf2230000), + SPH_C32(0x11305147), SPH_C32(0xf9c84195), SPH_C32(0xbcbc4071), + SPH_C32(0x343b6a18) }, + { SPH_C32(0x140000c9), SPH_C32(0x29fa0000), SPH_C32(0xd1ac0000), + SPH_C32(0x251e0000), SPH_C32(0xa12c44d8), SPH_C32(0x3656dacf), + SPH_C32(0x6ee085bb), SPH_C32(0xdf876cdd), SPH_C32(0xdc8101e9), + SPH_C32(0xaf58c000), SPH_C32(0x727d0000), SPH_C32(0xb80a0000), + SPH_C32(0xed7e133d), SPH_C32(0x307cc7f9), SPH_C32(0x248ad675), + SPH_C32(0xc37da938) }, + { SPH_C32(0x5cb00110), SPH_C32(0x913e0000), SPH_C32(0x44190000), + SPH_C32(0x888c0000), SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), + SPH_C32(0x55ceea25), SPH_C32(0x925c44e9), SPH_C32(0xe8870170), + SPH_C32(0x9d720000), SPH_C32(0x12db0000), SPH_C32(0xd4220000), + SPH_C32(0xf2886b27), SPH_C32(0xa921e543), SPH_C32(0x4ef8b518), + SPH_C32(0x618813b1) }, + { SPH_C32(0xabc50119), SPH_C32(0x5e02c000), SPH_C32(0x87cf0000), + SPH_C32(0x8c1e0000), SPH_C32(0x64496db1), SPH_C32(0x6af72bdc), + SPH_C32(0x2f491b6b), SPH_C32(0x0c4adcf3), SPH_C32(0x3ced0170), + SPH_C32(0x10bac000), SPH_C32(0xb7740000), SPH_C32(0x9e0b0000), + SPH_C32(0x0ec6295d), SPH_C32(0x6095632f), SPH_C32(0xd6ce231c), + SPH_C32(0x96ced091) }, + { SPH_C32(0x88da0110), SPH_C32(0x1cf6c000), SPH_C32(0xe1b60000), + SPH_C32(0xc2a50000), SPH_C32(0x9a923662), SPH_C32(0x5bab9b0a), + SPH_C32(0xcdf87c21), SPH_C32(0x651a87c9), SPH_C32(0xcb980179), + SPH_C32(0xdf860000), SPH_C32(0x74a20000), SPH_C32(0x9a990000), + SPH_C32(0x0c5330f4), SPH_C32(0x987d5595), SPH_C32(0xac49d252), + SPH_C32(0x08d8488b) }, + { SPH_C32(0x7faf0119), SPH_C32(0xd3ca0000), SPH_C32(0x22600000), + SPH_C32(0xc6370000), SPH_C32(0x98072fcb), SPH_C32(0xa343adb0), + SPH_C32(0xb77f8d6f), SPH_C32(0xfb0c1fd3), SPH_C32(0x1ff20179), + SPH_C32(0x524ec000), SPH_C32(0xd10d0000), SPH_C32(0xd0b00000), + SPH_C32(0xf01d728e), SPH_C32(0x51c9d3f9), SPH_C32(0x347f4456), + SPH_C32(0xff9e8bab) }, + { SPH_C32(0x2bf401e0), SPH_C32(0x60640000), SPH_C32(0xb1ab0000), + SPH_C32(0xbc980000), SPH_C32(0xefeb0a94), SPH_C32(0xc894f143), + SPH_C32(0x5e0d273b), SPH_C32(0x5d6b3122), SPH_C32(0x1ceb0120), + SPH_C32(0x0b6a0000), SPH_C32(0x067e0000), SPH_C32(0xd73d0000), + SPH_C32(0xb01c159f), SPH_C32(0xcf9e9b5a), SPH_C32(0xd25cc5ca), + SPH_C32(0xebbc06c5) }, + { SPH_C32(0xdc8101e9), SPH_C32(0xaf58c000), SPH_C32(0x727d0000), + SPH_C32(0xb80a0000), SPH_C32(0xed7e133d), SPH_C32(0x307cc7f9), + SPH_C32(0x248ad675), SPH_C32(0xc37da938), SPH_C32(0xc8810120), + SPH_C32(0x86a2c000), SPH_C32(0xa3d10000), SPH_C32(0x9d140000), + SPH_C32(0x4c5257e5), SPH_C32(0x062a1d36), SPH_C32(0x4a6a53ce), + SPH_C32(0x1cfac5e5) }, + { SPH_C32(0xff9e01e0), SPH_C32(0xedacc000), SPH_C32(0x14040000), + SPH_C32(0xf6b10000), SPH_C32(0x13a548ee), SPH_C32(0x0120772f), + SPH_C32(0xc63bb13f), SPH_C32(0xaa2df202), SPH_C32(0x3ff40129), + SPH_C32(0x499e0000), SPH_C32(0x60070000), SPH_C32(0x99860000), + SPH_C32(0x4ec74e4c), SPH_C32(0xfec22b8c), SPH_C32(0x30eda280), + SPH_C32(0x82ec5dff) }, + { SPH_C32(0x08eb01e9), SPH_C32(0x22900000), SPH_C32(0xd7d20000), + SPH_C32(0xf2230000), SPH_C32(0x11305147), SPH_C32(0xf9c84195), + SPH_C32(0xbcbc4071), SPH_C32(0x343b6a18), SPH_C32(0xeb9e0129), + SPH_C32(0xc456c000), SPH_C32(0xc5a80000), SPH_C32(0xd3af0000), + SPH_C32(0xb2890c36), SPH_C32(0x3776ade0), SPH_C32(0xa8db3484), + SPH_C32(0x75aa9edf) }, + { SPH_C32(0xa8dc0140), SPH_C32(0x07260000), SPH_C32(0x50bc0000), + SPH_C32(0x8b930000), SPH_C32(0x24480aa0), SPH_C32(0xf4a0637f), + SPH_C32(0xc96a9af7), SPH_C32(0x1868519d), SPH_C32(0x6baf01d0), + SPH_C32(0xfa300000), SPH_C32(0xf3cc0000), SPH_C32(0xe3290000), + SPH_C32(0x392b6b13), SPH_C32(0x9515777f), SPH_C32(0xd99f08d4), + SPH_C32(0x248b730e) }, + { SPH_C32(0x5fa90149), SPH_C32(0xc81ac000), SPH_C32(0x936a0000), + SPH_C32(0x8f010000), SPH_C32(0x26dd1309), SPH_C32(0x0c4855c5), + SPH_C32(0xb3ed6bb9), SPH_C32(0x867ec987), SPH_C32(0xbfc501d0), + SPH_C32(0x77f8c000), SPH_C32(0x56630000), SPH_C32(0xa9000000), + SPH_C32(0xc5652969), SPH_C32(0x5ca1f113), SPH_C32(0x41a99ed0), + SPH_C32(0xd3cdb02e) }, + { SPH_C32(0x7cb60140), SPH_C32(0x8aeec000), SPH_C32(0xf5130000), + SPH_C32(0xc1ba0000), SPH_C32(0xd80648da), SPH_C32(0x3d14e513), + SPH_C32(0x515c0cf3), SPH_C32(0xef2e92bd), SPH_C32(0x48b001d9), + SPH_C32(0xb8c40000), SPH_C32(0x95b50000), SPH_C32(0xad920000), + SPH_C32(0xc7f030c0), SPH_C32(0xa449c7a9), SPH_C32(0x3b2e6f9e), + SPH_C32(0x4ddb2834) }, + { SPH_C32(0x8bc30149), SPH_C32(0x45d20000), SPH_C32(0x36c50000), + SPH_C32(0xc5280000), SPH_C32(0xda935173), SPH_C32(0xc5fcd3a9), + SPH_C32(0x2bdbfdbd), SPH_C32(0x71380aa7), SPH_C32(0x9cda01d9), + SPH_C32(0x350cc000), SPH_C32(0x301a0000), SPH_C32(0xe7bb0000), + SPH_C32(0x3bbe72ba), SPH_C32(0x6dfd41c5), SPH_C32(0xa318f99a), + SPH_C32(0xba9deb14) }, + { SPH_C32(0xdf9801b0), SPH_C32(0xf67c0000), SPH_C32(0xa50e0000), + SPH_C32(0xbf870000), SPH_C32(0xad7f742c), SPH_C32(0xae2b8f5a), + SPH_C32(0xc2a957e9), SPH_C32(0xd75f2456), SPH_C32(0x9fc30180), + SPH_C32(0x6c280000), SPH_C32(0xe7690000), SPH_C32(0xe0360000), + SPH_C32(0x7bbf15ab), SPH_C32(0xf3aa0966), SPH_C32(0x453b7806), + SPH_C32(0xaebf667a) }, + { SPH_C32(0x28ed01b9), SPH_C32(0x3940c000), SPH_C32(0x66d80000), + SPH_C32(0xbb150000), SPH_C32(0xafea6d85), SPH_C32(0x56c3b9e0), + SPH_C32(0xb82ea6a7), SPH_C32(0x4949bc4c), SPH_C32(0x4ba90180), + SPH_C32(0xe1e0c000), SPH_C32(0x42c60000), SPH_C32(0xaa1f0000), + SPH_C32(0x87f157d1), SPH_C32(0x3a1e8f0a), SPH_C32(0xdd0dee02), + SPH_C32(0x59f9a55a) }, + { SPH_C32(0x0bf201b0), SPH_C32(0x7bb4c000), SPH_C32(0x00a10000), + SPH_C32(0xf5ae0000), SPH_C32(0x51313656), SPH_C32(0x679f0936), + SPH_C32(0x5a9fc1ed), SPH_C32(0x2019e776), SPH_C32(0xbcdc0189), + SPH_C32(0x2edc0000), SPH_C32(0x81100000), SPH_C32(0xae8d0000), + SPH_C32(0x85644e78), SPH_C32(0xc2f6b9b0), SPH_C32(0xa78a1f4c), + SPH_C32(0xc7ef3d40) }, + { SPH_C32(0xfc8701b9), SPH_C32(0xb4880000), SPH_C32(0xc3770000), + SPH_C32(0xf13c0000), SPH_C32(0x53a42fff), SPH_C32(0x9f773f8c), + SPH_C32(0x201830a3), SPH_C32(0xbe0f7f6c), SPH_C32(0x68b60189), + SPH_C32(0xa314c000), SPH_C32(0x24bf0000), SPH_C32(0xe4a40000), + SPH_C32(0x792a0c02), SPH_C32(0x0b423fdc), SPH_C32(0x3fbc8948), + SPH_C32(0x30a9fe60) }, + { SPH_C32(0xef0b0270), SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), + SPH_C32(0x69490000), SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), + SPH_C32(0x66140a51), SPH_C32(0x924f5d0a), SPH_C32(0xc96b0030), + SPH_C32(0xe7250000), SPH_C32(0x2f840000), SPH_C32(0x264f0000), + SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), SPH_C32(0x509f6984), + SPH_C32(0x9e69af68) }, + { SPH_C32(0x187e0279), SPH_C32(0xf5c1c000), SPH_C32(0x9e780000), + SPH_C32(0x6ddb0000), SPH_C32(0x999a25af), SPH_C32(0xbced8343), + SPH_C32(0x1c93fb1f), SPH_C32(0x0c59c510), SPH_C32(0x1d010030), + SPH_C32(0x6aedc000), SPH_C32(0x8a2b0000), SPH_C32(0x6c660000), + SPH_C32(0xf4271983), SPH_C32(0xa448775b), SPH_C32(0xc8a9ff80), + SPH_C32(0x692f6c48) }, + { SPH_C32(0x3b610270), SPH_C32(0xb735c000), SPH_C32(0xf8010000), + SPH_C32(0x23600000), SPH_C32(0x67417e7c), SPH_C32(0x8db13395), + SPH_C32(0xfe229c55), SPH_C32(0x65099e2a), SPH_C32(0xea740039), + SPH_C32(0xa5d10000), SPH_C32(0x49fd0000), SPH_C32(0x68f40000), + SPH_C32(0xf6b2002a), SPH_C32(0x5ca041e1), SPH_C32(0xb22e0ece), + SPH_C32(0xf739f452) }, + { SPH_C32(0xcc140279), SPH_C32(0x78090000), SPH_C32(0x3bd70000), + SPH_C32(0x27f20000), SPH_C32(0x65d467d5), SPH_C32(0x7559052f), + SPH_C32(0x84a56d1b), SPH_C32(0xfb1f0630), SPH_C32(0x3e1e0039), + SPH_C32(0x2819c000), SPH_C32(0xec520000), SPH_C32(0x22dd0000), + SPH_C32(0x0afc4250), SPH_C32(0x9514c78d), SPH_C32(0x2a1898ca), + SPH_C32(0x007f3772) }, + { SPH_C32(0x984f0280), SPH_C32(0xcba70000), SPH_C32(0xa81c0000), + SPH_C32(0x5d5d0000), SPH_C32(0x1238428a), SPH_C32(0x1e8e59dc), + SPH_C32(0x6dd7c74f), SPH_C32(0x5d7828c1), SPH_C32(0x3d070060), + SPH_C32(0x713d0000), SPH_C32(0x3b210000), SPH_C32(0x25500000), + SPH_C32(0x4afd2541), SPH_C32(0x0b438f2e), SPH_C32(0xcc3b1956), + SPH_C32(0x145dba1c) }, + { SPH_C32(0x6f3a0289), SPH_C32(0x049bc000), SPH_C32(0x6bca0000), + SPH_C32(0x59cf0000), SPH_C32(0x10ad5b23), SPH_C32(0xe6666f66), + SPH_C32(0x17503601), SPH_C32(0xc36eb0db), SPH_C32(0xe96d0060), + SPH_C32(0xfcf5c000), SPH_C32(0x9e8e0000), SPH_C32(0x6f790000), + SPH_C32(0xb6b3673b), SPH_C32(0xc2f70942), SPH_C32(0x540d8f52), + SPH_C32(0xe31b793c) }, + { SPH_C32(0x4c250280), SPH_C32(0x466fc000), SPH_C32(0x0db30000), + SPH_C32(0x17740000), SPH_C32(0xee7600f0), SPH_C32(0xd73adfb0), + SPH_C32(0xf5e1514b), SPH_C32(0xaa3eebe1), SPH_C32(0x1e180069), + SPH_C32(0x33c90000), SPH_C32(0x5d580000), SPH_C32(0x6beb0000), + SPH_C32(0xb4267e92), SPH_C32(0x3a1f3ff8), SPH_C32(0x2e8a7e1c), + SPH_C32(0x7d0de126) }, + { SPH_C32(0xbb500289), SPH_C32(0x89530000), SPH_C32(0xce650000), + SPH_C32(0x13e60000), SPH_C32(0xece31959), SPH_C32(0x2fd2e90a), + SPH_C32(0x8f66a005), SPH_C32(0x342873fb), SPH_C32(0xca720069), + SPH_C32(0xbe01c000), SPH_C32(0xf8f70000), SPH_C32(0x21c20000), + SPH_C32(0x48683ce8), SPH_C32(0xf3abb994), SPH_C32(0xb6bce818), + SPH_C32(0x8a4b2206) }, + { SPH_C32(0x1b670220), SPH_C32(0xace50000), SPH_C32(0x490b0000), + SPH_C32(0x6a560000), SPH_C32(0xd99b42be), SPH_C32(0x22bacbe0), + SPH_C32(0xfab07a83), SPH_C32(0x187b487e), SPH_C32(0x4a430090), + SPH_C32(0x80670000), SPH_C32(0xce930000), SPH_C32(0x11440000), + SPH_C32(0xc3ca5bcd), SPH_C32(0x51c8630b), SPH_C32(0xc7f8d448), + SPH_C32(0xdb6acfd7) }, + { SPH_C32(0xec120229), SPH_C32(0x63d9c000), SPH_C32(0x8add0000), + SPH_C32(0x6ec40000), SPH_C32(0xdb0e5b17), SPH_C32(0xda52fd5a), + SPH_C32(0x80378bcd), SPH_C32(0x866dd064), SPH_C32(0x9e290090), + SPH_C32(0x0dafc000), SPH_C32(0x6b3c0000), SPH_C32(0x5b6d0000), + SPH_C32(0x3f8419b7), SPH_C32(0x987ce567), SPH_C32(0x5fce424c), + SPH_C32(0x2c2c0cf7) }, + { SPH_C32(0xcf0d0220), SPH_C32(0x212dc000), SPH_C32(0xeca40000), + SPH_C32(0x207f0000), SPH_C32(0x25d500c4), SPH_C32(0xeb0e4d8c), + SPH_C32(0x6286ec87), SPH_C32(0xef3d8b5e), SPH_C32(0x695c0099), + SPH_C32(0xc2930000), SPH_C32(0xa8ea0000), SPH_C32(0x5fff0000), + SPH_C32(0x3d11001e), SPH_C32(0x6094d3dd), SPH_C32(0x2549b302), + SPH_C32(0xb23a94ed) }, + { SPH_C32(0x38780229), SPH_C32(0xee110000), SPH_C32(0x2f720000), + SPH_C32(0x24ed0000), SPH_C32(0x2740196d), SPH_C32(0x13e67b36), + SPH_C32(0x18011dc9), SPH_C32(0x712b1344), SPH_C32(0xbd360099), + SPH_C32(0x4f5bc000), SPH_C32(0x0d450000), SPH_C32(0x15d60000), + SPH_C32(0xc15f4264), SPH_C32(0xa92055b1), SPH_C32(0xbd7f2506), + SPH_C32(0x457c57cd) }, + { SPH_C32(0x6c2302d0), SPH_C32(0x5dbf0000), SPH_C32(0xbcb90000), + SPH_C32(0x5e420000), SPH_C32(0x50ac3c32), SPH_C32(0x783127c5), + SPH_C32(0xf173b79d), SPH_C32(0xd74c3db5), SPH_C32(0xbe2f00c0), + SPH_C32(0x167f0000), SPH_C32(0xda360000), SPH_C32(0x125b0000), + SPH_C32(0x815e2575), SPH_C32(0x37771d12), SPH_C32(0x5b5ca49a), + SPH_C32(0x515edaa3) }, + { SPH_C32(0x9b5602d9), SPH_C32(0x9283c000), SPH_C32(0x7f6f0000), + SPH_C32(0x5ad00000), SPH_C32(0x5239259b), SPH_C32(0x80d9117f), + SPH_C32(0x8bf446d3), SPH_C32(0x495aa5af), SPH_C32(0x6a4500c0), + SPH_C32(0x9bb7c000), SPH_C32(0x7f990000), SPH_C32(0x58720000), + SPH_C32(0x7d10670f), SPH_C32(0xfec39b7e), SPH_C32(0xc36a329e), + SPH_C32(0xa6181983) }, + { SPH_C32(0xb84902d0), SPH_C32(0xd077c000), SPH_C32(0x19160000), + SPH_C32(0x146b0000), SPH_C32(0xace27e48), SPH_C32(0xb185a1a9), + SPH_C32(0x69452199), SPH_C32(0x200afe95), SPH_C32(0x9d3000c9), + SPH_C32(0x548b0000), SPH_C32(0xbc4f0000), SPH_C32(0x5ce00000), + SPH_C32(0x7f857ea6), SPH_C32(0x062badc4), SPH_C32(0xb9edc3d0), + SPH_C32(0x380e8199) }, + { SPH_C32(0x4f3c02d9), SPH_C32(0x1f4b0000), SPH_C32(0xdac00000), + SPH_C32(0x10f90000), SPH_C32(0xae7767e1), SPH_C32(0x496d9713), + SPH_C32(0x13c2d0d7), SPH_C32(0xbe1c668f), SPH_C32(0x495a00c9), + SPH_C32(0xd943c000), SPH_C32(0x19e00000), SPH_C32(0x16c90000), + SPH_C32(0x83cb3cdc), SPH_C32(0xcf9f2ba8), SPH_C32(0x21db55d4), + SPH_C32(0xcf4842b9) }, + { SPH_C32(0x078c0300), SPH_C32(0xa78f0000), SPH_C32(0x4f750000), + SPH_C32(0xbd6b0000), SPH_C32(0x69875721), SPH_C32(0xed2450ba), + SPH_C32(0x28ecbf49), SPH_C32(0xf3c74ebb), SPH_C32(0x7d5c0050), + SPH_C32(0xeb690000), SPH_C32(0x79460000), SPH_C32(0x7ae10000), + SPH_C32(0x9c3d44c6), SPH_C32(0x56c20912), SPH_C32(0x4ba936b9), + SPH_C32(0x6dbdf830) }, + { SPH_C32(0xf0f90309), SPH_C32(0x68b3c000), SPH_C32(0x8ca30000), + SPH_C32(0xb9f90000), SPH_C32(0x6b124e88), SPH_C32(0x15cc6600), + SPH_C32(0x526b4e07), SPH_C32(0x6dd1d6a1), SPH_C32(0xa9360050), + SPH_C32(0x66a1c000), SPH_C32(0xdce90000), SPH_C32(0x30c80000), + SPH_C32(0x607306bc), SPH_C32(0x9f768f7e), SPH_C32(0xd39fa0bd), + SPH_C32(0x9afb3b10) }, + { SPH_C32(0xd3e60300), SPH_C32(0x2a47c000), SPH_C32(0xeada0000), + SPH_C32(0xf7420000), SPH_C32(0x95c9155b), SPH_C32(0x2490d6d6), + SPH_C32(0xb0da294d), SPH_C32(0x04818d9b), SPH_C32(0x5e430059), + SPH_C32(0xa99d0000), SPH_C32(0x1f3f0000), SPH_C32(0x345a0000), + SPH_C32(0x62e61f15), SPH_C32(0x679eb9c4), SPH_C32(0xa91851f3), + SPH_C32(0x04eda30a) }, + { SPH_C32(0x24930309), SPH_C32(0xe57b0000), SPH_C32(0x290c0000), + SPH_C32(0xf3d00000), SPH_C32(0x975c0cf2), SPH_C32(0xdc78e06c), + SPH_C32(0xca5dd803), SPH_C32(0x9a971581), SPH_C32(0x8a290059), + SPH_C32(0x2455c000), SPH_C32(0xba900000), SPH_C32(0x7e730000), + SPH_C32(0x9ea85d6f), SPH_C32(0xae2a3fa8), SPH_C32(0x312ec7f7), + SPH_C32(0xf3ab602a) }, + { SPH_C32(0x70c803f0), SPH_C32(0x56d50000), SPH_C32(0xbac70000), + SPH_C32(0x897f0000), SPH_C32(0xe0b029ad), SPH_C32(0xb7afbc9f), + SPH_C32(0x232f7257), SPH_C32(0x3cf03b70), SPH_C32(0x89300000), + SPH_C32(0x7d710000), SPH_C32(0x6de30000), SPH_C32(0x79fe0000), + SPH_C32(0xdea93a7e), SPH_C32(0x307d770b), SPH_C32(0xd70d466b), + SPH_C32(0xe789ed44) }, + { SPH_C32(0x87bd03f9), SPH_C32(0x99e9c000), SPH_C32(0x79110000), + SPH_C32(0x8ded0000), SPH_C32(0xe2253004), SPH_C32(0x4f478a25), + SPH_C32(0x59a88319), SPH_C32(0xa2e6a36a), SPH_C32(0x5d5a0000), + SPH_C32(0xf0b9c000), SPH_C32(0xc84c0000), SPH_C32(0x33d70000), + SPH_C32(0x22e77804), SPH_C32(0xf9c9f167), SPH_C32(0x4f3bd06f), + SPH_C32(0x10cf2e64) }, + { SPH_C32(0xa4a203f0), SPH_C32(0xdb1dc000), SPH_C32(0x1f680000), + SPH_C32(0xc3560000), SPH_C32(0x1cfe6bd7), SPH_C32(0x7e1b3af3), + SPH_C32(0xbb19e453), SPH_C32(0xcbb6f850), SPH_C32(0xaa2f0009), + SPH_C32(0x3f850000), SPH_C32(0x0b9a0000), SPH_C32(0x37450000), + SPH_C32(0x207261ad), SPH_C32(0x0121c7dd), SPH_C32(0x35bc2121), + SPH_C32(0x8ed9b67e) }, + { SPH_C32(0x53d703f9), SPH_C32(0x14210000), SPH_C32(0xdcbe0000), + SPH_C32(0xc7c40000), SPH_C32(0x1e6b727e), SPH_C32(0x86f30c49), + SPH_C32(0xc19e151d), SPH_C32(0x55a0604a), SPH_C32(0x7e450009), + SPH_C32(0xb24dc000), SPH_C32(0xae350000), SPH_C32(0x7d6c0000), + SPH_C32(0xdc3c23d7), SPH_C32(0xc89541b1), SPH_C32(0xad8ab725), + SPH_C32(0x799f755e) }, + { SPH_C32(0xf3e00350), SPH_C32(0x31970000), SPH_C32(0x5bd00000), + SPH_C32(0xbe740000), SPH_C32(0x2b132999), SPH_C32(0x8b9b2ea3), + SPH_C32(0xb448cf9b), SPH_C32(0x79f35bcf), SPH_C32(0xfe7400f0), + SPH_C32(0x8c2b0000), SPH_C32(0x98510000), SPH_C32(0x4dea0000), + SPH_C32(0x579e44f2), SPH_C32(0x6af69b2e), SPH_C32(0xdcce8b75), + SPH_C32(0x28be988f) }, + { SPH_C32(0x04950359), SPH_C32(0xfeabc000), SPH_C32(0x98060000), + SPH_C32(0xbae60000), SPH_C32(0x29863030), SPH_C32(0x73731819), + SPH_C32(0xcecf3ed5), SPH_C32(0xe7e5c3d5), SPH_C32(0x2a1e00f0), + SPH_C32(0x01e3c000), SPH_C32(0x3dfe0000), SPH_C32(0x07c30000), + SPH_C32(0xabd00688), SPH_C32(0xa3421d42), SPH_C32(0x44f81d71), + SPH_C32(0xdff85baf) }, + { SPH_C32(0x278a0350), SPH_C32(0xbc5fc000), SPH_C32(0xfe7f0000), + SPH_C32(0xf45d0000), SPH_C32(0xd75d6be3), SPH_C32(0x422fa8cf), + SPH_C32(0x2c7e599f), SPH_C32(0x8eb598ef), SPH_C32(0xdd6b00f9), + SPH_C32(0xcedf0000), SPH_C32(0xfe280000), SPH_C32(0x03510000), + SPH_C32(0xa9451f21), SPH_C32(0x5baa2bf8), SPH_C32(0x3e7fec3f), + SPH_C32(0x41eec3b5) }, + { SPH_C32(0xd0ff0359), SPH_C32(0x73630000), SPH_C32(0x3da90000), + SPH_C32(0xf0cf0000), SPH_C32(0xd5c8724a), SPH_C32(0xbac79e75), + SPH_C32(0x56f9a8d1), SPH_C32(0x10a300f5), SPH_C32(0x090100f9), + SPH_C32(0x4317c000), SPH_C32(0x5b870000), SPH_C32(0x49780000), + SPH_C32(0x550b5d5b), SPH_C32(0x921ead94), SPH_C32(0xa6497a3b), + SPH_C32(0xb6a80095) }, + { SPH_C32(0x84a403a0), SPH_C32(0xc0cd0000), SPH_C32(0xae620000), + SPH_C32(0x8a600000), SPH_C32(0xa2245715), SPH_C32(0xd110c286), + SPH_C32(0xbf8b0285), SPH_C32(0xb6c42e04), SPH_C32(0x0a1800a0), + SPH_C32(0x1a330000), SPH_C32(0x8cf40000), SPH_C32(0x4ef50000), + SPH_C32(0x150a3a4a), SPH_C32(0x0c49e537), SPH_C32(0x406afba7), + SPH_C32(0xa28a8dfb) }, + { SPH_C32(0x73d103a9), SPH_C32(0x0ff1c000), SPH_C32(0x6db40000), + SPH_C32(0x8ef20000), SPH_C32(0xa0b14ebc), SPH_C32(0x29f8f43c), + SPH_C32(0xc50cf3cb), SPH_C32(0x28d2b61e), SPH_C32(0xde7200a0), + SPH_C32(0x97fbc000), SPH_C32(0x295b0000), SPH_C32(0x04dc0000), + SPH_C32(0xe9447830), SPH_C32(0xc5fd635b), SPH_C32(0xd85c6da3), + SPH_C32(0x55cc4edb) }, + { SPH_C32(0x50ce03a0), SPH_C32(0x4d05c000), SPH_C32(0x0bcd0000), + SPH_C32(0xc0490000), SPH_C32(0x5e6a156f), SPH_C32(0x18a444ea), + SPH_C32(0x27bd9481), SPH_C32(0x4182ed24), SPH_C32(0x290700a9), + SPH_C32(0x58c70000), SPH_C32(0xea8d0000), SPH_C32(0x004e0000), + SPH_C32(0xebd16199), SPH_C32(0x3d1555e1), SPH_C32(0xa2db9ced), + SPH_C32(0xcbdad6c1) }, + { SPH_C32(0xa7bb03a9), SPH_C32(0x82390000), SPH_C32(0xc81b0000), + SPH_C32(0xc4db0000), SPH_C32(0x5cff0cc6), SPH_C32(0xe04c7250), + SPH_C32(0x5d3a65cf), SPH_C32(0xdf94753e), SPH_C32(0xfd6d00a9), + SPH_C32(0xd50fc000), SPH_C32(0x4f220000), SPH_C32(0x4a670000), + SPH_C32(0x179f23e3), SPH_C32(0xf4a1d38d), SPH_C32(0x3aed0ae9), + SPH_C32(0x3c9c15e1) }, + { SPH_C32(0x5b3c0210), SPH_C32(0x36b10000), SPH_C32(0x0b6c0000), + SPH_C32(0x35e70000), SPH_C32(0x0f5b2339), SPH_C32(0x7f3b4ddc), + SPH_C32(0x7d22556c), SPH_C32(0x619b0a52), SPH_C32(0x95db0120), + SPH_C32(0x761b0000), SPH_C32(0x6b9d0000), SPH_C32(0xaec30000), + SPH_C32(0x6eb52fe1), SPH_C32(0xffe3ec51), SPH_C32(0x055183a1), + SPH_C32(0x0c35eb81) }, + { SPH_C32(0xac490219), SPH_C32(0xf98dc000), SPH_C32(0xc8ba0000), + SPH_C32(0x31750000), SPH_C32(0x0dce3a90), SPH_C32(0x87d37b66), + SPH_C32(0x07a5a422), SPH_C32(0xff8d9248), SPH_C32(0x41b10120), + SPH_C32(0xfbd3c000), SPH_C32(0xce320000), SPH_C32(0xe4ea0000), + SPH_C32(0x92fb6d9b), SPH_C32(0x36576a3d), SPH_C32(0x9d6715a5), + SPH_C32(0xfb7328a1) }, + { SPH_C32(0x8f560210), SPH_C32(0xbb79c000), SPH_C32(0xaec30000), + SPH_C32(0x7fce0000), SPH_C32(0xf3156143), SPH_C32(0xb68fcbb0), + SPH_C32(0xe514c368), SPH_C32(0x96ddc972), SPH_C32(0xb6c40129), + SPH_C32(0x34ef0000), SPH_C32(0x0de40000), SPH_C32(0xe0780000), + SPH_C32(0x906e7432), SPH_C32(0xcebf5c87), SPH_C32(0xe7e0e4eb), + SPH_C32(0x6565b0bb) }, + { SPH_C32(0x78230219), SPH_C32(0x74450000), SPH_C32(0x6d150000), + SPH_C32(0x7b5c0000), SPH_C32(0xf18078ea), SPH_C32(0x4e67fd0a), + SPH_C32(0x9f933226), SPH_C32(0x08cb5168), SPH_C32(0x62ae0129), + SPH_C32(0xb927c000), SPH_C32(0xa84b0000), SPH_C32(0xaa510000), + SPH_C32(0x6c203648), SPH_C32(0x070bdaeb), SPH_C32(0x7fd672ef), + SPH_C32(0x9223739b) }, + { SPH_C32(0x2c7802e0), SPH_C32(0xc7eb0000), SPH_C32(0xfede0000), + SPH_C32(0x01f30000), SPH_C32(0x866c5db5), SPH_C32(0x25b0a1f9), + SPH_C32(0x76e19872), SPH_C32(0xaeac7f99), SPH_C32(0x61b70170), + SPH_C32(0xe0030000), SPH_C32(0x7f380000), SPH_C32(0xaddc0000), + SPH_C32(0x2c215159), SPH_C32(0x995c9248), SPH_C32(0x99f5f373), + SPH_C32(0x8601fef5) }, + { SPH_C32(0xdb0d02e9), SPH_C32(0x08d7c000), SPH_C32(0x3d080000), + SPH_C32(0x05610000), SPH_C32(0x84f9441c), SPH_C32(0xdd589743), + SPH_C32(0x0c66693c), SPH_C32(0x30bae783), SPH_C32(0xb5dd0170), + SPH_C32(0x6dcbc000), SPH_C32(0xda970000), SPH_C32(0xe7f50000), + SPH_C32(0xd06f1323), SPH_C32(0x50e81424), SPH_C32(0x01c36577), + SPH_C32(0x71473dd5) }, + { SPH_C32(0xf81202e0), SPH_C32(0x4a23c000), SPH_C32(0x5b710000), + SPH_C32(0x4bda0000), SPH_C32(0x7a221fcf), SPH_C32(0xec042795), + SPH_C32(0xeed70e76), SPH_C32(0x59eabcb9), SPH_C32(0x42a80179), + SPH_C32(0xa2f70000), SPH_C32(0x19410000), SPH_C32(0xe3670000), + SPH_C32(0xd2fa0a8a), SPH_C32(0xa800229e), SPH_C32(0x7b449439), + SPH_C32(0xef51a5cf) }, + { SPH_C32(0x0f6702e9), SPH_C32(0x851f0000), SPH_C32(0x98a70000), + SPH_C32(0x4f480000), SPH_C32(0x78b70666), SPH_C32(0x14ec112f), + SPH_C32(0x9450ff38), SPH_C32(0xc7fc24a3), SPH_C32(0x96c20179), + SPH_C32(0x2f3fc000), SPH_C32(0xbcee0000), SPH_C32(0xa94e0000), + SPH_C32(0x2eb448f0), SPH_C32(0x61b4a4f2), SPH_C32(0xe372023d), + SPH_C32(0x181766ef) }, + { SPH_C32(0xaf500240), SPH_C32(0xa0a90000), SPH_C32(0x1fc90000), + SPH_C32(0x36f80000), SPH_C32(0x4dcf5d81), SPH_C32(0x198433c5), + SPH_C32(0xe18625be), SPH_C32(0xebaf1f26), SPH_C32(0x16f30180), + SPH_C32(0x11590000), SPH_C32(0x8a8a0000), SPH_C32(0x99c80000), + SPH_C32(0xa5162fd5), SPH_C32(0xc3d77e6d), SPH_C32(0x92363e6d), + SPH_C32(0x49368b3e) }, + { SPH_C32(0x58250249), SPH_C32(0x6f95c000), SPH_C32(0xdc1f0000), + SPH_C32(0x326a0000), SPH_C32(0x4f5a4428), SPH_C32(0xe16c057f), + SPH_C32(0x9b01d4f0), SPH_C32(0x75b9873c), SPH_C32(0xc2990180), + SPH_C32(0x9c91c000), SPH_C32(0x2f250000), SPH_C32(0xd3e10000), + SPH_C32(0x59586daf), SPH_C32(0x0a63f801), SPH_C32(0x0a00a869), + SPH_C32(0xbe70481e) }, + { SPH_C32(0x7b3a0240), SPH_C32(0x2d61c000), SPH_C32(0xba660000), + SPH_C32(0x7cd10000), SPH_C32(0xb1811ffb), SPH_C32(0xd030b5a9), + SPH_C32(0x79b0b3ba), SPH_C32(0x1ce9dc06), SPH_C32(0x35ec0189), + SPH_C32(0x53ad0000), SPH_C32(0xecf30000), SPH_C32(0xd7730000), + SPH_C32(0x5bcd7406), SPH_C32(0xf28bcebb), SPH_C32(0x70875927), + SPH_C32(0x2066d004) }, + { SPH_C32(0x8c4f0249), SPH_C32(0xe25d0000), SPH_C32(0x79b00000), + SPH_C32(0x78430000), SPH_C32(0xb3140652), SPH_C32(0x28d88313), + SPH_C32(0x033742f4), SPH_C32(0x82ff441c), SPH_C32(0xe1860189), + SPH_C32(0xde65c000), SPH_C32(0x495c0000), SPH_C32(0x9d5a0000), + SPH_C32(0xa783367c), SPH_C32(0x3b3f48d7), SPH_C32(0xe8b1cf23), + SPH_C32(0xd7201324) }, + { SPH_C32(0xd81402b0), SPH_C32(0x51f30000), SPH_C32(0xea7b0000), + SPH_C32(0x02ec0000), SPH_C32(0xc4f8230d), SPH_C32(0x430fdfe0), + SPH_C32(0xea45e8a0), SPH_C32(0x24986aed), SPH_C32(0xe29f01d0), + SPH_C32(0x87410000), SPH_C32(0x9e2f0000), SPH_C32(0x9ad70000), + SPH_C32(0xe782516d), SPH_C32(0xa5680074), SPH_C32(0x0e924ebf), + SPH_C32(0xc3029e4a) }, + { SPH_C32(0x2f6102b9), SPH_C32(0x9ecfc000), SPH_C32(0x29ad0000), + SPH_C32(0x067e0000), SPH_C32(0xc66d3aa4), SPH_C32(0xbbe7e95a), + SPH_C32(0x90c219ee), SPH_C32(0xba8ef2f7), SPH_C32(0x36f501d0), + SPH_C32(0x0a89c000), SPH_C32(0x3b800000), SPH_C32(0xd0fe0000), + SPH_C32(0x1bcc1317), SPH_C32(0x6cdc8618), SPH_C32(0x96a4d8bb), + SPH_C32(0x34445d6a) }, + { SPH_C32(0x0c7e02b0), SPH_C32(0xdc3bc000), SPH_C32(0x4fd40000), + SPH_C32(0x48c50000), SPH_C32(0x38b66177), SPH_C32(0x8abb598c), + SPH_C32(0x72737ea4), SPH_C32(0xd3dea9cd), SPH_C32(0xc18001d9), + SPH_C32(0xc5b50000), SPH_C32(0xf8560000), SPH_C32(0xd46c0000), + SPH_C32(0x19590abe), SPH_C32(0x9434b0a2), SPH_C32(0xec2329f5), + SPH_C32(0xaa52c570) }, + { SPH_C32(0xfb0b02b9), SPH_C32(0x13070000), SPH_C32(0x8c020000), + SPH_C32(0x4c570000), SPH_C32(0x3a2378de), SPH_C32(0x72536f36), + SPH_C32(0x08f48fea), SPH_C32(0x4dc831d7), SPH_C32(0x15ea01d9), + SPH_C32(0x487dc000), SPH_C32(0x5df90000), SPH_C32(0x9e450000), + SPH_C32(0xe51748c4), SPH_C32(0x5d8036ce), SPH_C32(0x7415bff1), + SPH_C32(0x5d140650) }, + { SPH_C32(0xb3bb0360), SPH_C32(0xabc30000), SPH_C32(0x19b70000), + SPH_C32(0xe1c50000), SPH_C32(0xfdd3481e), SPH_C32(0xd61aa89f), + SPH_C32(0x33dae074), SPH_C32(0x001319e3), SPH_C32(0x21ec0140), + SPH_C32(0x7a570000), SPH_C32(0x3d5f0000), SPH_C32(0xf26d0000), + SPH_C32(0xfae130de), SPH_C32(0xc4dd1474), SPH_C32(0x1e67dc9c), + SPH_C32(0xffe1bcd9) }, + { SPH_C32(0x44ce0369), SPH_C32(0x64ffc000), SPH_C32(0xda610000), + SPH_C32(0xe5570000), SPH_C32(0xff4651b7), SPH_C32(0x2ef29e25), + SPH_C32(0x495d113a), SPH_C32(0x9e0581f9), SPH_C32(0xf5860140), + SPH_C32(0xf79fc000), SPH_C32(0x98f00000), SPH_C32(0xb8440000), + SPH_C32(0x06af72a4), SPH_C32(0x0d699218), SPH_C32(0x86514a98), + SPH_C32(0x08a77ff9) }, + { SPH_C32(0x67d10360), SPH_C32(0x260bc000), SPH_C32(0xbc180000), + SPH_C32(0xabec0000), SPH_C32(0x019d0a64), SPH_C32(0x1fae2ef3), + SPH_C32(0xabec7670), SPH_C32(0xf755dac3), SPH_C32(0x02f30149), + SPH_C32(0x38a30000), SPH_C32(0x5b260000), SPH_C32(0xbcd60000), + SPH_C32(0x043a6b0d), SPH_C32(0xf581a4a2), SPH_C32(0xfcd6bbd6), + SPH_C32(0x96b1e7e3) }, + { SPH_C32(0x90a40369), SPH_C32(0xe9370000), SPH_C32(0x7fce0000), + SPH_C32(0xaf7e0000), SPH_C32(0x030813cd), SPH_C32(0xe7461849), + SPH_C32(0xd16b873e), SPH_C32(0x694342d9), SPH_C32(0xd6990149), + SPH_C32(0xb56bc000), SPH_C32(0xfe890000), SPH_C32(0xf6ff0000), + SPH_C32(0xf8742977), SPH_C32(0x3c3522ce), SPH_C32(0x64e02dd2), + SPH_C32(0x61f724c3) }, + { SPH_C32(0xc4ff0390), SPH_C32(0x5a990000), SPH_C32(0xec050000), + SPH_C32(0xd5d10000), SPH_C32(0x74e43692), SPH_C32(0x8c9144ba), + SPH_C32(0x38192d6a), SPH_C32(0xcf246c28), SPH_C32(0xd5800110), + SPH_C32(0xec4f0000), SPH_C32(0x29fa0000), SPH_C32(0xf1720000), + SPH_C32(0xb8754e66), SPH_C32(0xa2626a6d), SPH_C32(0x82c3ac4e), + SPH_C32(0x75d5a9ad) }, + { SPH_C32(0x338a0399), SPH_C32(0x95a5c000), SPH_C32(0x2fd30000), + SPH_C32(0xd1430000), SPH_C32(0x76712f3b), SPH_C32(0x74797200), + SPH_C32(0x429edc24), SPH_C32(0x5132f432), SPH_C32(0x01ea0110), + SPH_C32(0x6187c000), SPH_C32(0x8c550000), SPH_C32(0xbb5b0000), + SPH_C32(0x443b0c1c), SPH_C32(0x6bd6ec01), SPH_C32(0x1af53a4a), + SPH_C32(0x82936a8d) }, + { SPH_C32(0x10950390), SPH_C32(0xd751c000), SPH_C32(0x49aa0000), + SPH_C32(0x9ff80000), SPH_C32(0x88aa74e8), SPH_C32(0x4525c2d6), + SPH_C32(0xa02fbb6e), SPH_C32(0x3862af08), SPH_C32(0xf69f0119), + SPH_C32(0xaebb0000), SPH_C32(0x4f830000), SPH_C32(0xbfc90000), + SPH_C32(0x46ae15b5), SPH_C32(0x933edabb), SPH_C32(0x6072cb04), + SPH_C32(0x1c85f297) }, + { SPH_C32(0xe7e00399), SPH_C32(0x186d0000), SPH_C32(0x8a7c0000), + SPH_C32(0x9b6a0000), SPH_C32(0x8a3f6d41), SPH_C32(0xbdcdf46c), + SPH_C32(0xdaa84a20), SPH_C32(0xa6743712), SPH_C32(0x22f50119), + SPH_C32(0x2373c000), SPH_C32(0xea2c0000), SPH_C32(0xf5e00000), + SPH_C32(0xbae057cf), SPH_C32(0x5a8a5cd7), SPH_C32(0xf8445d00), + SPH_C32(0xebc331b7) }, + { SPH_C32(0x47d70330), SPH_C32(0x3ddb0000), SPH_C32(0x0d120000), + SPH_C32(0xe2da0000), SPH_C32(0xbf4736a6), SPH_C32(0xb0a5d686), + SPH_C32(0xaf7e90a6), SPH_C32(0x8a270c97), SPH_C32(0xa2c401e0), + SPH_C32(0x1d150000), SPH_C32(0xdc480000), SPH_C32(0xc5660000), + SPH_C32(0x314230ea), SPH_C32(0xf8e98648), SPH_C32(0x89006150), + SPH_C32(0xbae2dc66) }, + { SPH_C32(0xb0a20339), SPH_C32(0xf2e7c000), SPH_C32(0xcec40000), + SPH_C32(0xe6480000), SPH_C32(0xbdd22f0f), SPH_C32(0x484de03c), + SPH_C32(0xd5f961e8), SPH_C32(0x1431948d), SPH_C32(0x76ae01e0), + SPH_C32(0x90ddc000), SPH_C32(0x79e70000), SPH_C32(0x8f4f0000), + SPH_C32(0xcd0c7290), SPH_C32(0x315d0024), SPH_C32(0x1136f754), + SPH_C32(0x4da41f46) }, + { SPH_C32(0x93bd0330), SPH_C32(0xb013c000), SPH_C32(0xa8bd0000), + SPH_C32(0xa8f30000), SPH_C32(0x430974dc), SPH_C32(0x791150ea), + SPH_C32(0x374806a2), SPH_C32(0x7d61cfb7), SPH_C32(0x81db01e9), + SPH_C32(0x5fe10000), SPH_C32(0xba310000), SPH_C32(0x8bdd0000), + SPH_C32(0xcf996b39), SPH_C32(0xc9b5369e), SPH_C32(0x6bb1061a), + SPH_C32(0xd3b2875c) }, + { SPH_C32(0x64c80339), SPH_C32(0x7f2f0000), SPH_C32(0x6b6b0000), + SPH_C32(0xac610000), SPH_C32(0x419c6d75), SPH_C32(0x81f96650), + SPH_C32(0x4dcff7ec), SPH_C32(0xe37757ad), SPH_C32(0x55b101e9), + SPH_C32(0xd229c000), SPH_C32(0x1f9e0000), SPH_C32(0xc1f40000), + SPH_C32(0x33d72943), SPH_C32(0x0001b0f2), SPH_C32(0xf387901e), + SPH_C32(0x24f4447c) }, + { SPH_C32(0x309303c0), SPH_C32(0xcc810000), SPH_C32(0xf8a00000), + SPH_C32(0xd6ce0000), SPH_C32(0x3670482a), SPH_C32(0xea2e3aa3), + SPH_C32(0xa4bd5db8), SPH_C32(0x4510795c), SPH_C32(0x56a801b0), + SPH_C32(0x8b0d0000), SPH_C32(0xc8ed0000), SPH_C32(0xc6790000), + SPH_C32(0x73d64e52), SPH_C32(0x9e56f851), SPH_C32(0x15a41182), + SPH_C32(0x30d6c912) }, + { SPH_C32(0xc7e603c9), SPH_C32(0x03bdc000), SPH_C32(0x3b760000), + SPH_C32(0xd25c0000), SPH_C32(0x34e55183), SPH_C32(0x12c60c19), + SPH_C32(0xde3aacf6), SPH_C32(0xdb06e146), SPH_C32(0x82c201b0), + SPH_C32(0x06c5c000), SPH_C32(0x6d420000), SPH_C32(0x8c500000), + SPH_C32(0x8f980c28), SPH_C32(0x57e27e3d), SPH_C32(0x8d928786), + SPH_C32(0xc7900a32) }, + { SPH_C32(0xe4f903c0), SPH_C32(0x4149c000), SPH_C32(0x5d0f0000), + SPH_C32(0x9ce70000), SPH_C32(0xca3e0a50), SPH_C32(0x239abccf), + SPH_C32(0x3c8bcbbc), SPH_C32(0xb256ba7c), SPH_C32(0x75b701b9), + SPH_C32(0xc9f90000), SPH_C32(0xae940000), SPH_C32(0x88c20000), + SPH_C32(0x8d0d1581), SPH_C32(0xaf0a4887), SPH_C32(0xf71576c8), + SPH_C32(0x59869228) }, + { SPH_C32(0x138c03c9), SPH_C32(0x8e750000), SPH_C32(0x9ed90000), + SPH_C32(0x98750000), SPH_C32(0xc8ab13f9), SPH_C32(0xdb728a75), + SPH_C32(0x460c3af2), SPH_C32(0x2c402266), SPH_C32(0xa1dd01b9), + SPH_C32(0x4431c000), SPH_C32(0x0b3b0000), SPH_C32(0xc2eb0000), + SPH_C32(0x714357fb), SPH_C32(0x66beceeb), SPH_C32(0x6f23e0cc), + SPH_C32(0xaec05108) } +}; + +static const sph_u32 T512_14[128][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xb83d0000), SPH_C32(0x16710600), SPH_C32(0x379a0000), + SPH_C32(0xf5b10000), SPH_C32(0x228161ac), SPH_C32(0xae48f145), + SPH_C32(0x66241616), SPH_C32(0xc5c1eb3e), SPH_C32(0xfd250000), + SPH_C32(0xb3c41100), SPH_C32(0xcef00000), SPH_C32(0xcef90000), + SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), SPH_C32(0x7098b0a6), + SPH_C32(0x1af21fe1) }, + { SPH_C32(0x75a40000), SPH_C32(0xc28b2700), SPH_C32(0x94a40000), + SPH_C32(0x90f50000), SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), + SPH_C32(0x1767c483), SPH_C32(0xaedf667e), SPH_C32(0xd1660000), + SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), SPH_C32(0xf6940000), + SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), SPH_C32(0xb4431b17), + SPH_C32(0x857f3c2b) }, + { SPH_C32(0xcd990000), SPH_C32(0xd4fa2100), SPH_C32(0xa33e0000), + SPH_C32(0x65440000), SPH_C32(0xd9f9364c), SPH_C32(0xe786faeb), + SPH_C32(0x7143d295), SPH_C32(0x6b1e8d40), SPH_C32(0x2c430000), + SPH_C32(0xa8781200), SPH_C32(0x501c0000), SPH_C32(0x386d0000), + SPH_C32(0x3f4f30a7), SPH_C32(0x422b9861), SPH_C32(0xc4dbabb1), + SPH_C32(0x9f8d23ca) }, + { SPH_C32(0xd1660000), SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), + SPH_C32(0xf6940000), SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), + SPH_C32(0xb4431b17), SPH_C32(0x857f3c2b), SPH_C32(0xa4c20000), + SPH_C32(0xd9372400), SPH_C32(0x0a480000), SPH_C32(0x66610000), + SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), SPH_C32(0xa324df94), + SPH_C32(0x2ba05a55) }, + { SPH_C32(0x695b0000), SPH_C32(0x0dcd0500), SPH_C32(0xa9760000), + SPH_C32(0x03250000), SPH_C32(0x2183248b), SPH_C32(0x61380db7), + SPH_C32(0xd2670d01), SPH_C32(0x40bed715), SPH_C32(0x59e70000), + SPH_C32(0x6af33500), SPH_C32(0xc4b80000), SPH_C32(0xa8980000), + SPH_C32(0xc4376747), SPH_C32(0x0be593cf), SPH_C32(0xd3bc6f32), + SPH_C32(0x315245b4) }, + { SPH_C32(0xa4c20000), SPH_C32(0xd9372400), SPH_C32(0x0a480000), + SPH_C32(0x66610000), SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), + SPH_C32(0xa324df94), SPH_C32(0x2ba05a55), SPH_C32(0x75a40000), + SPH_C32(0xc28b2700), SPH_C32(0x94a40000), SPH_C32(0x90f50000), + SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), SPH_C32(0x1767c483), + SPH_C32(0xaedf667e) }, + { SPH_C32(0x1cff0000), SPH_C32(0xcf462200), SPH_C32(0x3dd20000), + SPH_C32(0x93d00000), SPH_C32(0xdafb736b), SPH_C32(0x28f60619), + SPH_C32(0xc500c982), SPH_C32(0xee61b16b), SPH_C32(0x88810000), + SPH_C32(0x714f3600), SPH_C32(0x5a540000), SPH_C32(0x5e0c0000), + SPH_C32(0xc7352260), SPH_C32(0xc4956f3d), SPH_C32(0x67ff7425), + SPH_C32(0xb42d799f) }, + { SPH_C32(0x75c90003), SPH_C32(0x0e10c000), SPH_C32(0xd1200000), + SPH_C32(0xbaea0000), SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), + SPH_C32(0xbb28761d), SPH_C32(0x00b72e2b), SPH_C32(0xeecf0001), + SPH_C32(0x6f564000), SPH_C32(0xf33e0000), SPH_C32(0xa79e0000), + SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), SPH_C32(0x4a3b40ba), + SPH_C32(0xfeabf254) }, + { SPH_C32(0xcdf40003), SPH_C32(0x1861c600), SPH_C32(0xe6ba0000), + SPH_C32(0x4f5b0000), SPH_C32(0xa9454e92), SPH_C32(0x29104612), + SPH_C32(0xdd0c600b), SPH_C32(0xc576c515), SPH_C32(0x13ea0001), + SPH_C32(0xdc925100), SPH_C32(0x3dce0000), SPH_C32(0x69670000), + SPH_C32(0x81f80799), SPH_C32(0x3a4a8f56), SPH_C32(0x3aa3f01c), + SPH_C32(0xe459edb5) }, + { SPH_C32(0x006d0003), SPH_C32(0xcc9be700), SPH_C32(0x45840000), + SPH_C32(0x2a1f0000), SPH_C32(0x70bc78de), SPH_C32(0xce96bcf9), + SPH_C32(0xac4fb29e), SPH_C32(0xae684855), SPH_C32(0x3fa90001), + SPH_C32(0x74ea4300), SPH_C32(0x6dd20000), SPH_C32(0x510a0000), + SPH_C32(0xbeb7373e), SPH_C32(0x78611737), SPH_C32(0xfe785bad), + SPH_C32(0x7bd4ce7f) }, + { SPH_C32(0xb8500003), SPH_C32(0xdaeae100), SPH_C32(0x721e0000), + SPH_C32(0xdfae0000), SPH_C32(0x523d1972), SPH_C32(0x60de4dbc), + SPH_C32(0xca6ba488), SPH_C32(0x6ba9a36b), SPH_C32(0xc28c0001), + SPH_C32(0xc72e5200), SPH_C32(0xa3220000), SPH_C32(0x9ff30000), + SPH_C32(0x82fa42be), SPH_C32(0xf53a73a4), SPH_C32(0x8ee0eb0b), + SPH_C32(0x6126d19e) }, + { SPH_C32(0xa4af0003), SPH_C32(0x15acc300), SPH_C32(0x4fcc0000), + SPH_C32(0x4c7e0000), SPH_C32(0x88c66a19), SPH_C32(0x48284ba5), + SPH_C32(0x0f6b6d0a), SPH_C32(0x85c81200), SPH_C32(0x4a0d0001), + SPH_C32(0xb6616400), SPH_C32(0xf9760000), SPH_C32(0xc1ff0000), + SPH_C32(0x45cf60de), SPH_C32(0x31af1c99), SPH_C32(0xe91f9f2e), + SPH_C32(0xd50ba801) }, + { SPH_C32(0x1c920003), SPH_C32(0x03ddc500), SPH_C32(0x78560000), + SPH_C32(0xb9cf0000), SPH_C32(0xaa470bb5), SPH_C32(0xe660bae0), + SPH_C32(0x694f7b1c), SPH_C32(0x4009f93e), SPH_C32(0xb7280001), + SPH_C32(0x05a57500), SPH_C32(0x37860000), SPH_C32(0x0f060000), + SPH_C32(0x7982155e), SPH_C32(0xbcf4780a), SPH_C32(0x99872f88), + SPH_C32(0xcff9b7e0) }, + { SPH_C32(0xd10b0003), SPH_C32(0xd727e400), SPH_C32(0xdb680000), + SPH_C32(0xdc8b0000), SPH_C32(0x73be3df9), SPH_C32(0x01e6400b), + SPH_C32(0x180ca989), SPH_C32(0x2b17747e), SPH_C32(0x9b6b0001), + SPH_C32(0xaddd6700), SPH_C32(0x679a0000), SPH_C32(0x376b0000), + SPH_C32(0x46cd25f9), SPH_C32(0xfedfe06b), SPH_C32(0x5d5c8439), + SPH_C32(0x5074942a) }, + { SPH_C32(0x69360003), SPH_C32(0xc156e200), SPH_C32(0xecf20000), + SPH_C32(0x293a0000), SPH_C32(0x513f5c55), SPH_C32(0xafaeb14e), + SPH_C32(0x7e28bf9f), SPH_C32(0xeed69f40), SPH_C32(0x664e0001), + SPH_C32(0x1e197600), SPH_C32(0xa96a0000), SPH_C32(0xf9920000), + SPH_C32(0x7a805079), SPH_C32(0x738484f8), SPH_C32(0x2dc4349f), + SPH_C32(0x4a868bcb) }, + { SPH_C32(0xeecf0001), SPH_C32(0x6f564000), SPH_C32(0xf33e0000), + SPH_C32(0xa79e0000), SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), + SPH_C32(0x4a3b40ba), SPH_C32(0xfeabf254), SPH_C32(0x9b060002), + SPH_C32(0x61468000), SPH_C32(0x221e0000), SPH_C32(0x1d740000), + SPH_C32(0x36715d27), SPH_C32(0x30495c92), SPH_C32(0xf11336a7), + SPH_C32(0xfe1cdc7f) }, + { SPH_C32(0x56f20001), SPH_C32(0x79274600), SPH_C32(0xc4a40000), + SPH_C32(0x522f0000), SPH_C32(0x9f3413b5), SPH_C32(0x19591a80), + SPH_C32(0x2c1f56ac), SPH_C32(0x3b6a196a), SPH_C32(0x66230002), + SPH_C32(0xd2829100), SPH_C32(0xecee0000), SPH_C32(0xd38d0000), + SPH_C32(0x0a3c28a7), SPH_C32(0xbd123801), SPH_C32(0x818b8601), + SPH_C32(0xe4eec39e) }, + { SPH_C32(0x9b6b0001), SPH_C32(0xaddd6700), SPH_C32(0x679a0000), + SPH_C32(0x376b0000), SPH_C32(0x46cd25f9), SPH_C32(0xfedfe06b), + SPH_C32(0x5d5c8439), SPH_C32(0x5074942a), SPH_C32(0x4a600002), + SPH_C32(0x7afa8300), SPH_C32(0xbcf20000), SPH_C32(0xebe00000), + SPH_C32(0x35731800), SPH_C32(0xff39a060), SPH_C32(0x45502db0), + SPH_C32(0x7b63e054) }, + { SPH_C32(0x23560001), SPH_C32(0xbbac6100), SPH_C32(0x50000000), + SPH_C32(0xc2da0000), SPH_C32(0x644c4455), SPH_C32(0x5097112e), + SPH_C32(0x3b78922f), SPH_C32(0x95b57f14), SPH_C32(0xb7450002), + SPH_C32(0xc93e9200), SPH_C32(0x72020000), SPH_C32(0x25190000), + SPH_C32(0x093e6d80), SPH_C32(0x7262c4f3), SPH_C32(0x35c89d16), + SPH_C32(0x6191ffb5) }, + { SPH_C32(0x3fa90001), SPH_C32(0x74ea4300), SPH_C32(0x6dd20000), + SPH_C32(0x510a0000), SPH_C32(0xbeb7373e), SPH_C32(0x78611737), + SPH_C32(0xfe785bad), SPH_C32(0x7bd4ce7f), SPH_C32(0x3fc40002), + SPH_C32(0xb871a400), SPH_C32(0x28560000), SPH_C32(0x7b150000), + SPH_C32(0xce0b4fe0), SPH_C32(0xb6f7abce), SPH_C32(0x5237e933), + SPH_C32(0xd5bc862a) }, + { SPH_C32(0x87940001), SPH_C32(0x629b4500), SPH_C32(0x5a480000), + SPH_C32(0xa4bb0000), SPH_C32(0x9c365692), SPH_C32(0xd629e672), + SPH_C32(0x985c4dbb), SPH_C32(0xbe152541), SPH_C32(0xc2e10002), + SPH_C32(0x0bb5b500), SPH_C32(0xe6a60000), SPH_C32(0xb5ec0000), + SPH_C32(0xf2463a60), SPH_C32(0x3baccf5d), SPH_C32(0x22af5995), + SPH_C32(0xcf4e99cb) }, + { SPH_C32(0x4a0d0001), SPH_C32(0xb6616400), SPH_C32(0xf9760000), + SPH_C32(0xc1ff0000), SPH_C32(0x45cf60de), SPH_C32(0x31af1c99), + SPH_C32(0xe91f9f2e), SPH_C32(0xd50ba801), SPH_C32(0xeea20002), + SPH_C32(0xa3cda700), SPH_C32(0xb6ba0000), SPH_C32(0x8d810000), + SPH_C32(0xcd090ac7), SPH_C32(0x7987573c), SPH_C32(0xe674f224), + SPH_C32(0x50c3ba01) }, + { SPH_C32(0xf2300001), SPH_C32(0xa0106200), SPH_C32(0xceec0000), + SPH_C32(0x344e0000), SPH_C32(0x674e0172), SPH_C32(0x9fe7eddc), + SPH_C32(0x8f3b8938), SPH_C32(0x10ca433f), SPH_C32(0x13870002), + SPH_C32(0x1009b600), SPH_C32(0x784a0000), SPH_C32(0x43780000), + SPH_C32(0xf1447f47), SPH_C32(0xf4dc33af), SPH_C32(0x96ec4282), + SPH_C32(0x4a31a5e0) }, + { SPH_C32(0x9b060002), SPH_C32(0x61468000), SPH_C32(0x221e0000), + SPH_C32(0x1d740000), SPH_C32(0x36715d27), SPH_C32(0x30495c92), + SPH_C32(0xf11336a7), SPH_C32(0xfe1cdc7f), SPH_C32(0x75c90003), + SPH_C32(0x0e10c000), SPH_C32(0xd1200000), SPH_C32(0xbaea0000), + SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), SPH_C32(0xbb28761d), + SPH_C32(0x00b72e2b) }, + { SPH_C32(0x233b0002), SPH_C32(0x77378600), SPH_C32(0x15840000), + SPH_C32(0xe8c50000), SPH_C32(0x14f03c8b), SPH_C32(0x9e01add7), + SPH_C32(0x973720b1), SPH_C32(0x3bdd3741), SPH_C32(0x88ec0003), + SPH_C32(0xbdd4d100), SPH_C32(0x1fd00000), SPH_C32(0x74130000), + SPH_C32(0xb7895abe), SPH_C32(0x0a03d3c4), SPH_C32(0xcbb0c6bb), + SPH_C32(0x1a4531ca) }, + { SPH_C32(0xeea20002), SPH_C32(0xa3cda700), SPH_C32(0xb6ba0000), + SPH_C32(0x8d810000), SPH_C32(0xcd090ac7), SPH_C32(0x7987573c), + SPH_C32(0xe674f224), SPH_C32(0x50c3ba01), SPH_C32(0xa4af0003), + SPH_C32(0x15acc300), SPH_C32(0x4fcc0000), SPH_C32(0x4c7e0000), + SPH_C32(0x88c66a19), SPH_C32(0x48284ba5), SPH_C32(0x0f6b6d0a), + SPH_C32(0x85c81200) }, + { SPH_C32(0x569f0002), SPH_C32(0xb5bca100), SPH_C32(0x81200000), + SPH_C32(0x78300000), SPH_C32(0xef886b6b), SPH_C32(0xd7cfa679), + SPH_C32(0x8050e432), SPH_C32(0x9502513f), SPH_C32(0x598a0003), + SPH_C32(0xa668d200), SPH_C32(0x813c0000), SPH_C32(0x82870000), + SPH_C32(0xb48b1f99), SPH_C32(0xc5732f36), SPH_C32(0x7ff3ddac), + SPH_C32(0x9f3a0de1) }, + { SPH_C32(0x4a600002), SPH_C32(0x7afa8300), SPH_C32(0xbcf20000), + SPH_C32(0xebe00000), SPH_C32(0x35731800), SPH_C32(0xff39a060), + SPH_C32(0x45502db0), SPH_C32(0x7b63e054), SPH_C32(0xd10b0003), + SPH_C32(0xd727e400), SPH_C32(0xdb680000), SPH_C32(0xdc8b0000), + SPH_C32(0x73be3df9), SPH_C32(0x01e6400b), SPH_C32(0x180ca989), + SPH_C32(0x2b17747e) }, + { SPH_C32(0xf25d0002), SPH_C32(0x6c8b8500), SPH_C32(0x8b680000), + SPH_C32(0x1e510000), SPH_C32(0x17f279ac), SPH_C32(0x51715125), + SPH_C32(0x23743ba6), SPH_C32(0xbea20b6a), SPH_C32(0x2c2e0003), + SPH_C32(0x64e3f500), SPH_C32(0x15980000), SPH_C32(0x12720000), + SPH_C32(0x4ff34879), SPH_C32(0x8cbd2498), SPH_C32(0x6894192f), + SPH_C32(0x31e56b9f) }, + { SPH_C32(0x3fc40002), SPH_C32(0xb871a400), SPH_C32(0x28560000), + SPH_C32(0x7b150000), SPH_C32(0xce0b4fe0), SPH_C32(0xb6f7abce), + SPH_C32(0x5237e933), SPH_C32(0xd5bc862a), SPH_C32(0x006d0003), + SPH_C32(0xcc9be700), SPH_C32(0x45840000), SPH_C32(0x2a1f0000), + SPH_C32(0x70bc78de), SPH_C32(0xce96bcf9), SPH_C32(0xac4fb29e), + SPH_C32(0xae684855) }, + { SPH_C32(0x87f90002), SPH_C32(0xae00a200), SPH_C32(0x1fcc0000), + SPH_C32(0x8ea40000), SPH_C32(0xec8a2e4c), SPH_C32(0x18bf5a8b), + SPH_C32(0x3413ff25), SPH_C32(0x107d6d14), SPH_C32(0xfd480003), + SPH_C32(0x7f5ff600), SPH_C32(0x8b740000), SPH_C32(0xe4e60000), + SPH_C32(0x4cf10d5e), SPH_C32(0x43cdd86a), SPH_C32(0xdcd70238), + SPH_C32(0xb49a57b4) }, + { SPH_C32(0xf6800005), SPH_C32(0x3443c000), SPH_C32(0x24070000), + SPH_C32(0x8f3d0000), SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), + SPH_C32(0xcdc58b19), SPH_C32(0xd795ba31), SPH_C32(0xa67f0001), + SPH_C32(0x71378000), SPH_C32(0x19fc0000), SPH_C32(0x96db0000), + SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), SPH_C32(0x2c6d478f), + SPH_C32(0xac8e6c88) }, + { SPH_C32(0x4ebd0005), SPH_C32(0x2232c600), SPH_C32(0x139d0000), + SPH_C32(0x7a8c0000), SPH_C32(0x03b65a57), SPH_C32(0xa4f024eb), + SPH_C32(0xabe19d0f), SPH_C32(0x1254510f), SPH_C32(0x5b5a0001), + SPH_C32(0xc2f39100), SPH_C32(0xd70c0000), SPH_C32(0x58220000), + SPH_C32(0x06c6187d), SPH_C32(0x6691ca60), SPH_C32(0x5cf5f729), + SPH_C32(0xb67c7369) }, + { SPH_C32(0x83240005), SPH_C32(0xf6c8e700), SPH_C32(0xb0a30000), + SPH_C32(0x1fc80000), SPH_C32(0xda4f6c1b), SPH_C32(0x4376de00), + SPH_C32(0xdaa24f9a), SPH_C32(0x794adc4f), SPH_C32(0x77190001), + SPH_C32(0x6a8b8300), SPH_C32(0x87100000), SPH_C32(0x604f0000), + SPH_C32(0x398928da), SPH_C32(0x24ba5201), SPH_C32(0x982e5c98), + SPH_C32(0x29f150a3) }, + { SPH_C32(0x3b190005), SPH_C32(0xe0b9e100), SPH_C32(0x87390000), + SPH_C32(0xea790000), SPH_C32(0xf8ce0db7), SPH_C32(0xed3e2f45), + SPH_C32(0xbc86598c), SPH_C32(0xbc8b3771), SPH_C32(0x8a3c0001), + SPH_C32(0xd94f9200), SPH_C32(0x49e00000), SPH_C32(0xaeb60000), + SPH_C32(0x05c45d5a), SPH_C32(0xa9e13692), SPH_C32(0xe8b6ec3e), + SPH_C32(0x33034f42) }, + { SPH_C32(0x27e60005), SPH_C32(0x2fffc300), SPH_C32(0xbaeb0000), + SPH_C32(0x79a90000), SPH_C32(0x22357edc), SPH_C32(0xc5c8295c), + SPH_C32(0x7986900e), SPH_C32(0x52ea861a), SPH_C32(0x02bd0001), + SPH_C32(0xa800a400), SPH_C32(0x13b40000), SPH_C32(0xf0ba0000), + SPH_C32(0xc2f17f3a), SPH_C32(0x6d7459af), SPH_C32(0x8f49981b), + SPH_C32(0x872e36dd) }, + { SPH_C32(0x9fdb0005), SPH_C32(0x398ec500), SPH_C32(0x8d710000), + SPH_C32(0x8c180000), SPH_C32(0x00b41f70), SPH_C32(0x6b80d819), + SPH_C32(0x1fa28618), SPH_C32(0x972b6d24), SPH_C32(0xff980001), + SPH_C32(0x1bc4b500), SPH_C32(0xdd440000), SPH_C32(0x3e430000), + SPH_C32(0xfebc0aba), SPH_C32(0xe02f3d3c), SPH_C32(0xffd128bd), + SPH_C32(0x9ddc293c) }, + { SPH_C32(0x52420005), SPH_C32(0xed74e400), SPH_C32(0x2e4f0000), + SPH_C32(0xe95c0000), SPH_C32(0xd94d293c), SPH_C32(0x8c0622f2), + SPH_C32(0x6ee1548d), SPH_C32(0xfc35e064), SPH_C32(0xd3db0001), + SPH_C32(0xb3bca700), SPH_C32(0x8d580000), SPH_C32(0x062e0000), + SPH_C32(0xc1f33a1d), SPH_C32(0xa204a55d), SPH_C32(0x3b0a830c), + SPH_C32(0x02510af6) }, + { SPH_C32(0xea7f0005), SPH_C32(0xfb05e200), SPH_C32(0x19d50000), + SPH_C32(0x1ced0000), SPH_C32(0xfbcc4890), SPH_C32(0x224ed3b7), + SPH_C32(0x08c5429b), SPH_C32(0x39f40b5a), SPH_C32(0x2efe0001), + SPH_C32(0x0078b600), SPH_C32(0x43a80000), SPH_C32(0xc8d70000), + SPH_C32(0xfdbe4f9d), SPH_C32(0x2f5fc1ce), SPH_C32(0x4b9233aa), + SPH_C32(0x18a31517) }, + { SPH_C32(0x83490006), SPH_C32(0x3a530000), SPH_C32(0xf5270000), + SPH_C32(0x35d70000), SPH_C32(0xaaf314c5), SPH_C32(0x8de062f9), + SPH_C32(0x76edfd04), SPH_C32(0xd722941a), SPH_C32(0x48b00000), + SPH_C32(0x1e61c000), SPH_C32(0xeac20000), SPH_C32(0x31450000), + SPH_C32(0x873e1fe4), SPH_C32(0x5cdb4536), SPH_C32(0x66560735), + SPH_C32(0x52259edc) }, + { SPH_C32(0x3b740006), SPH_C32(0x2c220600), SPH_C32(0xc2bd0000), + SPH_C32(0xc0660000), SPH_C32(0x88727569), SPH_C32(0x23a893bc), + SPH_C32(0x10c9eb12), SPH_C32(0x12e37f24), SPH_C32(0xb5950000), + SPH_C32(0xada5d100), SPH_C32(0x24320000), SPH_C32(0xffbc0000), + SPH_C32(0xbb736a64), SPH_C32(0xd18021a5), SPH_C32(0x16ceb793), + SPH_C32(0x48d7813d) }, + { SPH_C32(0xf6ed0006), SPH_C32(0xf8d82700), SPH_C32(0x61830000), + SPH_C32(0xa5220000), SPH_C32(0x518b4325), SPH_C32(0xc42e6957), + SPH_C32(0x618a3987), SPH_C32(0x79fdf264), SPH_C32(0x99d60000), + SPH_C32(0x05ddc300), SPH_C32(0x742e0000), SPH_C32(0xc7d10000), + SPH_C32(0x843c5ac3), SPH_C32(0x93abb9c4), SPH_C32(0xd2151c22), + SPH_C32(0xd75aa2f7) }, + { SPH_C32(0x4ed00006), SPH_C32(0xeea92100), SPH_C32(0x56190000), + SPH_C32(0x50930000), SPH_C32(0x730a2289), SPH_C32(0x6a669812), + SPH_C32(0x07ae2f91), SPH_C32(0xbc3c195a), SPH_C32(0x64f30000), + SPH_C32(0xb619d200), SPH_C32(0xbade0000), SPH_C32(0x09280000), + SPH_C32(0xb8712f43), SPH_C32(0x1ef0dd57), SPH_C32(0xa28dac84), + SPH_C32(0xcda8bd16) }, + { SPH_C32(0x522f0006), SPH_C32(0x21ef0300), SPH_C32(0x6bcb0000), + SPH_C32(0xc3430000), SPH_C32(0xa9f151e2), SPH_C32(0x42909e0b), + SPH_C32(0xc2aee613), SPH_C32(0x525da831), SPH_C32(0xec720000), + SPH_C32(0xc756e400), SPH_C32(0xe08a0000), SPH_C32(0x57240000), + SPH_C32(0x7f440d23), SPH_C32(0xda65b26a), SPH_C32(0xc572d8a1), + SPH_C32(0x7985c489) }, + { SPH_C32(0xea120006), SPH_C32(0x379e0500), SPH_C32(0x5c510000), + SPH_C32(0x36f20000), SPH_C32(0x8b70304e), SPH_C32(0xecd86f4e), + SPH_C32(0xa48af005), SPH_C32(0x979c430f), SPH_C32(0x11570000), + SPH_C32(0x7492f500), SPH_C32(0x2e7a0000), SPH_C32(0x99dd0000), + SPH_C32(0x430978a3), SPH_C32(0x573ed6f9), SPH_C32(0xb5ea6807), + SPH_C32(0x6377db68) }, + { SPH_C32(0x278b0006), SPH_C32(0xe3642400), SPH_C32(0xff6f0000), + SPH_C32(0x53b60000), SPH_C32(0x52890602), SPH_C32(0x0b5e95a5), + SPH_C32(0xd5c92290), SPH_C32(0xfc82ce4f), SPH_C32(0x3d140000), + SPH_C32(0xdceae700), SPH_C32(0x7e660000), SPH_C32(0xa1b00000), + SPH_C32(0x7c464804), SPH_C32(0x15154e98), SPH_C32(0x7131c3b6), + SPH_C32(0xfcfaf8a2) }, + { SPH_C32(0x9fb60006), SPH_C32(0xf5152200), SPH_C32(0xc8f50000), + SPH_C32(0xa6070000), SPH_C32(0x700867ae), SPH_C32(0xa51664e0), + SPH_C32(0xb3ed3486), SPH_C32(0x39432571), SPH_C32(0xc0310000), + SPH_C32(0x6f2ef600), SPH_C32(0xb0960000), SPH_C32(0x6f490000), + SPH_C32(0x400b3d84), SPH_C32(0x984e2a0b), SPH_C32(0x01a97310), + SPH_C32(0xe608e743) }, + { SPH_C32(0x184f0004), SPH_C32(0x5b158000), SPH_C32(0xd7390000), + SPH_C32(0x28a30000), SPH_C32(0x9c8249e2), SPH_C32(0xbda93e6b), + SPH_C32(0x87fecba3), SPH_C32(0x293e4865), SPH_C32(0x3d790003), + SPH_C32(0x10710000), SPH_C32(0x3be20000), SPH_C32(0x8baf0000), + SPH_C32(0x0cfa30da), SPH_C32(0xdb83f261), SPH_C32(0xdd7e7128), + SPH_C32(0x5292b0f7) }, + { SPH_C32(0xa0720004), SPH_C32(0x4d648600), SPH_C32(0xe0a30000), + SPH_C32(0xdd120000), SPH_C32(0xbe03284e), SPH_C32(0x13e1cf2e), + SPH_C32(0xe1daddb5), SPH_C32(0xecffa35b), SPH_C32(0xc05c0003), + SPH_C32(0xa3b51100), SPH_C32(0xf5120000), SPH_C32(0x45560000), + SPH_C32(0x30b7455a), SPH_C32(0x56d896f2), SPH_C32(0xade6c18e), + SPH_C32(0x4860af16) }, + { SPH_C32(0x6deb0004), SPH_C32(0x999ea700), SPH_C32(0x439d0000), + SPH_C32(0xb8560000), SPH_C32(0x67fa1e02), SPH_C32(0xf46735c5), + SPH_C32(0x90990f20), SPH_C32(0x87e12e1b), SPH_C32(0xec1f0003), + SPH_C32(0x0bcd0300), SPH_C32(0xa50e0000), SPH_C32(0x7d3b0000), + SPH_C32(0x0ff875fd), SPH_C32(0x14f30e93), SPH_C32(0x693d6a3f), + SPH_C32(0xd7ed8cdc) }, + { SPH_C32(0xd5d60004), SPH_C32(0x8fefa100), SPH_C32(0x74070000), + SPH_C32(0x4de70000), SPH_C32(0x457b7fae), SPH_C32(0x5a2fc480), + SPH_C32(0xf6bd1936), SPH_C32(0x4220c525), SPH_C32(0x113a0003), + SPH_C32(0xb8091200), SPH_C32(0x6bfe0000), SPH_C32(0xb3c20000), + SPH_C32(0x33b5007d), SPH_C32(0x99a86a00), SPH_C32(0x19a5da99), + SPH_C32(0xcd1f933d) }, + { SPH_C32(0xc9290004), SPH_C32(0x40a98300), SPH_C32(0x49d50000), + SPH_C32(0xde370000), SPH_C32(0x9f800cc5), SPH_C32(0x72d9c299), + SPH_C32(0x33bdd0b4), SPH_C32(0xac41744e), SPH_C32(0x99bb0003), + SPH_C32(0xc9462400), SPH_C32(0x31aa0000), SPH_C32(0xedce0000), + SPH_C32(0xf480221d), SPH_C32(0x5d3d053d), SPH_C32(0x7e5aaebc), + SPH_C32(0x7932eaa2) }, + { SPH_C32(0x71140004), SPH_C32(0x56d88500), SPH_C32(0x7e4f0000), + SPH_C32(0x2b860000), SPH_C32(0xbd016d69), SPH_C32(0xdc9133dc), + SPH_C32(0x5599c6a2), SPH_C32(0x69809f70), SPH_C32(0x649e0003), + SPH_C32(0x7a823500), SPH_C32(0xff5a0000), SPH_C32(0x23370000), + SPH_C32(0xc8cd579d), SPH_C32(0xd06661ae), SPH_C32(0x0ec21e1a), + SPH_C32(0x63c0f543) }, + { SPH_C32(0xbc8d0004), SPH_C32(0x8222a400), SPH_C32(0xdd710000), + SPH_C32(0x4ec20000), SPH_C32(0x64f85b25), SPH_C32(0x3b17c937), + SPH_C32(0x24da1437), SPH_C32(0x029e1230), SPH_C32(0x48dd0003), + SPH_C32(0xd2fa2700), SPH_C32(0xaf460000), SPH_C32(0x1b5a0000), + SPH_C32(0xf782673a), SPH_C32(0x924df9cf), SPH_C32(0xca19b5ab), + SPH_C32(0xfc4dd689) }, + { SPH_C32(0x04b00004), SPH_C32(0x9453a200), SPH_C32(0xeaeb0000), + SPH_C32(0xbb730000), SPH_C32(0x46793a89), SPH_C32(0x955f3872), + SPH_C32(0x42fe0221), SPH_C32(0xc75ff90e), SPH_C32(0xb5f80003), + SPH_C32(0x613e3600), SPH_C32(0x61b60000), SPH_C32(0xd5a30000), + SPH_C32(0xcbcf12ba), SPH_C32(0x1f169d5c), SPH_C32(0xba81050d), + SPH_C32(0xe6bfc968) }, + { SPH_C32(0x6d860007), SPH_C32(0x55054000), SPH_C32(0x06190000), + SPH_C32(0x92490000), SPH_C32(0x174666dc), SPH_C32(0x3af1893c), + SPH_C32(0x3cd6bdbe), SPH_C32(0x2989664e), SPH_C32(0xd3b60002), + SPH_C32(0x7f274000), SPH_C32(0xc8dc0000), SPH_C32(0x2c310000), + SPH_C32(0xb14f42c3), SPH_C32(0x6c9219a4), SPH_C32(0x97453192), + SPH_C32(0xac3942a3) }, + { SPH_C32(0xd5bb0007), SPH_C32(0x43744600), SPH_C32(0x31830000), + SPH_C32(0x67f80000), SPH_C32(0x35c70770), SPH_C32(0x94b97879), + SPH_C32(0x5af2aba8), SPH_C32(0xec488d70), SPH_C32(0x2e930002), + SPH_C32(0xcce35100), SPH_C32(0x062c0000), SPH_C32(0xe2c80000), + SPH_C32(0x8d023743), SPH_C32(0xe1c97d37), SPH_C32(0xe7dd8134), + SPH_C32(0xb6cb5d42) }, + { SPH_C32(0x18220007), SPH_C32(0x978e6700), SPH_C32(0x92bd0000), + SPH_C32(0x02bc0000), SPH_C32(0xec3e313c), SPH_C32(0x733f8292), + SPH_C32(0x2bb1793d), SPH_C32(0x87560030), SPH_C32(0x02d00002), + SPH_C32(0x649b4300), SPH_C32(0x56300000), SPH_C32(0xdaa50000), + SPH_C32(0xb24d07e4), SPH_C32(0xa3e2e556), SPH_C32(0x23062a85), + SPH_C32(0x29467e88) }, + { SPH_C32(0xa01f0007), SPH_C32(0x81ff6100), SPH_C32(0xa5270000), + SPH_C32(0xf70d0000), SPH_C32(0xcebf5090), SPH_C32(0xdd7773d7), + SPH_C32(0x4d956f2b), SPH_C32(0x4297eb0e), SPH_C32(0xfff50002), + SPH_C32(0xd75f5200), SPH_C32(0x98c00000), SPH_C32(0x145c0000), + SPH_C32(0x8e007264), SPH_C32(0x2eb981c5), SPH_C32(0x539e9a23), + SPH_C32(0x33b46169) }, + { SPH_C32(0xbce00007), SPH_C32(0x4eb94300), SPH_C32(0x98f50000), + SPH_C32(0x64dd0000), SPH_C32(0x144423fb), SPH_C32(0xf58175ce), + SPH_C32(0x8895a6a9), SPH_C32(0xacf65a65), SPH_C32(0x77740002), + SPH_C32(0xa6106400), SPH_C32(0xc2940000), SPH_C32(0x4a500000), + SPH_C32(0x49355004), SPH_C32(0xea2ceef8), SPH_C32(0x3461ee06), + SPH_C32(0x879918f6) }, + { SPH_C32(0x04dd0007), SPH_C32(0x58c84500), SPH_C32(0xaf6f0000), + SPH_C32(0x916c0000), SPH_C32(0x36c54257), SPH_C32(0x5bc9848b), + SPH_C32(0xeeb1b0bf), SPH_C32(0x6937b15b), SPH_C32(0x8a510002), + SPH_C32(0x15d47500), SPH_C32(0x0c640000), SPH_C32(0x84a90000), + SPH_C32(0x75782584), SPH_C32(0x67778a6b), SPH_C32(0x44f95ea0), + SPH_C32(0x9d6b0717) }, + { SPH_C32(0xc9440007), SPH_C32(0x8c326400), SPH_C32(0x0c510000), + SPH_C32(0xf4280000), SPH_C32(0xef3c741b), SPH_C32(0xbc4f7e60), + SPH_C32(0x9ff2622a), SPH_C32(0x02293c1b), SPH_C32(0xa6120002), + SPH_C32(0xbdac6700), SPH_C32(0x5c780000), SPH_C32(0xbcc40000), + SPH_C32(0x4a371523), SPH_C32(0x255c120a), SPH_C32(0x8022f511), + SPH_C32(0x02e624dd) }, + { SPH_C32(0x71790007), SPH_C32(0x9a436200), SPH_C32(0x3bcb0000), + SPH_C32(0x01990000), SPH_C32(0xcdbd15b7), SPH_C32(0x12078f25), + SPH_C32(0xf9d6743c), SPH_C32(0xc7e8d725), SPH_C32(0x5b370002), + SPH_C32(0x0e687600), SPH_C32(0x92880000), SPH_C32(0x723d0000), + SPH_C32(0x767a60a3), SPH_C32(0xa8077699), SPH_C32(0xf0ba45b7), + SPH_C32(0x18143b3c) }, + { SPH_C32(0xa67f0001), SPH_C32(0x71378000), SPH_C32(0x19fc0000), + SPH_C32(0x96db0000), SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), + SPH_C32(0x2c6d478f), SPH_C32(0xac8e6c88), SPH_C32(0x50ff0004), + SPH_C32(0x45744000), SPH_C32(0x3dfb0000), SPH_C32(0x19e60000), + SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), SPH_C32(0xe1a8cc96), + SPH_C32(0x7b1bd6b9) }, + { SPH_C32(0x1e420001), SPH_C32(0x67468600), SPH_C32(0x2e660000), + SPH_C32(0x636a0000), SPH_C32(0x180a0c51), SPH_C32(0x45825fb6), + SPH_C32(0x4a495199), SPH_C32(0x694f87b6), SPH_C32(0xadda0004), + SPH_C32(0xf6b05100), SPH_C32(0xf30b0000), SPH_C32(0xd71f0000), + SPH_C32(0x27f12386), SPH_C32(0x6c291fce), SPH_C32(0x91307c30), + SPH_C32(0x61e9c958) }, + { SPH_C32(0xd3db0001), SPH_C32(0xb3bca700), SPH_C32(0x8d580000), + SPH_C32(0x062e0000), SPH_C32(0xc1f33a1d), SPH_C32(0xa204a55d), + SPH_C32(0x3b0a830c), SPH_C32(0x02510af6), SPH_C32(0x81990004), + SPH_C32(0x5ec84300), SPH_C32(0xa3170000), SPH_C32(0xef720000), + SPH_C32(0x18be1321), SPH_C32(0x2e0287af), SPH_C32(0x55ebd781), + SPH_C32(0xfe64ea92) }, + { SPH_C32(0x6be60001), SPH_C32(0xa5cda100), SPH_C32(0xbac20000), + SPH_C32(0xf39f0000), SPH_C32(0xe3725bb1), SPH_C32(0x0c4c5418), + SPH_C32(0x5d2e951a), SPH_C32(0xc790e1c8), SPH_C32(0x7cbc0004), + SPH_C32(0xed0c5200), SPH_C32(0x6de70000), SPH_C32(0x218b0000), + SPH_C32(0x24f366a1), SPH_C32(0xa359e33c), SPH_C32(0x25736727), + SPH_C32(0xe496f573) }, + { SPH_C32(0x77190001), SPH_C32(0x6a8b8300), SPH_C32(0x87100000), + SPH_C32(0x604f0000), SPH_C32(0x398928da), SPH_C32(0x24ba5201), + SPH_C32(0x982e5c98), SPH_C32(0x29f150a3), SPH_C32(0xf43d0004), + SPH_C32(0x9c436400), SPH_C32(0x37b30000), SPH_C32(0x7f870000), + SPH_C32(0xe3c644c1), SPH_C32(0x67cc8c01), SPH_C32(0x428c1302), + SPH_C32(0x50bb8cec) }, + { SPH_C32(0xcf240001), SPH_C32(0x7cfa8500), SPH_C32(0xb08a0000), + SPH_C32(0x95fe0000), SPH_C32(0x1b084976), SPH_C32(0x8af2a344), + SPH_C32(0xfe0a4a8e), SPH_C32(0xec30bb9d), SPH_C32(0x09180004), + SPH_C32(0x2f877500), SPH_C32(0xf9430000), SPH_C32(0xb17e0000), + SPH_C32(0xdf8b3141), SPH_C32(0xea97e892), SPH_C32(0x3214a3a4), + SPH_C32(0x4a49930d) }, + { SPH_C32(0x02bd0001), SPH_C32(0xa800a400), SPH_C32(0x13b40000), + SPH_C32(0xf0ba0000), SPH_C32(0xc2f17f3a), SPH_C32(0x6d7459af), + SPH_C32(0x8f49981b), SPH_C32(0x872e36dd), SPH_C32(0x255b0004), + SPH_C32(0x87ff6700), SPH_C32(0xa95f0000), SPH_C32(0x89130000), + SPH_C32(0xe0c401e6), SPH_C32(0xa8bc70f3), SPH_C32(0xf6cf0815), + SPH_C32(0xd5c4b0c7) }, + { SPH_C32(0xba800001), SPH_C32(0xbe71a200), SPH_C32(0x242e0000), + SPH_C32(0x050b0000), SPH_C32(0xe0701e96), SPH_C32(0xc33ca8ea), + SPH_C32(0xe96d8e0d), SPH_C32(0x42efdde3), SPH_C32(0xd87e0004), + SPH_C32(0x343b7600), SPH_C32(0x67af0000), SPH_C32(0x47ea0000), + SPH_C32(0xdc897466), SPH_C32(0x25e71460), SPH_C32(0x8657b8b3), + SPH_C32(0xcf36af26) }, + { SPH_C32(0xd3b60002), SPH_C32(0x7f274000), SPH_C32(0xc8dc0000), + SPH_C32(0x2c310000), SPH_C32(0xb14f42c3), SPH_C32(0x6c9219a4), + SPH_C32(0x97453192), SPH_C32(0xac3942a3), SPH_C32(0xbe300005), + SPH_C32(0x2a220000), SPH_C32(0xcec50000), SPH_C32(0xbe780000), + SPH_C32(0xa609241f), SPH_C32(0x56639098), SPH_C32(0xab938c2c), + SPH_C32(0x85b024ed) }, + { SPH_C32(0x6b8b0002), SPH_C32(0x69564600), SPH_C32(0xff460000), + SPH_C32(0xd9800000), SPH_C32(0x93ce236f), SPH_C32(0xc2dae8e1), + SPH_C32(0xf1612784), SPH_C32(0x69f8a99d), SPH_C32(0x43150005), + SPH_C32(0x99e61100), SPH_C32(0x00350000), SPH_C32(0x70810000), + SPH_C32(0x9a44519f), SPH_C32(0xdb38f40b), SPH_C32(0xdb0b3c8a), + SPH_C32(0x9f423b0c) }, + { SPH_C32(0xa6120002), SPH_C32(0xbdac6700), SPH_C32(0x5c780000), + SPH_C32(0xbcc40000), SPH_C32(0x4a371523), SPH_C32(0x255c120a), + SPH_C32(0x8022f511), SPH_C32(0x02e624dd), SPH_C32(0x6f560005), + SPH_C32(0x319e0300), SPH_C32(0x50290000), SPH_C32(0x48ec0000), + SPH_C32(0xa50b6138), SPH_C32(0x99136c6a), SPH_C32(0x1fd0973b), + SPH_C32(0x00cf18c6) }, + { SPH_C32(0x1e2f0002), SPH_C32(0xabdd6100), SPH_C32(0x6be20000), + SPH_C32(0x49750000), SPH_C32(0x68b6748f), SPH_C32(0x8b14e34f), + SPH_C32(0xe606e307), SPH_C32(0xc727cfe3), SPH_C32(0x92730005), + SPH_C32(0x825a1200), SPH_C32(0x9ed90000), SPH_C32(0x86150000), + SPH_C32(0x994614b8), SPH_C32(0x144808f9), SPH_C32(0x6f48279d), + SPH_C32(0x1a3d0727) }, + { SPH_C32(0x02d00002), SPH_C32(0x649b4300), SPH_C32(0x56300000), + SPH_C32(0xdaa50000), SPH_C32(0xb24d07e4), SPH_C32(0xa3e2e556), + SPH_C32(0x23062a85), SPH_C32(0x29467e88), SPH_C32(0x1af20005), + SPH_C32(0xf3152400), SPH_C32(0xc48d0000), SPH_C32(0xd8190000), + SPH_C32(0x5e7336d8), SPH_C32(0xd0dd67c4), SPH_C32(0x08b753b8), + SPH_C32(0xae107eb8) }, + { SPH_C32(0xbaed0002), SPH_C32(0x72ea4500), SPH_C32(0x61aa0000), + SPH_C32(0x2f140000), SPH_C32(0x90cc6648), SPH_C32(0x0daa1413), + SPH_C32(0x45223c93), SPH_C32(0xec8795b6), SPH_C32(0xe7d70005), + SPH_C32(0x40d13500), SPH_C32(0x0a7d0000), SPH_C32(0x16e00000), + SPH_C32(0x623e4358), SPH_C32(0x5d860357), SPH_C32(0x782fe31e), + SPH_C32(0xb4e26159) }, + { SPH_C32(0x77740002), SPH_C32(0xa6106400), SPH_C32(0xc2940000), + SPH_C32(0x4a500000), SPH_C32(0x49355004), SPH_C32(0xea2ceef8), + SPH_C32(0x3461ee06), SPH_C32(0x879918f6), SPH_C32(0xcb940005), + SPH_C32(0xe8a92700), SPH_C32(0x5a610000), SPH_C32(0x2e8d0000), + SPH_C32(0x5d7173ff), SPH_C32(0x1fad9b36), SPH_C32(0xbcf448af), + SPH_C32(0x2b6f4293) }, + { SPH_C32(0xcf490002), SPH_C32(0xb0616200), SPH_C32(0xf50e0000), + SPH_C32(0xbfe10000), SPH_C32(0x6bb431a8), SPH_C32(0x44641fbd), + SPH_C32(0x5245f810), SPH_C32(0x4258f3c8), SPH_C32(0x36b10005), + SPH_C32(0x5b6d3600), SPH_C32(0x94910000), SPH_C32(0xe0740000), + SPH_C32(0x613c067f), SPH_C32(0x92f6ffa5), SPH_C32(0xcc6cf809), + SPH_C32(0x319d5d72) }, + { SPH_C32(0x48b00000), SPH_C32(0x1e61c000), SPH_C32(0xeac20000), + SPH_C32(0x31450000), SPH_C32(0x873e1fe4), SPH_C32(0x5cdb4536), + SPH_C32(0x66560735), SPH_C32(0x52259edc), SPH_C32(0xcbf90006), + SPH_C32(0x2432c000), SPH_C32(0x1fe50000), SPH_C32(0x04920000), + SPH_C32(0x2dcd0b21), SPH_C32(0xd13b27cf), SPH_C32(0x10bbfa31), + SPH_C32(0x85070ac6) }, + { SPH_C32(0xf08d0000), SPH_C32(0x0810c600), SPH_C32(0xdd580000), + SPH_C32(0xc4f40000), SPH_C32(0xa5bf7e48), SPH_C32(0xf293b473), + SPH_C32(0x00721123), SPH_C32(0x97e475e2), SPH_C32(0x36dc0006), + SPH_C32(0x97f6d100), SPH_C32(0xd1150000), SPH_C32(0xca6b0000), + SPH_C32(0x11807ea1), SPH_C32(0x5c60435c), SPH_C32(0x60234a97), + SPH_C32(0x9ff51527) }, + { SPH_C32(0x3d140000), SPH_C32(0xdceae700), SPH_C32(0x7e660000), + SPH_C32(0xa1b00000), SPH_C32(0x7c464804), SPH_C32(0x15154e98), + SPH_C32(0x7131c3b6), SPH_C32(0xfcfaf8a2), SPH_C32(0x1a9f0006), + SPH_C32(0x3f8ec300), SPH_C32(0x81090000), SPH_C32(0xf2060000), + SPH_C32(0x2ecf4e06), SPH_C32(0x1e4bdb3d), SPH_C32(0xa4f8e126), + SPH_C32(0x007836ed) }, + { SPH_C32(0x85290000), SPH_C32(0xca9be100), SPH_C32(0x49fc0000), + SPH_C32(0x54010000), SPH_C32(0x5ec729a8), SPH_C32(0xbb5dbfdd), + SPH_C32(0x1715d5a0), SPH_C32(0x393b139c), SPH_C32(0xe7ba0006), + SPH_C32(0x8c4ad200), SPH_C32(0x4ff90000), SPH_C32(0x3cff0000), + SPH_C32(0x12823b86), SPH_C32(0x9310bfae), SPH_C32(0xd4605180), + SPH_C32(0x1a8a290c) }, + { SPH_C32(0x99d60000), SPH_C32(0x05ddc300), SPH_C32(0x742e0000), + SPH_C32(0xc7d10000), SPH_C32(0x843c5ac3), SPH_C32(0x93abb9c4), + SPH_C32(0xd2151c22), SPH_C32(0xd75aa2f7), SPH_C32(0x6f3b0006), + SPH_C32(0xfd05e400), SPH_C32(0x15ad0000), SPH_C32(0x62f30000), + SPH_C32(0xd5b719e6), SPH_C32(0x5785d093), SPH_C32(0xb39f25a5), + SPH_C32(0xaea75093) }, + { SPH_C32(0x21eb0000), SPH_C32(0x13acc500), SPH_C32(0x43b40000), + SPH_C32(0x32600000), SPH_C32(0xa6bd3b6f), SPH_C32(0x3de34881), + SPH_C32(0xb4310a34), SPH_C32(0x129b49c9), SPH_C32(0x921e0006), + SPH_C32(0x4ec1f500), SPH_C32(0xdb5d0000), SPH_C32(0xac0a0000), + SPH_C32(0xe9fa6c66), SPH_C32(0xdadeb400), SPH_C32(0xc3079503), + SPH_C32(0xb4554f72) }, + { SPH_C32(0xec720000), SPH_C32(0xc756e400), SPH_C32(0xe08a0000), + SPH_C32(0x57240000), SPH_C32(0x7f440d23), SPH_C32(0xda65b26a), + SPH_C32(0xc572d8a1), SPH_C32(0x7985c489), SPH_C32(0xbe5d0006), + SPH_C32(0xe6b9e700), SPH_C32(0x8b410000), SPH_C32(0x94670000), + SPH_C32(0xd6b55cc1), SPH_C32(0x98f52c61), SPH_C32(0x07dc3eb2), + SPH_C32(0x2bd86cb8) }, + { SPH_C32(0x544f0000), SPH_C32(0xd127e200), SPH_C32(0xd7100000), + SPH_C32(0xa2950000), SPH_C32(0x5dc56c8f), SPH_C32(0x742d432f), + SPH_C32(0xa356ceb7), SPH_C32(0xbc442fb7), SPH_C32(0x43780006), + SPH_C32(0x557df600), SPH_C32(0x45b10000), SPH_C32(0x5a9e0000), + SPH_C32(0xeaf82941), SPH_C32(0x15ae48f2), SPH_C32(0x77448e14), + SPH_C32(0x312a7359) }, + { SPH_C32(0x3d790003), SPH_C32(0x10710000), SPH_C32(0x3be20000), + SPH_C32(0x8baf0000), SPH_C32(0x0cfa30da), SPH_C32(0xdb83f261), + SPH_C32(0xdd7e7128), SPH_C32(0x5292b0f7), SPH_C32(0x25360007), + SPH_C32(0x4b648000), SPH_C32(0xecdb0000), SPH_C32(0xa30c0000), + SPH_C32(0x90787938), SPH_C32(0x662acc0a), SPH_C32(0x5a80ba8b), + SPH_C32(0x7bacf892) }, + { SPH_C32(0x85440003), SPH_C32(0x06000600), SPH_C32(0x0c780000), + SPH_C32(0x7e1e0000), SPH_C32(0x2e7b5176), SPH_C32(0x75cb0324), + SPH_C32(0xbb5a673e), SPH_C32(0x97535bc9), SPH_C32(0xd8130007), + SPH_C32(0xf8a09100), SPH_C32(0x222b0000), SPH_C32(0x6df50000), + SPH_C32(0xac350cb8), SPH_C32(0xeb71a899), SPH_C32(0x2a180a2d), + SPH_C32(0x615ee773) }, + { SPH_C32(0x48dd0003), SPH_C32(0xd2fa2700), SPH_C32(0xaf460000), + SPH_C32(0x1b5a0000), SPH_C32(0xf782673a), SPH_C32(0x924df9cf), + SPH_C32(0xca19b5ab), SPH_C32(0xfc4dd689), SPH_C32(0xf4500007), + SPH_C32(0x50d88300), SPH_C32(0x72370000), SPH_C32(0x55980000), + SPH_C32(0x937a3c1f), SPH_C32(0xa95a30f8), SPH_C32(0xeec3a19c), + SPH_C32(0xfed3c4b9) }, + { SPH_C32(0xf0e00003), SPH_C32(0xc48b2100), SPH_C32(0x98dc0000), + SPH_C32(0xeeeb0000), SPH_C32(0xd5030696), SPH_C32(0x3c05088a), + SPH_C32(0xac3da3bd), SPH_C32(0x398c3db7), SPH_C32(0x09750007), + SPH_C32(0xe31c9200), SPH_C32(0xbcc70000), SPH_C32(0x9b610000), + SPH_C32(0xaf37499f), SPH_C32(0x2401546b), SPH_C32(0x9e5b113a), + SPH_C32(0xe421db58) }, + { SPH_C32(0xec1f0003), SPH_C32(0x0bcd0300), SPH_C32(0xa50e0000), + SPH_C32(0x7d3b0000), SPH_C32(0x0ff875fd), SPH_C32(0x14f30e93), + SPH_C32(0x693d6a3f), SPH_C32(0xd7ed8cdc), SPH_C32(0x81f40007), + SPH_C32(0x9253a400), SPH_C32(0xe6930000), SPH_C32(0xc56d0000), + SPH_C32(0x68026bff), SPH_C32(0xe0943b56), SPH_C32(0xf9a4651f), + SPH_C32(0x500ca2c7) }, + { SPH_C32(0x54220003), SPH_C32(0x1dbc0500), SPH_C32(0x92940000), + SPH_C32(0x888a0000), SPH_C32(0x2d791451), SPH_C32(0xbabbffd6), + SPH_C32(0x0f197c29), SPH_C32(0x122c67e2), SPH_C32(0x7cd10007), + SPH_C32(0x2197b500), SPH_C32(0x28630000), SPH_C32(0x0b940000), + SPH_C32(0x544f1e7f), SPH_C32(0x6dcf5fc5), SPH_C32(0x893cd5b9), + SPH_C32(0x4afebd26) }, + { SPH_C32(0x99bb0003), SPH_C32(0xc9462400), SPH_C32(0x31aa0000), + SPH_C32(0xedce0000), SPH_C32(0xf480221d), SPH_C32(0x5d3d053d), + SPH_C32(0x7e5aaebc), SPH_C32(0x7932eaa2), SPH_C32(0x50920007), + SPH_C32(0x89efa700), SPH_C32(0x787f0000), SPH_C32(0x33f90000), + SPH_C32(0x6b002ed8), SPH_C32(0x2fe4c7a4), SPH_C32(0x4de77e08), + SPH_C32(0xd5739eec) }, + { SPH_C32(0x21860003), SPH_C32(0xdf372200), SPH_C32(0x06300000), + SPH_C32(0x187f0000), SPH_C32(0xd60143b1), SPH_C32(0xf375f478), + SPH_C32(0x187eb8aa), SPH_C32(0xbcf3019c), SPH_C32(0xadb70007), + SPH_C32(0x3a2bb600), SPH_C32(0xb68f0000), SPH_C32(0xfd000000), + SPH_C32(0x574d5b58), SPH_C32(0xa2bfa337), SPH_C32(0x3d7fceae), + SPH_C32(0xcf81810d) }, + { SPH_C32(0x50ff0004), SPH_C32(0x45744000), SPH_C32(0x3dfb0000), + SPH_C32(0x19e60000), SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), + SPH_C32(0xe1a8cc96), SPH_C32(0x7b1bd6b9), SPH_C32(0xf6800005), + SPH_C32(0x3443c000), SPH_C32(0x24070000), SPH_C32(0x8f3d0000), + SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), SPH_C32(0xcdc58b19), + SPH_C32(0xd795ba31) }, + { SPH_C32(0xe8c20004), SPH_C32(0x53054600), SPH_C32(0x0a610000), + SPH_C32(0xec570000), SPH_C32(0x393d37aa), SPH_C32(0x4f3a8a18), + SPH_C32(0x878cda80), SPH_C32(0xbeda3d87), SPH_C32(0x0ba50005), + SPH_C32(0x8787d100), SPH_C32(0xeaf70000), SPH_C32(0x41c40000), + SPH_C32(0x1d7a4e7b), SPH_C32(0x87e3b13d), SPH_C32(0xbd5d3bbf), + SPH_C32(0xcd67a5d0) }, + { SPH_C32(0x255b0004), SPH_C32(0x87ff6700), SPH_C32(0xa95f0000), + SPH_C32(0x89130000), SPH_C32(0xe0c401e6), SPH_C32(0xa8bc70f3), + SPH_C32(0xf6cf0815), SPH_C32(0xd5c4b0c7), SPH_C32(0x27e60005), + SPH_C32(0x2fffc300), SPH_C32(0xbaeb0000), SPH_C32(0x79a90000), + SPH_C32(0x22357edc), SPH_C32(0xc5c8295c), SPH_C32(0x7986900e), + SPH_C32(0x52ea861a) }, + { SPH_C32(0x9d660004), SPH_C32(0x918e6100), SPH_C32(0x9ec50000), + SPH_C32(0x7ca20000), SPH_C32(0xc245604a), SPH_C32(0x06f481b6), + SPH_C32(0x90eb1e03), SPH_C32(0x10055bf9), SPH_C32(0xdac30005), + SPH_C32(0x9c3bd200), SPH_C32(0x741b0000), SPH_C32(0xb7500000), + SPH_C32(0x1e780b5c), SPH_C32(0x48934dcf), SPH_C32(0x091e20a8), + SPH_C32(0x481899fb) }, + { SPH_C32(0x81990004), SPH_C32(0x5ec84300), SPH_C32(0xa3170000), + SPH_C32(0xef720000), SPH_C32(0x18be1321), SPH_C32(0x2e0287af), + SPH_C32(0x55ebd781), SPH_C32(0xfe64ea92), SPH_C32(0x52420005), + SPH_C32(0xed74e400), SPH_C32(0x2e4f0000), SPH_C32(0xe95c0000), + SPH_C32(0xd94d293c), SPH_C32(0x8c0622f2), SPH_C32(0x6ee1548d), + SPH_C32(0xfc35e064) }, + { SPH_C32(0x39a40004), SPH_C32(0x48b94500), SPH_C32(0x948d0000), + SPH_C32(0x1ac30000), SPH_C32(0x3a3f728d), SPH_C32(0x804a76ea), + SPH_C32(0x33cfc197), SPH_C32(0x3ba501ac), SPH_C32(0xaf670005), + SPH_C32(0x5eb0f500), SPH_C32(0xe0bf0000), SPH_C32(0x27a50000), + SPH_C32(0xe5005cbc), SPH_C32(0x015d4661), SPH_C32(0x1e79e42b), + SPH_C32(0xe6c7ff85) }, + { SPH_C32(0xf43d0004), SPH_C32(0x9c436400), SPH_C32(0x37b30000), + SPH_C32(0x7f870000), SPH_C32(0xe3c644c1), SPH_C32(0x67cc8c01), + SPH_C32(0x428c1302), SPH_C32(0x50bb8cec), SPH_C32(0x83240005), + SPH_C32(0xf6c8e700), SPH_C32(0xb0a30000), SPH_C32(0x1fc80000), + SPH_C32(0xda4f6c1b), SPH_C32(0x4376de00), SPH_C32(0xdaa24f9a), + SPH_C32(0x794adc4f) }, + { SPH_C32(0x4c000004), SPH_C32(0x8a326200), SPH_C32(0x00290000), + SPH_C32(0x8a360000), SPH_C32(0xc147256d), SPH_C32(0xc9847d44), + SPH_C32(0x24a80514), SPH_C32(0x957a67d2), SPH_C32(0x7e010005), + SPH_C32(0x450cf600), SPH_C32(0x7e530000), SPH_C32(0xd1310000), + SPH_C32(0xe602199b), SPH_C32(0xce2dba93), SPH_C32(0xaa3aff3c), + SPH_C32(0x63b8c3ae) }, + { SPH_C32(0x25360007), SPH_C32(0x4b648000), SPH_C32(0xecdb0000), + SPH_C32(0xa30c0000), SPH_C32(0x90787938), SPH_C32(0x662acc0a), + SPH_C32(0x5a80ba8b), SPH_C32(0x7bacf892), SPH_C32(0x184f0004), + SPH_C32(0x5b158000), SPH_C32(0xd7390000), SPH_C32(0x28a30000), + SPH_C32(0x9c8249e2), SPH_C32(0xbda93e6b), SPH_C32(0x87fecba3), + SPH_C32(0x293e4865) }, + { SPH_C32(0x9d0b0007), SPH_C32(0x5d158600), SPH_C32(0xdb410000), + SPH_C32(0x56bd0000), SPH_C32(0xb2f91894), SPH_C32(0xc8623d4f), + SPH_C32(0x3ca4ac9d), SPH_C32(0xbe6d13ac), SPH_C32(0xe56a0004), + SPH_C32(0xe8d19100), SPH_C32(0x19c90000), SPH_C32(0xe65a0000), + SPH_C32(0xa0cf3c62), SPH_C32(0x30f25af8), SPH_C32(0xf7667b05), + SPH_C32(0x33cc5784) }, + { SPH_C32(0x50920007), SPH_C32(0x89efa700), SPH_C32(0x787f0000), + SPH_C32(0x33f90000), SPH_C32(0x6b002ed8), SPH_C32(0x2fe4c7a4), + SPH_C32(0x4de77e08), SPH_C32(0xd5739eec), SPH_C32(0xc9290004), + SPH_C32(0x40a98300), SPH_C32(0x49d50000), SPH_C32(0xde370000), + SPH_C32(0x9f800cc5), SPH_C32(0x72d9c299), SPH_C32(0x33bdd0b4), + SPH_C32(0xac41744e) }, + { SPH_C32(0xe8af0007), SPH_C32(0x9f9ea100), SPH_C32(0x4fe50000), + SPH_C32(0xc6480000), SPH_C32(0x49814f74), SPH_C32(0x81ac36e1), + SPH_C32(0x2bc3681e), SPH_C32(0x10b275d2), SPH_C32(0x340c0004), + SPH_C32(0xf36d9200), SPH_C32(0x87250000), SPH_C32(0x10ce0000), + SPH_C32(0xa3cd7945), SPH_C32(0xff82a60a), SPH_C32(0x43256012), + SPH_C32(0xb6b36baf) }, + { SPH_C32(0xf4500007), SPH_C32(0x50d88300), SPH_C32(0x72370000), + SPH_C32(0x55980000), SPH_C32(0x937a3c1f), SPH_C32(0xa95a30f8), + SPH_C32(0xeec3a19c), SPH_C32(0xfed3c4b9), SPH_C32(0xbc8d0004), + SPH_C32(0x8222a400), SPH_C32(0xdd710000), SPH_C32(0x4ec20000), + SPH_C32(0x64f85b25), SPH_C32(0x3b17c937), SPH_C32(0x24da1437), + SPH_C32(0x029e1230) }, + { SPH_C32(0x4c6d0007), SPH_C32(0x46a98500), SPH_C32(0x45ad0000), + SPH_C32(0xa0290000), SPH_C32(0xb1fb5db3), SPH_C32(0x0712c1bd), + SPH_C32(0x88e7b78a), SPH_C32(0x3b122f87), SPH_C32(0x41a80004), + SPH_C32(0x31e6b500), SPH_C32(0x13810000), SPH_C32(0x803b0000), + SPH_C32(0x58b52ea5), SPH_C32(0xb64cada4), SPH_C32(0x5442a491), + SPH_C32(0x186c0dd1) }, + { SPH_C32(0x81f40007), SPH_C32(0x9253a400), SPH_C32(0xe6930000), + SPH_C32(0xc56d0000), SPH_C32(0x68026bff), SPH_C32(0xe0943b56), + SPH_C32(0xf9a4651f), SPH_C32(0x500ca2c7), SPH_C32(0x6deb0004), + SPH_C32(0x999ea700), SPH_C32(0x439d0000), SPH_C32(0xb8560000), + SPH_C32(0x67fa1e02), SPH_C32(0xf46735c5), SPH_C32(0x90990f20), + SPH_C32(0x87e12e1b) }, + { SPH_C32(0x39c90007), SPH_C32(0x8422a200), SPH_C32(0xd1090000), + SPH_C32(0x30dc0000), SPH_C32(0x4a830a53), SPH_C32(0x4edcca13), + SPH_C32(0x9f807309), SPH_C32(0x95cd49f9), SPH_C32(0x90ce0004), + SPH_C32(0x2a5ab600), SPH_C32(0x8d6d0000), SPH_C32(0x76af0000), + SPH_C32(0x5bb76b82), SPH_C32(0x793c5156), SPH_C32(0xe001bf86), + SPH_C32(0x9d1331fa) }, + { SPH_C32(0xbe300005), SPH_C32(0x2a220000), SPH_C32(0xcec50000), + SPH_C32(0xbe780000), SPH_C32(0xa609241f), SPH_C32(0x56639098), + SPH_C32(0xab938c2c), SPH_C32(0x85b024ed), SPH_C32(0x6d860007), + SPH_C32(0x55054000), SPH_C32(0x06190000), SPH_C32(0x92490000), + SPH_C32(0x174666dc), SPH_C32(0x3af1893c), SPH_C32(0x3cd6bdbe), + SPH_C32(0x2989664e) }, + { SPH_C32(0x060d0005), SPH_C32(0x3c530600), SPH_C32(0xf95f0000), + SPH_C32(0x4bc90000), SPH_C32(0x848845b3), SPH_C32(0xf82b61dd), + SPH_C32(0xcdb79a3a), SPH_C32(0x4071cfd3), SPH_C32(0x90a30007), + SPH_C32(0xe6c15100), SPH_C32(0xc8e90000), SPH_C32(0x5cb00000), + SPH_C32(0x2b0b135c), SPH_C32(0xb7aaedaf), SPH_C32(0x4c4e0d18), + SPH_C32(0x337b79af) }, + { SPH_C32(0xcb940005), SPH_C32(0xe8a92700), SPH_C32(0x5a610000), + SPH_C32(0x2e8d0000), SPH_C32(0x5d7173ff), SPH_C32(0x1fad9b36), + SPH_C32(0xbcf448af), SPH_C32(0x2b6f4293), SPH_C32(0xbce00007), + SPH_C32(0x4eb94300), SPH_C32(0x98f50000), SPH_C32(0x64dd0000), + SPH_C32(0x144423fb), SPH_C32(0xf58175ce), SPH_C32(0x8895a6a9), + SPH_C32(0xacf65a65) }, + { SPH_C32(0x73a90005), SPH_C32(0xfed82100), SPH_C32(0x6dfb0000), + SPH_C32(0xdb3c0000), SPH_C32(0x7ff01253), SPH_C32(0xb1e56a73), + SPH_C32(0xdad05eb9), SPH_C32(0xeeaea9ad), SPH_C32(0x41c50007), + SPH_C32(0xfd7d5200), SPH_C32(0x56050000), SPH_C32(0xaa240000), + SPH_C32(0x2809567b), SPH_C32(0x78da115d), SPH_C32(0xf80d160f), + SPH_C32(0xb6044584) }, + { SPH_C32(0x6f560005), SPH_C32(0x319e0300), SPH_C32(0x50290000), + SPH_C32(0x48ec0000), SPH_C32(0xa50b6138), SPH_C32(0x99136c6a), + SPH_C32(0x1fd0973b), SPH_C32(0x00cf18c6), SPH_C32(0xc9440007), + SPH_C32(0x8c326400), SPH_C32(0x0c510000), SPH_C32(0xf4280000), + SPH_C32(0xef3c741b), SPH_C32(0xbc4f7e60), SPH_C32(0x9ff2622a), + SPH_C32(0x02293c1b) }, + { SPH_C32(0xd76b0005), SPH_C32(0x27ef0500), SPH_C32(0x67b30000), + SPH_C32(0xbd5d0000), SPH_C32(0x878a0094), SPH_C32(0x375b9d2f), + SPH_C32(0x79f4812d), SPH_C32(0xc50ef3f8), SPH_C32(0x34610007), + SPH_C32(0x3ff67500), SPH_C32(0xc2a10000), SPH_C32(0x3ad10000), + SPH_C32(0xd371019b), SPH_C32(0x31141af3), SPH_C32(0xef6ad28c), + SPH_C32(0x18db23fa) }, + { SPH_C32(0x1af20005), SPH_C32(0xf3152400), SPH_C32(0xc48d0000), + SPH_C32(0xd8190000), SPH_C32(0x5e7336d8), SPH_C32(0xd0dd67c4), + SPH_C32(0x08b753b8), SPH_C32(0xae107eb8), SPH_C32(0x18220007), + SPH_C32(0x978e6700), SPH_C32(0x92bd0000), SPH_C32(0x02bc0000), + SPH_C32(0xec3e313c), SPH_C32(0x733f8292), SPH_C32(0x2bb1793d), + SPH_C32(0x87560030) }, + { SPH_C32(0xa2cf0005), SPH_C32(0xe5642200), SPH_C32(0xf3170000), + SPH_C32(0x2da80000), SPH_C32(0x7cf25774), SPH_C32(0x7e959681), + SPH_C32(0x6e9345ae), SPH_C32(0x6bd19586), SPH_C32(0xe5070007), + SPH_C32(0x244a7600), SPH_C32(0x5c4d0000), SPH_C32(0xcc450000), + SPH_C32(0xd07344bc), SPH_C32(0xfe64e601), SPH_C32(0x5b29c99b), + SPH_C32(0x9da41fd1) }, + { SPH_C32(0xcbf90006), SPH_C32(0x2432c000), SPH_C32(0x1fe50000), + SPH_C32(0x04920000), SPH_C32(0x2dcd0b21), SPH_C32(0xd13b27cf), + SPH_C32(0x10bbfa31), SPH_C32(0x85070ac6), SPH_C32(0x83490006), + SPH_C32(0x3a530000), SPH_C32(0xf5270000), SPH_C32(0x35d70000), + SPH_C32(0xaaf314c5), SPH_C32(0x8de062f9), SPH_C32(0x76edfd04), + SPH_C32(0xd722941a) }, + { SPH_C32(0x73c40006), SPH_C32(0x3243c600), SPH_C32(0x287f0000), + SPH_C32(0xf1230000), SPH_C32(0x0f4c6a8d), SPH_C32(0x7f73d68a), + SPH_C32(0x769fec27), SPH_C32(0x40c6e1f8), SPH_C32(0x7e6c0006), + SPH_C32(0x89971100), SPH_C32(0x3bd70000), SPH_C32(0xfb2e0000), + SPH_C32(0x96be6145), SPH_C32(0x00bb066a), SPH_C32(0x06754da2), + SPH_C32(0xcdd08bfb) }, + { SPH_C32(0xbe5d0006), SPH_C32(0xe6b9e700), SPH_C32(0x8b410000), + SPH_C32(0x94670000), SPH_C32(0xd6b55cc1), SPH_C32(0x98f52c61), + SPH_C32(0x07dc3eb2), SPH_C32(0x2bd86cb8), SPH_C32(0x522f0006), + SPH_C32(0x21ef0300), SPH_C32(0x6bcb0000), SPH_C32(0xc3430000), + SPH_C32(0xa9f151e2), SPH_C32(0x42909e0b), SPH_C32(0xc2aee613), + SPH_C32(0x525da831) }, + { SPH_C32(0x06600006), SPH_C32(0xf0c8e100), SPH_C32(0xbcdb0000), + SPH_C32(0x61d60000), SPH_C32(0xf4343d6d), SPH_C32(0x36bddd24), + SPH_C32(0x61f828a4), SPH_C32(0xee198786), SPH_C32(0xaf0a0006), + SPH_C32(0x922b1200), SPH_C32(0xa53b0000), SPH_C32(0x0dba0000), + SPH_C32(0x95bc2462), SPH_C32(0xcfcbfa98), SPH_C32(0xb23656b5), + SPH_C32(0x48afb7d0) }, + { SPH_C32(0x1a9f0006), SPH_C32(0x3f8ec300), SPH_C32(0x81090000), + SPH_C32(0xf2060000), SPH_C32(0x2ecf4e06), SPH_C32(0x1e4bdb3d), + SPH_C32(0xa4f8e126), SPH_C32(0x007836ed), SPH_C32(0x278b0006), + SPH_C32(0xe3642400), SPH_C32(0xff6f0000), SPH_C32(0x53b60000), + SPH_C32(0x52890602), SPH_C32(0x0b5e95a5), SPH_C32(0xd5c92290), + SPH_C32(0xfc82ce4f) }, + { SPH_C32(0xa2a20006), SPH_C32(0x29ffc500), SPH_C32(0xb6930000), + SPH_C32(0x07b70000), SPH_C32(0x0c4e2faa), SPH_C32(0xb0032a78), + SPH_C32(0xc2dcf730), SPH_C32(0xc5b9ddd3), SPH_C32(0xdaae0006), + SPH_C32(0x50a03500), SPH_C32(0x319f0000), SPH_C32(0x9d4f0000), + SPH_C32(0x6ec47382), SPH_C32(0x8605f136), SPH_C32(0xa5519236), + SPH_C32(0xe670d1ae) }, + { SPH_C32(0x6f3b0006), SPH_C32(0xfd05e400), SPH_C32(0x15ad0000), + SPH_C32(0x62f30000), SPH_C32(0xd5b719e6), SPH_C32(0x5785d093), + SPH_C32(0xb39f25a5), SPH_C32(0xaea75093), SPH_C32(0xf6ed0006), + SPH_C32(0xf8d82700), SPH_C32(0x61830000), SPH_C32(0xa5220000), + SPH_C32(0x518b4325), SPH_C32(0xc42e6957), SPH_C32(0x618a3987), + SPH_C32(0x79fdf264) }, + { SPH_C32(0xd7060006), SPH_C32(0xeb74e200), SPH_C32(0x22370000), + SPH_C32(0x97420000), SPH_C32(0xf736784a), SPH_C32(0xf9cd21d6), + SPH_C32(0xd5bb33b3), SPH_C32(0x6b66bbad), SPH_C32(0x0bc80006), + SPH_C32(0x4b1c3600), SPH_C32(0xaf730000), SPH_C32(0x6bdb0000), + SPH_C32(0x6dc636a5), SPH_C32(0x49750dc4), SPH_C32(0x11128921), + SPH_C32(0x630fed85) } +}; + +static const sph_u32 T512_21[128][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x54500000), SPH_C32(0x0671005c), SPH_C32(0x25ae0000), + SPH_C32(0x6a1e0000), SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), + SPH_C32(0xbfba18c3), SPH_C32(0x7e715d17), SPH_C32(0xbc8d0000), + SPH_C32(0xfc3b0018), SPH_C32(0x19830000), SPH_C32(0xd10b0000), + SPH_C32(0xae1878c4), SPH_C32(0x42a69856), SPH_C32(0x0012da37), + SPH_C32(0x2c3b504e) }, + { SPH_C32(0xbc8d0000), SPH_C32(0xfc3b0018), SPH_C32(0x19830000), + SPH_C32(0xd10b0000), SPH_C32(0xae1878c4), SPH_C32(0x42a69856), + SPH_C32(0x0012da37), SPH_C32(0x2c3b504e), SPH_C32(0xe8dd0000), + SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), SPH_C32(0xbb150000), + SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), SPH_C32(0xbfa8c2f4), + SPH_C32(0x524a0d59) }, + { SPH_C32(0xe8dd0000), SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), + SPH_C32(0xbb150000), SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), + SPH_C32(0xbfa8c2f4), SPH_C32(0x524a0d59), SPH_C32(0x54500000), + SPH_C32(0x0671005c), SPH_C32(0x25ae0000), SPH_C32(0x6a1e0000), + SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), SPH_C32(0xbfba18c3), + SPH_C32(0x7e715d17) }, + { SPH_C32(0x69510000), SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), + SPH_C32(0xac2f0000), SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), + SPH_C32(0x87ec287c), SPH_C32(0xbce1a3ce), SPH_C32(0xc6730000), + SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), SPH_C32(0x218d0000), + SPH_C32(0x23111587), SPH_C32(0x7913512f), SPH_C32(0x1d28ac88), + SPH_C32(0x378dd173) }, + { SPH_C32(0x3d010000), SPH_C32(0xd29000c0), SPH_C32(0xe68d0000), + SPH_C32(0xc6310000), SPH_C32(0xca304571), SPH_C32(0xa8ea90ce), + SPH_C32(0x385630bf), SPH_C32(0xc290fed9), SPH_C32(0x7afe0000), + SPH_C32(0x53b60014), SPH_C32(0xbd420000), SPH_C32(0xf0860000), + SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), SPH_C32(0x1d3a76bf), + SPH_C32(0x1bb6813d) }, + { SPH_C32(0xd5dc0000), SPH_C32(0x28da0084), SPH_C32(0xdaa00000), + SPH_C32(0x7d240000), SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), + SPH_C32(0x87fef24b), SPH_C32(0x90daf380), SPH_C32(0x2eae0000), + SPH_C32(0x55c70048), SPH_C32(0x98ec0000), SPH_C32(0x9a980000), + SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), SPH_C32(0xa2806e7c), + SPH_C32(0x65c7dc2a) }, + { SPH_C32(0x818c0000), SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), + SPH_C32(0x173a0000), SPH_C32(0x64283db5), SPH_C32(0xea4c0898), + SPH_C32(0x3844ea88), SPH_C32(0xeeabae97), SPH_C32(0x92230000), + SPH_C32(0xa9fc0050), SPH_C32(0x816f0000), SPH_C32(0x4b930000), + SPH_C32(0x0db45b58), SPH_C32(0x1f5dd43d), SPH_C32(0xa292b44b), + SPH_C32(0x49fc8c64) }, + { SPH_C32(0xc6730000), SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), + SPH_C32(0x218d0000), SPH_C32(0x23111587), SPH_C32(0x7913512f), + SPH_C32(0x1d28ac88), SPH_C32(0x378dd173), SPH_C32(0xaf220000), + SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), SPH_C32(0x8da20000), + SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), SPH_C32(0x9ac484f4), + SPH_C32(0x8b6c72bd) }, + { SPH_C32(0x92230000), SPH_C32(0xa9fc0050), SPH_C32(0x816f0000), + SPH_C32(0x4b930000), SPH_C32(0x0db45b58), SPH_C32(0x1f5dd43d), + SPH_C32(0xa292b44b), SPH_C32(0x49fc8c64), SPH_C32(0x13af0000), + SPH_C32(0x87570088), SPH_C32(0x7e610000), SPH_C32(0x5ca90000), + SPH_C32(0x699c66ed), SPH_C32(0xf511dca5), SPH_C32(0x9ad65ec3), + SPH_C32(0xa75722f3) }, + { SPH_C32(0x7afe0000), SPH_C32(0x53b60014), SPH_C32(0xbd420000), + SPH_C32(0xf0860000), SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), + SPH_C32(0x1d3a76bf), SPH_C32(0x1bb6813d), SPH_C32(0x47ff0000), + SPH_C32(0x812600d4), SPH_C32(0x5bcf0000), SPH_C32(0x36b70000), + SPH_C32(0x47392832), SPH_C32(0x935f59b7), SPH_C32(0x256c4600), + SPH_C32(0xd9267fe4) }, + { SPH_C32(0x2eae0000), SPH_C32(0x55c70048), SPH_C32(0x98ec0000), + SPH_C32(0x9a980000), SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), + SPH_C32(0xa2806e7c), SPH_C32(0x65c7dc2a), SPH_C32(0xfb720000), + SPH_C32(0x7d1d00cc), SPH_C32(0x424c0000), SPH_C32(0xe7bc0000), + SPH_C32(0xe92150f6), SPH_C32(0xd1f9c1e1), SPH_C32(0x257e9c37), + SPH_C32(0xf51d2faa) }, + { SPH_C32(0xaf220000), SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), + SPH_C32(0x8da20000), SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), + SPH_C32(0x9ac484f4), SPH_C32(0x8b6c72bd), SPH_C32(0x69510000), + SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), SPH_C32(0xac2f0000), + SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), SPH_C32(0x87ec287c), + SPH_C32(0xbce1a3ce) }, + { SPH_C32(0xfb720000), SPH_C32(0x7d1d00cc), SPH_C32(0x424c0000), + SPH_C32(0xe7bc0000), SPH_C32(0xe92150f6), SPH_C32(0xd1f9c1e1), + SPH_C32(0x257e9c37), SPH_C32(0xf51d2faa), SPH_C32(0xd5dc0000), + SPH_C32(0x28da0084), SPH_C32(0xdaa00000), SPH_C32(0x7d240000), + SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), SPH_C32(0x87fef24b), + SPH_C32(0x90daf380) }, + { SPH_C32(0x13af0000), SPH_C32(0x87570088), SPH_C32(0x7e610000), + SPH_C32(0x5ca90000), SPH_C32(0x699c66ed), SPH_C32(0xf511dca5), + SPH_C32(0x9ad65ec3), SPH_C32(0xa75722f3), SPH_C32(0x818c0000), + SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), SPH_C32(0x173a0000), + SPH_C32(0x64283db5), SPH_C32(0xea4c0898), SPH_C32(0x3844ea88), + SPH_C32(0xeeabae97) }, + { SPH_C32(0x47ff0000), SPH_C32(0x812600d4), SPH_C32(0x5bcf0000), + SPH_C32(0x36b70000), SPH_C32(0x47392832), SPH_C32(0x935f59b7), + SPH_C32(0x256c4600), SPH_C32(0xd9267fe4), SPH_C32(0x3d010000), + SPH_C32(0xd29000c0), SPH_C32(0xe68d0000), SPH_C32(0xc6310000), + SPH_C32(0xca304571), SPH_C32(0xa8ea90ce), SPH_C32(0x385630bf), + SPH_C32(0xc290fed9) }, + { SPH_C32(0x0c720000), SPH_C32(0x49e50f00), SPH_C32(0x42790000), + SPH_C32(0x5cea0000), SPH_C32(0x33aa301a), SPH_C32(0x15822514), + SPH_C32(0x95a34b7b), SPH_C32(0xb44b0090), SPH_C32(0xfe220000), + SPH_C32(0xa7580500), SPH_C32(0x25d10000), SPH_C32(0xf7600000), + SPH_C32(0x893178da), SPH_C32(0x1fd4f860), SPH_C32(0x4ed0a315), + SPH_C32(0xa123ff9f) }, + { SPH_C32(0x58220000), SPH_C32(0x4f940f5c), SPH_C32(0x67d70000), + SPH_C32(0x36f40000), SPH_C32(0x1d0f7ec5), SPH_C32(0x73cca006), + SPH_C32(0x2a1953b8), SPH_C32(0xca3a5d87), SPH_C32(0x42af0000), + SPH_C32(0x5b630518), SPH_C32(0x3c520000), SPH_C32(0x266b0000), + SPH_C32(0x2729001e), SPH_C32(0x5d726036), SPH_C32(0x4ec27922), + SPH_C32(0x8d18afd1) }, + { SPH_C32(0xb0ff0000), SPH_C32(0xb5de0f18), SPH_C32(0x5bfa0000), + SPH_C32(0x8de10000), SPH_C32(0x9db248de), SPH_C32(0x5724bd42), + SPH_C32(0x95b1914c), SPH_C32(0x987050de), SPH_C32(0x16ff0000), + SPH_C32(0x5d120544), SPH_C32(0x19fc0000), SPH_C32(0x4c750000), + SPH_C32(0x098c4ec1), SPH_C32(0x3b3ce524), SPH_C32(0xf17861e1), + SPH_C32(0xf369f2c6) }, + { SPH_C32(0xe4af0000), SPH_C32(0xb3af0f44), SPH_C32(0x7e540000), + SPH_C32(0xe7ff0000), SPH_C32(0xb3170601), SPH_C32(0x316a3850), + SPH_C32(0x2a0b898f), SPH_C32(0xe6010dc9), SPH_C32(0xaa720000), + SPH_C32(0xa129055c), SPH_C32(0x007f0000), SPH_C32(0x9d7e0000), + SPH_C32(0xa7943605), SPH_C32(0x799a7d72), SPH_C32(0xf16abbd6), + SPH_C32(0xdf52a288) }, + { SPH_C32(0x65230000), SPH_C32(0x9d040f9c), SPH_C32(0x815a0000), + SPH_C32(0xf0c50000), SPH_C32(0xd73f3bb4), SPH_C32(0xdb2630c8), + SPH_C32(0x124f6307), SPH_C32(0x08aaa35e), SPH_C32(0x38510000), + SPH_C32(0x08d5050c), SPH_C32(0x81100000), SPH_C32(0xd6ed0000), + SPH_C32(0xaa206d5d), SPH_C32(0x66c7a94f), SPH_C32(0x53f80f9d), + SPH_C32(0x96ae2eec) }, + { SPH_C32(0x31730000), SPH_C32(0x9b750fc0), SPH_C32(0xa4f40000), + SPH_C32(0x9adb0000), SPH_C32(0xf99a756b), SPH_C32(0xbd68b5da), + SPH_C32(0xadf57bc4), SPH_C32(0x76dbfe49), SPH_C32(0x84dc0000), + SPH_C32(0xf4ee0514), SPH_C32(0x98930000), SPH_C32(0x07e60000), + SPH_C32(0x04381599), SPH_C32(0x24613119), SPH_C32(0x53ead5aa), + SPH_C32(0xba957ea2) }, + { SPH_C32(0xd9ae0000), SPH_C32(0x613f0f84), SPH_C32(0x98d90000), + SPH_C32(0x21ce0000), SPH_C32(0x79274370), SPH_C32(0x9980a89e), + SPH_C32(0x125db930), SPH_C32(0x2491f310), SPH_C32(0xd08c0000), + SPH_C32(0xf29f0548), SPH_C32(0xbd3d0000), SPH_C32(0x6df80000), + SPH_C32(0x2a9d5b46), SPH_C32(0x422fb40b), SPH_C32(0xec50cd69), + SPH_C32(0xc4e423b5) }, + { SPH_C32(0x8dfe0000), SPH_C32(0x674e0fd8), SPH_C32(0xbd770000), + SPH_C32(0x4bd00000), SPH_C32(0x57820daf), SPH_C32(0xffce2d8c), + SPH_C32(0xade7a1f3), SPH_C32(0x5ae0ae07), SPH_C32(0x6c010000), + SPH_C32(0x0ea40550), SPH_C32(0xa4be0000), SPH_C32(0xbcf30000), + SPH_C32(0x84852382), SPH_C32(0x00892c5d), SPH_C32(0xec42175e), + SPH_C32(0xe8df73fb) }, + { SPH_C32(0xca010000), SPH_C32(0xe6680f0c), SPH_C32(0xe6b80000), + SPH_C32(0x7d670000), SPH_C32(0x10bb259d), SPH_C32(0x6c91743b), + SPH_C32(0x888be7f3), SPH_C32(0x83c6d1e3), SPH_C32(0x51000000), + SPH_C32(0xdc340590), SPH_C32(0x42330000), SPH_C32(0x7ac20000), + SPH_C32(0x4eb566f3), SPH_C32(0xa863bc93), SPH_C32(0xd41427e1), + SPH_C32(0x2a4f8d22) }, + { SPH_C32(0x9e510000), SPH_C32(0xe0190f50), SPH_C32(0xc3160000), + SPH_C32(0x17790000), SPH_C32(0x3e1e6b42), SPH_C32(0x0adff129), + SPH_C32(0x3731ff30), SPH_C32(0xfdb78cf4), SPH_C32(0xed8d0000), + SPH_C32(0x200f0588), SPH_C32(0x5bb00000), SPH_C32(0xabc90000), + SPH_C32(0xe0ad1e37), SPH_C32(0xeac524c5), SPH_C32(0xd406fdd6), + SPH_C32(0x0674dd6c) }, + { SPH_C32(0x768c0000), SPH_C32(0x1a530f14), SPH_C32(0xff3b0000), + SPH_C32(0xac6c0000), SPH_C32(0xbea35d59), SPH_C32(0x2e37ec6d), + SPH_C32(0x88993dc4), SPH_C32(0xaffd81ad), SPH_C32(0xb9dd0000), + SPH_C32(0x267e05d4), SPH_C32(0x7e1e0000), SPH_C32(0xc1d70000), + SPH_C32(0xce0850e8), SPH_C32(0x8c8ba1d7), SPH_C32(0x6bbce515), + SPH_C32(0x7805807b) }, + { SPH_C32(0x22dc0000), SPH_C32(0x1c220f48), SPH_C32(0xda950000), + SPH_C32(0xc6720000), SPH_C32(0x90061386), SPH_C32(0x4879697f), + SPH_C32(0x37232507), SPH_C32(0xd18cdcba), SPH_C32(0x05500000), + SPH_C32(0xda4505cc), SPH_C32(0x679d0000), SPH_C32(0x10dc0000), + SPH_C32(0x6010282c), SPH_C32(0xce2d3981), SPH_C32(0x6bae3f22), + SPH_C32(0x543ed035) }, + { SPH_C32(0xa3500000), SPH_C32(0x32890f90), SPH_C32(0x259b0000), + SPH_C32(0xd1480000), SPH_C32(0xf42e2e33), SPH_C32(0xa23561e7), + SPH_C32(0x0f67cf8f), SPH_C32(0x3f27722d), SPH_C32(0x97730000), + SPH_C32(0x73b9059c), SPH_C32(0xe6f20000), SPH_C32(0x5b4f0000), + SPH_C32(0x6da47374), SPH_C32(0xd170edbc), SPH_C32(0xc93c8b69), + SPH_C32(0x1dc25c51) }, + { SPH_C32(0xf7000000), SPH_C32(0x34f80fcc), SPH_C32(0x00350000), + SPH_C32(0xbb560000), SPH_C32(0xda8b60ec), SPH_C32(0xc47be4f5), + SPH_C32(0xb0ddd74c), SPH_C32(0x41562f3a), SPH_C32(0x2bfe0000), + SPH_C32(0x8f820584), SPH_C32(0xff710000), SPH_C32(0x8a440000), + SPH_C32(0xc3bc0bb0), SPH_C32(0x93d675ea), SPH_C32(0xc92e515e), + SPH_C32(0x31f90c1f) }, + { SPH_C32(0x1fdd0000), SPH_C32(0xceb20f88), SPH_C32(0x3c180000), + SPH_C32(0x00430000), SPH_C32(0x5a3656f7), SPH_C32(0xe093f9b1), + SPH_C32(0x0f7515b8), SPH_C32(0x131c2263), SPH_C32(0x7fae0000), + SPH_C32(0x89f305d8), SPH_C32(0xdadf0000), SPH_C32(0xe05a0000), + SPH_C32(0xed19456f), SPH_C32(0xf598f0f8), SPH_C32(0x7694499d), + SPH_C32(0x4f885108) }, + { SPH_C32(0x4b8d0000), SPH_C32(0xc8c30fd4), SPH_C32(0x19b60000), + SPH_C32(0x6a5d0000), SPH_C32(0x74931828), SPH_C32(0x86dd7ca3), + SPH_C32(0xb0cf0d7b), SPH_C32(0x6d6d7f74), SPH_C32(0xc3230000), + SPH_C32(0x75c805c0), SPH_C32(0xc35c0000), SPH_C32(0x31510000), + SPH_C32(0x43013dab), SPH_C32(0xb73e68ae), SPH_C32(0x768693aa), + SPH_C32(0x63b30146) }, + { SPH_C32(0xfe220000), SPH_C32(0xa7580500), SPH_C32(0x25d10000), + SPH_C32(0xf7600000), SPH_C32(0x893178da), SPH_C32(0x1fd4f860), + SPH_C32(0x4ed0a315), SPH_C32(0xa123ff9f), SPH_C32(0xf2500000), + SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), SPH_C32(0xab8a0000), + SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), SPH_C32(0xdb73e86e), + SPH_C32(0x1568ff0f) }, + { SPH_C32(0xaa720000), SPH_C32(0xa129055c), SPH_C32(0x007f0000), + SPH_C32(0x9d7e0000), SPH_C32(0xa7943605), SPH_C32(0x799a7d72), + SPH_C32(0xf16abbd6), SPH_C32(0xdf52a288), SPH_C32(0x4edd0000), + SPH_C32(0x12860a18), SPH_C32(0x7e2b0000), SPH_C32(0x7a810000), + SPH_C32(0x14833004), SPH_C32(0x48f04522), SPH_C32(0xdb613259), + SPH_C32(0x3953af41) }, + { SPH_C32(0x42af0000), SPH_C32(0x5b630518), SPH_C32(0x3c520000), + SPH_C32(0x266b0000), SPH_C32(0x2729001e), SPH_C32(0x5d726036), + SPH_C32(0x4ec27922), SPH_C32(0x8d18afd1), SPH_C32(0x1a8d0000), + SPH_C32(0x14f70a44), SPH_C32(0x5b850000), SPH_C32(0x109f0000), + SPH_C32(0x3a267edb), SPH_C32(0x2ebec030), SPH_C32(0x64db2a9a), + SPH_C32(0x4722f256) }, + { SPH_C32(0x16ff0000), SPH_C32(0x5d120544), SPH_C32(0x19fc0000), + SPH_C32(0x4c750000), SPH_C32(0x098c4ec1), SPH_C32(0x3b3ce524), + SPH_C32(0xf17861e1), SPH_C32(0xf369f2c6), SPH_C32(0xa6000000), + SPH_C32(0xe8cc0a5c), SPH_C32(0x42060000), SPH_C32(0xc1940000), + SPH_C32(0x943e061f), SPH_C32(0x6c185866), SPH_C32(0x64c9f0ad), + SPH_C32(0x6b19a218) }, + { SPH_C32(0x97730000), SPH_C32(0x73b9059c), SPH_C32(0xe6f20000), + SPH_C32(0x5b4f0000), SPH_C32(0x6da47374), SPH_C32(0xd170edbc), + SPH_C32(0xc93c8b69), SPH_C32(0x1dc25c51), SPH_C32(0x34230000), + SPH_C32(0x41300a0c), SPH_C32(0xc3690000), SPH_C32(0x8a070000), + SPH_C32(0x998a5d47), SPH_C32(0x73458c5b), SPH_C32(0xc65b44e6), + SPH_C32(0x22e52e7c) }, + { SPH_C32(0xc3230000), SPH_C32(0x75c805c0), SPH_C32(0xc35c0000), + SPH_C32(0x31510000), SPH_C32(0x43013dab), SPH_C32(0xb73e68ae), + SPH_C32(0x768693aa), SPH_C32(0x63b30146), SPH_C32(0x88ae0000), + SPH_C32(0xbd0b0a14), SPH_C32(0xdaea0000), SPH_C32(0x5b0c0000), + SPH_C32(0x37922583), SPH_C32(0x31e3140d), SPH_C32(0xc6499ed1), + SPH_C32(0x0ede7e32) }, + { SPH_C32(0x2bfe0000), SPH_C32(0x8f820584), SPH_C32(0xff710000), + SPH_C32(0x8a440000), SPH_C32(0xc3bc0bb0), SPH_C32(0x93d675ea), + SPH_C32(0xc92e515e), SPH_C32(0x31f90c1f), SPH_C32(0xdcfe0000), + SPH_C32(0xbb7a0a48), SPH_C32(0xff440000), SPH_C32(0x31120000), + SPH_C32(0x19376b5c), SPH_C32(0x57ad911f), SPH_C32(0x79f38612), + SPH_C32(0x70af2325) }, + { SPH_C32(0x7fae0000), SPH_C32(0x89f305d8), SPH_C32(0xdadf0000), + SPH_C32(0xe05a0000), SPH_C32(0xed19456f), SPH_C32(0xf598f0f8), + SPH_C32(0x7694499d), SPH_C32(0x4f885108), SPH_C32(0x60730000), + SPH_C32(0x47410a50), SPH_C32(0xe6c70000), SPH_C32(0xe0190000), + SPH_C32(0xb72f1398), SPH_C32(0x150b0949), SPH_C32(0x79e15c25), + SPH_C32(0x5c94736b) }, + { SPH_C32(0x38510000), SPH_C32(0x08d5050c), SPH_C32(0x81100000), + SPH_C32(0xd6ed0000), SPH_C32(0xaa206d5d), SPH_C32(0x66c7a94f), + SPH_C32(0x53f80f9d), SPH_C32(0x96ae2eec), SPH_C32(0x5d720000), + SPH_C32(0x95d10a90), SPH_C32(0x004a0000), SPH_C32(0x26280000), + SPH_C32(0x7d1f56e9), SPH_C32(0xbde19987), SPH_C32(0x41b76c9a), + SPH_C32(0x9e048db2) }, + { SPH_C32(0x6c010000), SPH_C32(0x0ea40550), SPH_C32(0xa4be0000), + SPH_C32(0xbcf30000), SPH_C32(0x84852382), SPH_C32(0x00892c5d), + SPH_C32(0xec42175e), SPH_C32(0xe8df73fb), SPH_C32(0xe1ff0000), + SPH_C32(0x69ea0a88), SPH_C32(0x19c90000), SPH_C32(0xf7230000), + SPH_C32(0xd3072e2d), SPH_C32(0xff4701d1), SPH_C32(0x41a5b6ad), + SPH_C32(0xb23fddfc) }, + { SPH_C32(0x84dc0000), SPH_C32(0xf4ee0514), SPH_C32(0x98930000), + SPH_C32(0x07e60000), SPH_C32(0x04381599), SPH_C32(0x24613119), + SPH_C32(0x53ead5aa), SPH_C32(0xba957ea2), SPH_C32(0xb5af0000), + SPH_C32(0x6f9b0ad4), SPH_C32(0x3c670000), SPH_C32(0x9d3d0000), + SPH_C32(0xfda260f2), SPH_C32(0x990984c3), SPH_C32(0xfe1fae6e), + SPH_C32(0xcc4e80eb) }, + { SPH_C32(0xd08c0000), SPH_C32(0xf29f0548), SPH_C32(0xbd3d0000), + SPH_C32(0x6df80000), SPH_C32(0x2a9d5b46), SPH_C32(0x422fb40b), + SPH_C32(0xec50cd69), SPH_C32(0xc4e423b5), SPH_C32(0x09220000), + SPH_C32(0x93a00acc), SPH_C32(0x25e40000), SPH_C32(0x4c360000), + SPH_C32(0x53ba1836), SPH_C32(0xdbaf1c95), SPH_C32(0xfe0d7459), + SPH_C32(0xe075d0a5) }, + { SPH_C32(0x51000000), SPH_C32(0xdc340590), SPH_C32(0x42330000), + SPH_C32(0x7ac20000), SPH_C32(0x4eb566f3), SPH_C32(0xa863bc93), + SPH_C32(0xd41427e1), SPH_C32(0x2a4f8d22), SPH_C32(0x9b010000), + SPH_C32(0x3a5c0a9c), SPH_C32(0xa48b0000), SPH_C32(0x07a50000), + SPH_C32(0x5e0e436e), SPH_C32(0xc4f2c8a8), SPH_C32(0x5c9fc012), + SPH_C32(0xa9895cc1) }, + { SPH_C32(0x05500000), SPH_C32(0xda4505cc), SPH_C32(0x679d0000), + SPH_C32(0x10dc0000), SPH_C32(0x6010282c), SPH_C32(0xce2d3981), + SPH_C32(0x6bae3f22), SPH_C32(0x543ed035), SPH_C32(0x278c0000), + SPH_C32(0xc6670a84), SPH_C32(0xbd080000), SPH_C32(0xd6ae0000), + SPH_C32(0xf0163baa), SPH_C32(0x865450fe), SPH_C32(0x5c8d1a25), + SPH_C32(0x85b20c8f) }, + { SPH_C32(0xed8d0000), SPH_C32(0x200f0588), SPH_C32(0x5bb00000), + SPH_C32(0xabc90000), SPH_C32(0xe0ad1e37), SPH_C32(0xeac524c5), + SPH_C32(0xd406fdd6), SPH_C32(0x0674dd6c), SPH_C32(0x73dc0000), + SPH_C32(0xc0160ad8), SPH_C32(0x98a60000), SPH_C32(0xbcb00000), + SPH_C32(0xdeb37575), SPH_C32(0xe01ad5ec), SPH_C32(0xe33702e6), + SPH_C32(0xfbc35198) }, + { SPH_C32(0xb9dd0000), SPH_C32(0x267e05d4), SPH_C32(0x7e1e0000), + SPH_C32(0xc1d70000), SPH_C32(0xce0850e8), SPH_C32(0x8c8ba1d7), + SPH_C32(0x6bbce515), SPH_C32(0x7805807b), SPH_C32(0xcf510000), + SPH_C32(0x3c2d0ac0), SPH_C32(0x81250000), SPH_C32(0x6dbb0000), + SPH_C32(0x70ab0db1), SPH_C32(0xa2bc4dba), SPH_C32(0xe325d8d1), + SPH_C32(0xd7f801d6) }, + { SPH_C32(0xf2500000), SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), + SPH_C32(0xab8a0000), SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), + SPH_C32(0xdb73e86e), SPH_C32(0x1568ff0f), SPH_C32(0x0c720000), + SPH_C32(0x49e50f00), SPH_C32(0x42790000), SPH_C32(0x5cea0000), + SPH_C32(0x33aa301a), SPH_C32(0x15822514), SPH_C32(0x95a34b7b), + SPH_C32(0xb44b0090) }, + { SPH_C32(0xa6000000), SPH_C32(0xe8cc0a5c), SPH_C32(0x42060000), + SPH_C32(0xc1940000), SPH_C32(0x943e061f), SPH_C32(0x6c185866), + SPH_C32(0x64c9f0ad), SPH_C32(0x6b19a218), SPH_C32(0xb0ff0000), + SPH_C32(0xb5de0f18), SPH_C32(0x5bfa0000), SPH_C32(0x8de10000), + SPH_C32(0x9db248de), SPH_C32(0x5724bd42), SPH_C32(0x95b1914c), + SPH_C32(0x987050de) }, + { SPH_C32(0x4edd0000), SPH_C32(0x12860a18), SPH_C32(0x7e2b0000), + SPH_C32(0x7a810000), SPH_C32(0x14833004), SPH_C32(0x48f04522), + SPH_C32(0xdb613259), SPH_C32(0x3953af41), SPH_C32(0xe4af0000), + SPH_C32(0xb3af0f44), SPH_C32(0x7e540000), SPH_C32(0xe7ff0000), + SPH_C32(0xb3170601), SPH_C32(0x316a3850), SPH_C32(0x2a0b898f), + SPH_C32(0xe6010dc9) }, + { SPH_C32(0x1a8d0000), SPH_C32(0x14f70a44), SPH_C32(0x5b850000), + SPH_C32(0x109f0000), SPH_C32(0x3a267edb), SPH_C32(0x2ebec030), + SPH_C32(0x64db2a9a), SPH_C32(0x4722f256), SPH_C32(0x58220000), + SPH_C32(0x4f940f5c), SPH_C32(0x67d70000), SPH_C32(0x36f40000), + SPH_C32(0x1d0f7ec5), SPH_C32(0x73cca006), SPH_C32(0x2a1953b8), + SPH_C32(0xca3a5d87) }, + { SPH_C32(0x9b010000), SPH_C32(0x3a5c0a9c), SPH_C32(0xa48b0000), + SPH_C32(0x07a50000), SPH_C32(0x5e0e436e), SPH_C32(0xc4f2c8a8), + SPH_C32(0x5c9fc012), SPH_C32(0xa9895cc1), SPH_C32(0xca010000), + SPH_C32(0xe6680f0c), SPH_C32(0xe6b80000), SPH_C32(0x7d670000), + SPH_C32(0x10bb259d), SPH_C32(0x6c91743b), SPH_C32(0x888be7f3), + SPH_C32(0x83c6d1e3) }, + { SPH_C32(0xcf510000), SPH_C32(0x3c2d0ac0), SPH_C32(0x81250000), + SPH_C32(0x6dbb0000), SPH_C32(0x70ab0db1), SPH_C32(0xa2bc4dba), + SPH_C32(0xe325d8d1), SPH_C32(0xd7f801d6), SPH_C32(0x768c0000), + SPH_C32(0x1a530f14), SPH_C32(0xff3b0000), SPH_C32(0xac6c0000), + SPH_C32(0xbea35d59), SPH_C32(0x2e37ec6d), SPH_C32(0x88993dc4), + SPH_C32(0xaffd81ad) }, + { SPH_C32(0x278c0000), SPH_C32(0xc6670a84), SPH_C32(0xbd080000), + SPH_C32(0xd6ae0000), SPH_C32(0xf0163baa), SPH_C32(0x865450fe), + SPH_C32(0x5c8d1a25), SPH_C32(0x85b20c8f), SPH_C32(0x22dc0000), + SPH_C32(0x1c220f48), SPH_C32(0xda950000), SPH_C32(0xc6720000), + SPH_C32(0x90061386), SPH_C32(0x4879697f), SPH_C32(0x37232507), + SPH_C32(0xd18cdcba) }, + { SPH_C32(0x73dc0000), SPH_C32(0xc0160ad8), SPH_C32(0x98a60000), + SPH_C32(0xbcb00000), SPH_C32(0xdeb37575), SPH_C32(0xe01ad5ec), + SPH_C32(0xe33702e6), SPH_C32(0xfbc35198), SPH_C32(0x9e510000), + SPH_C32(0xe0190f50), SPH_C32(0xc3160000), SPH_C32(0x17790000), + SPH_C32(0x3e1e6b42), SPH_C32(0x0adff129), SPH_C32(0x3731ff30), + SPH_C32(0xfdb78cf4) }, + { SPH_C32(0x34230000), SPH_C32(0x41300a0c), SPH_C32(0xc3690000), + SPH_C32(0x8a070000), SPH_C32(0x998a5d47), SPH_C32(0x73458c5b), + SPH_C32(0xc65b44e6), SPH_C32(0x22e52e7c), SPH_C32(0xa3500000), + SPH_C32(0x32890f90), SPH_C32(0x259b0000), SPH_C32(0xd1480000), + SPH_C32(0xf42e2e33), SPH_C32(0xa23561e7), SPH_C32(0x0f67cf8f), + SPH_C32(0x3f27722d) }, + { SPH_C32(0x60730000), SPH_C32(0x47410a50), SPH_C32(0xe6c70000), + SPH_C32(0xe0190000), SPH_C32(0xb72f1398), SPH_C32(0x150b0949), + SPH_C32(0x79e15c25), SPH_C32(0x5c94736b), SPH_C32(0x1fdd0000), + SPH_C32(0xceb20f88), SPH_C32(0x3c180000), SPH_C32(0x00430000), + SPH_C32(0x5a3656f7), SPH_C32(0xe093f9b1), SPH_C32(0x0f7515b8), + SPH_C32(0x131c2263) }, + { SPH_C32(0x88ae0000), SPH_C32(0xbd0b0a14), SPH_C32(0xdaea0000), + SPH_C32(0x5b0c0000), SPH_C32(0x37922583), SPH_C32(0x31e3140d), + SPH_C32(0xc6499ed1), SPH_C32(0x0ede7e32), SPH_C32(0x4b8d0000), + SPH_C32(0xc8c30fd4), SPH_C32(0x19b60000), SPH_C32(0x6a5d0000), + SPH_C32(0x74931828), SPH_C32(0x86dd7ca3), SPH_C32(0xb0cf0d7b), + SPH_C32(0x6d6d7f74) }, + { SPH_C32(0xdcfe0000), SPH_C32(0xbb7a0a48), SPH_C32(0xff440000), + SPH_C32(0x31120000), SPH_C32(0x19376b5c), SPH_C32(0x57ad911f), + SPH_C32(0x79f38612), SPH_C32(0x70af2325), SPH_C32(0xf7000000), + SPH_C32(0x34f80fcc), SPH_C32(0x00350000), SPH_C32(0xbb560000), + SPH_C32(0xda8b60ec), SPH_C32(0xc47be4f5), SPH_C32(0xb0ddd74c), + SPH_C32(0x41562f3a) }, + { SPH_C32(0x5d720000), SPH_C32(0x95d10a90), SPH_C32(0x004a0000), + SPH_C32(0x26280000), SPH_C32(0x7d1f56e9), SPH_C32(0xbde19987), + SPH_C32(0x41b76c9a), SPH_C32(0x9e048db2), SPH_C32(0x65230000), + SPH_C32(0x9d040f9c), SPH_C32(0x815a0000), SPH_C32(0xf0c50000), + SPH_C32(0xd73f3bb4), SPH_C32(0xdb2630c8), SPH_C32(0x124f6307), + SPH_C32(0x08aaa35e) }, + { SPH_C32(0x09220000), SPH_C32(0x93a00acc), SPH_C32(0x25e40000), + SPH_C32(0x4c360000), SPH_C32(0x53ba1836), SPH_C32(0xdbaf1c95), + SPH_C32(0xfe0d7459), SPH_C32(0xe075d0a5), SPH_C32(0xd9ae0000), + SPH_C32(0x613f0f84), SPH_C32(0x98d90000), SPH_C32(0x21ce0000), + SPH_C32(0x79274370), SPH_C32(0x9980a89e), SPH_C32(0x125db930), + SPH_C32(0x2491f310) }, + { SPH_C32(0xe1ff0000), SPH_C32(0x69ea0a88), SPH_C32(0x19c90000), + SPH_C32(0xf7230000), SPH_C32(0xd3072e2d), SPH_C32(0xff4701d1), + SPH_C32(0x41a5b6ad), SPH_C32(0xb23fddfc), SPH_C32(0x8dfe0000), + SPH_C32(0x674e0fd8), SPH_C32(0xbd770000), SPH_C32(0x4bd00000), + SPH_C32(0x57820daf), SPH_C32(0xffce2d8c), SPH_C32(0xade7a1f3), + SPH_C32(0x5ae0ae07) }, + { SPH_C32(0xb5af0000), SPH_C32(0x6f9b0ad4), SPH_C32(0x3c670000), + SPH_C32(0x9d3d0000), SPH_C32(0xfda260f2), SPH_C32(0x990984c3), + SPH_C32(0xfe1fae6e), SPH_C32(0xcc4e80eb), SPH_C32(0x31730000), + SPH_C32(0x9b750fc0), SPH_C32(0xa4f40000), SPH_C32(0x9adb0000), + SPH_C32(0xf99a756b), SPH_C32(0xbd68b5da), SPH_C32(0xadf57bc4), + SPH_C32(0x76dbfe49) }, + { SPH_C32(0x45180000), SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), + SPH_C32(0x3b480000), SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), + SPH_C32(0x16bca6b0), SPH_C32(0xdf33f4df), SPH_C32(0xb83d0000), + SPH_C32(0x16710600), SPH_C32(0x379a0000), SPH_C32(0xf5b10000), + SPH_C32(0x228161ac), SPH_C32(0xae48f145), SPH_C32(0x66241616), + SPH_C32(0xc5c1eb3e) }, + { SPH_C32(0x11480000), SPH_C32(0xa3c4175c), SPH_C32(0xdcc40000), + SPH_C32(0x51560000), SPH_C32(0x30695af3), SPH_C32(0x455d10c4), + SPH_C32(0xa906be73), SPH_C32(0xa142a9c8), SPH_C32(0x04b00000), + SPH_C32(0xea4a0618), SPH_C32(0x2e190000), SPH_C32(0x24ba0000), + SPH_C32(0x8c991968), SPH_C32(0xecee6913), SPH_C32(0x6636cc21), + SPH_C32(0xe9fabb70) }, + { SPH_C32(0xf9950000), SPH_C32(0x598e1718), SPH_C32(0xe0e90000), + SPH_C32(0xea430000), SPH_C32(0xb0d46ce8), SPH_C32(0x61b50d80), + SPH_C32(0x16ae7c87), SPH_C32(0xf308a491), SPH_C32(0x50e00000), + SPH_C32(0xec3b0644), SPH_C32(0x0bb70000), SPH_C32(0x4ea40000), + SPH_C32(0xa23c57b7), SPH_C32(0x8aa0ec01), SPH_C32(0xd98cd4e2), + SPH_C32(0x978be667) }, + { SPH_C32(0xadc50000), SPH_C32(0x5fff1744), SPH_C32(0xc5470000), + SPH_C32(0x805d0000), SPH_C32(0x9e712237), SPH_C32(0x07fb8892), + SPH_C32(0xa9146444), SPH_C32(0x8d79f986), SPH_C32(0xec6d0000), + SPH_C32(0x1000065c), SPH_C32(0x12340000), SPH_C32(0x9faf0000), + SPH_C32(0x0c242f73), SPH_C32(0xc8067457), SPH_C32(0xd99e0ed5), + SPH_C32(0xbbb0b629) }, + { SPH_C32(0x2c490000), SPH_C32(0x7154179c), SPH_C32(0x3a490000), + SPH_C32(0x97670000), SPH_C32(0xfa591f82), SPH_C32(0xedb7800a), + SPH_C32(0x91508ecc), SPH_C32(0x63d25711), SPH_C32(0x7e4e0000), + SPH_C32(0xb9fc060c), SPH_C32(0x935b0000), SPH_C32(0xd43c0000), + SPH_C32(0x0190742b), SPH_C32(0xd75ba06a), SPH_C32(0x7b0cba9e), + SPH_C32(0xf24c3a4d) }, + { SPH_C32(0x78190000), SPH_C32(0x772517c0), SPH_C32(0x1fe70000), + SPH_C32(0xfd790000), SPH_C32(0xd4fc515d), SPH_C32(0x8bf90518), + SPH_C32(0x2eea960f), SPH_C32(0x1da30a06), SPH_C32(0xc2c30000), + SPH_C32(0x45c70614), SPH_C32(0x8ad80000), SPH_C32(0x05370000), + SPH_C32(0xaf880cef), SPH_C32(0x95fd383c), SPH_C32(0x7b1e60a9), + SPH_C32(0xde776a03) }, + { SPH_C32(0x90c40000), SPH_C32(0x8d6f1784), SPH_C32(0x23ca0000), + SPH_C32(0x466c0000), SPH_C32(0x54416746), SPH_C32(0xaf11185c), + SPH_C32(0x914254fb), SPH_C32(0x4fe9075f), SPH_C32(0x96930000), + SPH_C32(0x43b60648), SPH_C32(0xaf760000), SPH_C32(0x6f290000), + SPH_C32(0x812d4230), SPH_C32(0xf3b3bd2e), SPH_C32(0xc4a4786a), + SPH_C32(0xa0063714) }, + { SPH_C32(0xc4940000), SPH_C32(0x8b1e17d8), SPH_C32(0x06640000), + SPH_C32(0x2c720000), SPH_C32(0x7ae42999), SPH_C32(0xc95f9d4e), + SPH_C32(0x2ef84c38), SPH_C32(0x31985a48), SPH_C32(0x2a1e0000), + SPH_C32(0xbf8d0650), SPH_C32(0xb6f50000), SPH_C32(0xbe220000), + SPH_C32(0x2f353af4), SPH_C32(0xb1152578), SPH_C32(0xc4b6a25d), + SPH_C32(0x8c3d675a) }, + { SPH_C32(0x836b0000), SPH_C32(0x0a38170c), SPH_C32(0x5dab0000), + SPH_C32(0x1ac50000), SPH_C32(0x3ddd01ab), SPH_C32(0x5a00c4f9), + SPH_C32(0x0b940a38), SPH_C32(0xe8be25ac), SPH_C32(0x171f0000), + SPH_C32(0x6d1d0690), SPH_C32(0x50780000), SPH_C32(0x78130000), + SPH_C32(0xe5057f85), SPH_C32(0x19ffb5b6), SPH_C32(0xfce092e2), + SPH_C32(0x4ead9983) }, + { SPH_C32(0xd73b0000), SPH_C32(0x0c491750), SPH_C32(0x78050000), + SPH_C32(0x70db0000), SPH_C32(0x13784f74), SPH_C32(0x3c4e41eb), + SPH_C32(0xb42e12fb), SPH_C32(0x96cf78bb), SPH_C32(0xab920000), + SPH_C32(0x91260688), SPH_C32(0x49fb0000), SPH_C32(0xa9180000), + SPH_C32(0x4b1d0741), SPH_C32(0x5b592de0), SPH_C32(0xfcf248d5), + SPH_C32(0x6296c9cd) }, + { SPH_C32(0x3fe60000), SPH_C32(0xf6031714), SPH_C32(0x44280000), + SPH_C32(0xcbce0000), SPH_C32(0x93c5796f), SPH_C32(0x18a65caf), + SPH_C32(0x0b86d00f), SPH_C32(0xc48575e2), SPH_C32(0xffc20000), + SPH_C32(0x975706d4), SPH_C32(0x6c550000), SPH_C32(0xc3060000), + SPH_C32(0x65b8499e), SPH_C32(0x3d17a8f2), SPH_C32(0x43485016), + SPH_C32(0x1ce794da) }, + { SPH_C32(0x6bb60000), SPH_C32(0xf0721748), SPH_C32(0x61860000), + SPH_C32(0xa1d00000), SPH_C32(0xbd6037b0), SPH_C32(0x7ee8d9bd), + SPH_C32(0xb43cc8cc), SPH_C32(0xbaf428f5), SPH_C32(0x434f0000), + SPH_C32(0x6b6c06cc), SPH_C32(0x75d60000), SPH_C32(0x120d0000), + SPH_C32(0xcba0315a), SPH_C32(0x7fb130a4), SPH_C32(0x435a8a21), + SPH_C32(0x30dcc494) }, + { SPH_C32(0xea3a0000), SPH_C32(0xded91790), SPH_C32(0x9e880000), + SPH_C32(0xb6ea0000), SPH_C32(0xd9480a05), SPH_C32(0x94a4d125), + SPH_C32(0x8c782244), SPH_C32(0x545f8662), SPH_C32(0xd16c0000), + SPH_C32(0xc290069c), SPH_C32(0xf4b90000), SPH_C32(0x599e0000), + SPH_C32(0xc6146a02), SPH_C32(0x60ece499), SPH_C32(0xe1c83e6a), + SPH_C32(0x792048f0) }, + { SPH_C32(0xbe6a0000), SPH_C32(0xd8a817cc), SPH_C32(0xbb260000), + SPH_C32(0xdcf40000), SPH_C32(0xf7ed44da), SPH_C32(0xf2ea5437), + SPH_C32(0x33c23a87), SPH_C32(0x2a2edb75), SPH_C32(0x6de10000), + SPH_C32(0x3eab0684), SPH_C32(0xed3a0000), SPH_C32(0x88950000), + SPH_C32(0x680c12c6), SPH_C32(0x224a7ccf), SPH_C32(0xe1dae45d), + SPH_C32(0x551b18be) }, + { SPH_C32(0x56b70000), SPH_C32(0x22e21788), SPH_C32(0x870b0000), + SPH_C32(0x67e10000), SPH_C32(0x775072c1), SPH_C32(0xd6024973), + SPH_C32(0x8c6af873), SPH_C32(0x7864d62c), SPH_C32(0x39b10000), + SPH_C32(0x38da06d8), SPH_C32(0xc8940000), SPH_C32(0xe28b0000), + SPH_C32(0x46a95c19), SPH_C32(0x4404f9dd), SPH_C32(0x5e60fc9e), + SPH_C32(0x2b6a45a9) }, + { SPH_C32(0x02e70000), SPH_C32(0x249317d4), SPH_C32(0xa2a50000), + SPH_C32(0x0dff0000), SPH_C32(0x59f53c1e), SPH_C32(0xb04ccc61), + SPH_C32(0x33d0e0b0), SPH_C32(0x06158b3b), SPH_C32(0x853c0000), + SPH_C32(0xc4e106c0), SPH_C32(0xd1170000), SPH_C32(0x33800000), + SPH_C32(0xe8b124dd), SPH_C32(0x06a2618b), SPH_C32(0x5e7226a9), + SPH_C32(0x075115e7) }, + { SPH_C32(0x496a0000), SPH_C32(0xec501800), SPH_C32(0xbb130000), + SPH_C32(0x67a20000), SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), + SPH_C32(0x831fedcb), SPH_C32(0x6b78f44f), SPH_C32(0x461f0000), + SPH_C32(0xb1290300), SPH_C32(0x124b0000), SPH_C32(0x02d10000), + SPH_C32(0xabb01976), SPH_C32(0xb19c0925), SPH_C32(0x28f4b503), + SPH_C32(0x64e214a1) }, + { SPH_C32(0x1d3a0000), SPH_C32(0xea21185c), SPH_C32(0x9ebd0000), + SPH_C32(0x0dbc0000), SPH_C32(0x03c36ae9), SPH_C32(0x50df35d0), + SPH_C32(0x3ca5f508), SPH_C32(0x1509a958), SPH_C32(0xfa920000), + SPH_C32(0x4d120318), SPH_C32(0x0bc80000), SPH_C32(0xd3da0000), + SPH_C32(0x05a861b2), SPH_C32(0xf33a9173), SPH_C32(0x28e66f34), + SPH_C32(0x48d944ef) }, + { SPH_C32(0xf5e70000), SPH_C32(0x106b1818), SPH_C32(0xa2900000), + SPH_C32(0xb6a90000), SPH_C32(0x837e5cf2), SPH_C32(0x74372894), + SPH_C32(0x830d37fc), SPH_C32(0x4743a401), SPH_C32(0xaec20000), + SPH_C32(0x4b630344), SPH_C32(0x2e660000), SPH_C32(0xb9c40000), + SPH_C32(0x2b0d2f6d), SPH_C32(0x95741461), SPH_C32(0x975c77f7), + SPH_C32(0x36a819f8) }, + { SPH_C32(0xa1b70000), SPH_C32(0x161a1844), SPH_C32(0x873e0000), + SPH_C32(0xdcb70000), SPH_C32(0xaddb122d), SPH_C32(0x1279ad86), + SPH_C32(0x3cb72f3f), SPH_C32(0x3932f916), SPH_C32(0x124f0000), + SPH_C32(0xb758035c), SPH_C32(0x37e50000), SPH_C32(0x68cf0000), + SPH_C32(0x851557a9), SPH_C32(0xd7d28c37), SPH_C32(0x974eadc0), + SPH_C32(0x1a9349b6) }, + { SPH_C32(0x203b0000), SPH_C32(0x38b1189c), SPH_C32(0x78300000), + SPH_C32(0xcb8d0000), SPH_C32(0xc9f32f98), SPH_C32(0xf835a51e), + SPH_C32(0x04f3c5b7), SPH_C32(0xd7995781), SPH_C32(0x806c0000), + SPH_C32(0x1ea4030c), SPH_C32(0xb68a0000), SPH_C32(0x235c0000), + SPH_C32(0x88a10cf1), SPH_C32(0xc88f580a), SPH_C32(0x35dc198b), + SPH_C32(0x536fc5d2) }, + { SPH_C32(0x746b0000), SPH_C32(0x3ec018c0), SPH_C32(0x5d9e0000), + SPH_C32(0xa1930000), SPH_C32(0xe7566147), SPH_C32(0x9e7b200c), + SPH_C32(0xbb49dd74), SPH_C32(0xa9e80a96), SPH_C32(0x3ce10000), + SPH_C32(0xe29f0314), SPH_C32(0xaf090000), SPH_C32(0xf2570000), + SPH_C32(0x26b97435), SPH_C32(0x8a29c05c), SPH_C32(0x35cec3bc), + SPH_C32(0x7f54959c) }, + { SPH_C32(0x9cb60000), SPH_C32(0xc48a1884), SPH_C32(0x61b30000), + SPH_C32(0x1a860000), SPH_C32(0x67eb575c), SPH_C32(0xba933d48), + SPH_C32(0x04e11f80), SPH_C32(0xfba207cf), SPH_C32(0x68b10000), + SPH_C32(0xe4ee0348), SPH_C32(0x8aa70000), SPH_C32(0x98490000), + SPH_C32(0x081c3aea), SPH_C32(0xec67454e), SPH_C32(0x8a74db7f), + SPH_C32(0x0125c88b) }, + { SPH_C32(0xc8e60000), SPH_C32(0xc2fb18d8), SPH_C32(0x441d0000), + SPH_C32(0x70980000), SPH_C32(0x494e1983), SPH_C32(0xdcddb85a), + SPH_C32(0xbb5b0743), SPH_C32(0x85d35ad8), SPH_C32(0xd43c0000), + SPH_C32(0x18d50350), SPH_C32(0x93240000), SPH_C32(0x49420000), + SPH_C32(0xa604422e), SPH_C32(0xaec1dd18), SPH_C32(0x8a660148), + SPH_C32(0x2d1e98c5) }, + { SPH_C32(0x8f190000), SPH_C32(0x43dd180c), SPH_C32(0x1fd20000), + SPH_C32(0x462f0000), SPH_C32(0x0e7731b1), SPH_C32(0x4f82e1ed), + SPH_C32(0x9e374143), SPH_C32(0x5cf5253c), SPH_C32(0xe93d0000), + SPH_C32(0xca450390), SPH_C32(0x75a90000), SPH_C32(0x8f730000), + SPH_C32(0x6c34075f), SPH_C32(0x062b4dd6), SPH_C32(0xb23031f7), + SPH_C32(0xef8e661c) }, + { SPH_C32(0xdb490000), SPH_C32(0x45ac1850), SPH_C32(0x3a7c0000), + SPH_C32(0x2c310000), SPH_C32(0x20d27f6e), SPH_C32(0x29cc64ff), + SPH_C32(0x218d5980), SPH_C32(0x2284782b), SPH_C32(0x55b00000), + SPH_C32(0x367e0388), SPH_C32(0x6c2a0000), SPH_C32(0x5e780000), + SPH_C32(0xc22c7f9b), SPH_C32(0x448dd580), SPH_C32(0xb222ebc0), + SPH_C32(0xc3b53652) }, + { SPH_C32(0x33940000), SPH_C32(0xbfe61814), SPH_C32(0x06510000), + SPH_C32(0x97240000), SPH_C32(0xa06f4975), SPH_C32(0x0d2479bb), + SPH_C32(0x9e259b74), SPH_C32(0x70ce7572), SPH_C32(0x01e00000), + SPH_C32(0x300f03d4), SPH_C32(0x49840000), SPH_C32(0x34660000), + SPH_C32(0xec893144), SPH_C32(0x22c35092), SPH_C32(0x0d98f303), + SPH_C32(0xbdc46b45) }, + { SPH_C32(0x67c40000), SPH_C32(0xb9971848), SPH_C32(0x23ff0000), + SPH_C32(0xfd3a0000), SPH_C32(0x8eca07aa), SPH_C32(0x6b6afca9), + SPH_C32(0x219f83b7), SPH_C32(0x0ebf2865), SPH_C32(0xbd6d0000), + SPH_C32(0xcc3403cc), SPH_C32(0x50070000), SPH_C32(0xe56d0000), + SPH_C32(0x42914980), SPH_C32(0x6065c8c4), SPH_C32(0x0d8a2934), + SPH_C32(0x91ff3b0b) }, + { SPH_C32(0xe6480000), SPH_C32(0x973c1890), SPH_C32(0xdcf10000), + SPH_C32(0xea000000), SPH_C32(0xeae23a1f), SPH_C32(0x8126f431), + SPH_C32(0x19db693f), SPH_C32(0xe01486f2), SPH_C32(0x2f4e0000), + SPH_C32(0x65c8039c), SPH_C32(0xd1680000), SPH_C32(0xaefe0000), + SPH_C32(0x4f2512d8), SPH_C32(0x7f381cf9), SPH_C32(0xaf189d7f), + SPH_C32(0xd803b76f) }, + { SPH_C32(0xb2180000), SPH_C32(0x914d18cc), SPH_C32(0xf95f0000), + SPH_C32(0x801e0000), SPH_C32(0xc44774c0), SPH_C32(0xe7687123), + SPH_C32(0xa66171fc), SPH_C32(0x9e65dbe5), SPH_C32(0x93c30000), + SPH_C32(0x99f30384), SPH_C32(0xc8eb0000), SPH_C32(0x7ff50000), + SPH_C32(0xe13d6a1c), SPH_C32(0x3d9e84af), SPH_C32(0xaf0a4748), + SPH_C32(0xf438e721) }, + { SPH_C32(0x5ac50000), SPH_C32(0x6b071888), SPH_C32(0xc5720000), + SPH_C32(0x3b0b0000), SPH_C32(0x44fa42db), SPH_C32(0xc3806c67), + SPH_C32(0x19c9b308), SPH_C32(0xcc2fd6bc), SPH_C32(0xc7930000), + SPH_C32(0x9f8203d8), SPH_C32(0xed450000), SPH_C32(0x15eb0000), + SPH_C32(0xcf9824c3), SPH_C32(0x5bd001bd), SPH_C32(0x10b05f8b), + SPH_C32(0x8a49ba36) }, + { SPH_C32(0x0e950000), SPH_C32(0x6d7618d4), SPH_C32(0xe0dc0000), + SPH_C32(0x51150000), SPH_C32(0x6a5f0c04), SPH_C32(0xa5cee975), + SPH_C32(0xa673abcb), SPH_C32(0xb25e8bab), SPH_C32(0x7b1e0000), + SPH_C32(0x63b903c0), SPH_C32(0xf4c60000), SPH_C32(0xc4e00000), + SPH_C32(0x61805c07), SPH_C32(0x197699eb), SPH_C32(0x10a285bc), + SPH_C32(0xa672ea78) }, + { SPH_C32(0xbb3a0000), SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), + SPH_C32(0xcc280000), SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), + SPH_C32(0x586c05a5), SPH_C32(0x7e100b40), SPH_C32(0x4a6d0000), + SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), SPH_C32(0x5e3b0000), + SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), SPH_C32(0xbd57fe78), + SPH_C32(0xd0a91431) }, + { SPH_C32(0xef6a0000), SPH_C32(0x049c125c), SPH_C32(0xf9150000), + SPH_C32(0xa6360000), SPH_C32(0xb9582229), SPH_C32(0x5a89e8a4), + SPH_C32(0xe7d61d66), SPH_C32(0x00615657), SPH_C32(0xf6e00000), + SPH_C32(0x04f70c18), SPH_C32(0x49b10000), SPH_C32(0x8f300000), + SPH_C32(0x360251a8), SPH_C32(0xe6b8b467), SPH_C32(0xbd45244f), + SPH_C32(0xfc92447f) }, + { SPH_C32(0x07b70000), SPH_C32(0xfed61218), SPH_C32(0xc5380000), + SPH_C32(0x1d230000), SPH_C32(0x39e51432), SPH_C32(0x7e61f5e0), + SPH_C32(0x587edf92), SPH_C32(0x522b5b0e), SPH_C32(0xa2b00000), + SPH_C32(0x02860c44), SPH_C32(0x6c1f0000), SPH_C32(0xe52e0000), + SPH_C32(0x18a71f77), SPH_C32(0x80f63175), SPH_C32(0x02ff3c8c), + SPH_C32(0x82e31968) }, + { SPH_C32(0x53e70000), SPH_C32(0xf8a71244), SPH_C32(0xe0960000), + SPH_C32(0x773d0000), SPH_C32(0x17405aed), SPH_C32(0x182f70f2), + SPH_C32(0xe7c4c751), SPH_C32(0x2c5a0619), SPH_C32(0x1e3d0000), + SPH_C32(0xfebd0c5c), SPH_C32(0x759c0000), SPH_C32(0x34250000), + SPH_C32(0xb6bf67b3), SPH_C32(0xc250a923), SPH_C32(0x02ede6bb), + SPH_C32(0xaed84926) }, + { SPH_C32(0xd26b0000), SPH_C32(0xd60c129c), SPH_C32(0x1f980000), + SPH_C32(0x60070000), SPH_C32(0x73686758), SPH_C32(0xf263786a), + SPH_C32(0xdf802dd9), SPH_C32(0xc2f1a88e), SPH_C32(0x8c1e0000), + SPH_C32(0x57410c0c), SPH_C32(0xf4f30000), SPH_C32(0x7fb60000), + SPH_C32(0xbb0b3ceb), SPH_C32(0xdd0d7d1e), SPH_C32(0xa07f52f0), + SPH_C32(0xe724c542) }, + { SPH_C32(0x863b0000), SPH_C32(0xd07d12c0), SPH_C32(0x3a360000), + SPH_C32(0x0a190000), SPH_C32(0x5dcd2987), SPH_C32(0x942dfd78), + SPH_C32(0x603a351a), SPH_C32(0xbc80f599), SPH_C32(0x30930000), + SPH_C32(0xab7a0c14), SPH_C32(0xed700000), SPH_C32(0xaebd0000), + SPH_C32(0x1513442f), SPH_C32(0x9fabe548), SPH_C32(0xa06d88c7), + SPH_C32(0xcb1f950c) }, + { SPH_C32(0x6ee60000), SPH_C32(0x2a371284), SPH_C32(0x061b0000), + SPH_C32(0xb10c0000), SPH_C32(0xdd701f9c), SPH_C32(0xb0c5e03c), + SPH_C32(0xdf92f7ee), SPH_C32(0xeecaf8c0), SPH_C32(0x64c30000), + SPH_C32(0xad0b0c48), SPH_C32(0xc8de0000), SPH_C32(0xc4a30000), + SPH_C32(0x3bb60af0), SPH_C32(0xf9e5605a), SPH_C32(0x1fd79004), + SPH_C32(0xb56ec81b) }, + { SPH_C32(0x3ab60000), SPH_C32(0x2c4612d8), SPH_C32(0x23b50000), + SPH_C32(0xdb120000), SPH_C32(0xf3d55143), SPH_C32(0xd68b652e), + SPH_C32(0x6028ef2d), SPH_C32(0x90bba5d7), SPH_C32(0xd84e0000), + SPH_C32(0x51300c50), SPH_C32(0xd15d0000), SPH_C32(0x15a80000), + SPH_C32(0x95ae7234), SPH_C32(0xbb43f80c), SPH_C32(0x1fc54a33), + SPH_C32(0x99559855) }, + { SPH_C32(0x7d490000), SPH_C32(0xad60120c), SPH_C32(0x787a0000), + SPH_C32(0xeda50000), SPH_C32(0xb4ec7971), SPH_C32(0x45d43c99), + SPH_C32(0x4544a92d), SPH_C32(0x499dda33), SPH_C32(0xe54f0000), + SPH_C32(0x83a00c90), SPH_C32(0x37d00000), SPH_C32(0xd3990000), + SPH_C32(0x5f9e3745), SPH_C32(0x13a968c2), SPH_C32(0x27937a8c), + SPH_C32(0x5bc5668c) }, + { SPH_C32(0x29190000), SPH_C32(0xab111250), SPH_C32(0x5dd40000), + SPH_C32(0x87bb0000), SPH_C32(0x9a4937ae), SPH_C32(0x239ab98b), + SPH_C32(0xfafeb1ee), SPH_C32(0x37ec8724), SPH_C32(0x59c20000), + SPH_C32(0x7f9b0c88), SPH_C32(0x2e530000), SPH_C32(0x02920000), + SPH_C32(0xf1864f81), SPH_C32(0x510ff094), SPH_C32(0x2781a0bb), + SPH_C32(0x77fe36c2) }, + { SPH_C32(0xc1c40000), SPH_C32(0x515b1214), SPH_C32(0x61f90000), + SPH_C32(0x3cae0000), SPH_C32(0x1af401b5), SPH_C32(0x0772a4cf), + SPH_C32(0x4556731a), SPH_C32(0x65a68a7d), SPH_C32(0x0d920000), + SPH_C32(0x79ea0cd4), SPH_C32(0x0bfd0000), SPH_C32(0x688c0000), + SPH_C32(0xdf23015e), SPH_C32(0x37417586), SPH_C32(0x983bb878), + SPH_C32(0x098f6bd5) }, + { SPH_C32(0x95940000), SPH_C32(0x572a1248), SPH_C32(0x44570000), + SPH_C32(0x56b00000), SPH_C32(0x34514f6a), SPH_C32(0x613c21dd), + SPH_C32(0xfaec6bd9), SPH_C32(0x1bd7d76a), SPH_C32(0xb11f0000), + SPH_C32(0x85d10ccc), SPH_C32(0x127e0000), SPH_C32(0xb9870000), + SPH_C32(0x713b799a), SPH_C32(0x75e7edd0), SPH_C32(0x9829624f), + SPH_C32(0x25b43b9b) }, + { SPH_C32(0x14180000), SPH_C32(0x79811290), SPH_C32(0xbb590000), + SPH_C32(0x418a0000), SPH_C32(0x507972df), SPH_C32(0x8b702945), + SPH_C32(0xc2a88151), SPH_C32(0xf57c79fd), SPH_C32(0x233c0000), + SPH_C32(0x2c2d0c9c), SPH_C32(0x93110000), SPH_C32(0xf2140000), + SPH_C32(0x7c8f22c2), SPH_C32(0x6aba39ed), SPH_C32(0x3abbd604), + SPH_C32(0x6c48b7ff) }, + { SPH_C32(0x40480000), SPH_C32(0x7ff012cc), SPH_C32(0x9ef70000), + SPH_C32(0x2b940000), SPH_C32(0x7edc3c00), SPH_C32(0xed3eac57), + SPH_C32(0x7d129992), SPH_C32(0x8b0d24ea), SPH_C32(0x9fb10000), + SPH_C32(0xd0160c84), SPH_C32(0x8a920000), SPH_C32(0x231f0000), + SPH_C32(0xd2975a06), SPH_C32(0x281ca1bb), SPH_C32(0x3aa90c33), + SPH_C32(0x4073e7b1) }, + { SPH_C32(0xa8950000), SPH_C32(0x85ba1288), SPH_C32(0xa2da0000), + SPH_C32(0x90810000), SPH_C32(0xfe610a1b), SPH_C32(0xc9d6b113), + SPH_C32(0xc2ba5b66), SPH_C32(0xd94729b3), SPH_C32(0xcbe10000), + SPH_C32(0xd6670cd8), SPH_C32(0xaf3c0000), SPH_C32(0x49010000), + SPH_C32(0xfc3214d9), SPH_C32(0x4e5224a9), SPH_C32(0x851314f0), + SPH_C32(0x3e02baa6) }, + { SPH_C32(0xfcc50000), SPH_C32(0x83cb12d4), SPH_C32(0x87740000), + SPH_C32(0xfa9f0000), SPH_C32(0xd0c444c4), SPH_C32(0xaf983401), + SPH_C32(0x7d0043a5), SPH_C32(0xa73674a4), SPH_C32(0x776c0000), + SPH_C32(0x2a5c0cc0), SPH_C32(0xb6bf0000), SPH_C32(0x980a0000), + SPH_C32(0x522a6c1d), SPH_C32(0x0cf4bcff), SPH_C32(0x8501cec7), + SPH_C32(0x1239eae8) }, + { SPH_C32(0xb7480000), SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), + SPH_C32(0x90c20000), SPH_C32(0xa4575cec), SPH_C32(0x294548a2), + SPH_C32(0xcdcf4ede), SPH_C32(0xca5b0bd0), SPH_C32(0xb44f0000), + SPH_C32(0x5f940900), SPH_C32(0x75e30000), SPH_C32(0xa95b0000), + SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), SPH_C32(0xf3875d6d), + SPH_C32(0x718aebae) }, + { SPH_C32(0xe3180000), SPH_C32(0x4d791d5c), SPH_C32(0xbb6c0000), + SPH_C32(0xfadc0000), SPH_C32(0x8af21233), SPH_C32(0x4f0bcdb0), + SPH_C32(0x7275561d), SPH_C32(0xb42a56c7), SPH_C32(0x08c20000), + SPH_C32(0xa3af0918), SPH_C32(0x6c600000), SPH_C32(0x78500000), + SPH_C32(0xbf332972), SPH_C32(0xf96c4c07), SPH_C32(0xf395875a), + SPH_C32(0x5db1bbe0) }, + { SPH_C32(0x0bc50000), SPH_C32(0xb7331d18), SPH_C32(0x87410000), + SPH_C32(0x41c90000), SPH_C32(0x0a4f2428), SPH_C32(0x6be3d0f4), + SPH_C32(0xcddd94e9), SPH_C32(0xe6605b9e), SPH_C32(0x5c920000), + SPH_C32(0xa5de0944), SPH_C32(0x49ce0000), SPH_C32(0x124e0000), + SPH_C32(0x919667ad), SPH_C32(0x9f22c915), SPH_C32(0x4c2f9f99), + SPH_C32(0x23c0e6f7) }, + { SPH_C32(0x5f950000), SPH_C32(0xb1421d44), SPH_C32(0xa2ef0000), + SPH_C32(0x2bd70000), SPH_C32(0x24ea6af7), SPH_C32(0x0dad55e6), + SPH_C32(0x72678c2a), SPH_C32(0x98110689), SPH_C32(0xe01f0000), + SPH_C32(0x59e5095c), SPH_C32(0x504d0000), SPH_C32(0xc3450000), + SPH_C32(0x3f8e1f69), SPH_C32(0xdd845143), SPH_C32(0x4c3d45ae), + SPH_C32(0x0ffbb6b9) }, + { SPH_C32(0xde190000), SPH_C32(0x9fe91d9c), SPH_C32(0x5de10000), + SPH_C32(0x3ced0000), SPH_C32(0x40c25742), SPH_C32(0xe7e15d7e), + SPH_C32(0x4a2366a2), SPH_C32(0x76baa81e), SPH_C32(0x723c0000), + SPH_C32(0xf019090c), SPH_C32(0xd1220000), SPH_C32(0x88d60000), + SPH_C32(0x323a4431), SPH_C32(0xc2d9857e), SPH_C32(0xeeaff1e5), + SPH_C32(0x46073add) }, + { SPH_C32(0x8a490000), SPH_C32(0x99981dc0), SPH_C32(0x784f0000), + SPH_C32(0x56f30000), SPH_C32(0x6e67199d), SPH_C32(0x81afd86c), + SPH_C32(0xf5997e61), SPH_C32(0x08cbf509), SPH_C32(0xceb10000), + SPH_C32(0x0c220914), SPH_C32(0xc8a10000), SPH_C32(0x59dd0000), + SPH_C32(0x9c223cf5), SPH_C32(0x807f1d28), SPH_C32(0xeebd2bd2), + SPH_C32(0x6a3c6a93) }, + { SPH_C32(0x62940000), SPH_C32(0x63d21d84), SPH_C32(0x44620000), + SPH_C32(0xede60000), SPH_C32(0xeeda2f86), SPH_C32(0xa547c528), + SPH_C32(0x4a31bc95), SPH_C32(0x5a81f850), SPH_C32(0x9ae10000), + SPH_C32(0x0a530948), SPH_C32(0xed0f0000), SPH_C32(0x33c30000), + SPH_C32(0xb287722a), SPH_C32(0xe631983a), SPH_C32(0x51073311), + SPH_C32(0x144d3784) }, + { SPH_C32(0x36c40000), SPH_C32(0x65a31dd8), SPH_C32(0x61cc0000), + SPH_C32(0x87f80000), SPH_C32(0xc07f6159), SPH_C32(0xc309403a), + SPH_C32(0xf58ba456), SPH_C32(0x24f0a547), SPH_C32(0x266c0000), + SPH_C32(0xf6680950), SPH_C32(0xf48c0000), SPH_C32(0xe2c80000), + SPH_C32(0x1c9f0aee), SPH_C32(0xa497006c), SPH_C32(0x5115e926), + SPH_C32(0x387667ca) }, + { SPH_C32(0x713b0000), SPH_C32(0xe4851d0c), SPH_C32(0x3a030000), + SPH_C32(0xb14f0000), SPH_C32(0x8746496b), SPH_C32(0x5056198d), + SPH_C32(0xd0e7e256), SPH_C32(0xfdd6daa3), SPH_C32(0x1b6d0000), + SPH_C32(0x24f80990), SPH_C32(0x12010000), SPH_C32(0x24f90000), + SPH_C32(0xd6af4f9f), SPH_C32(0x0c7d90a2), SPH_C32(0x6943d999), + SPH_C32(0xfae69913) }, + { SPH_C32(0x256b0000), SPH_C32(0xe2f41d50), SPH_C32(0x1fad0000), + SPH_C32(0xdb510000), SPH_C32(0xa9e307b4), SPH_C32(0x36189c9f), + SPH_C32(0x6f5dfa95), SPH_C32(0x83a787b4), SPH_C32(0xa7e00000), + SPH_C32(0xd8c30988), SPH_C32(0x0b820000), SPH_C32(0xf5f20000), + SPH_C32(0x78b7375b), SPH_C32(0x4edb08f4), SPH_C32(0x695103ae), + SPH_C32(0xd6ddc95d) }, + { SPH_C32(0xcdb60000), SPH_C32(0x18be1d14), SPH_C32(0x23800000), + SPH_C32(0x60440000), SPH_C32(0x295e31af), SPH_C32(0x12f081db), + SPH_C32(0xd0f53861), SPH_C32(0xd1ed8aed), SPH_C32(0xf3b00000), + SPH_C32(0xdeb209d4), SPH_C32(0x2e2c0000), SPH_C32(0x9fec0000), + SPH_C32(0x56127984), SPH_C32(0x28958de6), SPH_C32(0xd6eb1b6d), + SPH_C32(0xa8ac944a) }, + { SPH_C32(0x99e60000), SPH_C32(0x1ecf1d48), SPH_C32(0x062e0000), + SPH_C32(0x0a5a0000), SPH_C32(0x07fb7f70), SPH_C32(0x74be04c9), + SPH_C32(0x6f4f20a2), SPH_C32(0xaf9cd7fa), SPH_C32(0x4f3d0000), + SPH_C32(0x228909cc), SPH_C32(0x37af0000), SPH_C32(0x4ee70000), + SPH_C32(0xf80a0140), SPH_C32(0x6a3315b0), SPH_C32(0xd6f9c15a), + SPH_C32(0x8497c404) }, + { SPH_C32(0x186a0000), SPH_C32(0x30641d90), SPH_C32(0xf9200000), + SPH_C32(0x1d600000), SPH_C32(0x63d342c5), SPH_C32(0x9ef20c51), + SPH_C32(0x570bca2a), SPH_C32(0x4137796d), SPH_C32(0xdd1e0000), + SPH_C32(0x8b75099c), SPH_C32(0xb6c00000), SPH_C32(0x05740000), + SPH_C32(0xf5be5a18), SPH_C32(0x756ec18d), SPH_C32(0x746b7511), + SPH_C32(0xcd6b4860) }, + { SPH_C32(0x4c3a0000), SPH_C32(0x36151dcc), SPH_C32(0xdc8e0000), + SPH_C32(0x777e0000), SPH_C32(0x4d760c1a), SPH_C32(0xf8bc8943), + SPH_C32(0xe8b1d2e9), SPH_C32(0x3f46247a), SPH_C32(0x61930000), + SPH_C32(0x774e0984), SPH_C32(0xaf430000), SPH_C32(0xd47f0000), + SPH_C32(0x5ba622dc), SPH_C32(0x37c859db), SPH_C32(0x7479af26), + SPH_C32(0xe150182e) }, + { SPH_C32(0xa4e70000), SPH_C32(0xcc5f1d88), SPH_C32(0xe0a30000), + SPH_C32(0xcc6b0000), SPH_C32(0xcdcb3a01), SPH_C32(0xdc549407), + SPH_C32(0x5719101d), SPH_C32(0x6d0c2923), SPH_C32(0x35c30000), + SPH_C32(0x713f09d8), SPH_C32(0x8aed0000), SPH_C32(0xbe610000), + SPH_C32(0x75036c03), SPH_C32(0x5186dcc9), SPH_C32(0xcbc3b7e5), + SPH_C32(0x9f214539) }, + { SPH_C32(0xf0b70000), SPH_C32(0xca2e1dd4), SPH_C32(0xc50d0000), + SPH_C32(0xa6750000), SPH_C32(0xe36e74de), SPH_C32(0xba1a1115), + SPH_C32(0xe8a308de), SPH_C32(0x137d7434), SPH_C32(0x894e0000), + SPH_C32(0x8d0409c0), SPH_C32(0x936e0000), SPH_C32(0x6f6a0000), + SPH_C32(0xdb1b14c7), SPH_C32(0x1320449f), SPH_C32(0xcbd16dd2), + SPH_C32(0xb31a1577) } +}; + +static const sph_u32 T512_28[128][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x1e4e0000), SPH_C32(0xdecf0000), SPH_C32(0x6df80180), + SPH_C32(0x77240000), SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), + SPH_C32(0xcda31812), SPH_C32(0x98aa496e), SPH_C32(0xb2060000), + SPH_C32(0xc5690000), SPH_C32(0x28031200), SPH_C32(0x74670000), + SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), SPH_C32(0x33d1dfec), + SPH_C32(0x094e3198) }, + { SPH_C32(0xaec30000), SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), + SPH_C32(0x2c150000), SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), + SPH_C32(0xab92f78f), SPH_C32(0xa312567b), SPH_C32(0xdb250000), + SPH_C32(0x09290000), SPH_C32(0x49aac000), SPH_C32(0x81e10000), + SPH_C32(0xcafe6b59), SPH_C32(0x42793431), SPH_C32(0x43566b76), + SPH_C32(0xe86cba2e) }, + { SPH_C32(0xb08d0000), SPH_C32(0x42800001), SPH_C32(0x1429e180), + SPH_C32(0x5b310000), SPH_C32(0xa98b722d), SPH_C32(0x92f0de78), + SPH_C32(0x6631ef9d), SPH_C32(0x3bb81f15), SPH_C32(0x69230000), + SPH_C32(0xcc400000), SPH_C32(0x61a9d200), SPH_C32(0xf5860000), + SPH_C32(0x7c3c5dad), SPH_C32(0xa96b0dc9), SPH_C32(0x7087b49a), + SPH_C32(0xe1228bb6) }, + { SPH_C32(0xdb250000), SPH_C32(0x09290000), SPH_C32(0x49aac000), + SPH_C32(0x81e10000), SPH_C32(0xcafe6b59), SPH_C32(0x42793431), + SPH_C32(0x43566b76), SPH_C32(0xe86cba2e), SPH_C32(0x75e60000), + SPH_C32(0x95660001), SPH_C32(0x307b2000), SPH_C32(0xadf40000), + SPH_C32(0x8f321eea), SPH_C32(0x24298307), SPH_C32(0xe8c49cf9), + SPH_C32(0x4b7eec55) }, + { SPH_C32(0xc56b0000), SPH_C32(0xd7e60000), SPH_C32(0x2452c180), + SPH_C32(0xf6c50000), SPH_C32(0x26b96cc7), SPH_C32(0xb6d95d7f), + SPH_C32(0x8ef57364), SPH_C32(0x70c6f340), SPH_C32(0xc7e00000), + SPH_C32(0x500f0001), SPH_C32(0x18783200), SPH_C32(0xd9930000), + SPH_C32(0x39f0281e), SPH_C32(0xcf3bbaff), SPH_C32(0xdb154315), + SPH_C32(0x4230ddcd) }, + { SPH_C32(0x75e60000), SPH_C32(0x95660001), SPH_C32(0x307b2000), + SPH_C32(0xadf40000), SPH_C32(0x8f321eea), SPH_C32(0x24298307), + SPH_C32(0xe8c49cf9), SPH_C32(0x4b7eec55), SPH_C32(0xaec30000), + SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), SPH_C32(0x2c150000), + SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), SPH_C32(0xab92f78f), + SPH_C32(0xa312567b) }, + { SPH_C32(0x6ba80000), SPH_C32(0x4ba90001), SPH_C32(0x5d832180), + SPH_C32(0xdad00000), SPH_C32(0x63751974), SPH_C32(0xd089ea49), + SPH_C32(0x256784eb), SPH_C32(0xd3d4a53b), SPH_C32(0x1cc50000), + SPH_C32(0x59260001), SPH_C32(0x51d2f200), SPH_C32(0x58720000), + SPH_C32(0xf30e4347), SPH_C32(0x8d428ece), SPH_C32(0x98432863), + SPH_C32(0xaa5c67e3) }, + { SPH_C32(0x86790000), SPH_C32(0x3f390002), SPH_C32(0xe19ae000), + SPH_C32(0x98560000), SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), + SPH_C32(0xd3dd4944), SPH_C32(0x161ddab9), SPH_C32(0x30b70000), + SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), SPH_C32(0x42c40000), + SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), SPH_C32(0x21afa1ea), + SPH_C32(0xb0a51834) }, + { SPH_C32(0x98370000), SPH_C32(0xe1f60002), SPH_C32(0x8c62e180), + SPH_C32(0xef720000), SPH_C32(0x79226090), SPH_C32(0xba28a1a4), + SPH_C32(0x1e7e5156), SPH_C32(0x8eb793d7), SPH_C32(0x82b10000), + SPH_C32(0x20b90000), SPH_C32(0xdcf77200), SPH_C32(0x36a30000), + SPH_C32(0xd57a0b9e), SPH_C32(0x93a8ad98), SPH_C32(0x127e7e06), + SPH_C32(0xb9eb29ac) }, + { SPH_C32(0x28ba0000), SPH_C32(0xa3760003), SPH_C32(0x984b0000), + SPH_C32(0xb4430000), SPH_C32(0xd0a912bd), SPH_C32(0x28d87fdc), + SPH_C32(0x784fbecb), SPH_C32(0xb50f8cc2), SPH_C32(0xeb920000), + SPH_C32(0xecf90000), SPH_C32(0xbd5ea000), SPH_C32(0xc3250000), + SPH_C32(0xa9465633), SPH_C32(0x3ac3a051), SPH_C32(0x62f9ca9c), + SPH_C32(0x58c9a21a) }, + { SPH_C32(0x36f40000), SPH_C32(0x7db90003), SPH_C32(0xf5b30180), + SPH_C32(0xc3670000), SPH_C32(0x3cee1523), SPH_C32(0xdc781692), + SPH_C32(0xb5eca6d9), SPH_C32(0x2da5c5ac), SPH_C32(0x59940000), + SPH_C32(0x29900000), SPH_C32(0x955db200), SPH_C32(0xb7420000), + SPH_C32(0x1f8460c7), SPH_C32(0xd1d199a9), SPH_C32(0x51281570), + SPH_C32(0x51879382) }, + { SPH_C32(0x5d5c0000), SPH_C32(0x36100002), SPH_C32(0xa8302000), + SPH_C32(0x19b70000), SPH_C32(0x5f9b0c57), SPH_C32(0x0cf1fcdb), + SPH_C32(0x908b2232), SPH_C32(0xfe716097), SPH_C32(0x45510000), + SPH_C32(0x70b60001), SPH_C32(0xc48f4000), SPH_C32(0xef300000), + SPH_C32(0xec8a2380), SPH_C32(0x5c931767), SPH_C32(0xc96b3d13), + SPH_C32(0xfbdbf461) }, + { SPH_C32(0x43120000), SPH_C32(0xe8df0002), SPH_C32(0xc5c82180), + SPH_C32(0x6e930000), SPH_C32(0xb3dc0bc9), SPH_C32(0xf8519595), + SPH_C32(0x5d283a20), SPH_C32(0x66db29f9), SPH_C32(0xf7570000), + SPH_C32(0xb5df0001), SPH_C32(0xec8c5200), SPH_C32(0x9b570000), + SPH_C32(0x5a481574), SPH_C32(0xb7812e9f), SPH_C32(0xfabae2ff), + SPH_C32(0xf295c5f9) }, + { SPH_C32(0xf39f0000), SPH_C32(0xaa5f0003), SPH_C32(0xd1e1c000), + SPH_C32(0x35a20000), SPH_C32(0x1a5779e4), SPH_C32(0x6aa14bed), + SPH_C32(0x3b19d5bd), SPH_C32(0x5d6336ec), SPH_C32(0x9e740000), + SPH_C32(0x799f0001), SPH_C32(0x8d258000), SPH_C32(0x6ed10000), + SPH_C32(0x267448d9), SPH_C32(0x1eea2356), SPH_C32(0x8a3d5665), + SPH_C32(0x13b74e4f) }, + { SPH_C32(0xedd10000), SPH_C32(0x74900003), SPH_C32(0xbc19c180), + SPH_C32(0x42860000), SPH_C32(0xf6107e7a), SPH_C32(0x9e0122a3), + SPH_C32(0xf6bacdaf), SPH_C32(0xc5c97f82), SPH_C32(0x2c720000), + SPH_C32(0xbcf60001), SPH_C32(0xa5269200), SPH_C32(0x1ab60000), + SPH_C32(0x90b67e2d), SPH_C32(0xf5f81aae), SPH_C32(0xb9ec8989), + SPH_C32(0x1af97fd7) }, + { SPH_C32(0x30b70000), SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), + SPH_C32(0x42c40000), SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), + SPH_C32(0x21afa1ea), SPH_C32(0xb0a51834), SPH_C32(0xb6ce0000), + SPH_C32(0xdae90002), SPH_C32(0x156e8000), SPH_C32(0xda920000), + SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), SPH_C32(0xf272e8ae), + SPH_C32(0xa6b8c28d) }, + { SPH_C32(0x2ef90000), SPH_C32(0x3b1f0000), SPH_C32(0x990c6180), + SPH_C32(0x35e00000), SPH_C32(0x8fff3af4), SPH_C32(0x8c1afd2e), + SPH_C32(0xec0cb9f8), SPH_C32(0x280f515a), SPH_C32(0x04c80000), + SPH_C32(0x1f800002), SPH_C32(0x3d6d9200), SPH_C32(0xaef50000), + SPH_C32(0x401f6c90), SPH_C32(0xdd206572), SPH_C32(0xc1a33742), + SPH_C32(0xaff6f315) }, + { SPH_C32(0x9e740000), SPH_C32(0x799f0001), SPH_C32(0x8d258000), + SPH_C32(0x6ed10000), SPH_C32(0x267448d9), SPH_C32(0x1eea2356), + SPH_C32(0x8a3d5665), SPH_C32(0x13b74e4f), SPH_C32(0x6deb0000), + SPH_C32(0xd3c00002), SPH_C32(0x5cc44000), SPH_C32(0x5b730000), + SPH_C32(0x3c23313d), SPH_C32(0x744b68bb), SPH_C32(0xb12483d8), + SPH_C32(0x4ed478a3) }, + { SPH_C32(0x803a0000), SPH_C32(0xa7500001), SPH_C32(0xe0dd8180), + SPH_C32(0x19f50000), SPH_C32(0xca334f47), SPH_C32(0xea4a4a18), + SPH_C32(0x479e4e77), SPH_C32(0x8b1d0721), SPH_C32(0xdfed0000), + SPH_C32(0x16a90002), SPH_C32(0x74c75200), SPH_C32(0x2f140000), + SPH_C32(0x8ae107c9), SPH_C32(0x9f595143), SPH_C32(0x82f55c34), + SPH_C32(0x479a493b) }, + { SPH_C32(0xeb920000), SPH_C32(0xecf90000), SPH_C32(0xbd5ea000), + SPH_C32(0xc3250000), SPH_C32(0xa9465633), SPH_C32(0x3ac3a051), + SPH_C32(0x62f9ca9c), SPH_C32(0x58c9a21a), SPH_C32(0xc3280000), + SPH_C32(0x4f8f0003), SPH_C32(0x2515a000), SPH_C32(0x77660000), + SPH_C32(0x79ef448e), SPH_C32(0x121bdf8d), SPH_C32(0x1ab67457), + SPH_C32(0xedc62ed8) }, + { SPH_C32(0xf5dc0000), SPH_C32(0x32360000), SPH_C32(0xd0a6a180), + SPH_C32(0xb4010000), SPH_C32(0x450151ad), SPH_C32(0xce63c91f), + SPH_C32(0xaf5ad28e), SPH_C32(0xc063eb74), SPH_C32(0x712e0000), + SPH_C32(0x8ae60003), SPH_C32(0x0d16b200), SPH_C32(0x03010000), + SPH_C32(0xcf2d727a), SPH_C32(0xf909e675), SPH_C32(0x2967abbb), + SPH_C32(0xe4881f40) }, + { SPH_C32(0x45510000), SPH_C32(0x70b60001), SPH_C32(0xc48f4000), + SPH_C32(0xef300000), SPH_C32(0xec8a2380), SPH_C32(0x5c931767), + SPH_C32(0xc96b3d13), SPH_C32(0xfbdbf461), SPH_C32(0x180d0000), + SPH_C32(0x46a60003), SPH_C32(0x6cbf6000), SPH_C32(0xf6870000), + SPH_C32(0xb3112fd7), SPH_C32(0x5062ebbc), SPH_C32(0x59e01f21), + SPH_C32(0x05aa94f6) }, + { SPH_C32(0x5b1f0000), SPH_C32(0xae790001), SPH_C32(0xa9774180), + SPH_C32(0x98140000), SPH_C32(0x00cd241e), SPH_C32(0xa8337e29), + SPH_C32(0x04c82501), SPH_C32(0x6371bd0f), SPH_C32(0xaa0b0000), + SPH_C32(0x83cf0003), SPH_C32(0x44bc7200), SPH_C32(0x82e00000), + SPH_C32(0x05d31923), SPH_C32(0xbb70d244), SPH_C32(0x6a31c0cd), + SPH_C32(0x0ce4a56e) }, + { SPH_C32(0xb6ce0000), SPH_C32(0xdae90002), SPH_C32(0x156e8000), + SPH_C32(0xda920000), SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), + SPH_C32(0xf272e8ae), SPH_C32(0xa6b8c28d), SPH_C32(0x86790000), + SPH_C32(0x3f390002), SPH_C32(0xe19ae000), SPH_C32(0x98560000), + SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), SPH_C32(0xd3dd4944), + SPH_C32(0x161ddab9) }, + { SPH_C32(0xa8800000), SPH_C32(0x04260002), SPH_C32(0x78968180), + SPH_C32(0xadb60000), SPH_C32(0x1a9a5dfa), SPH_C32(0xc29235c4), + SPH_C32(0x3fd1f0bc), SPH_C32(0x3e128be3), SPH_C32(0x347f0000), + SPH_C32(0xfa500002), SPH_C32(0xc999f200), SPH_C32(0xec310000), + SPH_C32(0x23a751fa), SPH_C32(0xa59af112), SPH_C32(0xe00c96a8), + SPH_C32(0x1f53eb21) }, + { SPH_C32(0x180d0000), SPH_C32(0x46a60003), SPH_C32(0x6cbf6000), + SPH_C32(0xf6870000), SPH_C32(0xb3112fd7), SPH_C32(0x5062ebbc), + SPH_C32(0x59e01f21), SPH_C32(0x05aa94f6), SPH_C32(0x5d5c0000), + SPH_C32(0x36100002), SPH_C32(0xa8302000), SPH_C32(0x19b70000), + SPH_C32(0x5f9b0c57), SPH_C32(0x0cf1fcdb), SPH_C32(0x908b2232), + SPH_C32(0xfe716097) }, + { SPH_C32(0x06430000), SPH_C32(0x98690003), SPH_C32(0x01476180), + SPH_C32(0x81a30000), SPH_C32(0x5f562849), SPH_C32(0xa4c282f2), + SPH_C32(0x94430733), SPH_C32(0x9d00dd98), SPH_C32(0xef5a0000), + SPH_C32(0xf3790002), SPH_C32(0x80333200), SPH_C32(0x6dd00000), + SPH_C32(0xe9593aa3), SPH_C32(0xe7e3c523), SPH_C32(0xa35afdde), + SPH_C32(0xf73f510f) }, + { SPH_C32(0x6deb0000), SPH_C32(0xd3c00002), SPH_C32(0x5cc44000), + SPH_C32(0x5b730000), SPH_C32(0x3c23313d), SPH_C32(0x744b68bb), + SPH_C32(0xb12483d8), SPH_C32(0x4ed478a3), SPH_C32(0xf39f0000), + SPH_C32(0xaa5f0003), SPH_C32(0xd1e1c000), SPH_C32(0x35a20000), + SPH_C32(0x1a5779e4), SPH_C32(0x6aa14bed), SPH_C32(0x3b19d5bd), + SPH_C32(0x5d6336ec) }, + { SPH_C32(0x73a50000), SPH_C32(0x0d0f0002), SPH_C32(0x313c4180), + SPH_C32(0x2c570000), SPH_C32(0xd06436a3), SPH_C32(0x80eb01f5), + SPH_C32(0x7c879bca), SPH_C32(0xd67e31cd), SPH_C32(0x41990000), + SPH_C32(0x6f360003), SPH_C32(0xf9e2d200), SPH_C32(0x41c50000), + SPH_C32(0xac954f10), SPH_C32(0x81b37215), SPH_C32(0x08c80a51), + SPH_C32(0x542d0774) }, + { SPH_C32(0xc3280000), SPH_C32(0x4f8f0003), SPH_C32(0x2515a000), + SPH_C32(0x77660000), SPH_C32(0x79ef448e), SPH_C32(0x121bdf8d), + SPH_C32(0x1ab67457), SPH_C32(0xedc62ed8), SPH_C32(0x28ba0000), + SPH_C32(0xa3760003), SPH_C32(0x984b0000), SPH_C32(0xb4430000), + SPH_C32(0xd0a912bd), SPH_C32(0x28d87fdc), SPH_C32(0x784fbecb), + SPH_C32(0xb50f8cc2) }, + { SPH_C32(0xdd660000), SPH_C32(0x91400003), SPH_C32(0x48eda180), + SPH_C32(0x00420000), SPH_C32(0x95a84310), SPH_C32(0xe6bbb6c3), + SPH_C32(0xd7156c45), SPH_C32(0x756c67b6), SPH_C32(0x9abc0000), + SPH_C32(0x661f0003), SPH_C32(0xb0481200), SPH_C32(0xc0240000), + SPH_C32(0x666b2449), SPH_C32(0xc3ca4624), SPH_C32(0x4b9e6127), + SPH_C32(0xbc41bd5a) }, + { SPH_C32(0x14190000), SPH_C32(0x23ca003c), SPH_C32(0x50df0000), + SPH_C32(0x44b60000), SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), + SPH_C32(0x61e610b0), SPH_C32(0xdbcadb80), SPH_C32(0xe3430000), + SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), SPH_C32(0xaa4e0000), + SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), SPH_C32(0x123db156), + SPH_C32(0x3a4e99d7) }, + { SPH_C32(0x0a570000), SPH_C32(0xfd05003c), SPH_C32(0x3d270180), + SPH_C32(0x33920000), SPH_C32(0xf72b602e), SPH_C32(0xc853c53b), + SPH_C32(0xac4508a2), SPH_C32(0x436092ee), SPH_C32(0x51450000), + SPH_C32(0xff270014), SPH_C32(0xdac51200), SPH_C32(0xde290000), + SPH_C32(0x6ddc7452), SPH_C32(0xce7987ed), SPH_C32(0x21ec6eba), + SPH_C32(0x3300a84f) }, + { SPH_C32(0xbada0000), SPH_C32(0xbf85003d), SPH_C32(0x290ee000), + SPH_C32(0x68a30000), SPH_C32(0x5ea01203), SPH_C32(0x5aa31b43), + SPH_C32(0xca74e73f), SPH_C32(0x78d88dfb), SPH_C32(0x38660000), + SPH_C32(0x33670014), SPH_C32(0xbb6cc000), SPH_C32(0x2baf0000), + SPH_C32(0x11e029ff), SPH_C32(0x67128a24), SPH_C32(0x516bda20), + SPH_C32(0xd22223f9) }, + { SPH_C32(0xa4940000), SPH_C32(0x614a003d), SPH_C32(0x44f6e180), + SPH_C32(0x1f870000), SPH_C32(0xb2e7159d), SPH_C32(0xae03720d), + SPH_C32(0x07d7ff2d), SPH_C32(0xe072c495), SPH_C32(0x8a600000), + SPH_C32(0xf60e0014), SPH_C32(0x936fd200), SPH_C32(0x5fc80000), + SPH_C32(0xa7221f0b), SPH_C32(0x8c00b3dc), SPH_C32(0x62ba05cc), + SPH_C32(0xdb6c1261) }, + { SPH_C32(0xcf3c0000), SPH_C32(0x2ae3003c), SPH_C32(0x1975c000), + SPH_C32(0xc5570000), SPH_C32(0xd1920ce9), SPH_C32(0x7e8a9844), + SPH_C32(0x22b07bc6), SPH_C32(0x33a661ae), SPH_C32(0x96a50000), + SPH_C32(0xaf280015), SPH_C32(0xc2bd2000), SPH_C32(0x07ba0000), + SPH_C32(0x542c5c4c), SPH_C32(0x01423d12), SPH_C32(0xfaf92daf), + SPH_C32(0x71307582) }, + { SPH_C32(0xd1720000), SPH_C32(0xf42c003c), SPH_C32(0x748dc180), + SPH_C32(0xb2730000), SPH_C32(0x3dd50b77), SPH_C32(0x8a2af10a), + SPH_C32(0xef1363d4), SPH_C32(0xab0c28c0), SPH_C32(0x24a30000), + SPH_C32(0x6a410015), SPH_C32(0xeabe3200), SPH_C32(0x73dd0000), + SPH_C32(0xe2ee6ab8), SPH_C32(0xea5004ea), SPH_C32(0xc928f243), + SPH_C32(0x787e441a) }, + { SPH_C32(0x61ff0000), SPH_C32(0xb6ac003d), SPH_C32(0x60a42000), + SPH_C32(0xe9420000), SPH_C32(0x945e795a), SPH_C32(0x18da2f72), + SPH_C32(0x89228c49), SPH_C32(0x90b437d5), SPH_C32(0x4d800000), + SPH_C32(0xa6010015), SPH_C32(0x8b17e000), SPH_C32(0x865b0000), + SPH_C32(0x9ed23715), SPH_C32(0x433b0923), SPH_C32(0xb9af46d9), + SPH_C32(0x995ccfac) }, + { SPH_C32(0x7fb10000), SPH_C32(0x6863003d), SPH_C32(0x0d5c2180), + SPH_C32(0x9e660000), SPH_C32(0x78197ec4), SPH_C32(0xec7a463c), + SPH_C32(0x4481945b), SPH_C32(0x081e7ebb), SPH_C32(0xff860000), + SPH_C32(0x63680015), SPH_C32(0xa314f200), SPH_C32(0xf23c0000), + SPH_C32(0x281001e1), SPH_C32(0xa82930db), SPH_C32(0x8a7e9935), + SPH_C32(0x9012fe34) }, + { SPH_C32(0x92600000), SPH_C32(0x1cf3003e), SPH_C32(0xb145e000), + SPH_C32(0xdce00000), SPH_C32(0x8e0900be), SPH_C32(0x727b649f), + SPH_C32(0xb23b59f4), SPH_C32(0xcdd70139), SPH_C32(0xd3f40000), + SPH_C32(0xdf9e0014), SPH_C32(0x06326000), SPH_C32(0xe88a0000), + SPH_C32(0xb8a67fcc), SPH_C32(0x5dd12a75), SPH_C32(0x339210bc), + SPH_C32(0x8aeb81e3) }, + { SPH_C32(0x8c2e0000), SPH_C32(0xc23c003e), SPH_C32(0xdcbde180), + SPH_C32(0xabc40000), SPH_C32(0x624e0720), SPH_C32(0x86db0dd1), + SPH_C32(0x7f9841e6), SPH_C32(0x557d4857), SPH_C32(0x61f20000), + SPH_C32(0x1af70014), SPH_C32(0x2e317200), SPH_C32(0x9ced0000), + SPH_C32(0x0e644938), SPH_C32(0xb6c3138d), SPH_C32(0x0043cf50), + SPH_C32(0x83a5b07b) }, + { SPH_C32(0x3ca30000), SPH_C32(0x80bc003f), SPH_C32(0xc8940000), + SPH_C32(0xf0f50000), SPH_C32(0xcbc5750d), SPH_C32(0x142bd3a9), + SPH_C32(0x19a9ae7b), SPH_C32(0x6ec55742), SPH_C32(0x08d10000), + SPH_C32(0xd6b70014), SPH_C32(0x4f98a000), SPH_C32(0x696b0000), + SPH_C32(0x72581495), SPH_C32(0x1fa81e44), SPH_C32(0x70c47bca), + SPH_C32(0x62873bcd) }, + { SPH_C32(0x22ed0000), SPH_C32(0x5e73003f), SPH_C32(0xa56c0180), + SPH_C32(0x87d10000), SPH_C32(0x27827293), SPH_C32(0xe08bbae7), + SPH_C32(0xd40ab669), SPH_C32(0xf66f1e2c), SPH_C32(0xbad70000), + SPH_C32(0x13de0014), SPH_C32(0x679bb200), SPH_C32(0x1d0c0000), + SPH_C32(0xc49a2261), SPH_C32(0xf4ba27bc), SPH_C32(0x4315a426), + SPH_C32(0x6bc90a55) }, + { SPH_C32(0x49450000), SPH_C32(0x15da003e), SPH_C32(0xf8ef2000), + SPH_C32(0x5d010000), SPH_C32(0x44f76be7), SPH_C32(0x300250ae), + SPH_C32(0xf16d3282), SPH_C32(0x25bbbb17), SPH_C32(0xa6120000), + SPH_C32(0x4af80015), SPH_C32(0x36494000), SPH_C32(0x457e0000), + SPH_C32(0x37946126), SPH_C32(0x79f8a972), SPH_C32(0xdb568c45), + SPH_C32(0xc1956db6) }, + { SPH_C32(0x570b0000), SPH_C32(0xcb15003e), SPH_C32(0x95172180), + SPH_C32(0x2a250000), SPH_C32(0xa8b06c79), SPH_C32(0xc4a239e0), + SPH_C32(0x3cce2a90), SPH_C32(0xbd11f279), SPH_C32(0x14140000), + SPH_C32(0x8f910015), SPH_C32(0x1e4a5200), SPH_C32(0x31190000), + SPH_C32(0x815657d2), SPH_C32(0x92ea908a), SPH_C32(0xe88753a9), + SPH_C32(0xc8db5c2e) }, + { SPH_C32(0xe7860000), SPH_C32(0x8995003f), SPH_C32(0x813ec000), + SPH_C32(0x71140000), SPH_C32(0x013b1e54), SPH_C32(0x5652e798), + SPH_C32(0x5affc50d), SPH_C32(0x86a9ed6c), SPH_C32(0x7d370000), + SPH_C32(0x43d10015), SPH_C32(0x7fe38000), SPH_C32(0xc49f0000), + SPH_C32(0xfd6a0a7f), SPH_C32(0x3b819d43), SPH_C32(0x9800e733), + SPH_C32(0x29f9d798) }, + { SPH_C32(0xf9c80000), SPH_C32(0x575a003f), SPH_C32(0xecc6c180), + SPH_C32(0x06300000), SPH_C32(0xed7c19ca), SPH_C32(0xa2f28ed6), + SPH_C32(0x975cdd1f), SPH_C32(0x1e03a402), SPH_C32(0xcf310000), + SPH_C32(0x86b80015), SPH_C32(0x57e09200), SPH_C32(0xb0f80000), + SPH_C32(0x4ba83c8b), SPH_C32(0xd093a4bb), SPH_C32(0xabd138df), + SPH_C32(0x20b7e600) }, + { SPH_C32(0x24ae0000), SPH_C32(0xc61a003c), SPH_C32(0xa42b6000), + SPH_C32(0x06720000), SPH_C32(0x78d45ada), SPH_C32(0x44493815), + SPH_C32(0x4049b15a), SPH_C32(0x6b6fc3b4), SPH_C32(0x558d0000), + SPH_C32(0xe0a70016), SPH_C32(0xe7a88000), SPH_C32(0x70dc0000), + SPH_C32(0x2dc318c2), SPH_C32(0x1359e29f), SPH_C32(0xe04f59f8), + SPH_C32(0x9cf65b5a) }, + { SPH_C32(0x3ae00000), SPH_C32(0x18d5003c), SPH_C32(0xc9d36180), + SPH_C32(0x71560000), SPH_C32(0x94935d44), SPH_C32(0xb0e9515b), + SPH_C32(0x8deaa948), SPH_C32(0xf3c58ada), SPH_C32(0xe78b0000), + SPH_C32(0x25ce0016), SPH_C32(0xcfab9200), SPH_C32(0x04bb0000), + SPH_C32(0x9b012e36), SPH_C32(0xf84bdb67), SPH_C32(0xd39e8614), + SPH_C32(0x95b86ac2) }, + { SPH_C32(0x8a6d0000), SPH_C32(0x5a55003d), SPH_C32(0xddfa8000), + SPH_C32(0x2a670000), SPH_C32(0x3d182f69), SPH_C32(0x22198f23), + SPH_C32(0xebdb46d5), SPH_C32(0xc87d95cf), SPH_C32(0x8ea80000), + SPH_C32(0xe98e0016), SPH_C32(0xae024000), SPH_C32(0xf13d0000), + SPH_C32(0xe73d739b), SPH_C32(0x5120d6ae), SPH_C32(0xa319328e), + SPH_C32(0x749ae174) }, + { SPH_C32(0x94230000), SPH_C32(0x849a003d), SPH_C32(0xb0028180), + SPH_C32(0x5d430000), SPH_C32(0xd15f28f7), SPH_C32(0xd6b9e66d), + SPH_C32(0x26785ec7), SPH_C32(0x50d7dca1), SPH_C32(0x3cae0000), + SPH_C32(0x2ce70016), SPH_C32(0x86015200), SPH_C32(0x855a0000), + SPH_C32(0x51ff456f), SPH_C32(0xba32ef56), SPH_C32(0x90c8ed62), + SPH_C32(0x7dd4d0ec) }, + { SPH_C32(0xff8b0000), SPH_C32(0xcf33003c), SPH_C32(0xed81a000), + SPH_C32(0x87930000), SPH_C32(0xb22a3183), SPH_C32(0x06300c24), + SPH_C32(0x031fda2c), SPH_C32(0x8303799a), SPH_C32(0x206b0000), + SPH_C32(0x75c10017), SPH_C32(0xd7d3a000), SPH_C32(0xdd280000), + SPH_C32(0xa2f10628), SPH_C32(0x37706198), SPH_C32(0x088bc501), + SPH_C32(0xd788b70f) }, + { SPH_C32(0xe1c50000), SPH_C32(0x11fc003c), SPH_C32(0x8079a180), + SPH_C32(0xf0b70000), SPH_C32(0x5e6d361d), SPH_C32(0xf290656a), + SPH_C32(0xcebcc23e), SPH_C32(0x1ba930f4), SPH_C32(0x926d0000), + SPH_C32(0xb0a80017), SPH_C32(0xffd0b200), SPH_C32(0xa94f0000), + SPH_C32(0x143330dc), SPH_C32(0xdc625860), SPH_C32(0x3b5a1aed), + SPH_C32(0xdec68697) }, + { SPH_C32(0x51480000), SPH_C32(0x537c003d), SPH_C32(0x94504000), + SPH_C32(0xab860000), SPH_C32(0xf7e64430), SPH_C32(0x6060bb12), + SPH_C32(0xa88d2da3), SPH_C32(0x20112fe1), SPH_C32(0xfb4e0000), + SPH_C32(0x7ce80017), SPH_C32(0x9e796000), SPH_C32(0x5cc90000), + SPH_C32(0x680f6d71), SPH_C32(0x750955a9), SPH_C32(0x4bddae77), + SPH_C32(0x3fe40d21) }, + { SPH_C32(0x4f060000), SPH_C32(0x8db3003d), SPH_C32(0xf9a84180), + SPH_C32(0xdca20000), SPH_C32(0x1ba143ae), SPH_C32(0x94c0d25c), + SPH_C32(0x652e35b1), SPH_C32(0xb8bb668f), SPH_C32(0x49480000), + SPH_C32(0xb9810017), SPH_C32(0xb67a7200), SPH_C32(0x28ae0000), + SPH_C32(0xdecd5b85), SPH_C32(0x9e1b6c51), SPH_C32(0x780c719b), + SPH_C32(0x36aa3cb9) }, + { SPH_C32(0xa2d70000), SPH_C32(0xf923003e), SPH_C32(0x45b18000), + SPH_C32(0x9e240000), SPH_C32(0xedb13dd4), SPH_C32(0x0ac1f0ff), + SPH_C32(0x9394f81e), SPH_C32(0x7d72190d), SPH_C32(0x653a0000), + SPH_C32(0x05770016), SPH_C32(0x135ce000), SPH_C32(0x32180000), + SPH_C32(0x4e7b25a8), SPH_C32(0x6be376ff), SPH_C32(0xc1e0f812), + SPH_C32(0x2c53436e) }, + { SPH_C32(0xbc990000), SPH_C32(0x27ec003e), SPH_C32(0x28498180), + SPH_C32(0xe9000000), SPH_C32(0x01f63a4a), SPH_C32(0xfe6199b1), + SPH_C32(0x5e37e00c), SPH_C32(0xe5d85063), SPH_C32(0xd73c0000), + SPH_C32(0xc01e0016), SPH_C32(0x3b5ff200), SPH_C32(0x467f0000), + SPH_C32(0xf8b9135c), SPH_C32(0x80f14f07), SPH_C32(0xf23127fe), + SPH_C32(0x251d72f6) }, + { SPH_C32(0x0c140000), SPH_C32(0x656c003f), SPH_C32(0x3c606000), + SPH_C32(0xb2310000), SPH_C32(0xa87d4867), SPH_C32(0x6c9147c9), + SPH_C32(0x38060f91), SPH_C32(0xde604f76), SPH_C32(0xbe1f0000), + SPH_C32(0x0c5e0016), SPH_C32(0x5af62000), SPH_C32(0xb3f90000), + SPH_C32(0x84854ef1), SPH_C32(0x299a42ce), SPH_C32(0x82b69364), + SPH_C32(0xc43ff940) }, + { SPH_C32(0x125a0000), SPH_C32(0xbba3003f), SPH_C32(0x51986180), + SPH_C32(0xc5150000), SPH_C32(0x443a4ff9), SPH_C32(0x98312e87), + SPH_C32(0xf5a51783), SPH_C32(0x46ca0618), SPH_C32(0x0c190000), + SPH_C32(0xc9370016), SPH_C32(0x72f53200), SPH_C32(0xc79e0000), + SPH_C32(0x32477805), SPH_C32(0xc2887b36), SPH_C32(0xb1674c88), + SPH_C32(0xcd71c8d8) }, + { SPH_C32(0x79f20000), SPH_C32(0xf00a003e), SPH_C32(0x0c1b4000), + SPH_C32(0x1fc50000), SPH_C32(0x274f568d), SPH_C32(0x48b8c4ce), + SPH_C32(0xd0c29368), SPH_C32(0x951ea323), SPH_C32(0x10dc0000), + SPH_C32(0x90110017), SPH_C32(0x2327c000), SPH_C32(0x9fec0000), + SPH_C32(0xc1493b42), SPH_C32(0x4fcaf5f8), SPH_C32(0x292464eb), + SPH_C32(0x672daf3b) }, + { SPH_C32(0x67bc0000), SPH_C32(0x2ec5003e), SPH_C32(0x61e34180), + SPH_C32(0x68e10000), SPH_C32(0xcb085113), SPH_C32(0xbc18ad80), + SPH_C32(0x1d618b7a), SPH_C32(0x0db4ea4d), SPH_C32(0xa2da0000), + SPH_C32(0x55780017), SPH_C32(0x0b24d200), SPH_C32(0xeb8b0000), + SPH_C32(0x778b0db6), SPH_C32(0xa4d8cc00), SPH_C32(0x1af5bb07), + SPH_C32(0x6e639ea3) }, + { SPH_C32(0xd7310000), SPH_C32(0x6c45003f), SPH_C32(0x75caa000), + SPH_C32(0x33d00000), SPH_C32(0x6283233e), SPH_C32(0x2ee873f8), + SPH_C32(0x7b5064e7), SPH_C32(0x360cf558), SPH_C32(0xcbf90000), + SPH_C32(0x99380017), SPH_C32(0x6a8d0000), SPH_C32(0x1e0d0000), + SPH_C32(0x0bb7501b), SPH_C32(0x0db3c1c9), SPH_C32(0x6a720f9d), + SPH_C32(0x8f411515) }, + { SPH_C32(0xc97f0000), SPH_C32(0xb28a003f), SPH_C32(0x1832a180), + SPH_C32(0x44f40000), SPH_C32(0x8ec424a0), SPH_C32(0xda481ab6), + SPH_C32(0xb6f37cf5), SPH_C32(0xaea6bc36), SPH_C32(0x79ff0000), + SPH_C32(0x5c510017), SPH_C32(0x428e1200), SPH_C32(0x6a6a0000), + SPH_C32(0xbd7566ef), SPH_C32(0xe6a1f831), SPH_C32(0x59a3d071), + SPH_C32(0x860f248d) }, + { SPH_C32(0xe3430000), SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), + SPH_C32(0xaa4e0000), SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), + SPH_C32(0x123db156), SPH_C32(0x3a4e99d7), SPH_C32(0xf75a0000), + SPH_C32(0x19840028), SPH_C32(0xa2190000), SPH_C32(0xeef80000), + SPH_C32(0xc0722516), SPH_C32(0x19981260), SPH_C32(0x73dba1e6), + SPH_C32(0xe1844257) }, + { SPH_C32(0xfd0d0000), SPH_C32(0xe4810014), SPH_C32(0x9f3e0180), + SPH_C32(0xdd6a0000), SPH_C32(0x37594538), SPH_C32(0xd1cbd75b), + SPH_C32(0xdf9ea944), SPH_C32(0xa2e4d0b9), SPH_C32(0x455c0000), + SPH_C32(0xdced0028), SPH_C32(0x8a1a1200), SPH_C32(0x9a9f0000), + SPH_C32(0x76b013e2), SPH_C32(0xf28a2b98), SPH_C32(0x400a7e0a), + SPH_C32(0xe8ca73cf) }, + { SPH_C32(0x4d800000), SPH_C32(0xa6010015), SPH_C32(0x8b17e000), + SPH_C32(0x865b0000), SPH_C32(0x9ed23715), SPH_C32(0x433b0923), + SPH_C32(0xb9af46d9), SPH_C32(0x995ccfac), SPH_C32(0x2c7f0000), + SPH_C32(0x10ad0028), SPH_C32(0xebb3c000), SPH_C32(0x6f190000), + SPH_C32(0x0a8c4e4f), SPH_C32(0x5be12651), SPH_C32(0x308dca90), + SPH_C32(0x09e8f879) }, + { SPH_C32(0x53ce0000), SPH_C32(0x78ce0015), SPH_C32(0xe6efe180), + SPH_C32(0xf17f0000), SPH_C32(0x7295308b), SPH_C32(0xb79b606d), + SPH_C32(0x740c5ecb), SPH_C32(0x01f686c2), SPH_C32(0x9e790000), + SPH_C32(0xd5c40028), SPH_C32(0xc3b0d200), SPH_C32(0x1b7e0000), + SPH_C32(0xbc4e78bb), SPH_C32(0xb0f31fa9), SPH_C32(0x035c157c), + SPH_C32(0x00a6c9e1) }, + { SPH_C32(0x38660000), SPH_C32(0x33670014), SPH_C32(0xbb6cc000), + SPH_C32(0x2baf0000), SPH_C32(0x11e029ff), SPH_C32(0x67128a24), + SPH_C32(0x516bda20), SPH_C32(0xd22223f9), SPH_C32(0x82bc0000), + SPH_C32(0x8ce20029), SPH_C32(0x92622000), SPH_C32(0x430c0000), + SPH_C32(0x4f403bfc), SPH_C32(0x3db19167), SPH_C32(0x9b1f3d1f), + SPH_C32(0xaafaae02) }, + { SPH_C32(0x26280000), SPH_C32(0xeda80014), SPH_C32(0xd694c180), + SPH_C32(0x5c8b0000), SPH_C32(0xfda72e61), SPH_C32(0x93b2e36a), + SPH_C32(0x9cc8c232), SPH_C32(0x4a886a97), SPH_C32(0x30ba0000), + SPH_C32(0x498b0029), SPH_C32(0xba613200), SPH_C32(0x376b0000), + SPH_C32(0xf9820d08), SPH_C32(0xd6a3a89f), SPH_C32(0xa8cee2f3), + SPH_C32(0xa3b49f9a) }, + { SPH_C32(0x96a50000), SPH_C32(0xaf280015), SPH_C32(0xc2bd2000), + SPH_C32(0x07ba0000), SPH_C32(0x542c5c4c), SPH_C32(0x01423d12), + SPH_C32(0xfaf92daf), SPH_C32(0x71307582), SPH_C32(0x59990000), + SPH_C32(0x85cb0029), SPH_C32(0xdbc8e000), SPH_C32(0xc2ed0000), + SPH_C32(0x85be50a5), SPH_C32(0x7fc8a556), SPH_C32(0xd8495669), + SPH_C32(0x4296142c) }, + { SPH_C32(0x88eb0000), SPH_C32(0x71e70015), SPH_C32(0xaf452180), + SPH_C32(0x709e0000), SPH_C32(0xb86b5bd2), SPH_C32(0xf5e2545c), + SPH_C32(0x375a35bd), SPH_C32(0xe99a3cec), SPH_C32(0xeb9f0000), + SPH_C32(0x40a20029), SPH_C32(0xf3cbf200), SPH_C32(0xb68a0000), + SPH_C32(0x337c6651), SPH_C32(0x94da9cae), SPH_C32(0xeb988985), + SPH_C32(0x4bd825b4) }, + { SPH_C32(0x653a0000), SPH_C32(0x05770016), SPH_C32(0x135ce000), + SPH_C32(0x32180000), SPH_C32(0x4e7b25a8), SPH_C32(0x6be376ff), + SPH_C32(0xc1e0f812), SPH_C32(0x2c53436e), SPH_C32(0xc7ed0000), + SPH_C32(0xfc540028), SPH_C32(0x56ed6000), SPH_C32(0xac3c0000), + SPH_C32(0xa3ca187c), SPH_C32(0x61228600), SPH_C32(0x5274000c), + SPH_C32(0x51215a63) }, + { SPH_C32(0x7b740000), SPH_C32(0xdbb80016), SPH_C32(0x7ea4e180), + SPH_C32(0x453c0000), SPH_C32(0xa23c2236), SPH_C32(0x9f431fb1), + SPH_C32(0x0c43e000), SPH_C32(0xb4f90a00), SPH_C32(0x75eb0000), + SPH_C32(0x393d0028), SPH_C32(0x7eee7200), SPH_C32(0xd85b0000), + SPH_C32(0x15082e88), SPH_C32(0x8a30bff8), SPH_C32(0x61a5dfe0), + SPH_C32(0x586f6bfb) }, + { SPH_C32(0xcbf90000), SPH_C32(0x99380017), SPH_C32(0x6a8d0000), + SPH_C32(0x1e0d0000), SPH_C32(0x0bb7501b), SPH_C32(0x0db3c1c9), + SPH_C32(0x6a720f9d), SPH_C32(0x8f411515), SPH_C32(0x1cc80000), + SPH_C32(0xf57d0028), SPH_C32(0x1f47a000), SPH_C32(0x2ddd0000), + SPH_C32(0x69347325), SPH_C32(0x235bb231), SPH_C32(0x11226b7a), + SPH_C32(0xb94de04d) }, + { SPH_C32(0xd5b70000), SPH_C32(0x47f70017), SPH_C32(0x07750180), + SPH_C32(0x69290000), SPH_C32(0xe7f05785), SPH_C32(0xf913a887), + SPH_C32(0xa7d1178f), SPH_C32(0x17eb5c7b), SPH_C32(0xaece0000), + SPH_C32(0x30140028), SPH_C32(0x3744b200), SPH_C32(0x59ba0000), + SPH_C32(0xdff645d1), SPH_C32(0xc8498bc9), SPH_C32(0x22f3b496), + SPH_C32(0xb003d1d5) }, + { SPH_C32(0xbe1f0000), SPH_C32(0x0c5e0016), SPH_C32(0x5af62000), + SPH_C32(0xb3f90000), SPH_C32(0x84854ef1), SPH_C32(0x299a42ce), + SPH_C32(0x82b69364), SPH_C32(0xc43ff940), SPH_C32(0xb20b0000), + SPH_C32(0x69320029), SPH_C32(0x66964000), SPH_C32(0x01c80000), + SPH_C32(0x2cf80696), SPH_C32(0x450b0507), SPH_C32(0xbab09cf5), + SPH_C32(0x1a5fb636) }, + { SPH_C32(0xa0510000), SPH_C32(0xd2910016), SPH_C32(0x370e2180), + SPH_C32(0xc4dd0000), SPH_C32(0x68c2496f), SPH_C32(0xdd3a2b80), + SPH_C32(0x4f158b76), SPH_C32(0x5c95b02e), SPH_C32(0x000d0000), + SPH_C32(0xac5b0029), SPH_C32(0x4e955200), SPH_C32(0x75af0000), + SPH_C32(0x9a3a3062), SPH_C32(0xae193cff), SPH_C32(0x89614319), + SPH_C32(0x131187ae) }, + { SPH_C32(0x10dc0000), SPH_C32(0x90110017), SPH_C32(0x2327c000), + SPH_C32(0x9fec0000), SPH_C32(0xc1493b42), SPH_C32(0x4fcaf5f8), + SPH_C32(0x292464eb), SPH_C32(0x672daf3b), SPH_C32(0x692e0000), + SPH_C32(0x601b0029), SPH_C32(0x2f3c8000), SPH_C32(0x80290000), + SPH_C32(0xe6066dcf), SPH_C32(0x07723136), SPH_C32(0xf9e6f783), + SPH_C32(0xf2330c18) }, + { SPH_C32(0x0e920000), SPH_C32(0x4ede0017), SPH_C32(0x4edfc180), + SPH_C32(0xe8c80000), SPH_C32(0x2d0e3cdc), SPH_C32(0xbb6a9cb6), + SPH_C32(0xe4877cf9), SPH_C32(0xff87e655), SPH_C32(0xdb280000), + SPH_C32(0xa5720029), SPH_C32(0x073f9200), SPH_C32(0xf44e0000), + SPH_C32(0x50c45b3b), SPH_C32(0xec6008ce), SPH_C32(0xca37286f), + SPH_C32(0xfb7d3d80) }, + { SPH_C32(0xd3f40000), SPH_C32(0xdf9e0014), SPH_C32(0x06326000), + SPH_C32(0xe88a0000), SPH_C32(0xb8a67fcc), SPH_C32(0x5dd12a75), + SPH_C32(0x339210bc), SPH_C32(0x8aeb81e3), SPH_C32(0x41940000), + SPH_C32(0xc36d002a), SPH_C32(0xb7778000), SPH_C32(0x346a0000), + SPH_C32(0x36af7f72), SPH_C32(0x2faa4eea), SPH_C32(0x81a94948), + SPH_C32(0x473c80da) }, + { SPH_C32(0xcdba0000), SPH_C32(0x01510014), SPH_C32(0x6bca6180), + SPH_C32(0x9fae0000), SPH_C32(0x54e17852), SPH_C32(0xa971433b), + SPH_C32(0xfe3108ae), SPH_C32(0x1241c88d), SPH_C32(0xf3920000), + SPH_C32(0x0604002a), SPH_C32(0x9f749200), SPH_C32(0x400d0000), + SPH_C32(0x806d4986), SPH_C32(0xc4b87712), SPH_C32(0xb27896a4), + SPH_C32(0x4e72b142) }, + { SPH_C32(0x7d370000), SPH_C32(0x43d10015), SPH_C32(0x7fe38000), + SPH_C32(0xc49f0000), SPH_C32(0xfd6a0a7f), SPH_C32(0x3b819d43), + SPH_C32(0x9800e733), SPH_C32(0x29f9d798), SPH_C32(0x9ab10000), + SPH_C32(0xca44002a), SPH_C32(0xfedd4000), SPH_C32(0xb58b0000), + SPH_C32(0xfc51142b), SPH_C32(0x6dd37adb), SPH_C32(0xc2ff223e), + SPH_C32(0xaf503af4) }, + { SPH_C32(0x63790000), SPH_C32(0x9d1e0015), SPH_C32(0x121b8180), + SPH_C32(0xb3bb0000), SPH_C32(0x112d0de1), SPH_C32(0xcf21f40d), + SPH_C32(0x55a3ff21), SPH_C32(0xb1539ef6), SPH_C32(0x28b70000), + SPH_C32(0x0f2d002a), SPH_C32(0xd6de5200), SPH_C32(0xc1ec0000), + SPH_C32(0x4a9322df), SPH_C32(0x86c14323), SPH_C32(0xf12efdd2), + SPH_C32(0xa61e0b6c) }, + { SPH_C32(0x08d10000), SPH_C32(0xd6b70014), SPH_C32(0x4f98a000), + SPH_C32(0x696b0000), SPH_C32(0x72581495), SPH_C32(0x1fa81e44), + SPH_C32(0x70c47bca), SPH_C32(0x62873bcd), SPH_C32(0x34720000), + SPH_C32(0x560b002b), SPH_C32(0x870ca000), SPH_C32(0x999e0000), + SPH_C32(0xb99d6198), SPH_C32(0x0b83cded), SPH_C32(0x696dd5b1), + SPH_C32(0x0c426c8f) }, + { SPH_C32(0x169f0000), SPH_C32(0x08780014), SPH_C32(0x2260a180), + SPH_C32(0x1e4f0000), SPH_C32(0x9e1f130b), SPH_C32(0xeb08770a), + SPH_C32(0xbd6763d8), SPH_C32(0xfa2d72a3), SPH_C32(0x86740000), + SPH_C32(0x9362002b), SPH_C32(0xaf0fb200), SPH_C32(0xedf90000), + SPH_C32(0x0f5f576c), SPH_C32(0xe091f415), SPH_C32(0x5abc0a5d), + SPH_C32(0x050c5d17) }, + { SPH_C32(0xa6120000), SPH_C32(0x4af80015), SPH_C32(0x36494000), + SPH_C32(0x457e0000), SPH_C32(0x37946126), SPH_C32(0x79f8a972), + SPH_C32(0xdb568c45), SPH_C32(0xc1956db6), SPH_C32(0xef570000), + SPH_C32(0x5f22002b), SPH_C32(0xcea66000), SPH_C32(0x187f0000), + SPH_C32(0x73630ac1), SPH_C32(0x49faf9dc), SPH_C32(0x2a3bbec7), + SPH_C32(0xe42ed6a1) }, + { SPH_C32(0xb85c0000), SPH_C32(0x94370015), SPH_C32(0x5bb14180), + SPH_C32(0x325a0000), SPH_C32(0xdbd366b8), SPH_C32(0x8d58c03c), + SPH_C32(0x16f59457), SPH_C32(0x593f24d8), SPH_C32(0x5d510000), + SPH_C32(0x9a4b002b), SPH_C32(0xe6a57200), SPH_C32(0x6c180000), + SPH_C32(0xc5a13c35), SPH_C32(0xa2e8c024), SPH_C32(0x19ea612b), + SPH_C32(0xed60e739) }, + { SPH_C32(0x558d0000), SPH_C32(0xe0a70016), SPH_C32(0xe7a88000), + SPH_C32(0x70dc0000), SPH_C32(0x2dc318c2), SPH_C32(0x1359e29f), + SPH_C32(0xe04f59f8), SPH_C32(0x9cf65b5a), SPH_C32(0x71230000), + SPH_C32(0x26bd002a), SPH_C32(0x4383e000), SPH_C32(0x76ae0000), + SPH_C32(0x55174218), SPH_C32(0x5710da8a), SPH_C32(0xa006e8a2), + SPH_C32(0xf79998ee) }, + { SPH_C32(0x4bc30000), SPH_C32(0x3e680016), SPH_C32(0x8a508180), + SPH_C32(0x07f80000), SPH_C32(0xc1841f5c), SPH_C32(0xe7f98bd1), + SPH_C32(0x2dec41ea), SPH_C32(0x045c1234), SPH_C32(0xc3250000), + SPH_C32(0xe3d4002a), SPH_C32(0x6b80f200), SPH_C32(0x02c90000), + SPH_C32(0xe3d574ec), SPH_C32(0xbc02e372), SPH_C32(0x93d7374e), + SPH_C32(0xfed7a976) }, + { SPH_C32(0xfb4e0000), SPH_C32(0x7ce80017), SPH_C32(0x9e796000), + SPH_C32(0x5cc90000), SPH_C32(0x680f6d71), SPH_C32(0x750955a9), + SPH_C32(0x4bddae77), SPH_C32(0x3fe40d21), SPH_C32(0xaa060000), + SPH_C32(0x2f94002a), SPH_C32(0x0a292000), SPH_C32(0xf74f0000), + SPH_C32(0x9fe92941), SPH_C32(0x1569eebb), SPH_C32(0xe35083d4), + SPH_C32(0x1ff522c0) }, + { SPH_C32(0xe5000000), SPH_C32(0xa2270017), SPH_C32(0xf3816180), + SPH_C32(0x2bed0000), SPH_C32(0x84486aef), SPH_C32(0x81a93ce7), + SPH_C32(0x867eb665), SPH_C32(0xa74e444f), SPH_C32(0x18000000), + SPH_C32(0xeafd002a), SPH_C32(0x222a3200), SPH_C32(0x83280000), + SPH_C32(0x292b1fb5), SPH_C32(0xfe7bd743), SPH_C32(0xd0815c38), + SPH_C32(0x16bb1358) }, + { SPH_C32(0x8ea80000), SPH_C32(0xe98e0016), SPH_C32(0xae024000), + SPH_C32(0xf13d0000), SPH_C32(0xe73d739b), SPH_C32(0x5120d6ae), + SPH_C32(0xa319328e), SPH_C32(0x749ae174), SPH_C32(0x04c50000), + SPH_C32(0xb3db002b), SPH_C32(0x73f8c000), SPH_C32(0xdb5a0000), + SPH_C32(0xda255cf2), SPH_C32(0x7339598d), SPH_C32(0x48c2745b), + SPH_C32(0xbce774bb) }, + { SPH_C32(0x90e60000), SPH_C32(0x37410016), SPH_C32(0xc3fa4180), + SPH_C32(0x86190000), SPH_C32(0x0b7a7405), SPH_C32(0xa580bfe0), + SPH_C32(0x6eba2a9c), SPH_C32(0xec30a81a), SPH_C32(0xb6c30000), + SPH_C32(0x76b2002b), SPH_C32(0x5bfbd200), SPH_C32(0xaf3d0000), + SPH_C32(0x6ce76a06), SPH_C32(0x982b6075), SPH_C32(0x7b13abb7), + SPH_C32(0xb5a94523) }, + { SPH_C32(0x206b0000), SPH_C32(0x75c10017), SPH_C32(0xd7d3a000), + SPH_C32(0xdd280000), SPH_C32(0xa2f10628), SPH_C32(0x37706198), + SPH_C32(0x088bc501), SPH_C32(0xd788b70f), SPH_C32(0xdfe00000), + SPH_C32(0xbaf2002b), SPH_C32(0x3a520000), SPH_C32(0x5abb0000), + SPH_C32(0x10db37ab), SPH_C32(0x31406dbc), SPH_C32(0x0b941f2d), + SPH_C32(0x548bce95) }, + { SPH_C32(0x3e250000), SPH_C32(0xab0e0017), SPH_C32(0xba2ba180), + SPH_C32(0xaa0c0000), SPH_C32(0x4eb601b6), SPH_C32(0xc3d008d6), + SPH_C32(0xc528dd13), SPH_C32(0x4f22fe61), SPH_C32(0x6de60000), + SPH_C32(0x7f9b002b), SPH_C32(0x12511200), SPH_C32(0x2edc0000), + SPH_C32(0xa619015f), SPH_C32(0xda525444), SPH_C32(0x3845c0c1), + SPH_C32(0x5dc5ff0d) }, + { SPH_C32(0xf75a0000), SPH_C32(0x19840028), SPH_C32(0xa2190000), + SPH_C32(0xeef80000), SPH_C32(0xc0722516), SPH_C32(0x19981260), + SPH_C32(0x73dba1e6), SPH_C32(0xe1844257), SPH_C32(0x14190000), + SPH_C32(0x23ca003c), SPH_C32(0x50df0000), SPH_C32(0x44b60000), + SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), SPH_C32(0x61e610b0), + SPH_C32(0xdbcadb80) }, + { SPH_C32(0xe9140000), SPH_C32(0xc74b0028), SPH_C32(0xcfe10180), + SPH_C32(0x99dc0000), SPH_C32(0x2c352288), SPH_C32(0xed387b2e), + SPH_C32(0xbe78b9f4), SPH_C32(0x792e0b39), SPH_C32(0xa61f0000), + SPH_C32(0xe6a3003c), SPH_C32(0x78dc1200), SPH_C32(0x30d10000), + SPH_C32(0xadae5144), SPH_C32(0xd7e1958d), SPH_C32(0x5237cf5c), + SPH_C32(0xd284ea18) }, + { SPH_C32(0x59990000), SPH_C32(0x85cb0029), SPH_C32(0xdbc8e000), + SPH_C32(0xc2ed0000), SPH_C32(0x85be50a5), SPH_C32(0x7fc8a556), + SPH_C32(0xd8495669), SPH_C32(0x4296142c), SPH_C32(0xcf3c0000), + SPH_C32(0x2ae3003c), SPH_C32(0x1975c000), SPH_C32(0xc5570000), + SPH_C32(0xd1920ce9), SPH_C32(0x7e8a9844), SPH_C32(0x22b07bc6), + SPH_C32(0x33a661ae) }, + { SPH_C32(0x47d70000), SPH_C32(0x5b040029), SPH_C32(0xb630e180), + SPH_C32(0xb5c90000), SPH_C32(0x69f9573b), SPH_C32(0x8b68cc18), + SPH_C32(0x15ea4e7b), SPH_C32(0xda3c5d42), SPH_C32(0x7d3a0000), + SPH_C32(0xef8a003c), SPH_C32(0x3176d200), SPH_C32(0xb1300000), + SPH_C32(0x67503a1d), SPH_C32(0x9598a1bc), SPH_C32(0x1161a42a), + SPH_C32(0x3ae85036) }, + { SPH_C32(0x2c7f0000), SPH_C32(0x10ad0028), SPH_C32(0xebb3c000), + SPH_C32(0x6f190000), SPH_C32(0x0a8c4e4f), SPH_C32(0x5be12651), + SPH_C32(0x308dca90), SPH_C32(0x09e8f879), SPH_C32(0x61ff0000), + SPH_C32(0xb6ac003d), SPH_C32(0x60a42000), SPH_C32(0xe9420000), + SPH_C32(0x945e795a), SPH_C32(0x18da2f72), SPH_C32(0x89228c49), + SPH_C32(0x90b437d5) }, + { SPH_C32(0x32310000), SPH_C32(0xce620028), SPH_C32(0x864bc180), + SPH_C32(0x183d0000), SPH_C32(0xe6cb49d1), SPH_C32(0xaf414f1f), + SPH_C32(0xfd2ed282), SPH_C32(0x9142b117), SPH_C32(0xd3f90000), + SPH_C32(0x73c5003d), SPH_C32(0x48a73200), SPH_C32(0x9d250000), + SPH_C32(0x229c4fae), SPH_C32(0xf3c8168a), SPH_C32(0xbaf353a5), + SPH_C32(0x99fa064d) }, + { SPH_C32(0x82bc0000), SPH_C32(0x8ce20029), SPH_C32(0x92622000), + SPH_C32(0x430c0000), SPH_C32(0x4f403bfc), SPH_C32(0x3db19167), + SPH_C32(0x9b1f3d1f), SPH_C32(0xaafaae02), SPH_C32(0xbada0000), + SPH_C32(0xbf85003d), SPH_C32(0x290ee000), SPH_C32(0x68a30000), + SPH_C32(0x5ea01203), SPH_C32(0x5aa31b43), SPH_C32(0xca74e73f), + SPH_C32(0x78d88dfb) }, + { SPH_C32(0x9cf20000), SPH_C32(0x522d0029), SPH_C32(0xff9a2180), + SPH_C32(0x34280000), SPH_C32(0xa3073c62), SPH_C32(0xc911f829), + SPH_C32(0x56bc250d), SPH_C32(0x3250e76c), SPH_C32(0x08dc0000), + SPH_C32(0x7aec003d), SPH_C32(0x010df200), SPH_C32(0x1cc40000), + SPH_C32(0xe86224f7), SPH_C32(0xb1b122bb), SPH_C32(0xf9a538d3), + SPH_C32(0x7196bc63) }, + { SPH_C32(0x71230000), SPH_C32(0x26bd002a), SPH_C32(0x4383e000), + SPH_C32(0x76ae0000), SPH_C32(0x55174218), SPH_C32(0x5710da8a), + SPH_C32(0xa006e8a2), SPH_C32(0xf79998ee), SPH_C32(0x24ae0000), + SPH_C32(0xc61a003c), SPH_C32(0xa42b6000), SPH_C32(0x06720000), + SPH_C32(0x78d45ada), SPH_C32(0x44493815), SPH_C32(0x4049b15a), + SPH_C32(0x6b6fc3b4) }, + { SPH_C32(0x6f6d0000), SPH_C32(0xf872002a), SPH_C32(0x2e7be180), + SPH_C32(0x018a0000), SPH_C32(0xb9504586), SPH_C32(0xa3b0b3c4), + SPH_C32(0x6da5f0b0), SPH_C32(0x6f33d180), SPH_C32(0x96a80000), + SPH_C32(0x0373003c), SPH_C32(0x8c287200), SPH_C32(0x72150000), + SPH_C32(0xce166c2e), SPH_C32(0xaf5b01ed), SPH_C32(0x73986eb6), + SPH_C32(0x6221f22c) }, + { SPH_C32(0xdfe00000), SPH_C32(0xbaf2002b), SPH_C32(0x3a520000), + SPH_C32(0x5abb0000), SPH_C32(0x10db37ab), SPH_C32(0x31406dbc), + SPH_C32(0x0b941f2d), SPH_C32(0x548bce95), SPH_C32(0xff8b0000), + SPH_C32(0xcf33003c), SPH_C32(0xed81a000), SPH_C32(0x87930000), + SPH_C32(0xb22a3183), SPH_C32(0x06300c24), SPH_C32(0x031fda2c), + SPH_C32(0x8303799a) }, + { SPH_C32(0xc1ae0000), SPH_C32(0x643d002b), SPH_C32(0x57aa0180), + SPH_C32(0x2d9f0000), SPH_C32(0xfc9c3035), SPH_C32(0xc5e004f2), + SPH_C32(0xc637073f), SPH_C32(0xcc2187fb), SPH_C32(0x4d8d0000), + SPH_C32(0x0a5a003c), SPH_C32(0xc582b200), SPH_C32(0xf3f40000), + SPH_C32(0x04e80777), SPH_C32(0xed2235dc), SPH_C32(0x30ce05c0), + SPH_C32(0x8a4d4802) }, + { SPH_C32(0xaa060000), SPH_C32(0x2f94002a), SPH_C32(0x0a292000), + SPH_C32(0xf74f0000), SPH_C32(0x9fe92941), SPH_C32(0x1569eebb), + SPH_C32(0xe35083d4), SPH_C32(0x1ff522c0), SPH_C32(0x51480000), + SPH_C32(0x537c003d), SPH_C32(0x94504000), SPH_C32(0xab860000), + SPH_C32(0xf7e64430), SPH_C32(0x6060bb12), SPH_C32(0xa88d2da3), + SPH_C32(0x20112fe1) }, + { SPH_C32(0xb4480000), SPH_C32(0xf15b002a), SPH_C32(0x67d12180), + SPH_C32(0x806b0000), SPH_C32(0x73ae2edf), SPH_C32(0xe1c987f5), + SPH_C32(0x2ef39bc6), SPH_C32(0x875f6bae), SPH_C32(0xe34e0000), + SPH_C32(0x9615003d), SPH_C32(0xbc535200), SPH_C32(0xdfe10000), + SPH_C32(0x412472c4), SPH_C32(0x8b7282ea), SPH_C32(0x9b5cf24f), + SPH_C32(0x295f1e79) }, + { SPH_C32(0x04c50000), SPH_C32(0xb3db002b), SPH_C32(0x73f8c000), + SPH_C32(0xdb5a0000), SPH_C32(0xda255cf2), SPH_C32(0x7339598d), + SPH_C32(0x48c2745b), SPH_C32(0xbce774bb), SPH_C32(0x8a6d0000), + SPH_C32(0x5a55003d), SPH_C32(0xddfa8000), SPH_C32(0x2a670000), + SPH_C32(0x3d182f69), SPH_C32(0x22198f23), SPH_C32(0xebdb46d5), + SPH_C32(0xc87d95cf) }, + { SPH_C32(0x1a8b0000), SPH_C32(0x6d14002b), SPH_C32(0x1e00c180), + SPH_C32(0xac7e0000), SPH_C32(0x36625b6c), SPH_C32(0x879930c3), + SPH_C32(0x85616c49), SPH_C32(0x244d3dd5), SPH_C32(0x386b0000), + SPH_C32(0x9f3c003d), SPH_C32(0xf5f99200), SPH_C32(0x5e000000), + SPH_C32(0x8bda199d), SPH_C32(0xc90bb6db), SPH_C32(0xd80a9939), + SPH_C32(0xc133a457) }, + { SPH_C32(0xc7ed0000), SPH_C32(0xfc540028), SPH_C32(0x56ed6000), + SPH_C32(0xac3c0000), SPH_C32(0xa3ca187c), SPH_C32(0x61228600), + SPH_C32(0x5274000c), SPH_C32(0x51215a63), SPH_C32(0xa2d70000), + SPH_C32(0xf923003e), SPH_C32(0x45b18000), SPH_C32(0x9e240000), + SPH_C32(0xedb13dd4), SPH_C32(0x0ac1f0ff), SPH_C32(0x9394f81e), + SPH_C32(0x7d72190d) }, + { SPH_C32(0xd9a30000), SPH_C32(0x229b0028), SPH_C32(0x3b156180), + SPH_C32(0xdb180000), SPH_C32(0x4f8d1fe2), SPH_C32(0x9582ef4e), + SPH_C32(0x9fd7181e), SPH_C32(0xc98b130d), SPH_C32(0x10d10000), + SPH_C32(0x3c4a003e), SPH_C32(0x6db29200), SPH_C32(0xea430000), + SPH_C32(0x5b730b20), SPH_C32(0xe1d3c907), SPH_C32(0xa04527f2), + SPH_C32(0x743c2895) }, + { SPH_C32(0x692e0000), SPH_C32(0x601b0029), SPH_C32(0x2f3c8000), + SPH_C32(0x80290000), SPH_C32(0xe6066dcf), SPH_C32(0x07723136), + SPH_C32(0xf9e6f783), SPH_C32(0xf2330c18), SPH_C32(0x79f20000), + SPH_C32(0xf00a003e), SPH_C32(0x0c1b4000), SPH_C32(0x1fc50000), + SPH_C32(0x274f568d), SPH_C32(0x48b8c4ce), SPH_C32(0xd0c29368), + SPH_C32(0x951ea323) }, + { SPH_C32(0x77600000), SPH_C32(0xbed40029), SPH_C32(0x42c48180), + SPH_C32(0xf70d0000), SPH_C32(0x0a416a51), SPH_C32(0xf3d25878), + SPH_C32(0x3445ef91), SPH_C32(0x6a994576), SPH_C32(0xcbf40000), + SPH_C32(0x3563003e), SPH_C32(0x24185200), SPH_C32(0x6ba20000), + SPH_C32(0x918d6079), SPH_C32(0xa3aafd36), SPH_C32(0xe3134c84), + SPH_C32(0x9c5092bb) }, + { SPH_C32(0x1cc80000), SPH_C32(0xf57d0028), SPH_C32(0x1f47a000), + SPH_C32(0x2ddd0000), SPH_C32(0x69347325), SPH_C32(0x235bb231), + SPH_C32(0x11226b7a), SPH_C32(0xb94de04d), SPH_C32(0xd7310000), + SPH_C32(0x6c45003f), SPH_C32(0x75caa000), SPH_C32(0x33d00000), + SPH_C32(0x6283233e), SPH_C32(0x2ee873f8), SPH_C32(0x7b5064e7), + SPH_C32(0x360cf558) }, + { SPH_C32(0x02860000), SPH_C32(0x2bb20028), SPH_C32(0x72bfa180), + SPH_C32(0x5af90000), SPH_C32(0x857374bb), SPH_C32(0xd7fbdb7f), + SPH_C32(0xdc817368), SPH_C32(0x21e7a923), SPH_C32(0x65370000), + SPH_C32(0xa92c003f), SPH_C32(0x5dc9b200), SPH_C32(0x47b70000), + SPH_C32(0xd44115ca), SPH_C32(0xc5fa4a00), SPH_C32(0x4881bb0b), + SPH_C32(0x3f42c4c0) }, + { SPH_C32(0xb20b0000), SPH_C32(0x69320029), SPH_C32(0x66964000), + SPH_C32(0x01c80000), SPH_C32(0x2cf80696), SPH_C32(0x450b0507), + SPH_C32(0xbab09cf5), SPH_C32(0x1a5fb636), SPH_C32(0x0c140000), + SPH_C32(0x656c003f), SPH_C32(0x3c606000), SPH_C32(0xb2310000), + SPH_C32(0xa87d4867), SPH_C32(0x6c9147c9), SPH_C32(0x38060f91), + SPH_C32(0xde604f76) }, + { SPH_C32(0xac450000), SPH_C32(0xb7fd0029), SPH_C32(0x0b6e4180), + SPH_C32(0x76ec0000), SPH_C32(0xc0bf0108), SPH_C32(0xb1ab6c49), + SPH_C32(0x771384e7), SPH_C32(0x82f5ff58), SPH_C32(0xbe120000), + SPH_C32(0xa005003f), SPH_C32(0x14637200), SPH_C32(0xc6560000), + SPH_C32(0x1ebf7e93), SPH_C32(0x87837e31), SPH_C32(0x0bd7d07d), + SPH_C32(0xd72e7eee) }, + { SPH_C32(0x41940000), SPH_C32(0xc36d002a), SPH_C32(0xb7778000), + SPH_C32(0x346a0000), SPH_C32(0x36af7f72), SPH_C32(0x2faa4eea), + SPH_C32(0x81a94948), SPH_C32(0x473c80da), SPH_C32(0x92600000), + SPH_C32(0x1cf3003e), SPH_C32(0xb145e000), SPH_C32(0xdce00000), + SPH_C32(0x8e0900be), SPH_C32(0x727b649f), SPH_C32(0xb23b59f4), + SPH_C32(0xcdd70139) }, + { SPH_C32(0x5fda0000), SPH_C32(0x1da2002a), SPH_C32(0xda8f8180), + SPH_C32(0x434e0000), SPH_C32(0xdae878ec), SPH_C32(0xdb0a27a4), + SPH_C32(0x4c0a515a), SPH_C32(0xdf96c9b4), SPH_C32(0x20660000), + SPH_C32(0xd99a003e), SPH_C32(0x9946f200), SPH_C32(0xa8870000), + SPH_C32(0x38cb364a), SPH_C32(0x99695d67), SPH_C32(0x81ea8618), + SPH_C32(0xc49930a1) }, + { SPH_C32(0xef570000), SPH_C32(0x5f22002b), SPH_C32(0xcea66000), + SPH_C32(0x187f0000), SPH_C32(0x73630ac1), SPH_C32(0x49faf9dc), + SPH_C32(0x2a3bbec7), SPH_C32(0xe42ed6a1), SPH_C32(0x49450000), + SPH_C32(0x15da003e), SPH_C32(0xf8ef2000), SPH_C32(0x5d010000), + SPH_C32(0x44f76be7), SPH_C32(0x300250ae), SPH_C32(0xf16d3282), + SPH_C32(0x25bbbb17) }, + { SPH_C32(0xf1190000), SPH_C32(0x81ed002b), SPH_C32(0xa35e6180), + SPH_C32(0x6f5b0000), SPH_C32(0x9f240d5f), SPH_C32(0xbd5a9092), + SPH_C32(0xe798a6d5), SPH_C32(0x7c849fcf), SPH_C32(0xfb430000), + SPH_C32(0xd0b3003e), SPH_C32(0xd0ec3200), SPH_C32(0x29660000), + SPH_C32(0xf2355d13), SPH_C32(0xdb106956), SPH_C32(0xc2bced6e), + SPH_C32(0x2cf58a8f) }, + { SPH_C32(0x9ab10000), SPH_C32(0xca44002a), SPH_C32(0xfedd4000), + SPH_C32(0xb58b0000), SPH_C32(0xfc51142b), SPH_C32(0x6dd37adb), + SPH_C32(0xc2ff223e), SPH_C32(0xaf503af4), SPH_C32(0xe7860000), + SPH_C32(0x8995003f), SPH_C32(0x813ec000), SPH_C32(0x71140000), + SPH_C32(0x013b1e54), SPH_C32(0x5652e798), SPH_C32(0x5affc50d), + SPH_C32(0x86a9ed6c) }, + { SPH_C32(0x84ff0000), SPH_C32(0x148b002a), SPH_C32(0x93254180), + SPH_C32(0xc2af0000), SPH_C32(0x101613b5), SPH_C32(0x99731395), + SPH_C32(0x0f5c3a2c), SPH_C32(0x37fa739a), SPH_C32(0x55800000), + SPH_C32(0x4cfc003f), SPH_C32(0xa93dd200), SPH_C32(0x05730000), + SPH_C32(0xb7f928a0), SPH_C32(0xbd40de60), SPH_C32(0x692e1ae1), + SPH_C32(0x8fe7dcf4) }, + { SPH_C32(0x34720000), SPH_C32(0x560b002b), SPH_C32(0x870ca000), + SPH_C32(0x999e0000), SPH_C32(0xb99d6198), SPH_C32(0x0b83cded), + SPH_C32(0x696dd5b1), SPH_C32(0x0c426c8f), SPH_C32(0x3ca30000), + SPH_C32(0x80bc003f), SPH_C32(0xc8940000), SPH_C32(0xf0f50000), + SPH_C32(0xcbc5750d), SPH_C32(0x142bd3a9), SPH_C32(0x19a9ae7b), + SPH_C32(0x6ec55742) }, + { SPH_C32(0x2a3c0000), SPH_C32(0x88c4002b), SPH_C32(0xeaf4a180), + SPH_C32(0xeeba0000), SPH_C32(0x55da6606), SPH_C32(0xff23a4a3), + SPH_C32(0xa4cecda3), SPH_C32(0x94e825e1), SPH_C32(0x8ea50000), + SPH_C32(0x45d5003f), SPH_C32(0xe0971200), SPH_C32(0x84920000), + SPH_C32(0x7d0743f9), SPH_C32(0xff39ea51), SPH_C32(0x2a787197), + SPH_C32(0x678b66da) } +}; + +static const sph_u32 T512_35[128][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x52500000), SPH_C32(0x29540000), SPH_C32(0x6a61004e), + SPH_C32(0xf0ff0000), SPH_C32(0x9a317eec), SPH_C32(0x452341ce), + SPH_C32(0xcf568fe5), SPH_C32(0x5303130f), SPH_C32(0x538d0000), + SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), SPH_C32(0x56ff0000), + SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), SPH_C32(0xa9444018), + SPH_C32(0x7f975691) }, + { SPH_C32(0x538d0000), SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), + SPH_C32(0x56ff0000), SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), + SPH_C32(0xa9444018), SPH_C32(0x7f975691), SPH_C32(0x01dd0000), + SPH_C32(0x80a80000), SPH_C32(0xf4960048), SPH_C32(0xa6000000), + SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), SPH_C32(0x6612cffd), + SPH_C32(0x2c94459e) }, + { SPH_C32(0x01dd0000), SPH_C32(0x80a80000), SPH_C32(0xf4960048), + SPH_C32(0xa6000000), SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), + SPH_C32(0x6612cffd), SPH_C32(0x2c94459e), SPH_C32(0x52500000), + SPH_C32(0x29540000), SPH_C32(0x6a61004e), SPH_C32(0xf0ff0000), + SPH_C32(0x9a317eec), SPH_C32(0x452341ce), SPH_C32(0xcf568fe5), + SPH_C32(0x5303130f) }, + { SPH_C32(0xcc140000), SPH_C32(0xa5630000), SPH_C32(0x5ab90780), + SPH_C32(0x3b500000), SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), + SPH_C32(0x694348c1), SPH_C32(0xca5a87fe), SPH_C32(0x819e0000), + SPH_C32(0xec570000), SPH_C32(0x66320280), SPH_C32(0x95f30000), + SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), SPH_C32(0xe65aa22d), + SPH_C32(0x8e67b7fa) }, + { SPH_C32(0x9e440000), SPH_C32(0x8c370000), SPH_C32(0x30d807ce), + SPH_C32(0xcbaf0000), SPH_C32(0xd1e16d13), SPH_C32(0xc2b875d6), + SPH_C32(0xa615c724), SPH_C32(0x995994f1), SPH_C32(0xd2130000), + SPH_C32(0x45ab0000), SPH_C32(0xf8c50286), SPH_C32(0xc30c0000), + SPH_C32(0x574d284c), SPH_C32(0xda31f145), SPH_C32(0x4f1ee235), + SPH_C32(0xf1f0e16b) }, + { SPH_C32(0x9f990000), SPH_C32(0x0c9f0000), SPH_C32(0xc44e0786), + SPH_C32(0x6daf0000), SPH_C32(0x413413b1), SPH_C32(0x155ef9e1), + SPH_C32(0xc00708d9), SPH_C32(0xb5cdd16f), SPH_C32(0x80430000), + SPH_C32(0x6cff0000), SPH_C32(0x92a402c8), SPH_C32(0x33f30000), + SPH_C32(0xcd7c56a0), SPH_C32(0x9f12b08b), SPH_C32(0x80486dd0), + SPH_C32(0xa2f3f264) }, + { SPH_C32(0xcdc90000), SPH_C32(0x25cb0000), SPH_C32(0xae2f07c8), + SPH_C32(0x9d500000), SPH_C32(0xdb056d5d), SPH_C32(0x507db82f), + SPH_C32(0x0f51873c), SPH_C32(0xe6cec260), SPH_C32(0xd3ce0000), + SPH_C32(0xc5030000), SPH_C32(0x0c5302ce), SPH_C32(0x650c0000), + SPH_C32(0xc79856ee), SPH_C32(0x0dd77d72), SPH_C32(0x290c2dc8), + SPH_C32(0xdd64a4f5) }, + { SPH_C32(0x819e0000), SPH_C32(0xec570000), SPH_C32(0x66320280), + SPH_C32(0x95f30000), SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), + SPH_C32(0xe65aa22d), SPH_C32(0x8e67b7fa), SPH_C32(0x4d8a0000), + SPH_C32(0x49340000), SPH_C32(0x3c8b0500), SPH_C32(0xaea30000), + SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), SPH_C32(0x8f19eaec), + SPH_C32(0x443d3004) }, + { SPH_C32(0xd3ce0000), SPH_C32(0xc5030000), SPH_C32(0x0c5302ce), + SPH_C32(0x650c0000), SPH_C32(0xc79856ee), SPH_C32(0x0dd77d72), + SPH_C32(0x290c2dc8), SPH_C32(0xdd64a4f5), SPH_C32(0x1e070000), + SPH_C32(0xe0c80000), SPH_C32(0xa27c0506), SPH_C32(0xf85c0000), + SPH_C32(0x1c9d3bb3), SPH_C32(0x5daac55d), SPH_C32(0x265daaf4), + SPH_C32(0x3baa6695) }, + { SPH_C32(0xd2130000), SPH_C32(0x45ab0000), SPH_C32(0xf8c50286), + SPH_C32(0xc30c0000), SPH_C32(0x574d284c), SPH_C32(0xda31f145), + SPH_C32(0x4f1ee235), SPH_C32(0xf1f0e16b), SPH_C32(0x4c570000), + SPH_C32(0xc99c0000), SPH_C32(0xc81d0548), SPH_C32(0x08a30000), + SPH_C32(0x86ac455f), SPH_C32(0x18898493), SPH_C32(0xe90b2511), + SPH_C32(0x68a9759a) }, + { SPH_C32(0x80430000), SPH_C32(0x6cff0000), SPH_C32(0x92a402c8), + SPH_C32(0x33f30000), SPH_C32(0xcd7c56a0), SPH_C32(0x9f12b08b), + SPH_C32(0x80486dd0), SPH_C32(0xa2f3f264), SPH_C32(0x1fda0000), + SPH_C32(0x60600000), SPH_C32(0x56ea054e), SPH_C32(0x5e5c0000), + SPH_C32(0x8c484511), SPH_C32(0x8a4c496a), SPH_C32(0x404f6509), + SPH_C32(0x173e230b) }, + { SPH_C32(0x4d8a0000), SPH_C32(0x49340000), SPH_C32(0x3c8b0500), + SPH_C32(0xaea30000), SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), + SPH_C32(0x8f19eaec), SPH_C32(0x443d3004), SPH_C32(0xcc140000), + SPH_C32(0xa5630000), SPH_C32(0x5ab90780), SPH_C32(0x3b500000), + SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), SPH_C32(0x694348c1), + SPH_C32(0xca5a87fe) }, + { SPH_C32(0x1fda0000), SPH_C32(0x60600000), SPH_C32(0x56ea054e), + SPH_C32(0x5e5c0000), SPH_C32(0x8c484511), SPH_C32(0x8a4c496a), + SPH_C32(0x404f6509), SPH_C32(0x173e230b), SPH_C32(0x9f990000), + SPH_C32(0x0c9f0000), SPH_C32(0xc44e0786), SPH_C32(0x6daf0000), + SPH_C32(0x413413b1), SPH_C32(0x155ef9e1), SPH_C32(0xc00708d9), + SPH_C32(0xb5cdd16f) }, + { SPH_C32(0x1e070000), SPH_C32(0xe0c80000), SPH_C32(0xa27c0506), + SPH_C32(0xf85c0000), SPH_C32(0x1c9d3bb3), SPH_C32(0x5daac55d), + SPH_C32(0x265daaf4), SPH_C32(0x3baa6695), SPH_C32(0xcdc90000), + SPH_C32(0x25cb0000), SPH_C32(0xae2f07c8), SPH_C32(0x9d500000), + SPH_C32(0xdb056d5d), SPH_C32(0x507db82f), SPH_C32(0x0f51873c), + SPH_C32(0xe6cec260) }, + { SPH_C32(0x4c570000), SPH_C32(0xc99c0000), SPH_C32(0xc81d0548), + SPH_C32(0x08a30000), SPH_C32(0x86ac455f), SPH_C32(0x18898493), + SPH_C32(0xe90b2511), SPH_C32(0x68a9759a), SPH_C32(0x9e440000), + SPH_C32(0x8c370000), SPH_C32(0x30d807ce), SPH_C32(0xcbaf0000), + SPH_C32(0xd1e16d13), SPH_C32(0xc2b875d6), SPH_C32(0xa615c724), + SPH_C32(0x995994f1) }, + { SPH_C32(0x78230000), SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), + SPH_C32(0x90a50000), SPH_C32(0x713e2879), SPH_C32(0x7ee98924), + SPH_C32(0xf08ca062), SPH_C32(0x636f8bab), SPH_C32(0x02af0000), + SPH_C32(0xb7280000), SPH_C32(0xba1c0300), SPH_C32(0x56980000), + SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), SPH_C32(0xa95c149a), + SPH_C32(0xf4f6ea7b) }, + { SPH_C32(0x2a730000), SPH_C32(0x3ba80000), SPH_C32(0xc35b0bce), + SPH_C32(0x605a0000), SPH_C32(0xeb0f5695), SPH_C32(0x3bcac8ea), + SPH_C32(0x3fda2f87), SPH_C32(0x306c98a4), SPH_C32(0x51220000), + SPH_C32(0x1ed40000), SPH_C32(0x24eb0306), SPH_C32(0x00670000), + SPH_C32(0xb069459d), SPH_C32(0x128d0b9e), SPH_C32(0x00185482), + SPH_C32(0x8b61bcea) }, + { SPH_C32(0x2bae0000), SPH_C32(0xbb000000), SPH_C32(0x37cd0b86), + SPH_C32(0xc65a0000), SPH_C32(0x7bda2837), SPH_C32(0xec2c44dd), + SPH_C32(0x59c8e07a), SPH_C32(0x1cf8dd3a), SPH_C32(0x03720000), + SPH_C32(0x37800000), SPH_C32(0x4e8a0348), SPH_C32(0xf0980000), + SPH_C32(0x2a583b71), SPH_C32(0x57ae4a50), SPH_C32(0xcf4edb67), + SPH_C32(0xd862afe5) }, + { SPH_C32(0x79fe0000), SPH_C32(0x92540000), SPH_C32(0x5dac0bc8), + SPH_C32(0x36a50000), SPH_C32(0xe1eb56db), SPH_C32(0xa90f0513), + SPH_C32(0x969e6f9f), SPH_C32(0x4ffbce35), SPH_C32(0x50ff0000), + SPH_C32(0x9e7c0000), SPH_C32(0xd07d034e), SPH_C32(0xa6670000), + SPH_C32(0x20bc3b3f), SPH_C32(0xc56b87a9), SPH_C32(0x660a9b7f), + SPH_C32(0xa7f5f974) }, + { SPH_C32(0xb4370000), SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), + SPH_C32(0xabf50000), SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), + SPH_C32(0x99cfe8a3), SPH_C32(0xa9350c55), SPH_C32(0x83310000), + SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), SPH_C32(0xc36b0000), + SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), SPH_C32(0x4f06b6b7), + SPH_C32(0x7a915d81) }, + { SPH_C32(0xe6670000), SPH_C32(0x9ecb0000), SPH_C32(0x99e20c4e), + SPH_C32(0x5b0a0000), SPH_C32(0xa0df456a), SPH_C32(0xbc51fcf2), + SPH_C32(0x56996746), SPH_C32(0xfa361f5a), SPH_C32(0xd0bc0000), + SPH_C32(0xf2830000), SPH_C32(0x42d90186), SPH_C32(0x95940000), + SPH_C32(0xedc06d9f), SPH_C32(0x5a793722), SPH_C32(0xe642f6af), + SPH_C32(0x05060b10) }, + { SPH_C32(0xe7ba0000), SPH_C32(0x1e630000), SPH_C32(0x6d740c06), + SPH_C32(0xfd0a0000), SPH_C32(0x300a3bc8), SPH_C32(0x6bb770c5), + SPH_C32(0x308ba8bb), SPH_C32(0xd6a25ac4), SPH_C32(0x82ec0000), + SPH_C32(0xdbd70000), SPH_C32(0x28b801c8), SPH_C32(0x656b0000), + SPH_C32(0x77f11373), SPH_C32(0x1f5a76ec), SPH_C32(0x2914794a), + SPH_C32(0x5605181f) }, + { SPH_C32(0xb5ea0000), SPH_C32(0x37370000), SPH_C32(0x07150c48), + SPH_C32(0x0df50000), SPH_C32(0xaa3b4524), SPH_C32(0x2e94310b), + SPH_C32(0xffdd275e), SPH_C32(0x85a149cb), SPH_C32(0xd1610000), + SPH_C32(0x722b0000), SPH_C32(0xb64f01ce), SPH_C32(0x33940000), + SPH_C32(0x7d15133d), SPH_C32(0x8d9fbb15), SPH_C32(0x80503952), + SPH_C32(0x29924e8e) }, + { SPH_C32(0xf9bd0000), SPH_C32(0xfeab0000), SPH_C32(0xcf080900), + SPH_C32(0x05560000), SPH_C32(0x2c97007b), SPH_C32(0x361db598), + SPH_C32(0x16d6024f), SPH_C32(0xed083c51), SPH_C32(0x4f250000), + SPH_C32(0xfe1c0000), SPH_C32(0x86970600), SPH_C32(0xf83b0000), + SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), SPH_C32(0x2645fe76), + SPH_C32(0xb0cbda7f) }, + { SPH_C32(0xabed0000), SPH_C32(0xd7ff0000), SPH_C32(0xa569094e), + SPH_C32(0xf5a90000), SPH_C32(0xb6a67e97), SPH_C32(0x733ef456), + SPH_C32(0xd9808daa), SPH_C32(0xbe0b2f5e), SPH_C32(0x1ca80000), + SPH_C32(0x57e00000), SPH_C32(0x18600606), SPH_C32(0xaec40000), + SPH_C32(0xa6107e60), SPH_C32(0xdde2033a), SPH_C32(0x8f01be6e), + SPH_C32(0xcf5c8cee) }, + { SPH_C32(0xaa300000), SPH_C32(0x57570000), SPH_C32(0x51ff0906), + SPH_C32(0x53a90000), SPH_C32(0x26730035), SPH_C32(0xa4d87861), + SPH_C32(0xbf924257), SPH_C32(0x929f6ac0), SPH_C32(0x4ef80000), + SPH_C32(0x7eb40000), SPH_C32(0x72010648), SPH_C32(0x5e3b0000), + SPH_C32(0x3c21008c), SPH_C32(0x98c142f4), SPH_C32(0x4057318b), + SPH_C32(0x9c5f9fe1) }, + { SPH_C32(0xf8600000), SPH_C32(0x7e030000), SPH_C32(0x3b9e0948), + SPH_C32(0xa3560000), SPH_C32(0xbc427ed9), SPH_C32(0xe1fb39af), + SPH_C32(0x70c4cdb2), SPH_C32(0xc19c79cf), SPH_C32(0x1d750000), + SPH_C32(0xd7480000), SPH_C32(0xecf6064e), SPH_C32(0x08c40000), + SPH_C32(0x36c500c2), SPH_C32(0x0a048f0d), SPH_C32(0xe9137193), + SPH_C32(0xe3c8c970) }, + { SPH_C32(0x35a90000), SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), + SPH_C32(0x3e060000), SPH_C32(0x67471384), SPH_C32(0xb1868180), + SPH_C32(0x7f954a8e), SPH_C32(0x2752bbaf), SPH_C32(0xcebb0000), + SPH_C32(0x124b0000), SPH_C32(0xe0a50480), SPH_C32(0x6dc80000), + SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), SPH_C32(0xc01f5c5b), + SPH_C32(0x3eac6d85) }, + { SPH_C32(0x67f90000), SPH_C32(0x729c0000), SPH_C32(0xffd00ece), + SPH_C32(0xcef90000), SPH_C32(0xfd766d68), SPH_C32(0xf4a5c04e), + SPH_C32(0xb0c3c56b), SPH_C32(0x7451a8a0), SPH_C32(0x9d360000), + SPH_C32(0xbbb70000), SPH_C32(0x7e520486), SPH_C32(0x3b370000), + SPH_C32(0xfbb95662), SPH_C32(0x95163f86), SPH_C32(0x695b1c43), + SPH_C32(0x413b3b14) }, + { SPH_C32(0x66240000), SPH_C32(0xf2340000), SPH_C32(0x0b460e86), + SPH_C32(0x68f90000), SPH_C32(0x6da313ca), SPH_C32(0x23434c79), + SPH_C32(0xd6d10a96), SPH_C32(0x58c5ed3e), SPH_C32(0xcf660000), + SPH_C32(0x92e30000), SPH_C32(0x143304c8), SPH_C32(0xcbc80000), + SPH_C32(0x6188288e), SPH_C32(0xd0357e48), SPH_C32(0xa60d93a6), + SPH_C32(0x1238281b) }, + { SPH_C32(0x34740000), SPH_C32(0xdb600000), SPH_C32(0x61270ec8), + SPH_C32(0x98060000), SPH_C32(0xf7926d26), SPH_C32(0x66600db7), + SPH_C32(0x19878573), SPH_C32(0x0bc6fe31), SPH_C32(0x9ceb0000), + SPH_C32(0x3b1f0000), SPH_C32(0x8ac404ce), SPH_C32(0x9d370000), + SPH_C32(0x6b6c28c0), SPH_C32(0x42f0b3b1), SPH_C32(0x0f49d3be), + SPH_C32(0x6daf7e8a) }, + { SPH_C32(0x02af0000), SPH_C32(0xb7280000), SPH_C32(0xba1c0300), + SPH_C32(0x56980000), SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), + SPH_C32(0xa95c149a), SPH_C32(0xf4f6ea7b), SPH_C32(0x7a8c0000), + SPH_C32(0xa5d40000), SPH_C32(0x13260880), SPH_C32(0xc63d0000), + SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), SPH_C32(0x59d0b4f8), + SPH_C32(0x979961d0) }, + { SPH_C32(0x50ff0000), SPH_C32(0x9e7c0000), SPH_C32(0xd07d034e), + SPH_C32(0xa6670000), SPH_C32(0x20bc3b3f), SPH_C32(0xc56b87a9), + SPH_C32(0x660a9b7f), SPH_C32(0xa7f5f974), SPH_C32(0x29010000), + SPH_C32(0x0c280000), SPH_C32(0x8dd10886), SPH_C32(0x90c20000), + SPH_C32(0xc1576de4), SPH_C32(0x6c6482ba), SPH_C32(0xf094f4e0), + SPH_C32(0xe80e3741) }, + { SPH_C32(0x51220000), SPH_C32(0x1ed40000), SPH_C32(0x24eb0306), + SPH_C32(0x00670000), SPH_C32(0xb069459d), SPH_C32(0x128d0b9e), + SPH_C32(0x00185482), SPH_C32(0x8b61bcea), SPH_C32(0x7b510000), + SPH_C32(0x257c0000), SPH_C32(0xe7b008c8), SPH_C32(0x603d0000), + SPH_C32(0x5b661308), SPH_C32(0x2947c374), SPH_C32(0x3fc27b05), + SPH_C32(0xbb0d244e) }, + { SPH_C32(0x03720000), SPH_C32(0x37800000), SPH_C32(0x4e8a0348), + SPH_C32(0xf0980000), SPH_C32(0x2a583b71), SPH_C32(0x57ae4a50), + SPH_C32(0xcf4edb67), SPH_C32(0xd862afe5), SPH_C32(0x28dc0000), + SPH_C32(0x8c800000), SPH_C32(0x794708ce), SPH_C32(0x36c20000), + SPH_C32(0x51821346), SPH_C32(0xbb820e8d), SPH_C32(0x96863b1d), + SPH_C32(0xc49a72df) }, + { SPH_C32(0xcebb0000), SPH_C32(0x124b0000), SPH_C32(0xe0a50480), + SPH_C32(0x6dc80000), SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), + SPH_C32(0xc01f5c5b), SPH_C32(0x3eac6d85), SPH_C32(0xfb120000), + SPH_C32(0x49830000), SPH_C32(0x75140a00), SPH_C32(0x53ce0000), + SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), SPH_C32(0xbf8a16d5), + SPH_C32(0x19fed62a) }, + { SPH_C32(0x9ceb0000), SPH_C32(0x3b1f0000), SPH_C32(0x8ac404ce), + SPH_C32(0x9d370000), SPH_C32(0x6b6c28c0), SPH_C32(0x42f0b3b1), + SPH_C32(0x0f49d3be), SPH_C32(0x6daf7e8a), SPH_C32(0xa89f0000), + SPH_C32(0xe07f0000), SPH_C32(0xebe30a06), SPH_C32(0x05310000), + SPH_C32(0x9cfe45e6), SPH_C32(0x2490be06), SPH_C32(0x16ce56cd), + SPH_C32(0x666980bb) }, + { SPH_C32(0x9d360000), SPH_C32(0xbbb70000), SPH_C32(0x7e520486), + SPH_C32(0x3b370000), SPH_C32(0xfbb95662), SPH_C32(0x95163f86), + SPH_C32(0x695b1c43), SPH_C32(0x413b3b14), SPH_C32(0xfacf0000), + SPH_C32(0xc92b0000), SPH_C32(0x81820a48), SPH_C32(0xf5ce0000), + SPH_C32(0x06cf3b0a), SPH_C32(0x61b3ffc8), SPH_C32(0xd998d928), + SPH_C32(0x356a93b4) }, + { SPH_C32(0xcf660000), SPH_C32(0x92e30000), SPH_C32(0x143304c8), + SPH_C32(0xcbc80000), SPH_C32(0x6188288e), SPH_C32(0xd0357e48), + SPH_C32(0xa60d93a6), SPH_C32(0x1238281b), SPH_C32(0xa9420000), + SPH_C32(0x60d70000), SPH_C32(0x1f750a4e), SPH_C32(0xa3310000), + SPH_C32(0x0c2b3b44), SPH_C32(0xf3763231), SPH_C32(0x70dc9930), + SPH_C32(0x4afdc525) }, + { SPH_C32(0x83310000), SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), + SPH_C32(0xc36b0000), SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), + SPH_C32(0x4f06b6b7), SPH_C32(0x7a915d81), SPH_C32(0x37060000), + SPH_C32(0xece00000), SPH_C32(0x2fad0d80), SPH_C32(0x689e0000), + SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), SPH_C32(0xd6c95e14), + SPH_C32(0xd3a451d4) }, + { SPH_C32(0xd1610000), SPH_C32(0x722b0000), SPH_C32(0xb64f01ce), + SPH_C32(0x33940000), SPH_C32(0x7d15133d), SPH_C32(0x8d9fbb15), + SPH_C32(0x80503952), SPH_C32(0x29924e8e), SPH_C32(0x648b0000), + SPH_C32(0x451c0000), SPH_C32(0xb15a0d86), SPH_C32(0x3e610000), + SPH_C32(0xd72e5619), SPH_C32(0xa30b8a1e), SPH_C32(0x7f8d1e0c), + SPH_C32(0xac330745) }, + { SPH_C32(0xd0bc0000), SPH_C32(0xf2830000), SPH_C32(0x42d90186), + SPH_C32(0x95940000), SPH_C32(0xedc06d9f), SPH_C32(0x5a793722), + SPH_C32(0xe642f6af), SPH_C32(0x05060b10), SPH_C32(0x36db0000), + SPH_C32(0x6c480000), SPH_C32(0xdb3b0dc8), SPH_C32(0xce9e0000), + SPH_C32(0x4d1f28f5), SPH_C32(0xe628cbd0), SPH_C32(0xb0db91e9), + SPH_C32(0xff30144a) }, + { SPH_C32(0x82ec0000), SPH_C32(0xdbd70000), SPH_C32(0x28b801c8), + SPH_C32(0x656b0000), SPH_C32(0x77f11373), SPH_C32(0x1f5a76ec), + SPH_C32(0x2914794a), SPH_C32(0x5605181f), SPH_C32(0x65560000), + SPH_C32(0xc5b40000), SPH_C32(0x45cc0dce), SPH_C32(0x98610000), + SPH_C32(0x47fb28bb), SPH_C32(0x74ed0629), SPH_C32(0x199fd1f1), + SPH_C32(0x80a742db) }, + { SPH_C32(0x4f250000), SPH_C32(0xfe1c0000), SPH_C32(0x86970600), + SPH_C32(0xf83b0000), SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), + SPH_C32(0x2645fe76), SPH_C32(0xb0cbda7f), SPH_C32(0xb6980000), + SPH_C32(0x00b70000), SPH_C32(0x499f0f00), SPH_C32(0xfd6d0000), + SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), SPH_C32(0x3093fc39), + SPH_C32(0x5dc3e62e) }, + { SPH_C32(0x1d750000), SPH_C32(0xd7480000), SPH_C32(0xecf6064e), + SPH_C32(0x08c40000), SPH_C32(0x36c500c2), SPH_C32(0x0a048f0d), + SPH_C32(0xe9137193), SPH_C32(0xe3c8c970), SPH_C32(0xe5150000), + SPH_C32(0xa94b0000), SPH_C32(0xd7680f06), SPH_C32(0xab920000), + SPH_C32(0x8a877e1b), SPH_C32(0xebffb6a2), SPH_C32(0x99d7bc21), + SPH_C32(0x2254b0bf) }, + { SPH_C32(0x1ca80000), SPH_C32(0x57e00000), SPH_C32(0x18600606), + SPH_C32(0xaec40000), SPH_C32(0xa6107e60), SPH_C32(0xdde2033a), + SPH_C32(0x8f01be6e), SPH_C32(0xcf5c8cee), SPH_C32(0xb7450000), + SPH_C32(0x801f0000), SPH_C32(0xbd090f48), SPH_C32(0x5b6d0000), + SPH_C32(0x10b600f7), SPH_C32(0xaedcf76c), SPH_C32(0x568133c4), + SPH_C32(0x7157a3b0) }, + { SPH_C32(0x4ef80000), SPH_C32(0x7eb40000), SPH_C32(0x72010648), + SPH_C32(0x5e3b0000), SPH_C32(0x3c21008c), SPH_C32(0x98c142f4), + SPH_C32(0x4057318b), SPH_C32(0x9c5f9fe1), SPH_C32(0xe4c80000), + SPH_C32(0x29e30000), SPH_C32(0x23fe0f4e), SPH_C32(0x0d920000), + SPH_C32(0x1a5200b9), SPH_C32(0x3c193a95), SPH_C32(0xffc573dc), + SPH_C32(0x0ec0f521) }, + { SPH_C32(0x7a8c0000), SPH_C32(0xa5d40000), SPH_C32(0x13260880), + SPH_C32(0xc63d0000), SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), + SPH_C32(0x59d0b4f8), SPH_C32(0x979961d0), SPH_C32(0x78230000), + SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), SPH_C32(0x90a50000), + SPH_C32(0x713e2879), SPH_C32(0x7ee98924), SPH_C32(0xf08ca062), + SPH_C32(0x636f8bab) }, + { SPH_C32(0x28dc0000), SPH_C32(0x8c800000), SPH_C32(0x794708ce), + SPH_C32(0x36c20000), SPH_C32(0x51821346), SPH_C32(0xbb820e8d), + SPH_C32(0x96863b1d), SPH_C32(0xc49a72df), SPH_C32(0x2bae0000), + SPH_C32(0xbb000000), SPH_C32(0x37cd0b86), SPH_C32(0xc65a0000), + SPH_C32(0x7bda2837), SPH_C32(0xec2c44dd), SPH_C32(0x59c8e07a), + SPH_C32(0x1cf8dd3a) }, + { SPH_C32(0x29010000), SPH_C32(0x0c280000), SPH_C32(0x8dd10886), + SPH_C32(0x90c20000), SPH_C32(0xc1576de4), SPH_C32(0x6c6482ba), + SPH_C32(0xf094f4e0), SPH_C32(0xe80e3741), SPH_C32(0x79fe0000), + SPH_C32(0x92540000), SPH_C32(0x5dac0bc8), SPH_C32(0x36a50000), + SPH_C32(0xe1eb56db), SPH_C32(0xa90f0513), SPH_C32(0x969e6f9f), + SPH_C32(0x4ffbce35) }, + { SPH_C32(0x7b510000), SPH_C32(0x257c0000), SPH_C32(0xe7b008c8), + SPH_C32(0x603d0000), SPH_C32(0x5b661308), SPH_C32(0x2947c374), + SPH_C32(0x3fc27b05), SPH_C32(0xbb0d244e), SPH_C32(0x2a730000), + SPH_C32(0x3ba80000), SPH_C32(0xc35b0bce), SPH_C32(0x605a0000), + SPH_C32(0xeb0f5695), SPH_C32(0x3bcac8ea), SPH_C32(0x3fda2f87), + SPH_C32(0x306c98a4) }, + { SPH_C32(0xb6980000), SPH_C32(0x00b70000), SPH_C32(0x499f0f00), + SPH_C32(0xfd6d0000), SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), + SPH_C32(0x3093fc39), SPH_C32(0x5dc3e62e), SPH_C32(0xf9bd0000), + SPH_C32(0xfeab0000), SPH_C32(0xcf080900), SPH_C32(0x05560000), + SPH_C32(0x2c97007b), SPH_C32(0x361db598), SPH_C32(0x16d6024f), + SPH_C32(0xed083c51) }, + { SPH_C32(0xe4c80000), SPH_C32(0x29e30000), SPH_C32(0x23fe0f4e), + SPH_C32(0x0d920000), SPH_C32(0x1a5200b9), SPH_C32(0x3c193a95), + SPH_C32(0xffc573dc), SPH_C32(0x0ec0f521), SPH_C32(0xaa300000), + SPH_C32(0x57570000), SPH_C32(0x51ff0906), SPH_C32(0x53a90000), + SPH_C32(0x26730035), SPH_C32(0xa4d87861), SPH_C32(0xbf924257), + SPH_C32(0x929f6ac0) }, + { SPH_C32(0xe5150000), SPH_C32(0xa94b0000), SPH_C32(0xd7680f06), + SPH_C32(0xab920000), SPH_C32(0x8a877e1b), SPH_C32(0xebffb6a2), + SPH_C32(0x99d7bc21), SPH_C32(0x2254b0bf), SPH_C32(0xf8600000), + SPH_C32(0x7e030000), SPH_C32(0x3b9e0948), SPH_C32(0xa3560000), + SPH_C32(0xbc427ed9), SPH_C32(0xe1fb39af), SPH_C32(0x70c4cdb2), + SPH_C32(0xc19c79cf) }, + { SPH_C32(0xb7450000), SPH_C32(0x801f0000), SPH_C32(0xbd090f48), + SPH_C32(0x5b6d0000), SPH_C32(0x10b600f7), SPH_C32(0xaedcf76c), + SPH_C32(0x568133c4), SPH_C32(0x7157a3b0), SPH_C32(0xabed0000), + SPH_C32(0xd7ff0000), SPH_C32(0xa569094e), SPH_C32(0xf5a90000), + SPH_C32(0xb6a67e97), SPH_C32(0x733ef456), SPH_C32(0xd9808daa), + SPH_C32(0xbe0b2f5e) }, + { SPH_C32(0xfb120000), SPH_C32(0x49830000), SPH_C32(0x75140a00), + SPH_C32(0x53ce0000), SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), + SPH_C32(0xbf8a16d5), SPH_C32(0x19fed62a), SPH_C32(0x35a90000), + SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), SPH_C32(0x3e060000), + SPH_C32(0x67471384), SPH_C32(0xb1868180), SPH_C32(0x7f954a8e), + SPH_C32(0x2752bbaf) }, + { SPH_C32(0xa9420000), SPH_C32(0x60d70000), SPH_C32(0x1f750a4e), + SPH_C32(0xa3310000), SPH_C32(0x0c2b3b44), SPH_C32(0xf3763231), + SPH_C32(0x70dc9930), SPH_C32(0x4afdc525), SPH_C32(0x66240000), + SPH_C32(0xf2340000), SPH_C32(0x0b460e86), SPH_C32(0x68f90000), + SPH_C32(0x6da313ca), SPH_C32(0x23434c79), SPH_C32(0xd6d10a96), + SPH_C32(0x58c5ed3e) }, + { SPH_C32(0xa89f0000), SPH_C32(0xe07f0000), SPH_C32(0xebe30a06), + SPH_C32(0x05310000), SPH_C32(0x9cfe45e6), SPH_C32(0x2490be06), + SPH_C32(0x16ce56cd), SPH_C32(0x666980bb), SPH_C32(0x34740000), + SPH_C32(0xdb600000), SPH_C32(0x61270ec8), SPH_C32(0x98060000), + SPH_C32(0xf7926d26), SPH_C32(0x66600db7), SPH_C32(0x19878573), + SPH_C32(0x0bc6fe31) }, + { SPH_C32(0xfacf0000), SPH_C32(0xc92b0000), SPH_C32(0x81820a48), + SPH_C32(0xf5ce0000), SPH_C32(0x06cf3b0a), SPH_C32(0x61b3ffc8), + SPH_C32(0xd998d928), SPH_C32(0x356a93b4), SPH_C32(0x67f90000), + SPH_C32(0x729c0000), SPH_C32(0xffd00ece), SPH_C32(0xcef90000), + SPH_C32(0xfd766d68), SPH_C32(0xf4a5c04e), SPH_C32(0xb0c3c56b), + SPH_C32(0x7451a8a0) }, + { SPH_C32(0x37060000), SPH_C32(0xece00000), SPH_C32(0x2fad0d80), + SPH_C32(0x689e0000), SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), + SPH_C32(0xd6c95e14), SPH_C32(0xd3a451d4), SPH_C32(0xb4370000), + SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), SPH_C32(0xabf50000), + SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), SPH_C32(0x99cfe8a3), + SPH_C32(0xa9350c55) }, + { SPH_C32(0x65560000), SPH_C32(0xc5b40000), SPH_C32(0x45cc0dce), + SPH_C32(0x98610000), SPH_C32(0x47fb28bb), SPH_C32(0x74ed0629), + SPH_C32(0x199fd1f1), SPH_C32(0x80a742db), SPH_C32(0xe7ba0000), + SPH_C32(0x1e630000), SPH_C32(0x6d740c06), SPH_C32(0xfd0a0000), + SPH_C32(0x300a3bc8), SPH_C32(0x6bb770c5), SPH_C32(0x308ba8bb), + SPH_C32(0xd6a25ac4) }, + { SPH_C32(0x648b0000), SPH_C32(0x451c0000), SPH_C32(0xb15a0d86), + SPH_C32(0x3e610000), SPH_C32(0xd72e5619), SPH_C32(0xa30b8a1e), + SPH_C32(0x7f8d1e0c), SPH_C32(0xac330745), SPH_C32(0xb5ea0000), + SPH_C32(0x37370000), SPH_C32(0x07150c48), SPH_C32(0x0df50000), + SPH_C32(0xaa3b4524), SPH_C32(0x2e94310b), SPH_C32(0xffdd275e), + SPH_C32(0x85a149cb) }, + { SPH_C32(0x36db0000), SPH_C32(0x6c480000), SPH_C32(0xdb3b0dc8), + SPH_C32(0xce9e0000), SPH_C32(0x4d1f28f5), SPH_C32(0xe628cbd0), + SPH_C32(0xb0db91e9), SPH_C32(0xff30144a), SPH_C32(0xe6670000), + SPH_C32(0x9ecb0000), SPH_C32(0x99e20c4e), SPH_C32(0x5b0a0000), + SPH_C32(0xa0df456a), SPH_C32(0xbc51fcf2), SPH_C32(0x56996746), + SPH_C32(0xfa361f5a) }, + { SPH_C32(0xac480000), SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), + SPH_C32(0x03430000), SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), + SPH_C32(0xfe72c7fe), SPH_C32(0x91e478f6), SPH_C32(0x1e4e0000), + SPH_C32(0xdecf0000), SPH_C32(0x6df80180), SPH_C32(0x77240000), + SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), SPH_C32(0xcda31812), + SPH_C32(0x98aa496e) }, + { SPH_C32(0xfe180000), SPH_C32(0x32f20000), SPH_C32(0x2f9a13ce), + SPH_C32(0xf3bc0000), SPH_C32(0xc0b44f86), SPH_C32(0x5a911178), + SPH_C32(0x3124481b), SPH_C32(0xc2e76bf9), SPH_C32(0x4dc30000), + SPH_C32(0x77330000), SPH_C32(0xf30f0186), SPH_C32(0x21db0000), + SPH_C32(0xe6a307d0), SPH_C32(0x6665a4b7), SPH_C32(0x64e7580a), + SPH_C32(0xe73d1fff) }, + { SPH_C32(0xffc50000), SPH_C32(0xb25a0000), SPH_C32(0xdb0c1386), + SPH_C32(0x55bc0000), SPH_C32(0x50613124), SPH_C32(0x8d779d4f), + SPH_C32(0x573687e6), SPH_C32(0xee732e67), SPH_C32(0x1f930000), + SPH_C32(0x5e670000), SPH_C32(0x996e01c8), SPH_C32(0xd1240000), + SPH_C32(0x7c92793c), SPH_C32(0x2346e579), SPH_C32(0xabb1d7ef), + SPH_C32(0xb43e0cf0) }, + { SPH_C32(0xad950000), SPH_C32(0x9b0e0000), SPH_C32(0xb16d13c8), + SPH_C32(0xa5430000), SPH_C32(0xca504fc8), SPH_C32(0xc854dc81), + SPH_C32(0x98600803), SPH_C32(0xbd703d68), SPH_C32(0x4c1e0000), + SPH_C32(0xf79b0000), SPH_C32(0x079901ce), SPH_C32(0x87db0000), + SPH_C32(0x76767972), SPH_C32(0xb1832880), SPH_C32(0x02f597f7), + SPH_C32(0xcba95a61) }, + { SPH_C32(0x605c0000), SPH_C32(0xbec50000), SPH_C32(0x1f421400), + SPH_C32(0x38130000), SPH_C32(0x11552295), SPH_C32(0x982964ae), + SPH_C32(0x97318f3f), SPH_C32(0x5bbeff08), SPH_C32(0x9fd00000), + SPH_C32(0x32980000), SPH_C32(0x0bca0300), SPH_C32(0xe2d70000), + SPH_C32(0xb1ee2f9c), SPH_C32(0xbc5455f2), SPH_C32(0x2bf9ba3f), + SPH_C32(0x16cdfe94) }, + { SPH_C32(0x320c0000), SPH_C32(0x97910000), SPH_C32(0x7523144e), + SPH_C32(0xc8ec0000), SPH_C32(0x8b645c79), SPH_C32(0xdd0a2560), + SPH_C32(0x586700da), SPH_C32(0x08bdec07), SPH_C32(0xcc5d0000), + SPH_C32(0x9b640000), SPH_C32(0x953d0306), SPH_C32(0xb4280000), + SPH_C32(0xbb0a2fd2), SPH_C32(0x2e91980b), SPH_C32(0x82bdfa27), + SPH_C32(0x695aa805) }, + { SPH_C32(0x33d10000), SPH_C32(0x17390000), SPH_C32(0x81b51406), + SPH_C32(0x6eec0000), SPH_C32(0x1bb122db), SPH_C32(0x0aeca957), + SPH_C32(0x3e75cf27), SPH_C32(0x2429a999), SPH_C32(0x9e0d0000), + SPH_C32(0xb2300000), SPH_C32(0xff5c0348), SPH_C32(0x44d70000), + SPH_C32(0x213b513e), SPH_C32(0x6bb2d9c5), SPH_C32(0x4deb75c2), + SPH_C32(0x3a59bb0a) }, + { SPH_C32(0x61810000), SPH_C32(0x3e6d0000), SPH_C32(0xebd41448), + SPH_C32(0x9e130000), SPH_C32(0x81805c37), SPH_C32(0x4fcfe899), + SPH_C32(0xf12340c2), SPH_C32(0x772aba96), SPH_C32(0xcd800000), + SPH_C32(0x1bcc0000), SPH_C32(0x61ab034e), SPH_C32(0x12280000), + SPH_C32(0x2bdf5170), SPH_C32(0xf977143c), SPH_C32(0xe4af35da), + SPH_C32(0x45ceed9b) }, + { SPH_C32(0x2dd60000), SPH_C32(0xf7f10000), SPH_C32(0x23c91100), + SPH_C32(0x96b00000), SPH_C32(0x072c1968), SPH_C32(0x57466c0a), + SPH_C32(0x182865d3), SPH_C32(0x1f83cf0c), SPH_C32(0x53c40000), + SPH_C32(0x97fb0000), SPH_C32(0x51730480), SPH_C32(0xd9870000), + SPH_C32(0xfa3e3c63), SPH_C32(0x3bcf61ea), SPH_C32(0x42baf2fe), + SPH_C32(0xdc97796a) }, + { SPH_C32(0x7f860000), SPH_C32(0xdea50000), SPH_C32(0x49a8114e), + SPH_C32(0x664f0000), SPH_C32(0x9d1d6784), SPH_C32(0x12652dc4), + SPH_C32(0xd77eea36), SPH_C32(0x4c80dc03), SPH_C32(0x00490000), + SPH_C32(0x3e070000), SPH_C32(0xcf840486), SPH_C32(0x8f780000), + SPH_C32(0xf0da3c2d), SPH_C32(0xa90aac13), SPH_C32(0xebfeb2e6), + SPH_C32(0xa3002ffb) }, + { SPH_C32(0x7e5b0000), SPH_C32(0x5e0d0000), SPH_C32(0xbd3e1106), + SPH_C32(0xc04f0000), SPH_C32(0x0dc81926), SPH_C32(0xc583a1f3), + SPH_C32(0xb16c25cb), SPH_C32(0x6014999d), SPH_C32(0x52190000), + SPH_C32(0x17530000), SPH_C32(0xa5e504c8), SPH_C32(0x7f870000), + SPH_C32(0x6aeb42c1), SPH_C32(0xec29eddd), SPH_C32(0x24a83d03), + SPH_C32(0xf0033cf4) }, + { SPH_C32(0x2c0b0000), SPH_C32(0x77590000), SPH_C32(0xd75f1148), + SPH_C32(0x30b00000), SPH_C32(0x97f967ca), SPH_C32(0x80a0e03d), + SPH_C32(0x7e3aaa2e), SPH_C32(0x33178a92), SPH_C32(0x01940000), + SPH_C32(0xbeaf0000), SPH_C32(0x3b1204ce), SPH_C32(0x29780000), + SPH_C32(0x600f428f), SPH_C32(0x7eec2024), SPH_C32(0x8dec7d1b), + SPH_C32(0x8f946a65) }, + { SPH_C32(0xe1c20000), SPH_C32(0x52920000), SPH_C32(0x79701680), + SPH_C32(0xade00000), SPH_C32(0x4cfc0a97), SPH_C32(0xd0dd5812), + SPH_C32(0x716b2d12), SPH_C32(0xd5d948f2), SPH_C32(0xd25a0000), + SPH_C32(0x7bac0000), SPH_C32(0x37410600), SPH_C32(0x4c740000), + SPH_C32(0xa7971461), SPH_C32(0x733b5d56), SPH_C32(0xa4e050d3), + SPH_C32(0x52f0ce90) }, + { SPH_C32(0xb3920000), SPH_C32(0x7bc60000), SPH_C32(0x131116ce), + SPH_C32(0x5d1f0000), SPH_C32(0xd6cd747b), SPH_C32(0x95fe19dc), + SPH_C32(0xbe3da2f7), SPH_C32(0x86da5bfd), SPH_C32(0x81d70000), + SPH_C32(0xd2500000), SPH_C32(0xa9b60606), SPH_C32(0x1a8b0000), + SPH_C32(0xad73142f), SPH_C32(0xe1fe90af), SPH_C32(0x0da410cb), + SPH_C32(0x2d679801) }, + { SPH_C32(0xb24f0000), SPH_C32(0xfb6e0000), SPH_C32(0xe7871686), + SPH_C32(0xfb1f0000), SPH_C32(0x46180ad9), SPH_C32(0x421895eb), + SPH_C32(0xd82f6d0a), SPH_C32(0xaa4e1e63), SPH_C32(0xd3870000), + SPH_C32(0xfb040000), SPH_C32(0xc3d70648), SPH_C32(0xea740000), + SPH_C32(0x37426ac3), SPH_C32(0xa4ddd161), SPH_C32(0xc2f29f2e), + SPH_C32(0x7e648b0e) }, + { SPH_C32(0xe01f0000), SPH_C32(0xd23a0000), SPH_C32(0x8de616c8), + SPH_C32(0x0be00000), SPH_C32(0xdc297435), SPH_C32(0x073bd425), + SPH_C32(0x1779e2ef), SPH_C32(0xf94d0d6c), SPH_C32(0x800a0000), + SPH_C32(0x52f80000), SPH_C32(0x5d20064e), SPH_C32(0xbc8b0000), + SPH_C32(0x3da66a8d), SPH_C32(0x36181c98), SPH_C32(0x6bb6df36), + SPH_C32(0x01f3dd9f) }, + { SPH_C32(0xd46b0000), SPH_C32(0x095a0000), SPH_C32(0xecc11800), + SPH_C32(0x93e60000), SPH_C32(0x2bbb1913), SPH_C32(0x615bd992), + SPH_C32(0x0efe679c), SPH_C32(0xf28bf35d), SPH_C32(0x1ce10000), + SPH_C32(0x69e70000), SPH_C32(0xd7e40280), SPH_C32(0x21bc0000), + SPH_C32(0x56ca424d), SPH_C32(0x74e8af29), SPH_C32(0x64ff0c88), + SPH_C32(0x6c5ca315) }, + { SPH_C32(0x863b0000), SPH_C32(0x200e0000), SPH_C32(0x86a0184e), + SPH_C32(0x63190000), SPH_C32(0xb18a67ff), SPH_C32(0x2478985c), + SPH_C32(0xc1a8e879), SPH_C32(0xa188e052), SPH_C32(0x4f6c0000), + SPH_C32(0xc01b0000), SPH_C32(0x49130286), SPH_C32(0x77430000), + SPH_C32(0x5c2e4203), SPH_C32(0xe62d62d0), SPH_C32(0xcdbb4c90), + SPH_C32(0x13cbf584) }, + { SPH_C32(0x87e60000), SPH_C32(0xa0a60000), SPH_C32(0x72361806), + SPH_C32(0xc5190000), SPH_C32(0x215f195d), SPH_C32(0xf39e146b), + SPH_C32(0xa7ba2784), SPH_C32(0x8d1ca5cc), SPH_C32(0x1d3c0000), + SPH_C32(0xe94f0000), SPH_C32(0x237202c8), SPH_C32(0x87bc0000), + SPH_C32(0xc61f3cef), SPH_C32(0xa30e231e), SPH_C32(0x02edc375), + SPH_C32(0x40c8e68b) }, + { SPH_C32(0xd5b60000), SPH_C32(0x89f20000), SPH_C32(0x18571848), + SPH_C32(0x35e60000), SPH_C32(0xbb6e67b1), SPH_C32(0xb6bd55a5), + SPH_C32(0x68eca861), SPH_C32(0xde1fb6c3), SPH_C32(0x4eb10000), + SPH_C32(0x40b30000), SPH_C32(0xbd8502ce), SPH_C32(0xd1430000), + SPH_C32(0xccfb3ca1), SPH_C32(0x31cbeee7), SPH_C32(0xaba9836d), + SPH_C32(0x3f5fb01a) }, + { SPH_C32(0x187f0000), SPH_C32(0xac390000), SPH_C32(0xb6781f80), + SPH_C32(0xa8b60000), SPH_C32(0x606b0aec), SPH_C32(0xe6c0ed8a), + SPH_C32(0x67bd2f5d), SPH_C32(0x38d174a3), SPH_C32(0x9d7f0000), + SPH_C32(0x85b00000), SPH_C32(0xb1d60000), SPH_C32(0xb44f0000), + SPH_C32(0x0b636a4f), SPH_C32(0x3c1c9395), SPH_C32(0x82a5aea5), + SPH_C32(0xe23b14ef) }, + { SPH_C32(0x4a2f0000), SPH_C32(0x856d0000), SPH_C32(0xdc191fce), + SPH_C32(0x58490000), SPH_C32(0xfa5a7400), SPH_C32(0xa3e3ac44), + SPH_C32(0xa8eba0b8), SPH_C32(0x6bd267ac), SPH_C32(0xcef20000), + SPH_C32(0x2c4c0000), SPH_C32(0x2f210006), SPH_C32(0xe2b00000), + SPH_C32(0x01876a01), SPH_C32(0xaed95e6c), SPH_C32(0x2be1eebd), + SPH_C32(0x9dac427e) }, + { SPH_C32(0x4bf20000), SPH_C32(0x05c50000), SPH_C32(0x288f1f86), + SPH_C32(0xfe490000), SPH_C32(0x6a8f0aa2), SPH_C32(0x74052073), + SPH_C32(0xcef96f45), SPH_C32(0x47462232), SPH_C32(0x9ca20000), + SPH_C32(0x05180000), SPH_C32(0x45400048), SPH_C32(0x124f0000), + SPH_C32(0x9bb614ed), SPH_C32(0xebfa1fa2), SPH_C32(0xe4b76158), + SPH_C32(0xceaf5171) }, + { SPH_C32(0x19a20000), SPH_C32(0x2c910000), SPH_C32(0x42ee1fc8), + SPH_C32(0x0eb60000), SPH_C32(0xf0be744e), SPH_C32(0x312661bd), + SPH_C32(0x01afe0a0), SPH_C32(0x1445313d), SPH_C32(0xcf2f0000), + SPH_C32(0xace40000), SPH_C32(0xdbb7004e), SPH_C32(0x44b00000), + SPH_C32(0x915214a3), SPH_C32(0x793fd25b), SPH_C32(0x4df32140), + SPH_C32(0xb13807e0) }, + { SPH_C32(0x55f50000), SPH_C32(0xe50d0000), SPH_C32(0x8af31a80), + SPH_C32(0x06150000), SPH_C32(0x76123111), SPH_C32(0x29afe52e), + SPH_C32(0xe8a4c5b1), SPH_C32(0x7cec44a7), SPH_C32(0x516b0000), + SPH_C32(0x20d30000), SPH_C32(0xeb6f0780), SPH_C32(0x8f1f0000), + SPH_C32(0x40b379b0), SPH_C32(0xbb87a78d), SPH_C32(0xebe6e664), + SPH_C32(0x28619311) }, + { SPH_C32(0x07a50000), SPH_C32(0xcc590000), SPH_C32(0xe0921ace), + SPH_C32(0xf6ea0000), SPH_C32(0xec234ffd), SPH_C32(0x6c8ca4e0), + SPH_C32(0x27f24a54), SPH_C32(0x2fef57a8), SPH_C32(0x02e60000), + SPH_C32(0x892f0000), SPH_C32(0x75980786), SPH_C32(0xd9e00000), + SPH_C32(0x4a5779fe), SPH_C32(0x29426a74), SPH_C32(0x42a2a67c), + SPH_C32(0x57f6c580) }, + { SPH_C32(0x06780000), SPH_C32(0x4cf10000), SPH_C32(0x14041a86), + SPH_C32(0x50ea0000), SPH_C32(0x7cf6315f), SPH_C32(0xbb6a28d7), + SPH_C32(0x41e085a9), SPH_C32(0x037b1236), SPH_C32(0x50b60000), + SPH_C32(0xa07b0000), SPH_C32(0x1ff907c8), SPH_C32(0x291f0000), + SPH_C32(0xd0660712), SPH_C32(0x6c612bba), SPH_C32(0x8df42999), + SPH_C32(0x04f5d68f) }, + { SPH_C32(0x54280000), SPH_C32(0x65a50000), SPH_C32(0x7e651ac8), + SPH_C32(0xa0150000), SPH_C32(0xe6c74fb3), SPH_C32(0xfe496919), + SPH_C32(0x8eb60a4c), SPH_C32(0x50780139), SPH_C32(0x033b0000), + SPH_C32(0x09870000), SPH_C32(0x810e07ce), SPH_C32(0x7fe00000), + SPH_C32(0xda82075c), SPH_C32(0xfea4e643), SPH_C32(0x24b06981), + SPH_C32(0x7b62801e) }, + { SPH_C32(0x99e10000), SPH_C32(0x406e0000), SPH_C32(0xd04a1d00), + SPH_C32(0x3d450000), SPH_C32(0x3dc222ee), SPH_C32(0xae34d136), + SPH_C32(0x81e78d70), SPH_C32(0xb6b6c359), SPH_C32(0xd0f50000), + SPH_C32(0xcc840000), SPH_C32(0x8d5d0500), SPH_C32(0x1aec0000), + SPH_C32(0x1d1a51b2), SPH_C32(0xf3739b31), SPH_C32(0x0dbc4449), + SPH_C32(0xa60624eb) }, + { SPH_C32(0xcbb10000), SPH_C32(0x693a0000), SPH_C32(0xba2b1d4e), + SPH_C32(0xcdba0000), SPH_C32(0xa7f35c02), SPH_C32(0xeb1790f8), + SPH_C32(0x4eb10295), SPH_C32(0xe5b5d056), SPH_C32(0x83780000), + SPH_C32(0x65780000), SPH_C32(0x13aa0506), SPH_C32(0x4c130000), + SPH_C32(0x17fe51fc), SPH_C32(0x61b656c8), SPH_C32(0xa4f80451), + SPH_C32(0xd991727a) }, + { SPH_C32(0xca6c0000), SPH_C32(0xe9920000), SPH_C32(0x4ebd1d06), + SPH_C32(0x6bba0000), SPH_C32(0x372622a0), SPH_C32(0x3cf11ccf), + SPH_C32(0x28a3cd68), SPH_C32(0xc92195c8), SPH_C32(0xd1280000), + SPH_C32(0x4c2c0000), SPH_C32(0x79cb0548), SPH_C32(0xbcec0000), + SPH_C32(0x8dcf2f10), SPH_C32(0x24951706), SPH_C32(0x6bae8bb4), + SPH_C32(0x8a926175) }, + { SPH_C32(0x983c0000), SPH_C32(0xc0c60000), SPH_C32(0x24dc1d48), + SPH_C32(0x9b450000), SPH_C32(0xad175c4c), SPH_C32(0x79d25d01), + SPH_C32(0xe7f5428d), SPH_C32(0x9a2286c7), SPH_C32(0x82a50000), + SPH_C32(0xe5d00000), SPH_C32(0xe73c054e), SPH_C32(0xea130000), + SPH_C32(0x872b2f5e), SPH_C32(0xb650daff), SPH_C32(0xc2eacbac), + SPH_C32(0xf50537e4) }, + { SPH_C32(0xaee70000), SPH_C32(0xac8e0000), SPH_C32(0xffe71080), + SPH_C32(0x55db0000), SPH_C32(0xe00874b9), SPH_C32(0x9ffa96d1), + SPH_C32(0x572ed364), SPH_C32(0x6512928d), SPH_C32(0x64c20000), + SPH_C32(0x7b1b0000), SPH_C32(0x7ede0900), SPH_C32(0xb1190000), + SPH_C32(0x27f46a34), SPH_C32(0x0a01260d), SPH_C32(0x9473acea), + SPH_C32(0x0f3328be) }, + { SPH_C32(0xfcb70000), SPH_C32(0x85da0000), SPH_C32(0x958610ce), + SPH_C32(0xa5240000), SPH_C32(0x7a390a55), SPH_C32(0xdad9d71f), + SPH_C32(0x98785c81), SPH_C32(0x36118182), SPH_C32(0x374f0000), + SPH_C32(0xd2e70000), SPH_C32(0xe0290906), SPH_C32(0xe7e60000), + SPH_C32(0x2d106a7a), SPH_C32(0x98c4ebf4), SPH_C32(0x3d37ecf2), + SPH_C32(0x70a47e2f) }, + { SPH_C32(0xfd6a0000), SPH_C32(0x05720000), SPH_C32(0x61101086), + SPH_C32(0x03240000), SPH_C32(0xeaec74f7), SPH_C32(0x0d3f5b28), + SPH_C32(0xfe6a937c), SPH_C32(0x1a85c41c), SPH_C32(0x651f0000), + SPH_C32(0xfbb30000), SPH_C32(0x8a480948), SPH_C32(0x17190000), + SPH_C32(0xb7211496), SPH_C32(0xdde7aa3a), SPH_C32(0xf2616317), + SPH_C32(0x23a76d20) }, + { SPH_C32(0xaf3a0000), SPH_C32(0x2c260000), SPH_C32(0x0b7110c8), + SPH_C32(0xf3db0000), SPH_C32(0x70dd0a1b), SPH_C32(0x481c1ae6), + SPH_C32(0x313c1c99), SPH_C32(0x4986d713), SPH_C32(0x36920000), + SPH_C32(0x524f0000), SPH_C32(0x14bf094e), SPH_C32(0x41e60000), + SPH_C32(0xbdc514d8), SPH_C32(0x4f2267c3), SPH_C32(0x5b25230f), + SPH_C32(0x5c303bb1) }, + { SPH_C32(0x62f30000), SPH_C32(0x09ed0000), SPH_C32(0xa55e1700), + SPH_C32(0x6e8b0000), SPH_C32(0xabd86746), SPH_C32(0x1861a2c9), + SPH_C32(0x3e6d9ba5), SPH_C32(0xaf481573), SPH_C32(0xe55c0000), + SPH_C32(0x974c0000), SPH_C32(0x18ec0b80), SPH_C32(0x24ea0000), + SPH_C32(0x7a5d4236), SPH_C32(0x42f51ab1), SPH_C32(0x72290ec7), + SPH_C32(0x81549f44) }, + { SPH_C32(0x30a30000), SPH_C32(0x20b90000), SPH_C32(0xcf3f174e), + SPH_C32(0x9e740000), SPH_C32(0x31e919aa), SPH_C32(0x5d42e307), + SPH_C32(0xf13b1440), SPH_C32(0xfc4b067c), SPH_C32(0xb6d10000), + SPH_C32(0x3eb00000), SPH_C32(0x861b0b86), SPH_C32(0x72150000), + SPH_C32(0x70b94278), SPH_C32(0xd030d748), SPH_C32(0xdb6d4edf), + SPH_C32(0xfec3c9d5) }, + { SPH_C32(0x317e0000), SPH_C32(0xa0110000), SPH_C32(0x3ba91706), + SPH_C32(0x38740000), SPH_C32(0xa13c6708), SPH_C32(0x8aa46f30), + SPH_C32(0x9729dbbd), SPH_C32(0xd0df43e2), SPH_C32(0xe4810000), + SPH_C32(0x17e40000), SPH_C32(0xec7a0bc8), SPH_C32(0x82ea0000), + SPH_C32(0xea883c94), SPH_C32(0x95139686), SPH_C32(0x143bc13a), + SPH_C32(0xadc0dada) }, + { SPH_C32(0x632e0000), SPH_C32(0x89450000), SPH_C32(0x51c81748), + SPH_C32(0xc88b0000), SPH_C32(0x3b0d19e4), SPH_C32(0xcf872efe), + SPH_C32(0x587f5458), SPH_C32(0x83dc50ed), SPH_C32(0xb70c0000), + SPH_C32(0xbe180000), SPH_C32(0x728d0bce), SPH_C32(0xd4150000), + SPH_C32(0xe06c3cda), SPH_C32(0x07d65b7f), SPH_C32(0xbd7f8122), + SPH_C32(0xd2578c4b) }, + { SPH_C32(0x2f790000), SPH_C32(0x40d90000), SPH_C32(0x99d51200), + SPH_C32(0xc0280000), SPH_C32(0xbda15cbb), SPH_C32(0xd70eaa6d), + SPH_C32(0xb1747149), SPH_C32(0xeb752577), SPH_C32(0x29480000), + SPH_C32(0x322f0000), SPH_C32(0x42550c00), SPH_C32(0x1fba0000), + SPH_C32(0x318d51c9), SPH_C32(0xc56e2ea9), SPH_C32(0x1b6a4606), + SPH_C32(0x4b0e18ba) }, + { SPH_C32(0x7d290000), SPH_C32(0x698d0000), SPH_C32(0xf3b4124e), + SPH_C32(0x30d70000), SPH_C32(0x27902257), SPH_C32(0x922deba3), + SPH_C32(0x7e22feac), SPH_C32(0xb8763678), SPH_C32(0x7ac50000), + SPH_C32(0x9bd30000), SPH_C32(0xdca20c06), SPH_C32(0x49450000), + SPH_C32(0x3b695187), SPH_C32(0x57abe350), SPH_C32(0xb22e061e), + SPH_C32(0x34994e2b) }, + { SPH_C32(0x7cf40000), SPH_C32(0xe9250000), SPH_C32(0x07221206), + SPH_C32(0x96d70000), SPH_C32(0xb7455cf5), SPH_C32(0x45cb6794), + SPH_C32(0x18303151), SPH_C32(0x94e273e6), SPH_C32(0x28950000), + SPH_C32(0xb2870000), SPH_C32(0xb6c30c48), SPH_C32(0xb9ba0000), + SPH_C32(0xa1582f6b), SPH_C32(0x1288a29e), SPH_C32(0x7d7889fb), + SPH_C32(0x679a5d24) }, + { SPH_C32(0x2ea40000), SPH_C32(0xc0710000), SPH_C32(0x6d431248), + SPH_C32(0x66280000), SPH_C32(0x2d742219), SPH_C32(0x00e8265a), + SPH_C32(0xd766beb4), SPH_C32(0xc7e160e9), SPH_C32(0x7b180000), + SPH_C32(0x1b7b0000), SPH_C32(0x28340c4e), SPH_C32(0xef450000), + SPH_C32(0xabbc2f25), SPH_C32(0x804d6f67), SPH_C32(0xd43cc9e3), + SPH_C32(0x180d0bb5) }, + { SPH_C32(0xe36d0000), SPH_C32(0xe5ba0000), SPH_C32(0xc36c1580), + SPH_C32(0xfb780000), SPH_C32(0xf6714f44), SPH_C32(0x50959e75), + SPH_C32(0xd8373988), SPH_C32(0x212fa289), SPH_C32(0xa8d60000), + SPH_C32(0xde780000), SPH_C32(0x24670e80), SPH_C32(0x8a490000), + SPH_C32(0x6c2479cb), SPH_C32(0x8d9a1215), SPH_C32(0xfd30e42b), + SPH_C32(0xc569af40) }, + { SPH_C32(0xb13d0000), SPH_C32(0xccee0000), SPH_C32(0xa90d15ce), + SPH_C32(0x0b870000), SPH_C32(0x6c4031a8), SPH_C32(0x15b6dfbb), + SPH_C32(0x1761b66d), SPH_C32(0x722cb186), SPH_C32(0xfb5b0000), + SPH_C32(0x77840000), SPH_C32(0xba900e86), SPH_C32(0xdcb60000), + SPH_C32(0x66c07985), SPH_C32(0x1f5fdfec), SPH_C32(0x5474a433), + SPH_C32(0xbafef9d1) }, + { SPH_C32(0xb0e00000), SPH_C32(0x4c460000), SPH_C32(0x5d9b1586), + SPH_C32(0xad870000), SPH_C32(0xfc954f0a), SPH_C32(0xc250538c), + SPH_C32(0x71737990), SPH_C32(0x5eb8f418), SPH_C32(0xa90b0000), + SPH_C32(0x5ed00000), SPH_C32(0xd0f10ec8), SPH_C32(0x2c490000), + SPH_C32(0xfcf10769), SPH_C32(0x5a7c9e22), SPH_C32(0x9b222bd6), + SPH_C32(0xe9fdeade) }, + { SPH_C32(0xe2b00000), SPH_C32(0x65120000), SPH_C32(0x37fa15c8), + SPH_C32(0x5d780000), SPH_C32(0x66a431e6), SPH_C32(0x87731242), + SPH_C32(0xbe25f675), SPH_C32(0x0dbbe717), SPH_C32(0xfa860000), + SPH_C32(0xf72c0000), SPH_C32(0x4e060ece), SPH_C32(0x7ab60000), + SPH_C32(0xf6150727), SPH_C32(0xc8b953db), SPH_C32(0x32666bce), + SPH_C32(0x966abc4f) }, + { SPH_C32(0xd6c40000), SPH_C32(0xbe720000), SPH_C32(0x56dd1b00), + SPH_C32(0xc57e0000), SPH_C32(0x91365cc0), SPH_C32(0xe1131ff5), + SPH_C32(0xa7a27306), SPH_C32(0x067d1926), SPH_C32(0x666d0000), + SPH_C32(0xcc330000), SPH_C32(0xc4c20a00), SPH_C32(0xe7810000), + SPH_C32(0x9d792fe7), SPH_C32(0x8a49e06a), SPH_C32(0x3d2fb870), + SPH_C32(0xfbc5c2c5) }, + { SPH_C32(0x84940000), SPH_C32(0x97260000), SPH_C32(0x3cbc1b4e), + SPH_C32(0x35810000), SPH_C32(0x0b07222c), SPH_C32(0xa4305e3b), + SPH_C32(0x68f4fce3), SPH_C32(0x557e0a29), SPH_C32(0x35e00000), + SPH_C32(0x65cf0000), SPH_C32(0x5a350a06), SPH_C32(0xb17e0000), + SPH_C32(0x979d2fa9), SPH_C32(0x188c2d93), SPH_C32(0x946bf868), + SPH_C32(0x84529454) }, + { SPH_C32(0x85490000), SPH_C32(0x178e0000), SPH_C32(0xc82a1b06), + SPH_C32(0x93810000), SPH_C32(0x9bd25c8e), SPH_C32(0x73d6d20c), + SPH_C32(0x0ee6331e), SPH_C32(0x79ea4fb7), SPH_C32(0x67b00000), + SPH_C32(0x4c9b0000), SPH_C32(0x30540a48), SPH_C32(0x41810000), + SPH_C32(0x0dac5145), SPH_C32(0x5daf6c5d), SPH_C32(0x5b3d778d), + SPH_C32(0xd751875b) }, + { SPH_C32(0xd7190000), SPH_C32(0x3eda0000), SPH_C32(0xa24b1b48), + SPH_C32(0x637e0000), SPH_C32(0x01e32262), SPH_C32(0x36f593c2), + SPH_C32(0xc1b0bcfb), SPH_C32(0x2ae95cb8), SPH_C32(0x343d0000), + SPH_C32(0xe5670000), SPH_C32(0xaea30a4e), SPH_C32(0x177e0000), + SPH_C32(0x0748510b), SPH_C32(0xcf6aa1a4), SPH_C32(0xf2793795), + SPH_C32(0xa8c6d1ca) }, + { SPH_C32(0x1ad00000), SPH_C32(0x1b110000), SPH_C32(0x0c641c80), + SPH_C32(0xfe2e0000), SPH_C32(0xdae64f3f), SPH_C32(0x66882bed), + SPH_C32(0xcee13bc7), SPH_C32(0xcc279ed8), SPH_C32(0xe7f30000), + SPH_C32(0x20640000), SPH_C32(0xa2f00880), SPH_C32(0x72720000), + SPH_C32(0xc0d007e5), SPH_C32(0xc2bddcd6), SPH_C32(0xdb751a5d), + SPH_C32(0x75a2753f) }, + { SPH_C32(0x48800000), SPH_C32(0x32450000), SPH_C32(0x66051cce), + SPH_C32(0x0ed10000), SPH_C32(0x40d731d3), SPH_C32(0x23ab6a23), + SPH_C32(0x01b7b422), SPH_C32(0x9f248dd7), SPH_C32(0xb47e0000), + SPH_C32(0x89980000), SPH_C32(0x3c070886), SPH_C32(0x248d0000), + SPH_C32(0xca3407ab), SPH_C32(0x5078112f), SPH_C32(0x72315a45), + SPH_C32(0x0a3523ae) }, + { SPH_C32(0x495d0000), SPH_C32(0xb2ed0000), SPH_C32(0x92931c86), + SPH_C32(0xa8d10000), SPH_C32(0xd0024f71), SPH_C32(0xf44de614), + SPH_C32(0x67a57bdf), SPH_C32(0xb3b0c849), SPH_C32(0xe62e0000), + SPH_C32(0xa0cc0000), SPH_C32(0x566608c8), SPH_C32(0xd4720000), + SPH_C32(0x50057947), SPH_C32(0x155b50e1), SPH_C32(0xbd67d5a0), + SPH_C32(0x593630a1) }, + { SPH_C32(0x1b0d0000), SPH_C32(0x9bb90000), SPH_C32(0xf8f21cc8), + SPH_C32(0x582e0000), SPH_C32(0x4a33319d), SPH_C32(0xb16ea7da), + SPH_C32(0xa8f3f43a), SPH_C32(0xe0b3db46), SPH_C32(0xb5a30000), + SPH_C32(0x09300000), SPH_C32(0xc89108ce), SPH_C32(0x828d0000), + SPH_C32(0x5ae17909), SPH_C32(0x879e9d18), SPH_C32(0x142395b8), + SPH_C32(0x26a16630) }, + { SPH_C32(0x575a0000), SPH_C32(0x52250000), SPH_C32(0x30ef1980), + SPH_C32(0x508d0000), SPH_C32(0xcc9f74c2), SPH_C32(0xa9e72349), + SPH_C32(0x41f8d12b), SPH_C32(0x881aaedc), SPH_C32(0x2be70000), + SPH_C32(0x85070000), SPH_C32(0xf8490f00), SPH_C32(0x49220000), + SPH_C32(0x8b00141a), SPH_C32(0x4526e8ce), SPH_C32(0xb236529c), + SPH_C32(0xbff8f2c1) }, + { SPH_C32(0x050a0000), SPH_C32(0x7b710000), SPH_C32(0x5a8e19ce), + SPH_C32(0xa0720000), SPH_C32(0x56ae0a2e), SPH_C32(0xecc46287), + SPH_C32(0x8eae5ece), SPH_C32(0xdb19bdd3), SPH_C32(0x786a0000), + SPH_C32(0x2cfb0000), SPH_C32(0x66be0f06), SPH_C32(0x1fdd0000), + SPH_C32(0x81e41454), SPH_C32(0xd7e32537), SPH_C32(0x1b721284), + SPH_C32(0xc06fa450) }, + { SPH_C32(0x04d70000), SPH_C32(0xfbd90000), SPH_C32(0xae181986), + SPH_C32(0x06720000), SPH_C32(0xc67b748c), SPH_C32(0x3b22eeb0), + SPH_C32(0xe8bc9133), SPH_C32(0xf78df84d), SPH_C32(0x2a3a0000), + SPH_C32(0x05af0000), SPH_C32(0x0cdf0f48), SPH_C32(0xef220000), + SPH_C32(0x1bd56ab8), SPH_C32(0x92c064f9), SPH_C32(0xd4249d61), + SPH_C32(0x936cb75f) }, + { SPH_C32(0x56870000), SPH_C32(0xd28d0000), SPH_C32(0xc47919c8), + SPH_C32(0xf68d0000), SPH_C32(0x5c4a0a60), SPH_C32(0x7e01af7e), + SPH_C32(0x27ea1ed6), SPH_C32(0xa48eeb42), SPH_C32(0x79b70000), + SPH_C32(0xac530000), SPH_C32(0x92280f4e), SPH_C32(0xb9dd0000), + SPH_C32(0x11316af6), SPH_C32(0x0005a900), SPH_C32(0x7d60dd79), + SPH_C32(0xecfbe1ce) }, + { SPH_C32(0x9b4e0000), SPH_C32(0xf7460000), SPH_C32(0x6a561e00), + SPH_C32(0x6bdd0000), SPH_C32(0x874f673d), SPH_C32(0x2e7c1751), + SPH_C32(0x28bb99ea), SPH_C32(0x42402922), SPH_C32(0xaa790000), + SPH_C32(0x69500000), SPH_C32(0x9e7b0d80), SPH_C32(0xdcd10000), + SPH_C32(0xd6a93c18), SPH_C32(0x0dd2d472), SPH_C32(0x546cf0b1), + SPH_C32(0x319f453b) }, + { SPH_C32(0xc91e0000), SPH_C32(0xde120000), SPH_C32(0x00371e4e), + SPH_C32(0x9b220000), SPH_C32(0x1d7e19d1), SPH_C32(0x6b5f569f), + SPH_C32(0xe7ed160f), SPH_C32(0x11433a2d), SPH_C32(0xf9f40000), + SPH_C32(0xc0ac0000), SPH_C32(0x008c0d86), SPH_C32(0x8a2e0000), + SPH_C32(0xdc4d3c56), SPH_C32(0x9f17198b), SPH_C32(0xfd28b0a9), + SPH_C32(0x4e0813aa) }, + { SPH_C32(0xc8c30000), SPH_C32(0x5eba0000), SPH_C32(0xf4a11e06), + SPH_C32(0x3d220000), SPH_C32(0x8dab6773), SPH_C32(0xbcb9daa8), + SPH_C32(0x81ffd9f2), SPH_C32(0x3dd77fb3), SPH_C32(0xaba40000), + SPH_C32(0xe9f80000), SPH_C32(0x6aed0dc8), SPH_C32(0x7ad10000), + SPH_C32(0x467c42ba), SPH_C32(0xda345845), SPH_C32(0x327e3f4c), + SPH_C32(0x1d0b00a5) }, + { SPH_C32(0x9a930000), SPH_C32(0x77ee0000), SPH_C32(0x9ec01e48), + SPH_C32(0xcddd0000), SPH_C32(0x179a199f), SPH_C32(0xf99a9b66), + SPH_C32(0x4ea95617), SPH_C32(0x6ed46cbc), SPH_C32(0xf8290000), + SPH_C32(0x40040000), SPH_C32(0xf41a0dce), SPH_C32(0x2c2e0000), + SPH_C32(0x4c9842f4), SPH_C32(0x48f195bc), SPH_C32(0x9b3a7f54), + SPH_C32(0x629c5634) } +}; + +static const sph_u32 T512_42[128][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x92560000), SPH_C32(0x1eda0000), SPH_C32(0xea510000), + SPH_C32(0xe8b13000), SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), + SPH_C32(0xb15c2254), SPH_C32(0x33c5244f), SPH_C32(0x8c3a0000), + SPH_C32(0xda980000), SPH_C32(0x607f0000), SPH_C32(0x54078800), + SPH_C32(0x85714513), SPH_C32(0x6006b243), SPH_C32(0xdb50399c), + SPH_C32(0x8a58e6a4) }, + { SPH_C32(0x58430000), SPH_C32(0x807e0000), SPH_C32(0x78330001), + SPH_C32(0xc66b3800), SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), + SPH_C32(0xac73fe6f), SPH_C32(0x3a4479b1), SPH_C32(0x1d5a0000), + SPH_C32(0x2b720000), SPH_C32(0x488d0000), SPH_C32(0xaf611800), + SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), SPH_C32(0x81a20429), + SPH_C32(0x1e7536a6) }, + { SPH_C32(0xca150000), SPH_C32(0x9ea40000), SPH_C32(0x92620001), + SPH_C32(0x2eda0800), SPH_C32(0x4e020a79), SPH_C32(0x92565e44), + SPH_C32(0x1d2fdc3b), SPH_C32(0x09815dfe), SPH_C32(0x91600000), + SPH_C32(0xf1ea0000), SPH_C32(0x28f20000), SPH_C32(0xfb669000), + SPH_C32(0xa0ba6bd6), SPH_C32(0xa87f0d93), SPH_C32(0x5af23db5), + SPH_C32(0x942dd002) }, + { SPH_C32(0x1d5a0000), SPH_C32(0x2b720000), SPH_C32(0x488d0000), + SPH_C32(0xaf611800), SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), + SPH_C32(0x81a20429), SPH_C32(0x1e7536a6), SPH_C32(0x45190000), + SPH_C32(0xab0c0000), SPH_C32(0x30be0001), SPH_C32(0x690a2000), + SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), SPH_C32(0x2dd1fa46), + SPH_C32(0x24314f17) }, + { SPH_C32(0x8f0c0000), SPH_C32(0x35a80000), SPH_C32(0xa2dc0000), + SPH_C32(0x47d02800), SPH_C32(0x8cfe7860), SPH_C32(0x2382de49), + SPH_C32(0x30fe267d), SPH_C32(0x2db012e9), SPH_C32(0xc9230000), + SPH_C32(0x71940000), SPH_C32(0x50c10001), SPH_C32(0x3d0da800), + SPH_C32(0x478d370a), SPH_C32(0xd1d2324e), SPH_C32(0xf681c3da), + SPH_C32(0xae69a9b3) }, + { SPH_C32(0x45190000), SPH_C32(0xab0c0000), SPH_C32(0x30be0001), + SPH_C32(0x690a2000), SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), + SPH_C32(0x2dd1fa46), SPH_C32(0x24314f17), SPH_C32(0x58430000), + SPH_C32(0x807e0000), SPH_C32(0x78330001), SPH_C32(0xc66b3800), + SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), SPH_C32(0xac73fe6f), + SPH_C32(0x3a4479b1) }, + { SPH_C32(0xd74f0000), SPH_C32(0xb5d60000), SPH_C32(0xdaef0001), + SPH_C32(0x81bb1000), SPH_C32(0x6bc924bc), SPH_C32(0x5a2fe194), + SPH_C32(0x9c8dd812), SPH_C32(0x17f46b58), SPH_C32(0xd4790000), + SPH_C32(0x5ae60000), SPH_C32(0x184c0001), SPH_C32(0x926cb000), + SPH_C32(0x624619cf), SPH_C32(0x19ab8d9e), SPH_C32(0x7723c7f3), + SPH_C32(0xb01c9f15) }, + { SPH_C32(0xa53b0000), SPH_C32(0x14260000), SPH_C32(0x4e30001e), + SPH_C32(0x7cae0000), SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), + SPH_C32(0xf73168d8), SPH_C32(0x0b1b4946), SPH_C32(0x07ed0000), + SPH_C32(0xb2500000), SPH_C32(0x8774000a), SPH_C32(0x970d0000), + SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), SPH_C32(0xf4786222), + SPH_C32(0x9075b1ce) }, + { SPH_C32(0x376d0000), SPH_C32(0x0afc0000), SPH_C32(0xa461001e), + SPH_C32(0x941f3000), SPH_C32(0x26ab5b70), SPH_C32(0x9324cba4), + SPH_C32(0x466d4a8c), SPH_C32(0x38de6d09), SPH_C32(0x8bd70000), + SPH_C32(0x68c80000), SPH_C32(0xe70b000a), SPH_C32(0xc30a8800), + SPH_C32(0xc60366bd), SPH_C32(0x28c1dce7), SPH_C32(0x2f285bbe), + SPH_C32(0x1a2d576a) }, + { SPH_C32(0xfd780000), SPH_C32(0x94580000), SPH_C32(0x3603001f), + SPH_C32(0xbac53800), SPH_C32(0x68a95109), SPH_C32(0x017295e0), + SPH_C32(0x5b4296b7), SPH_C32(0x315f30f7), SPH_C32(0x1ab70000), + SPH_C32(0x99220000), SPH_C32(0xcff9000a), SPH_C32(0x386c1800), + SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), SPH_C32(0x75da660b), + SPH_C32(0x8e008768) }, + { SPH_C32(0x6f2e0000), SPH_C32(0x8a820000), SPH_C32(0xdc52001f), + SPH_C32(0x52740800), SPH_C32(0xc19c07ac), SPH_C32(0xea89f479), + SPH_C32(0xea1eb4e3), SPH_C32(0x029a14b8), SPH_C32(0x968d0000), + SPH_C32(0x43ba0000), SPH_C32(0xaf86000a), SPH_C32(0x6c6b9000), + SPH_C32(0xe3c84878), SPH_C32(0xe0b86337), SPH_C32(0xae8a5f97), + SPH_C32(0x045861cc) }, + { SPH_C32(0xb8610000), SPH_C32(0x3f540000), SPH_C32(0x06bd001e), + SPH_C32(0xd3cf1800), SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), + SPH_C32(0x76936cf1), SPH_C32(0x156e7fe0), SPH_C32(0x42f40000), + SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), SPH_C32(0xfe072000), + SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), SPH_C32(0xd9a99864), + SPH_C32(0xb444fed9) }, + { SPH_C32(0x2a370000), SPH_C32(0x218e0000), SPH_C32(0xecec001e), + SPH_C32(0x3b7e2800), SPH_C32(0x036075b5), SPH_C32(0x5b5d7474), + SPH_C32(0xc7cf4ea5), SPH_C32(0x26ab5baf), SPH_C32(0xcece0000), + SPH_C32(0xc3c40000), SPH_C32(0xd7b5000b), SPH_C32(0xaa00a800), + SPH_C32(0x04ff14a4), SPH_C32(0x99155cea), SPH_C32(0x02f9a1f8), + SPH_C32(0x3e1c187d) }, + { SPH_C32(0xe0220000), SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), + SPH_C32(0x15a42000), SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), + SPH_C32(0xdae0929e), SPH_C32(0x2f2a0651), SPH_C32(0x5fae0000), + SPH_C32(0x322e0000), SPH_C32(0xff47000b), SPH_C32(0x51663800), + SPH_C32(0xa4457f72), SPH_C32(0x316a5179), SPH_C32(0x580b9c4d), + SPH_C32(0xaa31c87f) }, + { SPH_C32(0x72740000), SPH_C32(0xa1f00000), SPH_C32(0x94df001f), + SPH_C32(0xfd151000), SPH_C32(0xe4572969), SPH_C32(0x22f04ba9), + SPH_C32(0x6bbcb0ca), SPH_C32(0x1cef221e), SPH_C32(0xd3940000), + SPH_C32(0xe8b60000), SPH_C32(0x9f38000b), SPH_C32(0x0561b000), + SPH_C32(0x21343a61), SPH_C32(0x516ce33a), SPH_C32(0x835ba5d1), + SPH_C32(0x20692edb) }, + { SPH_C32(0x07ed0000), SPH_C32(0xb2500000), SPH_C32(0x8774000a), + SPH_C32(0x970d0000), SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), + SPH_C32(0xf4786222), SPH_C32(0x9075b1ce), SPH_C32(0xa2d60000), + SPH_C32(0xa6760000), SPH_C32(0xc9440014), SPH_C32(0xeba30000), + SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), SPH_C32(0x03490afa), + SPH_C32(0x9b6ef888) }, + { SPH_C32(0x95bb0000), SPH_C32(0xac8a0000), SPH_C32(0x6d25000a), + SPH_C32(0x7fbc3000), SPH_C32(0xea47750b), SPH_C32(0xa33c0f3d), + SPH_C32(0x45244076), SPH_C32(0xa3b09581), SPH_C32(0x2eec0000), + SPH_C32(0x7cee0000), SPH_C32(0xa93b0014), SPH_C32(0xbfa48800), + SPH_C32(0x499d6b68), SPH_C32(0x501e76da), SPH_C32(0xd8193366), + SPH_C32(0x11361e2c) }, + { SPH_C32(0x5fae0000), SPH_C32(0x322e0000), SPH_C32(0xff47000b), + SPH_C32(0x51663800), SPH_C32(0xa4457f72), SPH_C32(0x316a5179), + SPH_C32(0x580b9c4d), SPH_C32(0xaa31c87f), SPH_C32(0xbf8c0000), + SPH_C32(0x8d040000), SPH_C32(0x81c90014), SPH_C32(0x44c21800), + SPH_C32(0xe92700be), SPH_C32(0xf8617b49), SPH_C32(0x82eb0ed3), + SPH_C32(0x851bce2e) }, + { SPH_C32(0xcdf80000), SPH_C32(0x2cf40000), SPH_C32(0x1516000b), + SPH_C32(0xb9d70800), SPH_C32(0x0d7029d7), SPH_C32(0xda9130e0), + SPH_C32(0xe957be19), SPH_C32(0x99f4ec30), SPH_C32(0x33b60000), + SPH_C32(0x579c0000), SPH_C32(0xe1b60014), SPH_C32(0x10c59000), + SPH_C32(0x6c5645ad), SPH_C32(0x9867c90a), SPH_C32(0x59bb374f), + SPH_C32(0x0f43288a) }, + { SPH_C32(0x1ab70000), SPH_C32(0x99220000), SPH_C32(0xcff9000a), + SPH_C32(0x386c1800), SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), + SPH_C32(0x75da660b), SPH_C32(0x8e008768), SPH_C32(0xe7cf0000), + SPH_C32(0x0d7a0000), SPH_C32(0xf9fa0015), SPH_C32(0x82a92000), + SPH_C32(0x0e105c62), SPH_C32(0x81cc4494), SPH_C32(0x2e98f0bc), + SPH_C32(0xbf5fb79f) }, + { SPH_C32(0x88e10000), SPH_C32(0x87f80000), SPH_C32(0x25a8000a), + SPH_C32(0xd0dd2800), SPH_C32(0xcf8c5bce), SPH_C32(0x6b45b0ed), + SPH_C32(0xc486445f), SPH_C32(0xbdc5a327), SPH_C32(0x6bf50000), + SPH_C32(0xd7e20000), SPH_C32(0x99850015), SPH_C32(0xd6aea800), + SPH_C32(0x8b611971), SPH_C32(0xe1caf6d7), SPH_C32(0xf5c8c920), + SPH_C32(0x3507513b) }, + { SPH_C32(0x42f40000), SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), + SPH_C32(0xfe072000), SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), + SPH_C32(0xd9a99864), SPH_C32(0xb444fed9), SPH_C32(0xfa950000), + SPH_C32(0x26080000), SPH_C32(0xb1770015), SPH_C32(0x2dc83800), + SPH_C32(0x2bdb72a7), SPH_C32(0x49b5fb44), SPH_C32(0xaf3af495), + SPH_C32(0xa12a8139) }, + { SPH_C32(0xd0a20000), SPH_C32(0x07860000), SPH_C32(0x5d9b000b), + SPH_C32(0x16b61000), SPH_C32(0x28bb0712), SPH_C32(0x12e88f30), + SPH_C32(0x68f5ba30), SPH_C32(0x8781da96), SPH_C32(0x76af0000), + SPH_C32(0xfc900000), SPH_C32(0xd1080015), SPH_C32(0x79cfb000), + SPH_C32(0xaeaa37b4), SPH_C32(0x29b34907), SPH_C32(0x746acd09), + SPH_C32(0x2b72679d) }, + { SPH_C32(0xa2d60000), SPH_C32(0xa6760000), SPH_C32(0xc9440014), + SPH_C32(0xeba30000), SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), + SPH_C32(0x03490afa), SPH_C32(0x9b6ef888), SPH_C32(0xa53b0000), + SPH_C32(0x14260000), SPH_C32(0x4e30001e), SPH_C32(0x7cae0000), + SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), SPH_C32(0xf73168d8), + SPH_C32(0x0b1b4946) }, + { SPH_C32(0x30800000), SPH_C32(0xb8ac0000), SPH_C32(0x23150014), + SPH_C32(0x03123000), SPH_C32(0x65d978de), SPH_C32(0xdbe3a500), + SPH_C32(0xb21528ae), SPH_C32(0xa8abdcc7), SPH_C32(0x29010000), + SPH_C32(0xcebe0000), SPH_C32(0x2e4f001e), SPH_C32(0x28a98800), + SPH_C32(0x0aef48c6), SPH_C32(0x18d9187e), SPH_C32(0x2c615144), + SPH_C32(0x8143afe2) }, + { SPH_C32(0xfa950000), SPH_C32(0x26080000), SPH_C32(0xb1770015), + SPH_C32(0x2dc83800), SPH_C32(0x2bdb72a7), SPH_C32(0x49b5fb44), + SPH_C32(0xaf3af495), SPH_C32(0xa12a8139), SPH_C32(0xb8610000), + SPH_C32(0x3f540000), SPH_C32(0x06bd001e), SPH_C32(0xd3cf1800), + SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), SPH_C32(0x76936cf1), + SPH_C32(0x156e7fe0) }, + { SPH_C32(0x68c30000), SPH_C32(0x38d20000), SPH_C32(0x5b260015), + SPH_C32(0xc5790800), SPH_C32(0x82ee2402), SPH_C32(0xa24e9add), + SPH_C32(0x1e66d6c1), SPH_C32(0x92efa576), SPH_C32(0x345b0000), + SPH_C32(0xe5cc0000), SPH_C32(0x66c2001e), SPH_C32(0x87c89000), + SPH_C32(0x2f246603), SPH_C32(0xd0a0a7ae), SPH_C32(0xadc3556d), + SPH_C32(0x9f369944) }, + { SPH_C32(0xbf8c0000), SPH_C32(0x8d040000), SPH_C32(0x81c90014), + SPH_C32(0x44c21800), SPH_C32(0xe92700be), SPH_C32(0xf8617b49), + SPH_C32(0x82eb0ed3), SPH_C32(0x851bce2e), SPH_C32(0xe0220000), + SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), SPH_C32(0x15a42000), + SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), SPH_C32(0xdae0929e), + SPH_C32(0x2f2a0651) }, + { SPH_C32(0x2dda0000), SPH_C32(0x93de0000), SPH_C32(0x6b980014), + SPH_C32(0xac732800), SPH_C32(0x4012561b), SPH_C32(0x139a1ad0), + SPH_C32(0x33b72c87), SPH_C32(0xb6deea61), SPH_C32(0x6c180000), + SPH_C32(0x65b20000), SPH_C32(0x1ef1001f), SPH_C32(0x41a3a800), + SPH_C32(0xc8133adf), SPH_C32(0xa90d9873), SPH_C32(0x01b0ab02), + SPH_C32(0xa572e0f5) }, + { SPH_C32(0xe7cf0000), SPH_C32(0x0d7a0000), SPH_C32(0xf9fa0015), + SPH_C32(0x82a92000), SPH_C32(0x0e105c62), SPH_C32(0x81cc4494), + SPH_C32(0x2e98f0bc), SPH_C32(0xbf5fb79f), SPH_C32(0xfd780000), + SPH_C32(0x94580000), SPH_C32(0x3603001f), SPH_C32(0xbac53800), + SPH_C32(0x68a95109), SPH_C32(0x017295e0), SPH_C32(0x5b4296b7), + SPH_C32(0x315f30f7) }, + { SPH_C32(0x75990000), SPH_C32(0x13a00000), SPH_C32(0x13ab0015), + SPH_C32(0x6a181000), SPH_C32(0xa7250ac7), SPH_C32(0x6a37250d), + SPH_C32(0x9fc4d2e8), SPH_C32(0x8c9a93d0), SPH_C32(0x71420000), + SPH_C32(0x4ec00000), SPH_C32(0x567c001f), SPH_C32(0xeec2b000), + SPH_C32(0xedd8141a), SPH_C32(0x617427a3), SPH_C32(0x8012af2b), + SPH_C32(0xbb07d653) }, + { SPH_C32(0x88980000), SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), + SPH_C32(0xfb4e0000), SPH_C32(0xf158079a), SPH_C32(0x61ae9167), + SPH_C32(0xa895706c), SPH_C32(0xe6107494), SPH_C32(0x0bc20000), + SPH_C32(0xdb630000), SPH_C32(0x7e88000c), SPH_C32(0x15860000), + SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), SPH_C32(0xf460449e), + SPH_C32(0xd8b61463) }, + { SPH_C32(0x1ace0000), SPH_C32(0x014e0000), SPH_C32(0x959e002e), + SPH_C32(0x13ff3000), SPH_C32(0x586d513f), SPH_C32(0x8a55f0fe), + SPH_C32(0x19c95238), SPH_C32(0xd5d550db), SPH_C32(0x87f80000), + SPH_C32(0x01fb0000), SPH_C32(0x1ef7000c), SPH_C32(0x41818800), + SPH_C32(0x148c0de0), SPH_C32(0x15870900), SPH_C32(0x2f307d02), + SPH_C32(0x52eef2c7) }, + { SPH_C32(0xd0db0000), SPH_C32(0x9fea0000), SPH_C32(0x07fc002f), + SPH_C32(0x3d253800), SPH_C32(0x166f5b46), SPH_C32(0x1803aeba), + SPH_C32(0x04e68e03), SPH_C32(0xdc540d25), SPH_C32(0x16980000), + SPH_C32(0xf0110000), SPH_C32(0x3605000c), SPH_C32(0xbae71800), + SPH_C32(0xb4366636), SPH_C32(0xbdf80493), SPH_C32(0x75c240b7), + SPH_C32(0xc6c322c5) }, + { SPH_C32(0x428d0000), SPH_C32(0x81300000), SPH_C32(0xedad002f), + SPH_C32(0xd5940800), SPH_C32(0xbf5a0de3), SPH_C32(0xf3f8cf23), + SPH_C32(0xb5baac57), SPH_C32(0xef91296a), SPH_C32(0x9aa20000), + SPH_C32(0x2a890000), SPH_C32(0x567a000c), SPH_C32(0xeee09000), + SPH_C32(0x31472325), SPH_C32(0xddfeb6d0), SPH_C32(0xae92792b), + SPH_C32(0x4c9bc461) }, + { SPH_C32(0x95c20000), SPH_C32(0x34e60000), SPH_C32(0x3742002e), + SPH_C32(0x542f1800), SPH_C32(0xd493295f), SPH_C32(0xa9d72eb7), + SPH_C32(0x29377445), SPH_C32(0xf8654232), SPH_C32(0x4edb0000), + SPH_C32(0x706f0000), SPH_C32(0x4e36000d), SPH_C32(0x7c8c2000), + SPH_C32(0x53013aea), SPH_C32(0xc4553b4e), SPH_C32(0xd9b1bed8), + SPH_C32(0xfc875b74) }, + { SPH_C32(0x07940000), SPH_C32(0x2a3c0000), SPH_C32(0xdd13002e), + SPH_C32(0xbc9e2800), SPH_C32(0x7da67ffa), SPH_C32(0x422c4f2e), + SPH_C32(0x986b5611), SPH_C32(0xcba0667d), SPH_C32(0xc2e10000), + SPH_C32(0xaaf70000), SPH_C32(0x2e49000d), SPH_C32(0x288ba800), + SPH_C32(0xd6707ff9), SPH_C32(0xa453890d), SPH_C32(0x02e18744), + SPH_C32(0x76dfbdd0) }, + { SPH_C32(0xcd810000), SPH_C32(0xb4980000), SPH_C32(0x4f71002f), + SPH_C32(0x92442000), SPH_C32(0x33a47583), SPH_C32(0xd07a116a), + SPH_C32(0x85448a2a), SPH_C32(0xc2213b83), SPH_C32(0x53810000), + SPH_C32(0x5b1d0000), SPH_C32(0x06bb000d), SPH_C32(0xd3ed3800), + SPH_C32(0x76ca142f), SPH_C32(0x0c2c849e), SPH_C32(0x5813baf1), + SPH_C32(0xe2f26dd2) }, + { SPH_C32(0x5fd70000), SPH_C32(0xaa420000), SPH_C32(0xa520002f), + SPH_C32(0x7af51000), SPH_C32(0x9a912326), SPH_C32(0x3b8170f3), + SPH_C32(0x3418a87e), SPH_C32(0xf1e41fcc), SPH_C32(0xdfbb0000), + SPH_C32(0x81850000), SPH_C32(0x66c4000d), SPH_C32(0x87eab000), + SPH_C32(0xf3bb513c), SPH_C32(0x6c2a36dd), SPH_C32(0x8343836d), + SPH_C32(0x68aa8b76) }, + { SPH_C32(0x2da30000), SPH_C32(0x0bb20000), SPH_C32(0x31ff0030), + SPH_C32(0x87e00000), SPH_C32(0x7ec60a4f), SPH_C32(0x19713b5a), + SPH_C32(0x5fa418b4), SPH_C32(0xed0b3dd2), SPH_C32(0x0c2f0000), + SPH_C32(0x69330000), SPH_C32(0xf9fc0006), SPH_C32(0x828b0000), + SPH_C32(0xd28f6b5d), SPH_C32(0x3d46d5e7), SPH_C32(0x001826bc), + SPH_C32(0x48c3a5ad) }, + { SPH_C32(0xbff50000), SPH_C32(0x15680000), SPH_C32(0xdbae0030), + SPH_C32(0x6f513000), SPH_C32(0xd7f35cea), SPH_C32(0xf28a5ac3), + SPH_C32(0xeef83ae0), SPH_C32(0xdece199d), SPH_C32(0x80150000), + SPH_C32(0xb3ab0000), SPH_C32(0x99830006), SPH_C32(0xd68c8800), + SPH_C32(0x57fe2e4e), SPH_C32(0x5d4067a4), SPH_C32(0xdb481f20), + SPH_C32(0xc29b4309) }, + { SPH_C32(0x75e00000), SPH_C32(0x8bcc0000), SPH_C32(0x49cc0031), + SPH_C32(0x418b3800), SPH_C32(0x99f15693), SPH_C32(0x60dc0487), + SPH_C32(0xf3d7e6db), SPH_C32(0xd74f4463), SPH_C32(0x11750000), + SPH_C32(0x42410000), SPH_C32(0xb1710006), SPH_C32(0x2dea1800), + SPH_C32(0xf7444598), SPH_C32(0xf53f6a37), SPH_C32(0x81ba2295), + SPH_C32(0x56b6930b) }, + { SPH_C32(0xe7b60000), SPH_C32(0x95160000), SPH_C32(0xa39d0031), + SPH_C32(0xa93a0800), SPH_C32(0x30c40036), SPH_C32(0x8b27651e), + SPH_C32(0x428bc48f), SPH_C32(0xe48a602c), SPH_C32(0x9d4f0000), + SPH_C32(0x98d90000), SPH_C32(0xd10e0006), SPH_C32(0x79ed9000), + SPH_C32(0x7235008b), SPH_C32(0x9539d874), SPH_C32(0x5aea1b09), + SPH_C32(0xdcee75af) }, + { SPH_C32(0x30f90000), SPH_C32(0x20c00000), SPH_C32(0x79720030), + SPH_C32(0x28811800), SPH_C32(0x5b0d248a), SPH_C32(0xd108848a), + SPH_C32(0xde061c9d), SPH_C32(0xf37e0b74), SPH_C32(0x49360000), + SPH_C32(0xc23f0000), SPH_C32(0xc9420007), SPH_C32(0xeb812000), + SPH_C32(0x10731944), SPH_C32(0x8c9255ea), SPH_C32(0x2dc9dcfa), + SPH_C32(0x6cf2eaba) }, + { SPH_C32(0xa2af0000), SPH_C32(0x3e1a0000), SPH_C32(0x93230030), + SPH_C32(0xc0302800), SPH_C32(0xf238722f), SPH_C32(0x3af3e513), + SPH_C32(0x6f5a3ec9), SPH_C32(0xc0bb2f3b), SPH_C32(0xc50c0000), + SPH_C32(0x18a70000), SPH_C32(0xa93d0007), SPH_C32(0xbf86a800), + SPH_C32(0x95025c57), SPH_C32(0xec94e7a9), SPH_C32(0xf699e566), + SPH_C32(0xe6aa0c1e) }, + { SPH_C32(0x68ba0000), SPH_C32(0xa0be0000), SPH_C32(0x01410031), + SPH_C32(0xeeea2000), SPH_C32(0xbc3a7856), SPH_C32(0xa8a5bb57), + SPH_C32(0x7275e2f2), SPH_C32(0xc93a72c5), SPH_C32(0x546c0000), + SPH_C32(0xe94d0000), SPH_C32(0x81cf0007), SPH_C32(0x44e03800), + SPH_C32(0x35b83781), SPH_C32(0x44ebea3a), SPH_C32(0xac6bd8d3), + SPH_C32(0x7287dc1c) }, + { SPH_C32(0xfaec0000), SPH_C32(0xbe640000), SPH_C32(0xeb100031), + SPH_C32(0x065b1000), SPH_C32(0x150f2ef3), SPH_C32(0x435edace), + SPH_C32(0xc329c0a6), SPH_C32(0xfaff568a), SPH_C32(0xd8560000), + SPH_C32(0x33d50000), SPH_C32(0xe1b00007), SPH_C32(0x10e7b000), + SPH_C32(0xb0c97292), SPH_C32(0x24ed5879), SPH_C32(0x773be14f), + SPH_C32(0xf8df3ab8) }, + { SPH_C32(0x8f750000), SPH_C32(0xadc40000), SPH_C32(0xf8bb0024), + SPH_C32(0x6c430000), SPH_C32(0xb22a2434), SPH_C32(0x2969ffc3), + SPH_C32(0x5ced124e), SPH_C32(0x7665c55a), SPH_C32(0xa9140000), + SPH_C32(0x7d150000), SPH_C32(0xb7cc0018), SPH_C32(0xfe250000), + SPH_C32(0x5d116688), SPH_C32(0x45997fda), SPH_C32(0xf7294e64), + SPH_C32(0x43d8eceb) }, + { SPH_C32(0x1d230000), SPH_C32(0xb31e0000), SPH_C32(0x12ea0024), + SPH_C32(0x84f23000), SPH_C32(0x1b1f7291), SPH_C32(0xc2929e5a), + SPH_C32(0xedb1301a), SPH_C32(0x45a0e115), SPH_C32(0x252e0000), + SPH_C32(0xa78d0000), SPH_C32(0xd7b30018), SPH_C32(0xaa228800), + SPH_C32(0xd860239b), SPH_C32(0x259fcd99), SPH_C32(0x2c7977f8), + SPH_C32(0xc9800a4f) }, + { SPH_C32(0xd7360000), SPH_C32(0x2dba0000), SPH_C32(0x80880025), + SPH_C32(0xaa283800), SPH_C32(0x551d78e8), SPH_C32(0x50c4c01e), + SPH_C32(0xf09eec21), SPH_C32(0x4c21bceb), SPH_C32(0xb44e0000), + SPH_C32(0x56670000), SPH_C32(0xff410018), SPH_C32(0x51441800), + SPH_C32(0x78da484d), SPH_C32(0x8de0c00a), SPH_C32(0x768b4a4d), + SPH_C32(0x5dadda4d) }, + { SPH_C32(0x45600000), SPH_C32(0x33600000), SPH_C32(0x6ad90025), + SPH_C32(0x42990800), SPH_C32(0xfc282e4d), SPH_C32(0xbb3fa187), + SPH_C32(0x41c2ce75), SPH_C32(0x7fe498a4), SPH_C32(0x38740000), + SPH_C32(0x8cff0000), SPH_C32(0x9f3e0018), SPH_C32(0x05439000), + SPH_C32(0xfdab0d5e), SPH_C32(0xede67249), SPH_C32(0xaddb73d1), + SPH_C32(0xd7f53ce9) }, + { SPH_C32(0x922f0000), SPH_C32(0x86b60000), SPH_C32(0xb0360024), + SPH_C32(0xc3221800), SPH_C32(0x97e10af1), SPH_C32(0xe1104013), + SPH_C32(0xdd4f1667), SPH_C32(0x6810f3fc), SPH_C32(0xec0d0000), + SPH_C32(0xd6190000), SPH_C32(0x87720019), SPH_C32(0x972f2000), + SPH_C32(0x9fed1491), SPH_C32(0xf44dffd7), SPH_C32(0xdaf8b422), + SPH_C32(0x67e9a3fc) }, + { SPH_C32(0x00790000), SPH_C32(0x986c0000), SPH_C32(0x5a670024), + SPH_C32(0x2b932800), SPH_C32(0x3ed45c54), SPH_C32(0x0aeb218a), + SPH_C32(0x6c133433), SPH_C32(0x5bd5d7b3), SPH_C32(0x60370000), + SPH_C32(0x0c810000), SPH_C32(0xe70d0019), SPH_C32(0xc328a800), + SPH_C32(0x1a9c5182), SPH_C32(0x944b4d94), SPH_C32(0x01a88dbe), + SPH_C32(0xedb14558) }, + { SPH_C32(0xca6c0000), SPH_C32(0x06c80000), SPH_C32(0xc8050025), + SPH_C32(0x05492000), SPH_C32(0x70d6562d), SPH_C32(0x98bd7fce), + SPH_C32(0x713ce808), SPH_C32(0x52548a4d), SPH_C32(0xf1570000), + SPH_C32(0xfd6b0000), SPH_C32(0xcfff0019), SPH_C32(0x384e3800), + SPH_C32(0xba263a54), SPH_C32(0x3c344007), SPH_C32(0x5b5ab00b), + SPH_C32(0x799c955a) }, + { SPH_C32(0x583a0000), SPH_C32(0x18120000), SPH_C32(0x22540025), + SPH_C32(0xedf81000), SPH_C32(0xd9e30088), SPH_C32(0x73461e57), + SPH_C32(0xc060ca5c), SPH_C32(0x6191ae02), SPH_C32(0x7d6d0000), + SPH_C32(0x27f30000), SPH_C32(0xaf800019), SPH_C32(0x6c49b000), + SPH_C32(0x3f577f47), SPH_C32(0x5c32f244), SPH_C32(0x800a8997), + SPH_C32(0xf3c473fe) }, + { SPH_C32(0x2a4e0000), SPH_C32(0xb9e20000), SPH_C32(0xb68b003a), + SPH_C32(0x10ed0000), SPH_C32(0x3db429e1), SPH_C32(0x51b655fe), + SPH_C32(0xabdc7a96), SPH_C32(0x7d7e8c1c), SPH_C32(0xaef90000), + SPH_C32(0xcf450000), SPH_C32(0x30b80012), SPH_C32(0x69280000), + SPH_C32(0x1e634526), SPH_C32(0x0d5e117e), SPH_C32(0x03512c46), + SPH_C32(0xd3ad5d25) }, + { SPH_C32(0xb8180000), SPH_C32(0xa7380000), SPH_C32(0x5cda003a), + SPH_C32(0xf85c3000), SPH_C32(0x94817f44), SPH_C32(0xba4d3467), + SPH_C32(0x1a8058c2), SPH_C32(0x4ebba853), SPH_C32(0x22c30000), + SPH_C32(0x15dd0000), SPH_C32(0x50c70012), SPH_C32(0x3d2f8800), + SPH_C32(0x9b120035), SPH_C32(0x6d58a33d), SPH_C32(0xd80115da), + SPH_C32(0x59f5bb81) }, + { SPH_C32(0x720d0000), SPH_C32(0x399c0000), SPH_C32(0xceb8003b), + SPH_C32(0xd6863800), SPH_C32(0xda83753d), SPH_C32(0x281b6a23), + SPH_C32(0x07af84f9), SPH_C32(0x473af5ad), SPH_C32(0xb3a30000), + SPH_C32(0xe4370000), SPH_C32(0x78350012), SPH_C32(0xc6491800), + SPH_C32(0x3ba86be3), SPH_C32(0xc527aeae), SPH_C32(0x82f3286f), + SPH_C32(0xcdd86b83) }, + { SPH_C32(0xe05b0000), SPH_C32(0x27460000), SPH_C32(0x24e9003b), + SPH_C32(0x3e370800), SPH_C32(0x73b62398), SPH_C32(0xc3e00bba), + SPH_C32(0xb6f3a6ad), SPH_C32(0x74ffd1e2), SPH_C32(0x3f990000), + SPH_C32(0x3eaf0000), SPH_C32(0x184a0012), SPH_C32(0x924e9000), + SPH_C32(0xbed92ef0), SPH_C32(0xa5211ced), SPH_C32(0x59a311f3), + SPH_C32(0x47808d27) }, + { SPH_C32(0x37140000), SPH_C32(0x92900000), SPH_C32(0xfe06003a), + SPH_C32(0xbf8c1800), SPH_C32(0x187f0724), SPH_C32(0x99cfea2e), + SPH_C32(0x2a7e7ebf), SPH_C32(0x630bbaba), SPH_C32(0xebe00000), + SPH_C32(0x64490000), SPH_C32(0x00060013), SPH_C32(0x00222000), + SPH_C32(0xdc9f373f), SPH_C32(0xbc8a9173), SPH_C32(0x2e80d600), + SPH_C32(0xf79c1232) }, + { SPH_C32(0xa5420000), SPH_C32(0x8c4a0000), SPH_C32(0x1457003a), + SPH_C32(0x573d2800), SPH_C32(0xb14a5181), SPH_C32(0x72348bb7), + SPH_C32(0x9b225ceb), SPH_C32(0x50ce9ef5), SPH_C32(0x67da0000), + SPH_C32(0xbed10000), SPH_C32(0x60790013), SPH_C32(0x5425a800), + SPH_C32(0x59ee722c), SPH_C32(0xdc8c2330), SPH_C32(0xf5d0ef9c), + SPH_C32(0x7dc4f496) }, + { SPH_C32(0x6f570000), SPH_C32(0x12ee0000), SPH_C32(0x8635003b), + SPH_C32(0x79e72000), SPH_C32(0xff485bf8), SPH_C32(0xe062d5f3), + SPH_C32(0x860d80d0), SPH_C32(0x594fc30b), SPH_C32(0xf6ba0000), + SPH_C32(0x4f3b0000), SPH_C32(0x488b0013), SPH_C32(0xaf433800), + SPH_C32(0xf95419fa), SPH_C32(0x74f32ea3), SPH_C32(0xaf22d229), + SPH_C32(0xe9e92494) }, + { SPH_C32(0xfd010000), SPH_C32(0x0c340000), SPH_C32(0x6c64003b), + SPH_C32(0x91561000), SPH_C32(0x567d0d5d), SPH_C32(0x0b99b46a), + SPH_C32(0x3751a284), SPH_C32(0x6a8ae744), SPH_C32(0x7a800000), + SPH_C32(0x95a30000), SPH_C32(0x28f40013), SPH_C32(0xfb44b000), + SPH_C32(0x7c255ce9), SPH_C32(0x14f59ce0), SPH_C32(0x7472ebb5), + SPH_C32(0x63b1c230) }, + { SPH_C32(0x0bc20000), SPH_C32(0xdb630000), SPH_C32(0x7e88000c), + SPH_C32(0x15860000), SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), + SPH_C32(0xf460449e), SPH_C32(0xd8b61463), SPH_C32(0x835a0000), + SPH_C32(0xc4f70000), SPH_C32(0x01470022), SPH_C32(0xeec80000), + SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), SPH_C32(0x5cf534f2), + SPH_C32(0x3ea660f7) }, + { SPH_C32(0x99940000), SPH_C32(0xc5b90000), SPH_C32(0x94d9000c), + SPH_C32(0xfd373000), SPH_C32(0x38c81e56), SPH_C32(0x9e7adada), + SPH_C32(0x453c66ca), SPH_C32(0xeb73302c), SPH_C32(0x0f600000), + SPH_C32(0x1e6f0000), SPH_C32(0x61380022), SPH_C32(0xbacf8800), + SPH_C32(0xe5d40a7a), SPH_C32(0x74299867), SPH_C32(0x87a50d6e), + SPH_C32(0xb4fe8653) }, + { SPH_C32(0x53810000), SPH_C32(0x5b1d0000), SPH_C32(0x06bb000d), + SPH_C32(0xd3ed3800), SPH_C32(0x76ca142f), SPH_C32(0x0c2c849e), + SPH_C32(0x5813baf1), SPH_C32(0xe2f26dd2), SPH_C32(0x9e000000), + SPH_C32(0xef850000), SPH_C32(0x49ca0022), SPH_C32(0x41a91800), + SPH_C32(0x456e61ac), SPH_C32(0xdc5695f4), SPH_C32(0xdd5730db), + SPH_C32(0x20d35651) }, + { SPH_C32(0xc1d70000), SPH_C32(0x45c70000), SPH_C32(0xecea000d), + SPH_C32(0x3b5c0800), SPH_C32(0xdfff428a), SPH_C32(0xe7d7e507), + SPH_C32(0xe94f98a5), SPH_C32(0xd137499d), SPH_C32(0x123a0000), + SPH_C32(0x351d0000), SPH_C32(0x29b50022), SPH_C32(0x15ae9000), + SPH_C32(0xc01f24bf), SPH_C32(0xbc5027b7), SPH_C32(0x06070947), + SPH_C32(0xaa8bb0f5) }, + { SPH_C32(0x16980000), SPH_C32(0xf0110000), SPH_C32(0x3605000c), + SPH_C32(0xbae71800), SPH_C32(0xb4366636), SPH_C32(0xbdf80493), + SPH_C32(0x75c240b7), SPH_C32(0xc6c322c5), SPH_C32(0xc6430000), + SPH_C32(0x6ffb0000), SPH_C32(0x31f90023), SPH_C32(0x87c22000), + SPH_C32(0xa2593d70), SPH_C32(0xa5fbaa29), SPH_C32(0x7124ceb4), + SPH_C32(0x1a972fe0) }, + { SPH_C32(0x84ce0000), SPH_C32(0xeecb0000), SPH_C32(0xdc54000c), + SPH_C32(0x52562800), SPH_C32(0x1d033093), SPH_C32(0x5603650a), + SPH_C32(0xc49e62e3), SPH_C32(0xf506068a), SPH_C32(0x4a790000), + SPH_C32(0xb5630000), SPH_C32(0x51860023), SPH_C32(0xd3c5a800), + SPH_C32(0x27287863), SPH_C32(0xc5fd186a), SPH_C32(0xaa74f728), + SPH_C32(0x90cfc944) }, + { SPH_C32(0x4edb0000), SPH_C32(0x706f0000), SPH_C32(0x4e36000d), + SPH_C32(0x7c8c2000), SPH_C32(0x53013aea), SPH_C32(0xc4553b4e), + SPH_C32(0xd9b1bed8), SPH_C32(0xfc875b74), SPH_C32(0xdb190000), + SPH_C32(0x44890000), SPH_C32(0x79740023), SPH_C32(0x28a33800), + SPH_C32(0x879213b5), SPH_C32(0x6d8215f9), SPH_C32(0xf086ca9d), + SPH_C32(0x04e21946) }, + { SPH_C32(0xdc8d0000), SPH_C32(0x6eb50000), SPH_C32(0xa467000d), + SPH_C32(0x943d1000), SPH_C32(0xfa346c4f), SPH_C32(0x2fae5ad7), + SPH_C32(0x68ed9c8c), SPH_C32(0xcf427f3b), SPH_C32(0x57230000), + SPH_C32(0x9e110000), SPH_C32(0x190b0023), SPH_C32(0x7ca4b000), + SPH_C32(0x02e356a6), SPH_C32(0x0d84a7ba), SPH_C32(0x2bd6f301), + SPH_C32(0x8ebaffe2) }, + { SPH_C32(0xaef90000), SPH_C32(0xcf450000), SPH_C32(0x30b80012), + SPH_C32(0x69280000), SPH_C32(0x1e634526), SPH_C32(0x0d5e117e), + SPH_C32(0x03512c46), SPH_C32(0xd3ad5d25), SPH_C32(0x84b70000), + SPH_C32(0x76a70000), SPH_C32(0x86330028), SPH_C32(0x79c50000), + SPH_C32(0x23d76cc7), SPH_C32(0x5ce84480), SPH_C32(0xa88d56d0), + SPH_C32(0xaed3d139) }, + { SPH_C32(0x3caf0000), SPH_C32(0xd19f0000), SPH_C32(0xdae90012), + SPH_C32(0x81993000), SPH_C32(0xb7561383), SPH_C32(0xe6a570e7), + SPH_C32(0xb20d0e12), SPH_C32(0xe068796a), SPH_C32(0x088d0000), + SPH_C32(0xac3f0000), SPH_C32(0xe64c0028), SPH_C32(0x2dc28800), + SPH_C32(0xa6a629d4), SPH_C32(0x3ceef6c3), SPH_C32(0x73dd6f4c), + SPH_C32(0x248b379d) }, + { SPH_C32(0xf6ba0000), SPH_C32(0x4f3b0000), SPH_C32(0x488b0013), + SPH_C32(0xaf433800), SPH_C32(0xf95419fa), SPH_C32(0x74f32ea3), + SPH_C32(0xaf22d229), SPH_C32(0xe9e92494), SPH_C32(0x99ed0000), + SPH_C32(0x5dd50000), SPH_C32(0xcebe0028), SPH_C32(0xd6a41800), + SPH_C32(0x061c4202), SPH_C32(0x9491fb50), SPH_C32(0x292f52f9), + SPH_C32(0xb0a6e79f) }, + { SPH_C32(0x64ec0000), SPH_C32(0x51e10000), SPH_C32(0xa2da0013), + SPH_C32(0x47f20800), SPH_C32(0x50614f5f), SPH_C32(0x9f084f3a), + SPH_C32(0x1e7ef07d), SPH_C32(0xda2c00db), SPH_C32(0x15d70000), + SPH_C32(0x874d0000), SPH_C32(0xaec10028), SPH_C32(0x82a39000), + SPH_C32(0x836d0711), SPH_C32(0xf4974913), SPH_C32(0xf27f6b65), + SPH_C32(0x3afe013b) }, + { SPH_C32(0xb3a30000), SPH_C32(0xe4370000), SPH_C32(0x78350012), + SPH_C32(0xc6491800), SPH_C32(0x3ba86be3), SPH_C32(0xc527aeae), + SPH_C32(0x82f3286f), SPH_C32(0xcdd86b83), SPH_C32(0xc1ae0000), + SPH_C32(0xddab0000), SPH_C32(0xb68d0029), SPH_C32(0x10cf2000), + SPH_C32(0xe12b1ede), SPH_C32(0xed3cc48d), SPH_C32(0x855cac96), + SPH_C32(0x8ae29e2e) }, + { SPH_C32(0x21f50000), SPH_C32(0xfaed0000), SPH_C32(0x92640012), + SPH_C32(0x2ef82800), SPH_C32(0x929d3d46), SPH_C32(0x2edccf37), + SPH_C32(0x33af0a3b), SPH_C32(0xfe1d4fcc), SPH_C32(0x4d940000), + SPH_C32(0x07330000), SPH_C32(0xd6f20029), SPH_C32(0x44c8a800), + SPH_C32(0x645a5bcd), SPH_C32(0x8d3a76ce), SPH_C32(0x5e0c950a), + SPH_C32(0x00ba788a) }, + { SPH_C32(0xebe00000), SPH_C32(0x64490000), SPH_C32(0x00060013), + SPH_C32(0x00222000), SPH_C32(0xdc9f373f), SPH_C32(0xbc8a9173), + SPH_C32(0x2e80d600), SPH_C32(0xf79c1232), SPH_C32(0xdcf40000), + SPH_C32(0xf6d90000), SPH_C32(0xfe000029), SPH_C32(0xbfae3800), + SPH_C32(0xc4e0301b), SPH_C32(0x25457b5d), SPH_C32(0x04fea8bf), + SPH_C32(0x9497a888) }, + { SPH_C32(0x79b60000), SPH_C32(0x7a930000), SPH_C32(0xea570013), + SPH_C32(0xe8931000), SPH_C32(0x75aa619a), SPH_C32(0x5771f0ea), + SPH_C32(0x9fdcf454), SPH_C32(0xc459367d), SPH_C32(0x50ce0000), + SPH_C32(0x2c410000), SPH_C32(0x9e7f0029), SPH_C32(0xeba9b000), + SPH_C32(0x41917508), SPH_C32(0x4543c91e), SPH_C32(0xdfae9123), + SPH_C32(0x1ecf4e2c) }, + { SPH_C32(0x0c2f0000), SPH_C32(0x69330000), SPH_C32(0xf9fc0006), + SPH_C32(0x828b0000), SPH_C32(0xd28f6b5d), SPH_C32(0x3d46d5e7), + SPH_C32(0x001826bc), SPH_C32(0x48c3a5ad), SPH_C32(0x218c0000), + SPH_C32(0x62810000), SPH_C32(0xc8030036), SPH_C32(0x056b0000), + SPH_C32(0xac496112), SPH_C32(0x2437eebd), SPH_C32(0x5fbc3e08), + SPH_C32(0xa5c8987f) }, + { SPH_C32(0x9e790000), SPH_C32(0x77e90000), SPH_C32(0x13ad0006), + SPH_C32(0x6a3a3000), SPH_C32(0x7bba3df8), SPH_C32(0xd6bdb47e), + SPH_C32(0xb14404e8), SPH_C32(0x7b0681e2), SPH_C32(0xadb60000), + SPH_C32(0xb8190000), SPH_C32(0xa87c0036), SPH_C32(0x516c8800), + SPH_C32(0x29382401), SPH_C32(0x44315cfe), SPH_C32(0x84ec0794), + SPH_C32(0x2f907edb) }, + { SPH_C32(0x546c0000), SPH_C32(0xe94d0000), SPH_C32(0x81cf0007), + SPH_C32(0x44e03800), SPH_C32(0x35b83781), SPH_C32(0x44ebea3a), + SPH_C32(0xac6bd8d3), SPH_C32(0x7287dc1c), SPH_C32(0x3cd60000), + SPH_C32(0x49f30000), SPH_C32(0x808e0036), SPH_C32(0xaa0a1800), + SPH_C32(0x89824fd7), SPH_C32(0xec4e516d), SPH_C32(0xde1e3a21), + SPH_C32(0xbbbdaed9) }, + { SPH_C32(0xc63a0000), SPH_C32(0xf7970000), SPH_C32(0x6b9e0007), + SPH_C32(0xac510800), SPH_C32(0x9c8d6124), SPH_C32(0xaf108ba3), + SPH_C32(0x1d37fa87), SPH_C32(0x4142f853), SPH_C32(0xb0ec0000), + SPH_C32(0x936b0000), SPH_C32(0xe0f10036), SPH_C32(0xfe0d9000), + SPH_C32(0x0cf30ac4), SPH_C32(0x8c48e32e), SPH_C32(0x054e03bd), + SPH_C32(0x31e5487d) }, + { SPH_C32(0x11750000), SPH_C32(0x42410000), SPH_C32(0xb1710006), + SPH_C32(0x2dea1800), SPH_C32(0xf7444598), SPH_C32(0xf53f6a37), + SPH_C32(0x81ba2295), SPH_C32(0x56b6930b), SPH_C32(0x64950000), + SPH_C32(0xc98d0000), SPH_C32(0xf8bd0037), SPH_C32(0x6c612000), + SPH_C32(0x6eb5130b), SPH_C32(0x95e36eb0), SPH_C32(0x726dc44e), + SPH_C32(0x81f9d768) }, + { SPH_C32(0x83230000), SPH_C32(0x5c9b0000), SPH_C32(0x5b200006), + SPH_C32(0xc55b2800), SPH_C32(0x5e71133d), SPH_C32(0x1ec40bae), + SPH_C32(0x30e600c1), SPH_C32(0x6573b744), SPH_C32(0xe8af0000), + SPH_C32(0x13150000), SPH_C32(0x98c20037), SPH_C32(0x3866a800), + SPH_C32(0xebc45618), SPH_C32(0xf5e5dcf3), SPH_C32(0xa93dfdd2), + SPH_C32(0x0ba131cc) }, + { SPH_C32(0x49360000), SPH_C32(0xc23f0000), SPH_C32(0xc9420007), + SPH_C32(0xeb812000), SPH_C32(0x10731944), SPH_C32(0x8c9255ea), + SPH_C32(0x2dc9dcfa), SPH_C32(0x6cf2eaba), SPH_C32(0x79cf0000), + SPH_C32(0xe2ff0000), SPH_C32(0xb0300037), SPH_C32(0xc3003800), + SPH_C32(0x4b7e3dce), SPH_C32(0x5d9ad160), SPH_C32(0xf3cfc067), + SPH_C32(0x9f8ce1ce) }, + { SPH_C32(0xdb600000), SPH_C32(0xdce50000), SPH_C32(0x23130007), + SPH_C32(0x03301000), SPH_C32(0xb9464fe1), SPH_C32(0x67693473), + SPH_C32(0x9c95feae), SPH_C32(0x5f37cef5), SPH_C32(0xf5f50000), + SPH_C32(0x38670000), SPH_C32(0xd04f0037), SPH_C32(0x9707b000), + SPH_C32(0xce0f78dd), SPH_C32(0x3d9c6323), SPH_C32(0x289ff9fb), + SPH_C32(0x15d4076a) }, + { SPH_C32(0xa9140000), SPH_C32(0x7d150000), SPH_C32(0xb7cc0018), + SPH_C32(0xfe250000), SPH_C32(0x5d116688), SPH_C32(0x45997fda), + SPH_C32(0xf7294e64), SPH_C32(0x43d8eceb), SPH_C32(0x26610000), + SPH_C32(0xd0d10000), SPH_C32(0x4f77003c), SPH_C32(0x92660000), + SPH_C32(0xef3b42bc), SPH_C32(0x6cf08019), SPH_C32(0xabc45c2a), + SPH_C32(0x35bd29b1) }, + { SPH_C32(0x3b420000), SPH_C32(0x63cf0000), SPH_C32(0x5d9d0018), + SPH_C32(0x16943000), SPH_C32(0xf424302d), SPH_C32(0xae621e43), + SPH_C32(0x46756c30), SPH_C32(0x701dc8a4), SPH_C32(0xaa5b0000), + SPH_C32(0x0a490000), SPH_C32(0x2f08003c), SPH_C32(0xc6618800), + SPH_C32(0x6a4a07af), SPH_C32(0x0cf6325a), SPH_C32(0x709465b6), + SPH_C32(0xbfe5cf15) }, + { SPH_C32(0xf1570000), SPH_C32(0xfd6b0000), SPH_C32(0xcfff0019), + SPH_C32(0x384e3800), SPH_C32(0xba263a54), SPH_C32(0x3c344007), + SPH_C32(0x5b5ab00b), SPH_C32(0x799c955a), SPH_C32(0x3b3b0000), + SPH_C32(0xfba30000), SPH_C32(0x07fa003c), SPH_C32(0x3d071800), + SPH_C32(0xcaf06c79), SPH_C32(0xa4893fc9), SPH_C32(0x2a665803), + SPH_C32(0x2bc81f17) }, + { SPH_C32(0x63010000), SPH_C32(0xe3b10000), SPH_C32(0x25ae0019), + SPH_C32(0xd0ff0800), SPH_C32(0x13136cf1), SPH_C32(0xd7cf219e), + SPH_C32(0xea06925f), SPH_C32(0x4a59b115), SPH_C32(0xb7010000), + SPH_C32(0x213b0000), SPH_C32(0x6785003c), SPH_C32(0x69009000), + SPH_C32(0x4f81296a), SPH_C32(0xc48f8d8a), SPH_C32(0xf136619f), + SPH_C32(0xa190f9b3) }, + { SPH_C32(0xb44e0000), SPH_C32(0x56670000), SPH_C32(0xff410018), + SPH_C32(0x51441800), SPH_C32(0x78da484d), SPH_C32(0x8de0c00a), + SPH_C32(0x768b4a4d), SPH_C32(0x5dadda4d), SPH_C32(0x63780000), + SPH_C32(0x7bdd0000), SPH_C32(0x7fc9003d), SPH_C32(0xfb6c2000), + SPH_C32(0x2dc730a5), SPH_C32(0xdd240014), SPH_C32(0x8615a66c), + SPH_C32(0x118c66a6) }, + { SPH_C32(0x26180000), SPH_C32(0x48bd0000), SPH_C32(0x15100018), + SPH_C32(0xb9f52800), SPH_C32(0xd1ef1ee8), SPH_C32(0x661ba193), + SPH_C32(0xc7d76819), SPH_C32(0x6e68fe02), SPH_C32(0xef420000), + SPH_C32(0xa1450000), SPH_C32(0x1fb6003d), SPH_C32(0xaf6ba800), + SPH_C32(0xa8b675b6), SPH_C32(0xbd22b257), SPH_C32(0x5d459ff0), + SPH_C32(0x9bd48002) }, + { SPH_C32(0xec0d0000), SPH_C32(0xd6190000), SPH_C32(0x87720019), + SPH_C32(0x972f2000), SPH_C32(0x9fed1491), SPH_C32(0xf44dffd7), + SPH_C32(0xdaf8b422), SPH_C32(0x67e9a3fc), SPH_C32(0x7e220000), + SPH_C32(0x50af0000), SPH_C32(0x3744003d), SPH_C32(0x540d3800), + SPH_C32(0x080c1e60), SPH_C32(0x155dbfc4), SPH_C32(0x07b7a245), + SPH_C32(0x0ff95000) }, + { SPH_C32(0x7e5b0000), SPH_C32(0xc8c30000), SPH_C32(0x6d230019), + SPH_C32(0x7f9e1000), SPH_C32(0x36d84234), SPH_C32(0x1fb69e4e), + SPH_C32(0x6ba49676), SPH_C32(0x542c87b3), SPH_C32(0xf2180000), + SPH_C32(0x8a370000), SPH_C32(0x573b003d), SPH_C32(0x000ab000), + SPH_C32(0x8d7d5b73), SPH_C32(0x755b0d87), SPH_C32(0xdce79bd9), + SPH_C32(0x85a1b6a4) }, + { SPH_C32(0x835a0000), SPH_C32(0xc4f70000), SPH_C32(0x01470022), + SPH_C32(0xeec80000), SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), + SPH_C32(0x5cf534f2), SPH_C32(0x3ea660f7), SPH_C32(0x88980000), + SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), SPH_C32(0xfb4e0000), + SPH_C32(0xf158079a), SPH_C32(0x61ae9167), SPH_C32(0xa895706c), + SPH_C32(0xe6107494) }, + { SPH_C32(0x110c0000), SPH_C32(0xda2d0000), SPH_C32(0xeb160022), + SPH_C32(0x06793000), SPH_C32(0xc99019cc), SPH_C32(0xffd44bbd), + SPH_C32(0xeda916a6), SPH_C32(0x0d6344b8), SPH_C32(0x04a20000), + SPH_C32(0xc50c0000), SPH_C32(0x1fb0002e), SPH_C32(0xaf498800), + SPH_C32(0x74294289), SPH_C32(0x01a82324), SPH_C32(0x73c549f0), + SPH_C32(0x6c489230) }, + { SPH_C32(0xdb190000), SPH_C32(0x44890000), SPH_C32(0x79740023), + SPH_C32(0x28a33800), SPH_C32(0x879213b5), SPH_C32(0x6d8215f9), + SPH_C32(0xf086ca9d), SPH_C32(0x04e21946), SPH_C32(0x95c20000), + SPH_C32(0x34e60000), SPH_C32(0x3742002e), SPH_C32(0x542f1800), + SPH_C32(0xd493295f), SPH_C32(0xa9d72eb7), SPH_C32(0x29377445), + SPH_C32(0xf8654232) }, + { SPH_C32(0x494f0000), SPH_C32(0x5a530000), SPH_C32(0x93250023), + SPH_C32(0xc0120800), SPH_C32(0x2ea74510), SPH_C32(0x86797460), + SPH_C32(0x41dae8c9), SPH_C32(0x37273d09), SPH_C32(0x19f80000), + SPH_C32(0xee7e0000), SPH_C32(0x573d002e), SPH_C32(0x00289000), + SPH_C32(0x51e26c4c), SPH_C32(0xc9d19cf4), SPH_C32(0xf2674dd9), + SPH_C32(0x723da496) }, + { SPH_C32(0x9e000000), SPH_C32(0xef850000), SPH_C32(0x49ca0022), + SPH_C32(0x41a91800), SPH_C32(0x456e61ac), SPH_C32(0xdc5695f4), + SPH_C32(0xdd5730db), SPH_C32(0x20d35651), SPH_C32(0xcd810000), + SPH_C32(0xb4980000), SPH_C32(0x4f71002f), SPH_C32(0x92442000), + SPH_C32(0x33a47583), SPH_C32(0xd07a116a), SPH_C32(0x85448a2a), + SPH_C32(0xc2213b83) }, + { SPH_C32(0x0c560000), SPH_C32(0xf15f0000), SPH_C32(0xa39b0022), + SPH_C32(0xa9182800), SPH_C32(0xec5b3709), SPH_C32(0x37adf46d), + SPH_C32(0x6c0b128f), SPH_C32(0x1316721e), SPH_C32(0x41bb0000), + SPH_C32(0x6e000000), SPH_C32(0x2f0e002f), SPH_C32(0xc643a800), + SPH_C32(0xb6d53090), SPH_C32(0xb07ca329), SPH_C32(0x5e14b3b6), + SPH_C32(0x4879dd27) }, + { SPH_C32(0xc6430000), SPH_C32(0x6ffb0000), SPH_C32(0x31f90023), + SPH_C32(0x87c22000), SPH_C32(0xa2593d70), SPH_C32(0xa5fbaa29), + SPH_C32(0x7124ceb4), SPH_C32(0x1a972fe0), SPH_C32(0xd0db0000), + SPH_C32(0x9fea0000), SPH_C32(0x07fc002f), SPH_C32(0x3d253800), + SPH_C32(0x166f5b46), SPH_C32(0x1803aeba), SPH_C32(0x04e68e03), + SPH_C32(0xdc540d25) }, + { SPH_C32(0x54150000), SPH_C32(0x71210000), SPH_C32(0xdba80023), + SPH_C32(0x6f731000), SPH_C32(0x0b6c6bd5), SPH_C32(0x4e00cbb0), + SPH_C32(0xc078ece0), SPH_C32(0x29520baf), SPH_C32(0x5ce10000), + SPH_C32(0x45720000), SPH_C32(0x6783002f), SPH_C32(0x6922b000), + SPH_C32(0x931e1e55), SPH_C32(0x78051cf9), SPH_C32(0xdfb6b79f), + SPH_C32(0x560ceb81) }, + { SPH_C32(0x26610000), SPH_C32(0xd0d10000), SPH_C32(0x4f77003c), + SPH_C32(0x92660000), SPH_C32(0xef3b42bc), SPH_C32(0x6cf08019), + SPH_C32(0xabc45c2a), SPH_C32(0x35bd29b1), SPH_C32(0x8f750000), + SPH_C32(0xadc40000), SPH_C32(0xf8bb0024), SPH_C32(0x6c430000), + SPH_C32(0xb22a2434), SPH_C32(0x2969ffc3), SPH_C32(0x5ced124e), + SPH_C32(0x7665c55a) }, + { SPH_C32(0xb4370000), SPH_C32(0xce0b0000), SPH_C32(0xa526003c), + SPH_C32(0x7ad73000), SPH_C32(0x460e1419), SPH_C32(0x870be180), + SPH_C32(0x1a987e7e), SPH_C32(0x06780dfe), SPH_C32(0x034f0000), + SPH_C32(0x775c0000), SPH_C32(0x98c40024), SPH_C32(0x38448800), + SPH_C32(0x375b6127), SPH_C32(0x496f4d80), SPH_C32(0x87bd2bd2), + SPH_C32(0xfc3d23fe) }, + { SPH_C32(0x7e220000), SPH_C32(0x50af0000), SPH_C32(0x3744003d), + SPH_C32(0x540d3800), SPH_C32(0x080c1e60), SPH_C32(0x155dbfc4), + SPH_C32(0x07b7a245), SPH_C32(0x0ff95000), SPH_C32(0x922f0000), + SPH_C32(0x86b60000), SPH_C32(0xb0360024), SPH_C32(0xc3221800), + SPH_C32(0x97e10af1), SPH_C32(0xe1104013), SPH_C32(0xdd4f1667), + SPH_C32(0x6810f3fc) }, + { SPH_C32(0xec740000), SPH_C32(0x4e750000), SPH_C32(0xdd15003d), + SPH_C32(0xbcbc0800), SPH_C32(0xa13948c5), SPH_C32(0xfea6de5d), + SPH_C32(0xb6eb8011), SPH_C32(0x3c3c744f), SPH_C32(0x1e150000), + SPH_C32(0x5c2e0000), SPH_C32(0xd0490024), SPH_C32(0x97259000), + SPH_C32(0x12904fe2), SPH_C32(0x8116f250), SPH_C32(0x061f2ffb), + SPH_C32(0xe2481558) }, + { SPH_C32(0x3b3b0000), SPH_C32(0xfba30000), SPH_C32(0x07fa003c), + SPH_C32(0x3d071800), SPH_C32(0xcaf06c79), SPH_C32(0xa4893fc9), + SPH_C32(0x2a665803), SPH_C32(0x2bc81f17), SPH_C32(0xca6c0000), + SPH_C32(0x06c80000), SPH_C32(0xc8050025), SPH_C32(0x05492000), + SPH_C32(0x70d6562d), SPH_C32(0x98bd7fce), SPH_C32(0x713ce808), + SPH_C32(0x52548a4d) }, + { SPH_C32(0xa96d0000), SPH_C32(0xe5790000), SPH_C32(0xedab003c), + SPH_C32(0xd5b62800), SPH_C32(0x63c53adc), SPH_C32(0x4f725e50), + SPH_C32(0x9b3a7a57), SPH_C32(0x180d3b58), SPH_C32(0x46560000), + SPH_C32(0xdc500000), SPH_C32(0xa87a0025), SPH_C32(0x514ea800), + SPH_C32(0xf5a7133e), SPH_C32(0xf8bbcd8d), SPH_C32(0xaa6cd194), + SPH_C32(0xd80c6ce9) }, + { SPH_C32(0x63780000), SPH_C32(0x7bdd0000), SPH_C32(0x7fc9003d), + SPH_C32(0xfb6c2000), SPH_C32(0x2dc730a5), SPH_C32(0xdd240014), + SPH_C32(0x8615a66c), SPH_C32(0x118c66a6), SPH_C32(0xd7360000), + SPH_C32(0x2dba0000), SPH_C32(0x80880025), SPH_C32(0xaa283800), + SPH_C32(0x551d78e8), SPH_C32(0x50c4c01e), SPH_C32(0xf09eec21), + SPH_C32(0x4c21bceb) }, + { SPH_C32(0xf12e0000), SPH_C32(0x65070000), SPH_C32(0x9598003d), + SPH_C32(0x13dd1000), SPH_C32(0x84f26600), SPH_C32(0x36df618d), + SPH_C32(0x37498438), SPH_C32(0x224942e9), SPH_C32(0x5b0c0000), + SPH_C32(0xf7220000), SPH_C32(0xe0f70025), SPH_C32(0xfe2fb000), + SPH_C32(0xd06c3dfb), SPH_C32(0x30c2725d), SPH_C32(0x2bced5bd), + SPH_C32(0xc6795a4f) }, + { SPH_C32(0x84b70000), SPH_C32(0x76a70000), SPH_C32(0x86330028), + SPH_C32(0x79c50000), SPH_C32(0x23d76cc7), SPH_C32(0x5ce84480), + SPH_C32(0xa88d56d0), SPH_C32(0xaed3d139), SPH_C32(0x2a4e0000), + SPH_C32(0xb9e20000), SPH_C32(0xb68b003a), SPH_C32(0x10ed0000), + SPH_C32(0x3db429e1), SPH_C32(0x51b655fe), SPH_C32(0xabdc7a96), + SPH_C32(0x7d7e8c1c) }, + { SPH_C32(0x16e10000), SPH_C32(0x687d0000), SPH_C32(0x6c620028), + SPH_C32(0x91743000), SPH_C32(0x8ae23a62), SPH_C32(0xb7132519), + SPH_C32(0x19d17484), SPH_C32(0x9d16f576), SPH_C32(0xa6740000), + SPH_C32(0x637a0000), SPH_C32(0xd6f4003a), SPH_C32(0x44ea8800), + SPH_C32(0xb8c56cf2), SPH_C32(0x31b0e7bd), SPH_C32(0x708c430a), + SPH_C32(0xf7266ab8) }, + { SPH_C32(0xdcf40000), SPH_C32(0xf6d90000), SPH_C32(0xfe000029), + SPH_C32(0xbfae3800), SPH_C32(0xc4e0301b), SPH_C32(0x25457b5d), + SPH_C32(0x04fea8bf), SPH_C32(0x9497a888), SPH_C32(0x37140000), + SPH_C32(0x92900000), SPH_C32(0xfe06003a), SPH_C32(0xbf8c1800), + SPH_C32(0x187f0724), SPH_C32(0x99cfea2e), SPH_C32(0x2a7e7ebf), + SPH_C32(0x630bbaba) }, + { SPH_C32(0x4ea20000), SPH_C32(0xe8030000), SPH_C32(0x14510029), + SPH_C32(0x571f0800), SPH_C32(0x6dd566be), SPH_C32(0xcebe1ac4), + SPH_C32(0xb5a28aeb), SPH_C32(0xa7528cc7), SPH_C32(0xbb2e0000), + SPH_C32(0x48080000), SPH_C32(0x9e79003a), SPH_C32(0xeb8b9000), + SPH_C32(0x9d0e4237), SPH_C32(0xf9c9586d), SPH_C32(0xf12e4723), + SPH_C32(0xe9535c1e) }, + { SPH_C32(0x99ed0000), SPH_C32(0x5dd50000), SPH_C32(0xcebe0028), + SPH_C32(0xd6a41800), SPH_C32(0x061c4202), SPH_C32(0x9491fb50), + SPH_C32(0x292f52f9), SPH_C32(0xb0a6e79f), SPH_C32(0x6f570000), + SPH_C32(0x12ee0000), SPH_C32(0x8635003b), SPH_C32(0x79e72000), + SPH_C32(0xff485bf8), SPH_C32(0xe062d5f3), SPH_C32(0x860d80d0), + SPH_C32(0x594fc30b) }, + { SPH_C32(0x0bbb0000), SPH_C32(0x430f0000), SPH_C32(0x24ef0028), + SPH_C32(0x3e152800), SPH_C32(0xaf2914a7), SPH_C32(0x7f6a9ac9), + SPH_C32(0x987370ad), SPH_C32(0x8363c3d0), SPH_C32(0xe36d0000), + SPH_C32(0xc8760000), SPH_C32(0xe64a003b), SPH_C32(0x2de0a800), + SPH_C32(0x7a391eeb), SPH_C32(0x806467b0), SPH_C32(0x5d5db94c), + SPH_C32(0xd31725af) }, + { SPH_C32(0xc1ae0000), SPH_C32(0xddab0000), SPH_C32(0xb68d0029), + SPH_C32(0x10cf2000), SPH_C32(0xe12b1ede), SPH_C32(0xed3cc48d), + SPH_C32(0x855cac96), SPH_C32(0x8ae29e2e), SPH_C32(0x720d0000), + SPH_C32(0x399c0000), SPH_C32(0xceb8003b), SPH_C32(0xd6863800), + SPH_C32(0xda83753d), SPH_C32(0x281b6a23), SPH_C32(0x07af84f9), + SPH_C32(0x473af5ad) }, + { SPH_C32(0x53f80000), SPH_C32(0xc3710000), SPH_C32(0x5cdc0029), + SPH_C32(0xf87e1000), SPH_C32(0x481e487b), SPH_C32(0x06c7a514), + SPH_C32(0x34008ec2), SPH_C32(0xb927ba61), SPH_C32(0xfe370000), + SPH_C32(0xe3040000), SPH_C32(0xaec7003b), SPH_C32(0x8281b000), + SPH_C32(0x5ff2302e), SPH_C32(0x481dd860), SPH_C32(0xdcffbd65), + SPH_C32(0xcd621309) }, + { SPH_C32(0x218c0000), SPH_C32(0x62810000), SPH_C32(0xc8030036), + SPH_C32(0x056b0000), SPH_C32(0xac496112), SPH_C32(0x2437eebd), + SPH_C32(0x5fbc3e08), SPH_C32(0xa5c8987f), SPH_C32(0x2da30000), + SPH_C32(0x0bb20000), SPH_C32(0x31ff0030), SPH_C32(0x87e00000), + SPH_C32(0x7ec60a4f), SPH_C32(0x19713b5a), SPH_C32(0x5fa418b4), + SPH_C32(0xed0b3dd2) }, + { SPH_C32(0xb3da0000), SPH_C32(0x7c5b0000), SPH_C32(0x22520036), + SPH_C32(0xedda3000), SPH_C32(0x057c37b7), SPH_C32(0xcfcc8f24), + SPH_C32(0xeee01c5c), SPH_C32(0x960dbc30), SPH_C32(0xa1990000), + SPH_C32(0xd12a0000), SPH_C32(0x51800030), SPH_C32(0xd3e78800), + SPH_C32(0xfbb74f5c), SPH_C32(0x79778919), SPH_C32(0x84f42128), + SPH_C32(0x6753db76) }, + { SPH_C32(0x79cf0000), SPH_C32(0xe2ff0000), SPH_C32(0xb0300037), + SPH_C32(0xc3003800), SPH_C32(0x4b7e3dce), SPH_C32(0x5d9ad160), + SPH_C32(0xf3cfc067), SPH_C32(0x9f8ce1ce), SPH_C32(0x30f90000), + SPH_C32(0x20c00000), SPH_C32(0x79720030), SPH_C32(0x28811800), + SPH_C32(0x5b0d248a), SPH_C32(0xd108848a), SPH_C32(0xde061c9d), + SPH_C32(0xf37e0b74) }, + { SPH_C32(0xeb990000), SPH_C32(0xfc250000), SPH_C32(0x5a610037), + SPH_C32(0x2bb10800), SPH_C32(0xe24b6b6b), SPH_C32(0xb661b0f9), + SPH_C32(0x4293e233), SPH_C32(0xac49c581), SPH_C32(0xbcc30000), + SPH_C32(0xfa580000), SPH_C32(0x190d0030), SPH_C32(0x7c869000), + SPH_C32(0xde7c6199), SPH_C32(0xb10e36c9), SPH_C32(0x05562501), + SPH_C32(0x7926edd0) }, + { SPH_C32(0x3cd60000), SPH_C32(0x49f30000), SPH_C32(0x808e0036), + SPH_C32(0xaa0a1800), SPH_C32(0x89824fd7), SPH_C32(0xec4e516d), + SPH_C32(0xde1e3a21), SPH_C32(0xbbbdaed9), SPH_C32(0x68ba0000), + SPH_C32(0xa0be0000), SPH_C32(0x01410031), SPH_C32(0xeeea2000), + SPH_C32(0xbc3a7856), SPH_C32(0xa8a5bb57), SPH_C32(0x7275e2f2), + SPH_C32(0xc93a72c5) }, + { SPH_C32(0xae800000), SPH_C32(0x57290000), SPH_C32(0x6adf0036), + SPH_C32(0x42bb2800), SPH_C32(0x20b71972), SPH_C32(0x07b530f4), + SPH_C32(0x6f421875), SPH_C32(0x88788a96), SPH_C32(0xe4800000), + SPH_C32(0x7a260000), SPH_C32(0x613e0031), SPH_C32(0xbaeda800), + SPH_C32(0x394b3d45), SPH_C32(0xc8a30914), SPH_C32(0xa925db6e), + SPH_C32(0x43629461) }, + { SPH_C32(0x64950000), SPH_C32(0xc98d0000), SPH_C32(0xf8bd0037), + SPH_C32(0x6c612000), SPH_C32(0x6eb5130b), SPH_C32(0x95e36eb0), + SPH_C32(0x726dc44e), SPH_C32(0x81f9d768), SPH_C32(0x75e00000), + SPH_C32(0x8bcc0000), SPH_C32(0x49cc0031), SPH_C32(0x418b3800), + SPH_C32(0x99f15693), SPH_C32(0x60dc0487), SPH_C32(0xf3d7e6db), + SPH_C32(0xd74f4463) }, + { SPH_C32(0xf6c30000), SPH_C32(0xd7570000), SPH_C32(0x12ec0037), + SPH_C32(0x84d01000), SPH_C32(0xc78045ae), SPH_C32(0x7e180f29), + SPH_C32(0xc331e61a), SPH_C32(0xb23cf327), SPH_C32(0xf9da0000), + SPH_C32(0x51540000), SPH_C32(0x29b30031), SPH_C32(0x158cb000), + SPH_C32(0x1c801380), SPH_C32(0x00dab6c4), SPH_C32(0x2887df47), + SPH_C32(0x5d17a2c7) } +}; + +static const sph_u32 T512_49[128][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xe6280000), SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), + SPH_C32(0xd3d002e0), SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), + SPH_C32(0x289506b4), SPH_C32(0xd75a4897), SPH_C32(0xf0c50000), + SPH_C32(0x59230000), SPH_C32(0x45820000), SPH_C32(0xe18d00c0), + SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), SPH_C32(0xcbe0fe1c), + SPH_C32(0x56a7b19f) }, + { SPH_C32(0xf0c50000), SPH_C32(0x59230000), SPH_C32(0x45820000), + SPH_C32(0xe18d00c0), SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), + SPH_C32(0xcbe0fe1c), SPH_C32(0x56a7b19f), SPH_C32(0x16ed0000), + SPH_C32(0x15680000), SPH_C32(0xedd70000), SPH_C32(0x325d0220), + SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), SPH_C32(0xe375f8a8), + SPH_C32(0x81fdf908) }, + { SPH_C32(0x16ed0000), SPH_C32(0x15680000), SPH_C32(0xedd70000), + SPH_C32(0x325d0220), SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), + SPH_C32(0xe375f8a8), SPH_C32(0x81fdf908), SPH_C32(0xe6280000), + SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), SPH_C32(0xd3d002e0), + SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), SPH_C32(0x289506b4), + SPH_C32(0xd75a4897) }, + { SPH_C32(0xb4310000), SPH_C32(0x77330000), SPH_C32(0xb15d0000), + SPH_C32(0x7fd004e0), SPH_C32(0x78a26138), SPH_C32(0xd116c35d), + SPH_C32(0xd256d489), SPH_C32(0x4e6f74de), SPH_C32(0xe3060000), + SPH_C32(0xbdc10000), SPH_C32(0x87130000), SPH_C32(0xbff20060), + SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), SPH_C32(0x73c5ab06), + SPH_C32(0x5bd61539) }, + { SPH_C32(0x52190000), SPH_C32(0x3b780000), SPH_C32(0x19080000), + SPH_C32(0xac000600), SPH_C32(0xa0c35180), SPH_C32(0x49b17387), + SPH_C32(0xfac3d23d), SPH_C32(0x99353c49), SPH_C32(0x13c30000), + SPH_C32(0xe4e20000), SPH_C32(0xc2910000), SPH_C32(0x5e7f00a0), + SPH_C32(0x15d70c2b), SPH_C32(0x4f5861c8), SPH_C32(0xb825551a), + SPH_C32(0x0d71a4a6) }, + { SPH_C32(0x44f40000), SPH_C32(0x2e100000), SPH_C32(0xf4df0000), + SPH_C32(0x9e5d0420), SPH_C32(0x43cf6709), SPH_C32(0x13fb95c4), + SPH_C32(0x19b62a95), SPH_C32(0x18c8c541), SPH_C32(0xf5eb0000), + SPH_C32(0xa8a90000), SPH_C32(0x6ac40000), SPH_C32(0x8daf0240), + SPH_C32(0xcdb63c93), SPH_C32(0xd7ffd112), SPH_C32(0x90b053ae), + SPH_C32(0xda2bec31) }, + { SPH_C32(0xa2dc0000), SPH_C32(0x625b0000), SPH_C32(0x5c8a0000), + SPH_C32(0x4d8d06c0), SPH_C32(0x9bae57b1), SPH_C32(0x8b5c251e), + SPH_C32(0x31232c21), SPH_C32(0xcf928dd6), SPH_C32(0x052e0000), + SPH_C32(0xf18a0000), SPH_C32(0x2f460000), SPH_C32(0x6c220280), + SPH_C32(0xf6db3aa2), SPH_C32(0x1512878b), SPH_C32(0x5b50adb2), + SPH_C32(0x8c8c5dae) }, + { SPH_C32(0xe3060000), SPH_C32(0xbdc10000), SPH_C32(0x87130000), + SPH_C32(0xbff20060), SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), + SPH_C32(0x73c5ab06), SPH_C32(0x5bd61539), SPH_C32(0x57370000), + SPH_C32(0xcaf20000), SPH_C32(0x364e0000), SPH_C32(0xc0220480), + SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), SPH_C32(0xa1937f8f), + SPH_C32(0x15b961e7) }, + { SPH_C32(0x052e0000), SPH_C32(0xf18a0000), SPH_C32(0x2f460000), + SPH_C32(0x6c220280), SPH_C32(0xf6db3aa2), SPH_C32(0x1512878b), + SPH_C32(0x5b50adb2), SPH_C32(0x8c8c5dae), SPH_C32(0xa7f20000), + SPH_C32(0x93d10000), SPH_C32(0x73cc0000), SPH_C32(0x21af0440), + SPH_C32(0x6d756d13), SPH_C32(0x9e4ea295), SPH_C32(0x6a738193), + SPH_C32(0x431ed078) }, + { SPH_C32(0x13c30000), SPH_C32(0xe4e20000), SPH_C32(0xc2910000), + SPH_C32(0x5e7f00a0), SPH_C32(0x15d70c2b), SPH_C32(0x4f5861c8), + SPH_C32(0xb825551a), SPH_C32(0x0d71a4a6), SPH_C32(0x41da0000), + SPH_C32(0xdf9a0000), SPH_C32(0xdb990000), SPH_C32(0xf27f06a0), + SPH_C32(0xb5145dab), SPH_C32(0x06e9124f), SPH_C32(0x42e68727), + SPH_C32(0x944498ef) }, + { SPH_C32(0xf5eb0000), SPH_C32(0xa8a90000), SPH_C32(0x6ac40000), + SPH_C32(0x8daf0240), SPH_C32(0xcdb63c93), SPH_C32(0xd7ffd112), + SPH_C32(0x90b053ae), SPH_C32(0xda2bec31), SPH_C32(0xb11f0000), + SPH_C32(0x86b90000), SPH_C32(0x9e1b0000), SPH_C32(0x13f20660), + SPH_C32(0x8e795b9a), SPH_C32(0xc40444d6), SPH_C32(0x8906793b), + SPH_C32(0xc2e32970) }, + { SPH_C32(0x57370000), SPH_C32(0xcaf20000), SPH_C32(0x364e0000), + SPH_C32(0xc0220480), SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), + SPH_C32(0xa1937f8f), SPH_C32(0x15b961e7), SPH_C32(0xb4310000), + SPH_C32(0x77330000), SPH_C32(0xb15d0000), SPH_C32(0x7fd004e0), + SPH_C32(0x78a26138), SPH_C32(0xd116c35d), SPH_C32(0xd256d489), + SPH_C32(0x4e6f74de) }, + { SPH_C32(0xb11f0000), SPH_C32(0x86b90000), SPH_C32(0x9e1b0000), + SPH_C32(0x13f20660), SPH_C32(0x8e795b9a), SPH_C32(0xc40444d6), + SPH_C32(0x8906793b), SPH_C32(0xc2e32970), SPH_C32(0x44f40000), + SPH_C32(0x2e100000), SPH_C32(0xf4df0000), SPH_C32(0x9e5d0420), + SPH_C32(0x43cf6709), SPH_C32(0x13fb95c4), SPH_C32(0x19b62a95), + SPH_C32(0x18c8c541) }, + { SPH_C32(0xa7f20000), SPH_C32(0x93d10000), SPH_C32(0x73cc0000), + SPH_C32(0x21af0440), SPH_C32(0x6d756d13), SPH_C32(0x9e4ea295), + SPH_C32(0x6a738193), SPH_C32(0x431ed078), SPH_C32(0xa2dc0000), + SPH_C32(0x625b0000), SPH_C32(0x5c8a0000), SPH_C32(0x4d8d06c0), + SPH_C32(0x9bae57b1), SPH_C32(0x8b5c251e), SPH_C32(0x31232c21), + SPH_C32(0xcf928dd6) }, + { SPH_C32(0x41da0000), SPH_C32(0xdf9a0000), SPH_C32(0xdb990000), + SPH_C32(0xf27f06a0), SPH_C32(0xb5145dab), SPH_C32(0x06e9124f), + SPH_C32(0x42e68727), SPH_C32(0x944498ef), SPH_C32(0x52190000), + SPH_C32(0x3b780000), SPH_C32(0x19080000), SPH_C32(0xac000600), + SPH_C32(0xa0c35180), SPH_C32(0x49b17387), SPH_C32(0xfac3d23d), + SPH_C32(0x99353c49) }, + { SPH_C32(0x02f20000), SPH_C32(0xa2810000), SPH_C32(0x873f0000), + SPH_C32(0xe36c7800), SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), + SPH_C32(0xc4c23237), SPH_C32(0x7f32259e), SPH_C32(0xbadd0000), + SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), SPH_C32(0xf7282800), + SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), SPH_C32(0xea5a8d14), + SPH_C32(0x2a2c18f0) }, + { SPH_C32(0xe4da0000), SPH_C32(0xeeca0000), SPH_C32(0x2f6a0000), + SPH_C32(0x30bc7ae0), SPH_C32(0xc67c4457), SPH_C32(0x9f9a9b0c), + SPH_C32(0xec573483), SPH_C32(0xa8686d09), SPH_C32(0x4a180000), + SPH_C32(0x4a8e0000), SPH_C32(0xf2650000), SPH_C32(0x16a528c0), + SPH_C32(0xe428127c), SPH_C32(0xf4f795a3), SPH_C32(0x21ba7308), + SPH_C32(0x7c8ba96f) }, + { SPH_C32(0xf2370000), SPH_C32(0xfba20000), SPH_C32(0xc2bd0000), + SPH_C32(0x02e178c0), SPH_C32(0x257072de), SPH_C32(0xc5d07d4f), + SPH_C32(0x0f22cc2b), SPH_C32(0x29959401), SPH_C32(0xac300000), + SPH_C32(0x06c50000), SPH_C32(0x5a300000), SPH_C32(0xc5752a20), + SPH_C32(0x3c4922c4), SPH_C32(0x6c502579), SPH_C32(0x092f75bc), + SPH_C32(0xabd1e1f8) }, + { SPH_C32(0x141f0000), SPH_C32(0xb7e90000), SPH_C32(0x6ae80000), + SPH_C32(0xd1317a20), SPH_C32(0xfd114266), SPH_C32(0x5d77cd95), + SPH_C32(0x27b7ca9f), SPH_C32(0xfecfdc96), SPH_C32(0x5cf50000), + SPH_C32(0x5fe60000), SPH_C32(0x1fb20000), SPH_C32(0x24f82ae0), + SPH_C32(0x072424f5), SPH_C32(0xaebd73e0), SPH_C32(0xc2cf8ba0), + SPH_C32(0xfd765067) }, + { SPH_C32(0xb6c30000), SPH_C32(0xd5b20000), SPH_C32(0x36620000), + SPH_C32(0x9cbc7ce0), SPH_C32(0x66bf15d7), SPH_C32(0xd62be88b), + SPH_C32(0x1694e6be), SPH_C32(0x315d5140), SPH_C32(0x59db0000), + SPH_C32(0xae6c0000), SPH_C32(0x30f40000), SPH_C32(0x48da2860), + SPH_C32(0xf1ff1e57), SPH_C32(0xbbaff46b), SPH_C32(0x999f2612), + SPH_C32(0x71fa0dc9) }, + { SPH_C32(0x50eb0000), SPH_C32(0x99f90000), SPH_C32(0x9e370000), + SPH_C32(0x4f6c7e00), SPH_C32(0xbede256f), SPH_C32(0x4e8c5851), + SPH_C32(0x3e01e00a), SPH_C32(0xe60719d7), SPH_C32(0xa91e0000), + SPH_C32(0xf74f0000), SPH_C32(0x75760000), SPH_C32(0xa95728a0), + SPH_C32(0xca921866), SPH_C32(0x7942a2f2), SPH_C32(0x527fd80e), + SPH_C32(0x275dbc56) }, + { SPH_C32(0x46060000), SPH_C32(0x8c910000), SPH_C32(0x73e00000), + SPH_C32(0x7d317c20), SPH_C32(0x5dd213e6), SPH_C32(0x14c6be12), + SPH_C32(0xdd7418a2), SPH_C32(0x67fae0df), SPH_C32(0x4f360000), + SPH_C32(0xbb040000), SPH_C32(0xdd230000), SPH_C32(0x7a872a40), + SPH_C32(0x12f328de), SPH_C32(0xe1e51228), SPH_C32(0x7aeadeba), + SPH_C32(0xf007f4c1) }, + { SPH_C32(0xa02e0000), SPH_C32(0xc0da0000), SPH_C32(0xdbb50000), + SPH_C32(0xaee17ec0), SPH_C32(0x85b3235e), SPH_C32(0x8c610ec8), + SPH_C32(0xf5e11e16), SPH_C32(0xb0a0a848), SPH_C32(0xbff30000), + SPH_C32(0xe2270000), SPH_C32(0x98a10000), SPH_C32(0x9b0a2a80), + SPH_C32(0x299e2eef), SPH_C32(0x230844b1), SPH_C32(0xb10a20a6), + SPH_C32(0xa6a0455e) }, + { SPH_C32(0xe1f40000), SPH_C32(0x1f400000), SPH_C32(0x002c0000), + SPH_C32(0x5c9e7860), SPH_C32(0x30a77ef5), SPH_C32(0x8a881c87), + SPH_C32(0xb7079931), SPH_C32(0x24e430a7), SPH_C32(0xedea0000), + SPH_C32(0xd95f0000), SPH_C32(0x81a90000), SPH_C32(0x370a2c80), + SPH_C32(0x895d7f6f), SPH_C32(0x6ab93736), SPH_C32(0x4bc9f29b), + SPH_C32(0x3f957917) }, + { SPH_C32(0x07dc0000), SPH_C32(0x530b0000), SPH_C32(0xa8790000), + SPH_C32(0x8f4e7a80), SPH_C32(0xe8c64e4d), SPH_C32(0x122fac5d), + SPH_C32(0x9f929f85), SPH_C32(0xf3be7830), SPH_C32(0x1d2f0000), + SPH_C32(0x807c0000), SPH_C32(0xc42b0000), SPH_C32(0xd6872c40), + SPH_C32(0xb230795e), SPH_C32(0xa85461af), SPH_C32(0x80290c87), + SPH_C32(0x6932c888) }, + { SPH_C32(0x11310000), SPH_C32(0x46630000), SPH_C32(0x45ae0000), + SPH_C32(0xbd1378a0), SPH_C32(0x0bca78c4), SPH_C32(0x48654a1e), + SPH_C32(0x7ce7672d), SPH_C32(0x72438138), SPH_C32(0xfb070000), + SPH_C32(0xcc370000), SPH_C32(0x6c7e0000), SPH_C32(0x05572ea0), + SPH_C32(0x6a5149e6), SPH_C32(0x30f3d175), SPH_C32(0xa8bc0a33), + SPH_C32(0xbe68801f) }, + { SPH_C32(0xf7190000), SPH_C32(0x0a280000), SPH_C32(0xedfb0000), + SPH_C32(0x6ec37a40), SPH_C32(0xd3ab487c), SPH_C32(0xd0c2fac4), + SPH_C32(0x54726199), SPH_C32(0xa519c9af), SPH_C32(0x0bc20000), + SPH_C32(0x95140000), SPH_C32(0x29fc0000), SPH_C32(0xe4da2e60), + SPH_C32(0x513c4fd7), SPH_C32(0xf21e87ec), SPH_C32(0x635cf42f), + SPH_C32(0xe8cf3180) }, + { SPH_C32(0x55c50000), SPH_C32(0x68730000), SPH_C32(0xb1710000), + SPH_C32(0x234e7c80), SPH_C32(0x48051fcd), SPH_C32(0x5b9edfda), + SPH_C32(0x65514db8), SPH_C32(0x6a8b4479), SPH_C32(0x0eec0000), + SPH_C32(0x649e0000), SPH_C32(0x06ba0000), SPH_C32(0x88f82ce0), + SPH_C32(0xa7e77575), SPH_C32(0xe70c0067), SPH_C32(0x380c599d), + SPH_C32(0x64436c2e) }, + { SPH_C32(0xb3ed0000), SPH_C32(0x24380000), SPH_C32(0x19240000), + SPH_C32(0xf09e7e60), SPH_C32(0x90642f75), SPH_C32(0xc3396f00), + SPH_C32(0x4dc44b0c), SPH_C32(0xbdd10cee), SPH_C32(0xfe290000), + SPH_C32(0x3dbd0000), SPH_C32(0x43380000), SPH_C32(0x69752c20), + SPH_C32(0x9c8a7344), SPH_C32(0x25e156fe), SPH_C32(0xf3eca781), + SPH_C32(0x32e4ddb1) }, + { SPH_C32(0xa5000000), SPH_C32(0x31500000), SPH_C32(0xf4f30000), + SPH_C32(0xc2c37c40), SPH_C32(0x736819fc), SPH_C32(0x99738943), + SPH_C32(0xaeb1b3a4), SPH_C32(0x3c2cf5e6), SPH_C32(0x18010000), + SPH_C32(0x71f60000), SPH_C32(0xeb6d0000), SPH_C32(0xbaa52ec0), + SPH_C32(0x44eb43fc), SPH_C32(0xbd46e624), SPH_C32(0xdb79a135), + SPH_C32(0xe5be9526) }, + { SPH_C32(0x43280000), SPH_C32(0x7d1b0000), SPH_C32(0x5ca60000), + SPH_C32(0x11137ea0), SPH_C32(0xab092944), SPH_C32(0x01d43999), + SPH_C32(0x8624b510), SPH_C32(0xeb76bd71), SPH_C32(0xe8c40000), + SPH_C32(0x28d50000), SPH_C32(0xaeef0000), SPH_C32(0x5b282e00), + SPH_C32(0x7f8645cd), SPH_C32(0x7fabb0bd), SPH_C32(0x10995f29), + SPH_C32(0xb31924b9) }, + { SPH_C32(0xbadd0000), SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), + SPH_C32(0xf7282800), SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), + SPH_C32(0xea5a8d14), SPH_C32(0x2a2c18f0), SPH_C32(0xb82f0000), + SPH_C32(0xb12c0000), SPH_C32(0x30d80000), SPH_C32(0x14445000), + SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), SPH_C32(0x2e98bf23), + SPH_C32(0x551e3d6e) }, + { SPH_C32(0x5cf50000), SPH_C32(0x5fe60000), SPH_C32(0x1fb20000), + SPH_C32(0x24f82ae0), SPH_C32(0x072424f5), SPH_C32(0xaebd73e0), + SPH_C32(0xc2cf8ba0), SPH_C32(0xfd765067), SPH_C32(0x48ea0000), + SPH_C32(0xe80f0000), SPH_C32(0x755a0000), SPH_C32(0xf5c950c0), + SPH_C32(0xfa356693), SPH_C32(0xf3cabe75), SPH_C32(0xe578413f), + SPH_C32(0x03b98cf1) }, + { SPH_C32(0x4a180000), SPH_C32(0x4a8e0000), SPH_C32(0xf2650000), + SPH_C32(0x16a528c0), SPH_C32(0xe428127c), SPH_C32(0xf4f795a3), + SPH_C32(0x21ba7308), SPH_C32(0x7c8ba96f), SPH_C32(0xaec20000), + SPH_C32(0xa4440000), SPH_C32(0xdd0f0000), SPH_C32(0x26195220), + SPH_C32(0x2254562b), SPH_C32(0x6b6d0eaf), SPH_C32(0xcded478b), + SPH_C32(0xd4e3c466) }, + { SPH_C32(0xac300000), SPH_C32(0x06c50000), SPH_C32(0x5a300000), + SPH_C32(0xc5752a20), SPH_C32(0x3c4922c4), SPH_C32(0x6c502579), + SPH_C32(0x092f75bc), SPH_C32(0xabd1e1f8), SPH_C32(0x5e070000), + SPH_C32(0xfd670000), SPH_C32(0x988d0000), SPH_C32(0xc79452e0), + SPH_C32(0x1939501a), SPH_C32(0xa9805836), SPH_C32(0x060db997), + SPH_C32(0x824475f9) }, + { SPH_C32(0x0eec0000), SPH_C32(0x649e0000), SPH_C32(0x06ba0000), + SPH_C32(0x88f82ce0), SPH_C32(0xa7e77575), SPH_C32(0xe70c0067), + SPH_C32(0x380c599d), SPH_C32(0x64436c2e), SPH_C32(0x5b290000), + SPH_C32(0x0ced0000), SPH_C32(0xb7cb0000), SPH_C32(0xabb65060), + SPH_C32(0xefe26ab8), SPH_C32(0xbc92dfbd), SPH_C32(0x5d5d1425), + SPH_C32(0x0ec82857) }, + { SPH_C32(0xe8c40000), SPH_C32(0x28d50000), SPH_C32(0xaeef0000), + SPH_C32(0x5b282e00), SPH_C32(0x7f8645cd), SPH_C32(0x7fabb0bd), + SPH_C32(0x10995f29), SPH_C32(0xb31924b9), SPH_C32(0xabec0000), + SPH_C32(0x55ce0000), SPH_C32(0xf2490000), SPH_C32(0x4a3b50a0), + SPH_C32(0xd48f6c89), SPH_C32(0x7e7f8924), SPH_C32(0x96bdea39), + SPH_C32(0x586f99c8) }, + { SPH_C32(0xfe290000), SPH_C32(0x3dbd0000), SPH_C32(0x43380000), + SPH_C32(0x69752c20), SPH_C32(0x9c8a7344), SPH_C32(0x25e156fe), + SPH_C32(0xf3eca781), SPH_C32(0x32e4ddb1), SPH_C32(0x4dc40000), + SPH_C32(0x19850000), SPH_C32(0x5a1c0000), SPH_C32(0x99eb5240), + SPH_C32(0x0cee5c31), SPH_C32(0xe6d839fe), SPH_C32(0xbe28ec8d), + SPH_C32(0x8f35d15f) }, + { SPH_C32(0x18010000), SPH_C32(0x71f60000), SPH_C32(0xeb6d0000), + SPH_C32(0xbaa52ec0), SPH_C32(0x44eb43fc), SPH_C32(0xbd46e624), + SPH_C32(0xdb79a135), SPH_C32(0xe5be9526), SPH_C32(0xbd010000), + SPH_C32(0x40a60000), SPH_C32(0x1f9e0000), SPH_C32(0x78665280), + SPH_C32(0x37835a00), SPH_C32(0x24356f67), SPH_C32(0x75c81291), + SPH_C32(0xd99260c0) }, + { SPH_C32(0x59db0000), SPH_C32(0xae6c0000), SPH_C32(0x30f40000), + SPH_C32(0x48da2860), SPH_C32(0xf1ff1e57), SPH_C32(0xbbaff46b), + SPH_C32(0x999f2612), SPH_C32(0x71fa0dc9), SPH_C32(0xef180000), + SPH_C32(0x7bde0000), SPH_C32(0x06960000), SPH_C32(0xd4665480), + SPH_C32(0x97400b80), SPH_C32(0x6d841ce0), SPH_C32(0x8f0bc0ac), + SPH_C32(0x40a75c89) }, + { SPH_C32(0xbff30000), SPH_C32(0xe2270000), SPH_C32(0x98a10000), + SPH_C32(0x9b0a2a80), SPH_C32(0x299e2eef), SPH_C32(0x230844b1), + SPH_C32(0xb10a20a6), SPH_C32(0xa6a0455e), SPH_C32(0x1fdd0000), + SPH_C32(0x22fd0000), SPH_C32(0x43140000), SPH_C32(0x35eb5440), + SPH_C32(0xac2d0db1), SPH_C32(0xaf694a79), SPH_C32(0x44eb3eb0), + SPH_C32(0x1600ed16) }, + { SPH_C32(0xa91e0000), SPH_C32(0xf74f0000), SPH_C32(0x75760000), + SPH_C32(0xa95728a0), SPH_C32(0xca921866), SPH_C32(0x7942a2f2), + SPH_C32(0x527fd80e), SPH_C32(0x275dbc56), SPH_C32(0xf9f50000), + SPH_C32(0x6eb60000), SPH_C32(0xeb410000), SPH_C32(0xe63b56a0), + SPH_C32(0x744c3d09), SPH_C32(0x37cefaa3), SPH_C32(0x6c7e3804), + SPH_C32(0xc15aa581) }, + { SPH_C32(0x4f360000), SPH_C32(0xbb040000), SPH_C32(0xdd230000), + SPH_C32(0x7a872a40), SPH_C32(0x12f328de), SPH_C32(0xe1e51228), + SPH_C32(0x7aeadeba), SPH_C32(0xf007f4c1), SPH_C32(0x09300000), + SPH_C32(0x37950000), SPH_C32(0xaec30000), SPH_C32(0x07b65660), + SPH_C32(0x4f213b38), SPH_C32(0xf523ac3a), SPH_C32(0xa79ec618), + SPH_C32(0x97fd141e) }, + { SPH_C32(0xedea0000), SPH_C32(0xd95f0000), SPH_C32(0x81a90000), + SPH_C32(0x370a2c80), SPH_C32(0x895d7f6f), SPH_C32(0x6ab93736), + SPH_C32(0x4bc9f29b), SPH_C32(0x3f957917), SPH_C32(0x0c1e0000), + SPH_C32(0xc61f0000), SPH_C32(0x81850000), SPH_C32(0x6b9454e0), + SPH_C32(0xb9fa019a), SPH_C32(0xe0312bb1), SPH_C32(0xfcce6baa), + SPH_C32(0x1b7149b0) }, + { SPH_C32(0x0bc20000), SPH_C32(0x95140000), SPH_C32(0x29fc0000), + SPH_C32(0xe4da2e60), SPH_C32(0x513c4fd7), SPH_C32(0xf21e87ec), + SPH_C32(0x635cf42f), SPH_C32(0xe8cf3180), SPH_C32(0xfcdb0000), + SPH_C32(0x9f3c0000), SPH_C32(0xc4070000), SPH_C32(0x8a195420), + SPH_C32(0x829707ab), SPH_C32(0x22dc7d28), SPH_C32(0x372e95b6), + SPH_C32(0x4dd6f82f) }, + { SPH_C32(0x1d2f0000), SPH_C32(0x807c0000), SPH_C32(0xc42b0000), + SPH_C32(0xd6872c40), SPH_C32(0xb230795e), SPH_C32(0xa85461af), + SPH_C32(0x80290c87), SPH_C32(0x6932c888), SPH_C32(0x1af30000), + SPH_C32(0xd3770000), SPH_C32(0x6c520000), SPH_C32(0x59c956c0), + SPH_C32(0x5af63713), SPH_C32(0xba7bcdf2), SPH_C32(0x1fbb9302), + SPH_C32(0x9a8cb0b8) }, + { SPH_C32(0xfb070000), SPH_C32(0xcc370000), SPH_C32(0x6c7e0000), + SPH_C32(0x05572ea0), SPH_C32(0x6a5149e6), SPH_C32(0x30f3d175), + SPH_C32(0xa8bc0a33), SPH_C32(0xbe68801f), SPH_C32(0xea360000), + SPH_C32(0x8a540000), SPH_C32(0x29d00000), SPH_C32(0xb8445600), + SPH_C32(0x619b3122), SPH_C32(0x78969b6b), SPH_C32(0xd45b6d1e), + SPH_C32(0xcc2b0127) }, + { SPH_C32(0xb82f0000), SPH_C32(0xb12c0000), SPH_C32(0x30d80000), + SPH_C32(0x14445000), SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), + SPH_C32(0x2e98bf23), SPH_C32(0x551e3d6e), SPH_C32(0x02f20000), + SPH_C32(0xa2810000), SPH_C32(0x873f0000), SPH_C32(0xe36c7800), + SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), SPH_C32(0xc4c23237), + SPH_C32(0x7f32259e) }, + { SPH_C32(0x5e070000), SPH_C32(0xfd670000), SPH_C32(0x988d0000), + SPH_C32(0xc79452e0), SPH_C32(0x1939501a), SPH_C32(0xa9805836), + SPH_C32(0x060db997), SPH_C32(0x824475f9), SPH_C32(0xf2370000), + SPH_C32(0xfba20000), SPH_C32(0xc2bd0000), SPH_C32(0x02e178c0), + SPH_C32(0x257072de), SPH_C32(0xc5d07d4f), SPH_C32(0x0f22cc2b), + SPH_C32(0x29959401) }, + { SPH_C32(0x48ea0000), SPH_C32(0xe80f0000), SPH_C32(0x755a0000), + SPH_C32(0xf5c950c0), SPH_C32(0xfa356693), SPH_C32(0xf3cabe75), + SPH_C32(0xe578413f), SPH_C32(0x03b98cf1), SPH_C32(0x141f0000), + SPH_C32(0xb7e90000), SPH_C32(0x6ae80000), SPH_C32(0xd1317a20), + SPH_C32(0xfd114266), SPH_C32(0x5d77cd95), SPH_C32(0x27b7ca9f), + SPH_C32(0xfecfdc96) }, + { SPH_C32(0xaec20000), SPH_C32(0xa4440000), SPH_C32(0xdd0f0000), + SPH_C32(0x26195220), SPH_C32(0x2254562b), SPH_C32(0x6b6d0eaf), + SPH_C32(0xcded478b), SPH_C32(0xd4e3c466), SPH_C32(0xe4da0000), + SPH_C32(0xeeca0000), SPH_C32(0x2f6a0000), SPH_C32(0x30bc7ae0), + SPH_C32(0xc67c4457), SPH_C32(0x9f9a9b0c), SPH_C32(0xec573483), + SPH_C32(0xa8686d09) }, + { SPH_C32(0x0c1e0000), SPH_C32(0xc61f0000), SPH_C32(0x81850000), + SPH_C32(0x6b9454e0), SPH_C32(0xb9fa019a), SPH_C32(0xe0312bb1), + SPH_C32(0xfcce6baa), SPH_C32(0x1b7149b0), SPH_C32(0xe1f40000), + SPH_C32(0x1f400000), SPH_C32(0x002c0000), SPH_C32(0x5c9e7860), + SPH_C32(0x30a77ef5), SPH_C32(0x8a881c87), SPH_C32(0xb7079931), + SPH_C32(0x24e430a7) }, + { SPH_C32(0xea360000), SPH_C32(0x8a540000), SPH_C32(0x29d00000), + SPH_C32(0xb8445600), SPH_C32(0x619b3122), SPH_C32(0x78969b6b), + SPH_C32(0xd45b6d1e), SPH_C32(0xcc2b0127), SPH_C32(0x11310000), + SPH_C32(0x46630000), SPH_C32(0x45ae0000), SPH_C32(0xbd1378a0), + SPH_C32(0x0bca78c4), SPH_C32(0x48654a1e), SPH_C32(0x7ce7672d), + SPH_C32(0x72438138) }, + { SPH_C32(0xfcdb0000), SPH_C32(0x9f3c0000), SPH_C32(0xc4070000), + SPH_C32(0x8a195420), SPH_C32(0x829707ab), SPH_C32(0x22dc7d28), + SPH_C32(0x372e95b6), SPH_C32(0x4dd6f82f), SPH_C32(0xf7190000), + SPH_C32(0x0a280000), SPH_C32(0xedfb0000), SPH_C32(0x6ec37a40), + SPH_C32(0xd3ab487c), SPH_C32(0xd0c2fac4), SPH_C32(0x54726199), + SPH_C32(0xa519c9af) }, + { SPH_C32(0x1af30000), SPH_C32(0xd3770000), SPH_C32(0x6c520000), + SPH_C32(0x59c956c0), SPH_C32(0x5af63713), SPH_C32(0xba7bcdf2), + SPH_C32(0x1fbb9302), SPH_C32(0x9a8cb0b8), SPH_C32(0x07dc0000), + SPH_C32(0x530b0000), SPH_C32(0xa8790000), SPH_C32(0x8f4e7a80), + SPH_C32(0xe8c64e4d), SPH_C32(0x122fac5d), SPH_C32(0x9f929f85), + SPH_C32(0xf3be7830) }, + { SPH_C32(0x5b290000), SPH_C32(0x0ced0000), SPH_C32(0xb7cb0000), + SPH_C32(0xabb65060), SPH_C32(0xefe26ab8), SPH_C32(0xbc92dfbd), + SPH_C32(0x5d5d1425), SPH_C32(0x0ec82857), SPH_C32(0x55c50000), + SPH_C32(0x68730000), SPH_C32(0xb1710000), SPH_C32(0x234e7c80), + SPH_C32(0x48051fcd), SPH_C32(0x5b9edfda), SPH_C32(0x65514db8), + SPH_C32(0x6a8b4479) }, + { SPH_C32(0xbd010000), SPH_C32(0x40a60000), SPH_C32(0x1f9e0000), + SPH_C32(0x78665280), SPH_C32(0x37835a00), SPH_C32(0x24356f67), + SPH_C32(0x75c81291), SPH_C32(0xd99260c0), SPH_C32(0xa5000000), + SPH_C32(0x31500000), SPH_C32(0xf4f30000), SPH_C32(0xc2c37c40), + SPH_C32(0x736819fc), SPH_C32(0x99738943), SPH_C32(0xaeb1b3a4), + SPH_C32(0x3c2cf5e6) }, + { SPH_C32(0xabec0000), SPH_C32(0x55ce0000), SPH_C32(0xf2490000), + SPH_C32(0x4a3b50a0), SPH_C32(0xd48f6c89), SPH_C32(0x7e7f8924), + SPH_C32(0x96bdea39), SPH_C32(0x586f99c8), SPH_C32(0x43280000), + SPH_C32(0x7d1b0000), SPH_C32(0x5ca60000), SPH_C32(0x11137ea0), + SPH_C32(0xab092944), SPH_C32(0x01d43999), SPH_C32(0x8624b510), + SPH_C32(0xeb76bd71) }, + { SPH_C32(0x4dc40000), SPH_C32(0x19850000), SPH_C32(0x5a1c0000), + SPH_C32(0x99eb5240), SPH_C32(0x0cee5c31), SPH_C32(0xe6d839fe), + SPH_C32(0xbe28ec8d), SPH_C32(0x8f35d15f), SPH_C32(0xb3ed0000), + SPH_C32(0x24380000), SPH_C32(0x19240000), SPH_C32(0xf09e7e60), + SPH_C32(0x90642f75), SPH_C32(0xc3396f00), SPH_C32(0x4dc44b0c), + SPH_C32(0xbdd10cee) }, + { SPH_C32(0xef180000), SPH_C32(0x7bde0000), SPH_C32(0x06960000), + SPH_C32(0xd4665480), SPH_C32(0x97400b80), SPH_C32(0x6d841ce0), + SPH_C32(0x8f0bc0ac), SPH_C32(0x40a75c89), SPH_C32(0xb6c30000), + SPH_C32(0xd5b20000), SPH_C32(0x36620000), SPH_C32(0x9cbc7ce0), + SPH_C32(0x66bf15d7), SPH_C32(0xd62be88b), SPH_C32(0x1694e6be), + SPH_C32(0x315d5140) }, + { SPH_C32(0x09300000), SPH_C32(0x37950000), SPH_C32(0xaec30000), + SPH_C32(0x07b65660), SPH_C32(0x4f213b38), SPH_C32(0xf523ac3a), + SPH_C32(0xa79ec618), SPH_C32(0x97fd141e), SPH_C32(0x46060000), + SPH_C32(0x8c910000), SPH_C32(0x73e00000), SPH_C32(0x7d317c20), + SPH_C32(0x5dd213e6), SPH_C32(0x14c6be12), SPH_C32(0xdd7418a2), + SPH_C32(0x67fae0df) }, + { SPH_C32(0x1fdd0000), SPH_C32(0x22fd0000), SPH_C32(0x43140000), + SPH_C32(0x35eb5440), SPH_C32(0xac2d0db1), SPH_C32(0xaf694a79), + SPH_C32(0x44eb3eb0), SPH_C32(0x1600ed16), SPH_C32(0xa02e0000), + SPH_C32(0xc0da0000), SPH_C32(0xdbb50000), SPH_C32(0xaee17ec0), + SPH_C32(0x85b3235e), SPH_C32(0x8c610ec8), SPH_C32(0xf5e11e16), + SPH_C32(0xb0a0a848) }, + { SPH_C32(0xf9f50000), SPH_C32(0x6eb60000), SPH_C32(0xeb410000), + SPH_C32(0xe63b56a0), SPH_C32(0x744c3d09), SPH_C32(0x37cefaa3), + SPH_C32(0x6c7e3804), SPH_C32(0xc15aa581), SPH_C32(0x50eb0000), + SPH_C32(0x99f90000), SPH_C32(0x9e370000), SPH_C32(0x4f6c7e00), + SPH_C32(0xbede256f), SPH_C32(0x4e8c5851), SPH_C32(0x3e01e00a), + SPH_C32(0xe60719d7) }, + { SPH_C32(0x1e6c0000), SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), + SPH_C32(0xbcb6b800), SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), + SPH_C32(0x6a0c1bc8), SPH_C32(0xb99dc2eb), SPH_C32(0x92560000), + SPH_C32(0x1eda0000), SPH_C32(0xea510000), SPH_C32(0xe8b13000), + SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), SPH_C32(0xb15c2254), + SPH_C32(0x33c5244f) }, + { SPH_C32(0xf8440000), SPH_C32(0x88090000), SPH_C32(0x227b0000), + SPH_C32(0x6f66bae0), SPH_C32(0xf425230e), SPH_C32(0x135a6300), + SPH_C32(0x42991d7c), SPH_C32(0x6ec78a7c), SPH_C32(0x62930000), + SPH_C32(0x47f90000), SPH_C32(0xafd30000), SPH_C32(0x093c30c0), + SPH_C32(0x92585094), SPH_C32(0x29163700), SPH_C32(0x7abcdc48), + SPH_C32(0x656295d0) }, + { SPH_C32(0xeea90000), SPH_C32(0x9d610000), SPH_C32(0xcfac0000), + SPH_C32(0x5d3bb8c0), SPH_C32(0x17291587), SPH_C32(0x49108543), + SPH_C32(0xa1ece5d4), SPH_C32(0xef3a7374), SPH_C32(0x84bb0000), + SPH_C32(0x0bb20000), SPH_C32(0x07860000), SPH_C32(0xdaec3220), + SPH_C32(0x4a39602c), SPH_C32(0xb1b187da), SPH_C32(0x5229dafc), + SPH_C32(0xb238dd47) }, + { SPH_C32(0x08810000), SPH_C32(0xd12a0000), SPH_C32(0x67f90000), + SPH_C32(0x8eebba20), SPH_C32(0xcf48253f), SPH_C32(0xd1b73599), + SPH_C32(0x8979e360), SPH_C32(0x38603be3), SPH_C32(0x747e0000), + SPH_C32(0x52910000), SPH_C32(0x42040000), SPH_C32(0x3b6132e0), + SPH_C32(0x7154661d), SPH_C32(0x735cd143), SPH_C32(0x99c924e0), + SPH_C32(0xe49f6cd8) }, + { SPH_C32(0xaa5d0000), SPH_C32(0xb3710000), SPH_C32(0x3b730000), + SPH_C32(0xc366bce0), SPH_C32(0x54e6728e), SPH_C32(0x5aeb1087), + SPH_C32(0xb85acf41), SPH_C32(0xf7f2b635), SPH_C32(0x71500000), + SPH_C32(0xa31b0000), SPH_C32(0x6d420000), SPH_C32(0x57433060), + SPH_C32(0x878f5cbf), SPH_C32(0x664e56c8), SPH_C32(0xc2998952), + SPH_C32(0x68133176) }, + { SPH_C32(0x4c750000), SPH_C32(0xff3a0000), SPH_C32(0x93260000), + SPH_C32(0x10b6be00), SPH_C32(0x8c874236), SPH_C32(0xc24ca05d), + SPH_C32(0x90cfc9f5), SPH_C32(0x20a8fea2), SPH_C32(0x81950000), + SPH_C32(0xfa380000), SPH_C32(0x28c00000), SPH_C32(0xb6ce30a0), + SPH_C32(0xbce25a8e), SPH_C32(0xa4a30051), SPH_C32(0x0979774e), + SPH_C32(0x3eb480e9) }, + { SPH_C32(0x5a980000), SPH_C32(0xea520000), SPH_C32(0x7ef10000), + SPH_C32(0x22ebbc20), SPH_C32(0x6f8b74bf), SPH_C32(0x9806461e), + SPH_C32(0x73ba315d), SPH_C32(0xa15507aa), SPH_C32(0x67bd0000), + SPH_C32(0xb6730000), SPH_C32(0x80950000), SPH_C32(0x651e3240), + SPH_C32(0x64836a36), SPH_C32(0x3c04b08b), SPH_C32(0x21ec71fa), + SPH_C32(0xe9eec87e) }, + { SPH_C32(0xbcb00000), SPH_C32(0xa6190000), SPH_C32(0xd6a40000), + SPH_C32(0xf13bbec0), SPH_C32(0xb7ea4407), SPH_C32(0x00a1f6c4), + SPH_C32(0x5b2f37e9), SPH_C32(0x760f4f3d), SPH_C32(0x97780000), + SPH_C32(0xef500000), SPH_C32(0xc5170000), SPH_C32(0x84933280), + SPH_C32(0x5fee6c07), SPH_C32(0xfee9e612), SPH_C32(0xea0c8fe6), + SPH_C32(0xbf4979e1) }, + { SPH_C32(0xfd6a0000), SPH_C32(0x79830000), SPH_C32(0x0d3d0000), + SPH_C32(0x0344b860), SPH_C32(0x02fe19ac), SPH_C32(0x0648e48b), + SPH_C32(0x19c9b0ce), SPH_C32(0xe24bd7d2), SPH_C32(0xc5610000), + SPH_C32(0xd4280000), SPH_C32(0xdc1f0000), SPH_C32(0x28933480), + SPH_C32(0xff2d3d87), SPH_C32(0xb7589595), SPH_C32(0x10cf5ddb), + SPH_C32(0x267c45a8) }, + { SPH_C32(0x1b420000), SPH_C32(0x35c80000), SPH_C32(0xa5680000), + SPH_C32(0xd094ba80), SPH_C32(0xda9f2914), SPH_C32(0x9eef5451), + SPH_C32(0x315cb67a), SPH_C32(0x35119f45), SPH_C32(0x35a40000), + SPH_C32(0x8d0b0000), SPH_C32(0x999d0000), SPH_C32(0xc91e3440), + SPH_C32(0xc4403bb6), SPH_C32(0x75b5c30c), SPH_C32(0xdb2fa3c7), + SPH_C32(0x70dbf437) }, + { SPH_C32(0x0daf0000), SPH_C32(0x20a00000), SPH_C32(0x48bf0000), + SPH_C32(0xe2c9b8a0), SPH_C32(0x39931f9d), SPH_C32(0xc4a5b212), + SPH_C32(0xd2294ed2), SPH_C32(0xb4ec664d), SPH_C32(0xd38c0000), + SPH_C32(0xc1400000), SPH_C32(0x31c80000), SPH_C32(0x1ace36a0), + SPH_C32(0x1c210b0e), SPH_C32(0xed1273d6), SPH_C32(0xf3baa573), + SPH_C32(0xa781bca0) }, + { SPH_C32(0xeb870000), SPH_C32(0x6ceb0000), SPH_C32(0xe0ea0000), + SPH_C32(0x3119ba40), SPH_C32(0xe1f22f25), SPH_C32(0x5c0202c8), + SPH_C32(0xfabc4866), SPH_C32(0x63b62eda), SPH_C32(0x23490000), + SPH_C32(0x98630000), SPH_C32(0x744a0000), SPH_C32(0xfb433660), + SPH_C32(0x274c0d3f), SPH_C32(0x2fff254f), SPH_C32(0x385a5b6f), + SPH_C32(0xf1260d3f) }, + { SPH_C32(0x495b0000), SPH_C32(0x0eb00000), SPH_C32(0xbc600000), + SPH_C32(0x7c94bc80), SPH_C32(0x7a5c7894), SPH_C32(0xd75e27d6), + SPH_C32(0xcb9f6447), SPH_C32(0xac24a30c), SPH_C32(0x26670000), + SPH_C32(0x69e90000), SPH_C32(0x5b0c0000), SPH_C32(0x976134e0), + SPH_C32(0xd197379d), SPH_C32(0x3aeda2c4), SPH_C32(0x630af6dd), + SPH_C32(0x7daa5091) }, + { SPH_C32(0xaf730000), SPH_C32(0x42fb0000), SPH_C32(0x14350000), + SPH_C32(0xaf44be60), SPH_C32(0xa23d482c), SPH_C32(0x4ff9970c), + SPH_C32(0xe30a62f3), SPH_C32(0x7b7eeb9b), SPH_C32(0xd6a20000), + SPH_C32(0x30ca0000), SPH_C32(0x1e8e0000), SPH_C32(0x76ec3420), + SPH_C32(0xeafa31ac), SPH_C32(0xf800f45d), SPH_C32(0xa8ea08c1), + SPH_C32(0x2b0de10e) }, + { SPH_C32(0xb99e0000), SPH_C32(0x57930000), SPH_C32(0xf9e20000), + SPH_C32(0x9d19bc40), SPH_C32(0x41317ea5), SPH_C32(0x15b3714f), + SPH_C32(0x007f9a5b), SPH_C32(0xfa831293), SPH_C32(0x308a0000), + SPH_C32(0x7c810000), SPH_C32(0xb6db0000), SPH_C32(0xa53c36c0), + SPH_C32(0x329b0114), SPH_C32(0x60a74487), SPH_C32(0x807f0e75), + SPH_C32(0xfc57a999) }, + { SPH_C32(0x5fb60000), SPH_C32(0x1bd80000), SPH_C32(0x51b70000), + SPH_C32(0x4ec9bea0), SPH_C32(0x99504e1d), SPH_C32(0x8d14c195), + SPH_C32(0x28ea9cef), SPH_C32(0x2dd95a04), SPH_C32(0xc04f0000), + SPH_C32(0x25a20000), SPH_C32(0xf3590000), SPH_C32(0x44b13600), + SPH_C32(0x09f60725), SPH_C32(0xa24a121e), SPH_C32(0x4b9ff069), + SPH_C32(0xaaf01806) }, + { SPH_C32(0x1c9e0000), SPH_C32(0x66c30000), SPH_C32(0x0d110000), + SPH_C32(0x5fdac000), SPH_C32(0x32596759), SPH_C32(0x8cc0f80c), + SPH_C32(0xaece29ff), SPH_C32(0xc6afe775), SPH_C32(0x288b0000), + SPH_C32(0x0d770000), SPH_C32(0x5db60000), SPH_C32(0x1f991800), + SPH_C32(0x767042e8), SPH_C32(0xdde1a2a3), SPH_C32(0x5b06af40), + SPH_C32(0x19e93cbf) }, + { SPH_C32(0xfab60000), SPH_C32(0x2a880000), SPH_C32(0xa5440000), + SPH_C32(0x8c0ac2e0), SPH_C32(0xea3857e1), SPH_C32(0x146748d6), + SPH_C32(0x865b2f4b), SPH_C32(0x11f5afe2), SPH_C32(0xd84e0000), + SPH_C32(0x54540000), SPH_C32(0x18340000), SPH_C32(0xfe1418c0), + SPH_C32(0x4d1d44d9), SPH_C32(0x1f0cf43a), SPH_C32(0x90e6515c), + SPH_C32(0x4f4e8d20) }, + { SPH_C32(0xec5b0000), SPH_C32(0x3fe00000), SPH_C32(0x48930000), + SPH_C32(0xbe57c0c0), SPH_C32(0x09346168), SPH_C32(0x4e2dae95), + SPH_C32(0x652ed7e3), SPH_C32(0x900856ea), SPH_C32(0x3e660000), + SPH_C32(0x181f0000), SPH_C32(0xb0610000), SPH_C32(0x2dc41a20), + SPH_C32(0x957c7461), SPH_C32(0x87ab44e0), SPH_C32(0xb87357e8), + SPH_C32(0x9814c5b7) }, + { SPH_C32(0x0a730000), SPH_C32(0x73ab0000), SPH_C32(0xe0c60000), + SPH_C32(0x6d87c220), SPH_C32(0xd15551d0), SPH_C32(0xd68a1e4f), + SPH_C32(0x4dbbd157), SPH_C32(0x47521e7d), SPH_C32(0xcea30000), + SPH_C32(0x413c0000), SPH_C32(0xf5e30000), SPH_C32(0xcc491ae0), + SPH_C32(0xae117250), SPH_C32(0x45461279), SPH_C32(0x7393a9f4), + SPH_C32(0xceb37428) }, + { SPH_C32(0xa8af0000), SPH_C32(0x11f00000), SPH_C32(0xbc4c0000), + SPH_C32(0x200ac4e0), SPH_C32(0x4afb0661), SPH_C32(0x5dd63b51), + SPH_C32(0x7c98fd76), SPH_C32(0x88c093ab), SPH_C32(0xcb8d0000), + SPH_C32(0xb0b60000), SPH_C32(0xdaa50000), SPH_C32(0xa06b1860), + SPH_C32(0x58ca48f2), SPH_C32(0x505495f2), SPH_C32(0x28c30446), + SPH_C32(0x423f2986) }, + { SPH_C32(0x4e870000), SPH_C32(0x5dbb0000), SPH_C32(0x14190000), + SPH_C32(0xf3dac600), SPH_C32(0x929a36d9), SPH_C32(0xc5718b8b), + SPH_C32(0x540dfbc2), SPH_C32(0x5f9adb3c), SPH_C32(0x3b480000), + SPH_C32(0xe9950000), SPH_C32(0x9f270000), SPH_C32(0x41e618a0), + SPH_C32(0x63a74ec3), SPH_C32(0x92b9c36b), SPH_C32(0xe323fa5a), + SPH_C32(0x14989819) }, + { SPH_C32(0x586a0000), SPH_C32(0x48d30000), SPH_C32(0xf9ce0000), + SPH_C32(0xc187c420), SPH_C32(0x71960050), SPH_C32(0x9f3b6dc8), + SPH_C32(0xb778036a), SPH_C32(0xde672234), SPH_C32(0xdd600000), + SPH_C32(0xa5de0000), SPH_C32(0x37720000), SPH_C32(0x92361a40), + SPH_C32(0xbbc67e7b), SPH_C32(0x0a1e73b1), SPH_C32(0xcbb6fcee), + SPH_C32(0xc3c2d08e) }, + { SPH_C32(0xbe420000), SPH_C32(0x04980000), SPH_C32(0x519b0000), + SPH_C32(0x1257c6c0), SPH_C32(0xa9f730e8), SPH_C32(0x079cdd12), + SPH_C32(0x9fed05de), SPH_C32(0x093d6aa3), SPH_C32(0x2da50000), + SPH_C32(0xfcfd0000), SPH_C32(0x72f00000), SPH_C32(0x73bb1a80), + SPH_C32(0x80ab784a), SPH_C32(0xc8f32528), SPH_C32(0x005602f2), + SPH_C32(0x95656111) }, + { SPH_C32(0xff980000), SPH_C32(0xdb020000), SPH_C32(0x8a020000), + SPH_C32(0xe028c060), SPH_C32(0x1ce36d43), SPH_C32(0x0175cf5d), + SPH_C32(0xdd0b82f9), SPH_C32(0x9d79f24c), SPH_C32(0x7fbc0000), + SPH_C32(0xc7850000), SPH_C32(0x6bf80000), SPH_C32(0xdfbb1c80), + SPH_C32(0x206829ca), SPH_C32(0x814256af), SPH_C32(0xfa95d0cf), + SPH_C32(0x0c505d58) }, + { SPH_C32(0x19b00000), SPH_C32(0x97490000), SPH_C32(0x22570000), + SPH_C32(0x33f8c280), SPH_C32(0xc4825dfb), SPH_C32(0x99d27f87), + SPH_C32(0xf59e844d), SPH_C32(0x4a23badb), SPH_C32(0x8f790000), + SPH_C32(0x9ea60000), SPH_C32(0x2e7a0000), SPH_C32(0x3e361c40), + SPH_C32(0x1b052ffb), SPH_C32(0x43af0036), SPH_C32(0x31752ed3), + SPH_C32(0x5af7ecc7) }, + { SPH_C32(0x0f5d0000), SPH_C32(0x82210000), SPH_C32(0xcf800000), + SPH_C32(0x01a5c0a0), SPH_C32(0x278e6b72), SPH_C32(0xc39899c4), + SPH_C32(0x16eb7ce5), SPH_C32(0xcbde43d3), SPH_C32(0x69510000), + SPH_C32(0xd2ed0000), SPH_C32(0x862f0000), SPH_C32(0xede61ea0), + SPH_C32(0xc3641f43), SPH_C32(0xdb08b0ec), SPH_C32(0x19e02867), + SPH_C32(0x8dada450) }, + { SPH_C32(0xe9750000), SPH_C32(0xce6a0000), SPH_C32(0x67d50000), + SPH_C32(0xd275c240), SPH_C32(0xffef5bca), SPH_C32(0x5b3f291e), + SPH_C32(0x3e7e7a51), SPH_C32(0x1c840b44), SPH_C32(0x99940000), + SPH_C32(0x8bce0000), SPH_C32(0xc3ad0000), SPH_C32(0x0c6b1e60), + SPH_C32(0xf8091972), SPH_C32(0x19e5e675), SPH_C32(0xd200d67b), + SPH_C32(0xdb0a15cf) }, + { SPH_C32(0x4ba90000), SPH_C32(0xac310000), SPH_C32(0x3b5f0000), + SPH_C32(0x9ff8c480), SPH_C32(0x64410c7b), SPH_C32(0xd0630c00), + SPH_C32(0x0f5d5670), SPH_C32(0xd3168692), SPH_C32(0x9cba0000), + SPH_C32(0x7a440000), SPH_C32(0xeceb0000), SPH_C32(0x60491ce0), + SPH_C32(0x0ed223d0), SPH_C32(0x0cf761fe), SPH_C32(0x89507bc9), + SPH_C32(0x57864861) }, + { SPH_C32(0xad810000), SPH_C32(0xe07a0000), SPH_C32(0x930a0000), + SPH_C32(0x4c28c660), SPH_C32(0xbc203cc3), SPH_C32(0x48c4bcda), + SPH_C32(0x27c850c4), SPH_C32(0x044cce05), SPH_C32(0x6c7f0000), + SPH_C32(0x23670000), SPH_C32(0xa9690000), SPH_C32(0x81c41c20), + SPH_C32(0x35bf25e1), SPH_C32(0xce1a3767), SPH_C32(0x42b085d5), + SPH_C32(0x0121f9fe) }, + { SPH_C32(0xbb6c0000), SPH_C32(0xf5120000), SPH_C32(0x7edd0000), + SPH_C32(0x7e75c440), SPH_C32(0x5f2c0a4a), SPH_C32(0x128e5a99), + SPH_C32(0xc4bda86c), SPH_C32(0x85b1370d), SPH_C32(0x8a570000), + SPH_C32(0x6f2c0000), SPH_C32(0x013c0000), SPH_C32(0x52141ec0), + SPH_C32(0xedde1559), SPH_C32(0x56bd87bd), SPH_C32(0x6a258361), + SPH_C32(0xd67bb169) }, + { SPH_C32(0x5d440000), SPH_C32(0xb9590000), SPH_C32(0xd6880000), + SPH_C32(0xada5c6a0), SPH_C32(0x874d3af2), SPH_C32(0x8a29ea43), + SPH_C32(0xec28aed8), SPH_C32(0x52eb7f9a), SPH_C32(0x7a920000), + SPH_C32(0x360f0000), SPH_C32(0x44be0000), SPH_C32(0xb3991e00), + SPH_C32(0xd6b31368), SPH_C32(0x9450d124), SPH_C32(0xa1c57d7d), + SPH_C32(0x80dc00f6) }, + { SPH_C32(0xa4b10000), SPH_C32(0xd7ef0000), SPH_C32(0x3dc90000), + SPH_C32(0x4b9e9000), SPH_C32(0xf30107fb), SPH_C32(0xbde710e0), + SPH_C32(0x805696dc), SPH_C32(0x93b1da1b), SPH_C32(0x2a790000), + SPH_C32(0xaff60000), SPH_C32(0xda890000), SPH_C32(0xfcf56000), + SPH_C32(0x686d3607), SPH_C32(0xdadc8975), SPH_C32(0x9fc49d77), + SPH_C32(0x66db1921) }, + { SPH_C32(0x42990000), SPH_C32(0x9ba40000), SPH_C32(0x959c0000), + SPH_C32(0x984e92e0), SPH_C32(0x2b603743), SPH_C32(0x2540a03a), + SPH_C32(0xa8c39068), SPH_C32(0x44eb928c), SPH_C32(0xdabc0000), + SPH_C32(0xf6d50000), SPH_C32(0x9f0b0000), SPH_C32(0x1d7860c0), + SPH_C32(0x53003036), SPH_C32(0x1831dfec), SPH_C32(0x5424636b), + SPH_C32(0x307ca8be) }, + { SPH_C32(0x54740000), SPH_C32(0x8ecc0000), SPH_C32(0x784b0000), + SPH_C32(0xaa1390c0), SPH_C32(0xc86c01ca), SPH_C32(0x7f0a4679), + SPH_C32(0x4bb668c0), SPH_C32(0xc5166b84), SPH_C32(0x3c940000), + SPH_C32(0xba9e0000), SPH_C32(0x375e0000), SPH_C32(0xcea86220), + SPH_C32(0x8b61008e), SPH_C32(0x80966f36), SPH_C32(0x7cb165df), + SPH_C32(0xe726e029) }, + { SPH_C32(0xb25c0000), SPH_C32(0xc2870000), SPH_C32(0xd01e0000), + SPH_C32(0x79c39220), SPH_C32(0x100d3172), SPH_C32(0xe7adf6a3), + SPH_C32(0x63236e74), SPH_C32(0x124c2313), SPH_C32(0xcc510000), + SPH_C32(0xe3bd0000), SPH_C32(0x72dc0000), SPH_C32(0x2f2562e0), + SPH_C32(0xb00c06bf), SPH_C32(0x427b39af), SPH_C32(0xb7519bc3), + SPH_C32(0xb18151b6) }, + { SPH_C32(0x10800000), SPH_C32(0xa0dc0000), SPH_C32(0x8c940000), + SPH_C32(0x344e94e0), SPH_C32(0x8ba366c3), SPH_C32(0x6cf1d3bd), + SPH_C32(0x52004255), SPH_C32(0xdddeaec5), SPH_C32(0xc97f0000), + SPH_C32(0x12370000), SPH_C32(0x5d9a0000), SPH_C32(0x43076060), + SPH_C32(0x46d73c1d), SPH_C32(0x5769be24), SPH_C32(0xec013671), + SPH_C32(0x3d0d0c18) }, + { SPH_C32(0xf6a80000), SPH_C32(0xec970000), SPH_C32(0x24c10000), + SPH_C32(0xe79e9600), SPH_C32(0x53c2567b), SPH_C32(0xf4566367), + SPH_C32(0x7a9544e1), SPH_C32(0x0a84e652), SPH_C32(0x39ba0000), + SPH_C32(0x4b140000), SPH_C32(0x18180000), SPH_C32(0xa28a60a0), + SPH_C32(0x7dba3a2c), SPH_C32(0x9584e8bd), SPH_C32(0x27e1c86d), + SPH_C32(0x6baabd87) }, + { SPH_C32(0xe0450000), SPH_C32(0xf9ff0000), SPH_C32(0xc9160000), + SPH_C32(0xd5c39420), SPH_C32(0xb0ce60f2), SPH_C32(0xae1c8524), + SPH_C32(0x99e0bc49), SPH_C32(0x8b791f5a), SPH_C32(0xdf920000), + SPH_C32(0x075f0000), SPH_C32(0xb04d0000), SPH_C32(0x715a6240), + SPH_C32(0xa5db0a94), SPH_C32(0x0d235867), SPH_C32(0x0f74ced9), + SPH_C32(0xbcf0f510) }, + { SPH_C32(0x066d0000), SPH_C32(0xb5b40000), SPH_C32(0x61430000), + SPH_C32(0x061396c0), SPH_C32(0x68af504a), SPH_C32(0x36bb35fe), + SPH_C32(0xb175bafd), SPH_C32(0x5c2357cd), SPH_C32(0x2f570000), + SPH_C32(0x5e7c0000), SPH_C32(0xf5cf0000), SPH_C32(0x90d76280), + SPH_C32(0x9eb60ca5), SPH_C32(0xcfce0efe), SPH_C32(0xc49430c5), + SPH_C32(0xea57448f) }, + { SPH_C32(0x47b70000), SPH_C32(0x6a2e0000), SPH_C32(0xbada0000), + SPH_C32(0xf46c9060), SPH_C32(0xddbb0de1), SPH_C32(0x305227b1), + SPH_C32(0xf3933dda), SPH_C32(0xc867cf22), SPH_C32(0x7d4e0000), + SPH_C32(0x65040000), SPH_C32(0xecc70000), SPH_C32(0x3cd76480), + SPH_C32(0x3e755d25), SPH_C32(0x867f7d79), SPH_C32(0x3e57e2f8), + SPH_C32(0x736278c6) }, + { SPH_C32(0xa19f0000), SPH_C32(0x26650000), SPH_C32(0x128f0000), + SPH_C32(0x27bc9280), SPH_C32(0x05da3d59), SPH_C32(0xa8f5976b), + SPH_C32(0xdb063b6e), SPH_C32(0x1f3d87b5), SPH_C32(0x8d8b0000), + SPH_C32(0x3c270000), SPH_C32(0xa9450000), SPH_C32(0xdd5a6440), + SPH_C32(0x05185b14), SPH_C32(0x44922be0), SPH_C32(0xf5b71ce4), + SPH_C32(0x25c5c959) }, + { SPH_C32(0xb7720000), SPH_C32(0x330d0000), SPH_C32(0xff580000), + SPH_C32(0x15e190a0), SPH_C32(0xe6d60bd0), SPH_C32(0xf2bf7128), + SPH_C32(0x3873c3c6), SPH_C32(0x9ec07ebd), SPH_C32(0x6ba30000), + SPH_C32(0x706c0000), SPH_C32(0x01100000), SPH_C32(0x0e8a66a0), + SPH_C32(0xdd796bac), SPH_C32(0xdc359b3a), SPH_C32(0xdd221a50), + SPH_C32(0xf29f81ce) }, + { SPH_C32(0x515a0000), SPH_C32(0x7f460000), SPH_C32(0x570d0000), + SPH_C32(0xc6319240), SPH_C32(0x3eb73b68), SPH_C32(0x6a18c1f2), + SPH_C32(0x10e6c572), SPH_C32(0x499a362a), SPH_C32(0x9b660000), + SPH_C32(0x294f0000), SPH_C32(0x44920000), SPH_C32(0xef076660), + SPH_C32(0xe6146d9d), SPH_C32(0x1ed8cda3), SPH_C32(0x16c2e44c), + SPH_C32(0xa4383051) }, + { SPH_C32(0xf3860000), SPH_C32(0x1d1d0000), SPH_C32(0x0b870000), + SPH_C32(0x8bbc9480), SPH_C32(0xa5196cd9), SPH_C32(0xe144e4ec), + SPH_C32(0x21c5e953), SPH_C32(0x8608bbfc), SPH_C32(0x9e480000), + SPH_C32(0xd8c50000), SPH_C32(0x6bd40000), SPH_C32(0x832564e0), + SPH_C32(0x10cf573f), SPH_C32(0x0bca4a28), SPH_C32(0x4d9249fe), + SPH_C32(0x28b46dff) }, + { SPH_C32(0x15ae0000), SPH_C32(0x51560000), SPH_C32(0xa3d20000), + SPH_C32(0x586c9660), SPH_C32(0x7d785c61), SPH_C32(0x79e35436), + SPH_C32(0x0950efe7), SPH_C32(0x5152f36b), SPH_C32(0x6e8d0000), + SPH_C32(0x81e60000), SPH_C32(0x2e560000), SPH_C32(0x62a86420), + SPH_C32(0x2ba2510e), SPH_C32(0xc9271cb1), SPH_C32(0x8672b7e2), + SPH_C32(0x7e13dc60) }, + { SPH_C32(0x03430000), SPH_C32(0x443e0000), SPH_C32(0x4e050000), + SPH_C32(0x6a319440), SPH_C32(0x9e746ae8), SPH_C32(0x23a9b275), + SPH_C32(0xea25174f), SPH_C32(0xd0af0a63), SPH_C32(0x88a50000), + SPH_C32(0xcdad0000), SPH_C32(0x86030000), SPH_C32(0xb17866c0), + SPH_C32(0xf3c361b6), SPH_C32(0x5180ac6b), SPH_C32(0xaee7b156), + SPH_C32(0xa94994f7) }, + { SPH_C32(0xe56b0000), SPH_C32(0x08750000), SPH_C32(0xe6500000), + SPH_C32(0xb9e196a0), SPH_C32(0x46155a50), SPH_C32(0xbb0e02af), + SPH_C32(0xc2b011fb), SPH_C32(0x07f542f4), SPH_C32(0x78600000), + SPH_C32(0x948e0000), SPH_C32(0xc3810000), SPH_C32(0x50f56600), + SPH_C32(0xc8ae6787), SPH_C32(0x936dfaf2), SPH_C32(0x65074f4a), + SPH_C32(0xffee2568) }, + { SPH_C32(0xa6430000), SPH_C32(0x756e0000), SPH_C32(0xbaf60000), + SPH_C32(0xa8f2e800), SPH_C32(0xed1c7314), SPH_C32(0xbada3b36), + SPH_C32(0x4494a4eb), SPH_C32(0xec83ff85), SPH_C32(0x90a40000), + SPH_C32(0xbc5b0000), SPH_C32(0x6d6e0000), SPH_C32(0x0bdd4800), + SPH_C32(0xb728224a), SPH_C32(0xecc64a4f), SPH_C32(0x759e1063), + SPH_C32(0x4cf701d1) }, + { SPH_C32(0x406b0000), SPH_C32(0x39250000), SPH_C32(0x12a30000), + SPH_C32(0x7b22eae0), SPH_C32(0x357d43ac), SPH_C32(0x227d8bec), + SPH_C32(0x6c01a25f), SPH_C32(0x3bd9b712), SPH_C32(0x60610000), + SPH_C32(0xe5780000), SPH_C32(0x28ec0000), SPH_C32(0xea5048c0), + SPH_C32(0x8c45247b), SPH_C32(0x2e2b1cd6), SPH_C32(0xbe7eee7f), + SPH_C32(0x1a50b04e) }, + { SPH_C32(0x56860000), SPH_C32(0x2c4d0000), SPH_C32(0xff740000), + SPH_C32(0x497fe8c0), SPH_C32(0xd6717525), SPH_C32(0x78376daf), + SPH_C32(0x8f745af7), SPH_C32(0xba244e1a), SPH_C32(0x86490000), + SPH_C32(0xa9330000), SPH_C32(0x80b90000), SPH_C32(0x39804a20), + SPH_C32(0x542414c3), SPH_C32(0xb68cac0c), SPH_C32(0x96ebe8cb), + SPH_C32(0xcd0af8d9) }, + { SPH_C32(0xb0ae0000), SPH_C32(0x60060000), SPH_C32(0x57210000), + SPH_C32(0x9aafea20), SPH_C32(0x0e10459d), SPH_C32(0xe090dd75), + SPH_C32(0xa7e15c43), SPH_C32(0x6d7e068d), SPH_C32(0x768c0000), + SPH_C32(0xf0100000), SPH_C32(0xc53b0000), SPH_C32(0xd80d4ae0), + SPH_C32(0x6f4912f2), SPH_C32(0x7461fa95), SPH_C32(0x5d0b16d7), + SPH_C32(0x9bad4946) }, + { SPH_C32(0x12720000), SPH_C32(0x025d0000), SPH_C32(0x0bab0000), + SPH_C32(0xd722ece0), SPH_C32(0x95be122c), SPH_C32(0x6bccf86b), + SPH_C32(0x96c27062), SPH_C32(0xa2ec8b5b), SPH_C32(0x73a20000), + SPH_C32(0x019a0000), SPH_C32(0xea7d0000), SPH_C32(0xb42f4860), + SPH_C32(0x99922850), SPH_C32(0x61737d1e), SPH_C32(0x065bbb65), + SPH_C32(0x172114e8) }, + { SPH_C32(0xf45a0000), SPH_C32(0x4e160000), SPH_C32(0xa3fe0000), + SPH_C32(0x04f2ee00), SPH_C32(0x4ddf2294), SPH_C32(0xf36b48b1), + SPH_C32(0xbe5776d6), SPH_C32(0x75b6c3cc), SPH_C32(0x83670000), + SPH_C32(0x58b90000), SPH_C32(0xafff0000), SPH_C32(0x55a248a0), + SPH_C32(0xa2ff2e61), SPH_C32(0xa39e2b87), SPH_C32(0xcdbb4579), + SPH_C32(0x4186a577) }, + { SPH_C32(0xe2b70000), SPH_C32(0x5b7e0000), SPH_C32(0x4e290000), + SPH_C32(0x36afec20), SPH_C32(0xaed3141d), SPH_C32(0xa921aef2), + SPH_C32(0x5d228e7e), SPH_C32(0xf44b3ac4), SPH_C32(0x654f0000), + SPH_C32(0x14f20000), SPH_C32(0x07aa0000), SPH_C32(0x86724a40), + SPH_C32(0x7a9e1ed9), SPH_C32(0x3b399b5d), SPH_C32(0xe52e43cd), + SPH_C32(0x96dcede0) }, + { SPH_C32(0x049f0000), SPH_C32(0x17350000), SPH_C32(0xe67c0000), + SPH_C32(0xe57feec0), SPH_C32(0x76b224a5), SPH_C32(0x31861e28), + SPH_C32(0x75b788ca), SPH_C32(0x23117253), SPH_C32(0x958a0000), + SPH_C32(0x4dd10000), SPH_C32(0x42280000), SPH_C32(0x67ff4a80), + SPH_C32(0x41f318e8), SPH_C32(0xf9d4cdc4), SPH_C32(0x2ecebdd1), + SPH_C32(0xc07b5c7f) }, + { SPH_C32(0x45450000), SPH_C32(0xc8af0000), SPH_C32(0x3de50000), + SPH_C32(0x1700e860), SPH_C32(0xc3a6790e), SPH_C32(0x376f0c67), + SPH_C32(0x37510fed), SPH_C32(0xb755eabc), SPH_C32(0xc7930000), + SPH_C32(0x76a90000), SPH_C32(0x5b200000), SPH_C32(0xcbff4c80), + SPH_C32(0xe1304968), SPH_C32(0xb065be43), SPH_C32(0xd40d6fec), + SPH_C32(0x594e6036) }, + { SPH_C32(0xa36d0000), SPH_C32(0x84e40000), SPH_C32(0x95b00000), + SPH_C32(0xc4d0ea80), SPH_C32(0x1bc749b6), SPH_C32(0xafc8bcbd), + SPH_C32(0x1fc40959), SPH_C32(0x600fa22b), SPH_C32(0x37560000), + SPH_C32(0x2f8a0000), SPH_C32(0x1ea20000), SPH_C32(0x2a724c40), + SPH_C32(0xda5d4f59), SPH_C32(0x7288e8da), SPH_C32(0x1fed91f0), + SPH_C32(0x0fe9d1a9) }, + { SPH_C32(0xb5800000), SPH_C32(0x918c0000), SPH_C32(0x78670000), + SPH_C32(0xf68de8a0), SPH_C32(0xf8cb7f3f), SPH_C32(0xf5825afe), + SPH_C32(0xfcb1f1f1), SPH_C32(0xe1f25b23), SPH_C32(0xd17e0000), + SPH_C32(0x63c10000), SPH_C32(0xb6f70000), SPH_C32(0xf9a24ea0), + SPH_C32(0x023c7fe1), SPH_C32(0xea2f5800), SPH_C32(0x37789744), + SPH_C32(0xd8b3993e) }, + { SPH_C32(0x53a80000), SPH_C32(0xddc70000), SPH_C32(0xd0320000), + SPH_C32(0x255dea40), SPH_C32(0x20aa4f87), SPH_C32(0x6d25ea24), + SPH_C32(0xd424f745), SPH_C32(0x36a813b4), SPH_C32(0x21bb0000), + SPH_C32(0x3ae20000), SPH_C32(0xf3750000), SPH_C32(0x182f4e60), + SPH_C32(0x395179d0), SPH_C32(0x28c20e99), SPH_C32(0xfc986958), + SPH_C32(0x8e1428a1) }, + { SPH_C32(0xf1740000), SPH_C32(0xbf9c0000), SPH_C32(0x8cb80000), + SPH_C32(0x68d0ec80), SPH_C32(0xbb041836), SPH_C32(0xe679cf3a), + SPH_C32(0xe507db64), SPH_C32(0xf93a9e62), SPH_C32(0x24950000), + SPH_C32(0xcb680000), SPH_C32(0xdc330000), SPH_C32(0x740d4ce0), + SPH_C32(0xcf8a4372), SPH_C32(0x3dd08912), SPH_C32(0xa7c8c4ea), + SPH_C32(0x0298750f) }, + { SPH_C32(0x175c0000), SPH_C32(0xf3d70000), SPH_C32(0x24ed0000), + SPH_C32(0xbb00ee60), SPH_C32(0x6365288e), SPH_C32(0x7ede7fe0), + SPH_C32(0xcd92ddd0), SPH_C32(0x2e60d6f5), SPH_C32(0xd4500000), + SPH_C32(0x924b0000), SPH_C32(0x99b10000), SPH_C32(0x95804c20), + SPH_C32(0xf4e74543), SPH_C32(0xff3ddf8b), SPH_C32(0x6c283af6), + SPH_C32(0x543fc490) }, + { SPH_C32(0x01b10000), SPH_C32(0xe6bf0000), SPH_C32(0xc93a0000), + SPH_C32(0x895dec40), SPH_C32(0x80691e07), SPH_C32(0x249499a3), + SPH_C32(0x2ee72578), SPH_C32(0xaf9d2ffd), SPH_C32(0x32780000), + SPH_C32(0xde000000), SPH_C32(0x31e40000), SPH_C32(0x46504ec0), + SPH_C32(0x2c8675fb), SPH_C32(0x679a6f51), SPH_C32(0x44bd3c42), + SPH_C32(0x83658c07) }, + { SPH_C32(0xe7990000), SPH_C32(0xaaf40000), SPH_C32(0x616f0000), + SPH_C32(0x5a8deea0), SPH_C32(0x58082ebf), SPH_C32(0xbc332979), + SPH_C32(0x067223cc), SPH_C32(0x78c7676a), SPH_C32(0xc2bd0000), + SPH_C32(0x87230000), SPH_C32(0x74660000), SPH_C32(0xa7dd4e00), + SPH_C32(0x17eb73ca), SPH_C32(0xa57739c8), SPH_C32(0x8f5dc25e), + SPH_C32(0xd5c23d98) } +}; + +static const sph_u32 T512_56[128][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xa8da0000), SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), + SPH_C32(0x07da0002), SPH_C32(0x7d669583), SPH_C32(0x1f98708a), + SPH_C32(0xbb668808), SPH_C32(0xda878000), SPH_C32(0xabe70000), + SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), SPH_C32(0x3d180005), + SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), SPH_C32(0xb5c347eb), + SPH_C32(0x3c5dfffe) }, + { SPH_C32(0x01930000), SPH_C32(0xe7820000), SPH_C32(0xedfb0000), + SPH_C32(0xcf0c000b), SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), + SPH_C32(0x063661e1), SPH_C32(0x536f9e7b), SPH_C32(0x92280000), + SPH_C32(0xdc850000), SPH_C32(0x57fa0000), SPH_C32(0x56dc0003), + SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), SPH_C32(0x90cef752), + SPH_C32(0x7b1675d7) }, + { SPH_C32(0xa9490000), SPH_C32(0x713c0000), SPH_C32(0xb1e60000), + SPH_C32(0xc8d60009), SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), + SPH_C32(0xbd50e9e9), SPH_C32(0x89e81e7b), SPH_C32(0x39cf0000), + SPH_C32(0x42880000), SPH_C32(0xf8dd0000), SPH_C32(0x6bc40006), + SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), SPH_C32(0x250db0b9), + SPH_C32(0x474b8a29) }, + { SPH_C32(0x92280000), SPH_C32(0xdc850000), SPH_C32(0x57fa0000), + SPH_C32(0x56dc0003), SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), + SPH_C32(0x90cef752), SPH_C32(0x7b1675d7), SPH_C32(0x93bb0000), + SPH_C32(0x3b070000), SPH_C32(0xba010000), SPH_C32(0x99d00008), + SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), SPH_C32(0x96f896b3), + SPH_C32(0x2879ebac) }, + { SPH_C32(0x3af20000), SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), + SPH_C32(0x51060001), SPH_C32(0xc78fb695), SPH_C32(0x4577d386), + SPH_C32(0x2ba87f5a), SPH_C32(0xa191f5d7), SPH_C32(0x385c0000), + SPH_C32(0xa50a0000), SPH_C32(0x15260000), SPH_C32(0xa4c8000d), + SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), SPH_C32(0x233bd158), + SPH_C32(0x14241452) }, + { SPH_C32(0x93bb0000), SPH_C32(0x3b070000), SPH_C32(0xba010000), + SPH_C32(0x99d00008), SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), + SPH_C32(0x96f896b3), SPH_C32(0x2879ebac), SPH_C32(0x01930000), + SPH_C32(0xe7820000), SPH_C32(0xedfb0000), SPH_C32(0xcf0c000b), + SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), SPH_C32(0x063661e1), + SPH_C32(0x536f9e7b) }, + { SPH_C32(0x3b610000), SPH_C32(0xadb90000), SPH_C32(0xe61c0000), + SPH_C32(0x9e0a000a), SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), + SPH_C32(0x2d9e1ebb), SPH_C32(0xf2fe6bac), SPH_C32(0xaa740000), + SPH_C32(0x798f0000), SPH_C32(0x42dc0000), SPH_C32(0xf214000e), + SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), SPH_C32(0xb3f5260a), + SPH_C32(0x6f326185) }, + { SPH_C32(0x5fa80000), SPH_C32(0x56030000), SPH_C32(0x43ae0000), + SPH_C32(0x64f30013), SPH_C32(0x257e86bf), SPH_C32(0x1311944e), + SPH_C32(0x541e95bf), SPH_C32(0x8ea4db69), SPH_C32(0x00440000), + SPH_C32(0x7f480000), SPH_C32(0xda7c0000), SPH_C32(0x2a230001), + SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), SPH_C32(0x030a9e60), + SPH_C32(0xbe0a679e) }, + { SPH_C32(0xf7720000), SPH_C32(0xc0bd0000), SPH_C32(0x1fb30000), + SPH_C32(0x63290011), SPH_C32(0x5818133c), SPH_C32(0x0c89e4c4), + SPH_C32(0xef781db7), SPH_C32(0x54235b69), SPH_C32(0xaba30000), + SPH_C32(0xe1450000), SPH_C32(0x755b0000), SPH_C32(0x173b0004), + SPH_C32(0x17e2d61f), SPH_C32(0xdd408a12), SPH_C32(0xb6c9d98b), + SPH_C32(0x82579860) }, + { SPH_C32(0x5e3b0000), SPH_C32(0xb1810000), SPH_C32(0xae550000), + SPH_C32(0xabff0018), SPH_C32(0xa8ae0be7), SPH_C32(0xafb22060), + SPH_C32(0x5228f45e), SPH_C32(0xddcb4512), SPH_C32(0x926c0000), + SPH_C32(0xa3cd0000), SPH_C32(0x8d860000), SPH_C32(0x7cff0002), + SPH_C32(0x8144eada), SPH_C32(0xf3593f8b), SPH_C32(0x93c46932), + SPH_C32(0xc51c1249) }, + { SPH_C32(0xf6e10000), SPH_C32(0x273f0000), SPH_C32(0xf2480000), + SPH_C32(0xac25001a), SPH_C32(0xd5c89e64), SPH_C32(0xb02a50ea), + SPH_C32(0xe94e7c56), SPH_C32(0x074cc512), SPH_C32(0x398b0000), + SPH_C32(0x3dc00000), SPH_C32(0x22a10000), SPH_C32(0x41e70007), + SPH_C32(0xad0bf509), SPH_C32(0x87af291e), SPH_C32(0x26072ed9), + SPH_C32(0xf941edb7) }, + { SPH_C32(0xcd800000), SPH_C32(0x8a860000), SPH_C32(0x14540000), + SPH_C32(0x322f0010), SPH_C32(0x9f97a5a9), SPH_C32(0x49fe3742), + SPH_C32(0xc4d062ed), SPH_C32(0xf5b2aebe), SPH_C32(0x93ff0000), + SPH_C32(0x444f0000), SPH_C32(0x607d0000), SPH_C32(0xb3f30009), + SPH_C32(0x0c946782), SPH_C32(0x4ffa8ba5), SPH_C32(0x95f208d3), + SPH_C32(0x96738c32) }, + { SPH_C32(0x655a0000), SPH_C32(0x1c380000), SPH_C32(0x48490000), + SPH_C32(0x35f50012), SPH_C32(0xe2f1302a), SPH_C32(0x566647c8), + SPH_C32(0x7fb6eae5), SPH_C32(0x2f352ebe), SPH_C32(0x38180000), + SPH_C32(0xda420000), SPH_C32(0xcf5a0000), SPH_C32(0x8eeb000c), + SPH_C32(0x20db7851), SPH_C32(0x3b0c9d30), SPH_C32(0x20314f38), + SPH_C32(0xaa2e73cc) }, + { SPH_C32(0xcc130000), SPH_C32(0x6d040000), SPH_C32(0xf9af0000), + SPH_C32(0xfd23001b), SPH_C32(0x124728f1), SPH_C32(0xf55d836c), + SPH_C32(0xc2e6030c), SPH_C32(0xa6dd30c5), SPH_C32(0x01d70000), + SPH_C32(0x98ca0000), SPH_C32(0x37870000), SPH_C32(0xe52f000a), + SPH_C32(0xb67d4494), SPH_C32(0x151528a9), SPH_C32(0x053cff81), + SPH_C32(0xed65f9e5) }, + { SPH_C32(0x64c90000), SPH_C32(0xfbba0000), SPH_C32(0xa5b20000), + SPH_C32(0xfaf90019), SPH_C32(0x6f21bd72), SPH_C32(0xeac5f3e6), + SPH_C32(0x79808b04), SPH_C32(0x7c5ab0c5), SPH_C32(0xaa300000), + SPH_C32(0x06c70000), SPH_C32(0x98a00000), SPH_C32(0xd837000f), + SPH_C32(0x9a325b47), SPH_C32(0x61e33e3c), SPH_C32(0xb0ffb86a), + SPH_C32(0xd138061b) }, + { SPH_C32(0x00440000), SPH_C32(0x7f480000), SPH_C32(0xda7c0000), + SPH_C32(0x2a230001), SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), + SPH_C32(0x030a9e60), SPH_C32(0xbe0a679e), SPH_C32(0x5fec0000), + SPH_C32(0x294b0000), SPH_C32(0x99d20000), SPH_C32(0x4ed00012), + SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), SPH_C32(0x57140bdf), + SPH_C32(0x30aebcf7) }, + { SPH_C32(0xa89e0000), SPH_C32(0xe9f60000), SPH_C32(0x86610000), + SPH_C32(0x2df90003), SPH_C32(0x46cb5c4f), SPH_C32(0xb62eec0d), + SPH_C32(0xb86c1668), SPH_C32(0x648de79e), SPH_C32(0xf40b0000), + SPH_C32(0xb7460000), SPH_C32(0x36f50000), SPH_C32(0x73c80017), + SPH_C32(0x329c50a0), SPH_C32(0xce511e5c), SPH_C32(0xe2d74c34), + SPH_C32(0x0cf34309) }, + { SPH_C32(0x01d70000), SPH_C32(0x98ca0000), SPH_C32(0x37870000), + SPH_C32(0xe52f000a), SPH_C32(0xb67d4494), SPH_C32(0x151528a9), + SPH_C32(0x053cff81), SPH_C32(0xed65f9e5), SPH_C32(0xcdc40000), + SPH_C32(0xf5ce0000), SPH_C32(0xce280000), SPH_C32(0x180c0011), + SPH_C32(0xa43a6c65), SPH_C32(0xe048abc5), SPH_C32(0xc7dafc8d), + SPH_C32(0x4bb8c920) }, + { SPH_C32(0xa90d0000), SPH_C32(0x0e740000), SPH_C32(0x6b9a0000), + SPH_C32(0xe2f50008), SPH_C32(0xcb1bd117), SPH_C32(0x0a8d5823), + SPH_C32(0xbe5a7789), SPH_C32(0x37e279e5), SPH_C32(0x66230000), + SPH_C32(0x6bc30000), SPH_C32(0x610f0000), SPH_C32(0x25140014), + SPH_C32(0x887573b6), SPH_C32(0x94bebd50), SPH_C32(0x7219bb66), + SPH_C32(0x77e536de) }, + { SPH_C32(0x926c0000), SPH_C32(0xa3cd0000), SPH_C32(0x8d860000), + SPH_C32(0x7cff0002), SPH_C32(0x8144eada), SPH_C32(0xf3593f8b), + SPH_C32(0x93c46932), SPH_C32(0xc51c1249), SPH_C32(0xcc570000), + SPH_C32(0x124c0000), SPH_C32(0x23d30000), SPH_C32(0xd700001a), + SPH_C32(0x29eae13d), SPH_C32(0x5ceb1feb), SPH_C32(0xc1ec9d6c), + SPH_C32(0x18d7575b) }, + { SPH_C32(0x3ab60000), SPH_C32(0x35730000), SPH_C32(0xd19b0000), + SPH_C32(0x7b250000), SPH_C32(0xfc227f59), SPH_C32(0xecc14f01), + SPH_C32(0x28a2e13a), SPH_C32(0x1f9b9249), SPH_C32(0x67b00000), + SPH_C32(0x8c410000), SPH_C32(0x8cf40000), SPH_C32(0xea18001f), + SPH_C32(0x05a5feee), SPH_C32(0x281d097e), SPH_C32(0x742fda87), + SPH_C32(0x248aa8a5) }, + { SPH_C32(0x93ff0000), SPH_C32(0x444f0000), SPH_C32(0x607d0000), + SPH_C32(0xb3f30009), SPH_C32(0x0c946782), SPH_C32(0x4ffa8ba5), + SPH_C32(0x95f208d3), SPH_C32(0x96738c32), SPH_C32(0x5e7f0000), + SPH_C32(0xcec90000), SPH_C32(0x74290000), SPH_C32(0x81dc0019), + SPH_C32(0x9303c22b), SPH_C32(0x0604bce7), SPH_C32(0x51226a3e), + SPH_C32(0x63c1228c) }, + { SPH_C32(0x3b250000), SPH_C32(0xd2f10000), SPH_C32(0x3c600000), + SPH_C32(0xb429000b), SPH_C32(0x71f2f201), SPH_C32(0x5062fb2f), + SPH_C32(0x2e9480db), SPH_C32(0x4cf40c32), SPH_C32(0xf5980000), + SPH_C32(0x50c40000), SPH_C32(0xdb0e0000), SPH_C32(0xbcc4001c), + SPH_C32(0xbf4cddf8), SPH_C32(0x72f2aa72), SPH_C32(0xe4e12dd5), + SPH_C32(0x5f9cdd72) }, + { SPH_C32(0x5fec0000), SPH_C32(0x294b0000), SPH_C32(0x99d20000), + SPH_C32(0x4ed00012), SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), + SPH_C32(0x57140bdf), SPH_C32(0x30aebcf7), SPH_C32(0x5fa80000), + SPH_C32(0x56030000), SPH_C32(0x43ae0000), SPH_C32(0x64f30013), + SPH_C32(0x257e86bf), SPH_C32(0x1311944e), SPH_C32(0x541e95bf), + SPH_C32(0x8ea4db69) }, + { SPH_C32(0xf7360000), SPH_C32(0xbff50000), SPH_C32(0xc5cf0000), + SPH_C32(0x490a0010), SPH_C32(0x63b5daf0), SPH_C32(0xa53f7843), + SPH_C32(0xec7283d7), SPH_C32(0xea293cf7), SPH_C32(0xf44f0000), + SPH_C32(0xc80e0000), SPH_C32(0xec890000), SPH_C32(0x59eb0016), + SPH_C32(0x0931996c), SPH_C32(0x67e782db), SPH_C32(0xe1ddd254), + SPH_C32(0xb2f92497) }, + { SPH_C32(0x5e7f0000), SPH_C32(0xcec90000), SPH_C32(0x74290000), + SPH_C32(0x81dc0019), SPH_C32(0x9303c22b), SPH_C32(0x0604bce7), + SPH_C32(0x51226a3e), SPH_C32(0x63c1228c), SPH_C32(0xcd800000), + SPH_C32(0x8a860000), SPH_C32(0x14540000), SPH_C32(0x322f0010), + SPH_C32(0x9f97a5a9), SPH_C32(0x49fe3742), SPH_C32(0xc4d062ed), + SPH_C32(0xf5b2aebe) }, + { SPH_C32(0xf6a50000), SPH_C32(0x58770000), SPH_C32(0x28340000), + SPH_C32(0x8606001b), SPH_C32(0xee6557a8), SPH_C32(0x199ccc6d), + SPH_C32(0xea44e236), SPH_C32(0xb946a28c), SPH_C32(0x66670000), + SPH_C32(0x148b0000), SPH_C32(0xbb730000), SPH_C32(0x0f370015), + SPH_C32(0xb3d8ba7a), SPH_C32(0x3d0821d7), SPH_C32(0x71132506), + SPH_C32(0xc9ef5140) }, + { SPH_C32(0xcdc40000), SPH_C32(0xf5ce0000), SPH_C32(0xce280000), + SPH_C32(0x180c0011), SPH_C32(0xa43a6c65), SPH_C32(0xe048abc5), + SPH_C32(0xc7dafc8d), SPH_C32(0x4bb8c920), SPH_C32(0xcc130000), + SPH_C32(0x6d040000), SPH_C32(0xf9af0000), SPH_C32(0xfd23001b), + SPH_C32(0x124728f1), SPH_C32(0xf55d836c), SPH_C32(0xc2e6030c), + SPH_C32(0xa6dd30c5) }, + { SPH_C32(0x651e0000), SPH_C32(0x63700000), SPH_C32(0x92350000), + SPH_C32(0x1fd60013), SPH_C32(0xd95cf9e6), SPH_C32(0xffd0db4f), + SPH_C32(0x7cbc7485), SPH_C32(0x913f4920), SPH_C32(0x67f40000), + SPH_C32(0xf3090000), SPH_C32(0x56880000), SPH_C32(0xc03b001e), + SPH_C32(0x3e083722), SPH_C32(0x81ab95f9), SPH_C32(0x772544e7), + SPH_C32(0x9a80cf3b) }, + { SPH_C32(0xcc570000), SPH_C32(0x124c0000), SPH_C32(0x23d30000), + SPH_C32(0xd700001a), SPH_C32(0x29eae13d), SPH_C32(0x5ceb1feb), + SPH_C32(0xc1ec9d6c), SPH_C32(0x18d7575b), SPH_C32(0x5e3b0000), + SPH_C32(0xb1810000), SPH_C32(0xae550000), SPH_C32(0xabff0018), + SPH_C32(0xa8ae0be7), SPH_C32(0xafb22060), SPH_C32(0x5228f45e), + SPH_C32(0xddcb4512) }, + { SPH_C32(0x648d0000), SPH_C32(0x84f20000), SPH_C32(0x7fce0000), + SPH_C32(0xd0da0018), SPH_C32(0x548c74be), SPH_C32(0x43736f61), + SPH_C32(0x7a8a1564), SPH_C32(0xc250d75b), SPH_C32(0xf5dc0000), + SPH_C32(0x2f8c0000), SPH_C32(0x01720000), SPH_C32(0x96e7001d), + SPH_C32(0x84e11434), SPH_C32(0xdb4436f5), SPH_C32(0xe7ebb3b5), + SPH_C32(0xe196baec) }, + { SPH_C32(0xee930000), SPH_C32(0xd6070000), SPH_C32(0x92c10000), + SPH_C32(0x2b9801e0), SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), + SPH_C32(0x45312374), SPH_C32(0x201f6a64), SPH_C32(0x7b280000), + SPH_C32(0x57420000), SPH_C32(0xa9e50000), SPH_C32(0x634300a0), + SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), SPH_C32(0x27f83b03), + SPH_C32(0xc7ff60f0) }, + { SPH_C32(0x46490000), SPH_C32(0x40b90000), SPH_C32(0xcedc0000), + SPH_C32(0x2c4201e2), SPH_C32(0xe937bdff), SPH_C32(0x24f48bdd), + SPH_C32(0xfe57ab7c), SPH_C32(0xfa98ea64), SPH_C32(0xd0cf0000), + SPH_C32(0xc94f0000), SPH_C32(0x06c20000), SPH_C32(0x5e5b00a5), + SPH_C32(0xb2945bfc), SPH_C32(0x196f832e), SPH_C32(0x923b7ce8), + SPH_C32(0xfba29f0e) }, + { SPH_C32(0xef000000), SPH_C32(0x31850000), SPH_C32(0x7f3a0000), + SPH_C32(0xe49401eb), SPH_C32(0x1981a524), SPH_C32(0x87cf4f79), + SPH_C32(0x43074295), SPH_C32(0x7370f41f), SPH_C32(0xe9000000), + SPH_C32(0x8bc70000), SPH_C32(0xfe1f0000), SPH_C32(0x359f00a3), + SPH_C32(0x24326739), SPH_C32(0x377636b7), SPH_C32(0xb736cc51), + SPH_C32(0xbce91527) }, + { SPH_C32(0x47da0000), SPH_C32(0xa73b0000), SPH_C32(0x23270000), + SPH_C32(0xe34e01e9), SPH_C32(0x64e730a7), SPH_C32(0x98573ff3), + SPH_C32(0xf861ca9d), SPH_C32(0xa9f7741f), SPH_C32(0x42e70000), + SPH_C32(0x15ca0000), SPH_C32(0x51380000), SPH_C32(0x088700a6), + SPH_C32(0x087d78ea), SPH_C32(0x43802022), SPH_C32(0x02f58bba), + SPH_C32(0x80b4ead9) }, + { SPH_C32(0x7cbb0000), SPH_C32(0x0a820000), SPH_C32(0xc53b0000), + SPH_C32(0x7d4401e3), SPH_C32(0x2eb80b6a), SPH_C32(0x6183585b), + SPH_C32(0xd5ffd426), SPH_C32(0x5b091fb3), SPH_C32(0xe8930000), + SPH_C32(0x6c450000), SPH_C32(0x13e40000), SPH_C32(0xfa9300a8), + SPH_C32(0xa9e2ea61), SPH_C32(0x8bd58299), SPH_C32(0xb100adb0), + SPH_C32(0xef868b5c) }, + { SPH_C32(0xd4610000), SPH_C32(0x9c3c0000), SPH_C32(0x99260000), + SPH_C32(0x7a9e01e1), SPH_C32(0x53de9ee9), SPH_C32(0x7e1b28d1), + SPH_C32(0x6e995c2e), SPH_C32(0x818e9fb3), SPH_C32(0x43740000), + SPH_C32(0xf2480000), SPH_C32(0xbcc30000), SPH_C32(0xc78b00ad), + SPH_C32(0x85adf5b2), SPH_C32(0xff23940c), SPH_C32(0x04c3ea5b), + SPH_C32(0xd3db74a2) }, + { SPH_C32(0x7d280000), SPH_C32(0xed000000), SPH_C32(0x28c00000), + SPH_C32(0xb24801e8), SPH_C32(0xa3688632), SPH_C32(0xdd20ec75), + SPH_C32(0xd3c9b5c7), SPH_C32(0x086681c8), SPH_C32(0x7abb0000), + SPH_C32(0xb0c00000), SPH_C32(0x441e0000), SPH_C32(0xac4f00ab), + SPH_C32(0x130bc977), SPH_C32(0xd13a2195), SPH_C32(0x21ce5ae2), + SPH_C32(0x9490fe8b) }, + { SPH_C32(0xd5f20000), SPH_C32(0x7bbe0000), SPH_C32(0x74dd0000), + SPH_C32(0xb59201ea), SPH_C32(0xde0e13b1), SPH_C32(0xc2b89cff), + SPH_C32(0x68af3dcf), SPH_C32(0xd2e101c8), SPH_C32(0xd15c0000), + SPH_C32(0x2ecd0000), SPH_C32(0xeb390000), SPH_C32(0x915700ae), + SPH_C32(0x3f44d6a4), SPH_C32(0xa5cc3700), SPH_C32(0x940d1d09), + SPH_C32(0xa8cd0175) }, + { SPH_C32(0xb13b0000), SPH_C32(0x80040000), SPH_C32(0xd16f0000), + SPH_C32(0x4f6b01f3), SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), + SPH_C32(0x112fb6cb), SPH_C32(0xaebbb10d), SPH_C32(0x7b6c0000), + SPH_C32(0x280a0000), SPH_C32(0x73990000), SPH_C32(0x496000a1), + SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), SPH_C32(0x24f2a563), + SPH_C32(0x79f5076e) }, + { SPH_C32(0x19e10000), SPH_C32(0x16ba0000), SPH_C32(0x8d720000), + SPH_C32(0x48b101f1), SPH_C32(0xcc493b40), SPH_C32(0x37e51f93), + SPH_C32(0xaa493ec3), SPH_C32(0x743c310d), SPH_C32(0xd08b0000), + SPH_C32(0xb6070000), SPH_C32(0xdcbe0000), SPH_C32(0x747800a4), + SPH_C32(0x89399230), SPH_C32(0xb0d91fa9), SPH_C32(0x9131e288), + SPH_C32(0x45a8f890) }, + { SPH_C32(0xb0a80000), SPH_C32(0x67860000), SPH_C32(0x3c940000), + SPH_C32(0x806701f8), SPH_C32(0x3cff239b), SPH_C32(0x94dedb37), + SPH_C32(0x1719d72a), SPH_C32(0xfdd42f76), SPH_C32(0xe9440000), + SPH_C32(0xf48f0000), SPH_C32(0x24630000), SPH_C32(0x1fbc00a2), + SPH_C32(0x1f9faef5), SPH_C32(0x9ec0aa30), SPH_C32(0xb43c5231), + SPH_C32(0x02e372b9) }, + { SPH_C32(0x18720000), SPH_C32(0xf1380000), SPH_C32(0x60890000), + SPH_C32(0x87bd01fa), SPH_C32(0x4199b618), SPH_C32(0x8b46abbd), + SPH_C32(0xac7f5f22), SPH_C32(0x2753af76), SPH_C32(0x42a30000), + SPH_C32(0x6a820000), SPH_C32(0x8b440000), SPH_C32(0x22a400a7), + SPH_C32(0x33d0b126), SPH_C32(0xea36bca5), SPH_C32(0x01ff15da), + SPH_C32(0x3ebe8d47) }, + { SPH_C32(0x23130000), SPH_C32(0x5c810000), SPH_C32(0x86950000), + SPH_C32(0x19b701f0), SPH_C32(0x0bc68dd5), SPH_C32(0x7292cc15), + SPH_C32(0x81e14199), SPH_C32(0xd5adc4da), SPH_C32(0xe8d70000), + SPH_C32(0x130d0000), SPH_C32(0xc9980000), SPH_C32(0xd0b000a9), + SPH_C32(0x924f23ad), SPH_C32(0x22631e1e), SPH_C32(0xb20a33d0), + SPH_C32(0x518cecc2) }, + { SPH_C32(0x8bc90000), SPH_C32(0xca3f0000), SPH_C32(0xda880000), + SPH_C32(0x1e6d01f2), SPH_C32(0x76a01856), SPH_C32(0x6d0abc9f), + SPH_C32(0x3a87c991), SPH_C32(0x0f2a44da), SPH_C32(0x43300000), + SPH_C32(0x8d000000), SPH_C32(0x66bf0000), SPH_C32(0xeda800ac), + SPH_C32(0xbe003c7e), SPH_C32(0x5695088b), SPH_C32(0x07c9743b), + SPH_C32(0x6dd1133c) }, + { SPH_C32(0x22800000), SPH_C32(0xbb030000), SPH_C32(0x6b6e0000), + SPH_C32(0xd6bb01fb), SPH_C32(0x8616008d), SPH_C32(0xce31783b), + SPH_C32(0x87d72078), SPH_C32(0x86c25aa1), SPH_C32(0x7aff0000), + SPH_C32(0xcf880000), SPH_C32(0x9e620000), SPH_C32(0x866c00aa), + SPH_C32(0x28a600bb), SPH_C32(0x788cbd12), SPH_C32(0x22c4c482), + SPH_C32(0x2a9a9915) }, + { SPH_C32(0x8a5a0000), SPH_C32(0x2dbd0000), SPH_C32(0x37730000), + SPH_C32(0xd16101f9), SPH_C32(0xfb70950e), SPH_C32(0xd1a908b1), + SPH_C32(0x3cb1a870), SPH_C32(0x5c45daa1), SPH_C32(0xd1180000), + SPH_C32(0x51850000), SPH_C32(0x31450000), SPH_C32(0xbb7400af), + SPH_C32(0x04e91f68), SPH_C32(0x0c7aab87), SPH_C32(0x97078369), + SPH_C32(0x16c766eb) }, + { SPH_C32(0xeed70000), SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), + SPH_C32(0x01bb01e1), SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), + SPH_C32(0x463bbd14), SPH_C32(0x9e150dfa), SPH_C32(0x24c40000), + SPH_C32(0x7e090000), SPH_C32(0x30370000), SPH_C32(0x2d9300b2), + SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), SPH_C32(0x70ec30dc), + SPH_C32(0xf751dc07) }, + { SPH_C32(0x460d0000), SPH_C32(0x3ff10000), SPH_C32(0x14a00000), + SPH_C32(0x066101e3), SPH_C32(0xd29a7433), SPH_C32(0x8d42175a), + SPH_C32(0xfd5d351c), SPH_C32(0x44928dfa), SPH_C32(0x8f230000), + SPH_C32(0xe0040000), SPH_C32(0x9f100000), SPH_C32(0x108b00b7), + SPH_C32(0xac47148f), SPH_C32(0xa3c88be7), SPH_C32(0xc52f7737), + SPH_C32(0xcb0c23f9) }, + { SPH_C32(0xef440000), SPH_C32(0x4ecd0000), SPH_C32(0xa5460000), + SPH_C32(0xceb701ea), SPH_C32(0x222c6ce8), SPH_C32(0x2e79d3fe), + SPH_C32(0x400ddcf5), SPH_C32(0xcd7a9381), SPH_C32(0xb6ec0000), + SPH_C32(0xa28c0000), SPH_C32(0x67cd0000), SPH_C32(0x7b4f00b1), + SPH_C32(0x3ae1284a), SPH_C32(0x8dd13e7e), SPH_C32(0xe022c78e), + SPH_C32(0x8c47a9d0) }, + { SPH_C32(0x479e0000), SPH_C32(0xd8730000), SPH_C32(0xf95b0000), + SPH_C32(0xc96d01e8), SPH_C32(0x5f4af96b), SPH_C32(0x31e1a374), + SPH_C32(0xfb6b54fd), SPH_C32(0x17fd1381), SPH_C32(0x1d0b0000), + SPH_C32(0x3c810000), SPH_C32(0xc8ea0000), SPH_C32(0x465700b4), + SPH_C32(0x16ae3799), SPH_C32(0xf92728eb), SPH_C32(0x55e18065), + SPH_C32(0xb01a562e) }, + { SPH_C32(0x7cff0000), SPH_C32(0x75ca0000), SPH_C32(0x1f470000), + SPH_C32(0x576701e2), SPH_C32(0x1515c2a6), SPH_C32(0xc835c4dc), + SPH_C32(0xd6f54a46), SPH_C32(0xe503782d), SPH_C32(0xb77f0000), + SPH_C32(0x450e0000), SPH_C32(0x8a360000), SPH_C32(0xb44300ba), + SPH_C32(0xb731a512), SPH_C32(0x31728a50), SPH_C32(0xe614a66f), + SPH_C32(0xdf2837ab) }, + { SPH_C32(0xd4250000), SPH_C32(0xe3740000), SPH_C32(0x435a0000), + SPH_C32(0x50bd01e0), SPH_C32(0x68735725), SPH_C32(0xd7adb456), + SPH_C32(0x6d93c24e), SPH_C32(0x3f84f82d), SPH_C32(0x1c980000), + SPH_C32(0xdb030000), SPH_C32(0x25110000), SPH_C32(0x895b00bf), + SPH_C32(0x9b7ebac1), SPH_C32(0x45849cc5), SPH_C32(0x53d7e184), + SPH_C32(0xe375c855) }, + { SPH_C32(0x7d6c0000), SPH_C32(0x92480000), SPH_C32(0xf2bc0000), + SPH_C32(0x986b01e9), SPH_C32(0x98c54ffe), SPH_C32(0x749670f2), + SPH_C32(0xd0c32ba7), SPH_C32(0xb66ce656), SPH_C32(0x25570000), + SPH_C32(0x998b0000), SPH_C32(0xddcc0000), SPH_C32(0xe29f00b9), + SPH_C32(0x0dd88604), SPH_C32(0x6b9d295c), SPH_C32(0x76da513d), + SPH_C32(0xa43e427c) }, + { SPH_C32(0xd5b60000), SPH_C32(0x04f60000), SPH_C32(0xaea10000), + SPH_C32(0x9fb101eb), SPH_C32(0xe5a3da7d), SPH_C32(0x6b0e0078), + SPH_C32(0x6ba5a3af), SPH_C32(0x6ceb6656), SPH_C32(0x8eb00000), + SPH_C32(0x07860000), SPH_C32(0x72eb0000), SPH_C32(0xdf8700bc), + SPH_C32(0x219799d7), SPH_C32(0x1f6b3fc9), SPH_C32(0xc31916d6), + SPH_C32(0x9863bd82) }, + { SPH_C32(0xb17f0000), SPH_C32(0xff4c0000), SPH_C32(0x0b130000), + SPH_C32(0x654801f2), SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), + SPH_C32(0x122528ab), SPH_C32(0x10b1d693), SPH_C32(0x24800000), + SPH_C32(0x01410000), SPH_C32(0xea4b0000), SPH_C32(0x07b000b3), + SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), SPH_C32(0x73e6aebc), + SPH_C32(0x495bbb99) }, + { SPH_C32(0x19a50000), SPH_C32(0x69f20000), SPH_C32(0x570e0000), + SPH_C32(0x629201f0), SPH_C32(0xf7e4f28c), SPH_C32(0x9e538314), + SPH_C32(0xa943a0a3), SPH_C32(0xca365693), SPH_C32(0x8f670000), + SPH_C32(0x9f4c0000), SPH_C32(0x456c0000), SPH_C32(0x3aa800b6), + SPH_C32(0x97eadd43), SPH_C32(0x0a7e1760), SPH_C32(0xc625e957), + SPH_C32(0x75064467) }, + { SPH_C32(0xb0ec0000), SPH_C32(0x18ce0000), SPH_C32(0xe6e80000), + SPH_C32(0xaa4401f9), SPH_C32(0x0752ea57), SPH_C32(0x3d6847b0), + SPH_C32(0x1413494a), SPH_C32(0x43de48e8), SPH_C32(0xb6a80000), + SPH_C32(0xddc40000), SPH_C32(0xbdb10000), SPH_C32(0x516c00b0), + SPH_C32(0x014ce186), SPH_C32(0x2467a2f9), SPH_C32(0xe32859ee), + SPH_C32(0x324dce4e) }, + { SPH_C32(0x18360000), SPH_C32(0x8e700000), SPH_C32(0xbaf50000), + SPH_C32(0xad9e01fb), SPH_C32(0x7a347fd4), SPH_C32(0x22f0373a), + SPH_C32(0xaf75c142), SPH_C32(0x9959c8e8), SPH_C32(0x1d4f0000), + SPH_C32(0x43c90000), SPH_C32(0x12960000), SPH_C32(0x6c7400b5), + SPH_C32(0x2d03fe55), SPH_C32(0x5091b46c), SPH_C32(0x56eb1e05), + SPH_C32(0x0e1031b0) }, + { SPH_C32(0x23570000), SPH_C32(0x23c90000), SPH_C32(0x5ce90000), + SPH_C32(0x339401f1), SPH_C32(0x306b4419), SPH_C32(0xdb245092), + SPH_C32(0x82ebdff9), SPH_C32(0x6ba7a344), SPH_C32(0xb73b0000), + SPH_C32(0x3a460000), SPH_C32(0x504a0000), SPH_C32(0x9e6000bb), + SPH_C32(0x8c9c6cde), SPH_C32(0x98c416d7), SPH_C32(0xe51e380f), + SPH_C32(0x61225035) }, + { SPH_C32(0x8b8d0000), SPH_C32(0xb5770000), SPH_C32(0x00f40000), + SPH_C32(0x344e01f3), SPH_C32(0x4d0dd19a), SPH_C32(0xc4bc2018), + SPH_C32(0x398d57f1), SPH_C32(0xb1202344), SPH_C32(0x1cdc0000), + SPH_C32(0xa44b0000), SPH_C32(0xff6d0000), SPH_C32(0xa37800be), + SPH_C32(0xa0d3730d), SPH_C32(0xec320042), SPH_C32(0x50dd7fe4), + SPH_C32(0x5d7fafcb) }, + { SPH_C32(0x22c40000), SPH_C32(0xc44b0000), SPH_C32(0xb1120000), + SPH_C32(0xfc9801fa), SPH_C32(0xbdbbc941), SPH_C32(0x6787e4bc), + SPH_C32(0x84ddbe18), SPH_C32(0x38c83d3f), SPH_C32(0x25130000), + SPH_C32(0xe6c30000), SPH_C32(0x07b00000), SPH_C32(0xc8bc00b8), + SPH_C32(0x36754fc8), SPH_C32(0xc22bb5db), SPH_C32(0x75d0cf5d), + SPH_C32(0x1a3425e2) }, + { SPH_C32(0x8a1e0000), SPH_C32(0x52f50000), SPH_C32(0xed0f0000), + SPH_C32(0xfb4201f8), SPH_C32(0xc0dd5cc2), SPH_C32(0x781f9436), + SPH_C32(0x3fbb3610), SPH_C32(0xe24fbd3f), SPH_C32(0x8ef40000), + SPH_C32(0x78ce0000), SPH_C32(0xa8970000), SPH_C32(0xf5a400bd), + SPH_C32(0x1a3a501b), SPH_C32(0xb6dda34e), SPH_C32(0xc01388b6), + SPH_C32(0x2669da1c) }, + { SPH_C32(0x7b280000), SPH_C32(0x57420000), SPH_C32(0xa9e50000), + SPH_C32(0x634300a0), SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), + SPH_C32(0x27f83b03), SPH_C32(0xc7ff60f0), SPH_C32(0x95bb0000), + SPH_C32(0x81450000), SPH_C32(0x3b240000), SPH_C32(0x48db0140), + SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), SPH_C32(0x62c91877), + SPH_C32(0xe7e00a94) }, + { SPH_C32(0xd3f20000), SPH_C32(0xc1fc0000), SPH_C32(0xf5f80000), + SPH_C32(0x649900a2), SPH_C32(0xe3bdd1ac), SPH_C32(0x7201e531), + SPH_C32(0x9c9eb30b), SPH_C32(0x1d78e0f0), SPH_C32(0x3e5c0000), + SPH_C32(0x1f480000), SPH_C32(0x94030000), SPH_C32(0x75c30145), + SPH_C32(0x26c57380), SPH_C32(0x22037879), SPH_C32(0xd70a5f9c), + SPH_C32(0xdbbdf56a) }, + { SPH_C32(0x7abb0000), SPH_C32(0xb0c00000), SPH_C32(0x441e0000), + SPH_C32(0xac4f00ab), SPH_C32(0x130bc977), SPH_C32(0xd13a2195), + SPH_C32(0x21ce5ae2), SPH_C32(0x9490fe8b), SPH_C32(0x07930000), + SPH_C32(0x5dc00000), SPH_C32(0x6cde0000), SPH_C32(0x1e070143), + SPH_C32(0xb0634f45), SPH_C32(0x0c1acde0), SPH_C32(0xf207ef25), + SPH_C32(0x9cf67f43) }, + { SPH_C32(0xd2610000), SPH_C32(0x267e0000), SPH_C32(0x18030000), + SPH_C32(0xab9500a9), SPH_C32(0x6e6d5cf4), SPH_C32(0xcea2511f), + SPH_C32(0x9aa8d2ea), SPH_C32(0x4e177e8b), SPH_C32(0xac740000), + SPH_C32(0xc3cd0000), SPH_C32(0xc3f90000), SPH_C32(0x231f0146), + SPH_C32(0x9c2c5096), SPH_C32(0x78ecdb75), SPH_C32(0x47c4a8ce), + SPH_C32(0xa0ab80bd) }, + { SPH_C32(0xe9000000), SPH_C32(0x8bc70000), SPH_C32(0xfe1f0000), + SPH_C32(0x359f00a3), SPH_C32(0x24326739), SPH_C32(0x377636b7), + SPH_C32(0xb736cc51), SPH_C32(0xbce91527), SPH_C32(0x06000000), + SPH_C32(0xba420000), SPH_C32(0x81250000), SPH_C32(0xd10b0148), + SPH_C32(0x3db3c21d), SPH_C32(0xb0b979ce), SPH_C32(0xf4318ec4), + SPH_C32(0xcf99e138) }, + { SPH_C32(0x41da0000), SPH_C32(0x1d790000), SPH_C32(0xa2020000), + SPH_C32(0x324500a1), SPH_C32(0x5954f2ba), SPH_C32(0x28ee463d), + SPH_C32(0x0c504459), SPH_C32(0x666e9527), SPH_C32(0xade70000), + SPH_C32(0x244f0000), SPH_C32(0x2e020000), SPH_C32(0xec13014d), + SPH_C32(0x11fcddce), SPH_C32(0xc44f6f5b), SPH_C32(0x41f2c92f), + SPH_C32(0xf3c41ec6) }, + { SPH_C32(0xe8930000), SPH_C32(0x6c450000), SPH_C32(0x13e40000), + SPH_C32(0xfa9300a8), SPH_C32(0xa9e2ea61), SPH_C32(0x8bd58299), + SPH_C32(0xb100adb0), SPH_C32(0xef868b5c), SPH_C32(0x94280000), + SPH_C32(0x66c70000), SPH_C32(0xd6df0000), SPH_C32(0x87d7014b), + SPH_C32(0x875ae10b), SPH_C32(0xea56dac2), SPH_C32(0x64ff7996), + SPH_C32(0xb48f94ef) }, + { SPH_C32(0x40490000), SPH_C32(0xfafb0000), SPH_C32(0x4ff90000), + SPH_C32(0xfd4900aa), SPH_C32(0xd4847fe2), SPH_C32(0x944df213), + SPH_C32(0x0a6625b8), SPH_C32(0x35010b5c), SPH_C32(0x3fcf0000), + SPH_C32(0xf8ca0000), SPH_C32(0x79f80000), SPH_C32(0xbacf014e), + SPH_C32(0xab15fed8), SPH_C32(0x9ea0cc57), SPH_C32(0xd13c3e7d), + SPH_C32(0x88d26b11) }, + { SPH_C32(0x24800000), SPH_C32(0x01410000), SPH_C32(0xea4b0000), + SPH_C32(0x07b000b3), SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), + SPH_C32(0x73e6aebc), SPH_C32(0x495bbb99), SPH_C32(0x95ff0000), + SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), SPH_C32(0x62f80141), + SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), SPH_C32(0x61c38617), + SPH_C32(0x59ea6d0a) }, + { SPH_C32(0x8c5a0000), SPH_C32(0x97ff0000), SPH_C32(0xb6560000), + SPH_C32(0x006a00b1), SPH_C32(0xc6c35713), SPH_C32(0x6110717f), + SPH_C32(0xc88026b4), SPH_C32(0x93dc3b99), SPH_C32(0x3e180000), + SPH_C32(0x60000000), SPH_C32(0x4e7f0000), SPH_C32(0x5fe00144), + SPH_C32(0x1d68ba4c), SPH_C32(0x8bb5e4fe), SPH_C32(0xd400c1fc), + SPH_C32(0x65b792f4) }, + { SPH_C32(0x25130000), SPH_C32(0xe6c30000), SPH_C32(0x07b00000), + SPH_C32(0xc8bc00b8), SPH_C32(0x36754fc8), SPH_C32(0xc22bb5db), + SPH_C32(0x75d0cf5d), SPH_C32(0x1a3425e2), SPH_C32(0x07d70000), + SPH_C32(0x22880000), SPH_C32(0xb6a20000), SPH_C32(0x34240142), + SPH_C32(0x8bce8689), SPH_C32(0xa5ac5167), SPH_C32(0xf10d7145), + SPH_C32(0x22fc18dd) }, + { SPH_C32(0x8dc90000), SPH_C32(0x707d0000), SPH_C32(0x5bad0000), + SPH_C32(0xcf6600ba), SPH_C32(0x4b13da4b), SPH_C32(0xddb3c551), + SPH_C32(0xceb64755), SPH_C32(0xc0b3a5e2), SPH_C32(0xac300000), + SPH_C32(0xbc850000), SPH_C32(0x19850000), SPH_C32(0x093c0147), + SPH_C32(0xa781995a), SPH_C32(0xd15a47f2), SPH_C32(0x44ce36ae), + SPH_C32(0x1ea1e723) }, + { SPH_C32(0xb6a80000), SPH_C32(0xddc40000), SPH_C32(0xbdb10000), + SPH_C32(0x516c00b0), SPH_C32(0x014ce186), SPH_C32(0x2467a2f9), + SPH_C32(0xe32859ee), SPH_C32(0x324dce4e), SPH_C32(0x06440000), + SPH_C32(0xc50a0000), SPH_C32(0x5b590000), SPH_C32(0xfb280149), + SPH_C32(0x061e0bd1), SPH_C32(0x190fe549), SPH_C32(0xf73b10a4), + SPH_C32(0x719386a6) }, + { SPH_C32(0x1e720000), SPH_C32(0x4b7a0000), SPH_C32(0xe1ac0000), + SPH_C32(0x56b600b2), SPH_C32(0x7c2a7405), SPH_C32(0x3bffd273), + SPH_C32(0x584ed1e6), SPH_C32(0xe8ca4e4e), SPH_C32(0xada30000), + SPH_C32(0x5b070000), SPH_C32(0xf47e0000), SPH_C32(0xc630014c), + SPH_C32(0x2a511402), SPH_C32(0x6df9f3dc), SPH_C32(0x42f8574f), + SPH_C32(0x4dce7958) }, + { SPH_C32(0xb73b0000), SPH_C32(0x3a460000), SPH_C32(0x504a0000), + SPH_C32(0x9e6000bb), SPH_C32(0x8c9c6cde), SPH_C32(0x98c416d7), + SPH_C32(0xe51e380f), SPH_C32(0x61225035), SPH_C32(0x946c0000), + SPH_C32(0x198f0000), SPH_C32(0x0ca30000), SPH_C32(0xadf4014a), + SPH_C32(0xbcf728c7), SPH_C32(0x43e04645), SPH_C32(0x67f5e7f6), + SPH_C32(0x0a85f371) }, + { SPH_C32(0x1fe10000), SPH_C32(0xacf80000), SPH_C32(0x0c570000), + SPH_C32(0x99ba00b9), SPH_C32(0xf1faf95d), SPH_C32(0x875c665d), + SPH_C32(0x5e78b007), SPH_C32(0xbba5d035), SPH_C32(0x3f8b0000), + SPH_C32(0x87820000), SPH_C32(0xa3840000), SPH_C32(0x90ec014f), + SPH_C32(0x90b83714), SPH_C32(0x371650d0), SPH_C32(0xd236a01d), + SPH_C32(0x36d80c8f) }, + { SPH_C32(0x7b6c0000), SPH_C32(0x280a0000), SPH_C32(0x73990000), + SPH_C32(0x496000a1), SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), + SPH_C32(0x24f2a563), SPH_C32(0x79f5076e), SPH_C32(0xca570000), + SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), SPH_C32(0x060b0152), + SPH_C32(0x14592320), SPH_C32(0xec526625), SPH_C32(0x35dd13a8), + SPH_C32(0xd74eb663) }, + { SPH_C32(0xd3b60000), SPH_C32(0xbeb40000), SPH_C32(0x2f840000), + SPH_C32(0x4eba00a3), SPH_C32(0xd8101860), SPH_C32(0xdbb779b6), + SPH_C32(0x9f942d6b), SPH_C32(0xa372876e), SPH_C32(0x61b00000), + SPH_C32(0x36030000), SPH_C32(0x0dd10000), SPH_C32(0x3b130157), + SPH_C32(0x38163cf3), SPH_C32(0x98a470b0), SPH_C32(0x801e5443), + SPH_C32(0xeb13499d) }, + { SPH_C32(0x7aff0000), SPH_C32(0xcf880000), SPH_C32(0x9e620000), + SPH_C32(0x866c00aa), SPH_C32(0x28a600bb), SPH_C32(0x788cbd12), + SPH_C32(0x22c4c482), SPH_C32(0x2a9a9915), SPH_C32(0x587f0000), + SPH_C32(0x748b0000), SPH_C32(0xf50c0000), SPH_C32(0x50d70151), + SPH_C32(0xaeb00036), SPH_C32(0xb6bdc529), SPH_C32(0xa513e4fa), + SPH_C32(0xac58c3b4) }, + { SPH_C32(0xd2250000), SPH_C32(0x59360000), SPH_C32(0xc27f0000), + SPH_C32(0x81b600a8), SPH_C32(0x55c09538), SPH_C32(0x6714cd98), + SPH_C32(0x99a24c8a), SPH_C32(0xf01d1915), SPH_C32(0xf3980000), + SPH_C32(0xea860000), SPH_C32(0x5a2b0000), SPH_C32(0x6dcf0154), + SPH_C32(0x82ff1fe5), SPH_C32(0xc24bd3bc), SPH_C32(0x10d0a311), + SPH_C32(0x90053c4a) }, + { SPH_C32(0xe9440000), SPH_C32(0xf48f0000), SPH_C32(0x24630000), + SPH_C32(0x1fbc00a2), SPH_C32(0x1f9faef5), SPH_C32(0x9ec0aa30), + SPH_C32(0xb43c5231), SPH_C32(0x02e372b9), SPH_C32(0x59ec0000), + SPH_C32(0x93090000), SPH_C32(0x18f70000), SPH_C32(0x9fdb015a), + SPH_C32(0x23608d6e), SPH_C32(0x0a1e7107), SPH_C32(0xa325851b), + SPH_C32(0xff375dcf) }, + { SPH_C32(0x419e0000), SPH_C32(0x62310000), SPH_C32(0x787e0000), + SPH_C32(0x186600a0), SPH_C32(0x62f93b76), SPH_C32(0x8158daba), + SPH_C32(0x0f5ada39), SPH_C32(0xd864f2b9), SPH_C32(0xf20b0000), + SPH_C32(0x0d040000), SPH_C32(0xb7d00000), SPH_C32(0xa2c3015f), + SPH_C32(0x0f2f92bd), SPH_C32(0x7ee86792), SPH_C32(0x16e6c2f0), + SPH_C32(0xc36aa231) }, + { SPH_C32(0xe8d70000), SPH_C32(0x130d0000), SPH_C32(0xc9980000), + SPH_C32(0xd0b000a9), SPH_C32(0x924f23ad), SPH_C32(0x22631e1e), + SPH_C32(0xb20a33d0), SPH_C32(0x518cecc2), SPH_C32(0xcbc40000), + SPH_C32(0x4f8c0000), SPH_C32(0x4f0d0000), SPH_C32(0xc9070159), + SPH_C32(0x9989ae78), SPH_C32(0x50f1d20b), SPH_C32(0x33eb7249), + SPH_C32(0x84212818) }, + { SPH_C32(0x400d0000), SPH_C32(0x85b30000), SPH_C32(0x95850000), + SPH_C32(0xd76a00ab), SPH_C32(0xef29b62e), SPH_C32(0x3dfb6e94), + SPH_C32(0x096cbbd8), SPH_C32(0x8b0b6cc2), SPH_C32(0x60230000), + SPH_C32(0xd1810000), SPH_C32(0xe02a0000), SPH_C32(0xf41f015c), + SPH_C32(0xb5c6b1ab), SPH_C32(0x2407c49e), SPH_C32(0x862835a2), + SPH_C32(0xb87cd7e6) }, + { SPH_C32(0x24c40000), SPH_C32(0x7e090000), SPH_C32(0x30370000), + SPH_C32(0x2d9300b2), SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), + SPH_C32(0x70ec30dc), SPH_C32(0xf751dc07), SPH_C32(0xca130000), + SPH_C32(0xd7460000), SPH_C32(0x788a0000), SPH_C32(0x2c280153), + SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), SPH_C32(0x36d78dc8), + SPH_C32(0x6944d1fd) }, + { SPH_C32(0x8c1e0000), SPH_C32(0xe8b70000), SPH_C32(0x6c2a0000), + SPH_C32(0x2a4900b0), SPH_C32(0xfd6e9edf), SPH_C32(0xc8a6edf8), + SPH_C32(0xcb8ab8d4), SPH_C32(0x2dd65c07), SPH_C32(0x61f40000), + SPH_C32(0x494b0000), SPH_C32(0xd7ad0000), SPH_C32(0x11300156), + SPH_C32(0x03bbf53f), SPH_C32(0x3112ec37), SPH_C32(0x8314ca23), + SPH_C32(0x55192e03) }, + { SPH_C32(0x25570000), SPH_C32(0x998b0000), SPH_C32(0xddcc0000), + SPH_C32(0xe29f00b9), SPH_C32(0x0dd88604), SPH_C32(0x6b9d295c), + SPH_C32(0x76da513d), SPH_C32(0xa43e427c), SPH_C32(0x583b0000), + SPH_C32(0x0bc30000), SPH_C32(0x2f700000), SPH_C32(0x7af40150), + SPH_C32(0x951dc9fa), SPH_C32(0x1f0b59ae), SPH_C32(0xa6197a9a), + SPH_C32(0x1252a42a) }, + { SPH_C32(0x8d8d0000), SPH_C32(0x0f350000), SPH_C32(0x81d10000), + SPH_C32(0xe54500bb), SPH_C32(0x70be1387), SPH_C32(0x740559d6), + SPH_C32(0xcdbcd935), SPH_C32(0x7eb9c27c), SPH_C32(0xf3dc0000), + SPH_C32(0x95ce0000), SPH_C32(0x80570000), SPH_C32(0x47ec0155), + SPH_C32(0xb952d629), SPH_C32(0x6bfd4f3b), SPH_C32(0x13da3d71), + SPH_C32(0x2e0f5bd4) }, + { SPH_C32(0xb6ec0000), SPH_C32(0xa28c0000), SPH_C32(0x67cd0000), + SPH_C32(0x7b4f00b1), SPH_C32(0x3ae1284a), SPH_C32(0x8dd13e7e), + SPH_C32(0xe022c78e), SPH_C32(0x8c47a9d0), SPH_C32(0x59a80000), + SPH_C32(0xec410000), SPH_C32(0xc28b0000), SPH_C32(0xb5f8015b), + SPH_C32(0x18cd44a2), SPH_C32(0xa3a8ed80), SPH_C32(0xa02f1b7b), + SPH_C32(0x413d3a51) }, + { SPH_C32(0x1e360000), SPH_C32(0x34320000), SPH_C32(0x3bd00000), + SPH_C32(0x7c9500b3), SPH_C32(0x4787bdc9), SPH_C32(0x92494ef4), + SPH_C32(0x5b444f86), SPH_C32(0x56c029d0), SPH_C32(0xf24f0000), + SPH_C32(0x724c0000), SPH_C32(0x6dac0000), SPH_C32(0x88e0015e), + SPH_C32(0x34825b71), SPH_C32(0xd75efb15), SPH_C32(0x15ec5c90), + SPH_C32(0x7d60c5af) }, + { SPH_C32(0xb77f0000), SPH_C32(0x450e0000), SPH_C32(0x8a360000), + SPH_C32(0xb44300ba), SPH_C32(0xb731a512), SPH_C32(0x31728a50), + SPH_C32(0xe614a66f), SPH_C32(0xdf2837ab), SPH_C32(0xcb800000), + SPH_C32(0x30c40000), SPH_C32(0x95710000), SPH_C32(0xe3240158), + SPH_C32(0xa22467b4), SPH_C32(0xf9474e8c), SPH_C32(0x30e1ec29), + SPH_C32(0x3a2b4f86) }, + { SPH_C32(0x1fa50000), SPH_C32(0xd3b00000), SPH_C32(0xd62b0000), + SPH_C32(0xb39900b8), SPH_C32(0xca573091), SPH_C32(0x2eeafada), + SPH_C32(0x5d722e67), SPH_C32(0x05afb7ab), SPH_C32(0x60670000), + SPH_C32(0xaec90000), SPH_C32(0x3a560000), SPH_C32(0xde3c015d), + SPH_C32(0x8e6b7867), SPH_C32(0x8db15819), SPH_C32(0x8522abc2), + SPH_C32(0x0676b078) }, + { SPH_C32(0x95bb0000), SPH_C32(0x81450000), SPH_C32(0x3b240000), + SPH_C32(0x48db0140), SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), + SPH_C32(0x62c91877), SPH_C32(0xe7e00a94), SPH_C32(0xee930000), + SPH_C32(0xd6070000), SPH_C32(0x92c10000), SPH_C32(0x2b9801e0), + SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), SPH_C32(0x45312374), + SPH_C32(0x201f6a64) }, + { SPH_C32(0x3d610000), SPH_C32(0x17fb0000), SPH_C32(0x67390000), + SPH_C32(0x4f010142), SPH_C32(0x77ecf9d0), SPH_C32(0x496d1e66), + SPH_C32(0xd9af907f), SPH_C32(0x3d678a94), SPH_C32(0x45740000), + SPH_C32(0x480a0000), SPH_C32(0x3de60000), SPH_C32(0x168001e5), + SPH_C32(0xb81e37af), SPH_C32(0x4f9aedc2), SPH_C32(0xf0f2649f), + SPH_C32(0x1c42959a) }, + { SPH_C32(0x94280000), SPH_C32(0x66c70000), SPH_C32(0xd6df0000), + SPH_C32(0x87d7014b), SPH_C32(0x875ae10b), SPH_C32(0xea56dac2), + SPH_C32(0x64ff7996), SPH_C32(0xb48f94ef), SPH_C32(0x7cbb0000), + SPH_C32(0x0a820000), SPH_C32(0xc53b0000), SPH_C32(0x7d4401e3), + SPH_C32(0x2eb80b6a), SPH_C32(0x6183585b), SPH_C32(0xd5ffd426), + SPH_C32(0x5b091fb3) }, + { SPH_C32(0x3cf20000), SPH_C32(0xf0790000), SPH_C32(0x8ac20000), + SPH_C32(0x800d0149), SPH_C32(0xfa3c7488), SPH_C32(0xf5ceaa48), + SPH_C32(0xdf99f19e), SPH_C32(0x6e0814ef), SPH_C32(0xd75c0000), + SPH_C32(0x948f0000), SPH_C32(0x6a1c0000), SPH_C32(0x405c01e6), + SPH_C32(0x02f714b9), SPH_C32(0x15754ece), SPH_C32(0x603c93cd), + SPH_C32(0x6754e04d) }, + { SPH_C32(0x07930000), SPH_C32(0x5dc00000), SPH_C32(0x6cde0000), + SPH_C32(0x1e070143), SPH_C32(0xb0634f45), SPH_C32(0x0c1acde0), + SPH_C32(0xf207ef25), SPH_C32(0x9cf67f43), SPH_C32(0x7d280000), + SPH_C32(0xed000000), SPH_C32(0x28c00000), SPH_C32(0xb24801e8), + SPH_C32(0xa3688632), SPH_C32(0xdd20ec75), SPH_C32(0xd3c9b5c7), + SPH_C32(0x086681c8) }, + { SPH_C32(0xaf490000), SPH_C32(0xcb7e0000), SPH_C32(0x30c30000), + SPH_C32(0x19dd0141), SPH_C32(0xcd05dac6), SPH_C32(0x1382bd6a), + SPH_C32(0x4961672d), SPH_C32(0x4671ff43), SPH_C32(0xd6cf0000), + SPH_C32(0x730d0000), SPH_C32(0x87e70000), SPH_C32(0x8f5001ed), + SPH_C32(0x8f2799e1), SPH_C32(0xa9d6fae0), SPH_C32(0x660af22c), + SPH_C32(0x343b7e36) }, + { SPH_C32(0x06000000), SPH_C32(0xba420000), SPH_C32(0x81250000), + SPH_C32(0xd10b0148), SPH_C32(0x3db3c21d), SPH_C32(0xb0b979ce), + SPH_C32(0xf4318ec4), SPH_C32(0xcf99e138), SPH_C32(0xef000000), + SPH_C32(0x31850000), SPH_C32(0x7f3a0000), SPH_C32(0xe49401eb), + SPH_C32(0x1981a524), SPH_C32(0x87cf4f79), SPH_C32(0x43074295), + SPH_C32(0x7370f41f) }, + { SPH_C32(0xaeda0000), SPH_C32(0x2cfc0000), SPH_C32(0xdd380000), + SPH_C32(0xd6d1014a), SPH_C32(0x40d5579e), SPH_C32(0xaf210944), + SPH_C32(0x4f5706cc), SPH_C32(0x151e6138), SPH_C32(0x44e70000), + SPH_C32(0xaf880000), SPH_C32(0xd01d0000), SPH_C32(0xd98c01ee), + SPH_C32(0x35cebaf7), SPH_C32(0xf33959ec), SPH_C32(0xf6c4057e), + SPH_C32(0x4f2d0be1) }, + { SPH_C32(0xca130000), SPH_C32(0xd7460000), SPH_C32(0x788a0000), + SPH_C32(0x2c280153), SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), + SPH_C32(0x36d78dc8), SPH_C32(0x6944d1fd), SPH_C32(0xeed70000), + SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), SPH_C32(0x01bb01e1), + SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), SPH_C32(0x463bbd14), + SPH_C32(0x9e150dfa) }, + { SPH_C32(0x62c90000), SPH_C32(0x41f80000), SPH_C32(0x24970000), + SPH_C32(0x2bf20151), SPH_C32(0x52927f6f), SPH_C32(0x5a7c8a28), + SPH_C32(0x8db105c0), SPH_C32(0xb3c351fd), SPH_C32(0x45300000), + SPH_C32(0x37420000), SPH_C32(0xe79a0000), SPH_C32(0x3ca301e4), + SPH_C32(0x83b3fe63), SPH_C32(0xe62c7145), SPH_C32(0xf3f8faff), + SPH_C32(0xa248f204) }, + { SPH_C32(0xcb800000), SPH_C32(0x30c40000), SPH_C32(0x95710000), + SPH_C32(0xe3240158), SPH_C32(0xa22467b4), SPH_C32(0xf9474e8c), + SPH_C32(0x30e1ec29), SPH_C32(0x3a2b4f86), SPH_C32(0x7cff0000), + SPH_C32(0x75ca0000), SPH_C32(0x1f470000), SPH_C32(0x576701e2), + SPH_C32(0x1515c2a6), SPH_C32(0xc835c4dc), SPH_C32(0xd6f54a46), + SPH_C32(0xe503782d) }, + { SPH_C32(0x635a0000), SPH_C32(0xa67a0000), SPH_C32(0xc96c0000), + SPH_C32(0xe4fe015a), SPH_C32(0xdf42f237), SPH_C32(0xe6df3e06), + SPH_C32(0x8b876421), SPH_C32(0xe0accf86), SPH_C32(0xd7180000), + SPH_C32(0xebc70000), SPH_C32(0xb0600000), SPH_C32(0x6a7f01e7), + SPH_C32(0x395add75), SPH_C32(0xbcc3d249), SPH_C32(0x63360dad), + SPH_C32(0xd95e87d3) }, + { SPH_C32(0x583b0000), SPH_C32(0x0bc30000), SPH_C32(0x2f700000), + SPH_C32(0x7af40150), SPH_C32(0x951dc9fa), SPH_C32(0x1f0b59ae), + SPH_C32(0xa6197a9a), SPH_C32(0x1252a42a), SPH_C32(0x7d6c0000), + SPH_C32(0x92480000), SPH_C32(0xf2bc0000), SPH_C32(0x986b01e9), + SPH_C32(0x98c54ffe), SPH_C32(0x749670f2), SPH_C32(0xd0c32ba7), + SPH_C32(0xb66ce656) }, + { SPH_C32(0xf0e10000), SPH_C32(0x9d7d0000), SPH_C32(0x736d0000), + SPH_C32(0x7d2e0152), SPH_C32(0xe87b5c79), SPH_C32(0x00932924), + SPH_C32(0x1d7ff292), SPH_C32(0xc8d5242a), SPH_C32(0xd68b0000), + SPH_C32(0x0c450000), SPH_C32(0x5d9b0000), SPH_C32(0xa57301ec), + SPH_C32(0xb48a502d), SPH_C32(0x00606667), SPH_C32(0x65006c4c), + SPH_C32(0x8a3119a8) }, + { SPH_C32(0x59a80000), SPH_C32(0xec410000), SPH_C32(0xc28b0000), + SPH_C32(0xb5f8015b), SPH_C32(0x18cd44a2), SPH_C32(0xa3a8ed80), + SPH_C32(0xa02f1b7b), SPH_C32(0x413d3a51), SPH_C32(0xef440000), + SPH_C32(0x4ecd0000), SPH_C32(0xa5460000), SPH_C32(0xceb701ea), + SPH_C32(0x222c6ce8), SPH_C32(0x2e79d3fe), SPH_C32(0x400ddcf5), + SPH_C32(0xcd7a9381) }, + { SPH_C32(0xf1720000), SPH_C32(0x7aff0000), SPH_C32(0x9e960000), + SPH_C32(0xb2220159), SPH_C32(0x65abd121), SPH_C32(0xbc309d0a), + SPH_C32(0x1b499373), SPH_C32(0x9bbaba51), SPH_C32(0x44a30000), + SPH_C32(0xd0c00000), SPH_C32(0x0a610000), SPH_C32(0xf3af01ef), + SPH_C32(0x0e63733b), SPH_C32(0x5a8fc56b), SPH_C32(0xf5ce9b1e), + SPH_C32(0xf1276c7f) }, + { SPH_C32(0x95ff0000), SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), + SPH_C32(0x62f80141), SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), + SPH_C32(0x61c38617), SPH_C32(0x59ea6d0a), SPH_C32(0xb17f0000), + SPH_C32(0xff4c0000), SPH_C32(0x0b130000), SPH_C32(0x654801f2), + SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), SPH_C32(0x122528ab), + SPH_C32(0x10b1d693) }, + { SPH_C32(0x3d250000), SPH_C32(0x68b30000), SPH_C32(0xbd450000), + SPH_C32(0x65220143), SPH_C32(0x4c41301c), SPH_C32(0xe0db82e1), + SPH_C32(0xdaa50e1f), SPH_C32(0x836ded0a), SPH_C32(0x1a980000), + SPH_C32(0x61410000), SPH_C32(0xa4340000), SPH_C32(0x585001f7), + SPH_C32(0xa6cd78dc), SPH_C32(0xf53de50b), SPH_C32(0xa7e66f40), + SPH_C32(0x2cec296d) }, + { SPH_C32(0x946c0000), SPH_C32(0x198f0000), SPH_C32(0x0ca30000), + SPH_C32(0xadf4014a), SPH_C32(0xbcf728c7), SPH_C32(0x43e04645), + SPH_C32(0x67f5e7f6), SPH_C32(0x0a85f371), SPH_C32(0x23570000), + SPH_C32(0x23c90000), SPH_C32(0x5ce90000), SPH_C32(0x339401f1), + SPH_C32(0x306b4419), SPH_C32(0xdb245092), SPH_C32(0x82ebdff9), + SPH_C32(0x6ba7a344) }, + { SPH_C32(0x3cb60000), SPH_C32(0x8f310000), SPH_C32(0x50be0000), + SPH_C32(0xaa2e0148), SPH_C32(0xc191bd44), SPH_C32(0x5c7836cf), + SPH_C32(0xdc936ffe), SPH_C32(0xd0027371), SPH_C32(0x88b00000), + SPH_C32(0xbdc40000), SPH_C32(0xf3ce0000), SPH_C32(0x0e8c01f4), + SPH_C32(0x1c245bca), SPH_C32(0xafd24607), SPH_C32(0x37289812), + SPH_C32(0x57fa5cba) }, + { SPH_C32(0x07d70000), SPH_C32(0x22880000), SPH_C32(0xb6a20000), + SPH_C32(0x34240142), SPH_C32(0x8bce8689), SPH_C32(0xa5ac5167), + SPH_C32(0xf10d7145), SPH_C32(0x22fc18dd), SPH_C32(0x22c40000), + SPH_C32(0xc44b0000), SPH_C32(0xb1120000), SPH_C32(0xfc9801fa), + SPH_C32(0xbdbbc941), SPH_C32(0x6787e4bc), SPH_C32(0x84ddbe18), + SPH_C32(0x38c83d3f) }, + { SPH_C32(0xaf0d0000), SPH_C32(0xb4360000), SPH_C32(0xeabf0000), + SPH_C32(0x33fe0140), SPH_C32(0xf6a8130a), SPH_C32(0xba3421ed), + SPH_C32(0x4a6bf94d), SPH_C32(0xf87b98dd), SPH_C32(0x89230000), + SPH_C32(0x5a460000), SPH_C32(0x1e350000), SPH_C32(0xc18001ff), + SPH_C32(0x91f4d692), SPH_C32(0x1371f229), SPH_C32(0x311ef9f3), + SPH_C32(0x0495c2c1) }, + { SPH_C32(0x06440000), SPH_C32(0xc50a0000), SPH_C32(0x5b590000), + SPH_C32(0xfb280149), SPH_C32(0x061e0bd1), SPH_C32(0x190fe549), + SPH_C32(0xf73b10a4), SPH_C32(0x719386a6), SPH_C32(0xb0ec0000), + SPH_C32(0x18ce0000), SPH_C32(0xe6e80000), SPH_C32(0xaa4401f9), + SPH_C32(0x0752ea57), SPH_C32(0x3d6847b0), SPH_C32(0x1413494a), + SPH_C32(0x43de48e8) }, + { SPH_C32(0xae9e0000), SPH_C32(0x53b40000), SPH_C32(0x07440000), + SPH_C32(0xfcf2014b), SPH_C32(0x7b789e52), SPH_C32(0x069795c3), + SPH_C32(0x4c5d98ac), SPH_C32(0xab1406a6), SPH_C32(0x1b0b0000), + SPH_C32(0x86c30000), SPH_C32(0x49cf0000), SPH_C32(0x975c01fc), + SPH_C32(0x2b1df584), SPH_C32(0x499e5125), SPH_C32(0xa1d00ea1), + SPH_C32(0x7f83b716) }, + { SPH_C32(0xca570000), SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), + SPH_C32(0x060b0152), SPH_C32(0x14592320), SPH_C32(0xec526625), + SPH_C32(0x35dd13a8), SPH_C32(0xd74eb663), SPH_C32(0xb13b0000), + SPH_C32(0x80040000), SPH_C32(0xd16f0000), SPH_C32(0x4f6b01f3), + SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), SPH_C32(0x112fb6cb), + SPH_C32(0xaebbb10d) }, + { SPH_C32(0x628d0000), SPH_C32(0x3eb00000), SPH_C32(0xfeeb0000), + SPH_C32(0x01d10150), SPH_C32(0x693fb6a3), SPH_C32(0xf3ca16af), + SPH_C32(0x8ebb9ba0), SPH_C32(0x0dc93663), SPH_C32(0x1adc0000), + SPH_C32(0x1e090000), SPH_C32(0x7e480000), SPH_C32(0x727301f6), + SPH_C32(0x9d60b110), SPH_C32(0x5c8b798c), SPH_C32(0xa4ecf120), + SPH_C32(0x92e64ef3) }, + { SPH_C32(0xcbc40000), SPH_C32(0x4f8c0000), SPH_C32(0x4f0d0000), + SPH_C32(0xc9070159), SPH_C32(0x9989ae78), SPH_C32(0x50f1d20b), + SPH_C32(0x33eb7249), SPH_C32(0x84212818), SPH_C32(0x23130000), + SPH_C32(0x5c810000), SPH_C32(0x86950000), SPH_C32(0x19b701f0), + SPH_C32(0x0bc68dd5), SPH_C32(0x7292cc15), SPH_C32(0x81e14199), + SPH_C32(0xd5adc4da) }, + { SPH_C32(0x631e0000), SPH_C32(0xd9320000), SPH_C32(0x13100000), + SPH_C32(0xcedd015b), SPH_C32(0xe4ef3bfb), SPH_C32(0x4f69a281), + SPH_C32(0x888dfa41), SPH_C32(0x5ea6a818), SPH_C32(0x88f40000), + SPH_C32(0xc28c0000), SPH_C32(0x29b20000), SPH_C32(0x24af01f5), + SPH_C32(0x27899206), SPH_C32(0x0664da80), SPH_C32(0x34220672), + SPH_C32(0xe9f03b24) }, + { SPH_C32(0x587f0000), SPH_C32(0x748b0000), SPH_C32(0xf50c0000), + SPH_C32(0x50d70151), SPH_C32(0xaeb00036), SPH_C32(0xb6bdc529), + SPH_C32(0xa513e4fa), SPH_C32(0xac58c3b4), SPH_C32(0x22800000), + SPH_C32(0xbb030000), SPH_C32(0x6b6e0000), SPH_C32(0xd6bb01fb), + SPH_C32(0x8616008d), SPH_C32(0xce31783b), SPH_C32(0x87d72078), + SPH_C32(0x86c25aa1) }, + { SPH_C32(0xf0a50000), SPH_C32(0xe2350000), SPH_C32(0xa9110000), + SPH_C32(0x570d0153), SPH_C32(0xd3d695b5), SPH_C32(0xa925b5a3), + SPH_C32(0x1e756cf2), SPH_C32(0x76df43b4), SPH_C32(0x89670000), + SPH_C32(0x250e0000), SPH_C32(0xc4490000), SPH_C32(0xeba301fe), + SPH_C32(0xaa591f5e), SPH_C32(0xbac76eae), SPH_C32(0x32146793), + SPH_C32(0xba9fa55f) }, + { SPH_C32(0x59ec0000), SPH_C32(0x93090000), SPH_C32(0x18f70000), + SPH_C32(0x9fdb015a), SPH_C32(0x23608d6e), SPH_C32(0x0a1e7107), + SPH_C32(0xa325851b), SPH_C32(0xff375dcf), SPH_C32(0xb0a80000), + SPH_C32(0x67860000), SPH_C32(0x3c940000), SPH_C32(0x806701f8), + SPH_C32(0x3cff239b), SPH_C32(0x94dedb37), SPH_C32(0x1719d72a), + SPH_C32(0xfdd42f76) }, + { SPH_C32(0xf1360000), SPH_C32(0x05b70000), SPH_C32(0x44ea0000), + SPH_C32(0x98010158), SPH_C32(0x5e0618ed), SPH_C32(0x1586018d), + SPH_C32(0x18430d13), SPH_C32(0x25b0ddcf), SPH_C32(0x1b4f0000), + SPH_C32(0xf98b0000), SPH_C32(0x93b30000), SPH_C32(0xbd7f01fd), + SPH_C32(0x10b03c48), SPH_C32(0xe028cda2), SPH_C32(0xa2da90c1), + SPH_C32(0xc189d088) } +}; + +static const sph_u32 T512_63[2][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x033d0000), SPH_C32(0x08b30000), SPH_C32(0xf33a0000), + SPH_C32(0x3ac20007), SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), + SPH_C32(0x0ea5cfe3), SPH_C32(0xe6da7ffe), SPH_C32(0xa8da0000), + SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), SPH_C32(0x07da0002), + SPH_C32(0x7d669583), SPH_C32(0x1f98708a), SPH_C32(0xbb668808), + SPH_C32(0xda878000) } +}; + +#define INPUT_BIG do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T512_0[acc >> 1][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + m8 = rp[8]; \ + m9 = rp[9]; \ + mA = rp[10]; \ + mB = rp[11]; \ + mC = rp[12]; \ + mD = rp[13]; \ + mE = rp[14]; \ + mF = rp[15]; \ + acc = (acc << 8) | buf[1]; \ + rp = &T512_7[(acc >> 2) & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[2]; \ + rp = &T512_14[(acc >> 3) & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[3]; \ + rp = &T512_21[(acc >> 4) & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[4]; \ + rp = &T512_28[(acc >> 5) & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[5]; \ + rp = &T512_35[(acc >> 6) & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = (acc << 8) | buf[6]; \ + rp = &T512_42[(acc >> 7) & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_49[acc & 0x7f][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[7]; \ + rp = &T512_56[acc >> 1][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + rp = &T512_63[acc & 0x01][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + } while (0) + +#endif + +#if SPH_HAMSI_EXPAND_BIG == 8 + +static const sph_u32 T512_0[256][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xef0b0270), SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), + SPH_C32(0x69490000), SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), + SPH_C32(0x66140a51), SPH_C32(0x924f5d0a), SPH_C32(0xc96b0030), + SPH_C32(0xe7250000), SPH_C32(0x2f840000), SPH_C32(0x264f0000), + SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), SPH_C32(0x509f6984), + SPH_C32(0x9e69af68) }, + { SPH_C32(0xc96b0030), SPH_C32(0xe7250000), SPH_C32(0x2f840000), + SPH_C32(0x264f0000), SPH_C32(0x08695bf9), SPH_C32(0x6dfcf137), + SPH_C32(0x509f6984), SPH_C32(0x9e69af68), SPH_C32(0x26600240), + SPH_C32(0xddd80000), SPH_C32(0x722a0000), SPH_C32(0x4f060000), + SPH_C32(0x936667ff), SPH_C32(0x29f944ce), SPH_C32(0x368b63d5), + SPH_C32(0x0c26f262) }, + { SPH_C32(0x26600240), SPH_C32(0xddd80000), SPH_C32(0x722a0000), + SPH_C32(0x4f060000), SPH_C32(0x936667ff), SPH_C32(0x29f944ce), + SPH_C32(0x368b63d5), SPH_C32(0x0c26f262), SPH_C32(0xef0b0270), + SPH_C32(0x3afd0000), SPH_C32(0x5dae0000), SPH_C32(0x69490000), + SPH_C32(0x9b0f3c06), SPH_C32(0x4405b5f9), SPH_C32(0x66140a51), + SPH_C32(0x924f5d0a) }, + { SPH_C32(0x145a3c00), SPH_C32(0xb9e90000), SPH_C32(0x61270000), + SPH_C32(0xf1610000), SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), + SPH_C32(0x47a96720), SPH_C32(0xe18e24c5), SPH_C32(0x23671400), + SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), SPH_C32(0xfb750000), + SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), SPH_C32(0x02c40a3f), + SPH_C32(0xdc24e61f) }, + { SPH_C32(0xfb513e70), SPH_C32(0x83140000), SPH_C32(0x3c890000), + SPH_C32(0x98280000), SPH_C32(0x556e016a), SPH_C32(0xf44c8881), + SPH_C32(0x21bd6d71), SPH_C32(0x73c179cf), SPH_C32(0xea0c1430), + SPH_C32(0x2f9c0000), SPH_C32(0xdb430000), SPH_C32(0xdd3a0000), + SPH_C32(0x7ba47f9c), SPH_C32(0x955a547e), SPH_C32(0x525b63bb), + SPH_C32(0x424d4977) }, + { SPH_C32(0xdd313c30), SPH_C32(0x5ecc0000), SPH_C32(0x4ea30000), + SPH_C32(0xd72e0000), SPH_C32(0xc6086695), SPH_C32(0xddb5cc4f), + SPH_C32(0x17360ea4), SPH_C32(0x7fe78bad), SPH_C32(0x05071640), + SPH_C32(0x15610000), SPH_C32(0x86ed0000), SPH_C32(0xb4730000), + SPH_C32(0xe0ab439a), SPH_C32(0xd15fe187), SPH_C32(0x344f69ea), + SPH_C32(0xd002147d) }, + { SPH_C32(0x323a3e40), SPH_C32(0x64310000), SPH_C32(0x130d0000), + SPH_C32(0xbe670000), SPH_C32(0x5d075a93), SPH_C32(0x99b079b6), + SPH_C32(0x712204f5), SPH_C32(0xeda8d6a7), SPH_C32(0xcc6c1670), + SPH_C32(0xf2440000), SPH_C32(0xa9690000), SPH_C32(0x923c0000), + SPH_C32(0xe8c21863), SPH_C32(0xbca310b0), SPH_C32(0x64d0006e), + SPH_C32(0x4e6bbb15) }, + { SPH_C32(0x23671400), SPH_C32(0xc8b90000), SPH_C32(0xf4c70000), + SPH_C32(0xfb750000), SPH_C32(0x73cd2465), SPH_C32(0xf8a6a549), + SPH_C32(0x02c40a3f), SPH_C32(0xdc24e61f), SPH_C32(0x373d2800), + SPH_C32(0x71500000), SPH_C32(0x95e00000), SPH_C32(0x0a140000), + SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), SPH_C32(0x456d6d1f), + SPH_C32(0x3daac2da) }, + { SPH_C32(0xcc6c1670), SPH_C32(0xf2440000), SPH_C32(0xa9690000), + SPH_C32(0x923c0000), SPH_C32(0xe8c21863), SPH_C32(0xbca310b0), + SPH_C32(0x64d0006e), SPH_C32(0x4e6bbb15), SPH_C32(0xfe562830), + SPH_C32(0x96750000), SPH_C32(0xba640000), SPH_C32(0x2c5b0000), + SPH_C32(0xb5c542f0), SPH_C32(0x25136906), SPH_C32(0x15f2049b), + SPH_C32(0xa3c36db2) }, + { SPH_C32(0xea0c1430), SPH_C32(0x2f9c0000), SPH_C32(0xdb430000), + SPH_C32(0xdd3a0000), SPH_C32(0x7ba47f9c), SPH_C32(0x955a547e), + SPH_C32(0x525b63bb), SPH_C32(0x424d4977), SPH_C32(0x115d2a40), + SPH_C32(0xac880000), SPH_C32(0xe7ca0000), SPH_C32(0x45120000), + SPH_C32(0x2eca7ef6), SPH_C32(0x6116dcff), SPH_C32(0x73e60eca), + SPH_C32(0x318c30b8) }, + { SPH_C32(0x05071640), SPH_C32(0x15610000), SPH_C32(0x86ed0000), + SPH_C32(0xb4730000), SPH_C32(0xe0ab439a), SPH_C32(0xd15fe187), + SPH_C32(0x344f69ea), SPH_C32(0xd002147d), SPH_C32(0xd8362a70), + SPH_C32(0x4bad0000), SPH_C32(0xc84e0000), SPH_C32(0x635d0000), + SPH_C32(0x26a3250f), SPH_C32(0x0cea2dc8), SPH_C32(0x2379674e), + SPH_C32(0xafe59fd0) }, + { SPH_C32(0x373d2800), SPH_C32(0x71500000), SPH_C32(0x95e00000), + SPH_C32(0x0a140000), SPH_C32(0xbdac1909), SPH_C32(0x48ef9831), + SPH_C32(0x456d6d1f), SPH_C32(0x3daac2da), SPH_C32(0x145a3c00), + SPH_C32(0xb9e90000), SPH_C32(0x61270000), SPH_C32(0xf1610000), + SPH_C32(0xce613d6c), SPH_C32(0xb0493d78), SPH_C32(0x47a96720), + SPH_C32(0xe18e24c5) }, + { SPH_C32(0xd8362a70), SPH_C32(0x4bad0000), SPH_C32(0xc84e0000), + SPH_C32(0x635d0000), SPH_C32(0x26a3250f), SPH_C32(0x0cea2dc8), + SPH_C32(0x2379674e), SPH_C32(0xafe59fd0), SPH_C32(0xdd313c30), + SPH_C32(0x5ecc0000), SPH_C32(0x4ea30000), SPH_C32(0xd72e0000), + SPH_C32(0xc6086695), SPH_C32(0xddb5cc4f), SPH_C32(0x17360ea4), + SPH_C32(0x7fe78bad) }, + { SPH_C32(0xfe562830), SPH_C32(0x96750000), SPH_C32(0xba640000), + SPH_C32(0x2c5b0000), SPH_C32(0xb5c542f0), SPH_C32(0x25136906), + SPH_C32(0x15f2049b), SPH_C32(0xa3c36db2), SPH_C32(0x323a3e40), + SPH_C32(0x64310000), SPH_C32(0x130d0000), SPH_C32(0xbe670000), + SPH_C32(0x5d075a93), SPH_C32(0x99b079b6), SPH_C32(0x712204f5), + SPH_C32(0xeda8d6a7) }, + { SPH_C32(0x115d2a40), SPH_C32(0xac880000), SPH_C32(0xe7ca0000), + SPH_C32(0x45120000), SPH_C32(0x2eca7ef6), SPH_C32(0x6116dcff), + SPH_C32(0x73e60eca), SPH_C32(0x318c30b8), SPH_C32(0xfb513e70), + SPH_C32(0x83140000), SPH_C32(0x3c890000), SPH_C32(0x98280000), + SPH_C32(0x556e016a), SPH_C32(0xf44c8881), SPH_C32(0x21bd6d71), + SPH_C32(0x73c179cf) }, + { SPH_C32(0x54285c00), SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), + SPH_C32(0xa1c50000), SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), + SPH_C32(0x6bb0419d), SPH_C32(0x551b3782), SPH_C32(0x9cbb1800), + SPH_C32(0xb0d30000), SPH_C32(0x92510000), SPH_C32(0xed930000), + SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), SPH_C32(0x430633da), + SPH_C32(0x78cace29) }, + { SPH_C32(0xbb235e70), SPH_C32(0xd0100000), SPH_C32(0x98780000), + SPH_C32(0xc88c0000), SPH_C32(0x28ad5b76), SPH_C32(0xd0a07118), + SPH_C32(0x0da44bcc), SPH_C32(0xc7546a88), SPH_C32(0x55d01830), + SPH_C32(0x57f60000), SPH_C32(0xbdd50000), SPH_C32(0xcbdc0000), + SPH_C32(0x515318bc), SPH_C32(0x8ce824c3), SPH_C32(0x13995a5e), + SPH_C32(0xe6a36141) }, + { SPH_C32(0x9d435c30), SPH_C32(0x0dc80000), SPH_C32(0xea520000), + SPH_C32(0x878a0000), SPH_C32(0xbbcb3c89), SPH_C32(0xf95935d6), + SPH_C32(0x3b2f2819), SPH_C32(0xcb7298ea), SPH_C32(0xbadb1a40), + SPH_C32(0x6d0b0000), SPH_C32(0xe07b0000), SPH_C32(0xa2950000), + SPH_C32(0xca5c24ba), SPH_C32(0xc8ed913a), SPH_C32(0x758d500f), + SPH_C32(0x74ec3c4b) }, + { SPH_C32(0x72485e40), SPH_C32(0x37350000), SPH_C32(0xb7fc0000), + SPH_C32(0xeec30000), SPH_C32(0x20c4008f), SPH_C32(0xbd5c802f), + SPH_C32(0x5d3b2248), SPH_C32(0x593dc5e0), SPH_C32(0x73b01a70), + SPH_C32(0x8a2e0000), SPH_C32(0xcfff0000), SPH_C32(0x84da0000), + SPH_C32(0xc2357f43), SPH_C32(0xa511600d), SPH_C32(0x2512398b), + SPH_C32(0xea859323) }, + { SPH_C32(0x40726000), SPH_C32(0x53040000), SPH_C32(0xa4f10000), + SPH_C32(0x50a40000), SPH_C32(0x7dc35a1c), SPH_C32(0x24ecf999), + SPH_C32(0x2c1926bd), SPH_C32(0xb4951347), SPH_C32(0xbfdc0c00), + SPH_C32(0x786a0000), SPH_C32(0x66960000), SPH_C32(0x16e60000), + SPH_C32(0x2af76720), SPH_C32(0x19b270bd), SPH_C32(0x41c239e5), + SPH_C32(0xa4ee2836) }, + { SPH_C32(0xaf796270), SPH_C32(0x69f90000), SPH_C32(0xf95f0000), + SPH_C32(0x39ed0000), SPH_C32(0xe6cc661a), SPH_C32(0x60e94c60), + SPH_C32(0x4a0d2cec), SPH_C32(0x26da4e4d), SPH_C32(0x76b70c30), + SPH_C32(0x9f4f0000), SPH_C32(0x49120000), SPH_C32(0x30a90000), + SPH_C32(0x229e3cd9), SPH_C32(0x744e818a), SPH_C32(0x115d5061), + SPH_C32(0x3a87875e) }, + { SPH_C32(0x89196030), SPH_C32(0xb4210000), SPH_C32(0x8b750000), + SPH_C32(0x76eb0000), SPH_C32(0x75aa01e5), SPH_C32(0x491008ae), + SPH_C32(0x7c864f39), SPH_C32(0x2afcbc2f), SPH_C32(0x99bc0e40), + SPH_C32(0xa5b20000), SPH_C32(0x14bc0000), SPH_C32(0x59e00000), + SPH_C32(0xb99100df), SPH_C32(0x304b3473), SPH_C32(0x77495a30), + SPH_C32(0xa8c8da54) }, + { SPH_C32(0x66126240), SPH_C32(0x8edc0000), SPH_C32(0xd6db0000), + SPH_C32(0x1fa20000), SPH_C32(0xeea53de3), SPH_C32(0x0d15bd57), + SPH_C32(0x1a924568), SPH_C32(0xb8b3e125), SPH_C32(0x50d70e70), + SPH_C32(0x42970000), SPH_C32(0x3b380000), SPH_C32(0x7faf0000), + SPH_C32(0xb1f85b26), SPH_C32(0x5db7c544), SPH_C32(0x27d633b4), + SPH_C32(0x36a1753c) }, + { SPH_C32(0x774f4800), SPH_C32(0x22540000), SPH_C32(0x31110000), + SPH_C32(0x5ab00000), SPH_C32(0xc06f4315), SPH_C32(0x6c0361a8), + SPH_C32(0x69744ba2), SPH_C32(0x893fd19d), SPH_C32(0xab863000), + SPH_C32(0xc1830000), SPH_C32(0x07b10000), SPH_C32(0xe7870000), + SPH_C32(0xe4965a4c), SPH_C32(0xa9fb4dc5), SPH_C32(0x066b5ec5), + SPH_C32(0x45600cf3) }, + { SPH_C32(0x98444a70), SPH_C32(0x18a90000), SPH_C32(0x6cbf0000), + SPH_C32(0x33f90000), SPH_C32(0x5b607f13), SPH_C32(0x2806d451), + SPH_C32(0x0f6041f3), SPH_C32(0x1b708c97), SPH_C32(0x62ed3030), + SPH_C32(0x26a60000), SPH_C32(0x28350000), SPH_C32(0xc1c80000), + SPH_C32(0xecff01b5), SPH_C32(0xc407bcf2), SPH_C32(0x56f43741), + SPH_C32(0xdb09a39b) }, + { SPH_C32(0xbe244830), SPH_C32(0xc5710000), SPH_C32(0x1e950000), + SPH_C32(0x7cff0000), SPH_C32(0xc80618ec), SPH_C32(0x01ff909f), + SPH_C32(0x39eb2226), SPH_C32(0x17567ef5), SPH_C32(0x8de63240), + SPH_C32(0x1c5b0000), SPH_C32(0x759b0000), SPH_C32(0xa8810000), + SPH_C32(0x77f03db3), SPH_C32(0x8002090b), SPH_C32(0x30e03d10), + SPH_C32(0x4946fe91) }, + { SPH_C32(0x512f4a40), SPH_C32(0xff8c0000), SPH_C32(0x433b0000), + SPH_C32(0x15b60000), SPH_C32(0x530924ea), SPH_C32(0x45fa2566), + SPH_C32(0x5fff2877), SPH_C32(0x851923ff), SPH_C32(0x448d3270), + SPH_C32(0xfb7e0000), SPH_C32(0x5a1f0000), SPH_C32(0x8ece0000), + SPH_C32(0x7f99664a), SPH_C32(0xedfef83c), SPH_C32(0x607f5494), + SPH_C32(0xd72f51f9) }, + { SPH_C32(0x63157400), SPH_C32(0x9bbd0000), SPH_C32(0x50360000), + SPH_C32(0xabd10000), SPH_C32(0x0e0e7e79), SPH_C32(0xdc4a5cd0), + SPH_C32(0x2edd2c82), SPH_C32(0x68b1f558), SPH_C32(0x88e12400), + SPH_C32(0x093a0000), SPH_C32(0xf3760000), SPH_C32(0x1cf20000), + SPH_C32(0x975b7e29), SPH_C32(0x515de88c), SPH_C32(0x04af54fa), + SPH_C32(0x9944eaec) }, + { SPH_C32(0x8c1e7670), SPH_C32(0xa1400000), SPH_C32(0x0d980000), + SPH_C32(0xc2980000), SPH_C32(0x9501427f), SPH_C32(0x984fe929), + SPH_C32(0x48c926d3), SPH_C32(0xfafea852), SPH_C32(0x418a2430), + SPH_C32(0xee1f0000), SPH_C32(0xdcf20000), SPH_C32(0x3abd0000), + SPH_C32(0x9f3225d0), SPH_C32(0x3ca119bb), SPH_C32(0x54303d7e), + SPH_C32(0x072d4584) }, + { SPH_C32(0xaa7e7430), SPH_C32(0x7c980000), SPH_C32(0x7fb20000), + SPH_C32(0x8d9e0000), SPH_C32(0x06672580), SPH_C32(0xb1b6ade7), + SPH_C32(0x7e424506), SPH_C32(0xf6d85a30), SPH_C32(0xae812640), + SPH_C32(0xd4e20000), SPH_C32(0x815c0000), SPH_C32(0x53f40000), + SPH_C32(0x043d19d6), SPH_C32(0x78a4ac42), SPH_C32(0x3224372f), + SPH_C32(0x9562188e) }, + { SPH_C32(0x45757640), SPH_C32(0x46650000), SPH_C32(0x221c0000), + SPH_C32(0xe4d70000), SPH_C32(0x9d681986), SPH_C32(0xf5b3181e), + SPH_C32(0x18564f57), SPH_C32(0x6497073a), SPH_C32(0x67ea2670), + SPH_C32(0x33c70000), SPH_C32(0xaed80000), SPH_C32(0x75bb0000), + SPH_C32(0x0c54422f), SPH_C32(0x15585d75), SPH_C32(0x62bb5eab), + SPH_C32(0x0b0bb7e6) }, + { SPH_C32(0x9cbb1800), SPH_C32(0xb0d30000), SPH_C32(0x92510000), + SPH_C32(0xed930000), SPH_C32(0x593a4345), SPH_C32(0xe114d5f4), + SPH_C32(0x430633da), SPH_C32(0x78cace29), SPH_C32(0xc8934400), + SPH_C32(0x5a3e0000), SPH_C32(0x57870000), SPH_C32(0x4c560000), + SPH_C32(0xea982435), SPH_C32(0x75b11115), SPH_C32(0x28b67247), + SPH_C32(0x2dd1f9ab) }, + { SPH_C32(0x73b01a70), SPH_C32(0x8a2e0000), SPH_C32(0xcfff0000), + SPH_C32(0x84da0000), SPH_C32(0xc2357f43), SPH_C32(0xa511600d), + SPH_C32(0x2512398b), SPH_C32(0xea859323), SPH_C32(0x01f84430), + SPH_C32(0xbd1b0000), SPH_C32(0x78030000), SPH_C32(0x6a190000), + SPH_C32(0xe2f17fcc), SPH_C32(0x184de022), SPH_C32(0x78291bc3), + SPH_C32(0xb3b856c3) }, + { SPH_C32(0x55d01830), SPH_C32(0x57f60000), SPH_C32(0xbdd50000), + SPH_C32(0xcbdc0000), SPH_C32(0x515318bc), SPH_C32(0x8ce824c3), + SPH_C32(0x13995a5e), SPH_C32(0xe6a36141), SPH_C32(0xeef34640), + SPH_C32(0x87e60000), SPH_C32(0x25ad0000), SPH_C32(0x03500000), + SPH_C32(0x79fe43ca), SPH_C32(0x5c4855db), SPH_C32(0x1e3d1192), + SPH_C32(0x21f70bc9) }, + { SPH_C32(0xbadb1a40), SPH_C32(0x6d0b0000), SPH_C32(0xe07b0000), + SPH_C32(0xa2950000), SPH_C32(0xca5c24ba), SPH_C32(0xc8ed913a), + SPH_C32(0x758d500f), SPH_C32(0x74ec3c4b), SPH_C32(0x27984670), + SPH_C32(0x60c30000), SPH_C32(0x0a290000), SPH_C32(0x251f0000), + SPH_C32(0x71971833), SPH_C32(0x31b4a4ec), SPH_C32(0x4ea27816), + SPH_C32(0xbf9ea4a1) }, + { SPH_C32(0x88e12400), SPH_C32(0x093a0000), SPH_C32(0xf3760000), + SPH_C32(0x1cf20000), SPH_C32(0x975b7e29), SPH_C32(0x515de88c), + SPH_C32(0x04af54fa), SPH_C32(0x9944eaec), SPH_C32(0xebf45000), + SPH_C32(0x92870000), SPH_C32(0xa3400000), SPH_C32(0xb7230000), + SPH_C32(0x99550050), SPH_C32(0x8d17b45c), SPH_C32(0x2a727878), + SPH_C32(0xf1f51fb4) }, + { SPH_C32(0x67ea2670), SPH_C32(0x33c70000), SPH_C32(0xaed80000), + SPH_C32(0x75bb0000), SPH_C32(0x0c54422f), SPH_C32(0x15585d75), + SPH_C32(0x62bb5eab), SPH_C32(0x0b0bb7e6), SPH_C32(0x229f5030), + SPH_C32(0x75a20000), SPH_C32(0x8cc40000), SPH_C32(0x916c0000), + SPH_C32(0x913c5ba9), SPH_C32(0xe0eb456b), SPH_C32(0x7aed11fc), + SPH_C32(0x6f9cb0dc) }, + { SPH_C32(0x418a2430), SPH_C32(0xee1f0000), SPH_C32(0xdcf20000), + SPH_C32(0x3abd0000), SPH_C32(0x9f3225d0), SPH_C32(0x3ca119bb), + SPH_C32(0x54303d7e), SPH_C32(0x072d4584), SPH_C32(0xcd945240), + SPH_C32(0x4f5f0000), SPH_C32(0xd16a0000), SPH_C32(0xf8250000), + SPH_C32(0x0a3367af), SPH_C32(0xa4eef092), SPH_C32(0x1cf91bad), + SPH_C32(0xfdd3edd6) }, + { SPH_C32(0xae812640), SPH_C32(0xd4e20000), SPH_C32(0x815c0000), + SPH_C32(0x53f40000), SPH_C32(0x043d19d6), SPH_C32(0x78a4ac42), + SPH_C32(0x3224372f), SPH_C32(0x9562188e), SPH_C32(0x04ff5270), + SPH_C32(0xa87a0000), SPH_C32(0xfeee0000), SPH_C32(0xde6a0000), + SPH_C32(0x025a3c56), SPH_C32(0xc91201a5), SPH_C32(0x4c667229), + SPH_C32(0x63ba42be) }, + { SPH_C32(0xbfdc0c00), SPH_C32(0x786a0000), SPH_C32(0x66960000), + SPH_C32(0x16e60000), SPH_C32(0x2af76720), SPH_C32(0x19b270bd), + SPH_C32(0x41c239e5), SPH_C32(0xa4ee2836), SPH_C32(0xffae6c00), + SPH_C32(0x2b6e0000), SPH_C32(0xc2670000), SPH_C32(0x46420000), + SPH_C32(0x57343d3c), SPH_C32(0x3d5e8924), SPH_C32(0x6ddb1f58), + SPH_C32(0x107b3b71) }, + { SPH_C32(0x50d70e70), SPH_C32(0x42970000), SPH_C32(0x3b380000), + SPH_C32(0x7faf0000), SPH_C32(0xb1f85b26), SPH_C32(0x5db7c544), + SPH_C32(0x27d633b4), SPH_C32(0x36a1753c), SPH_C32(0x36c56c30), + SPH_C32(0xcc4b0000), SPH_C32(0xede30000), SPH_C32(0x600d0000), + SPH_C32(0x5f5d66c5), SPH_C32(0x50a27813), SPH_C32(0x3d4476dc), + SPH_C32(0x8e129419) }, + { SPH_C32(0x76b70c30), SPH_C32(0x9f4f0000), SPH_C32(0x49120000), + SPH_C32(0x30a90000), SPH_C32(0x229e3cd9), SPH_C32(0x744e818a), + SPH_C32(0x115d5061), SPH_C32(0x3a87875e), SPH_C32(0xd9ce6e40), + SPH_C32(0xf6b60000), SPH_C32(0xb04d0000), SPH_C32(0x09440000), + SPH_C32(0xc4525ac3), SPH_C32(0x14a7cdea), SPH_C32(0x5b507c8d), + SPH_C32(0x1c5dc913) }, + { SPH_C32(0x99bc0e40), SPH_C32(0xa5b20000), SPH_C32(0x14bc0000), + SPH_C32(0x59e00000), SPH_C32(0xb99100df), SPH_C32(0x304b3473), + SPH_C32(0x77495a30), SPH_C32(0xa8c8da54), SPH_C32(0x10a56e70), + SPH_C32(0x11930000), SPH_C32(0x9fc90000), SPH_C32(0x2f0b0000), + SPH_C32(0xcc3b013a), SPH_C32(0x795b3cdd), SPH_C32(0x0bcf1509), + SPH_C32(0x8234667b) }, + { SPH_C32(0xab863000), SPH_C32(0xc1830000), SPH_C32(0x07b10000), + SPH_C32(0xe7870000), SPH_C32(0xe4965a4c), SPH_C32(0xa9fb4dc5), + SPH_C32(0x066b5ec5), SPH_C32(0x45600cf3), SPH_C32(0xdcc97800), + SPH_C32(0xe3d70000), SPH_C32(0x36a00000), SPH_C32(0xbd370000), + SPH_C32(0x24f91959), SPH_C32(0xc5f82c6d), SPH_C32(0x6f1f1567), + SPH_C32(0xcc5fdd6e) }, + { SPH_C32(0x448d3270), SPH_C32(0xfb7e0000), SPH_C32(0x5a1f0000), + SPH_C32(0x8ece0000), SPH_C32(0x7f99664a), SPH_C32(0xedfef83c), + SPH_C32(0x607f5494), SPH_C32(0xd72f51f9), SPH_C32(0x15a27830), + SPH_C32(0x04f20000), SPH_C32(0x19240000), SPH_C32(0x9b780000), + SPH_C32(0x2c9042a0), SPH_C32(0xa804dd5a), SPH_C32(0x3f807ce3), + SPH_C32(0x52367206) }, + { SPH_C32(0x62ed3030), SPH_C32(0x26a60000), SPH_C32(0x28350000), + SPH_C32(0xc1c80000), SPH_C32(0xecff01b5), SPH_C32(0xc407bcf2), + SPH_C32(0x56f43741), SPH_C32(0xdb09a39b), SPH_C32(0xfaa97a40), + SPH_C32(0x3e0f0000), SPH_C32(0x448a0000), SPH_C32(0xf2310000), + SPH_C32(0xb79f7ea6), SPH_C32(0xec0168a3), SPH_C32(0x599476b2), + SPH_C32(0xc0792f0c) }, + { SPH_C32(0x8de63240), SPH_C32(0x1c5b0000), SPH_C32(0x759b0000), + SPH_C32(0xa8810000), SPH_C32(0x77f03db3), SPH_C32(0x8002090b), + SPH_C32(0x30e03d10), SPH_C32(0x4946fe91), SPH_C32(0x33c27a70), + SPH_C32(0xd92a0000), SPH_C32(0x6b0e0000), SPH_C32(0xd47e0000), + SPH_C32(0xbff6255f), SPH_C32(0x81fd9994), SPH_C32(0x090b1f36), + SPH_C32(0x5e108064) }, + { SPH_C32(0xc8934400), SPH_C32(0x5a3e0000), SPH_C32(0x57870000), + SPH_C32(0x4c560000), SPH_C32(0xea982435), SPH_C32(0x75b11115), + SPH_C32(0x28b67247), SPH_C32(0x2dd1f9ab), SPH_C32(0x54285c00), + SPH_C32(0xeaed0000), SPH_C32(0xc5d60000), SPH_C32(0xa1c50000), + SPH_C32(0xb3a26770), SPH_C32(0x94a5c4e1), SPH_C32(0x6bb0419d), + SPH_C32(0x551b3782) }, + { SPH_C32(0x27984670), SPH_C32(0x60c30000), SPH_C32(0x0a290000), + SPH_C32(0x251f0000), SPH_C32(0x71971833), SPH_C32(0x31b4a4ec), + SPH_C32(0x4ea27816), SPH_C32(0xbf9ea4a1), SPH_C32(0x9d435c30), + SPH_C32(0x0dc80000), SPH_C32(0xea520000), SPH_C32(0x878a0000), + SPH_C32(0xbbcb3c89), SPH_C32(0xf95935d6), SPH_C32(0x3b2f2819), + SPH_C32(0xcb7298ea) }, + { SPH_C32(0x01f84430), SPH_C32(0xbd1b0000), SPH_C32(0x78030000), + SPH_C32(0x6a190000), SPH_C32(0xe2f17fcc), SPH_C32(0x184de022), + SPH_C32(0x78291bc3), SPH_C32(0xb3b856c3), SPH_C32(0x72485e40), + SPH_C32(0x37350000), SPH_C32(0xb7fc0000), SPH_C32(0xeec30000), + SPH_C32(0x20c4008f), SPH_C32(0xbd5c802f), SPH_C32(0x5d3b2248), + SPH_C32(0x593dc5e0) }, + { SPH_C32(0xeef34640), SPH_C32(0x87e60000), SPH_C32(0x25ad0000), + SPH_C32(0x03500000), SPH_C32(0x79fe43ca), SPH_C32(0x5c4855db), + SPH_C32(0x1e3d1192), SPH_C32(0x21f70bc9), SPH_C32(0xbb235e70), + SPH_C32(0xd0100000), SPH_C32(0x98780000), SPH_C32(0xc88c0000), + SPH_C32(0x28ad5b76), SPH_C32(0xd0a07118), SPH_C32(0x0da44bcc), + SPH_C32(0xc7546a88) }, + { SPH_C32(0xdcc97800), SPH_C32(0xe3d70000), SPH_C32(0x36a00000), + SPH_C32(0xbd370000), SPH_C32(0x24f91959), SPH_C32(0xc5f82c6d), + SPH_C32(0x6f1f1567), SPH_C32(0xcc5fdd6e), SPH_C32(0x774f4800), + SPH_C32(0x22540000), SPH_C32(0x31110000), SPH_C32(0x5ab00000), + SPH_C32(0xc06f4315), SPH_C32(0x6c0361a8), SPH_C32(0x69744ba2), + SPH_C32(0x893fd19d) }, + { SPH_C32(0x33c27a70), SPH_C32(0xd92a0000), SPH_C32(0x6b0e0000), + SPH_C32(0xd47e0000), SPH_C32(0xbff6255f), SPH_C32(0x81fd9994), + SPH_C32(0x090b1f36), SPH_C32(0x5e108064), SPH_C32(0xbe244830), + SPH_C32(0xc5710000), SPH_C32(0x1e950000), SPH_C32(0x7cff0000), + SPH_C32(0xc80618ec), SPH_C32(0x01ff909f), SPH_C32(0x39eb2226), + SPH_C32(0x17567ef5) }, + { SPH_C32(0x15a27830), SPH_C32(0x04f20000), SPH_C32(0x19240000), + SPH_C32(0x9b780000), SPH_C32(0x2c9042a0), SPH_C32(0xa804dd5a), + SPH_C32(0x3f807ce3), SPH_C32(0x52367206), SPH_C32(0x512f4a40), + SPH_C32(0xff8c0000), SPH_C32(0x433b0000), SPH_C32(0x15b60000), + SPH_C32(0x530924ea), SPH_C32(0x45fa2566), SPH_C32(0x5fff2877), + SPH_C32(0x851923ff) }, + { SPH_C32(0xfaa97a40), SPH_C32(0x3e0f0000), SPH_C32(0x448a0000), + SPH_C32(0xf2310000), SPH_C32(0xb79f7ea6), SPH_C32(0xec0168a3), + SPH_C32(0x599476b2), SPH_C32(0xc0792f0c), SPH_C32(0x98444a70), + SPH_C32(0x18a90000), SPH_C32(0x6cbf0000), SPH_C32(0x33f90000), + SPH_C32(0x5b607f13), SPH_C32(0x2806d451), SPH_C32(0x0f6041f3), + SPH_C32(0x1b708c97) }, + { SPH_C32(0xebf45000), SPH_C32(0x92870000), SPH_C32(0xa3400000), + SPH_C32(0xb7230000), SPH_C32(0x99550050), SPH_C32(0x8d17b45c), + SPH_C32(0x2a727878), SPH_C32(0xf1f51fb4), SPH_C32(0x63157400), + SPH_C32(0x9bbd0000), SPH_C32(0x50360000), SPH_C32(0xabd10000), + SPH_C32(0x0e0e7e79), SPH_C32(0xdc4a5cd0), SPH_C32(0x2edd2c82), + SPH_C32(0x68b1f558) }, + { SPH_C32(0x04ff5270), SPH_C32(0xa87a0000), SPH_C32(0xfeee0000), + SPH_C32(0xde6a0000), SPH_C32(0x025a3c56), SPH_C32(0xc91201a5), + SPH_C32(0x4c667229), SPH_C32(0x63ba42be), SPH_C32(0xaa7e7430), + SPH_C32(0x7c980000), SPH_C32(0x7fb20000), SPH_C32(0x8d9e0000), + SPH_C32(0x06672580), SPH_C32(0xb1b6ade7), SPH_C32(0x7e424506), + SPH_C32(0xf6d85a30) }, + { SPH_C32(0x229f5030), SPH_C32(0x75a20000), SPH_C32(0x8cc40000), + SPH_C32(0x916c0000), SPH_C32(0x913c5ba9), SPH_C32(0xe0eb456b), + SPH_C32(0x7aed11fc), SPH_C32(0x6f9cb0dc), SPH_C32(0x45757640), + SPH_C32(0x46650000), SPH_C32(0x221c0000), SPH_C32(0xe4d70000), + SPH_C32(0x9d681986), SPH_C32(0xf5b3181e), SPH_C32(0x18564f57), + SPH_C32(0x6497073a) }, + { SPH_C32(0xcd945240), SPH_C32(0x4f5f0000), SPH_C32(0xd16a0000), + SPH_C32(0xf8250000), SPH_C32(0x0a3367af), SPH_C32(0xa4eef092), + SPH_C32(0x1cf91bad), SPH_C32(0xfdd3edd6), SPH_C32(0x8c1e7670), + SPH_C32(0xa1400000), SPH_C32(0x0d980000), SPH_C32(0xc2980000), + SPH_C32(0x9501427f), SPH_C32(0x984fe929), SPH_C32(0x48c926d3), + SPH_C32(0xfafea852) }, + { SPH_C32(0xffae6c00), SPH_C32(0x2b6e0000), SPH_C32(0xc2670000), + SPH_C32(0x46420000), SPH_C32(0x57343d3c), SPH_C32(0x3d5e8924), + SPH_C32(0x6ddb1f58), SPH_C32(0x107b3b71), SPH_C32(0x40726000), + SPH_C32(0x53040000), SPH_C32(0xa4f10000), SPH_C32(0x50a40000), + SPH_C32(0x7dc35a1c), SPH_C32(0x24ecf999), SPH_C32(0x2c1926bd), + SPH_C32(0xb4951347) }, + { SPH_C32(0x10a56e70), SPH_C32(0x11930000), SPH_C32(0x9fc90000), + SPH_C32(0x2f0b0000), SPH_C32(0xcc3b013a), SPH_C32(0x795b3cdd), + SPH_C32(0x0bcf1509), SPH_C32(0x8234667b), SPH_C32(0x89196030), + SPH_C32(0xb4210000), SPH_C32(0x8b750000), SPH_C32(0x76eb0000), + SPH_C32(0x75aa01e5), SPH_C32(0x491008ae), SPH_C32(0x7c864f39), + SPH_C32(0x2afcbc2f) }, + { SPH_C32(0x36c56c30), SPH_C32(0xcc4b0000), SPH_C32(0xede30000), + SPH_C32(0x600d0000), SPH_C32(0x5f5d66c5), SPH_C32(0x50a27813), + SPH_C32(0x3d4476dc), SPH_C32(0x8e129419), SPH_C32(0x66126240), + SPH_C32(0x8edc0000), SPH_C32(0xd6db0000), SPH_C32(0x1fa20000), + SPH_C32(0xeea53de3), SPH_C32(0x0d15bd57), SPH_C32(0x1a924568), + SPH_C32(0xb8b3e125) }, + { SPH_C32(0xd9ce6e40), SPH_C32(0xf6b60000), SPH_C32(0xb04d0000), + SPH_C32(0x09440000), SPH_C32(0xc4525ac3), SPH_C32(0x14a7cdea), + SPH_C32(0x5b507c8d), SPH_C32(0x1c5dc913), SPH_C32(0xaf796270), + SPH_C32(0x69f90000), SPH_C32(0xf95f0000), SPH_C32(0x39ed0000), + SPH_C32(0xe6cc661a), SPH_C32(0x60e94c60), SPH_C32(0x4a0d2cec), + SPH_C32(0x26da4e4d) }, + { SPH_C32(0x29449c00), SPH_C32(0x64e70000), SPH_C32(0xf24b0000), + SPH_C32(0xc2f30000), SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), + SPH_C32(0xf3e04259), SPH_C32(0x8d0d9ec4), SPH_C32(0x466d0c00), + SPH_C32(0x08620000), SPH_C32(0xdd5d0000), SPH_C32(0xbadd0000), + SPH_C32(0x6a927942), SPH_C32(0x441f2b93), SPH_C32(0x218ace6f), + SPH_C32(0xbf2c0be2) }, + { SPH_C32(0xc64f9e70), SPH_C32(0x5e1a0000), SPH_C32(0xafe50000), + SPH_C32(0xabba0000), SPH_C32(0x95d17289), SPH_C32(0x12c782bc), + SPH_C32(0x95f44808), SPH_C32(0x1f42c3ce), SPH_C32(0x8f060c30), + SPH_C32(0xef470000), SPH_C32(0xf2d90000), SPH_C32(0x9c920000), + SPH_C32(0x62fb22bb), SPH_C32(0x29e3daa4), SPH_C32(0x7115a7eb), + SPH_C32(0x2145a48a) }, + { SPH_C32(0xe02f9c30), SPH_C32(0x83c20000), SPH_C32(0xddcf0000), + SPH_C32(0xe4bc0000), SPH_C32(0x06b71576), SPH_C32(0x3b3ec672), + SPH_C32(0xa37f2bdd), SPH_C32(0x136431ac), SPH_C32(0x600d0e40), + SPH_C32(0xd5ba0000), SPH_C32(0xaf770000), SPH_C32(0xf5db0000), + SPH_C32(0xf9f41ebd), SPH_C32(0x6de66f5d), SPH_C32(0x1701adba), + SPH_C32(0xb30af980) }, + { SPH_C32(0x0f249e40), SPH_C32(0xb93f0000), SPH_C32(0x80610000), + SPH_C32(0x8df50000), SPH_C32(0x9db82970), SPH_C32(0x7f3b738b), + SPH_C32(0xc56b218c), SPH_C32(0x812b6ca6), SPH_C32(0xa9660e70), + SPH_C32(0x329f0000), SPH_C32(0x80f30000), SPH_C32(0xd3940000), + SPH_C32(0xf19d4544), SPH_C32(0x001a9e6a), SPH_C32(0x479ec43e), + SPH_C32(0x2d6356e8) }, + { SPH_C32(0x3d1ea000), SPH_C32(0xdd0e0000), SPH_C32(0x936c0000), + SPH_C32(0x33920000), SPH_C32(0xc0bf73e3), SPH_C32(0xe68b0a3d), + SPH_C32(0xb4492579), SPH_C32(0x6c83ba01), SPH_C32(0x650a1800), + SPH_C32(0xc0db0000), SPH_C32(0x299a0000), SPH_C32(0x41a80000), + SPH_C32(0x195f5d27), SPH_C32(0xbcb98eda), SPH_C32(0x234ec450), + SPH_C32(0x6308edfd) }, + { SPH_C32(0xd215a270), SPH_C32(0xe7f30000), SPH_C32(0xcec20000), + SPH_C32(0x5adb0000), SPH_C32(0x5bb04fe5), SPH_C32(0xa28ebfc4), + SPH_C32(0xd25d2f28), SPH_C32(0xfecce70b), SPH_C32(0xac611830), + SPH_C32(0x27fe0000), SPH_C32(0x061e0000), SPH_C32(0x67e70000), + SPH_C32(0x113606de), SPH_C32(0xd1457fed), SPH_C32(0x73d1add4), + SPH_C32(0xfd614295) }, + { SPH_C32(0xf475a030), SPH_C32(0x3a2b0000), SPH_C32(0xbce80000), + SPH_C32(0x15dd0000), SPH_C32(0xc8d6281a), SPH_C32(0x8b77fb0a), + SPH_C32(0xe4d64cfd), SPH_C32(0xf2ea1569), SPH_C32(0x436a1a40), + SPH_C32(0x1d030000), SPH_C32(0x5bb00000), SPH_C32(0x0eae0000), + SPH_C32(0x8a393ad8), SPH_C32(0x9540ca14), SPH_C32(0x15c5a785), + SPH_C32(0x6f2e1f9f) }, + { SPH_C32(0x1b7ea240), SPH_C32(0x00d60000), SPH_C32(0xe1460000), + SPH_C32(0x7c940000), SPH_C32(0x53d9141c), SPH_C32(0xcf724ef3), + SPH_C32(0x82c246ac), SPH_C32(0x60a54863), SPH_C32(0x8a011a70), + SPH_C32(0xfa260000), SPH_C32(0x74340000), SPH_C32(0x28e10000), + SPH_C32(0x82506121), SPH_C32(0xf8bc3b23), SPH_C32(0x455ace01), + SPH_C32(0xf147b0f7) }, + { SPH_C32(0x0a238800), SPH_C32(0xac5e0000), SPH_C32(0x068c0000), + SPH_C32(0x39860000), SPH_C32(0x7d136aea), SPH_C32(0xae64920c), + SPH_C32(0xf1244866), SPH_C32(0x512978db), SPH_C32(0x71502400), + SPH_C32(0x79320000), SPH_C32(0x48bd0000), SPH_C32(0xb0c90000), + SPH_C32(0xd73e604b), SPH_C32(0x0cf0b3a2), SPH_C32(0x64e7a370), + SPH_C32(0x8286c938) }, + { SPH_C32(0xe5288a70), SPH_C32(0x96a30000), SPH_C32(0x5b220000), + SPH_C32(0x50cf0000), SPH_C32(0xe61c56ec), SPH_C32(0xea6127f5), + SPH_C32(0x97304237), SPH_C32(0xc36625d1), SPH_C32(0xb83b2430), + SPH_C32(0x9e170000), SPH_C32(0x67390000), SPH_C32(0x96860000), + SPH_C32(0xdf573bb2), SPH_C32(0x610c4295), SPH_C32(0x3478caf4), + SPH_C32(0x1cef6650) }, + { SPH_C32(0xc3488830), SPH_C32(0x4b7b0000), SPH_C32(0x29080000), + SPH_C32(0x1fc90000), SPH_C32(0x757a3113), SPH_C32(0xc398633b), + SPH_C32(0xa1bb21e2), SPH_C32(0xcf40d7b3), SPH_C32(0x57302640), + SPH_C32(0xa4ea0000), SPH_C32(0x3a970000), SPH_C32(0xffcf0000), + SPH_C32(0x445807b4), SPH_C32(0x2509f76c), SPH_C32(0x526cc0a5), + SPH_C32(0x8ea03b5a) }, + { SPH_C32(0x2c438a40), SPH_C32(0x71860000), SPH_C32(0x74a60000), + SPH_C32(0x76800000), SPH_C32(0xee750d15), SPH_C32(0x879dd6c2), + SPH_C32(0xc7af2bb3), SPH_C32(0x5d0f8ab9), SPH_C32(0x9e5b2670), + SPH_C32(0x43cf0000), SPH_C32(0x15130000), SPH_C32(0xd9800000), + SPH_C32(0x4c315c4d), SPH_C32(0x48f5065b), SPH_C32(0x02f3a921), + SPH_C32(0x10c99432) }, + { SPH_C32(0x1e79b400), SPH_C32(0x15b70000), SPH_C32(0x67ab0000), + SPH_C32(0xc8e70000), SPH_C32(0xb3725786), SPH_C32(0x1e2daf74), + SPH_C32(0xb68d2f46), SPH_C32(0xb0a75c1e), SPH_C32(0x52373000), + SPH_C32(0xb18b0000), SPH_C32(0xbc7a0000), SPH_C32(0x4bbc0000), + SPH_C32(0xa4f3442e), SPH_C32(0xf45616eb), SPH_C32(0x6623a94f), + SPH_C32(0x5ea22f27) }, + { SPH_C32(0xf172b670), SPH_C32(0x2f4a0000), SPH_C32(0x3a050000), + SPH_C32(0xa1ae0000), SPH_C32(0x287d6b80), SPH_C32(0x5a281a8d), + SPH_C32(0xd0992517), SPH_C32(0x22e80114), SPH_C32(0x9b5c3030), + SPH_C32(0x56ae0000), SPH_C32(0x93fe0000), SPH_C32(0x6df30000), + SPH_C32(0xac9a1fd7), SPH_C32(0x99aae7dc), SPH_C32(0x36bcc0cb), + SPH_C32(0xc0cb804f) }, + { SPH_C32(0xd712b430), SPH_C32(0xf2920000), SPH_C32(0x482f0000), + SPH_C32(0xeea80000), SPH_C32(0xbb1b0c7f), SPH_C32(0x73d15e43), + SPH_C32(0xe61246c2), SPH_C32(0x2ecef376), SPH_C32(0x74573240), + SPH_C32(0x6c530000), SPH_C32(0xce500000), SPH_C32(0x04ba0000), + SPH_C32(0x379523d1), SPH_C32(0xddaf5225), SPH_C32(0x50a8ca9a), + SPH_C32(0x5284dd45) }, + { SPH_C32(0x3819b640), SPH_C32(0xc86f0000), SPH_C32(0x15810000), + SPH_C32(0x87e10000), SPH_C32(0x20143079), SPH_C32(0x37d4ebba), + SPH_C32(0x80064c93), SPH_C32(0xbc81ae7c), SPH_C32(0xbd3c3270), + SPH_C32(0x8b760000), SPH_C32(0xe1d40000), SPH_C32(0x22f50000), + SPH_C32(0x3ffc7828), SPH_C32(0xb053a312), SPH_C32(0x0037a31e), + SPH_C32(0xcced722d) }, + { SPH_C32(0x7d6cc000), SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), + SPH_C32(0x63360000), SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), + SPH_C32(0x985003c4), SPH_C32(0xd816a946), SPH_C32(0xdad61400), + SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), SPH_C32(0x574e0000), + SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), SPH_C32(0x628cfdb5), + SPH_C32(0xc7e6c5cb) }, + { SPH_C32(0x9267c270), SPH_C32(0xb4f70000), SPH_C32(0x6a330000), + SPH_C32(0x0a7f0000), SPH_C32(0x267315f9), SPH_C32(0x8662465d), + SPH_C32(0xfe440995), SPH_C32(0x4a59f44c), SPH_C32(0x13bd1430), + SPH_C32(0x5f940000), SPH_C32(0x60880000), SPH_C32(0x71010000), + SPH_C32(0x3bc161fe), SPH_C32(0xc8f70f50), SPH_C32(0x32139431), + SPH_C32(0x598f6aa3) }, + { SPH_C32(0xb407c030), SPH_C32(0x692f0000), SPH_C32(0x18190000), + SPH_C32(0x45790000), SPH_C32(0xb5157206), SPH_C32(0xaf9b0293), + SPH_C32(0xc8cf6a40), SPH_C32(0x467f062e), SPH_C32(0xfcb61640), + SPH_C32(0x65690000), SPH_C32(0x3d260000), SPH_C32(0x18480000), + SPH_C32(0xa0ce5df8), SPH_C32(0x8cf2baa9), SPH_C32(0x54079e60), + SPH_C32(0xcbc037a9) }, + { SPH_C32(0x5b0cc240), SPH_C32(0x53d20000), SPH_C32(0x45b70000), + SPH_C32(0x2c300000), SPH_C32(0x2e1a4e00), SPH_C32(0xeb9eb76a), + SPH_C32(0xaedb6011), SPH_C32(0xd4305b24), SPH_C32(0x35dd1670), + SPH_C32(0x824c0000), SPH_C32(0x12a20000), SPH_C32(0x3e070000), + SPH_C32(0xa8a70601), SPH_C32(0xe10e4b9e), SPH_C32(0x0498f7e4), + SPH_C32(0x55a998c1) }, + { SPH_C32(0x6936fc00), SPH_C32(0x37e30000), SPH_C32(0x56ba0000), + SPH_C32(0x92570000), SPH_C32(0x731d1493), SPH_C32(0x722ecedc), + SPH_C32(0xdff964e4), SPH_C32(0x39988d83), SPH_C32(0xf9b10000), + SPH_C32(0x70080000), SPH_C32(0xbbcb0000), SPH_C32(0xac3b0000), + SPH_C32(0x40651e62), SPH_C32(0x5dad5b2e), SPH_C32(0x6048f78a), + SPH_C32(0x1bc223d4) }, + { SPH_C32(0x863dfe70), SPH_C32(0x0d1e0000), SPH_C32(0x0b140000), + SPH_C32(0xfb1e0000), SPH_C32(0xe8122895), SPH_C32(0x362b7b25), + SPH_C32(0xb9ed6eb5), SPH_C32(0xabd7d089), SPH_C32(0x30da0030), + SPH_C32(0x972d0000), SPH_C32(0x944f0000), SPH_C32(0x8a740000), + SPH_C32(0x480c459b), SPH_C32(0x3051aa19), SPH_C32(0x30d79e0e), + SPH_C32(0x85ab8cbc) }, + { SPH_C32(0xa05dfc30), SPH_C32(0xd0c60000), SPH_C32(0x793e0000), + SPH_C32(0xb4180000), SPH_C32(0x7b744f6a), SPH_C32(0x1fd23feb), + SPH_C32(0x8f660d60), SPH_C32(0xa7f122eb), SPH_C32(0xdfd10240), + SPH_C32(0xadd00000), SPH_C32(0xc9e10000), SPH_C32(0xe33d0000), + SPH_C32(0xd303799d), SPH_C32(0x74541fe0), SPH_C32(0x56c3945f), + SPH_C32(0x17e4d1b6) }, + { SPH_C32(0x4f56fe40), SPH_C32(0xea3b0000), SPH_C32(0x24900000), + SPH_C32(0xdd510000), SPH_C32(0xe07b736c), SPH_C32(0x5bd78a12), + SPH_C32(0xe9720731), SPH_C32(0x35be7fe1), SPH_C32(0x16ba0270), + SPH_C32(0x4af50000), SPH_C32(0xe6650000), SPH_C32(0xc5720000), + SPH_C32(0xdb6a2264), SPH_C32(0x19a8eed7), SPH_C32(0x065cfddb), + SPH_C32(0x898d7ede) }, + { SPH_C32(0x5e0bd400), SPH_C32(0x46b30000), SPH_C32(0xc35a0000), + SPH_C32(0x98430000), SPH_C32(0xceb10d9a), SPH_C32(0x3ac156ed), + SPH_C32(0x9a9409fb), SPH_C32(0x04324f59), SPH_C32(0xedeb3c00), + SPH_C32(0xc9e10000), SPH_C32(0xdaec0000), SPH_C32(0x5d5a0000), + SPH_C32(0x8e04230e), SPH_C32(0xede46656), SPH_C32(0x27e190aa), + SPH_C32(0xfa4c0711) }, + { SPH_C32(0xb100d670), SPH_C32(0x7c4e0000), SPH_C32(0x9ef40000), + SPH_C32(0xf10a0000), SPH_C32(0x55be319c), SPH_C32(0x7ec4e314), + SPH_C32(0xfc8003aa), SPH_C32(0x967d1253), SPH_C32(0x24803c30), + SPH_C32(0x2ec40000), SPH_C32(0xf5680000), SPH_C32(0x7b150000), + SPH_C32(0x866d78f7), SPH_C32(0x80189761), SPH_C32(0x777ef92e), + SPH_C32(0x6425a879) }, + { SPH_C32(0x9760d430), SPH_C32(0xa1960000), SPH_C32(0xecde0000), + SPH_C32(0xbe0c0000), SPH_C32(0xc6d85663), SPH_C32(0x573da7da), + SPH_C32(0xca0b607f), SPH_C32(0x9a5be031), SPH_C32(0xcb8b3e40), + SPH_C32(0x14390000), SPH_C32(0xa8c60000), SPH_C32(0x125c0000), + SPH_C32(0x1d6244f1), SPH_C32(0xc41d2298), SPH_C32(0x116af37f), + SPH_C32(0xf66af573) }, + { SPH_C32(0x786bd640), SPH_C32(0x9b6b0000), SPH_C32(0xb1700000), + SPH_C32(0xd7450000), SPH_C32(0x5dd76a65), SPH_C32(0x13381223), + SPH_C32(0xac1f6a2e), SPH_C32(0x0814bd3b), SPH_C32(0x02e03e70), + SPH_C32(0xf31c0000), SPH_C32(0x87420000), SPH_C32(0x34130000), + SPH_C32(0x150b1f08), SPH_C32(0xa9e1d3af), SPH_C32(0x41f59afb), + SPH_C32(0x68035a1b) }, + { SPH_C32(0x4a51e800), SPH_C32(0xff5a0000), SPH_C32(0xa27d0000), + SPH_C32(0x69220000), SPH_C32(0x00d030f6), SPH_C32(0x8a886b95), + SPH_C32(0xdd3d6edb), SPH_C32(0xe5bc6b9c), SPH_C32(0xce8c2800), + SPH_C32(0x01580000), SPH_C32(0x2e2b0000), SPH_C32(0xa62f0000), + SPH_C32(0xfdc9076b), SPH_C32(0x1542c31f), SPH_C32(0x25259a95), + SPH_C32(0x2668e10e) }, + { SPH_C32(0xa55aea70), SPH_C32(0xc5a70000), SPH_C32(0xffd30000), + SPH_C32(0x006b0000), SPH_C32(0x9bdf0cf0), SPH_C32(0xce8dde6c), + SPH_C32(0xbb29648a), SPH_C32(0x77f33696), SPH_C32(0x07e72830), + SPH_C32(0xe67d0000), SPH_C32(0x01af0000), SPH_C32(0x80600000), + SPH_C32(0xf5a05c92), SPH_C32(0x78be3228), SPH_C32(0x75baf311), + SPH_C32(0xb8014e66) }, + { SPH_C32(0x833ae830), SPH_C32(0x187f0000), SPH_C32(0x8df90000), + SPH_C32(0x4f6d0000), SPH_C32(0x08b96b0f), SPH_C32(0xe7749aa2), + SPH_C32(0x8da2075f), SPH_C32(0x7bd5c4f4), SPH_C32(0xe8ec2a40), + SPH_C32(0xdc800000), SPH_C32(0x5c010000), SPH_C32(0xe9290000), + SPH_C32(0x6eaf6094), SPH_C32(0x3cbb87d1), SPH_C32(0x13aef940), + SPH_C32(0x2a4e136c) }, + { SPH_C32(0x6c31ea40), SPH_C32(0x22820000), SPH_C32(0xd0570000), + SPH_C32(0x26240000), SPH_C32(0x93b65709), SPH_C32(0xa3712f5b), + SPH_C32(0xebb60d0e), SPH_C32(0xe99a99fe), SPH_C32(0x21872a70), + SPH_C32(0x3ba50000), SPH_C32(0x73850000), SPH_C32(0xcf660000), + SPH_C32(0x66c63b6d), SPH_C32(0x514776e6), SPH_C32(0x433190c4), + SPH_C32(0xb427bc04) }, + { SPH_C32(0xb5ff8400), SPH_C32(0xd4340000), SPH_C32(0x601a0000), + SPH_C32(0x2f600000), SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), + SPH_C32(0xb0e67183), SPH_C32(0xf5c750ed), SPH_C32(0x8efe4800), + SPH_C32(0x525c0000), SPH_C32(0x8ada0000), SPH_C32(0xf68b0000), + SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), SPH_C32(0x093cbc28), + SPH_C32(0x92fdf249) }, + { SPH_C32(0x5af48670), SPH_C32(0xeec90000), SPH_C32(0x3db40000), + SPH_C32(0x46290000), SPH_C32(0xcceb31cc), SPH_C32(0xf3d35748), + SPH_C32(0xd6f27bd2), SPH_C32(0x67880de7), SPH_C32(0x47954830), + SPH_C32(0xb5790000), SPH_C32(0xa55e0000), SPH_C32(0xd0c40000), + SPH_C32(0x8863068e), SPH_C32(0x5c52cbb1), SPH_C32(0x59a3d5ac), + SPH_C32(0x0c945d21) }, + { SPH_C32(0x7c948430), SPH_C32(0x33110000), SPH_C32(0x4f9e0000), + SPH_C32(0x092f0000), SPH_C32(0x5f8d5633), SPH_C32(0xda2a1386), + SPH_C32(0xe0791807), SPH_C32(0x6baeff85), SPH_C32(0xa89e4a40), + SPH_C32(0x8f840000), SPH_C32(0xf8f00000), SPH_C32(0xb98d0000), + SPH_C32(0x136c3a88), SPH_C32(0x18577e48), SPH_C32(0x3fb7dffd), + SPH_C32(0x9edb002b) }, + { SPH_C32(0x939f8640), SPH_C32(0x09ec0000), SPH_C32(0x12300000), + SPH_C32(0x60660000), SPH_C32(0xc4826a35), SPH_C32(0x9e2fa67f), + SPH_C32(0x866d1256), SPH_C32(0xf9e1a28f), SPH_C32(0x61f54a70), + SPH_C32(0x68a10000), SPH_C32(0xd7740000), SPH_C32(0x9fc20000), + SPH_C32(0x1b056171), SPH_C32(0x75ab8f7f), SPH_C32(0x6f28b679), + SPH_C32(0x00b2af43) }, + { SPH_C32(0xa1a5b800), SPH_C32(0x6ddd0000), SPH_C32(0x013d0000), + SPH_C32(0xde010000), SPH_C32(0x998530a6), SPH_C32(0x079fdfc9), + SPH_C32(0xf74f16a3), SPH_C32(0x14497428), SPH_C32(0xad995c00), + SPH_C32(0x9ae50000), SPH_C32(0x7e1d0000), SPH_C32(0x0dfe0000), + SPH_C32(0xf3c77912), SPH_C32(0xc9089fcf), SPH_C32(0x0bf8b617), + SPH_C32(0x4ed91456) }, + { SPH_C32(0x4eaeba70), SPH_C32(0x57200000), SPH_C32(0x5c930000), + SPH_C32(0xb7480000), SPH_C32(0x028a0ca0), SPH_C32(0x439a6a30), + SPH_C32(0x915b1cf2), SPH_C32(0x86062922), SPH_C32(0x64f25c30), + SPH_C32(0x7dc00000), SPH_C32(0x51990000), SPH_C32(0x2bb10000), + SPH_C32(0xfbae22eb), SPH_C32(0xa4f46ef8), SPH_C32(0x5b67df93), + SPH_C32(0xd0b0bb3e) }, + { SPH_C32(0x68ceb830), SPH_C32(0x8af80000), SPH_C32(0x2eb90000), + SPH_C32(0xf84e0000), SPH_C32(0x91ec6b5f), SPH_C32(0x6a632efe), + SPH_C32(0xa7d07f27), SPH_C32(0x8a20db40), SPH_C32(0x8bf95e40), + SPH_C32(0x473d0000), SPH_C32(0x0c370000), SPH_C32(0x42f80000), + SPH_C32(0x60a11eed), SPH_C32(0xe0f1db01), SPH_C32(0x3d73d5c2), + SPH_C32(0x42ffe634) }, + { SPH_C32(0x87c5ba40), SPH_C32(0xb0050000), SPH_C32(0x73170000), + SPH_C32(0x91070000), SPH_C32(0x0ae35759), SPH_C32(0x2e669b07), + SPH_C32(0xc1c47576), SPH_C32(0x186f864a), SPH_C32(0x42925e70), + SPH_C32(0xa0180000), SPH_C32(0x23b30000), SPH_C32(0x64b70000), + SPH_C32(0x68c84514), SPH_C32(0x8d0d2a36), SPH_C32(0x6decbc46), + SPH_C32(0xdc96495c) }, + { SPH_C32(0x96989000), SPH_C32(0x1c8d0000), SPH_C32(0x94dd0000), + SPH_C32(0xd4150000), SPH_C32(0x242929af), SPH_C32(0x4f7047f8), + SPH_C32(0xb2227bbc), SPH_C32(0x29e3b6f2), SPH_C32(0xb9c36000), + SPH_C32(0x230c0000), SPH_C32(0x1f3a0000), SPH_C32(0xfc9f0000), + SPH_C32(0x3da6447e), SPH_C32(0x7941a2b7), SPH_C32(0x4c51d137), + SPH_C32(0xaf573093) }, + { SPH_C32(0x79939270), SPH_C32(0x26700000), SPH_C32(0xc9730000), + SPH_C32(0xbd5c0000), SPH_C32(0xbf2615a9), SPH_C32(0x0b75f201), + SPH_C32(0xd43671ed), SPH_C32(0xbbacebf8), SPH_C32(0x70a86030), + SPH_C32(0xc4290000), SPH_C32(0x30be0000), SPH_C32(0xdad00000), + SPH_C32(0x35cf1f87), SPH_C32(0x14bd5380), SPH_C32(0x1cceb8b3), + SPH_C32(0x313e9ffb) }, + { SPH_C32(0x5ff39030), SPH_C32(0xfba80000), SPH_C32(0xbb590000), + SPH_C32(0xf25a0000), SPH_C32(0x2c407256), SPH_C32(0x228cb6cf), + SPH_C32(0xe2bd1238), SPH_C32(0xb78a199a), SPH_C32(0x9fa36240), + SPH_C32(0xfed40000), SPH_C32(0x6d100000), SPH_C32(0xb3990000), + SPH_C32(0xaec02381), SPH_C32(0x50b8e679), SPH_C32(0x7adab2e2), + SPH_C32(0xa371c2f1) }, + { SPH_C32(0xb0f89240), SPH_C32(0xc1550000), SPH_C32(0xe6f70000), + SPH_C32(0x9b130000), SPH_C32(0xb74f4e50), SPH_C32(0x66890336), + SPH_C32(0x84a91869), SPH_C32(0x25c54490), SPH_C32(0x56c86270), + SPH_C32(0x19f10000), SPH_C32(0x42940000), SPH_C32(0x95d60000), + SPH_C32(0xa6a97878), SPH_C32(0x3d44174e), SPH_C32(0x2a45db66), + SPH_C32(0x3d186d99) }, + { SPH_C32(0x82c2ac00), SPH_C32(0xa5640000), SPH_C32(0xf5fa0000), + SPH_C32(0x25740000), SPH_C32(0xea4814c3), SPH_C32(0xff397a80), + SPH_C32(0xf58b1c9c), SPH_C32(0xc86d9237), SPH_C32(0x9aa47400), + SPH_C32(0xebb50000), SPH_C32(0xebfd0000), SPH_C32(0x07ea0000), + SPH_C32(0x4e6b601b), SPH_C32(0x81e707fe), SPH_C32(0x4e95db08), + SPH_C32(0x7373d68c) }, + { SPH_C32(0x6dc9ae70), SPH_C32(0x9f990000), SPH_C32(0xa8540000), + SPH_C32(0x4c3d0000), SPH_C32(0x714728c5), SPH_C32(0xbb3ccf79), + SPH_C32(0x939f16cd), SPH_C32(0x5a22cf3d), SPH_C32(0x53cf7430), + SPH_C32(0x0c900000), SPH_C32(0xc4790000), SPH_C32(0x21a50000), + SPH_C32(0x46023be2), SPH_C32(0xec1bf6c9), SPH_C32(0x1e0ab28c), + SPH_C32(0xed1a79e4) }, + { SPH_C32(0x4ba9ac30), SPH_C32(0x42410000), SPH_C32(0xda7e0000), + SPH_C32(0x033b0000), SPH_C32(0xe2214f3a), SPH_C32(0x92c58bb7), + SPH_C32(0xa5147518), SPH_C32(0x56043d5f), SPH_C32(0xbcc47640), + SPH_C32(0x366d0000), SPH_C32(0x99d70000), SPH_C32(0x48ec0000), + SPH_C32(0xdd0d07e4), SPH_C32(0xa81e4330), SPH_C32(0x781eb8dd), + SPH_C32(0x7f5524ee) }, + { SPH_C32(0xa4a2ae40), SPH_C32(0x78bc0000), SPH_C32(0x87d00000), + SPH_C32(0x6a720000), SPH_C32(0x792e733c), SPH_C32(0xd6c03e4e), + SPH_C32(0xc3007f49), SPH_C32(0xc44b6055), SPH_C32(0x75af7670), + SPH_C32(0xd1480000), SPH_C32(0xb6530000), SPH_C32(0x6ea30000), + SPH_C32(0xd5645c1d), SPH_C32(0xc5e2b207), SPH_C32(0x2881d159), + SPH_C32(0xe13c8b86) }, + { SPH_C32(0xe1d7d800), SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), + SPH_C32(0x8ea50000), SPH_C32(0xe4466aba), SPH_C32(0x23732650), + SPH_C32(0xdb56301e), SPH_C32(0xa0dc676f), SPH_C32(0x12455000), + SPH_C32(0xe28f0000), SPH_C32(0x188b0000), SPH_C32(0x1b180000), + SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), SPH_C32(0x4a3a8ff2), + SPH_C32(0xea373c60) }, + { SPH_C32(0x0edcda70), SPH_C32(0x04240000), SPH_C32(0xf8620000), + SPH_C32(0xe7ec0000), SPH_C32(0x7f4956bc), SPH_C32(0x677693a9), + SPH_C32(0xbd423a4f), SPH_C32(0x32933a65), SPH_C32(0xdb2e5030), + SPH_C32(0x05aa0000), SPH_C32(0x370f0000), SPH_C32(0x3d570000), + SPH_C32(0xd15945cb), SPH_C32(0xbd461e45), SPH_C32(0x1aa5e676), + SPH_C32(0x745e9308) }, + { SPH_C32(0x28bcd830), SPH_C32(0xd9fc0000), SPH_C32(0x8a480000), + SPH_C32(0xa8ea0000), SPH_C32(0xec2f3143), SPH_C32(0x4e8fd767), + SPH_C32(0x8bc9599a), SPH_C32(0x3eb5c807), SPH_C32(0x34255240), + SPH_C32(0x3f570000), SPH_C32(0x6aa10000), SPH_C32(0x541e0000), + SPH_C32(0x4a5679cd), SPH_C32(0xf943abbc), SPH_C32(0x7cb1ec27), + SPH_C32(0xe611ce02) }, + { SPH_C32(0xc7b7da40), SPH_C32(0xe3010000), SPH_C32(0xd7e60000), + SPH_C32(0xc1a30000), SPH_C32(0x77200d45), SPH_C32(0x0a8a629e), + SPH_C32(0xeddd53cb), SPH_C32(0xacfa950d), SPH_C32(0xfd4e5270), + SPH_C32(0xd8720000), SPH_C32(0x45250000), SPH_C32(0x72510000), + SPH_C32(0x423f2234), SPH_C32(0x94bf5a8b), SPH_C32(0x2c2e85a3), + SPH_C32(0x7878616a) }, + { SPH_C32(0xf58de400), SPH_C32(0x87300000), SPH_C32(0xc4eb0000), + SPH_C32(0x7fc40000), SPH_C32(0x2a2757d6), SPH_C32(0x933a1b28), + SPH_C32(0x9cff573e), SPH_C32(0x415243aa), SPH_C32(0x31224400), + SPH_C32(0x2a360000), SPH_C32(0xec4c0000), SPH_C32(0xe06d0000), + SPH_C32(0xaafd3a57), SPH_C32(0x281c4a3b), SPH_C32(0x48fe85cd), + SPH_C32(0x3613da7f) }, + { SPH_C32(0x1a86e670), SPH_C32(0xbdcd0000), SPH_C32(0x99450000), + SPH_C32(0x168d0000), SPH_C32(0xb1286bd0), SPH_C32(0xd73faed1), + SPH_C32(0xfaeb5d6f), SPH_C32(0xd31d1ea0), SPH_C32(0xf8494430), + SPH_C32(0xcd130000), SPH_C32(0xc3c80000), SPH_C32(0xc6220000), + SPH_C32(0xa29461ae), SPH_C32(0x45e0bb0c), SPH_C32(0x1861ec49), + SPH_C32(0xa87a7517) }, + { SPH_C32(0x3ce6e430), SPH_C32(0x60150000), SPH_C32(0xeb6f0000), + SPH_C32(0x598b0000), SPH_C32(0x224e0c2f), SPH_C32(0xfec6ea1f), + SPH_C32(0xcc603eba), SPH_C32(0xdf3becc2), SPH_C32(0x17424640), + SPH_C32(0xf7ee0000), SPH_C32(0x9e660000), SPH_C32(0xaf6b0000), + SPH_C32(0x399b5da8), SPH_C32(0x01e50ef5), SPH_C32(0x7e75e618), + SPH_C32(0x3a35281d) }, + { SPH_C32(0xd3ede640), SPH_C32(0x5ae80000), SPH_C32(0xb6c10000), + SPH_C32(0x30c20000), SPH_C32(0xb9413029), SPH_C32(0xbac35fe6), + SPH_C32(0xaa7434eb), SPH_C32(0x4d74b1c8), SPH_C32(0xde294670), + SPH_C32(0x10cb0000), SPH_C32(0xb1e20000), SPH_C32(0x89240000), + SPH_C32(0x31f20651), SPH_C32(0x6c19ffc2), SPH_C32(0x2eea8f9c), + SPH_C32(0xa45c8775) }, + { SPH_C32(0xc2b0cc00), SPH_C32(0xf6600000), SPH_C32(0x510b0000), + SPH_C32(0x75d00000), SPH_C32(0x978b4edf), SPH_C32(0xdbd58319), + SPH_C32(0xd9923a21), SPH_C32(0x7cf88170), SPH_C32(0x25787800), + SPH_C32(0x93df0000), SPH_C32(0x8d6b0000), SPH_C32(0x110c0000), + SPH_C32(0x649c073b), SPH_C32(0x98557743), SPH_C32(0x0f57e2ed), + SPH_C32(0xd79dfeba) }, + { SPH_C32(0x2dbbce70), SPH_C32(0xcc9d0000), SPH_C32(0x0ca50000), + SPH_C32(0x1c990000), SPH_C32(0x0c8472d9), SPH_C32(0x9fd036e0), + SPH_C32(0xbf863070), SPH_C32(0xeeb7dc7a), SPH_C32(0xec137830), + SPH_C32(0x74fa0000), SPH_C32(0xa2ef0000), SPH_C32(0x37430000), + SPH_C32(0x6cf55cc2), SPH_C32(0xf5a98674), SPH_C32(0x5fc88b69), + SPH_C32(0x49f451d2) }, + { SPH_C32(0x0bdbcc30), SPH_C32(0x11450000), SPH_C32(0x7e8f0000), + SPH_C32(0x539f0000), SPH_C32(0x9fe21526), SPH_C32(0xb629722e), + SPH_C32(0x890d53a5), SPH_C32(0xe2912e18), SPH_C32(0x03187a40), + SPH_C32(0x4e070000), SPH_C32(0xff410000), SPH_C32(0x5e0a0000), + SPH_C32(0xf7fa60c4), SPH_C32(0xb1ac338d), SPH_C32(0x39dc8138), + SPH_C32(0xdbbb0cd8) }, + { SPH_C32(0xe4d0ce40), SPH_C32(0x2bb80000), SPH_C32(0x23210000), + SPH_C32(0x3ad60000), SPH_C32(0x04ed2920), SPH_C32(0xf22cc7d7), + SPH_C32(0xef1959f4), SPH_C32(0x70de7312), SPH_C32(0xca737a70), + SPH_C32(0xa9220000), SPH_C32(0xd0c50000), SPH_C32(0x78450000), + SPH_C32(0xff933b3d), SPH_C32(0xdc50c2ba), SPH_C32(0x6943e8bc), + SPH_C32(0x45d2a3b0) }, + { SPH_C32(0xd6eaf000), SPH_C32(0x4f890000), SPH_C32(0x302c0000), + SPH_C32(0x84b10000), SPH_C32(0x59ea73b3), SPH_C32(0x6b9cbe61), + SPH_C32(0x9e3b5d01), SPH_C32(0x9d76a5b5), SPH_C32(0x061f6c00), + SPH_C32(0x5b660000), SPH_C32(0x79ac0000), SPH_C32(0xea790000), + SPH_C32(0x1751235e), SPH_C32(0x60f3d20a), SPH_C32(0x0d93e8d2), + SPH_C32(0x0bb918a5) }, + { SPH_C32(0x39e1f270), SPH_C32(0x75740000), SPH_C32(0x6d820000), + SPH_C32(0xedf80000), SPH_C32(0xc2e54fb5), SPH_C32(0x2f990b98), + SPH_C32(0xf82f5750), SPH_C32(0x0f39f8bf), SPH_C32(0xcf746c30), + SPH_C32(0xbc430000), SPH_C32(0x56280000), SPH_C32(0xcc360000), + SPH_C32(0x1f3878a7), SPH_C32(0x0d0f233d), SPH_C32(0x5d0c8156), + SPH_C32(0x95d0b7cd) }, + { SPH_C32(0x1f81f030), SPH_C32(0xa8ac0000), SPH_C32(0x1fa80000), + SPH_C32(0xa2fe0000), SPH_C32(0x5183284a), SPH_C32(0x06604f56), + SPH_C32(0xcea43485), SPH_C32(0x031f0add), SPH_C32(0x207f6e40), + SPH_C32(0x86be0000), SPH_C32(0x0b860000), SPH_C32(0xa57f0000), + SPH_C32(0x843744a1), SPH_C32(0x490a96c4), SPH_C32(0x3b188b07), + SPH_C32(0x079feac7) }, + { SPH_C32(0xf08af240), SPH_C32(0x92510000), SPH_C32(0x42060000), + SPH_C32(0xcbb70000), SPH_C32(0xca8c144c), SPH_C32(0x4265faaf), + SPH_C32(0xa8b03ed4), SPH_C32(0x915057d7), SPH_C32(0xe9146e70), + SPH_C32(0x619b0000), SPH_C32(0x24020000), SPH_C32(0x83300000), + SPH_C32(0x8c5e1f58), SPH_C32(0x24f667f3), SPH_C32(0x6b87e283), + SPH_C32(0x99f645af) }, + { SPH_C32(0x466d0c00), SPH_C32(0x08620000), SPH_C32(0xdd5d0000), + SPH_C32(0xbadd0000), SPH_C32(0x6a927942), SPH_C32(0x441f2b93), + SPH_C32(0x218ace6f), SPH_C32(0xbf2c0be2), SPH_C32(0x6f299000), + SPH_C32(0x6c850000), SPH_C32(0x2f160000), SPH_C32(0x782e0000), + SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), SPH_C32(0xd26a8c36), + SPH_C32(0x32219526) }, + { SPH_C32(0xa9660e70), SPH_C32(0x329f0000), SPH_C32(0x80f30000), + SPH_C32(0xd3940000), SPH_C32(0xf19d4544), SPH_C32(0x001a9e6a), + SPH_C32(0x479ec43e), SPH_C32(0x2d6356e8), SPH_C32(0xa6429030), + SPH_C32(0x8ba00000), SPH_C32(0x00920000), SPH_C32(0x5e610000), + SPH_C32(0x6c256c34), SPH_C32(0x7f21ede1), SPH_C32(0x82f5e5b2), + SPH_C32(0xac483a4e) }, + { SPH_C32(0x8f060c30), SPH_C32(0xef470000), SPH_C32(0xf2d90000), + SPH_C32(0x9c920000), SPH_C32(0x62fb22bb), SPH_C32(0x29e3daa4), + SPH_C32(0x7115a7eb), SPH_C32(0x2145a48a), SPH_C32(0x49499240), + SPH_C32(0xb15d0000), SPH_C32(0x5d3c0000), SPH_C32(0x37280000), + SPH_C32(0xf72a5032), SPH_C32(0x3b245818), SPH_C32(0xe4e1efe3), + SPH_C32(0x3e076744) }, + { SPH_C32(0x600d0e40), SPH_C32(0xd5ba0000), SPH_C32(0xaf770000), + SPH_C32(0xf5db0000), SPH_C32(0xf9f41ebd), SPH_C32(0x6de66f5d), + SPH_C32(0x1701adba), SPH_C32(0xb30af980), SPH_C32(0x80229270), + SPH_C32(0x56780000), SPH_C32(0x72b80000), SPH_C32(0x11670000), + SPH_C32(0xff430bcb), SPH_C32(0x56d8a92f), SPH_C32(0xb47e8667), + SPH_C32(0xa06ec82c) }, + { SPH_C32(0x52373000), SPH_C32(0xb18b0000), SPH_C32(0xbc7a0000), + SPH_C32(0x4bbc0000), SPH_C32(0xa4f3442e), SPH_C32(0xf45616eb), + SPH_C32(0x6623a94f), SPH_C32(0x5ea22f27), SPH_C32(0x4c4e8400), + SPH_C32(0xa43c0000), SPH_C32(0xdbd10000), SPH_C32(0x835b0000), + SPH_C32(0x178113a8), SPH_C32(0xea7bb99f), SPH_C32(0xd0ae8609), + SPH_C32(0xee057339) }, + { SPH_C32(0xbd3c3270), SPH_C32(0x8b760000), SPH_C32(0xe1d40000), + SPH_C32(0x22f50000), SPH_C32(0x3ffc7828), SPH_C32(0xb053a312), + SPH_C32(0x0037a31e), SPH_C32(0xcced722d), SPH_C32(0x85258430), + SPH_C32(0x43190000), SPH_C32(0xf4550000), SPH_C32(0xa5140000), + SPH_C32(0x1fe84851), SPH_C32(0x878748a8), SPH_C32(0x8031ef8d), + SPH_C32(0x706cdc51) }, + { SPH_C32(0x9b5c3030), SPH_C32(0x56ae0000), SPH_C32(0x93fe0000), + SPH_C32(0x6df30000), SPH_C32(0xac9a1fd7), SPH_C32(0x99aae7dc), + SPH_C32(0x36bcc0cb), SPH_C32(0xc0cb804f), SPH_C32(0x6a2e8640), + SPH_C32(0x79e40000), SPH_C32(0xa9fb0000), SPH_C32(0xcc5d0000), + SPH_C32(0x84e77457), SPH_C32(0xc382fd51), SPH_C32(0xe625e5dc), + SPH_C32(0xe223815b) }, + { SPH_C32(0x74573240), SPH_C32(0x6c530000), SPH_C32(0xce500000), + SPH_C32(0x04ba0000), SPH_C32(0x379523d1), SPH_C32(0xddaf5225), + SPH_C32(0x50a8ca9a), SPH_C32(0x5284dd45), SPH_C32(0xa3458670), + SPH_C32(0x9ec10000), SPH_C32(0x867f0000), SPH_C32(0xea120000), + SPH_C32(0x8c8e2fae), SPH_C32(0xae7e0c66), SPH_C32(0xb6ba8c58), + SPH_C32(0x7c4a2e33) }, + { SPH_C32(0x650a1800), SPH_C32(0xc0db0000), SPH_C32(0x299a0000), + SPH_C32(0x41a80000), SPH_C32(0x195f5d27), SPH_C32(0xbcb98eda), + SPH_C32(0x234ec450), SPH_C32(0x6308edfd), SPH_C32(0x5814b800), + SPH_C32(0x1dd50000), SPH_C32(0xbaf60000), SPH_C32(0x723a0000), + SPH_C32(0xd9e02ec4), SPH_C32(0x5a3284e7), SPH_C32(0x9707e129), + SPH_C32(0x0f8b57fc) }, + { SPH_C32(0x8a011a70), SPH_C32(0xfa260000), SPH_C32(0x74340000), + SPH_C32(0x28e10000), SPH_C32(0x82506121), SPH_C32(0xf8bc3b23), + SPH_C32(0x455ace01), SPH_C32(0xf147b0f7), SPH_C32(0x917fb830), + SPH_C32(0xfaf00000), SPH_C32(0x95720000), SPH_C32(0x54750000), + SPH_C32(0xd189753d), SPH_C32(0x37ce75d0), SPH_C32(0xc79888ad), + SPH_C32(0x91e2f894) }, + { SPH_C32(0xac611830), SPH_C32(0x27fe0000), SPH_C32(0x061e0000), + SPH_C32(0x67e70000), SPH_C32(0x113606de), SPH_C32(0xd1457fed), + SPH_C32(0x73d1add4), SPH_C32(0xfd614295), SPH_C32(0x7e74ba40), + SPH_C32(0xc00d0000), SPH_C32(0xc8dc0000), SPH_C32(0x3d3c0000), + SPH_C32(0x4a86493b), SPH_C32(0x73cbc029), SPH_C32(0xa18c82fc), + SPH_C32(0x03ada59e) }, + { SPH_C32(0x436a1a40), SPH_C32(0x1d030000), SPH_C32(0x5bb00000), + SPH_C32(0x0eae0000), SPH_C32(0x8a393ad8), SPH_C32(0x9540ca14), + SPH_C32(0x15c5a785), SPH_C32(0x6f2e1f9f), SPH_C32(0xb71fba70), + SPH_C32(0x27280000), SPH_C32(0xe7580000), SPH_C32(0x1b730000), + SPH_C32(0x42ef12c2), SPH_C32(0x1e37311e), SPH_C32(0xf113eb78), + SPH_C32(0x9dc40af6) }, + { SPH_C32(0x71502400), SPH_C32(0x79320000), SPH_C32(0x48bd0000), + SPH_C32(0xb0c90000), SPH_C32(0xd73e604b), SPH_C32(0x0cf0b3a2), + SPH_C32(0x64e7a370), SPH_C32(0x8286c938), SPH_C32(0x7b73ac00), + SPH_C32(0xd56c0000), SPH_C32(0x4e310000), SPH_C32(0x894f0000), + SPH_C32(0xaa2d0aa1), SPH_C32(0xa29421ae), SPH_C32(0x95c3eb16), + SPH_C32(0xd3afb1e3) }, + { SPH_C32(0x9e5b2670), SPH_C32(0x43cf0000), SPH_C32(0x15130000), + SPH_C32(0xd9800000), SPH_C32(0x4c315c4d), SPH_C32(0x48f5065b), + SPH_C32(0x02f3a921), SPH_C32(0x10c99432), SPH_C32(0xb218ac30), + SPH_C32(0x32490000), SPH_C32(0x61b50000), SPH_C32(0xaf000000), + SPH_C32(0xa2445158), SPH_C32(0xcf68d099), SPH_C32(0xc55c8292), + SPH_C32(0x4dc61e8b) }, + { SPH_C32(0xb83b2430), SPH_C32(0x9e170000), SPH_C32(0x67390000), + SPH_C32(0x96860000), SPH_C32(0xdf573bb2), SPH_C32(0x610c4295), + SPH_C32(0x3478caf4), SPH_C32(0x1cef6650), SPH_C32(0x5d13ae40), + SPH_C32(0x08b40000), SPH_C32(0x3c1b0000), SPH_C32(0xc6490000), + SPH_C32(0x394b6d5e), SPH_C32(0x8b6d6560), SPH_C32(0xa34888c3), + SPH_C32(0xdf894381) }, + { SPH_C32(0x57302640), SPH_C32(0xa4ea0000), SPH_C32(0x3a970000), + SPH_C32(0xffcf0000), SPH_C32(0x445807b4), SPH_C32(0x2509f76c), + SPH_C32(0x526cc0a5), SPH_C32(0x8ea03b5a), SPH_C32(0x9478ae70), + SPH_C32(0xef910000), SPH_C32(0x139f0000), SPH_C32(0xe0060000), + SPH_C32(0x312236a7), SPH_C32(0xe6919457), SPH_C32(0xf3d7e147), + SPH_C32(0x41e0ece9) }, + { SPH_C32(0x12455000), SPH_C32(0xe28f0000), SPH_C32(0x188b0000), + SPH_C32(0x1b180000), SPH_C32(0xd9301e32), SPH_C32(0xd0baef72), + SPH_C32(0x4a3a8ff2), SPH_C32(0xea373c60), SPH_C32(0xf3928800), + SPH_C32(0xdc560000), SPH_C32(0xbd470000), SPH_C32(0x95bd0000), + SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), SPH_C32(0x916cbfec), + SPH_C32(0x4aeb5b0f) }, + { SPH_C32(0xfd4e5270), SPH_C32(0xd8720000), SPH_C32(0x45250000), + SPH_C32(0x72510000), SPH_C32(0x423f2234), SPH_C32(0x94bf5a8b), + SPH_C32(0x2c2e85a3), SPH_C32(0x7878616a), SPH_C32(0x3af98830), + SPH_C32(0x3b730000), SPH_C32(0x92c30000), SPH_C32(0xb3f20000), + SPH_C32(0x351f2f71), SPH_C32(0x9e353815), SPH_C32(0xc1f3d668), + SPH_C32(0xd482f467) }, + { SPH_C32(0xdb2e5030), SPH_C32(0x05aa0000), SPH_C32(0x370f0000), + SPH_C32(0x3d570000), SPH_C32(0xd15945cb), SPH_C32(0xbd461e45), + SPH_C32(0x1aa5e676), SPH_C32(0x745e9308), SPH_C32(0xd5f28a40), + SPH_C32(0x018e0000), SPH_C32(0xcf6d0000), SPH_C32(0xdabb0000), + SPH_C32(0xae101377), SPH_C32(0xda308dec), SPH_C32(0xa7e7dc39), + SPH_C32(0x46cda96d) }, + { SPH_C32(0x34255240), SPH_C32(0x3f570000), SPH_C32(0x6aa10000), + SPH_C32(0x541e0000), SPH_C32(0x4a5679cd), SPH_C32(0xf943abbc), + SPH_C32(0x7cb1ec27), SPH_C32(0xe611ce02), SPH_C32(0x1c998a70), + SPH_C32(0xe6ab0000), SPH_C32(0xe0e90000), SPH_C32(0xfcf40000), + SPH_C32(0xa679488e), SPH_C32(0xb7cc7cdb), SPH_C32(0xf778b5bd), + SPH_C32(0xd8a40605) }, + { SPH_C32(0x061f6c00), SPH_C32(0x5b660000), SPH_C32(0x79ac0000), + SPH_C32(0xea790000), SPH_C32(0x1751235e), SPH_C32(0x60f3d20a), + SPH_C32(0x0d93e8d2), SPH_C32(0x0bb918a5), SPH_C32(0xd0f59c00), + SPH_C32(0x14ef0000), SPH_C32(0x49800000), SPH_C32(0x6ec80000), + SPH_C32(0x4ebb50ed), SPH_C32(0x0b6f6c6b), SPH_C32(0x93a8b5d3), + SPH_C32(0x96cfbd10) }, + { SPH_C32(0xe9146e70), SPH_C32(0x619b0000), SPH_C32(0x24020000), + SPH_C32(0x83300000), SPH_C32(0x8c5e1f58), SPH_C32(0x24f667f3), + SPH_C32(0x6b87e283), SPH_C32(0x99f645af), SPH_C32(0x199e9c30), + SPH_C32(0xf3ca0000), SPH_C32(0x66040000), SPH_C32(0x48870000), + SPH_C32(0x46d20b14), SPH_C32(0x66939d5c), SPH_C32(0xc337dc57), + SPH_C32(0x08a61278) }, + { SPH_C32(0xcf746c30), SPH_C32(0xbc430000), SPH_C32(0x56280000), + SPH_C32(0xcc360000), SPH_C32(0x1f3878a7), SPH_C32(0x0d0f233d), + SPH_C32(0x5d0c8156), SPH_C32(0x95d0b7cd), SPH_C32(0xf6959e40), + SPH_C32(0xc9370000), SPH_C32(0x3baa0000), SPH_C32(0x21ce0000), + SPH_C32(0xdddd3712), SPH_C32(0x229628a5), SPH_C32(0xa523d606), + SPH_C32(0x9ae94f72) }, + { SPH_C32(0x207f6e40), SPH_C32(0x86be0000), SPH_C32(0x0b860000), + SPH_C32(0xa57f0000), SPH_C32(0x843744a1), SPH_C32(0x490a96c4), + SPH_C32(0x3b188b07), SPH_C32(0x079feac7), SPH_C32(0x3ffe9e70), + SPH_C32(0x2e120000), SPH_C32(0x142e0000), SPH_C32(0x07810000), + SPH_C32(0xd5b46ceb), SPH_C32(0x4f6ad992), SPH_C32(0xf5bcbf82), + SPH_C32(0x0480e01a) }, + { SPH_C32(0x31224400), SPH_C32(0x2a360000), SPH_C32(0xec4c0000), + SPH_C32(0xe06d0000), SPH_C32(0xaafd3a57), SPH_C32(0x281c4a3b), + SPH_C32(0x48fe85cd), SPH_C32(0x3613da7f), SPH_C32(0xc4afa000), + SPH_C32(0xad060000), SPH_C32(0x28a70000), SPH_C32(0x9fa90000), + SPH_C32(0x80da6d81), SPH_C32(0xbb265113), SPH_C32(0xd401d2f3), + SPH_C32(0x774199d5) }, + { SPH_C32(0xde294670), SPH_C32(0x10cb0000), SPH_C32(0xb1e20000), + SPH_C32(0x89240000), SPH_C32(0x31f20651), SPH_C32(0x6c19ffc2), + SPH_C32(0x2eea8f9c), SPH_C32(0xa45c8775), SPH_C32(0x0dc4a030), + SPH_C32(0x4a230000), SPH_C32(0x07230000), SPH_C32(0xb9e60000), + SPH_C32(0x88b33678), SPH_C32(0xd6daa024), SPH_C32(0x849ebb77), + SPH_C32(0xe92836bd) }, + { SPH_C32(0xf8494430), SPH_C32(0xcd130000), SPH_C32(0xc3c80000), + SPH_C32(0xc6220000), SPH_C32(0xa29461ae), SPH_C32(0x45e0bb0c), + SPH_C32(0x1861ec49), SPH_C32(0xa87a7517), SPH_C32(0xe2cfa240), + SPH_C32(0x70de0000), SPH_C32(0x5a8d0000), SPH_C32(0xd0af0000), + SPH_C32(0x13bc0a7e), SPH_C32(0x92df15dd), SPH_C32(0xe28ab126), + SPH_C32(0x7b676bb7) }, + { SPH_C32(0x17424640), SPH_C32(0xf7ee0000), SPH_C32(0x9e660000), + SPH_C32(0xaf6b0000), SPH_C32(0x399b5da8), SPH_C32(0x01e50ef5), + SPH_C32(0x7e75e618), SPH_C32(0x3a35281d), SPH_C32(0x2ba4a270), + SPH_C32(0x97fb0000), SPH_C32(0x75090000), SPH_C32(0xf6e00000), + SPH_C32(0x1bd55187), SPH_C32(0xff23e4ea), SPH_C32(0xb215d8a2), + SPH_C32(0xe50ec4df) }, + { SPH_C32(0x25787800), SPH_C32(0x93df0000), SPH_C32(0x8d6b0000), + SPH_C32(0x110c0000), SPH_C32(0x649c073b), SPH_C32(0x98557743), + SPH_C32(0x0f57e2ed), SPH_C32(0xd79dfeba), SPH_C32(0xe7c8b400), + SPH_C32(0x65bf0000), SPH_C32(0xdc600000), SPH_C32(0x64dc0000), + SPH_C32(0xf31749e4), SPH_C32(0x4380f45a), SPH_C32(0xd6c5d8cc), + SPH_C32(0xab657fca) }, + { SPH_C32(0xca737a70), SPH_C32(0xa9220000), SPH_C32(0xd0c50000), + SPH_C32(0x78450000), SPH_C32(0xff933b3d), SPH_C32(0xdc50c2ba), + SPH_C32(0x6943e8bc), SPH_C32(0x45d2a3b0), SPH_C32(0x2ea3b430), + SPH_C32(0x829a0000), SPH_C32(0xf3e40000), SPH_C32(0x42930000), + SPH_C32(0xfb7e121d), SPH_C32(0x2e7c056d), SPH_C32(0x865ab148), + SPH_C32(0x350cd0a2) }, + { SPH_C32(0xec137830), SPH_C32(0x74fa0000), SPH_C32(0xa2ef0000), + SPH_C32(0x37430000), SPH_C32(0x6cf55cc2), SPH_C32(0xf5a98674), + SPH_C32(0x5fc88b69), SPH_C32(0x49f451d2), SPH_C32(0xc1a8b640), + SPH_C32(0xb8670000), SPH_C32(0xae4a0000), SPH_C32(0x2bda0000), + SPH_C32(0x60712e1b), SPH_C32(0x6a79b094), SPH_C32(0xe04ebb19), + SPH_C32(0xa7438da8) }, + { SPH_C32(0x03187a40), SPH_C32(0x4e070000), SPH_C32(0xff410000), + SPH_C32(0x5e0a0000), SPH_C32(0xf7fa60c4), SPH_C32(0xb1ac338d), + SPH_C32(0x39dc8138), SPH_C32(0xdbbb0cd8), SPH_C32(0x08c3b670), + SPH_C32(0x5f420000), SPH_C32(0x81ce0000), SPH_C32(0x0d950000), + SPH_C32(0x681875e2), SPH_C32(0x078541a3), SPH_C32(0xb0d1d29d), + SPH_C32(0x392a22c0) }, + { SPH_C32(0xdad61400), SPH_C32(0xb8b10000), SPH_C32(0x4f0c0000), + SPH_C32(0x574e0000), SPH_C32(0x33a83a07), SPH_C32(0xa50bfe67), + SPH_C32(0x628cfdb5), SPH_C32(0xc7e6c5cb), SPH_C32(0xa7bad400), + SPH_C32(0x36bb0000), SPH_C32(0x78910000), SPH_C32(0x34780000), + SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), SPH_C32(0xfadcfe71), + SPH_C32(0x1ff06c8d) }, + { SPH_C32(0x35dd1670), SPH_C32(0x824c0000), SPH_C32(0x12a20000), + SPH_C32(0x3e070000), SPH_C32(0xa8a70601), SPH_C32(0xe10e4b9e), + SPH_C32(0x0498f7e4), SPH_C32(0x55a998c1), SPH_C32(0x6ed1d430), + SPH_C32(0xd19e0000), SPH_C32(0x57150000), SPH_C32(0x12370000), + SPH_C32(0x86bd4801), SPH_C32(0x0a90fcf4), SPH_C32(0xaa4397f5), + SPH_C32(0x8199c3e5) }, + { SPH_C32(0x13bd1430), SPH_C32(0x5f940000), SPH_C32(0x60880000), + SPH_C32(0x71010000), SPH_C32(0x3bc161fe), SPH_C32(0xc8f70f50), + SPH_C32(0x32139431), SPH_C32(0x598f6aa3), SPH_C32(0x81dad640), + SPH_C32(0xeb630000), SPH_C32(0x0abb0000), SPH_C32(0x7b7e0000), + SPH_C32(0x1db27407), SPH_C32(0x4e95490d), SPH_C32(0xcc579da4), + SPH_C32(0x13d69eef) }, + { SPH_C32(0xfcb61640), SPH_C32(0x65690000), SPH_C32(0x3d260000), + SPH_C32(0x18480000), SPH_C32(0xa0ce5df8), SPH_C32(0x8cf2baa9), + SPH_C32(0x54079e60), SPH_C32(0xcbc037a9), SPH_C32(0x48b1d670), + SPH_C32(0x0c460000), SPH_C32(0x253f0000), SPH_C32(0x5d310000), + SPH_C32(0x15db2ffe), SPH_C32(0x2369b83a), SPH_C32(0x9cc8f420), + SPH_C32(0x8dbf3187) }, + { SPH_C32(0xce8c2800), SPH_C32(0x01580000), SPH_C32(0x2e2b0000), + SPH_C32(0xa62f0000), SPH_C32(0xfdc9076b), SPH_C32(0x1542c31f), + SPH_C32(0x25259a95), SPH_C32(0x2668e10e), SPH_C32(0x84ddc000), + SPH_C32(0xfe020000), SPH_C32(0x8c560000), SPH_C32(0xcf0d0000), + SPH_C32(0xfd19379d), SPH_C32(0x9fcaa88a), SPH_C32(0xf818f44e), + SPH_C32(0xc3d48a92) }, + { SPH_C32(0x21872a70), SPH_C32(0x3ba50000), SPH_C32(0x73850000), + SPH_C32(0xcf660000), SPH_C32(0x66c63b6d), SPH_C32(0x514776e6), + SPH_C32(0x433190c4), SPH_C32(0xb427bc04), SPH_C32(0x4db6c030), + SPH_C32(0x19270000), SPH_C32(0xa3d20000), SPH_C32(0xe9420000), + SPH_C32(0xf5706c64), SPH_C32(0xf23659bd), SPH_C32(0xa8879dca), + SPH_C32(0x5dbd25fa) }, + { SPH_C32(0x07e72830), SPH_C32(0xe67d0000), SPH_C32(0x01af0000), + SPH_C32(0x80600000), SPH_C32(0xf5a05c92), SPH_C32(0x78be3228), + SPH_C32(0x75baf311), SPH_C32(0xb8014e66), SPH_C32(0xa2bdc240), + SPH_C32(0x23da0000), SPH_C32(0xfe7c0000), SPH_C32(0x800b0000), + SPH_C32(0x6e7f5062), SPH_C32(0xb633ec44), SPH_C32(0xce93979b), + SPH_C32(0xcff278f0) }, + { SPH_C32(0xe8ec2a40), SPH_C32(0xdc800000), SPH_C32(0x5c010000), + SPH_C32(0xe9290000), SPH_C32(0x6eaf6094), SPH_C32(0x3cbb87d1), + SPH_C32(0x13aef940), SPH_C32(0x2a4e136c), SPH_C32(0x6bd6c270), + SPH_C32(0xc4ff0000), SPH_C32(0xd1f80000), SPH_C32(0xa6440000), + SPH_C32(0x66160b9b), SPH_C32(0xdbcf1d73), SPH_C32(0x9e0cfe1f), + SPH_C32(0x519bd798) }, + { SPH_C32(0xf9b10000), SPH_C32(0x70080000), SPH_C32(0xbbcb0000), + SPH_C32(0xac3b0000), SPH_C32(0x40651e62), SPH_C32(0x5dad5b2e), + SPH_C32(0x6048f78a), SPH_C32(0x1bc223d4), SPH_C32(0x9087fc00), + SPH_C32(0x47eb0000), SPH_C32(0xed710000), SPH_C32(0x3e6c0000), + SPH_C32(0x33780af1), SPH_C32(0x2f8395f2), SPH_C32(0xbfb1936e), + SPH_C32(0x225aae57) }, + { SPH_C32(0x16ba0270), SPH_C32(0x4af50000), SPH_C32(0xe6650000), + SPH_C32(0xc5720000), SPH_C32(0xdb6a2264), SPH_C32(0x19a8eed7), + SPH_C32(0x065cfddb), SPH_C32(0x898d7ede), SPH_C32(0x59ecfc30), + SPH_C32(0xa0ce0000), SPH_C32(0xc2f50000), SPH_C32(0x18230000), + SPH_C32(0x3b115108), SPH_C32(0x427f64c5), SPH_C32(0xef2efaea), + SPH_C32(0xbc33013f) }, + { SPH_C32(0x30da0030), SPH_C32(0x972d0000), SPH_C32(0x944f0000), + SPH_C32(0x8a740000), SPH_C32(0x480c459b), SPH_C32(0x3051aa19), + SPH_C32(0x30d79e0e), SPH_C32(0x85ab8cbc), SPH_C32(0xb6e7fe40), + SPH_C32(0x9a330000), SPH_C32(0x9f5b0000), SPH_C32(0x716a0000), + SPH_C32(0xa01e6d0e), SPH_C32(0x067ad13c), SPH_C32(0x893af0bb), + SPH_C32(0x2e7c5c35) }, + { SPH_C32(0xdfd10240), SPH_C32(0xadd00000), SPH_C32(0xc9e10000), + SPH_C32(0xe33d0000), SPH_C32(0xd303799d), SPH_C32(0x74541fe0), + SPH_C32(0x56c3945f), SPH_C32(0x17e4d1b6), SPH_C32(0x7f8cfe70), + SPH_C32(0x7d160000), SPH_C32(0xb0df0000), SPH_C32(0x57250000), + SPH_C32(0xa87736f7), SPH_C32(0x6b86200b), SPH_C32(0xd9a5993f), + SPH_C32(0xb015f35d) }, + { SPH_C32(0xedeb3c00), SPH_C32(0xc9e10000), SPH_C32(0xdaec0000), + SPH_C32(0x5d5a0000), SPH_C32(0x8e04230e), SPH_C32(0xede46656), + SPH_C32(0x27e190aa), SPH_C32(0xfa4c0711), SPH_C32(0xb3e0e800), + SPH_C32(0x8f520000), SPH_C32(0x19b60000), SPH_C32(0xc5190000), + SPH_C32(0x40b52e94), SPH_C32(0xd72530bb), SPH_C32(0xbd759951), + SPH_C32(0xfe7e4848) }, + { SPH_C32(0x02e03e70), SPH_C32(0xf31c0000), SPH_C32(0x87420000), + SPH_C32(0x34130000), SPH_C32(0x150b1f08), SPH_C32(0xa9e1d3af), + SPH_C32(0x41f59afb), SPH_C32(0x68035a1b), SPH_C32(0x7a8be830), + SPH_C32(0x68770000), SPH_C32(0x36320000), SPH_C32(0xe3560000), + SPH_C32(0x48dc756d), SPH_C32(0xbad9c18c), SPH_C32(0xedeaf0d5), + SPH_C32(0x6017e720) }, + { SPH_C32(0x24803c30), SPH_C32(0x2ec40000), SPH_C32(0xf5680000), + SPH_C32(0x7b150000), SPH_C32(0x866d78f7), SPH_C32(0x80189761), + SPH_C32(0x777ef92e), SPH_C32(0x6425a879), SPH_C32(0x9580ea40), + SPH_C32(0x528a0000), SPH_C32(0x6b9c0000), SPH_C32(0x8a1f0000), + SPH_C32(0xd3d3496b), SPH_C32(0xfedc7475), SPH_C32(0x8bfefa84), + SPH_C32(0xf258ba2a) }, + { SPH_C32(0xcb8b3e40), SPH_C32(0x14390000), SPH_C32(0xa8c60000), + SPH_C32(0x125c0000), SPH_C32(0x1d6244f1), SPH_C32(0xc41d2298), + SPH_C32(0x116af37f), SPH_C32(0xf66af573), SPH_C32(0x5cebea70), + SPH_C32(0xb5af0000), SPH_C32(0x44180000), SPH_C32(0xac500000), + SPH_C32(0xdbba1292), SPH_C32(0x93208542), SPH_C32(0xdb619300), + SPH_C32(0x6c311542) }, + { SPH_C32(0x8efe4800), SPH_C32(0x525c0000), SPH_C32(0x8ada0000), + SPH_C32(0xf68b0000), SPH_C32(0x800a5d77), SPH_C32(0x31ae3a86), + SPH_C32(0x093cbc28), SPH_C32(0x92fdf249), SPH_C32(0x3b01cc00), + SPH_C32(0x86680000), SPH_C32(0xeac00000), SPH_C32(0xd9eb0000), + SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), SPH_C32(0xb9dacdab), + SPH_C32(0x673aa2a4) }, + { SPH_C32(0x61f54a70), SPH_C32(0x68a10000), SPH_C32(0xd7740000), + SPH_C32(0x9fc20000), SPH_C32(0x1b056171), SPH_C32(0x75ab8f7f), + SPH_C32(0x6f28b679), SPH_C32(0x00b2af43), SPH_C32(0xf26acc30), + SPH_C32(0x614d0000), SPH_C32(0xc5440000), SPH_C32(0xffa40000), + SPH_C32(0xdf870b44), SPH_C32(0xeb842900), SPH_C32(0xe945a42f), + SPH_C32(0xf9530dcc) }, + { SPH_C32(0x47954830), SPH_C32(0xb5790000), SPH_C32(0xa55e0000), + SPH_C32(0xd0c40000), SPH_C32(0x8863068e), SPH_C32(0x5c52cbb1), + SPH_C32(0x59a3d5ac), SPH_C32(0x0c945d21), SPH_C32(0x1d61ce40), + SPH_C32(0x5bb00000), SPH_C32(0x98ea0000), SPH_C32(0x96ed0000), + SPH_C32(0x44883742), SPH_C32(0xaf819cf9), SPH_C32(0x8f51ae7e), + SPH_C32(0x6b1c50c6) }, + { SPH_C32(0xa89e4a40), SPH_C32(0x8f840000), SPH_C32(0xf8f00000), + SPH_C32(0xb98d0000), SPH_C32(0x136c3a88), SPH_C32(0x18577e48), + SPH_C32(0x3fb7dffd), SPH_C32(0x9edb002b), SPH_C32(0xd40ace70), + SPH_C32(0xbc950000), SPH_C32(0xb76e0000), SPH_C32(0xb0a20000), + SPH_C32(0x4ce16cbb), SPH_C32(0xc27d6dce), SPH_C32(0xdfcec7fa), + SPH_C32(0xf575ffae) }, + { SPH_C32(0x9aa47400), SPH_C32(0xebb50000), SPH_C32(0xebfd0000), + SPH_C32(0x07ea0000), SPH_C32(0x4e6b601b), SPH_C32(0x81e707fe), + SPH_C32(0x4e95db08), SPH_C32(0x7373d68c), SPH_C32(0x1866d800), + SPH_C32(0x4ed10000), SPH_C32(0x1e070000), SPH_C32(0x229e0000), + SPH_C32(0xa42374d8), SPH_C32(0x7ede7d7e), SPH_C32(0xbb1ec794), + SPH_C32(0xbb1e44bb) }, + { SPH_C32(0x75af7670), SPH_C32(0xd1480000), SPH_C32(0xb6530000), + SPH_C32(0x6ea30000), SPH_C32(0xd5645c1d), SPH_C32(0xc5e2b207), + SPH_C32(0x2881d159), SPH_C32(0xe13c8b86), SPH_C32(0xd10dd830), + SPH_C32(0xa9f40000), SPH_C32(0x31830000), SPH_C32(0x04d10000), + SPH_C32(0xac4a2f21), SPH_C32(0x13228c49), SPH_C32(0xeb81ae10), + SPH_C32(0x2577ebd3) }, + { SPH_C32(0x53cf7430), SPH_C32(0x0c900000), SPH_C32(0xc4790000), + SPH_C32(0x21a50000), SPH_C32(0x46023be2), SPH_C32(0xec1bf6c9), + SPH_C32(0x1e0ab28c), SPH_C32(0xed1a79e4), SPH_C32(0x3e06da40), + SPH_C32(0x93090000), SPH_C32(0x6c2d0000), SPH_C32(0x6d980000), + SPH_C32(0x37451327), SPH_C32(0x572739b0), SPH_C32(0x8d95a441), + SPH_C32(0xb738b6d9) }, + { SPH_C32(0xbcc47640), SPH_C32(0x366d0000), SPH_C32(0x99d70000), + SPH_C32(0x48ec0000), SPH_C32(0xdd0d07e4), SPH_C32(0xa81e4330), + SPH_C32(0x781eb8dd), SPH_C32(0x7f5524ee), SPH_C32(0xf76dda70), + SPH_C32(0x742c0000), SPH_C32(0x43a90000), SPH_C32(0x4bd70000), + SPH_C32(0x3f2c48de), SPH_C32(0x3adbc887), SPH_C32(0xdd0acdc5), + SPH_C32(0x295119b1) }, + { SPH_C32(0xad995c00), SPH_C32(0x9ae50000), SPH_C32(0x7e1d0000), + SPH_C32(0x0dfe0000), SPH_C32(0xf3c77912), SPH_C32(0xc9089fcf), + SPH_C32(0x0bf8b617), SPH_C32(0x4ed91456), SPH_C32(0x0c3ce400), + SPH_C32(0xf7380000), SPH_C32(0x7f200000), SPH_C32(0xd3ff0000), + SPH_C32(0x6a4249b4), SPH_C32(0xce974006), SPH_C32(0xfcb7a0b4), + SPH_C32(0x5a90607e) }, + { SPH_C32(0x42925e70), SPH_C32(0xa0180000), SPH_C32(0x23b30000), + SPH_C32(0x64b70000), SPH_C32(0x68c84514), SPH_C32(0x8d0d2a36), + SPH_C32(0x6decbc46), SPH_C32(0xdc96495c), SPH_C32(0xc557e430), + SPH_C32(0x101d0000), SPH_C32(0x50a40000), SPH_C32(0xf5b00000), + SPH_C32(0x622b124d), SPH_C32(0xa36bb131), SPH_C32(0xac28c930), + SPH_C32(0xc4f9cf16) }, + { SPH_C32(0x64f25c30), SPH_C32(0x7dc00000), SPH_C32(0x51990000), + SPH_C32(0x2bb10000), SPH_C32(0xfbae22eb), SPH_C32(0xa4f46ef8), + SPH_C32(0x5b67df93), SPH_C32(0xd0b0bb3e), SPH_C32(0x2a5ce640), + SPH_C32(0x2ae00000), SPH_C32(0x0d0a0000), SPH_C32(0x9cf90000), + SPH_C32(0xf9242e4b), SPH_C32(0xe76e04c8), SPH_C32(0xca3cc361), + SPH_C32(0x56b6921c) }, + { SPH_C32(0x8bf95e40), SPH_C32(0x473d0000), SPH_C32(0x0c370000), + SPH_C32(0x42f80000), SPH_C32(0x60a11eed), SPH_C32(0xe0f1db01), + SPH_C32(0x3d73d5c2), SPH_C32(0x42ffe634), SPH_C32(0xe337e670), + SPH_C32(0xcdc50000), SPH_C32(0x228e0000), SPH_C32(0xbab60000), + SPH_C32(0xf14d75b2), SPH_C32(0x8a92f5ff), SPH_C32(0x9aa3aae5), + SPH_C32(0xc8df3d74) }, + { SPH_C32(0xb9c36000), SPH_C32(0x230c0000), SPH_C32(0x1f3a0000), + SPH_C32(0xfc9f0000), SPH_C32(0x3da6447e), SPH_C32(0x7941a2b7), + SPH_C32(0x4c51d137), SPH_C32(0xaf573093), SPH_C32(0x2f5bf000), + SPH_C32(0x3f810000), SPH_C32(0x8be70000), SPH_C32(0x288a0000), + SPH_C32(0x198f6dd1), SPH_C32(0x3631e54f), SPH_C32(0xfe73aa8b), + SPH_C32(0x86b48661) }, + { SPH_C32(0x56c86270), SPH_C32(0x19f10000), SPH_C32(0x42940000), + SPH_C32(0x95d60000), SPH_C32(0xa6a97878), SPH_C32(0x3d44174e), + SPH_C32(0x2a45db66), SPH_C32(0x3d186d99), SPH_C32(0xe630f030), + SPH_C32(0xd8a40000), SPH_C32(0xa4630000), SPH_C32(0x0ec50000), + SPH_C32(0x11e63628), SPH_C32(0x5bcd1478), SPH_C32(0xaeecc30f), + SPH_C32(0x18dd2909) }, + { SPH_C32(0x70a86030), SPH_C32(0xc4290000), SPH_C32(0x30be0000), + SPH_C32(0xdad00000), SPH_C32(0x35cf1f87), SPH_C32(0x14bd5380), + SPH_C32(0x1cceb8b3), SPH_C32(0x313e9ffb), SPH_C32(0x093bf240), + SPH_C32(0xe2590000), SPH_C32(0xf9cd0000), SPH_C32(0x678c0000), + SPH_C32(0x8ae90a2e), SPH_C32(0x1fc8a181), SPH_C32(0xc8f8c95e), + SPH_C32(0x8a927403) }, + { SPH_C32(0x9fa36240), SPH_C32(0xfed40000), SPH_C32(0x6d100000), + SPH_C32(0xb3990000), SPH_C32(0xaec02381), SPH_C32(0x50b8e679), + SPH_C32(0x7adab2e2), SPH_C32(0xa371c2f1), SPH_C32(0xc050f270), + SPH_C32(0x057c0000), SPH_C32(0xd6490000), SPH_C32(0x41c30000), + SPH_C32(0x828051d7), SPH_C32(0x723450b6), SPH_C32(0x9867a0da), + SPH_C32(0x14fbdb6b) }, + { SPH_C32(0x6f299000), SPH_C32(0x6c850000), SPH_C32(0x2f160000), + SPH_C32(0x782e0000), SPH_C32(0x644c37cd), SPH_C32(0x12dd1cd6), + SPH_C32(0xd26a8c36), SPH_C32(0x32219526), SPH_C32(0x29449c00), + SPH_C32(0x64e70000), SPH_C32(0xf24b0000), SPH_C32(0xc2f30000), + SPH_C32(0x0ede4e8f), SPH_C32(0x56c23745), SPH_C32(0xf3e04259), + SPH_C32(0x8d0d9ec4) }, + { SPH_C32(0x80229270), SPH_C32(0x56780000), SPH_C32(0x72b80000), + SPH_C32(0x11670000), SPH_C32(0xff430bcb), SPH_C32(0x56d8a92f), + SPH_C32(0xb47e8667), SPH_C32(0xa06ec82c), SPH_C32(0xe02f9c30), + SPH_C32(0x83c20000), SPH_C32(0xddcf0000), SPH_C32(0xe4bc0000), + SPH_C32(0x06b71576), SPH_C32(0x3b3ec672), SPH_C32(0xa37f2bdd), + SPH_C32(0x136431ac) }, + { SPH_C32(0xa6429030), SPH_C32(0x8ba00000), SPH_C32(0x00920000), + SPH_C32(0x5e610000), SPH_C32(0x6c256c34), SPH_C32(0x7f21ede1), + SPH_C32(0x82f5e5b2), SPH_C32(0xac483a4e), SPH_C32(0x0f249e40), + SPH_C32(0xb93f0000), SPH_C32(0x80610000), SPH_C32(0x8df50000), + SPH_C32(0x9db82970), SPH_C32(0x7f3b738b), SPH_C32(0xc56b218c), + SPH_C32(0x812b6ca6) }, + { SPH_C32(0x49499240), SPH_C32(0xb15d0000), SPH_C32(0x5d3c0000), + SPH_C32(0x37280000), SPH_C32(0xf72a5032), SPH_C32(0x3b245818), + SPH_C32(0xe4e1efe3), SPH_C32(0x3e076744), SPH_C32(0xc64f9e70), + SPH_C32(0x5e1a0000), SPH_C32(0xafe50000), SPH_C32(0xabba0000), + SPH_C32(0x95d17289), SPH_C32(0x12c782bc), SPH_C32(0x95f44808), + SPH_C32(0x1f42c3ce) }, + { SPH_C32(0x7b73ac00), SPH_C32(0xd56c0000), SPH_C32(0x4e310000), + SPH_C32(0x894f0000), SPH_C32(0xaa2d0aa1), SPH_C32(0xa29421ae), + SPH_C32(0x95c3eb16), SPH_C32(0xd3afb1e3), SPH_C32(0x0a238800), + SPH_C32(0xac5e0000), SPH_C32(0x068c0000), SPH_C32(0x39860000), + SPH_C32(0x7d136aea), SPH_C32(0xae64920c), SPH_C32(0xf1244866), + SPH_C32(0x512978db) }, + { SPH_C32(0x9478ae70), SPH_C32(0xef910000), SPH_C32(0x139f0000), + SPH_C32(0xe0060000), SPH_C32(0x312236a7), SPH_C32(0xe6919457), + SPH_C32(0xf3d7e147), SPH_C32(0x41e0ece9), SPH_C32(0xc3488830), + SPH_C32(0x4b7b0000), SPH_C32(0x29080000), SPH_C32(0x1fc90000), + SPH_C32(0x757a3113), SPH_C32(0xc398633b), SPH_C32(0xa1bb21e2), + SPH_C32(0xcf40d7b3) }, + { SPH_C32(0xb218ac30), SPH_C32(0x32490000), SPH_C32(0x61b50000), + SPH_C32(0xaf000000), SPH_C32(0xa2445158), SPH_C32(0xcf68d099), + SPH_C32(0xc55c8292), SPH_C32(0x4dc61e8b), SPH_C32(0x2c438a40), + SPH_C32(0x71860000), SPH_C32(0x74a60000), SPH_C32(0x76800000), + SPH_C32(0xee750d15), SPH_C32(0x879dd6c2), SPH_C32(0xc7af2bb3), + SPH_C32(0x5d0f8ab9) }, + { SPH_C32(0x5d13ae40), SPH_C32(0x08b40000), SPH_C32(0x3c1b0000), + SPH_C32(0xc6490000), SPH_C32(0x394b6d5e), SPH_C32(0x8b6d6560), + SPH_C32(0xa34888c3), SPH_C32(0xdf894381), SPH_C32(0xe5288a70), + SPH_C32(0x96a30000), SPH_C32(0x5b220000), SPH_C32(0x50cf0000), + SPH_C32(0xe61c56ec), SPH_C32(0xea6127f5), SPH_C32(0x97304237), + SPH_C32(0xc36625d1) }, + { SPH_C32(0x4c4e8400), SPH_C32(0xa43c0000), SPH_C32(0xdbd10000), + SPH_C32(0x835b0000), SPH_C32(0x178113a8), SPH_C32(0xea7bb99f), + SPH_C32(0xd0ae8609), SPH_C32(0xee057339), SPH_C32(0x1e79b400), + SPH_C32(0x15b70000), SPH_C32(0x67ab0000), SPH_C32(0xc8e70000), + SPH_C32(0xb3725786), SPH_C32(0x1e2daf74), SPH_C32(0xb68d2f46), + SPH_C32(0xb0a75c1e) }, + { SPH_C32(0xa3458670), SPH_C32(0x9ec10000), SPH_C32(0x867f0000), + SPH_C32(0xea120000), SPH_C32(0x8c8e2fae), SPH_C32(0xae7e0c66), + SPH_C32(0xb6ba8c58), SPH_C32(0x7c4a2e33), SPH_C32(0xd712b430), + SPH_C32(0xf2920000), SPH_C32(0x482f0000), SPH_C32(0xeea80000), + SPH_C32(0xbb1b0c7f), SPH_C32(0x73d15e43), SPH_C32(0xe61246c2), + SPH_C32(0x2ecef376) }, + { SPH_C32(0x85258430), SPH_C32(0x43190000), SPH_C32(0xf4550000), + SPH_C32(0xa5140000), SPH_C32(0x1fe84851), SPH_C32(0x878748a8), + SPH_C32(0x8031ef8d), SPH_C32(0x706cdc51), SPH_C32(0x3819b640), + SPH_C32(0xc86f0000), SPH_C32(0x15810000), SPH_C32(0x87e10000), + SPH_C32(0x20143079), SPH_C32(0x37d4ebba), SPH_C32(0x80064c93), + SPH_C32(0xbc81ae7c) }, + { SPH_C32(0x6a2e8640), SPH_C32(0x79e40000), SPH_C32(0xa9fb0000), + SPH_C32(0xcc5d0000), SPH_C32(0x84e77457), SPH_C32(0xc382fd51), + SPH_C32(0xe625e5dc), SPH_C32(0xe223815b), SPH_C32(0xf172b670), + SPH_C32(0x2f4a0000), SPH_C32(0x3a050000), SPH_C32(0xa1ae0000), + SPH_C32(0x287d6b80), SPH_C32(0x5a281a8d), SPH_C32(0xd0992517), + SPH_C32(0x22e80114) }, + { SPH_C32(0x5814b800), SPH_C32(0x1dd50000), SPH_C32(0xbaf60000), + SPH_C32(0x723a0000), SPH_C32(0xd9e02ec4), SPH_C32(0x5a3284e7), + SPH_C32(0x9707e129), SPH_C32(0x0f8b57fc), SPH_C32(0x3d1ea000), + SPH_C32(0xdd0e0000), SPH_C32(0x936c0000), SPH_C32(0x33920000), + SPH_C32(0xc0bf73e3), SPH_C32(0xe68b0a3d), SPH_C32(0xb4492579), + SPH_C32(0x6c83ba01) }, + { SPH_C32(0xb71fba70), SPH_C32(0x27280000), SPH_C32(0xe7580000), + SPH_C32(0x1b730000), SPH_C32(0x42ef12c2), SPH_C32(0x1e37311e), + SPH_C32(0xf113eb78), SPH_C32(0x9dc40af6), SPH_C32(0xf475a030), + SPH_C32(0x3a2b0000), SPH_C32(0xbce80000), SPH_C32(0x15dd0000), + SPH_C32(0xc8d6281a), SPH_C32(0x8b77fb0a), SPH_C32(0xe4d64cfd), + SPH_C32(0xf2ea1569) }, + { SPH_C32(0x917fb830), SPH_C32(0xfaf00000), SPH_C32(0x95720000), + SPH_C32(0x54750000), SPH_C32(0xd189753d), SPH_C32(0x37ce75d0), + SPH_C32(0xc79888ad), SPH_C32(0x91e2f894), SPH_C32(0x1b7ea240), + SPH_C32(0x00d60000), SPH_C32(0xe1460000), SPH_C32(0x7c940000), + SPH_C32(0x53d9141c), SPH_C32(0xcf724ef3), SPH_C32(0x82c246ac), + SPH_C32(0x60a54863) }, + { SPH_C32(0x7e74ba40), SPH_C32(0xc00d0000), SPH_C32(0xc8dc0000), + SPH_C32(0x3d3c0000), SPH_C32(0x4a86493b), SPH_C32(0x73cbc029), + SPH_C32(0xa18c82fc), SPH_C32(0x03ada59e), SPH_C32(0xd215a270), + SPH_C32(0xe7f30000), SPH_C32(0xcec20000), SPH_C32(0x5adb0000), + SPH_C32(0x5bb04fe5), SPH_C32(0xa28ebfc4), SPH_C32(0xd25d2f28), + SPH_C32(0xfecce70b) }, + { SPH_C32(0x3b01cc00), SPH_C32(0x86680000), SPH_C32(0xeac00000), + SPH_C32(0xd9eb0000), SPH_C32(0xd7ee50bd), SPH_C32(0x8678d837), + SPH_C32(0xb9dacdab), SPH_C32(0x673aa2a4), SPH_C32(0xb5ff8400), + SPH_C32(0xd4340000), SPH_C32(0x601a0000), SPH_C32(0x2f600000), + SPH_C32(0x57e40dca), SPH_C32(0xb7d6e2b1), SPH_C32(0xb0e67183), + SPH_C32(0xf5c750ed) }, + { SPH_C32(0xd40ace70), SPH_C32(0xbc950000), SPH_C32(0xb76e0000), + SPH_C32(0xb0a20000), SPH_C32(0x4ce16cbb), SPH_C32(0xc27d6dce), + SPH_C32(0xdfcec7fa), SPH_C32(0xf575ffae), SPH_C32(0x7c948430), + SPH_C32(0x33110000), SPH_C32(0x4f9e0000), SPH_C32(0x092f0000), + SPH_C32(0x5f8d5633), SPH_C32(0xda2a1386), SPH_C32(0xe0791807), + SPH_C32(0x6baeff85) }, + { SPH_C32(0xf26acc30), SPH_C32(0x614d0000), SPH_C32(0xc5440000), + SPH_C32(0xffa40000), SPH_C32(0xdf870b44), SPH_C32(0xeb842900), + SPH_C32(0xe945a42f), SPH_C32(0xf9530dcc), SPH_C32(0x939f8640), + SPH_C32(0x09ec0000), SPH_C32(0x12300000), SPH_C32(0x60660000), + SPH_C32(0xc4826a35), SPH_C32(0x9e2fa67f), SPH_C32(0x866d1256), + SPH_C32(0xf9e1a28f) }, + { SPH_C32(0x1d61ce40), SPH_C32(0x5bb00000), SPH_C32(0x98ea0000), + SPH_C32(0x96ed0000), SPH_C32(0x44883742), SPH_C32(0xaf819cf9), + SPH_C32(0x8f51ae7e), SPH_C32(0x6b1c50c6), SPH_C32(0x5af48670), + SPH_C32(0xeec90000), SPH_C32(0x3db40000), SPH_C32(0x46290000), + SPH_C32(0xcceb31cc), SPH_C32(0xf3d35748), SPH_C32(0xd6f27bd2), + SPH_C32(0x67880de7) }, + { SPH_C32(0x2f5bf000), SPH_C32(0x3f810000), SPH_C32(0x8be70000), + SPH_C32(0x288a0000), SPH_C32(0x198f6dd1), SPH_C32(0x3631e54f), + SPH_C32(0xfe73aa8b), SPH_C32(0x86b48661), SPH_C32(0x96989000), + SPH_C32(0x1c8d0000), SPH_C32(0x94dd0000), SPH_C32(0xd4150000), + SPH_C32(0x242929af), SPH_C32(0x4f7047f8), SPH_C32(0xb2227bbc), + SPH_C32(0x29e3b6f2) }, + { SPH_C32(0xc050f270), SPH_C32(0x057c0000), SPH_C32(0xd6490000), + SPH_C32(0x41c30000), SPH_C32(0x828051d7), SPH_C32(0x723450b6), + SPH_C32(0x9867a0da), SPH_C32(0x14fbdb6b), SPH_C32(0x5ff39030), + SPH_C32(0xfba80000), SPH_C32(0xbb590000), SPH_C32(0xf25a0000), + SPH_C32(0x2c407256), SPH_C32(0x228cb6cf), SPH_C32(0xe2bd1238), + SPH_C32(0xb78a199a) }, + { SPH_C32(0xe630f030), SPH_C32(0xd8a40000), SPH_C32(0xa4630000), + SPH_C32(0x0ec50000), SPH_C32(0x11e63628), SPH_C32(0x5bcd1478), + SPH_C32(0xaeecc30f), SPH_C32(0x18dd2909), SPH_C32(0xb0f89240), + SPH_C32(0xc1550000), SPH_C32(0xe6f70000), SPH_C32(0x9b130000), + SPH_C32(0xb74f4e50), SPH_C32(0x66890336), SPH_C32(0x84a91869), + SPH_C32(0x25c54490) }, + { SPH_C32(0x093bf240), SPH_C32(0xe2590000), SPH_C32(0xf9cd0000), + SPH_C32(0x678c0000), SPH_C32(0x8ae90a2e), SPH_C32(0x1fc8a181), + SPH_C32(0xc8f8c95e), SPH_C32(0x8a927403), SPH_C32(0x79939270), + SPH_C32(0x26700000), SPH_C32(0xc9730000), SPH_C32(0xbd5c0000), + SPH_C32(0xbf2615a9), SPH_C32(0x0b75f201), SPH_C32(0xd43671ed), + SPH_C32(0xbbacebf8) }, + { SPH_C32(0x1866d800), SPH_C32(0x4ed10000), SPH_C32(0x1e070000), + SPH_C32(0x229e0000), SPH_C32(0xa42374d8), SPH_C32(0x7ede7d7e), + SPH_C32(0xbb1ec794), SPH_C32(0xbb1e44bb), SPH_C32(0x82c2ac00), + SPH_C32(0xa5640000), SPH_C32(0xf5fa0000), SPH_C32(0x25740000), + SPH_C32(0xea4814c3), SPH_C32(0xff397a80), SPH_C32(0xf58b1c9c), + SPH_C32(0xc86d9237) }, + { SPH_C32(0xf76dda70), SPH_C32(0x742c0000), SPH_C32(0x43a90000), + SPH_C32(0x4bd70000), SPH_C32(0x3f2c48de), SPH_C32(0x3adbc887), + SPH_C32(0xdd0acdc5), SPH_C32(0x295119b1), SPH_C32(0x4ba9ac30), + SPH_C32(0x42410000), SPH_C32(0xda7e0000), SPH_C32(0x033b0000), + SPH_C32(0xe2214f3a), SPH_C32(0x92c58bb7), SPH_C32(0xa5147518), + SPH_C32(0x56043d5f) }, + { SPH_C32(0xd10dd830), SPH_C32(0xa9f40000), SPH_C32(0x31830000), + SPH_C32(0x04d10000), SPH_C32(0xac4a2f21), SPH_C32(0x13228c49), + SPH_C32(0xeb81ae10), SPH_C32(0x2577ebd3), SPH_C32(0xa4a2ae40), + SPH_C32(0x78bc0000), SPH_C32(0x87d00000), SPH_C32(0x6a720000), + SPH_C32(0x792e733c), SPH_C32(0xd6c03e4e), SPH_C32(0xc3007f49), + SPH_C32(0xc44b6055) }, + { SPH_C32(0x3e06da40), SPH_C32(0x93090000), SPH_C32(0x6c2d0000), + SPH_C32(0x6d980000), SPH_C32(0x37451327), SPH_C32(0x572739b0), + SPH_C32(0x8d95a441), SPH_C32(0xb738b6d9), SPH_C32(0x6dc9ae70), + SPH_C32(0x9f990000), SPH_C32(0xa8540000), SPH_C32(0x4c3d0000), + SPH_C32(0x714728c5), SPH_C32(0xbb3ccf79), SPH_C32(0x939f16cd), + SPH_C32(0x5a22cf3d) }, + { SPH_C32(0x0c3ce400), SPH_C32(0xf7380000), SPH_C32(0x7f200000), + SPH_C32(0xd3ff0000), SPH_C32(0x6a4249b4), SPH_C32(0xce974006), + SPH_C32(0xfcb7a0b4), SPH_C32(0x5a90607e), SPH_C32(0xa1a5b800), + SPH_C32(0x6ddd0000), SPH_C32(0x013d0000), SPH_C32(0xde010000), + SPH_C32(0x998530a6), SPH_C32(0x079fdfc9), SPH_C32(0xf74f16a3), + SPH_C32(0x14497428) }, + { SPH_C32(0xe337e670), SPH_C32(0xcdc50000), SPH_C32(0x228e0000), + SPH_C32(0xbab60000), SPH_C32(0xf14d75b2), SPH_C32(0x8a92f5ff), + SPH_C32(0x9aa3aae5), SPH_C32(0xc8df3d74), SPH_C32(0x68ceb830), + SPH_C32(0x8af80000), SPH_C32(0x2eb90000), SPH_C32(0xf84e0000), + SPH_C32(0x91ec6b5f), SPH_C32(0x6a632efe), SPH_C32(0xa7d07f27), + SPH_C32(0x8a20db40) }, + { SPH_C32(0xc557e430), SPH_C32(0x101d0000), SPH_C32(0x50a40000), + SPH_C32(0xf5b00000), SPH_C32(0x622b124d), SPH_C32(0xa36bb131), + SPH_C32(0xac28c930), SPH_C32(0xc4f9cf16), SPH_C32(0x87c5ba40), + SPH_C32(0xb0050000), SPH_C32(0x73170000), SPH_C32(0x91070000), + SPH_C32(0x0ae35759), SPH_C32(0x2e669b07), SPH_C32(0xc1c47576), + SPH_C32(0x186f864a) }, + { SPH_C32(0x2a5ce640), SPH_C32(0x2ae00000), SPH_C32(0x0d0a0000), + SPH_C32(0x9cf90000), SPH_C32(0xf9242e4b), SPH_C32(0xe76e04c8), + SPH_C32(0xca3cc361), SPH_C32(0x56b6921c), SPH_C32(0x4eaeba70), + SPH_C32(0x57200000), SPH_C32(0x5c930000), SPH_C32(0xb7480000), + SPH_C32(0x028a0ca0), SPH_C32(0x439a6a30), SPH_C32(0x915b1cf2), + SPH_C32(0x86062922) }, + { SPH_C32(0xf3928800), SPH_C32(0xdc560000), SPH_C32(0xbd470000), + SPH_C32(0x95bd0000), SPH_C32(0x3d767488), SPH_C32(0xf3c9c922), + SPH_C32(0x916cbfec), SPH_C32(0x4aeb5b0f), SPH_C32(0xe1d7d800), + SPH_C32(0x3ed90000), SPH_C32(0xa5cc0000), SPH_C32(0x8ea50000), + SPH_C32(0xe4466aba), SPH_C32(0x23732650), SPH_C32(0xdb56301e), + SPH_C32(0xa0dc676f) }, + { SPH_C32(0x1c998a70), SPH_C32(0xe6ab0000), SPH_C32(0xe0e90000), + SPH_C32(0xfcf40000), SPH_C32(0xa679488e), SPH_C32(0xb7cc7cdb), + SPH_C32(0xf778b5bd), SPH_C32(0xd8a40605), SPH_C32(0x28bcd830), + SPH_C32(0xd9fc0000), SPH_C32(0x8a480000), SPH_C32(0xa8ea0000), + SPH_C32(0xec2f3143), SPH_C32(0x4e8fd767), SPH_C32(0x8bc9599a), + SPH_C32(0x3eb5c807) }, + { SPH_C32(0x3af98830), SPH_C32(0x3b730000), SPH_C32(0x92c30000), + SPH_C32(0xb3f20000), SPH_C32(0x351f2f71), SPH_C32(0x9e353815), + SPH_C32(0xc1f3d668), SPH_C32(0xd482f467), SPH_C32(0xc7b7da40), + SPH_C32(0xe3010000), SPH_C32(0xd7e60000), SPH_C32(0xc1a30000), + SPH_C32(0x77200d45), SPH_C32(0x0a8a629e), SPH_C32(0xeddd53cb), + SPH_C32(0xacfa950d) }, + { SPH_C32(0xd5f28a40), SPH_C32(0x018e0000), SPH_C32(0xcf6d0000), + SPH_C32(0xdabb0000), SPH_C32(0xae101377), SPH_C32(0xda308dec), + SPH_C32(0xa7e7dc39), SPH_C32(0x46cda96d), SPH_C32(0x0edcda70), + SPH_C32(0x04240000), SPH_C32(0xf8620000), SPH_C32(0xe7ec0000), + SPH_C32(0x7f4956bc), SPH_C32(0x677693a9), SPH_C32(0xbd423a4f), + SPH_C32(0x32933a65) }, + { SPH_C32(0xe7c8b400), SPH_C32(0x65bf0000), SPH_C32(0xdc600000), + SPH_C32(0x64dc0000), SPH_C32(0xf31749e4), SPH_C32(0x4380f45a), + SPH_C32(0xd6c5d8cc), SPH_C32(0xab657fca), SPH_C32(0xc2b0cc00), + SPH_C32(0xf6600000), SPH_C32(0x510b0000), SPH_C32(0x75d00000), + SPH_C32(0x978b4edf), SPH_C32(0xdbd58319), SPH_C32(0xd9923a21), + SPH_C32(0x7cf88170) }, + { SPH_C32(0x08c3b670), SPH_C32(0x5f420000), SPH_C32(0x81ce0000), + SPH_C32(0x0d950000), SPH_C32(0x681875e2), SPH_C32(0x078541a3), + SPH_C32(0xb0d1d29d), SPH_C32(0x392a22c0), SPH_C32(0x0bdbcc30), + SPH_C32(0x11450000), SPH_C32(0x7e8f0000), SPH_C32(0x539f0000), + SPH_C32(0x9fe21526), SPH_C32(0xb629722e), SPH_C32(0x890d53a5), + SPH_C32(0xe2912e18) }, + { SPH_C32(0x2ea3b430), SPH_C32(0x829a0000), SPH_C32(0xf3e40000), + SPH_C32(0x42930000), SPH_C32(0xfb7e121d), SPH_C32(0x2e7c056d), + SPH_C32(0x865ab148), SPH_C32(0x350cd0a2), SPH_C32(0xe4d0ce40), + SPH_C32(0x2bb80000), SPH_C32(0x23210000), SPH_C32(0x3ad60000), + SPH_C32(0x04ed2920), SPH_C32(0xf22cc7d7), SPH_C32(0xef1959f4), + SPH_C32(0x70de7312) }, + { SPH_C32(0xc1a8b640), SPH_C32(0xb8670000), SPH_C32(0xae4a0000), + SPH_C32(0x2bda0000), SPH_C32(0x60712e1b), SPH_C32(0x6a79b094), + SPH_C32(0xe04ebb19), SPH_C32(0xa7438da8), SPH_C32(0x2dbbce70), + SPH_C32(0xcc9d0000), SPH_C32(0x0ca50000), SPH_C32(0x1c990000), + SPH_C32(0x0c8472d9), SPH_C32(0x9fd036e0), SPH_C32(0xbf863070), + SPH_C32(0xeeb7dc7a) }, + { SPH_C32(0xd0f59c00), SPH_C32(0x14ef0000), SPH_C32(0x49800000), + SPH_C32(0x6ec80000), SPH_C32(0x4ebb50ed), SPH_C32(0x0b6f6c6b), + SPH_C32(0x93a8b5d3), SPH_C32(0x96cfbd10), SPH_C32(0xd6eaf000), + SPH_C32(0x4f890000), SPH_C32(0x302c0000), SPH_C32(0x84b10000), + SPH_C32(0x59ea73b3), SPH_C32(0x6b9cbe61), SPH_C32(0x9e3b5d01), + SPH_C32(0x9d76a5b5) }, + { SPH_C32(0x3ffe9e70), SPH_C32(0x2e120000), SPH_C32(0x142e0000), + SPH_C32(0x07810000), SPH_C32(0xd5b46ceb), SPH_C32(0x4f6ad992), + SPH_C32(0xf5bcbf82), SPH_C32(0x0480e01a), SPH_C32(0x1f81f030), + SPH_C32(0xa8ac0000), SPH_C32(0x1fa80000), SPH_C32(0xa2fe0000), + SPH_C32(0x5183284a), SPH_C32(0x06604f56), SPH_C32(0xcea43485), + SPH_C32(0x031f0add) }, + { SPH_C32(0x199e9c30), SPH_C32(0xf3ca0000), SPH_C32(0x66040000), + SPH_C32(0x48870000), SPH_C32(0x46d20b14), SPH_C32(0x66939d5c), + SPH_C32(0xc337dc57), SPH_C32(0x08a61278), SPH_C32(0xf08af240), + SPH_C32(0x92510000), SPH_C32(0x42060000), SPH_C32(0xcbb70000), + SPH_C32(0xca8c144c), SPH_C32(0x4265faaf), SPH_C32(0xa8b03ed4), + SPH_C32(0x915057d7) }, + { SPH_C32(0xf6959e40), SPH_C32(0xc9370000), SPH_C32(0x3baa0000), + SPH_C32(0x21ce0000), SPH_C32(0xdddd3712), SPH_C32(0x229628a5), + SPH_C32(0xa523d606), SPH_C32(0x9ae94f72), SPH_C32(0x39e1f270), + SPH_C32(0x75740000), SPH_C32(0x6d820000), SPH_C32(0xedf80000), + SPH_C32(0xc2e54fb5), SPH_C32(0x2f990b98), SPH_C32(0xf82f5750), + SPH_C32(0x0f39f8bf) }, + { SPH_C32(0xc4afa000), SPH_C32(0xad060000), SPH_C32(0x28a70000), + SPH_C32(0x9fa90000), SPH_C32(0x80da6d81), SPH_C32(0xbb265113), + SPH_C32(0xd401d2f3), SPH_C32(0x774199d5), SPH_C32(0xf58de400), + SPH_C32(0x87300000), SPH_C32(0xc4eb0000), SPH_C32(0x7fc40000), + SPH_C32(0x2a2757d6), SPH_C32(0x933a1b28), SPH_C32(0x9cff573e), + SPH_C32(0x415243aa) }, + { SPH_C32(0x2ba4a270), SPH_C32(0x97fb0000), SPH_C32(0x75090000), + SPH_C32(0xf6e00000), SPH_C32(0x1bd55187), SPH_C32(0xff23e4ea), + SPH_C32(0xb215d8a2), SPH_C32(0xe50ec4df), SPH_C32(0x3ce6e430), + SPH_C32(0x60150000), SPH_C32(0xeb6f0000), SPH_C32(0x598b0000), + SPH_C32(0x224e0c2f), SPH_C32(0xfec6ea1f), SPH_C32(0xcc603eba), + SPH_C32(0xdf3becc2) }, + { SPH_C32(0x0dc4a030), SPH_C32(0x4a230000), SPH_C32(0x07230000), + SPH_C32(0xb9e60000), SPH_C32(0x88b33678), SPH_C32(0xd6daa024), + SPH_C32(0x849ebb77), SPH_C32(0xe92836bd), SPH_C32(0xd3ede640), + SPH_C32(0x5ae80000), SPH_C32(0xb6c10000), SPH_C32(0x30c20000), + SPH_C32(0xb9413029), SPH_C32(0xbac35fe6), SPH_C32(0xaa7434eb), + SPH_C32(0x4d74b1c8) }, + { SPH_C32(0xe2cfa240), SPH_C32(0x70de0000), SPH_C32(0x5a8d0000), + SPH_C32(0xd0af0000), SPH_C32(0x13bc0a7e), SPH_C32(0x92df15dd), + SPH_C32(0xe28ab126), SPH_C32(0x7b676bb7), SPH_C32(0x1a86e670), + SPH_C32(0xbdcd0000), SPH_C32(0x99450000), SPH_C32(0x168d0000), + SPH_C32(0xb1286bd0), SPH_C32(0xd73faed1), SPH_C32(0xfaeb5d6f), + SPH_C32(0xd31d1ea0) }, + { SPH_C32(0xa7bad400), SPH_C32(0x36bb0000), SPH_C32(0x78910000), + SPH_C32(0x34780000), SPH_C32(0x8ed413f8), SPH_C32(0x676c0dc3), + SPH_C32(0xfadcfe71), SPH_C32(0x1ff06c8d), SPH_C32(0x7d6cc000), + SPH_C32(0x8e0a0000), SPH_C32(0x379d0000), SPH_C32(0x63360000), + SPH_C32(0xbd7c29ff), SPH_C32(0xc267f3a4), SPH_C32(0x985003c4), + SPH_C32(0xd816a946) }, + { SPH_C32(0x48b1d670), SPH_C32(0x0c460000), SPH_C32(0x253f0000), + SPH_C32(0x5d310000), SPH_C32(0x15db2ffe), SPH_C32(0x2369b83a), + SPH_C32(0x9cc8f420), SPH_C32(0x8dbf3187), SPH_C32(0xb407c030), + SPH_C32(0x692f0000), SPH_C32(0x18190000), SPH_C32(0x45790000), + SPH_C32(0xb5157206), SPH_C32(0xaf9b0293), SPH_C32(0xc8cf6a40), + SPH_C32(0x467f062e) }, + { SPH_C32(0x6ed1d430), SPH_C32(0xd19e0000), SPH_C32(0x57150000), + SPH_C32(0x12370000), SPH_C32(0x86bd4801), SPH_C32(0x0a90fcf4), + SPH_C32(0xaa4397f5), SPH_C32(0x8199c3e5), SPH_C32(0x5b0cc240), + SPH_C32(0x53d20000), SPH_C32(0x45b70000), SPH_C32(0x2c300000), + SPH_C32(0x2e1a4e00), SPH_C32(0xeb9eb76a), SPH_C32(0xaedb6011), + SPH_C32(0xd4305b24) }, + { SPH_C32(0x81dad640), SPH_C32(0xeb630000), SPH_C32(0x0abb0000), + SPH_C32(0x7b7e0000), SPH_C32(0x1db27407), SPH_C32(0x4e95490d), + SPH_C32(0xcc579da4), SPH_C32(0x13d69eef), SPH_C32(0x9267c270), + SPH_C32(0xb4f70000), SPH_C32(0x6a330000), SPH_C32(0x0a7f0000), + SPH_C32(0x267315f9), SPH_C32(0x8662465d), SPH_C32(0xfe440995), + SPH_C32(0x4a59f44c) }, + { SPH_C32(0xb3e0e800), SPH_C32(0x8f520000), SPH_C32(0x19b60000), + SPH_C32(0xc5190000), SPH_C32(0x40b52e94), SPH_C32(0xd72530bb), + SPH_C32(0xbd759951), SPH_C32(0xfe7e4848), SPH_C32(0x5e0bd400), + SPH_C32(0x46b30000), SPH_C32(0xc35a0000), SPH_C32(0x98430000), + SPH_C32(0xceb10d9a), SPH_C32(0x3ac156ed), SPH_C32(0x9a9409fb), + SPH_C32(0x04324f59) }, + { SPH_C32(0x5cebea70), SPH_C32(0xb5af0000), SPH_C32(0x44180000), + SPH_C32(0xac500000), SPH_C32(0xdbba1292), SPH_C32(0x93208542), + SPH_C32(0xdb619300), SPH_C32(0x6c311542), SPH_C32(0x9760d430), + SPH_C32(0xa1960000), SPH_C32(0xecde0000), SPH_C32(0xbe0c0000), + SPH_C32(0xc6d85663), SPH_C32(0x573da7da), SPH_C32(0xca0b607f), + SPH_C32(0x9a5be031) }, + { SPH_C32(0x7a8be830), SPH_C32(0x68770000), SPH_C32(0x36320000), + SPH_C32(0xe3560000), SPH_C32(0x48dc756d), SPH_C32(0xbad9c18c), + SPH_C32(0xedeaf0d5), SPH_C32(0x6017e720), SPH_C32(0x786bd640), + SPH_C32(0x9b6b0000), SPH_C32(0xb1700000), SPH_C32(0xd7450000), + SPH_C32(0x5dd76a65), SPH_C32(0x13381223), SPH_C32(0xac1f6a2e), + SPH_C32(0x0814bd3b) }, + { SPH_C32(0x9580ea40), SPH_C32(0x528a0000), SPH_C32(0x6b9c0000), + SPH_C32(0x8a1f0000), SPH_C32(0xd3d3496b), SPH_C32(0xfedc7475), + SPH_C32(0x8bfefa84), SPH_C32(0xf258ba2a), SPH_C32(0xb100d670), + SPH_C32(0x7c4e0000), SPH_C32(0x9ef40000), SPH_C32(0xf10a0000), + SPH_C32(0x55be319c), SPH_C32(0x7ec4e314), SPH_C32(0xfc8003aa), + SPH_C32(0x967d1253) }, + { SPH_C32(0x84ddc000), SPH_C32(0xfe020000), SPH_C32(0x8c560000), + SPH_C32(0xcf0d0000), SPH_C32(0xfd19379d), SPH_C32(0x9fcaa88a), + SPH_C32(0xf818f44e), SPH_C32(0xc3d48a92), SPH_C32(0x4a51e800), + SPH_C32(0xff5a0000), SPH_C32(0xa27d0000), SPH_C32(0x69220000), + SPH_C32(0x00d030f6), SPH_C32(0x8a886b95), SPH_C32(0xdd3d6edb), + SPH_C32(0xe5bc6b9c) }, + { SPH_C32(0x6bd6c270), SPH_C32(0xc4ff0000), SPH_C32(0xd1f80000), + SPH_C32(0xa6440000), SPH_C32(0x66160b9b), SPH_C32(0xdbcf1d73), + SPH_C32(0x9e0cfe1f), SPH_C32(0x519bd798), SPH_C32(0x833ae830), + SPH_C32(0x187f0000), SPH_C32(0x8df90000), SPH_C32(0x4f6d0000), + SPH_C32(0x08b96b0f), SPH_C32(0xe7749aa2), SPH_C32(0x8da2075f), + SPH_C32(0x7bd5c4f4) }, + { SPH_C32(0x4db6c030), SPH_C32(0x19270000), SPH_C32(0xa3d20000), + SPH_C32(0xe9420000), SPH_C32(0xf5706c64), SPH_C32(0xf23659bd), + SPH_C32(0xa8879dca), SPH_C32(0x5dbd25fa), SPH_C32(0x6c31ea40), + SPH_C32(0x22820000), SPH_C32(0xd0570000), SPH_C32(0x26240000), + SPH_C32(0x93b65709), SPH_C32(0xa3712f5b), SPH_C32(0xebb60d0e), + SPH_C32(0xe99a99fe) }, + { SPH_C32(0xa2bdc240), SPH_C32(0x23da0000), SPH_C32(0xfe7c0000), + SPH_C32(0x800b0000), SPH_C32(0x6e7f5062), SPH_C32(0xb633ec44), + SPH_C32(0xce93979b), SPH_C32(0xcff278f0), SPH_C32(0xa55aea70), + SPH_C32(0xc5a70000), SPH_C32(0xffd30000), SPH_C32(0x006b0000), + SPH_C32(0x9bdf0cf0), SPH_C32(0xce8dde6c), SPH_C32(0xbb29648a), + SPH_C32(0x77f33696) }, + { SPH_C32(0x9087fc00), SPH_C32(0x47eb0000), SPH_C32(0xed710000), + SPH_C32(0x3e6c0000), SPH_C32(0x33780af1), SPH_C32(0x2f8395f2), + SPH_C32(0xbfb1936e), SPH_C32(0x225aae57), SPH_C32(0x6936fc00), + SPH_C32(0x37e30000), SPH_C32(0x56ba0000), SPH_C32(0x92570000), + SPH_C32(0x731d1493), SPH_C32(0x722ecedc), SPH_C32(0xdff964e4), + SPH_C32(0x39988d83) }, + { SPH_C32(0x7f8cfe70), SPH_C32(0x7d160000), SPH_C32(0xb0df0000), + SPH_C32(0x57250000), SPH_C32(0xa87736f7), SPH_C32(0x6b86200b), + SPH_C32(0xd9a5993f), SPH_C32(0xb015f35d), SPH_C32(0xa05dfc30), + SPH_C32(0xd0c60000), SPH_C32(0x793e0000), SPH_C32(0xb4180000), + SPH_C32(0x7b744f6a), SPH_C32(0x1fd23feb), SPH_C32(0x8f660d60), + SPH_C32(0xa7f122eb) }, + { SPH_C32(0x59ecfc30), SPH_C32(0xa0ce0000), SPH_C32(0xc2f50000), + SPH_C32(0x18230000), SPH_C32(0x3b115108), SPH_C32(0x427f64c5), + SPH_C32(0xef2efaea), SPH_C32(0xbc33013f), SPH_C32(0x4f56fe40), + SPH_C32(0xea3b0000), SPH_C32(0x24900000), SPH_C32(0xdd510000), + SPH_C32(0xe07b736c), SPH_C32(0x5bd78a12), SPH_C32(0xe9720731), + SPH_C32(0x35be7fe1) }, + { SPH_C32(0xb6e7fe40), SPH_C32(0x9a330000), SPH_C32(0x9f5b0000), + SPH_C32(0x716a0000), SPH_C32(0xa01e6d0e), SPH_C32(0x067ad13c), + SPH_C32(0x893af0bb), SPH_C32(0x2e7c5c35), SPH_C32(0x863dfe70), + SPH_C32(0x0d1e0000), SPH_C32(0x0b140000), SPH_C32(0xfb1e0000), + SPH_C32(0xe8122895), SPH_C32(0x362b7b25), SPH_C32(0xb9ed6eb5), + SPH_C32(0xabd7d089) } +}; + +static const sph_u32 T512_8[256][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xf6800005), SPH_C32(0x3443c000), SPH_C32(0x24070000), + SPH_C32(0x8f3d0000), SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), + SPH_C32(0xcdc58b19), SPH_C32(0xd795ba31), SPH_C32(0xa67f0001), + SPH_C32(0x71378000), SPH_C32(0x19fc0000), SPH_C32(0x96db0000), + SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), SPH_C32(0x2c6d478f), + SPH_C32(0xac8e6c88) }, + { SPH_C32(0xa67f0001), SPH_C32(0x71378000), SPH_C32(0x19fc0000), + SPH_C32(0x96db0000), SPH_C32(0x3a8b6dfd), SPH_C32(0xebcaaef3), + SPH_C32(0x2c6d478f), SPH_C32(0xac8e6c88), SPH_C32(0x50ff0004), + SPH_C32(0x45744000), SPH_C32(0x3dfb0000), SPH_C32(0x19e60000), + SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), SPH_C32(0xe1a8cc96), + SPH_C32(0x7b1bd6b9) }, + { SPH_C32(0x50ff0004), SPH_C32(0x45744000), SPH_C32(0x3dfb0000), + SPH_C32(0x19e60000), SPH_C32(0x1bbc5606), SPH_C32(0xe1727b5d), + SPH_C32(0xe1a8cc96), SPH_C32(0x7b1bd6b9), SPH_C32(0xf6800005), + SPH_C32(0x3443c000), SPH_C32(0x24070000), SPH_C32(0x8f3d0000), + SPH_C32(0x21373bfb), SPH_C32(0x0ab8d5ae), SPH_C32(0xcdc58b19), + SPH_C32(0xd795ba31) }, + { SPH_C32(0xf7750009), SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), + SPH_C32(0x04920000), SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), + SPH_C32(0x7a87f14e), SPH_C32(0x9e16981a), SPH_C32(0xd46a0000), + SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), SPH_C32(0x4a290000), + SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), SPH_C32(0x98369604), + SPH_C32(0xf746c320) }, + { SPH_C32(0x01f5000c), SPH_C32(0xfb7f0000), SPH_C32(0xe7d10000), + SPH_C32(0x8baf0000), SPH_C32(0x23a22252), SPH_C32(0xf250e314), + SPH_C32(0xb7427a57), SPH_C32(0x4983222b), SPH_C32(0x72150001), + SPH_C32(0xfcff4000), SPH_C32(0xbc530000), SPH_C32(0xdcf20000), + SPH_C32(0xc6c52f87), SPH_C32(0x227e289f), SPH_C32(0xb45bd18b), + SPH_C32(0x5bc8afa8) }, + { SPH_C32(0x510a0008), SPH_C32(0xbe0b4000), SPH_C32(0xda2a0000), + SPH_C32(0x92490000), SPH_C32(0x381e7454), SPH_C32(0x13229849), + SPH_C32(0x56eab6c1), SPH_C32(0x3298f492), SPH_C32(0x84950004), + SPH_C32(0xc8bc8000), SPH_C32(0x98540000), SPH_C32(0x53cf0000), + SPH_C32(0xe7f2147c), SPH_C32(0x28c6fd31), SPH_C32(0x799e5a92), + SPH_C32(0x8c5d1599) }, + { SPH_C32(0xa78a000d), SPH_C32(0x8a488000), SPH_C32(0xfe2d0000), + SPH_C32(0x1d740000), SPH_C32(0x19294faf), SPH_C32(0x199a4de7), + SPH_C32(0x9b2f3dd8), SPH_C32(0xe50d4ea3), SPH_C32(0x22ea0005), + SPH_C32(0xb98b0000), SPH_C32(0x81a80000), SPH_C32(0xc5140000), + SPH_C32(0xdd797981), SPH_C32(0xc30c53c2), SPH_C32(0x55f31d1d), + SPH_C32(0x20d37911) }, + { SPH_C32(0xd46a0000), SPH_C32(0x8dc8c000), SPH_C32(0xa5af0000), + SPH_C32(0x4a290000), SPH_C32(0xfc4e427a), SPH_C32(0xc9b4866c), + SPH_C32(0x98369604), SPH_C32(0xf746c320), SPH_C32(0x231f0009), + SPH_C32(0x42f40000), SPH_C32(0x66790000), SPH_C32(0x4ebb0000), + SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), SPH_C32(0xe2b1674a), + SPH_C32(0x69505b3a) }, + { SPH_C32(0x22ea0005), SPH_C32(0xb98b0000), SPH_C32(0x81a80000), + SPH_C32(0xc5140000), SPH_C32(0xdd797981), SPH_C32(0xc30c53c2), + SPH_C32(0x55f31d1d), SPH_C32(0x20d37911), SPH_C32(0x85600008), + SPH_C32(0x33c38000), SPH_C32(0x7f850000), SPH_C32(0xd8600000), + SPH_C32(0xc450362e), SPH_C32(0xda961e25), SPH_C32(0xcedc20c5), + SPH_C32(0xc5de37b2) }, + { SPH_C32(0x72150001), SPH_C32(0xfcff4000), SPH_C32(0xbc530000), + SPH_C32(0xdcf20000), SPH_C32(0xc6c52f87), SPH_C32(0x227e289f), + SPH_C32(0xb45bd18b), SPH_C32(0x5bc8afa8), SPH_C32(0x73e0000d), + SPH_C32(0x07804000), SPH_C32(0x5b820000), SPH_C32(0x575d0000), + SPH_C32(0xe5670dd5), SPH_C32(0xd02ecb8b), SPH_C32(0x0319abdc), + SPH_C32(0x124b8d83) }, + { SPH_C32(0x84950004), SPH_C32(0xc8bc8000), SPH_C32(0x98540000), + SPH_C32(0x53cf0000), SPH_C32(0xe7f2147c), SPH_C32(0x28c6fd31), + SPH_C32(0x799e5a92), SPH_C32(0x8c5d1599), SPH_C32(0xd59f000c), + SPH_C32(0x76b7c000), SPH_C32(0x427e0000), SPH_C32(0xc1860000), + SPH_C32(0xdfec6028), SPH_C32(0x3be46578), SPH_C32(0x2f74ec53), + SPH_C32(0xbec5e10b) }, + { SPH_C32(0x231f0009), SPH_C32(0x42f40000), SPH_C32(0x66790000), + SPH_C32(0x4ebb0000), SPH_C32(0xfedb5bd3), SPH_C32(0x315cb0d6), + SPH_C32(0xe2b1674a), SPH_C32(0x69505b3a), SPH_C32(0xf7750009), + SPH_C32(0xcf3cc000), SPH_C32(0xc3d60000), SPH_C32(0x04920000), + SPH_C32(0x029519a9), SPH_C32(0xf8e836ba), SPH_C32(0x7a87f14e), + SPH_C32(0x9e16981a) }, + { SPH_C32(0xd59f000c), SPH_C32(0x76b7c000), SPH_C32(0x427e0000), + SPH_C32(0xc1860000), SPH_C32(0xdfec6028), SPH_C32(0x3be46578), + SPH_C32(0x2f74ec53), SPH_C32(0xbec5e10b), SPH_C32(0x510a0008), + SPH_C32(0xbe0b4000), SPH_C32(0xda2a0000), SPH_C32(0x92490000), + SPH_C32(0x381e7454), SPH_C32(0x13229849), SPH_C32(0x56eab6c1), + SPH_C32(0x3298f492) }, + { SPH_C32(0x85600008), SPH_C32(0x33c38000), SPH_C32(0x7f850000), + SPH_C32(0xd8600000), SPH_C32(0xc450362e), SPH_C32(0xda961e25), + SPH_C32(0xcedc20c5), SPH_C32(0xc5de37b2), SPH_C32(0xa78a000d), + SPH_C32(0x8a488000), SPH_C32(0xfe2d0000), SPH_C32(0x1d740000), + SPH_C32(0x19294faf), SPH_C32(0x199a4de7), SPH_C32(0x9b2f3dd8), + SPH_C32(0xe50d4ea3) }, + { SPH_C32(0x73e0000d), SPH_C32(0x07804000), SPH_C32(0x5b820000), + SPH_C32(0x575d0000), SPH_C32(0xe5670dd5), SPH_C32(0xd02ecb8b), + SPH_C32(0x0319abdc), SPH_C32(0x124b8d83), SPH_C32(0x01f5000c), + SPH_C32(0xfb7f0000), SPH_C32(0xe7d10000), SPH_C32(0x8baf0000), + SPH_C32(0x23a22252), SPH_C32(0xf250e314), SPH_C32(0xb7427a57), + SPH_C32(0x4983222b) }, + { SPH_C32(0x774400f0), SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), + SPH_C32(0x34140000), SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), + SPH_C32(0x0bc3cd1e), SPH_C32(0xcf3775cb), SPH_C32(0xf46c0050), + SPH_C32(0x96180000), SPH_C32(0x14a50000), SPH_C32(0x031f0000), + SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), SPH_C32(0x9ca470d2), + SPH_C32(0x8a341574) }, + { SPH_C32(0x81c400f5), SPH_C32(0xc519c000), SPH_C32(0xd1b50000), + SPH_C32(0xbb290000), SPH_C32(0xa8004577), SPH_C32(0x5033398b), + SPH_C32(0xc6064607), SPH_C32(0x18a2cffa), SPH_C32(0x52130051), + SPH_C32(0xe72f8000), SPH_C32(0x0d590000), SPH_C32(0x95c40000), + SPH_C32(0x781f1345), SPH_C32(0x8d75d0ea), SPH_C32(0xb0c9375d), + SPH_C32(0x26ba79fc) }, + { SPH_C32(0xd13b00f1), SPH_C32(0x806d8000), SPH_C32(0xec4e0000), + SPH_C32(0xa2cf0000), SPH_C32(0xb3bc1371), SPH_C32(0xb14142d6), + SPH_C32(0x27ae8a91), SPH_C32(0x63b91943), SPH_C32(0xa4930054), + SPH_C32(0xd36c4000), SPH_C32(0x295e0000), SPH_C32(0x1af90000), + SPH_C32(0x592828be), SPH_C32(0x87cd0544), SPH_C32(0x7d0cbc44), + SPH_C32(0xf12fc3cd) }, + { SPH_C32(0x27bb00f4), SPH_C32(0xb42e4000), SPH_C32(0xc8490000), + SPH_C32(0x2df20000), SPH_C32(0x928b288a), SPH_C32(0xbbf99778), + SPH_C32(0xea6b0188), SPH_C32(0xb42ca372), SPH_C32(0x02ec0055), + SPH_C32(0xa25bc000), SPH_C32(0x30a20000), SPH_C32(0x8c220000), + SPH_C32(0x63a34543), SPH_C32(0x6c07abb7), SPH_C32(0x5161fbcb), + SPH_C32(0x5da1af45) }, + { SPH_C32(0x803100f9), SPH_C32(0x3e66c000), SPH_C32(0x36640000), + SPH_C32(0x30860000), SPH_C32(0x8ba26725), SPH_C32(0xa263da9f), + SPH_C32(0x71443c50), SPH_C32(0x5121edd1), SPH_C32(0x20060050), + SPH_C32(0x1bd0c000), SPH_C32(0xb10a0000), SPH_C32(0x49360000), + SPH_C32(0xbeda3cc2), SPH_C32(0xaf0bf875), SPH_C32(0x0492e6d6), + SPH_C32(0x7d72d654) }, + { SPH_C32(0x76b100fc), SPH_C32(0x0a250000), SPH_C32(0x12630000), + SPH_C32(0xbfbb0000), SPH_C32(0xaa955cde), SPH_C32(0xa8db0f31), + SPH_C32(0xbc81b749), SPH_C32(0x86b457e0), SPH_C32(0x86790051), + SPH_C32(0x6ae74000), SPH_C32(0xa8f60000), SPH_C32(0xdfed0000), + SPH_C32(0x8451513f), SPH_C32(0x44c15686), SPH_C32(0x28ffa159), + SPH_C32(0xd1fcbadc) }, + { SPH_C32(0x264e00f8), SPH_C32(0x4f514000), SPH_C32(0x2f980000), + SPH_C32(0xa65d0000), SPH_C32(0xb1290ad8), SPH_C32(0x49a9746c), + SPH_C32(0x5d297bdf), SPH_C32(0xfdaf8159), SPH_C32(0x70f90054), + SPH_C32(0x5ea48000), SPH_C32(0x8cf10000), SPH_C32(0x50d00000), + SPH_C32(0xa5666ac4), SPH_C32(0x4e798328), SPH_C32(0xe53a2a40), + SPH_C32(0x066900ed) }, + { SPH_C32(0xd0ce00fd), SPH_C32(0x7b128000), SPH_C32(0x0b9f0000), + SPH_C32(0x29600000), SPH_C32(0x901e3123), SPH_C32(0x4311a1c2), + SPH_C32(0x90ecf0c6), SPH_C32(0x2a3a3b68), SPH_C32(0xd6860055), + SPH_C32(0x2f930000), SPH_C32(0x950d0000), SPH_C32(0xc60b0000), + SPH_C32(0x9fed0739), SPH_C32(0xa5b32ddb), SPH_C32(0xc9576dcf), + SPH_C32(0xaae76c65) }, + { SPH_C32(0xa32e00f0), SPH_C32(0x7c92c000), SPH_C32(0x501d0000), + SPH_C32(0x7e3d0000), SPH_C32(0x75793cf6), SPH_C32(0x933f6a49), + SPH_C32(0x93f55b1a), SPH_C32(0x3871b6eb), SPH_C32(0xd7730059), + SPH_C32(0xd4ec0000), SPH_C32(0x72dc0000), SPH_C32(0x4da40000), + SPH_C32(0xbc4f256b), SPH_C32(0x57e3cecf), SPH_C32(0x7e151798), + SPH_C32(0xe3644e4e) }, + { SPH_C32(0x55ae00f5), SPH_C32(0x48d10000), SPH_C32(0x741a0000), + SPH_C32(0xf1000000), SPH_C32(0x544e070d), SPH_C32(0x9987bfe7), + SPH_C32(0x5e30d003), SPH_C32(0xefe40cda), SPH_C32(0x710c0058), + SPH_C32(0xa5db8000), SPH_C32(0x6b200000), SPH_C32(0xdb7f0000), + SPH_C32(0x86c44896), SPH_C32(0xbc29603c), SPH_C32(0x52785017), + SPH_C32(0x4fea22c6) }, + { SPH_C32(0x055100f1), SPH_C32(0x0da54000), SPH_C32(0x49e10000), + SPH_C32(0xe8e60000), SPH_C32(0x4ff2510b), SPH_C32(0x78f5c4ba), + SPH_C32(0xbf981c95), SPH_C32(0x94ffda63), SPH_C32(0x878c005d), + SPH_C32(0x91984000), SPH_C32(0x4f270000), SPH_C32(0x54420000), + SPH_C32(0xa7f3736d), SPH_C32(0xb691b592), SPH_C32(0x9fbddb0e), + SPH_C32(0x987f98f7) }, + { SPH_C32(0xf3d100f4), SPH_C32(0x39e68000), SPH_C32(0x6de60000), + SPH_C32(0x67db0000), SPH_C32(0x6ec56af0), SPH_C32(0x724d1114), + SPH_C32(0x725d978c), SPH_C32(0x436a6052), SPH_C32(0x21f3005c), + SPH_C32(0xe0afc000), SPH_C32(0x56db0000), SPH_C32(0xc2990000), + SPH_C32(0x9d781e90), SPH_C32(0x5d5b1b61), SPH_C32(0xb3d09c81), + SPH_C32(0x34f1f47f) }, + { SPH_C32(0x545b00f9), SPH_C32(0xb3ae0000), SPH_C32(0x93cb0000), + SPH_C32(0x7aaf0000), SPH_C32(0x77ec255f), SPH_C32(0x6bd75cf3), + SPH_C32(0xe972aa54), SPH_C32(0xa6672ef1), SPH_C32(0x03190059), + SPH_C32(0x5924c000), SPH_C32(0xd7730000), SPH_C32(0x078d0000), + SPH_C32(0x40016711), SPH_C32(0x9e5748a3), SPH_C32(0xe623819c), + SPH_C32(0x14228d6e) }, + { SPH_C32(0xa2db00fc), SPH_C32(0x87edc000), SPH_C32(0xb7cc0000), + SPH_C32(0xf5920000), SPH_C32(0x56db1ea4), SPH_C32(0x616f895d), + SPH_C32(0x24b7214d), SPH_C32(0x71f294c0), SPH_C32(0xa5660058), + SPH_C32(0x28134000), SPH_C32(0xce8f0000), SPH_C32(0x91560000), + SPH_C32(0x7a8a0aec), SPH_C32(0x759de650), SPH_C32(0xca4ec613), + SPH_C32(0xb8ace1e6) }, + { SPH_C32(0xf22400f8), SPH_C32(0xc2998000), SPH_C32(0x8a370000), + SPH_C32(0xec740000), SPH_C32(0x4d6748a2), SPH_C32(0x801df200), + SPH_C32(0xc51feddb), SPH_C32(0x0ae94279), SPH_C32(0x53e6005d), + SPH_C32(0x1c508000), SPH_C32(0xea880000), SPH_C32(0x1e6b0000), + SPH_C32(0x5bbd3117), SPH_C32(0x7f2533fe), SPH_C32(0x078b4d0a), + SPH_C32(0x6f395bd7) }, + { SPH_C32(0x04a400fd), SPH_C32(0xf6da4000), SPH_C32(0xae300000), + SPH_C32(0x63490000), SPH_C32(0x6c507359), SPH_C32(0x8aa527ae), + SPH_C32(0x08da66c2), SPH_C32(0xdd7cf848), SPH_C32(0xf599005c), + SPH_C32(0x6d670000), SPH_C32(0xf3740000), SPH_C32(0x88b00000), + SPH_C32(0x61365cea), SPH_C32(0x94ef9d0d), SPH_C32(0x2be60a85), + SPH_C32(0xc3b7375f) }, + { SPH_C32(0xf46c0050), SPH_C32(0x96180000), SPH_C32(0x14a50000), + SPH_C32(0x031f0000), SPH_C32(0x42947eb8), SPH_C32(0x66bf7e19), + SPH_C32(0x9ca470d2), SPH_C32(0x8a341574), SPH_C32(0x832800a0), + SPH_C32(0x67420000), SPH_C32(0xe1170000), SPH_C32(0x370b0000), + SPH_C32(0xcba30034), SPH_C32(0x3c34923c), SPH_C32(0x9767bdcc), + SPH_C32(0x450360bf) }, + { SPH_C32(0x02ec0055), SPH_C32(0xa25bc000), SPH_C32(0x30a20000), + SPH_C32(0x8c220000), SPH_C32(0x63a34543), SPH_C32(0x6c07abb7), + SPH_C32(0x5161fbcb), SPH_C32(0x5da1af45), SPH_C32(0x255700a1), + SPH_C32(0x16758000), SPH_C32(0xf8eb0000), SPH_C32(0xa1d00000), + SPH_C32(0xf1286dc9), SPH_C32(0xd7fe3ccf), SPH_C32(0xbb0afa43), + SPH_C32(0xe98d0c37) }, + { SPH_C32(0x52130051), SPH_C32(0xe72f8000), SPH_C32(0x0d590000), + SPH_C32(0x95c40000), SPH_C32(0x781f1345), SPH_C32(0x8d75d0ea), + SPH_C32(0xb0c9375d), SPH_C32(0x26ba79fc), SPH_C32(0xd3d700a4), + SPH_C32(0x22364000), SPH_C32(0xdcec0000), SPH_C32(0x2eed0000), + SPH_C32(0xd01f5632), SPH_C32(0xdd46e961), SPH_C32(0x76cf715a), + SPH_C32(0x3e18b606) }, + { SPH_C32(0xa4930054), SPH_C32(0xd36c4000), SPH_C32(0x295e0000), + SPH_C32(0x1af90000), SPH_C32(0x592828be), SPH_C32(0x87cd0544), + SPH_C32(0x7d0cbc44), SPH_C32(0xf12fc3cd), SPH_C32(0x75a800a5), + SPH_C32(0x5301c000), SPH_C32(0xc5100000), SPH_C32(0xb8360000), + SPH_C32(0xea943bcf), SPH_C32(0x368c4792), SPH_C32(0x5aa236d5), + SPH_C32(0x9296da8e) }, + { SPH_C32(0x03190059), SPH_C32(0x5924c000), SPH_C32(0xd7730000), + SPH_C32(0x078d0000), SPH_C32(0x40016711), SPH_C32(0x9e5748a3), + SPH_C32(0xe623819c), SPH_C32(0x14228d6e), SPH_C32(0x574200a0), + SPH_C32(0xea8ac000), SPH_C32(0x44b80000), SPH_C32(0x7d220000), + SPH_C32(0x37ed424e), SPH_C32(0xf5801450), SPH_C32(0x0f512bc8), + SPH_C32(0xb245a39f) }, + { SPH_C32(0xf599005c), SPH_C32(0x6d670000), SPH_C32(0xf3740000), + SPH_C32(0x88b00000), SPH_C32(0x61365cea), SPH_C32(0x94ef9d0d), + SPH_C32(0x2be60a85), SPH_C32(0xc3b7375f), SPH_C32(0xf13d00a1), + SPH_C32(0x9bbd4000), SPH_C32(0x5d440000), SPH_C32(0xebf90000), + SPH_C32(0x0d662fb3), SPH_C32(0x1e4abaa3), SPH_C32(0x233c6c47), + SPH_C32(0x1ecbcf17) }, + { SPH_C32(0xa5660058), SPH_C32(0x28134000), SPH_C32(0xce8f0000), + SPH_C32(0x91560000), SPH_C32(0x7a8a0aec), SPH_C32(0x759de650), + SPH_C32(0xca4ec613), SPH_C32(0xb8ace1e6), SPH_C32(0x07bd00a4), + SPH_C32(0xaffe8000), SPH_C32(0x79430000), SPH_C32(0x64c40000), + SPH_C32(0x2c511448), SPH_C32(0x14f26f0d), SPH_C32(0xeef9e75e), + SPH_C32(0xc95e7526) }, + { SPH_C32(0x53e6005d), SPH_C32(0x1c508000), SPH_C32(0xea880000), + SPH_C32(0x1e6b0000), SPH_C32(0x5bbd3117), SPH_C32(0x7f2533fe), + SPH_C32(0x078b4d0a), SPH_C32(0x6f395bd7), SPH_C32(0xa1c200a5), + SPH_C32(0xdec90000), SPH_C32(0x60bf0000), SPH_C32(0xf21f0000), + SPH_C32(0x16da79b5), SPH_C32(0xff38c1fe), SPH_C32(0xc294a0d1), + SPH_C32(0x65d019ae) }, + { SPH_C32(0x20060050), SPH_C32(0x1bd0c000), SPH_C32(0xb10a0000), + SPH_C32(0x49360000), SPH_C32(0xbeda3cc2), SPH_C32(0xaf0bf875), + SPH_C32(0x0492e6d6), SPH_C32(0x7d72d654), SPH_C32(0xa03700a9), + SPH_C32(0x25b60000), SPH_C32(0x876e0000), SPH_C32(0x79b00000), + SPH_C32(0x35785be7), SPH_C32(0x0d6822ea), SPH_C32(0x75d6da86), + SPH_C32(0x2c533b85) }, + { SPH_C32(0xd6860055), SPH_C32(0x2f930000), SPH_C32(0x950d0000), + SPH_C32(0xc60b0000), SPH_C32(0x9fed0739), SPH_C32(0xa5b32ddb), + SPH_C32(0xc9576dcf), SPH_C32(0xaae76c65), SPH_C32(0x064800a8), + SPH_C32(0x54818000), SPH_C32(0x9e920000), SPH_C32(0xef6b0000), + SPH_C32(0x0ff3361a), SPH_C32(0xe6a28c19), SPH_C32(0x59bb9d09), + SPH_C32(0x80dd570d) }, + { SPH_C32(0x86790051), SPH_C32(0x6ae74000), SPH_C32(0xa8f60000), + SPH_C32(0xdfed0000), SPH_C32(0x8451513f), SPH_C32(0x44c15686), + SPH_C32(0x28ffa159), SPH_C32(0xd1fcbadc), SPH_C32(0xf0c800ad), + SPH_C32(0x60c24000), SPH_C32(0xba950000), SPH_C32(0x60560000), + SPH_C32(0x2ec40de1), SPH_C32(0xec1a59b7), SPH_C32(0x947e1610), + SPH_C32(0x5748ed3c) }, + { SPH_C32(0x70f90054), SPH_C32(0x5ea48000), SPH_C32(0x8cf10000), + SPH_C32(0x50d00000), SPH_C32(0xa5666ac4), SPH_C32(0x4e798328), + SPH_C32(0xe53a2a40), SPH_C32(0x066900ed), SPH_C32(0x56b700ac), + SPH_C32(0x11f5c000), SPH_C32(0xa3690000), SPH_C32(0xf68d0000), + SPH_C32(0x144f601c), SPH_C32(0x07d0f744), SPH_C32(0xb813519f), + SPH_C32(0xfbc681b4) }, + { SPH_C32(0xd7730059), SPH_C32(0xd4ec0000), SPH_C32(0x72dc0000), + SPH_C32(0x4da40000), SPH_C32(0xbc4f256b), SPH_C32(0x57e3cecf), + SPH_C32(0x7e151798), SPH_C32(0xe3644e4e), SPH_C32(0x745d00a9), + SPH_C32(0xa87ec000), SPH_C32(0x22c10000), SPH_C32(0x33990000), + SPH_C32(0xc936199d), SPH_C32(0xc4dca486), SPH_C32(0xede04c82), + SPH_C32(0xdb15f8a5) }, + { SPH_C32(0x21f3005c), SPH_C32(0xe0afc000), SPH_C32(0x56db0000), + SPH_C32(0xc2990000), SPH_C32(0x9d781e90), SPH_C32(0x5d5b1b61), + SPH_C32(0xb3d09c81), SPH_C32(0x34f1f47f), SPH_C32(0xd22200a8), + SPH_C32(0xd9494000), SPH_C32(0x3b3d0000), SPH_C32(0xa5420000), + SPH_C32(0xf3bd7460), SPH_C32(0x2f160a75), SPH_C32(0xc18d0b0d), + SPH_C32(0x779b942d) }, + { SPH_C32(0x710c0058), SPH_C32(0xa5db8000), SPH_C32(0x6b200000), + SPH_C32(0xdb7f0000), SPH_C32(0x86c44896), SPH_C32(0xbc29603c), + SPH_C32(0x52785017), SPH_C32(0x4fea22c6), SPH_C32(0x24a200ad), + SPH_C32(0xed0a8000), SPH_C32(0x1f3a0000), SPH_C32(0x2a7f0000), + SPH_C32(0xd28a4f9b), SPH_C32(0x25aedfdb), SPH_C32(0x0c488014), + SPH_C32(0xa00e2e1c) }, + { SPH_C32(0x878c005d), SPH_C32(0x91984000), SPH_C32(0x4f270000), + SPH_C32(0x54420000), SPH_C32(0xa7f3736d), SPH_C32(0xb691b592), + SPH_C32(0x9fbddb0e), SPH_C32(0x987f98f7), SPH_C32(0x82dd00ac), + SPH_C32(0x9c3d0000), SPH_C32(0x06c60000), SPH_C32(0xbca40000), + SPH_C32(0xe8012266), SPH_C32(0xce647128), SPH_C32(0x2025c79b), + SPH_C32(0x0c804294) }, + { SPH_C32(0x832800a0), SPH_C32(0x67420000), SPH_C32(0xe1170000), + SPH_C32(0x370b0000), SPH_C32(0xcba30034), SPH_C32(0x3c34923c), + SPH_C32(0x9767bdcc), SPH_C32(0x450360bf), SPH_C32(0x774400f0), + SPH_C32(0xf15a0000), SPH_C32(0xf5b20000), SPH_C32(0x34140000), + SPH_C32(0x89377e8c), SPH_C32(0x5a8bec25), SPH_C32(0x0bc3cd1e), + SPH_C32(0xcf3775cb) }, + { SPH_C32(0x75a800a5), SPH_C32(0x5301c000), SPH_C32(0xc5100000), + SPH_C32(0xb8360000), SPH_C32(0xea943bcf), SPH_C32(0x368c4792), + SPH_C32(0x5aa236d5), SPH_C32(0x9296da8e), SPH_C32(0xd13b00f1), + SPH_C32(0x806d8000), SPH_C32(0xec4e0000), SPH_C32(0xa2cf0000), + SPH_C32(0xb3bc1371), SPH_C32(0xb14142d6), SPH_C32(0x27ae8a91), + SPH_C32(0x63b91943) }, + { SPH_C32(0x255700a1), SPH_C32(0x16758000), SPH_C32(0xf8eb0000), + SPH_C32(0xa1d00000), SPH_C32(0xf1286dc9), SPH_C32(0xd7fe3ccf), + SPH_C32(0xbb0afa43), SPH_C32(0xe98d0c37), SPH_C32(0x27bb00f4), + SPH_C32(0xb42e4000), SPH_C32(0xc8490000), SPH_C32(0x2df20000), + SPH_C32(0x928b288a), SPH_C32(0xbbf99778), SPH_C32(0xea6b0188), + SPH_C32(0xb42ca372) }, + { SPH_C32(0xd3d700a4), SPH_C32(0x22364000), SPH_C32(0xdcec0000), + SPH_C32(0x2eed0000), SPH_C32(0xd01f5632), SPH_C32(0xdd46e961), + SPH_C32(0x76cf715a), SPH_C32(0x3e18b606), SPH_C32(0x81c400f5), + SPH_C32(0xc519c000), SPH_C32(0xd1b50000), SPH_C32(0xbb290000), + SPH_C32(0xa8004577), SPH_C32(0x5033398b), SPH_C32(0xc6064607), + SPH_C32(0x18a2cffa) }, + { SPH_C32(0x745d00a9), SPH_C32(0xa87ec000), SPH_C32(0x22c10000), + SPH_C32(0x33990000), SPH_C32(0xc936199d), SPH_C32(0xc4dca486), + SPH_C32(0xede04c82), SPH_C32(0xdb15f8a5), SPH_C32(0xa32e00f0), + SPH_C32(0x7c92c000), SPH_C32(0x501d0000), SPH_C32(0x7e3d0000), + SPH_C32(0x75793cf6), SPH_C32(0x933f6a49), SPH_C32(0x93f55b1a), + SPH_C32(0x3871b6eb) }, + { SPH_C32(0x82dd00ac), SPH_C32(0x9c3d0000), SPH_C32(0x06c60000), + SPH_C32(0xbca40000), SPH_C32(0xe8012266), SPH_C32(0xce647128), + SPH_C32(0x2025c79b), SPH_C32(0x0c804294), SPH_C32(0x055100f1), + SPH_C32(0x0da54000), SPH_C32(0x49e10000), SPH_C32(0xe8e60000), + SPH_C32(0x4ff2510b), SPH_C32(0x78f5c4ba), SPH_C32(0xbf981c95), + SPH_C32(0x94ffda63) }, + { SPH_C32(0xd22200a8), SPH_C32(0xd9494000), SPH_C32(0x3b3d0000), + SPH_C32(0xa5420000), SPH_C32(0xf3bd7460), SPH_C32(0x2f160a75), + SPH_C32(0xc18d0b0d), SPH_C32(0x779b942d), SPH_C32(0xf3d100f4), + SPH_C32(0x39e68000), SPH_C32(0x6de60000), SPH_C32(0x67db0000), + SPH_C32(0x6ec56af0), SPH_C32(0x724d1114), SPH_C32(0x725d978c), + SPH_C32(0x436a6052) }, + { SPH_C32(0x24a200ad), SPH_C32(0xed0a8000), SPH_C32(0x1f3a0000), + SPH_C32(0x2a7f0000), SPH_C32(0xd28a4f9b), SPH_C32(0x25aedfdb), + SPH_C32(0x0c488014), SPH_C32(0xa00e2e1c), SPH_C32(0x55ae00f5), + SPH_C32(0x48d10000), SPH_C32(0x741a0000), SPH_C32(0xf1000000), + SPH_C32(0x544e070d), SPH_C32(0x9987bfe7), SPH_C32(0x5e30d003), + SPH_C32(0xefe40cda) }, + { SPH_C32(0x574200a0), SPH_C32(0xea8ac000), SPH_C32(0x44b80000), + SPH_C32(0x7d220000), SPH_C32(0x37ed424e), SPH_C32(0xf5801450), + SPH_C32(0x0f512bc8), SPH_C32(0xb245a39f), SPH_C32(0x545b00f9), + SPH_C32(0xb3ae0000), SPH_C32(0x93cb0000), SPH_C32(0x7aaf0000), + SPH_C32(0x77ec255f), SPH_C32(0x6bd75cf3), SPH_C32(0xe972aa54), + SPH_C32(0xa6672ef1) }, + { SPH_C32(0xa1c200a5), SPH_C32(0xdec90000), SPH_C32(0x60bf0000), + SPH_C32(0xf21f0000), SPH_C32(0x16da79b5), SPH_C32(0xff38c1fe), + SPH_C32(0xc294a0d1), SPH_C32(0x65d019ae), SPH_C32(0xf22400f8), + SPH_C32(0xc2998000), SPH_C32(0x8a370000), SPH_C32(0xec740000), + SPH_C32(0x4d6748a2), SPH_C32(0x801df200), SPH_C32(0xc51feddb), + SPH_C32(0x0ae94279) }, + { SPH_C32(0xf13d00a1), SPH_C32(0x9bbd4000), SPH_C32(0x5d440000), + SPH_C32(0xebf90000), SPH_C32(0x0d662fb3), SPH_C32(0x1e4abaa3), + SPH_C32(0x233c6c47), SPH_C32(0x1ecbcf17), SPH_C32(0x04a400fd), + SPH_C32(0xf6da4000), SPH_C32(0xae300000), SPH_C32(0x63490000), + SPH_C32(0x6c507359), SPH_C32(0x8aa527ae), SPH_C32(0x08da66c2), + SPH_C32(0xdd7cf848) }, + { SPH_C32(0x07bd00a4), SPH_C32(0xaffe8000), SPH_C32(0x79430000), + SPH_C32(0x64c40000), SPH_C32(0x2c511448), SPH_C32(0x14f26f0d), + SPH_C32(0xeef9e75e), SPH_C32(0xc95e7526), SPH_C32(0xa2db00fc), + SPH_C32(0x87edc000), SPH_C32(0xb7cc0000), SPH_C32(0xf5920000), + SPH_C32(0x56db1ea4), SPH_C32(0x616f895d), SPH_C32(0x24b7214d), + SPH_C32(0x71f294c0) }, + { SPH_C32(0xa03700a9), SPH_C32(0x25b60000), SPH_C32(0x876e0000), + SPH_C32(0x79b00000), SPH_C32(0x35785be7), SPH_C32(0x0d6822ea), + SPH_C32(0x75d6da86), SPH_C32(0x2c533b85), SPH_C32(0x803100f9), + SPH_C32(0x3e66c000), SPH_C32(0x36640000), SPH_C32(0x30860000), + SPH_C32(0x8ba26725), SPH_C32(0xa263da9f), SPH_C32(0x71443c50), + SPH_C32(0x5121edd1) }, + { SPH_C32(0x56b700ac), SPH_C32(0x11f5c000), SPH_C32(0xa3690000), + SPH_C32(0xf68d0000), SPH_C32(0x144f601c), SPH_C32(0x07d0f744), + SPH_C32(0xb813519f), SPH_C32(0xfbc681b4), SPH_C32(0x264e00f8), + SPH_C32(0x4f514000), SPH_C32(0x2f980000), SPH_C32(0xa65d0000), + SPH_C32(0xb1290ad8), SPH_C32(0x49a9746c), SPH_C32(0x5d297bdf), + SPH_C32(0xfdaf8159) }, + { SPH_C32(0x064800a8), SPH_C32(0x54818000), SPH_C32(0x9e920000), + SPH_C32(0xef6b0000), SPH_C32(0x0ff3361a), SPH_C32(0xe6a28c19), + SPH_C32(0x59bb9d09), SPH_C32(0x80dd570d), SPH_C32(0xd0ce00fd), + SPH_C32(0x7b128000), SPH_C32(0x0b9f0000), SPH_C32(0x29600000), + SPH_C32(0x901e3123), SPH_C32(0x4311a1c2), SPH_C32(0x90ecf0c6), + SPH_C32(0x2a3a3b68) }, + { SPH_C32(0xf0c800ad), SPH_C32(0x60c24000), SPH_C32(0xba950000), + SPH_C32(0x60560000), SPH_C32(0x2ec40de1), SPH_C32(0xec1a59b7), + SPH_C32(0x947e1610), SPH_C32(0x5748ed3c), SPH_C32(0x76b100fc), + SPH_C32(0x0a250000), SPH_C32(0x12630000), SPH_C32(0xbfbb0000), + SPH_C32(0xaa955cde), SPH_C32(0xa8db0f31), SPH_C32(0xbc81b749), + SPH_C32(0x86b457e0) }, + { SPH_C32(0xe8870170), SPH_C32(0x9d720000), SPH_C32(0x12db0000), + SPH_C32(0xd4220000), SPH_C32(0xf2886b27), SPH_C32(0xa921e543), + SPH_C32(0x4ef8b518), SPH_C32(0x618813b1), SPH_C32(0xb4370060), + SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), SPH_C32(0x5cae0000), + SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), SPH_C32(0x1b365f3d), + SPH_C32(0xf3d45758) }, + { SPH_C32(0x1e070175), SPH_C32(0xa931c000), SPH_C32(0x36dc0000), + SPH_C32(0x5b1f0000), SPH_C32(0xd3bf50dc), SPH_C32(0xa39930ed), + SPH_C32(0x833d3e01), SPH_C32(0xb61da980), SPH_C32(0x12480061), + SPH_C32(0x7d7b8000), SPH_C32(0x4f3e0000), SPH_C32(0xca750000), + SPH_C32(0xaedf72c2), SPH_C32(0xd0f456d6), SPH_C32(0x375b18b2), + SPH_C32(0x5f5a3bd0) }, + { SPH_C32(0x4ef80171), SPH_C32(0xec458000), SPH_C32(0x0b270000), + SPH_C32(0x42f90000), SPH_C32(0xc80306da), SPH_C32(0x42eb4bb0), + SPH_C32(0x6295f297), SPH_C32(0xcd067f39), SPH_C32(0xe4c80064), + SPH_C32(0x49384000), SPH_C32(0x6b390000), SPH_C32(0x45480000), + SPH_C32(0x8fe84939), SPH_C32(0xda4c8378), SPH_C32(0xfa9e93ab), + SPH_C32(0x88cf81e1) }, + { SPH_C32(0xb8780174), SPH_C32(0xd8064000), SPH_C32(0x2f200000), + SPH_C32(0xcdc40000), SPH_C32(0xe9343d21), SPH_C32(0x48539e1e), + SPH_C32(0xaf50798e), SPH_C32(0x1a93c508), SPH_C32(0x42b70065), + SPH_C32(0x380fc000), SPH_C32(0x72c50000), SPH_C32(0xd3930000), + SPH_C32(0xb56324c4), SPH_C32(0x31862d8b), SPH_C32(0xd6f3d424), + SPH_C32(0x2441ed69) }, + { SPH_C32(0x1ff20179), SPH_C32(0x524ec000), SPH_C32(0xd10d0000), + SPH_C32(0xd0b00000), SPH_C32(0xf01d728e), SPH_C32(0x51c9d3f9), + SPH_C32(0x347f4456), SPH_C32(0xff9e8bab), SPH_C32(0x605d0060), + SPH_C32(0x8184c000), SPH_C32(0xf36d0000), SPH_C32(0x16870000), + SPH_C32(0x681a5d45), SPH_C32(0xf28a7e49), SPH_C32(0x8300c939), + SPH_C32(0x04929478) }, + { SPH_C32(0xe972017c), SPH_C32(0x660d0000), SPH_C32(0xf50a0000), + SPH_C32(0x5f8d0000), SPH_C32(0xd12a4975), SPH_C32(0x5b710657), + SPH_C32(0xf9bacf4f), SPH_C32(0x280b319a), SPH_C32(0xc6220061), + SPH_C32(0xf0b34000), SPH_C32(0xea910000), SPH_C32(0x805c0000), + SPH_C32(0x529130b8), SPH_C32(0x1940d0ba), SPH_C32(0xaf6d8eb6), + SPH_C32(0xa81cf8f0) }, + { SPH_C32(0xb98d0178), SPH_C32(0x23794000), SPH_C32(0xc8f10000), + SPH_C32(0x466b0000), SPH_C32(0xca961f73), SPH_C32(0xba037d0a), + SPH_C32(0x181203d9), SPH_C32(0x5310e723), SPH_C32(0x30a20064), + SPH_C32(0xc4f08000), SPH_C32(0xce960000), SPH_C32(0x0f610000), + SPH_C32(0x73a60b43), SPH_C32(0x13f80514), SPH_C32(0x62a805af), + SPH_C32(0x7f8942c1) }, + { SPH_C32(0x4f0d017d), SPH_C32(0x173a8000), SPH_C32(0xecf60000), + SPH_C32(0xc9560000), SPH_C32(0xeba12488), SPH_C32(0xb0bba8a4), + SPH_C32(0xd5d788c0), SPH_C32(0x84855d12), SPH_C32(0x96dd0065), + SPH_C32(0xb5c70000), SPH_C32(0xd76a0000), SPH_C32(0x99ba0000), + SPH_C32(0x492d66be), SPH_C32(0xf832abe7), SPH_C32(0x4ec54220), + SPH_C32(0xd3072e49) }, + { SPH_C32(0x3ced0170), SPH_C32(0x10bac000), SPH_C32(0xb7740000), + SPH_C32(0x9e0b0000), SPH_C32(0x0ec6295d), SPH_C32(0x6095632f), + SPH_C32(0xd6ce231c), SPH_C32(0x96ced091), SPH_C32(0x97280069), + SPH_C32(0x4eb80000), SPH_C32(0x30bb0000), SPH_C32(0x12150000), + SPH_C32(0x6a8f44ec), SPH_C32(0x0a6248f3), SPH_C32(0xf9873877), + SPH_C32(0x9a840c62) }, + { SPH_C32(0xca6d0175), SPH_C32(0x24f90000), SPH_C32(0x93730000), + SPH_C32(0x11360000), SPH_C32(0x2ff112a6), SPH_C32(0x6a2db681), + SPH_C32(0x1b0ba805), SPH_C32(0x415b6aa0), SPH_C32(0x31570068), + SPH_C32(0x3f8f8000), SPH_C32(0x29470000), SPH_C32(0x84ce0000), + SPH_C32(0x50042911), SPH_C32(0xe1a8e600), SPH_C32(0xd5ea7ff8), + SPH_C32(0x360a60ea) }, + { SPH_C32(0x9a920171), SPH_C32(0x618d4000), SPH_C32(0xae880000), + SPH_C32(0x08d00000), SPH_C32(0x344d44a0), SPH_C32(0x8b5fcddc), + SPH_C32(0xfaa36493), SPH_C32(0x3a40bc19), SPH_C32(0xc7d7006d), + SPH_C32(0x0bcc4000), SPH_C32(0x0d400000), SPH_C32(0x0bf30000), + SPH_C32(0x713312ea), SPH_C32(0xeb1033ae), SPH_C32(0x182ff4e1), + SPH_C32(0xe19fdadb) }, + { SPH_C32(0x6c120174), SPH_C32(0x55ce8000), SPH_C32(0x8a8f0000), + SPH_C32(0x87ed0000), SPH_C32(0x157a7f5b), SPH_C32(0x81e71872), + SPH_C32(0x3766ef8a), SPH_C32(0xedd50628), SPH_C32(0x61a8006c), + SPH_C32(0x7afbc000), SPH_C32(0x14bc0000), SPH_C32(0x9d280000), + SPH_C32(0x4bb87f17), SPH_C32(0x00da9d5d), SPH_C32(0x3442b36e), + SPH_C32(0x4d11b653) }, + { SPH_C32(0xcb980179), SPH_C32(0xdf860000), SPH_C32(0x74a20000), + SPH_C32(0x9a990000), SPH_C32(0x0c5330f4), SPH_C32(0x987d5595), + SPH_C32(0xac49d252), SPH_C32(0x08d8488b), SPH_C32(0x43420069), + SPH_C32(0xc370c000), SPH_C32(0x95140000), SPH_C32(0x583c0000), + SPH_C32(0x96c10696), SPH_C32(0xc3d6ce9f), SPH_C32(0x61b1ae73), + SPH_C32(0x6dc2cf42) }, + { SPH_C32(0x3d18017c), SPH_C32(0xebc5c000), SPH_C32(0x50a50000), + SPH_C32(0x15a40000), SPH_C32(0x2d640b0f), SPH_C32(0x92c5803b), + SPH_C32(0x618c594b), SPH_C32(0xdf4df2ba), SPH_C32(0xe53d0068), + SPH_C32(0xb2474000), SPH_C32(0x8ce80000), SPH_C32(0xcee70000), + SPH_C32(0xac4a6b6b), SPH_C32(0x281c606c), SPH_C32(0x4ddce9fc), + SPH_C32(0xc14ca3ca) }, + { SPH_C32(0x6de70178), SPH_C32(0xaeb18000), SPH_C32(0x6d5e0000), + SPH_C32(0x0c420000), SPH_C32(0x36d85d09), SPH_C32(0x73b7fb66), + SPH_C32(0x802495dd), SPH_C32(0xa4562403), SPH_C32(0x13bd006d), + SPH_C32(0x86048000), SPH_C32(0xa8ef0000), SPH_C32(0x41da0000), + SPH_C32(0x8d7d5090), SPH_C32(0x22a4b5c2), SPH_C32(0x801962e5), + SPH_C32(0x16d919fb) }, + { SPH_C32(0x9b67017d), SPH_C32(0x9af24000), SPH_C32(0x49590000), + SPH_C32(0x837f0000), SPH_C32(0x17ef66f2), SPH_C32(0x790f2ec8), + SPH_C32(0x4de11ec4), SPH_C32(0x73c39e32), SPH_C32(0xb5c2006c), + SPH_C32(0xf7330000), SPH_C32(0xb1130000), SPH_C32(0xd7010000), + SPH_C32(0xb7f63d6d), SPH_C32(0xc96e1b31), SPH_C32(0xac74256a), + SPH_C32(0xba577573) }, + { SPH_C32(0x9fc30180), SPH_C32(0x6c280000), SPH_C32(0xe7690000), + SPH_C32(0xe0360000), SPH_C32(0x7bbf15ab), SPH_C32(0xf3aa0966), + SPH_C32(0x453b7806), SPH_C32(0xaebf667a), SPH_C32(0x405b0030), + SPH_C32(0x9a540000), SPH_C32(0x42670000), SPH_C32(0x5fb10000), + SPH_C32(0xd6c06187), SPH_C32(0x5d81863c), SPH_C32(0x87922fef), + SPH_C32(0x79e0422c) }, + { SPH_C32(0x69430185), SPH_C32(0x586bc000), SPH_C32(0xc36e0000), + SPH_C32(0x6f0b0000), SPH_C32(0x5a882e50), SPH_C32(0xf912dcc8), + SPH_C32(0x88fef31f), SPH_C32(0x792adc4b), SPH_C32(0xe6240031), + SPH_C32(0xeb638000), SPH_C32(0x5b9b0000), SPH_C32(0xc96a0000), + SPH_C32(0xec4b0c7a), SPH_C32(0xb64b28cf), SPH_C32(0xabff6860), + SPH_C32(0xd56e2ea4) }, + { SPH_C32(0x39bc0181), SPH_C32(0x1d1f8000), SPH_C32(0xfe950000), + SPH_C32(0x76ed0000), SPH_C32(0x41347856), SPH_C32(0x1860a795), + SPH_C32(0x69563f89), SPH_C32(0x02310af2), SPH_C32(0x10a40034), + SPH_C32(0xdf204000), SPH_C32(0x7f9c0000), SPH_C32(0x46570000), + SPH_C32(0xcd7c3781), SPH_C32(0xbcf3fd61), SPH_C32(0x663ae379), + SPH_C32(0x02fb9495) }, + { SPH_C32(0xcf3c0184), SPH_C32(0x295c4000), SPH_C32(0xda920000), + SPH_C32(0xf9d00000), SPH_C32(0x600343ad), SPH_C32(0x12d8723b), + SPH_C32(0xa493b490), SPH_C32(0xd5a4b0c3), SPH_C32(0xb6db0035), + SPH_C32(0xae17c000), SPH_C32(0x66600000), SPH_C32(0xd08c0000), + SPH_C32(0xf7f75a7c), SPH_C32(0x57395392), SPH_C32(0x4a57a4f6), + SPH_C32(0xae75f81d) }, + { SPH_C32(0x68b60189), SPH_C32(0xa314c000), SPH_C32(0x24bf0000), + SPH_C32(0xe4a40000), SPH_C32(0x792a0c02), SPH_C32(0x0b423fdc), + SPH_C32(0x3fbc8948), SPH_C32(0x30a9fe60), SPH_C32(0x94310030), + SPH_C32(0x179cc000), SPH_C32(0xe7c80000), SPH_C32(0x15980000), + SPH_C32(0x2a8e23fd), SPH_C32(0x94350050), SPH_C32(0x1fa4b9eb), + SPH_C32(0x8ea6810c) }, + { SPH_C32(0x9e36018c), SPH_C32(0x97570000), SPH_C32(0x00b80000), + SPH_C32(0x6b990000), SPH_C32(0x581d37f9), SPH_C32(0x01faea72), + SPH_C32(0xf2790251), SPH_C32(0xe73c4451), SPH_C32(0x324e0031), + SPH_C32(0x66ab4000), SPH_C32(0xfe340000), SPH_C32(0x83430000), + SPH_C32(0x10054e00), SPH_C32(0x7fffaea3), SPH_C32(0x33c9fe64), + SPH_C32(0x2228ed84) }, + { SPH_C32(0xcec90188), SPH_C32(0xd2234000), SPH_C32(0x3d430000), + SPH_C32(0x727f0000), SPH_C32(0x43a161ff), SPH_C32(0xe088912f), + SPH_C32(0x13d1cec7), SPH_C32(0x9c2792e8), SPH_C32(0xc4ce0034), + SPH_C32(0x52e88000), SPH_C32(0xda330000), SPH_C32(0x0c7e0000), + SPH_C32(0x313275fb), SPH_C32(0x75477b0d), SPH_C32(0xfe0c757d), + SPH_C32(0xf5bd57b5) }, + { SPH_C32(0x3849018d), SPH_C32(0xe6608000), SPH_C32(0x19440000), + SPH_C32(0xfd420000), SPH_C32(0x62965a04), SPH_C32(0xea304481), + SPH_C32(0xde1445de), SPH_C32(0x4bb228d9), SPH_C32(0x62b10035), + SPH_C32(0x23df0000), SPH_C32(0xc3cf0000), SPH_C32(0x9aa50000), + SPH_C32(0x0bb91806), SPH_C32(0x9e8dd5fe), SPH_C32(0xd26132f2), + SPH_C32(0x59333b3d) }, + { SPH_C32(0x4ba90180), SPH_C32(0xe1e0c000), SPH_C32(0x42c60000), + SPH_C32(0xaa1f0000), SPH_C32(0x87f157d1), SPH_C32(0x3a1e8f0a), + SPH_C32(0xdd0dee02), SPH_C32(0x59f9a55a), SPH_C32(0x63440039), + SPH_C32(0xd8a00000), SPH_C32(0x241e0000), SPH_C32(0x110a0000), + SPH_C32(0x281b3a54), SPH_C32(0x6cdd36ea), SPH_C32(0x652348a5), + SPH_C32(0x10b01916) }, + { SPH_C32(0xbd290185), SPH_C32(0xd5a30000), SPH_C32(0x66c10000), + SPH_C32(0x25220000), SPH_C32(0xa6c66c2a), SPH_C32(0x30a65aa4), + SPH_C32(0x10c8651b), SPH_C32(0x8e6c1f6b), SPH_C32(0xc53b0038), + SPH_C32(0xa9978000), SPH_C32(0x3de20000), SPH_C32(0x87d10000), + SPH_C32(0x129057a9), SPH_C32(0x87179819), SPH_C32(0x494e0f2a), + SPH_C32(0xbc3e759e) }, + { SPH_C32(0xedd60181), SPH_C32(0x90d74000), SPH_C32(0x5b3a0000), + SPH_C32(0x3cc40000), SPH_C32(0xbd7a3a2c), SPH_C32(0xd1d421f9), + SPH_C32(0xf160a98d), SPH_C32(0xf577c9d2), SPH_C32(0x33bb003d), + SPH_C32(0x9dd44000), SPH_C32(0x19e50000), SPH_C32(0x08ec0000), + SPH_C32(0x33a76c52), SPH_C32(0x8daf4db7), SPH_C32(0x848b8433), + SPH_C32(0x6babcfaf) }, + { SPH_C32(0x1b560184), SPH_C32(0xa4948000), SPH_C32(0x7f3d0000), + SPH_C32(0xb3f90000), SPH_C32(0x9c4d01d7), SPH_C32(0xdb6cf457), + SPH_C32(0x3ca52294), SPH_C32(0x22e273e3), SPH_C32(0x95c4003c), + SPH_C32(0xece3c000), SPH_C32(0x00190000), SPH_C32(0x9e370000), + SPH_C32(0x092c01af), SPH_C32(0x6665e344), SPH_C32(0xa8e6c3bc), + SPH_C32(0xc725a327) }, + { SPH_C32(0xbcdc0189), SPH_C32(0x2edc0000), SPH_C32(0x81100000), + SPH_C32(0xae8d0000), SPH_C32(0x85644e78), SPH_C32(0xc2f6b9b0), + SPH_C32(0xa78a1f4c), SPH_C32(0xc7ef3d40), SPH_C32(0xb72e0039), + SPH_C32(0x5568c000), SPH_C32(0x81b10000), SPH_C32(0x5b230000), + SPH_C32(0xd455782e), SPH_C32(0xa569b086), SPH_C32(0xfd15dea1), + SPH_C32(0xe7f6da36) }, + { SPH_C32(0x4a5c018c), SPH_C32(0x1a9fc000), SPH_C32(0xa5170000), + SPH_C32(0x21b00000), SPH_C32(0xa4537583), SPH_C32(0xc84e6c1e), + SPH_C32(0x6a4f9455), SPH_C32(0x107a8771), SPH_C32(0x11510038), + SPH_C32(0x245f4000), SPH_C32(0x984d0000), SPH_C32(0xcdf80000), + SPH_C32(0xeede15d3), SPH_C32(0x4ea31e75), SPH_C32(0xd178992e), + SPH_C32(0x4b78b6be) }, + { SPH_C32(0x1aa30188), SPH_C32(0x5feb8000), SPH_C32(0x98ec0000), + SPH_C32(0x38560000), SPH_C32(0xbfef2385), SPH_C32(0x293c1743), + SPH_C32(0x8be758c3), SPH_C32(0x6b6151c8), SPH_C32(0xe7d1003d), + SPH_C32(0x101c8000), SPH_C32(0xbc4a0000), SPH_C32(0x42c50000), + SPH_C32(0xcfe92e28), SPH_C32(0x441bcbdb), SPH_C32(0x1cbd1237), + SPH_C32(0x9ced0c8f) }, + { SPH_C32(0xec23018d), SPH_C32(0x6ba84000), SPH_C32(0xbceb0000), + SPH_C32(0xb76b0000), SPH_C32(0x9ed8187e), SPH_C32(0x2384c2ed), + SPH_C32(0x4622d3da), SPH_C32(0xbcf4ebf9), SPH_C32(0x41ae003c), + SPH_C32(0x612b0000), SPH_C32(0xa5b60000), SPH_C32(0xd41e0000), + SPH_C32(0xf56243d5), SPH_C32(0xafd16528), SPH_C32(0x30d055b8), + SPH_C32(0x30636007) }, + { SPH_C32(0x1ceb0120), SPH_C32(0x0b6a0000), SPH_C32(0x067e0000), + SPH_C32(0xd73d0000), SPH_C32(0xb01c159f), SPH_C32(0xcf9e9b5a), + SPH_C32(0xd25cc5ca), SPH_C32(0xebbc06c5), SPH_C32(0x371f00c0), + SPH_C32(0x6b0e0000), SPH_C32(0xb7d50000), SPH_C32(0x6ba50000), + SPH_C32(0x5ff71f0b), SPH_C32(0x070a6a19), SPH_C32(0x8c51e2f1), + SPH_C32(0xb6d737e7) }, + { SPH_C32(0xea6b0125), SPH_C32(0x3f29c000), SPH_C32(0x22790000), + SPH_C32(0x58000000), SPH_C32(0x912b2e64), SPH_C32(0xc5264ef4), + SPH_C32(0x1f994ed3), SPH_C32(0x3c29bcf4), SPH_C32(0x916000c1), + SPH_C32(0x1a398000), SPH_C32(0xae290000), SPH_C32(0xfd7e0000), + SPH_C32(0x657c72f6), SPH_C32(0xecc0c4ea), SPH_C32(0xa03ca57e), + SPH_C32(0x1a595b6f) }, + { SPH_C32(0xba940121), SPH_C32(0x7a5d8000), SPH_C32(0x1f820000), + SPH_C32(0x41e60000), SPH_C32(0x8a977862), SPH_C32(0x245435a9), + SPH_C32(0xfe318245), SPH_C32(0x47326a4d), SPH_C32(0x67e000c4), + SPH_C32(0x2e7a4000), SPH_C32(0x8a2e0000), SPH_C32(0x72430000), + SPH_C32(0x444b490d), SPH_C32(0xe6781144), SPH_C32(0x6df92e67), + SPH_C32(0xcdcce15e) }, + { SPH_C32(0x4c140124), SPH_C32(0x4e1e4000), SPH_C32(0x3b850000), + SPH_C32(0xcedb0000), SPH_C32(0xaba04399), SPH_C32(0x2eece007), + SPH_C32(0x33f4095c), SPH_C32(0x90a7d07c), SPH_C32(0xc19f00c5), + SPH_C32(0x5f4dc000), SPH_C32(0x93d20000), SPH_C32(0xe4980000), + SPH_C32(0x7ec024f0), SPH_C32(0x0db2bfb7), SPH_C32(0x419469e8), + SPH_C32(0x61428dd6) }, + { SPH_C32(0xeb9e0129), SPH_C32(0xc456c000), SPH_C32(0xc5a80000), + SPH_C32(0xd3af0000), SPH_C32(0xb2890c36), SPH_C32(0x3776ade0), + SPH_C32(0xa8db3484), SPH_C32(0x75aa9edf), SPH_C32(0xe37500c0), + SPH_C32(0xe6c6c000), SPH_C32(0x127a0000), SPH_C32(0x218c0000), + SPH_C32(0xa3b95d71), SPH_C32(0xcebeec75), SPH_C32(0x146774f5), + SPH_C32(0x4191f4c7) }, + { SPH_C32(0x1d1e012c), SPH_C32(0xf0150000), SPH_C32(0xe1af0000), + SPH_C32(0x5c920000), SPH_C32(0x93be37cd), SPH_C32(0x3dce784e), + SPH_C32(0x651ebf9d), SPH_C32(0xa23f24ee), SPH_C32(0x450a00c1), + SPH_C32(0x97f14000), SPH_C32(0x0b860000), SPH_C32(0xb7570000), + SPH_C32(0x9932308c), SPH_C32(0x25744286), SPH_C32(0x380a337a), + SPH_C32(0xed1f984f) }, + { SPH_C32(0x4de10128), SPH_C32(0xb5614000), SPH_C32(0xdc540000), + SPH_C32(0x45740000), SPH_C32(0x880261cb), SPH_C32(0xdcbc0313), + SPH_C32(0x84b6730b), SPH_C32(0xd924f257), SPH_C32(0xb38a00c4), + SPH_C32(0xa3b28000), SPH_C32(0x2f810000), SPH_C32(0x386a0000), + SPH_C32(0xb8050b77), SPH_C32(0x2fcc9728), SPH_C32(0xf5cfb863), + SPH_C32(0x3a8a227e) }, + { SPH_C32(0xbb61012d), SPH_C32(0x81228000), SPH_C32(0xf8530000), + SPH_C32(0xca490000), SPH_C32(0xa9355a30), SPH_C32(0xd604d6bd), + SPH_C32(0x4973f812), SPH_C32(0x0eb14866), SPH_C32(0x15f500c5), + SPH_C32(0xd2850000), SPH_C32(0x367d0000), SPH_C32(0xaeb10000), + SPH_C32(0x828e668a), SPH_C32(0xc40639db), SPH_C32(0xd9a2ffec), + SPH_C32(0x96044ef6) }, + { SPH_C32(0xc8810120), SPH_C32(0x86a2c000), SPH_C32(0xa3d10000), + SPH_C32(0x9d140000), SPH_C32(0x4c5257e5), SPH_C32(0x062a1d36), + SPH_C32(0x4a6a53ce), SPH_C32(0x1cfac5e5), SPH_C32(0x140000c9), + SPH_C32(0x29fa0000), SPH_C32(0xd1ac0000), SPH_C32(0x251e0000), + SPH_C32(0xa12c44d8), SPH_C32(0x3656dacf), SPH_C32(0x6ee085bb), + SPH_C32(0xdf876cdd) }, + { SPH_C32(0x3e010125), SPH_C32(0xb2e10000), SPH_C32(0x87d60000), + SPH_C32(0x12290000), SPH_C32(0x6d656c1e), SPH_C32(0x0c92c898), + SPH_C32(0x87afd8d7), SPH_C32(0xcb6f7fd4), SPH_C32(0xb27f00c8), + SPH_C32(0x58cd8000), SPH_C32(0xc8500000), SPH_C32(0xb3c50000), + SPH_C32(0x9ba72925), SPH_C32(0xdd9c743c), SPH_C32(0x428dc234), + SPH_C32(0x73090055) }, + { SPH_C32(0x6efe0121), SPH_C32(0xf7954000), SPH_C32(0xba2d0000), + SPH_C32(0x0bcf0000), SPH_C32(0x76d93a18), SPH_C32(0xede0b3c5), + SPH_C32(0x66071441), SPH_C32(0xb074a96d), SPH_C32(0x44ff00cd), + SPH_C32(0x6c8e4000), SPH_C32(0xec570000), SPH_C32(0x3cf80000), + SPH_C32(0xba9012de), SPH_C32(0xd724a192), SPH_C32(0x8f48492d), + SPH_C32(0xa49cba64) }, + { SPH_C32(0x987e0124), SPH_C32(0xc3d68000), SPH_C32(0x9e2a0000), + SPH_C32(0x84f20000), SPH_C32(0x57ee01e3), SPH_C32(0xe758666b), + SPH_C32(0xabc29f58), SPH_C32(0x67e1135c), SPH_C32(0xe28000cc), + SPH_C32(0x1db9c000), SPH_C32(0xf5ab0000), SPH_C32(0xaa230000), + SPH_C32(0x801b7f23), SPH_C32(0x3cee0f61), SPH_C32(0xa3250ea2), + SPH_C32(0x0812d6ec) }, + { SPH_C32(0x3ff40129), SPH_C32(0x499e0000), SPH_C32(0x60070000), + SPH_C32(0x99860000), SPH_C32(0x4ec74e4c), SPH_C32(0xfec22b8c), + SPH_C32(0x30eda280), SPH_C32(0x82ec5dff), SPH_C32(0xc06a00c9), + SPH_C32(0xa432c000), SPH_C32(0x74030000), SPH_C32(0x6f370000), + SPH_C32(0x5d6206a2), SPH_C32(0xffe25ca3), SPH_C32(0xf6d613bf), + SPH_C32(0x28c1affd) }, + { SPH_C32(0xc974012c), SPH_C32(0x7dddc000), SPH_C32(0x44000000), + SPH_C32(0x16bb0000), SPH_C32(0x6ff075b7), SPH_C32(0xf47afe22), + SPH_C32(0xfd282999), SPH_C32(0x5579e7ce), SPH_C32(0x661500c8), + SPH_C32(0xd5054000), SPH_C32(0x6dff0000), SPH_C32(0xf9ec0000), + SPH_C32(0x67e96b5f), SPH_C32(0x1428f250), SPH_C32(0xdabb5430), + SPH_C32(0x844fc375) }, + { SPH_C32(0x998b0128), SPH_C32(0x38a98000), SPH_C32(0x79fb0000), + SPH_C32(0x0f5d0000), SPH_C32(0x744c23b1), SPH_C32(0x1508857f), + SPH_C32(0x1c80e50f), SPH_C32(0x2e623177), SPH_C32(0x909500cd), + SPH_C32(0xe1468000), SPH_C32(0x49f80000), SPH_C32(0x76d10000), + SPH_C32(0x46de50a4), SPH_C32(0x1e9027fe), SPH_C32(0x177edf29), + SPH_C32(0x53da7944) }, + { SPH_C32(0x6f0b012d), SPH_C32(0x0cea4000), SPH_C32(0x5dfc0000), + SPH_C32(0x80600000), SPH_C32(0x557b184a), SPH_C32(0x1fb050d1), + SPH_C32(0xd1456e16), SPH_C32(0xf9f78b46), SPH_C32(0x36ea00cc), + SPH_C32(0x90710000), SPH_C32(0x50040000), SPH_C32(0xe00a0000), + SPH_C32(0x7c553d59), SPH_C32(0xf55a890d), SPH_C32(0x3b1398a6), + SPH_C32(0xff5415cc) }, + { SPH_C32(0x6baf01d0), SPH_C32(0xfa300000), SPH_C32(0xf3cc0000), + SPH_C32(0xe3290000), SPH_C32(0x392b6b13), SPH_C32(0x9515777f), + SPH_C32(0xd99f08d4), SPH_C32(0x248b730e), SPH_C32(0xc3730090), + SPH_C32(0xfd160000), SPH_C32(0xa3700000), SPH_C32(0x68ba0000), + SPH_C32(0x1d6361b3), SPH_C32(0x61b51400), SPH_C32(0x10f59223), + SPH_C32(0x3ce32293) }, + { SPH_C32(0x9d2f01d5), SPH_C32(0xce73c000), SPH_C32(0xd7cb0000), + SPH_C32(0x6c140000), SPH_C32(0x181c50e8), SPH_C32(0x9fada2d1), + SPH_C32(0x145a83cd), SPH_C32(0xf31ec93f), SPH_C32(0x650c0091), + SPH_C32(0x8c218000), SPH_C32(0xba8c0000), SPH_C32(0xfe610000), + SPH_C32(0x27e80c4e), SPH_C32(0x8a7fbaf3), SPH_C32(0x3c98d5ac), + SPH_C32(0x906d4e1b) }, + { SPH_C32(0xcdd001d1), SPH_C32(0x8b078000), SPH_C32(0xea300000), + SPH_C32(0x75f20000), SPH_C32(0x03a006ee), SPH_C32(0x7edfd98c), + SPH_C32(0xf5f24f5b), SPH_C32(0x88051f86), SPH_C32(0x938c0094), + SPH_C32(0xb8624000), SPH_C32(0x9e8b0000), SPH_C32(0x715c0000), + SPH_C32(0x06df37b5), SPH_C32(0x80c76f5d), SPH_C32(0xf15d5eb5), + SPH_C32(0x47f8f42a) }, + { SPH_C32(0x3b5001d4), SPH_C32(0xbf444000), SPH_C32(0xce370000), + SPH_C32(0xfacf0000), SPH_C32(0x22973d15), SPH_C32(0x74670c22), + SPH_C32(0x3837c442), SPH_C32(0x5f90a5b7), SPH_C32(0x35f30095), + SPH_C32(0xc955c000), SPH_C32(0x87770000), SPH_C32(0xe7870000), + SPH_C32(0x3c545a48), SPH_C32(0x6b0dc1ae), SPH_C32(0xdd30193a), + SPH_C32(0xeb7698a2) }, + { SPH_C32(0x9cda01d9), SPH_C32(0x350cc000), SPH_C32(0x301a0000), + SPH_C32(0xe7bb0000), SPH_C32(0x3bbe72ba), SPH_C32(0x6dfd41c5), + SPH_C32(0xa318f99a), SPH_C32(0xba9deb14), SPH_C32(0x17190090), + SPH_C32(0x70dec000), SPH_C32(0x06df0000), SPH_C32(0x22930000), + SPH_C32(0xe12d23c9), SPH_C32(0xa801926c), SPH_C32(0x88c30427), + SPH_C32(0xcba5e1b3) }, + { SPH_C32(0x6a5a01dc), SPH_C32(0x014f0000), SPH_C32(0x141d0000), + SPH_C32(0x68860000), SPH_C32(0x1a894941), SPH_C32(0x6745946b), + SPH_C32(0x6edd7283), SPH_C32(0x6d085125), SPH_C32(0xb1660091), + SPH_C32(0x01e94000), SPH_C32(0x1f230000), SPH_C32(0xb4480000), + SPH_C32(0xdba64e34), SPH_C32(0x43cb3c9f), SPH_C32(0xa4ae43a8), + SPH_C32(0x672b8d3b) }, + { SPH_C32(0x3aa501d8), SPH_C32(0x443b4000), SPH_C32(0x29e60000), + SPH_C32(0x71600000), SPH_C32(0x01351f47), SPH_C32(0x8637ef36), + SPH_C32(0x8f75be15), SPH_C32(0x1613879c), SPH_C32(0x47e60094), + SPH_C32(0x35aa8000), SPH_C32(0x3b240000), SPH_C32(0x3b750000), + SPH_C32(0xfa9175cf), SPH_C32(0x4973e931), SPH_C32(0x696bc8b1), + SPH_C32(0xb0be370a) }, + { SPH_C32(0xcc2501dd), SPH_C32(0x70788000), SPH_C32(0x0de10000), + SPH_C32(0xfe5d0000), SPH_C32(0x200224bc), SPH_C32(0x8c8f3a98), + SPH_C32(0x42b0350c), SPH_C32(0xc1863dad), SPH_C32(0xe1990095), + SPH_C32(0x449d0000), SPH_C32(0x22d80000), SPH_C32(0xadae0000), + SPH_C32(0xc01a1832), SPH_C32(0xa2b947c2), SPH_C32(0x45068f3e), + SPH_C32(0x1c305b82) }, + { SPH_C32(0xbfc501d0), SPH_C32(0x77f8c000), SPH_C32(0x56630000), + SPH_C32(0xa9000000), SPH_C32(0xc5652969), SPH_C32(0x5ca1f113), + SPH_C32(0x41a99ed0), SPH_C32(0xd3cdb02e), SPH_C32(0xe06c0099), + SPH_C32(0xbfe20000), SPH_C32(0xc5090000), SPH_C32(0x26010000), + SPH_C32(0xe3b83a60), SPH_C32(0x50e9a4d6), SPH_C32(0xf244f569), + SPH_C32(0x55b379a9) }, + { SPH_C32(0x494501d5), SPH_C32(0x43bb0000), SPH_C32(0x72640000), + SPH_C32(0x263d0000), SPH_C32(0xe4521292), SPH_C32(0x561924bd), + SPH_C32(0x8c6c15c9), SPH_C32(0x04580a1f), SPH_C32(0x46130098), + SPH_C32(0xced58000), SPH_C32(0xdcf50000), SPH_C32(0xb0da0000), + SPH_C32(0xd933579d), SPH_C32(0xbb230a25), SPH_C32(0xde29b2e6), + SPH_C32(0xf93d1521) }, + { SPH_C32(0x19ba01d1), SPH_C32(0x06cf4000), SPH_C32(0x4f9f0000), + SPH_C32(0x3fdb0000), SPH_C32(0xffee4494), SPH_C32(0xb76b5fe0), + SPH_C32(0x6dc4d95f), SPH_C32(0x7f43dca6), SPH_C32(0xb093009d), + SPH_C32(0xfa964000), SPH_C32(0xf8f20000), SPH_C32(0x3fe70000), + SPH_C32(0xf8046c66), SPH_C32(0xb19bdf8b), SPH_C32(0x13ec39ff), + SPH_C32(0x2ea8af10) }, + { SPH_C32(0xef3a01d4), SPH_C32(0x328c8000), SPH_C32(0x6b980000), + SPH_C32(0xb0e60000), SPH_C32(0xded97f6f), SPH_C32(0xbdd38a4e), + SPH_C32(0xa0015246), SPH_C32(0xa8d66697), SPH_C32(0x16ec009c), + SPH_C32(0x8ba1c000), SPH_C32(0xe10e0000), SPH_C32(0xa93c0000), + SPH_C32(0xc28f019b), SPH_C32(0x5a517178), SPH_C32(0x3f817e70), + SPH_C32(0x8226c398) }, + { SPH_C32(0x48b001d9), SPH_C32(0xb8c40000), SPH_C32(0x95b50000), + SPH_C32(0xad920000), SPH_C32(0xc7f030c0), SPH_C32(0xa449c7a9), + SPH_C32(0x3b2e6f9e), SPH_C32(0x4ddb2834), SPH_C32(0x34060099), + SPH_C32(0x322ac000), SPH_C32(0x60a60000), SPH_C32(0x6c280000), + SPH_C32(0x1ff6781a), SPH_C32(0x995d22ba), SPH_C32(0x6a72636d), + SPH_C32(0xa2f5ba89) }, + { SPH_C32(0xbe3001dc), SPH_C32(0x8c87c000), SPH_C32(0xb1b20000), + SPH_C32(0x22af0000), SPH_C32(0xe6c70b3b), SPH_C32(0xaef11207), + SPH_C32(0xf6ebe487), SPH_C32(0x9a4e9205), SPH_C32(0x92790098), + SPH_C32(0x431d4000), SPH_C32(0x795a0000), SPH_C32(0xfaf30000), + SPH_C32(0x257d15e7), SPH_C32(0x72978c49), SPH_C32(0x461f24e2), + SPH_C32(0x0e7bd601) }, + { SPH_C32(0xeecf01d8), SPH_C32(0xc9f38000), SPH_C32(0x8c490000), + SPH_C32(0x3b490000), SPH_C32(0xfd7b5d3d), SPH_C32(0x4f83695a), + SPH_C32(0x17432811), SPH_C32(0xe15544bc), SPH_C32(0x64f9009d), + SPH_C32(0x775e8000), SPH_C32(0x5d5d0000), SPH_C32(0x75ce0000), + SPH_C32(0x044a2e1c), SPH_C32(0x782f59e7), SPH_C32(0x8bdaaffb), + SPH_C32(0xd9ee6c30) }, + { SPH_C32(0x184f01dd), SPH_C32(0xfdb04000), SPH_C32(0xa84e0000), + SPH_C32(0xb4740000), SPH_C32(0xdc4c66c6), SPH_C32(0x453bbcf4), + SPH_C32(0xda86a308), SPH_C32(0x36c0fe8d), SPH_C32(0xc286009c), + SPH_C32(0x06690000), SPH_C32(0x44a10000), SPH_C32(0xe3150000), + SPH_C32(0x3ec143e1), SPH_C32(0x93e5f714), SPH_C32(0xa7b7e874), + SPH_C32(0x756000b8) }, + { SPH_C32(0xb4370060), SPH_C32(0x0c4c0000), SPH_C32(0x56c20000), + SPH_C32(0x5cae0000), SPH_C32(0x94541f3f), SPH_C32(0x3b3ef825), + SPH_C32(0x1b365f3d), SPH_C32(0xf3d45758), SPH_C32(0x5cb00110), + SPH_C32(0x913e0000), SPH_C32(0x44190000), SPH_C32(0x888c0000), + SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), SPH_C32(0x55ceea25), + SPH_C32(0x925c44e9) }, + { SPH_C32(0x42b70065), SPH_C32(0x380fc000), SPH_C32(0x72c50000), + SPH_C32(0xd3930000), SPH_C32(0xb56324c4), SPH_C32(0x31862d8b), + SPH_C32(0xd6f3d424), SPH_C32(0x2441ed69), SPH_C32(0xfacf0111), + SPH_C32(0xe0098000), SPH_C32(0x5de50000), SPH_C32(0x1e570000), + SPH_C32(0x5c5719e5), SPH_C32(0x79d5b395), SPH_C32(0x79a3adaa), + SPH_C32(0x3ed22861) }, + { SPH_C32(0x12480061), SPH_C32(0x7d7b8000), SPH_C32(0x4f3e0000), + SPH_C32(0xca750000), SPH_C32(0xaedf72c2), SPH_C32(0xd0f456d6), + SPH_C32(0x375b18b2), SPH_C32(0x5f5a3bd0), SPH_C32(0x0c4f0114), + SPH_C32(0xd44a4000), SPH_C32(0x79e20000), SPH_C32(0x916a0000), + SPH_C32(0x7d60221e), SPH_C32(0x736d663b), SPH_C32(0xb46626b3), + SPH_C32(0xe9479250) }, + { SPH_C32(0xe4c80064), SPH_C32(0x49384000), SPH_C32(0x6b390000), + SPH_C32(0x45480000), SPH_C32(0x8fe84939), SPH_C32(0xda4c8378), + SPH_C32(0xfa9e93ab), SPH_C32(0x88cf81e1), SPH_C32(0xaa300115), + SPH_C32(0xa57dc000), SPH_C32(0x601e0000), SPH_C32(0x07b10000), + SPH_C32(0x47eb4fe3), SPH_C32(0x98a7c8c8), SPH_C32(0x980b613c), + SPH_C32(0x45c9fed8) }, + { SPH_C32(0x43420069), SPH_C32(0xc370c000), SPH_C32(0x95140000), + SPH_C32(0x583c0000), SPH_C32(0x96c10696), SPH_C32(0xc3d6ce9f), + SPH_C32(0x61b1ae73), SPH_C32(0x6dc2cf42), SPH_C32(0x88da0110), + SPH_C32(0x1cf6c000), SPH_C32(0xe1b60000), SPH_C32(0xc2a50000), + SPH_C32(0x9a923662), SPH_C32(0x5bab9b0a), SPH_C32(0xcdf87c21), + SPH_C32(0x651a87c9) }, + { SPH_C32(0xb5c2006c), SPH_C32(0xf7330000), SPH_C32(0xb1130000), + SPH_C32(0xd7010000), SPH_C32(0xb7f63d6d), SPH_C32(0xc96e1b31), + SPH_C32(0xac74256a), SPH_C32(0xba577573), SPH_C32(0x2ea50111), + SPH_C32(0x6dc14000), SPH_C32(0xf84a0000), SPH_C32(0x547e0000), + SPH_C32(0xa0195b9f), SPH_C32(0xb06135f9), SPH_C32(0xe1953bae), + SPH_C32(0xc994eb41) }, + { SPH_C32(0xe53d0068), SPH_C32(0xb2474000), SPH_C32(0x8ce80000), + SPH_C32(0xcee70000), SPH_C32(0xac4a6b6b), SPH_C32(0x281c606c), + SPH_C32(0x4ddce9fc), SPH_C32(0xc14ca3ca), SPH_C32(0xd8250114), + SPH_C32(0x59828000), SPH_C32(0xdc4d0000), SPH_C32(0xdb430000), + SPH_C32(0x812e6064), SPH_C32(0xbad9e057), SPH_C32(0x2c50b0b7), + SPH_C32(0x1e015170) }, + { SPH_C32(0x13bd006d), SPH_C32(0x86048000), SPH_C32(0xa8ef0000), + SPH_C32(0x41da0000), SPH_C32(0x8d7d5090), SPH_C32(0x22a4b5c2), + SPH_C32(0x801962e5), SPH_C32(0x16d919fb), SPH_C32(0x7e5a0115), + SPH_C32(0x28b50000), SPH_C32(0xc5b10000), SPH_C32(0x4d980000), + SPH_C32(0xbba50d99), SPH_C32(0x51134ea4), SPH_C32(0x003df738), + SPH_C32(0xb28f3df8) }, + { SPH_C32(0x605d0060), SPH_C32(0x8184c000), SPH_C32(0xf36d0000), + SPH_C32(0x16870000), SPH_C32(0x681a5d45), SPH_C32(0xf28a7e49), + SPH_C32(0x8300c939), SPH_C32(0x04929478), SPH_C32(0x7faf0119), + SPH_C32(0xd3ca0000), SPH_C32(0x22600000), SPH_C32(0xc6370000), + SPH_C32(0x98072fcb), SPH_C32(0xa343adb0), SPH_C32(0xb77f8d6f), + SPH_C32(0xfb0c1fd3) }, + { SPH_C32(0x96dd0065), SPH_C32(0xb5c70000), SPH_C32(0xd76a0000), + SPH_C32(0x99ba0000), SPH_C32(0x492d66be), SPH_C32(0xf832abe7), + SPH_C32(0x4ec54220), SPH_C32(0xd3072e49), SPH_C32(0xd9d00118), + SPH_C32(0xa2fd8000), SPH_C32(0x3b9c0000), SPH_C32(0x50ec0000), + SPH_C32(0xa28c4236), SPH_C32(0x48890343), SPH_C32(0x9b12cae0), + SPH_C32(0x5782735b) }, + { SPH_C32(0xc6220061), SPH_C32(0xf0b34000), SPH_C32(0xea910000), + SPH_C32(0x805c0000), SPH_C32(0x529130b8), SPH_C32(0x1940d0ba), + SPH_C32(0xaf6d8eb6), SPH_C32(0xa81cf8f0), SPH_C32(0x2f50011d), + SPH_C32(0x96be4000), SPH_C32(0x1f9b0000), SPH_C32(0xdfd10000), + SPH_C32(0x83bb79cd), SPH_C32(0x4231d6ed), SPH_C32(0x56d741f9), + SPH_C32(0x8017c96a) }, + { SPH_C32(0x30a20064), SPH_C32(0xc4f08000), SPH_C32(0xce960000), + SPH_C32(0x0f610000), SPH_C32(0x73a60b43), SPH_C32(0x13f80514), + SPH_C32(0x62a805af), SPH_C32(0x7f8942c1), SPH_C32(0x892f011c), + SPH_C32(0xe789c000), SPH_C32(0x06670000), SPH_C32(0x490a0000), + SPH_C32(0xb9301430), SPH_C32(0xa9fb781e), SPH_C32(0x7aba0676), + SPH_C32(0x2c99a5e2) }, + { SPH_C32(0x97280069), SPH_C32(0x4eb80000), SPH_C32(0x30bb0000), + SPH_C32(0x12150000), SPH_C32(0x6a8f44ec), SPH_C32(0x0a6248f3), + SPH_C32(0xf9873877), SPH_C32(0x9a840c62), SPH_C32(0xabc50119), + SPH_C32(0x5e02c000), SPH_C32(0x87cf0000), SPH_C32(0x8c1e0000), + SPH_C32(0x64496db1), SPH_C32(0x6af72bdc), SPH_C32(0x2f491b6b), + SPH_C32(0x0c4adcf3) }, + { SPH_C32(0x61a8006c), SPH_C32(0x7afbc000), SPH_C32(0x14bc0000), + SPH_C32(0x9d280000), SPH_C32(0x4bb87f17), SPH_C32(0x00da9d5d), + SPH_C32(0x3442b36e), SPH_C32(0x4d11b653), SPH_C32(0x0dba0118), + SPH_C32(0x2f354000), SPH_C32(0x9e330000), SPH_C32(0x1ac50000), + SPH_C32(0x5ec2004c), SPH_C32(0x813d852f), SPH_C32(0x03245ce4), + SPH_C32(0xa0c4b07b) }, + { SPH_C32(0x31570068), SPH_C32(0x3f8f8000), SPH_C32(0x29470000), + SPH_C32(0x84ce0000), SPH_C32(0x50042911), SPH_C32(0xe1a8e600), + SPH_C32(0xd5ea7ff8), SPH_C32(0x360a60ea), SPH_C32(0xfb3a011d), + SPH_C32(0x1b768000), SPH_C32(0xba340000), SPH_C32(0x95f80000), + SPH_C32(0x7ff53bb7), SPH_C32(0x8b855081), SPH_C32(0xcee1d7fd), + SPH_C32(0x77510a4a) }, + { SPH_C32(0xc7d7006d), SPH_C32(0x0bcc4000), SPH_C32(0x0d400000), + SPH_C32(0x0bf30000), SPH_C32(0x713312ea), SPH_C32(0xeb1033ae), + SPH_C32(0x182ff4e1), SPH_C32(0xe19fdadb), SPH_C32(0x5d45011c), + SPH_C32(0x6a410000), SPH_C32(0xa3c80000), SPH_C32(0x03230000), + SPH_C32(0x457e564a), SPH_C32(0x604ffe72), SPH_C32(0xe28c9072), + SPH_C32(0xdbdf66c2) }, + { SPH_C32(0xc3730090), SPH_C32(0xfd160000), SPH_C32(0xa3700000), + SPH_C32(0x68ba0000), SPH_C32(0x1d6361b3), SPH_C32(0x61b51400), + SPH_C32(0x10f59223), SPH_C32(0x3ce32293), SPH_C32(0xa8dc0140), + SPH_C32(0x07260000), SPH_C32(0x50bc0000), SPH_C32(0x8b930000), + SPH_C32(0x24480aa0), SPH_C32(0xf4a0637f), SPH_C32(0xc96a9af7), + SPH_C32(0x1868519d) }, + { SPH_C32(0x35f30095), SPH_C32(0xc955c000), SPH_C32(0x87770000), + SPH_C32(0xe7870000), SPH_C32(0x3c545a48), SPH_C32(0x6b0dc1ae), + SPH_C32(0xdd30193a), SPH_C32(0xeb7698a2), SPH_C32(0x0ea30141), + SPH_C32(0x76118000), SPH_C32(0x49400000), SPH_C32(0x1d480000), + SPH_C32(0x1ec3675d), SPH_C32(0x1f6acd8c), SPH_C32(0xe507dd78), + SPH_C32(0xb4e63d15) }, + { SPH_C32(0x650c0091), SPH_C32(0x8c218000), SPH_C32(0xba8c0000), + SPH_C32(0xfe610000), SPH_C32(0x27e80c4e), SPH_C32(0x8a7fbaf3), + SPH_C32(0x3c98d5ac), SPH_C32(0x906d4e1b), SPH_C32(0xf8230144), + SPH_C32(0x42524000), SPH_C32(0x6d470000), SPH_C32(0x92750000), + SPH_C32(0x3ff45ca6), SPH_C32(0x15d21822), SPH_C32(0x28c25661), + SPH_C32(0x63738724) }, + { SPH_C32(0x938c0094), SPH_C32(0xb8624000), SPH_C32(0x9e8b0000), + SPH_C32(0x715c0000), SPH_C32(0x06df37b5), SPH_C32(0x80c76f5d), + SPH_C32(0xf15d5eb5), SPH_C32(0x47f8f42a), SPH_C32(0x5e5c0145), + SPH_C32(0x3365c000), SPH_C32(0x74bb0000), SPH_C32(0x04ae0000), + SPH_C32(0x057f315b), SPH_C32(0xfe18b6d1), SPH_C32(0x04af11ee), + SPH_C32(0xcffdebac) }, + { SPH_C32(0x34060099), SPH_C32(0x322ac000), SPH_C32(0x60a60000), + SPH_C32(0x6c280000), SPH_C32(0x1ff6781a), SPH_C32(0x995d22ba), + SPH_C32(0x6a72636d), SPH_C32(0xa2f5ba89), SPH_C32(0x7cb60140), + SPH_C32(0x8aeec000), SPH_C32(0xf5130000), SPH_C32(0xc1ba0000), + SPH_C32(0xd80648da), SPH_C32(0x3d14e513), SPH_C32(0x515c0cf3), + SPH_C32(0xef2e92bd) }, + { SPH_C32(0xc286009c), SPH_C32(0x06690000), SPH_C32(0x44a10000), + SPH_C32(0xe3150000), SPH_C32(0x3ec143e1), SPH_C32(0x93e5f714), + SPH_C32(0xa7b7e874), SPH_C32(0x756000b8), SPH_C32(0xdac90141), + SPH_C32(0xfbd94000), SPH_C32(0xecef0000), SPH_C32(0x57610000), + SPH_C32(0xe28d2527), SPH_C32(0xd6de4be0), SPH_C32(0x7d314b7c), + SPH_C32(0x43a0fe35) }, + { SPH_C32(0x92790098), SPH_C32(0x431d4000), SPH_C32(0x795a0000), + SPH_C32(0xfaf30000), SPH_C32(0x257d15e7), SPH_C32(0x72978c49), + SPH_C32(0x461f24e2), SPH_C32(0x0e7bd601), SPH_C32(0x2c490144), + SPH_C32(0xcf9a8000), SPH_C32(0xc8e80000), SPH_C32(0xd85c0000), + SPH_C32(0xc3ba1edc), SPH_C32(0xdc669e4e), SPH_C32(0xb0f4c065), + SPH_C32(0x94354404) }, + { SPH_C32(0x64f9009d), SPH_C32(0x775e8000), SPH_C32(0x5d5d0000), + SPH_C32(0x75ce0000), SPH_C32(0x044a2e1c), SPH_C32(0x782f59e7), + SPH_C32(0x8bdaaffb), SPH_C32(0xd9ee6c30), SPH_C32(0x8a360145), + SPH_C32(0xbead0000), SPH_C32(0xd1140000), SPH_C32(0x4e870000), + SPH_C32(0xf9317321), SPH_C32(0x37ac30bd), SPH_C32(0x9c9987ea), + SPH_C32(0x38bb288c) }, + { SPH_C32(0x17190090), SPH_C32(0x70dec000), SPH_C32(0x06df0000), + SPH_C32(0x22930000), SPH_C32(0xe12d23c9), SPH_C32(0xa801926c), + SPH_C32(0x88c30427), SPH_C32(0xcba5e1b3), SPH_C32(0x8bc30149), + SPH_C32(0x45d20000), SPH_C32(0x36c50000), SPH_C32(0xc5280000), + SPH_C32(0xda935173), SPH_C32(0xc5fcd3a9), SPH_C32(0x2bdbfdbd), + SPH_C32(0x71380aa7) }, + { SPH_C32(0xe1990095), SPH_C32(0x449d0000), SPH_C32(0x22d80000), + SPH_C32(0xadae0000), SPH_C32(0xc01a1832), SPH_C32(0xa2b947c2), + SPH_C32(0x45068f3e), SPH_C32(0x1c305b82), SPH_C32(0x2dbc0148), + SPH_C32(0x34e58000), SPH_C32(0x2f390000), SPH_C32(0x53f30000), + SPH_C32(0xe0183c8e), SPH_C32(0x2e367d5a), SPH_C32(0x07b6ba32), + SPH_C32(0xddb6662f) }, + { SPH_C32(0xb1660091), SPH_C32(0x01e94000), SPH_C32(0x1f230000), + SPH_C32(0xb4480000), SPH_C32(0xdba64e34), SPH_C32(0x43cb3c9f), + SPH_C32(0xa4ae43a8), SPH_C32(0x672b8d3b), SPH_C32(0xdb3c014d), + SPH_C32(0x00a64000), SPH_C32(0x0b3e0000), SPH_C32(0xdcce0000), + SPH_C32(0xc12f0775), SPH_C32(0x248ea8f4), SPH_C32(0xca73312b), + SPH_C32(0x0a23dc1e) }, + { SPH_C32(0x47e60094), SPH_C32(0x35aa8000), SPH_C32(0x3b240000), + SPH_C32(0x3b750000), SPH_C32(0xfa9175cf), SPH_C32(0x4973e931), + SPH_C32(0x696bc8b1), SPH_C32(0xb0be370a), SPH_C32(0x7d43014c), + SPH_C32(0x7191c000), SPH_C32(0x12c20000), SPH_C32(0x4a150000), + SPH_C32(0xfba46a88), SPH_C32(0xcf440607), SPH_C32(0xe61e76a4), + SPH_C32(0xa6adb096) }, + { SPH_C32(0xe06c0099), SPH_C32(0xbfe20000), SPH_C32(0xc5090000), + SPH_C32(0x26010000), SPH_C32(0xe3b83a60), SPH_C32(0x50e9a4d6), + SPH_C32(0xf244f569), SPH_C32(0x55b379a9), SPH_C32(0x5fa90149), + SPH_C32(0xc81ac000), SPH_C32(0x936a0000), SPH_C32(0x8f010000), + SPH_C32(0x26dd1309), SPH_C32(0x0c4855c5), SPH_C32(0xb3ed6bb9), + SPH_C32(0x867ec987) }, + { SPH_C32(0x16ec009c), SPH_C32(0x8ba1c000), SPH_C32(0xe10e0000), + SPH_C32(0xa93c0000), SPH_C32(0xc28f019b), SPH_C32(0x5a517178), + SPH_C32(0x3f817e70), SPH_C32(0x8226c398), SPH_C32(0xf9d60148), + SPH_C32(0xb92d4000), SPH_C32(0x8a960000), SPH_C32(0x19da0000), + SPH_C32(0x1c567ef4), SPH_C32(0xe782fb36), SPH_C32(0x9f802c36), + SPH_C32(0x2af0a50f) }, + { SPH_C32(0x46130098), SPH_C32(0xced58000), SPH_C32(0xdcf50000), + SPH_C32(0xb0da0000), SPH_C32(0xd933579d), SPH_C32(0xbb230a25), + SPH_C32(0xde29b2e6), SPH_C32(0xf93d1521), SPH_C32(0x0f56014d), + SPH_C32(0x8d6e8000), SPH_C32(0xae910000), SPH_C32(0x96e70000), + SPH_C32(0x3d61450f), SPH_C32(0xed3a2e98), SPH_C32(0x5245a72f), + SPH_C32(0xfd651f3e) }, + { SPH_C32(0xb093009d), SPH_C32(0xfa964000), SPH_C32(0xf8f20000), + SPH_C32(0x3fe70000), SPH_C32(0xf8046c66), SPH_C32(0xb19bdf8b), + SPH_C32(0x13ec39ff), SPH_C32(0x2ea8af10), SPH_C32(0xa929014c), + SPH_C32(0xfc590000), SPH_C32(0xb76d0000), SPH_C32(0x003c0000), + SPH_C32(0x07ea28f2), SPH_C32(0x06f0806b), SPH_C32(0x7e28e0a0), + SPH_C32(0x51eb73b6) }, + { SPH_C32(0x405b0030), SPH_C32(0x9a540000), SPH_C32(0x42670000), + SPH_C32(0x5fb10000), SPH_C32(0xd6c06187), SPH_C32(0x5d81863c), + SPH_C32(0x87922fef), SPH_C32(0x79e0422c), SPH_C32(0xdf9801b0), + SPH_C32(0xf67c0000), SPH_C32(0xa50e0000), SPH_C32(0xbf870000), + SPH_C32(0xad7f742c), SPH_C32(0xae2b8f5a), SPH_C32(0xc2a957e9), + SPH_C32(0xd75f2456) }, + { SPH_C32(0xb6db0035), SPH_C32(0xae17c000), SPH_C32(0x66600000), + SPH_C32(0xd08c0000), SPH_C32(0xf7f75a7c), SPH_C32(0x57395392), + SPH_C32(0x4a57a4f6), SPH_C32(0xae75f81d), SPH_C32(0x79e701b1), + SPH_C32(0x874b8000), SPH_C32(0xbcf20000), SPH_C32(0x295c0000), + SPH_C32(0x97f419d1), SPH_C32(0x45e121a9), SPH_C32(0xeec41066), + SPH_C32(0x7bd148de) }, + { SPH_C32(0xe6240031), SPH_C32(0xeb638000), SPH_C32(0x5b9b0000), + SPH_C32(0xc96a0000), SPH_C32(0xec4b0c7a), SPH_C32(0xb64b28cf), + SPH_C32(0xabff6860), SPH_C32(0xd56e2ea4), SPH_C32(0x8f6701b4), + SPH_C32(0xb3084000), SPH_C32(0x98f50000), SPH_C32(0xa6610000), + SPH_C32(0xb6c3222a), SPH_C32(0x4f59f407), SPH_C32(0x23019b7f), + SPH_C32(0xac44f2ef) }, + { SPH_C32(0x10a40034), SPH_C32(0xdf204000), SPH_C32(0x7f9c0000), + SPH_C32(0x46570000), SPH_C32(0xcd7c3781), SPH_C32(0xbcf3fd61), + SPH_C32(0x663ae379), SPH_C32(0x02fb9495), SPH_C32(0x291801b5), + SPH_C32(0xc23fc000), SPH_C32(0x81090000), SPH_C32(0x30ba0000), + SPH_C32(0x8c484fd7), SPH_C32(0xa4935af4), SPH_C32(0x0f6cdcf0), + SPH_C32(0x00ca9e67) }, + { SPH_C32(0xb72e0039), SPH_C32(0x5568c000), SPH_C32(0x81b10000), + SPH_C32(0x5b230000), SPH_C32(0xd455782e), SPH_C32(0xa569b086), + SPH_C32(0xfd15dea1), SPH_C32(0xe7f6da36), SPH_C32(0x0bf201b0), + SPH_C32(0x7bb4c000), SPH_C32(0x00a10000), SPH_C32(0xf5ae0000), + SPH_C32(0x51313656), SPH_C32(0x679f0936), SPH_C32(0x5a9fc1ed), + SPH_C32(0x2019e776) }, + { SPH_C32(0x41ae003c), SPH_C32(0x612b0000), SPH_C32(0xa5b60000), + SPH_C32(0xd41e0000), SPH_C32(0xf56243d5), SPH_C32(0xafd16528), + SPH_C32(0x30d055b8), SPH_C32(0x30636007), SPH_C32(0xad8d01b1), + SPH_C32(0x0a834000), SPH_C32(0x195d0000), SPH_C32(0x63750000), + SPH_C32(0x6bba5bab), SPH_C32(0x8c55a7c5), SPH_C32(0x76f28662), + SPH_C32(0x8c978bfe) }, + { SPH_C32(0x11510038), SPH_C32(0x245f4000), SPH_C32(0x984d0000), + SPH_C32(0xcdf80000), SPH_C32(0xeede15d3), SPH_C32(0x4ea31e75), + SPH_C32(0xd178992e), SPH_C32(0x4b78b6be), SPH_C32(0x5b0d01b4), + SPH_C32(0x3ec08000), SPH_C32(0x3d5a0000), SPH_C32(0xec480000), + SPH_C32(0x4a8d6050), SPH_C32(0x86ed726b), SPH_C32(0xbb370d7b), + SPH_C32(0x5b0231cf) }, + { SPH_C32(0xe7d1003d), SPH_C32(0x101c8000), SPH_C32(0xbc4a0000), + SPH_C32(0x42c50000), SPH_C32(0xcfe92e28), SPH_C32(0x441bcbdb), + SPH_C32(0x1cbd1237), SPH_C32(0x9ced0c8f), SPH_C32(0xfd7201b5), + SPH_C32(0x4ff70000), SPH_C32(0x24a60000), SPH_C32(0x7a930000), + SPH_C32(0x70060dad), SPH_C32(0x6d27dc98), SPH_C32(0x975a4af4), + SPH_C32(0xf78c5d47) }, + { SPH_C32(0x94310030), SPH_C32(0x179cc000), SPH_C32(0xe7c80000), + SPH_C32(0x15980000), SPH_C32(0x2a8e23fd), SPH_C32(0x94350050), + SPH_C32(0x1fa4b9eb), SPH_C32(0x8ea6810c), SPH_C32(0xfc8701b9), + SPH_C32(0xb4880000), SPH_C32(0xc3770000), SPH_C32(0xf13c0000), + SPH_C32(0x53a42fff), SPH_C32(0x9f773f8c), SPH_C32(0x201830a3), + SPH_C32(0xbe0f7f6c) }, + { SPH_C32(0x62b10035), SPH_C32(0x23df0000), SPH_C32(0xc3cf0000), + SPH_C32(0x9aa50000), SPH_C32(0x0bb91806), SPH_C32(0x9e8dd5fe), + SPH_C32(0xd26132f2), SPH_C32(0x59333b3d), SPH_C32(0x5af801b8), + SPH_C32(0xc5bf8000), SPH_C32(0xda8b0000), SPH_C32(0x67e70000), + SPH_C32(0x692f4202), SPH_C32(0x74bd917f), SPH_C32(0x0c75772c), + SPH_C32(0x128113e4) }, + { SPH_C32(0x324e0031), SPH_C32(0x66ab4000), SPH_C32(0xfe340000), + SPH_C32(0x83430000), SPH_C32(0x10054e00), SPH_C32(0x7fffaea3), + SPH_C32(0x33c9fe64), SPH_C32(0x2228ed84), SPH_C32(0xac7801bd), + SPH_C32(0xf1fc4000), SPH_C32(0xfe8c0000), SPH_C32(0xe8da0000), + SPH_C32(0x481879f9), SPH_C32(0x7e0544d1), SPH_C32(0xc1b0fc35), + SPH_C32(0xc514a9d5) }, + { SPH_C32(0xc4ce0034), SPH_C32(0x52e88000), SPH_C32(0xda330000), + SPH_C32(0x0c7e0000), SPH_C32(0x313275fb), SPH_C32(0x75477b0d), + SPH_C32(0xfe0c757d), SPH_C32(0xf5bd57b5), SPH_C32(0x0a0701bc), + SPH_C32(0x80cbc000), SPH_C32(0xe7700000), SPH_C32(0x7e010000), + SPH_C32(0x72931404), SPH_C32(0x95cfea22), SPH_C32(0xedddbbba), + SPH_C32(0x699ac55d) }, + { SPH_C32(0x63440039), SPH_C32(0xd8a00000), SPH_C32(0x241e0000), + SPH_C32(0x110a0000), SPH_C32(0x281b3a54), SPH_C32(0x6cdd36ea), + SPH_C32(0x652348a5), SPH_C32(0x10b01916), SPH_C32(0x28ed01b9), + SPH_C32(0x3940c000), SPH_C32(0x66d80000), SPH_C32(0xbb150000), + SPH_C32(0xafea6d85), SPH_C32(0x56c3b9e0), SPH_C32(0xb82ea6a7), + SPH_C32(0x4949bc4c) }, + { SPH_C32(0x95c4003c), SPH_C32(0xece3c000), SPH_C32(0x00190000), + SPH_C32(0x9e370000), SPH_C32(0x092c01af), SPH_C32(0x6665e344), + SPH_C32(0xa8e6c3bc), SPH_C32(0xc725a327), SPH_C32(0x8e9201b8), + SPH_C32(0x48774000), SPH_C32(0x7f240000), SPH_C32(0x2dce0000), + SPH_C32(0x95610078), SPH_C32(0xbd091713), SPH_C32(0x9443e128), + SPH_C32(0xe5c7d0c4) }, + { SPH_C32(0xc53b0038), SPH_C32(0xa9978000), SPH_C32(0x3de20000), + SPH_C32(0x87d10000), SPH_C32(0x129057a9), SPH_C32(0x87179819), + SPH_C32(0x494e0f2a), SPH_C32(0xbc3e759e), SPH_C32(0x781201bd), + SPH_C32(0x7c348000), SPH_C32(0x5b230000), SPH_C32(0xa2f30000), + SPH_C32(0xb4563b83), SPH_C32(0xb7b1c2bd), SPH_C32(0x59866a31), + SPH_C32(0x32526af5) }, + { SPH_C32(0x33bb003d), SPH_C32(0x9dd44000), SPH_C32(0x19e50000), + SPH_C32(0x08ec0000), SPH_C32(0x33a76c52), SPH_C32(0x8daf4db7), + SPH_C32(0x848b8433), SPH_C32(0x6babcfaf), SPH_C32(0xde6d01bc), + SPH_C32(0x0d030000), SPH_C32(0x42df0000), SPH_C32(0x34280000), + SPH_C32(0x8edd567e), SPH_C32(0x5c7b6c4e), SPH_C32(0x75eb2dbe), + SPH_C32(0x9edc067d) }, + { SPH_C32(0x371f00c0), SPH_C32(0x6b0e0000), SPH_C32(0xb7d50000), + SPH_C32(0x6ba50000), SPH_C32(0x5ff71f0b), SPH_C32(0x070a6a19), + SPH_C32(0x8c51e2f1), SPH_C32(0xb6d737e7), SPH_C32(0x2bf401e0), + SPH_C32(0x60640000), SPH_C32(0xb1ab0000), SPH_C32(0xbc980000), + SPH_C32(0xefeb0a94), SPH_C32(0xc894f143), SPH_C32(0x5e0d273b), + SPH_C32(0x5d6b3122) }, + { SPH_C32(0xc19f00c5), SPH_C32(0x5f4dc000), SPH_C32(0x93d20000), + SPH_C32(0xe4980000), SPH_C32(0x7ec024f0), SPH_C32(0x0db2bfb7), + SPH_C32(0x419469e8), SPH_C32(0x61428dd6), SPH_C32(0x8d8b01e1), + SPH_C32(0x11538000), SPH_C32(0xa8570000), SPH_C32(0x2a430000), + SPH_C32(0xd5606769), SPH_C32(0x235e5fb0), SPH_C32(0x726060b4), + SPH_C32(0xf1e55daa) }, + { SPH_C32(0x916000c1), SPH_C32(0x1a398000), SPH_C32(0xae290000), + SPH_C32(0xfd7e0000), SPH_C32(0x657c72f6), SPH_C32(0xecc0c4ea), + SPH_C32(0xa03ca57e), SPH_C32(0x1a595b6f), SPH_C32(0x7b0b01e4), + SPH_C32(0x25104000), SPH_C32(0x8c500000), SPH_C32(0xa57e0000), + SPH_C32(0xf4575c92), SPH_C32(0x29e68a1e), SPH_C32(0xbfa5ebad), + SPH_C32(0x2670e79b) }, + { SPH_C32(0x67e000c4), SPH_C32(0x2e7a4000), SPH_C32(0x8a2e0000), + SPH_C32(0x72430000), SPH_C32(0x444b490d), SPH_C32(0xe6781144), + SPH_C32(0x6df92e67), SPH_C32(0xcdcce15e), SPH_C32(0xdd7401e5), + SPH_C32(0x5427c000), SPH_C32(0x95ac0000), SPH_C32(0x33a50000), + SPH_C32(0xcedc316f), SPH_C32(0xc22c24ed), SPH_C32(0x93c8ac22), + SPH_C32(0x8afe8b13) }, + { SPH_C32(0xc06a00c9), SPH_C32(0xa432c000), SPH_C32(0x74030000), + SPH_C32(0x6f370000), SPH_C32(0x5d6206a2), SPH_C32(0xffe25ca3), + SPH_C32(0xf6d613bf), SPH_C32(0x28c1affd), SPH_C32(0xff9e01e0), + SPH_C32(0xedacc000), SPH_C32(0x14040000), SPH_C32(0xf6b10000), + SPH_C32(0x13a548ee), SPH_C32(0x0120772f), SPH_C32(0xc63bb13f), + SPH_C32(0xaa2df202) }, + { SPH_C32(0x36ea00cc), SPH_C32(0x90710000), SPH_C32(0x50040000), + SPH_C32(0xe00a0000), SPH_C32(0x7c553d59), SPH_C32(0xf55a890d), + SPH_C32(0x3b1398a6), SPH_C32(0xff5415cc), SPH_C32(0x59e101e1), + SPH_C32(0x9c9b4000), SPH_C32(0x0df80000), SPH_C32(0x606a0000), + SPH_C32(0x292e2513), SPH_C32(0xeaead9dc), SPH_C32(0xea56f6b0), + SPH_C32(0x06a39e8a) }, + { SPH_C32(0x661500c8), SPH_C32(0xd5054000), SPH_C32(0x6dff0000), + SPH_C32(0xf9ec0000), SPH_C32(0x67e96b5f), SPH_C32(0x1428f250), + SPH_C32(0xdabb5430), SPH_C32(0x844fc375), SPH_C32(0xaf6101e4), + SPH_C32(0xa8d88000), SPH_C32(0x29ff0000), SPH_C32(0xef570000), + SPH_C32(0x08191ee8), SPH_C32(0xe0520c72), SPH_C32(0x27937da9), + SPH_C32(0xd13624bb) }, + { SPH_C32(0x909500cd), SPH_C32(0xe1468000), SPH_C32(0x49f80000), + SPH_C32(0x76d10000), SPH_C32(0x46de50a4), SPH_C32(0x1e9027fe), + SPH_C32(0x177edf29), SPH_C32(0x53da7944), SPH_C32(0x091e01e5), + SPH_C32(0xd9ef0000), SPH_C32(0x30030000), SPH_C32(0x798c0000), + SPH_C32(0x32927315), SPH_C32(0x0b98a281), SPH_C32(0x0bfe3a26), + SPH_C32(0x7db84833) }, + { SPH_C32(0xe37500c0), SPH_C32(0xe6c6c000), SPH_C32(0x127a0000), + SPH_C32(0x218c0000), SPH_C32(0xa3b95d71), SPH_C32(0xcebeec75), + SPH_C32(0x146774f5), SPH_C32(0x4191f4c7), SPH_C32(0x08eb01e9), + SPH_C32(0x22900000), SPH_C32(0xd7d20000), SPH_C32(0xf2230000), + SPH_C32(0x11305147), SPH_C32(0xf9c84195), SPH_C32(0xbcbc4071), + SPH_C32(0x343b6a18) }, + { SPH_C32(0x15f500c5), SPH_C32(0xd2850000), SPH_C32(0x367d0000), + SPH_C32(0xaeb10000), SPH_C32(0x828e668a), SPH_C32(0xc40639db), + SPH_C32(0xd9a2ffec), SPH_C32(0x96044ef6), SPH_C32(0xae9401e8), + SPH_C32(0x53a78000), SPH_C32(0xce2e0000), SPH_C32(0x64f80000), + SPH_C32(0x2bbb3cba), SPH_C32(0x1202ef66), SPH_C32(0x90d107fe), + SPH_C32(0x98b50690) }, + { SPH_C32(0x450a00c1), SPH_C32(0x97f14000), SPH_C32(0x0b860000), + SPH_C32(0xb7570000), SPH_C32(0x9932308c), SPH_C32(0x25744286), + SPH_C32(0x380a337a), SPH_C32(0xed1f984f), SPH_C32(0x581401ed), + SPH_C32(0x67e44000), SPH_C32(0xea290000), SPH_C32(0xebc50000), + SPH_C32(0x0a8c0741), SPH_C32(0x18ba3ac8), SPH_C32(0x5d148ce7), + SPH_C32(0x4f20bca1) }, + { SPH_C32(0xb38a00c4), SPH_C32(0xa3b28000), SPH_C32(0x2f810000), + SPH_C32(0x386a0000), SPH_C32(0xb8050b77), SPH_C32(0x2fcc9728), + SPH_C32(0xf5cfb863), SPH_C32(0x3a8a227e), SPH_C32(0xfe6b01ec), + SPH_C32(0x16d3c000), SPH_C32(0xf3d50000), SPH_C32(0x7d1e0000), + SPH_C32(0x30076abc), SPH_C32(0xf370943b), SPH_C32(0x7179cb68), + SPH_C32(0xe3aed029) }, + { SPH_C32(0x140000c9), SPH_C32(0x29fa0000), SPH_C32(0xd1ac0000), + SPH_C32(0x251e0000), SPH_C32(0xa12c44d8), SPH_C32(0x3656dacf), + SPH_C32(0x6ee085bb), SPH_C32(0xdf876cdd), SPH_C32(0xdc8101e9), + SPH_C32(0xaf58c000), SPH_C32(0x727d0000), SPH_C32(0xb80a0000), + SPH_C32(0xed7e133d), SPH_C32(0x307cc7f9), SPH_C32(0x248ad675), + SPH_C32(0xc37da938) }, + { SPH_C32(0xe28000cc), SPH_C32(0x1db9c000), SPH_C32(0xf5ab0000), + SPH_C32(0xaa230000), SPH_C32(0x801b7f23), SPH_C32(0x3cee0f61), + SPH_C32(0xa3250ea2), SPH_C32(0x0812d6ec), SPH_C32(0x7afe01e8), + SPH_C32(0xde6f4000), SPH_C32(0x6b810000), SPH_C32(0x2ed10000), + SPH_C32(0xd7f57ec0), SPH_C32(0xdbb6690a), SPH_C32(0x08e791fa), + SPH_C32(0x6ff3c5b0) }, + { SPH_C32(0xb27f00c8), SPH_C32(0x58cd8000), SPH_C32(0xc8500000), + SPH_C32(0xb3c50000), SPH_C32(0x9ba72925), SPH_C32(0xdd9c743c), + SPH_C32(0x428dc234), SPH_C32(0x73090055), SPH_C32(0x8c7e01ed), + SPH_C32(0xea2c8000), SPH_C32(0x4f860000), SPH_C32(0xa1ec0000), + SPH_C32(0xf6c2453b), SPH_C32(0xd10ebca4), SPH_C32(0xc5221ae3), + SPH_C32(0xb8667f81) }, + { SPH_C32(0x44ff00cd), SPH_C32(0x6c8e4000), SPH_C32(0xec570000), + SPH_C32(0x3cf80000), SPH_C32(0xba9012de), SPH_C32(0xd724a192), + SPH_C32(0x8f48492d), SPH_C32(0xa49cba64), SPH_C32(0x2a0101ec), + SPH_C32(0x9b1b0000), SPH_C32(0x567a0000), SPH_C32(0x37370000), + SPH_C32(0xcc4928c6), SPH_C32(0x3ac41257), SPH_C32(0xe94f5d6c), + SPH_C32(0x14e81309) }, + { SPH_C32(0x5cb00110), SPH_C32(0x913e0000), SPH_C32(0x44190000), + SPH_C32(0x888c0000), SPH_C32(0x66dc7418), SPH_C32(0x921f1d66), + SPH_C32(0x55ceea25), SPH_C32(0x925c44e9), SPH_C32(0xe8870170), + SPH_C32(0x9d720000), SPH_C32(0x12db0000), SPH_C32(0xd4220000), + SPH_C32(0xf2886b27), SPH_C32(0xa921e543), SPH_C32(0x4ef8b518), + SPH_C32(0x618813b1) }, + { SPH_C32(0xaa300115), SPH_C32(0xa57dc000), SPH_C32(0x601e0000), + SPH_C32(0x07b10000), SPH_C32(0x47eb4fe3), SPH_C32(0x98a7c8c8), + SPH_C32(0x980b613c), SPH_C32(0x45c9fed8), SPH_C32(0x4ef80171), + SPH_C32(0xec458000), SPH_C32(0x0b270000), SPH_C32(0x42f90000), + SPH_C32(0xc80306da), SPH_C32(0x42eb4bb0), SPH_C32(0x6295f297), + SPH_C32(0xcd067f39) }, + { SPH_C32(0xfacf0111), SPH_C32(0xe0098000), SPH_C32(0x5de50000), + SPH_C32(0x1e570000), SPH_C32(0x5c5719e5), SPH_C32(0x79d5b395), + SPH_C32(0x79a3adaa), SPH_C32(0x3ed22861), SPH_C32(0xb8780174), + SPH_C32(0xd8064000), SPH_C32(0x2f200000), SPH_C32(0xcdc40000), + SPH_C32(0xe9343d21), SPH_C32(0x48539e1e), SPH_C32(0xaf50798e), + SPH_C32(0x1a93c508) }, + { SPH_C32(0x0c4f0114), SPH_C32(0xd44a4000), SPH_C32(0x79e20000), + SPH_C32(0x916a0000), SPH_C32(0x7d60221e), SPH_C32(0x736d663b), + SPH_C32(0xb46626b3), SPH_C32(0xe9479250), SPH_C32(0x1e070175), + SPH_C32(0xa931c000), SPH_C32(0x36dc0000), SPH_C32(0x5b1f0000), + SPH_C32(0xd3bf50dc), SPH_C32(0xa39930ed), SPH_C32(0x833d3e01), + SPH_C32(0xb61da980) }, + { SPH_C32(0xabc50119), SPH_C32(0x5e02c000), SPH_C32(0x87cf0000), + SPH_C32(0x8c1e0000), SPH_C32(0x64496db1), SPH_C32(0x6af72bdc), + SPH_C32(0x2f491b6b), SPH_C32(0x0c4adcf3), SPH_C32(0x3ced0170), + SPH_C32(0x10bac000), SPH_C32(0xb7740000), SPH_C32(0x9e0b0000), + SPH_C32(0x0ec6295d), SPH_C32(0x6095632f), SPH_C32(0xd6ce231c), + SPH_C32(0x96ced091) }, + { SPH_C32(0x5d45011c), SPH_C32(0x6a410000), SPH_C32(0xa3c80000), + SPH_C32(0x03230000), SPH_C32(0x457e564a), SPH_C32(0x604ffe72), + SPH_C32(0xe28c9072), SPH_C32(0xdbdf66c2), SPH_C32(0x9a920171), + SPH_C32(0x618d4000), SPH_C32(0xae880000), SPH_C32(0x08d00000), + SPH_C32(0x344d44a0), SPH_C32(0x8b5fcddc), SPH_C32(0xfaa36493), + SPH_C32(0x3a40bc19) }, + { SPH_C32(0x0dba0118), SPH_C32(0x2f354000), SPH_C32(0x9e330000), + SPH_C32(0x1ac50000), SPH_C32(0x5ec2004c), SPH_C32(0x813d852f), + SPH_C32(0x03245ce4), SPH_C32(0xa0c4b07b), SPH_C32(0x6c120174), + SPH_C32(0x55ce8000), SPH_C32(0x8a8f0000), SPH_C32(0x87ed0000), + SPH_C32(0x157a7f5b), SPH_C32(0x81e71872), SPH_C32(0x3766ef8a), + SPH_C32(0xedd50628) }, + { SPH_C32(0xfb3a011d), SPH_C32(0x1b768000), SPH_C32(0xba340000), + SPH_C32(0x95f80000), SPH_C32(0x7ff53bb7), SPH_C32(0x8b855081), + SPH_C32(0xcee1d7fd), SPH_C32(0x77510a4a), SPH_C32(0xca6d0175), + SPH_C32(0x24f90000), SPH_C32(0x93730000), SPH_C32(0x11360000), + SPH_C32(0x2ff112a6), SPH_C32(0x6a2db681), SPH_C32(0x1b0ba805), + SPH_C32(0x415b6aa0) }, + { SPH_C32(0x88da0110), SPH_C32(0x1cf6c000), SPH_C32(0xe1b60000), + SPH_C32(0xc2a50000), SPH_C32(0x9a923662), SPH_C32(0x5bab9b0a), + SPH_C32(0xcdf87c21), SPH_C32(0x651a87c9), SPH_C32(0xcb980179), + SPH_C32(0xdf860000), SPH_C32(0x74a20000), SPH_C32(0x9a990000), + SPH_C32(0x0c5330f4), SPH_C32(0x987d5595), SPH_C32(0xac49d252), + SPH_C32(0x08d8488b) }, + { SPH_C32(0x7e5a0115), SPH_C32(0x28b50000), SPH_C32(0xc5b10000), + SPH_C32(0x4d980000), SPH_C32(0xbba50d99), SPH_C32(0x51134ea4), + SPH_C32(0x003df738), SPH_C32(0xb28f3df8), SPH_C32(0x6de70178), + SPH_C32(0xaeb18000), SPH_C32(0x6d5e0000), SPH_C32(0x0c420000), + SPH_C32(0x36d85d09), SPH_C32(0x73b7fb66), SPH_C32(0x802495dd), + SPH_C32(0xa4562403) }, + { SPH_C32(0x2ea50111), SPH_C32(0x6dc14000), SPH_C32(0xf84a0000), + SPH_C32(0x547e0000), SPH_C32(0xa0195b9f), SPH_C32(0xb06135f9), + SPH_C32(0xe1953bae), SPH_C32(0xc994eb41), SPH_C32(0x9b67017d), + SPH_C32(0x9af24000), SPH_C32(0x49590000), SPH_C32(0x837f0000), + SPH_C32(0x17ef66f2), SPH_C32(0x790f2ec8), SPH_C32(0x4de11ec4), + SPH_C32(0x73c39e32) }, + { SPH_C32(0xd8250114), SPH_C32(0x59828000), SPH_C32(0xdc4d0000), + SPH_C32(0xdb430000), SPH_C32(0x812e6064), SPH_C32(0xbad9e057), + SPH_C32(0x2c50b0b7), SPH_C32(0x1e015170), SPH_C32(0x3d18017c), + SPH_C32(0xebc5c000), SPH_C32(0x50a50000), SPH_C32(0x15a40000), + SPH_C32(0x2d640b0f), SPH_C32(0x92c5803b), SPH_C32(0x618c594b), + SPH_C32(0xdf4df2ba) }, + { SPH_C32(0x7faf0119), SPH_C32(0xd3ca0000), SPH_C32(0x22600000), + SPH_C32(0xc6370000), SPH_C32(0x98072fcb), SPH_C32(0xa343adb0), + SPH_C32(0xb77f8d6f), SPH_C32(0xfb0c1fd3), SPH_C32(0x1ff20179), + SPH_C32(0x524ec000), SPH_C32(0xd10d0000), SPH_C32(0xd0b00000), + SPH_C32(0xf01d728e), SPH_C32(0x51c9d3f9), SPH_C32(0x347f4456), + SPH_C32(0xff9e8bab) }, + { SPH_C32(0x892f011c), SPH_C32(0xe789c000), SPH_C32(0x06670000), + SPH_C32(0x490a0000), SPH_C32(0xb9301430), SPH_C32(0xa9fb781e), + SPH_C32(0x7aba0676), SPH_C32(0x2c99a5e2), SPH_C32(0xb98d0178), + SPH_C32(0x23794000), SPH_C32(0xc8f10000), SPH_C32(0x466b0000), + SPH_C32(0xca961f73), SPH_C32(0xba037d0a), SPH_C32(0x181203d9), + SPH_C32(0x5310e723) }, + { SPH_C32(0xd9d00118), SPH_C32(0xa2fd8000), SPH_C32(0x3b9c0000), + SPH_C32(0x50ec0000), SPH_C32(0xa28c4236), SPH_C32(0x48890343), + SPH_C32(0x9b12cae0), SPH_C32(0x5782735b), SPH_C32(0x4f0d017d), + SPH_C32(0x173a8000), SPH_C32(0xecf60000), SPH_C32(0xc9560000), + SPH_C32(0xeba12488), SPH_C32(0xb0bba8a4), SPH_C32(0xd5d788c0), + SPH_C32(0x84855d12) }, + { SPH_C32(0x2f50011d), SPH_C32(0x96be4000), SPH_C32(0x1f9b0000), + SPH_C32(0xdfd10000), SPH_C32(0x83bb79cd), SPH_C32(0x4231d6ed), + SPH_C32(0x56d741f9), SPH_C32(0x8017c96a), SPH_C32(0xe972017c), + SPH_C32(0x660d0000), SPH_C32(0xf50a0000), SPH_C32(0x5f8d0000), + SPH_C32(0xd12a4975), SPH_C32(0x5b710657), SPH_C32(0xf9bacf4f), + SPH_C32(0x280b319a) }, + { SPH_C32(0x2bf401e0), SPH_C32(0x60640000), SPH_C32(0xb1ab0000), + SPH_C32(0xbc980000), SPH_C32(0xefeb0a94), SPH_C32(0xc894f143), + SPH_C32(0x5e0d273b), SPH_C32(0x5d6b3122), SPH_C32(0x1ceb0120), + SPH_C32(0x0b6a0000), SPH_C32(0x067e0000), SPH_C32(0xd73d0000), + SPH_C32(0xb01c159f), SPH_C32(0xcf9e9b5a), SPH_C32(0xd25cc5ca), + SPH_C32(0xebbc06c5) }, + { SPH_C32(0xdd7401e5), SPH_C32(0x5427c000), SPH_C32(0x95ac0000), + SPH_C32(0x33a50000), SPH_C32(0xcedc316f), SPH_C32(0xc22c24ed), + SPH_C32(0x93c8ac22), SPH_C32(0x8afe8b13), SPH_C32(0xba940121), + SPH_C32(0x7a5d8000), SPH_C32(0x1f820000), SPH_C32(0x41e60000), + SPH_C32(0x8a977862), SPH_C32(0x245435a9), SPH_C32(0xfe318245), + SPH_C32(0x47326a4d) }, + { SPH_C32(0x8d8b01e1), SPH_C32(0x11538000), SPH_C32(0xa8570000), + SPH_C32(0x2a430000), SPH_C32(0xd5606769), SPH_C32(0x235e5fb0), + SPH_C32(0x726060b4), SPH_C32(0xf1e55daa), SPH_C32(0x4c140124), + SPH_C32(0x4e1e4000), SPH_C32(0x3b850000), SPH_C32(0xcedb0000), + SPH_C32(0xaba04399), SPH_C32(0x2eece007), SPH_C32(0x33f4095c), + SPH_C32(0x90a7d07c) }, + { SPH_C32(0x7b0b01e4), SPH_C32(0x25104000), SPH_C32(0x8c500000), + SPH_C32(0xa57e0000), SPH_C32(0xf4575c92), SPH_C32(0x29e68a1e), + SPH_C32(0xbfa5ebad), SPH_C32(0x2670e79b), SPH_C32(0xea6b0125), + SPH_C32(0x3f29c000), SPH_C32(0x22790000), SPH_C32(0x58000000), + SPH_C32(0x912b2e64), SPH_C32(0xc5264ef4), SPH_C32(0x1f994ed3), + SPH_C32(0x3c29bcf4) }, + { SPH_C32(0xdc8101e9), SPH_C32(0xaf58c000), SPH_C32(0x727d0000), + SPH_C32(0xb80a0000), SPH_C32(0xed7e133d), SPH_C32(0x307cc7f9), + SPH_C32(0x248ad675), SPH_C32(0xc37da938), SPH_C32(0xc8810120), + SPH_C32(0x86a2c000), SPH_C32(0xa3d10000), SPH_C32(0x9d140000), + SPH_C32(0x4c5257e5), SPH_C32(0x062a1d36), SPH_C32(0x4a6a53ce), + SPH_C32(0x1cfac5e5) }, + { SPH_C32(0x2a0101ec), SPH_C32(0x9b1b0000), SPH_C32(0x567a0000), + SPH_C32(0x37370000), SPH_C32(0xcc4928c6), SPH_C32(0x3ac41257), + SPH_C32(0xe94f5d6c), SPH_C32(0x14e81309), SPH_C32(0x6efe0121), + SPH_C32(0xf7954000), SPH_C32(0xba2d0000), SPH_C32(0x0bcf0000), + SPH_C32(0x76d93a18), SPH_C32(0xede0b3c5), SPH_C32(0x66071441), + SPH_C32(0xb074a96d) }, + { SPH_C32(0x7afe01e8), SPH_C32(0xde6f4000), SPH_C32(0x6b810000), + SPH_C32(0x2ed10000), SPH_C32(0xd7f57ec0), SPH_C32(0xdbb6690a), + SPH_C32(0x08e791fa), SPH_C32(0x6ff3c5b0), SPH_C32(0x987e0124), + SPH_C32(0xc3d68000), SPH_C32(0x9e2a0000), SPH_C32(0x84f20000), + SPH_C32(0x57ee01e3), SPH_C32(0xe758666b), SPH_C32(0xabc29f58), + SPH_C32(0x67e1135c) }, + { SPH_C32(0x8c7e01ed), SPH_C32(0xea2c8000), SPH_C32(0x4f860000), + SPH_C32(0xa1ec0000), SPH_C32(0xf6c2453b), SPH_C32(0xd10ebca4), + SPH_C32(0xc5221ae3), SPH_C32(0xb8667f81), SPH_C32(0x3e010125), + SPH_C32(0xb2e10000), SPH_C32(0x87d60000), SPH_C32(0x12290000), + SPH_C32(0x6d656c1e), SPH_C32(0x0c92c898), SPH_C32(0x87afd8d7), + SPH_C32(0xcb6f7fd4) }, + { SPH_C32(0xff9e01e0), SPH_C32(0xedacc000), SPH_C32(0x14040000), + SPH_C32(0xf6b10000), SPH_C32(0x13a548ee), SPH_C32(0x0120772f), + SPH_C32(0xc63bb13f), SPH_C32(0xaa2df202), SPH_C32(0x3ff40129), + SPH_C32(0x499e0000), SPH_C32(0x60070000), SPH_C32(0x99860000), + SPH_C32(0x4ec74e4c), SPH_C32(0xfec22b8c), SPH_C32(0x30eda280), + SPH_C32(0x82ec5dff) }, + { SPH_C32(0x091e01e5), SPH_C32(0xd9ef0000), SPH_C32(0x30030000), + SPH_C32(0x798c0000), SPH_C32(0x32927315), SPH_C32(0x0b98a281), + SPH_C32(0x0bfe3a26), SPH_C32(0x7db84833), SPH_C32(0x998b0128), + SPH_C32(0x38a98000), SPH_C32(0x79fb0000), SPH_C32(0x0f5d0000), + SPH_C32(0x744c23b1), SPH_C32(0x1508857f), SPH_C32(0x1c80e50f), + SPH_C32(0x2e623177) }, + { SPH_C32(0x59e101e1), SPH_C32(0x9c9b4000), SPH_C32(0x0df80000), + SPH_C32(0x606a0000), SPH_C32(0x292e2513), SPH_C32(0xeaead9dc), + SPH_C32(0xea56f6b0), SPH_C32(0x06a39e8a), SPH_C32(0x6f0b012d), + SPH_C32(0x0cea4000), SPH_C32(0x5dfc0000), SPH_C32(0x80600000), + SPH_C32(0x557b184a), SPH_C32(0x1fb050d1), SPH_C32(0xd1456e16), + SPH_C32(0xf9f78b46) }, + { SPH_C32(0xaf6101e4), SPH_C32(0xa8d88000), SPH_C32(0x29ff0000), + SPH_C32(0xef570000), SPH_C32(0x08191ee8), SPH_C32(0xe0520c72), + SPH_C32(0x27937da9), SPH_C32(0xd13624bb), SPH_C32(0xc974012c), + SPH_C32(0x7dddc000), SPH_C32(0x44000000), SPH_C32(0x16bb0000), + SPH_C32(0x6ff075b7), SPH_C32(0xf47afe22), SPH_C32(0xfd282999), + SPH_C32(0x5579e7ce) }, + { SPH_C32(0x08eb01e9), SPH_C32(0x22900000), SPH_C32(0xd7d20000), + SPH_C32(0xf2230000), SPH_C32(0x11305147), SPH_C32(0xf9c84195), + SPH_C32(0xbcbc4071), SPH_C32(0x343b6a18), SPH_C32(0xeb9e0129), + SPH_C32(0xc456c000), SPH_C32(0xc5a80000), SPH_C32(0xd3af0000), + SPH_C32(0xb2890c36), SPH_C32(0x3776ade0), SPH_C32(0xa8db3484), + SPH_C32(0x75aa9edf) }, + { SPH_C32(0xfe6b01ec), SPH_C32(0x16d3c000), SPH_C32(0xf3d50000), + SPH_C32(0x7d1e0000), SPH_C32(0x30076abc), SPH_C32(0xf370943b), + SPH_C32(0x7179cb68), SPH_C32(0xe3aed029), SPH_C32(0x4de10128), + SPH_C32(0xb5614000), SPH_C32(0xdc540000), SPH_C32(0x45740000), + SPH_C32(0x880261cb), SPH_C32(0xdcbc0313), SPH_C32(0x84b6730b), + SPH_C32(0xd924f257) }, + { SPH_C32(0xae9401e8), SPH_C32(0x53a78000), SPH_C32(0xce2e0000), + SPH_C32(0x64f80000), SPH_C32(0x2bbb3cba), SPH_C32(0x1202ef66), + SPH_C32(0x90d107fe), SPH_C32(0x98b50690), SPH_C32(0xbb61012d), + SPH_C32(0x81228000), SPH_C32(0xf8530000), SPH_C32(0xca490000), + SPH_C32(0xa9355a30), SPH_C32(0xd604d6bd), SPH_C32(0x4973f812), + SPH_C32(0x0eb14866) }, + { SPH_C32(0x581401ed), SPH_C32(0x67e44000), SPH_C32(0xea290000), + SPH_C32(0xebc50000), SPH_C32(0x0a8c0741), SPH_C32(0x18ba3ac8), + SPH_C32(0x5d148ce7), SPH_C32(0x4f20bca1), SPH_C32(0x1d1e012c), + SPH_C32(0xf0150000), SPH_C32(0xe1af0000), SPH_C32(0x5c920000), + SPH_C32(0x93be37cd), SPH_C32(0x3dce784e), SPH_C32(0x651ebf9d), + SPH_C32(0xa23f24ee) }, + { SPH_C32(0xa8dc0140), SPH_C32(0x07260000), SPH_C32(0x50bc0000), + SPH_C32(0x8b930000), SPH_C32(0x24480aa0), SPH_C32(0xf4a0637f), + SPH_C32(0xc96a9af7), SPH_C32(0x1868519d), SPH_C32(0x6baf01d0), + SPH_C32(0xfa300000), SPH_C32(0xf3cc0000), SPH_C32(0xe3290000), + SPH_C32(0x392b6b13), SPH_C32(0x9515777f), SPH_C32(0xd99f08d4), + SPH_C32(0x248b730e) }, + { SPH_C32(0x5e5c0145), SPH_C32(0x3365c000), SPH_C32(0x74bb0000), + SPH_C32(0x04ae0000), SPH_C32(0x057f315b), SPH_C32(0xfe18b6d1), + SPH_C32(0x04af11ee), SPH_C32(0xcffdebac), SPH_C32(0xcdd001d1), + SPH_C32(0x8b078000), SPH_C32(0xea300000), SPH_C32(0x75f20000), + SPH_C32(0x03a006ee), SPH_C32(0x7edfd98c), SPH_C32(0xf5f24f5b), + SPH_C32(0x88051f86) }, + { SPH_C32(0x0ea30141), SPH_C32(0x76118000), SPH_C32(0x49400000), + SPH_C32(0x1d480000), SPH_C32(0x1ec3675d), SPH_C32(0x1f6acd8c), + SPH_C32(0xe507dd78), SPH_C32(0xb4e63d15), SPH_C32(0x3b5001d4), + SPH_C32(0xbf444000), SPH_C32(0xce370000), SPH_C32(0xfacf0000), + SPH_C32(0x22973d15), SPH_C32(0x74670c22), SPH_C32(0x3837c442), + SPH_C32(0x5f90a5b7) }, + { SPH_C32(0xf8230144), SPH_C32(0x42524000), SPH_C32(0x6d470000), + SPH_C32(0x92750000), SPH_C32(0x3ff45ca6), SPH_C32(0x15d21822), + SPH_C32(0x28c25661), SPH_C32(0x63738724), SPH_C32(0x9d2f01d5), + SPH_C32(0xce73c000), SPH_C32(0xd7cb0000), SPH_C32(0x6c140000), + SPH_C32(0x181c50e8), SPH_C32(0x9fada2d1), SPH_C32(0x145a83cd), + SPH_C32(0xf31ec93f) }, + { SPH_C32(0x5fa90149), SPH_C32(0xc81ac000), SPH_C32(0x936a0000), + SPH_C32(0x8f010000), SPH_C32(0x26dd1309), SPH_C32(0x0c4855c5), + SPH_C32(0xb3ed6bb9), SPH_C32(0x867ec987), SPH_C32(0xbfc501d0), + SPH_C32(0x77f8c000), SPH_C32(0x56630000), SPH_C32(0xa9000000), + SPH_C32(0xc5652969), SPH_C32(0x5ca1f113), SPH_C32(0x41a99ed0), + SPH_C32(0xd3cdb02e) }, + { SPH_C32(0xa929014c), SPH_C32(0xfc590000), SPH_C32(0xb76d0000), + SPH_C32(0x003c0000), SPH_C32(0x07ea28f2), SPH_C32(0x06f0806b), + SPH_C32(0x7e28e0a0), SPH_C32(0x51eb73b6), SPH_C32(0x19ba01d1), + SPH_C32(0x06cf4000), SPH_C32(0x4f9f0000), SPH_C32(0x3fdb0000), + SPH_C32(0xffee4494), SPH_C32(0xb76b5fe0), SPH_C32(0x6dc4d95f), + SPH_C32(0x7f43dca6) }, + { SPH_C32(0xf9d60148), SPH_C32(0xb92d4000), SPH_C32(0x8a960000), + SPH_C32(0x19da0000), SPH_C32(0x1c567ef4), SPH_C32(0xe782fb36), + SPH_C32(0x9f802c36), SPH_C32(0x2af0a50f), SPH_C32(0xef3a01d4), + SPH_C32(0x328c8000), SPH_C32(0x6b980000), SPH_C32(0xb0e60000), + SPH_C32(0xded97f6f), SPH_C32(0xbdd38a4e), SPH_C32(0xa0015246), + SPH_C32(0xa8d66697) }, + { SPH_C32(0x0f56014d), SPH_C32(0x8d6e8000), SPH_C32(0xae910000), + SPH_C32(0x96e70000), SPH_C32(0x3d61450f), SPH_C32(0xed3a2e98), + SPH_C32(0x5245a72f), SPH_C32(0xfd651f3e), SPH_C32(0x494501d5), + SPH_C32(0x43bb0000), SPH_C32(0x72640000), SPH_C32(0x263d0000), + SPH_C32(0xe4521292), SPH_C32(0x561924bd), SPH_C32(0x8c6c15c9), + SPH_C32(0x04580a1f) }, + { SPH_C32(0x7cb60140), SPH_C32(0x8aeec000), SPH_C32(0xf5130000), + SPH_C32(0xc1ba0000), SPH_C32(0xd80648da), SPH_C32(0x3d14e513), + SPH_C32(0x515c0cf3), SPH_C32(0xef2e92bd), SPH_C32(0x48b001d9), + SPH_C32(0xb8c40000), SPH_C32(0x95b50000), SPH_C32(0xad920000), + SPH_C32(0xc7f030c0), SPH_C32(0xa449c7a9), SPH_C32(0x3b2e6f9e), + SPH_C32(0x4ddb2834) }, + { SPH_C32(0x8a360145), SPH_C32(0xbead0000), SPH_C32(0xd1140000), + SPH_C32(0x4e870000), SPH_C32(0xf9317321), SPH_C32(0x37ac30bd), + SPH_C32(0x9c9987ea), SPH_C32(0x38bb288c), SPH_C32(0xeecf01d8), + SPH_C32(0xc9f38000), SPH_C32(0x8c490000), SPH_C32(0x3b490000), + SPH_C32(0xfd7b5d3d), SPH_C32(0x4f83695a), SPH_C32(0x17432811), + SPH_C32(0xe15544bc) }, + { SPH_C32(0xdac90141), SPH_C32(0xfbd94000), SPH_C32(0xecef0000), + SPH_C32(0x57610000), SPH_C32(0xe28d2527), SPH_C32(0xd6de4be0), + SPH_C32(0x7d314b7c), SPH_C32(0x43a0fe35), SPH_C32(0x184f01dd), + SPH_C32(0xfdb04000), SPH_C32(0xa84e0000), SPH_C32(0xb4740000), + SPH_C32(0xdc4c66c6), SPH_C32(0x453bbcf4), SPH_C32(0xda86a308), + SPH_C32(0x36c0fe8d) }, + { SPH_C32(0x2c490144), SPH_C32(0xcf9a8000), SPH_C32(0xc8e80000), + SPH_C32(0xd85c0000), SPH_C32(0xc3ba1edc), SPH_C32(0xdc669e4e), + SPH_C32(0xb0f4c065), SPH_C32(0x94354404), SPH_C32(0xbe3001dc), + SPH_C32(0x8c87c000), SPH_C32(0xb1b20000), SPH_C32(0x22af0000), + SPH_C32(0xe6c70b3b), SPH_C32(0xaef11207), SPH_C32(0xf6ebe487), + SPH_C32(0x9a4e9205) }, + { SPH_C32(0x8bc30149), SPH_C32(0x45d20000), SPH_C32(0x36c50000), + SPH_C32(0xc5280000), SPH_C32(0xda935173), SPH_C32(0xc5fcd3a9), + SPH_C32(0x2bdbfdbd), SPH_C32(0x71380aa7), SPH_C32(0x9cda01d9), + SPH_C32(0x350cc000), SPH_C32(0x301a0000), SPH_C32(0xe7bb0000), + SPH_C32(0x3bbe72ba), SPH_C32(0x6dfd41c5), SPH_C32(0xa318f99a), + SPH_C32(0xba9deb14) }, + { SPH_C32(0x7d43014c), SPH_C32(0x7191c000), SPH_C32(0x12c20000), + SPH_C32(0x4a150000), SPH_C32(0xfba46a88), SPH_C32(0xcf440607), + SPH_C32(0xe61e76a4), SPH_C32(0xa6adb096), SPH_C32(0x3aa501d8), + SPH_C32(0x443b4000), SPH_C32(0x29e60000), SPH_C32(0x71600000), + SPH_C32(0x01351f47), SPH_C32(0x8637ef36), SPH_C32(0x8f75be15), + SPH_C32(0x1613879c) }, + { SPH_C32(0x2dbc0148), SPH_C32(0x34e58000), SPH_C32(0x2f390000), + SPH_C32(0x53f30000), SPH_C32(0xe0183c8e), SPH_C32(0x2e367d5a), + SPH_C32(0x07b6ba32), SPH_C32(0xddb6662f), SPH_C32(0xcc2501dd), + SPH_C32(0x70788000), SPH_C32(0x0de10000), SPH_C32(0xfe5d0000), + SPH_C32(0x200224bc), SPH_C32(0x8c8f3a98), SPH_C32(0x42b0350c), + SPH_C32(0xc1863dad) }, + { SPH_C32(0xdb3c014d), SPH_C32(0x00a64000), SPH_C32(0x0b3e0000), + SPH_C32(0xdcce0000), SPH_C32(0xc12f0775), SPH_C32(0x248ea8f4), + SPH_C32(0xca73312b), SPH_C32(0x0a23dc1e), SPH_C32(0x6a5a01dc), + SPH_C32(0x014f0000), SPH_C32(0x141d0000), SPH_C32(0x68860000), + SPH_C32(0x1a894941), SPH_C32(0x6745946b), SPH_C32(0x6edd7283), + SPH_C32(0x6d085125) }, + { SPH_C32(0xdf9801b0), SPH_C32(0xf67c0000), SPH_C32(0xa50e0000), + SPH_C32(0xbf870000), SPH_C32(0xad7f742c), SPH_C32(0xae2b8f5a), + SPH_C32(0xc2a957e9), SPH_C32(0xd75f2456), SPH_C32(0x9fc30180), + SPH_C32(0x6c280000), SPH_C32(0xe7690000), SPH_C32(0xe0360000), + SPH_C32(0x7bbf15ab), SPH_C32(0xf3aa0966), SPH_C32(0x453b7806), + SPH_C32(0xaebf667a) }, + { SPH_C32(0x291801b5), SPH_C32(0xc23fc000), SPH_C32(0x81090000), + SPH_C32(0x30ba0000), SPH_C32(0x8c484fd7), SPH_C32(0xa4935af4), + SPH_C32(0x0f6cdcf0), SPH_C32(0x00ca9e67), SPH_C32(0x39bc0181), + SPH_C32(0x1d1f8000), SPH_C32(0xfe950000), SPH_C32(0x76ed0000), + SPH_C32(0x41347856), SPH_C32(0x1860a795), SPH_C32(0x69563f89), + SPH_C32(0x02310af2) }, + { SPH_C32(0x79e701b1), SPH_C32(0x874b8000), SPH_C32(0xbcf20000), + SPH_C32(0x295c0000), SPH_C32(0x97f419d1), SPH_C32(0x45e121a9), + SPH_C32(0xeec41066), SPH_C32(0x7bd148de), SPH_C32(0xcf3c0184), + SPH_C32(0x295c4000), SPH_C32(0xda920000), SPH_C32(0xf9d00000), + SPH_C32(0x600343ad), SPH_C32(0x12d8723b), SPH_C32(0xa493b490), + SPH_C32(0xd5a4b0c3) }, + { SPH_C32(0x8f6701b4), SPH_C32(0xb3084000), SPH_C32(0x98f50000), + SPH_C32(0xa6610000), SPH_C32(0xb6c3222a), SPH_C32(0x4f59f407), + SPH_C32(0x23019b7f), SPH_C32(0xac44f2ef), SPH_C32(0x69430185), + SPH_C32(0x586bc000), SPH_C32(0xc36e0000), SPH_C32(0x6f0b0000), + SPH_C32(0x5a882e50), SPH_C32(0xf912dcc8), SPH_C32(0x88fef31f), + SPH_C32(0x792adc4b) }, + { SPH_C32(0x28ed01b9), SPH_C32(0x3940c000), SPH_C32(0x66d80000), + SPH_C32(0xbb150000), SPH_C32(0xafea6d85), SPH_C32(0x56c3b9e0), + SPH_C32(0xb82ea6a7), SPH_C32(0x4949bc4c), SPH_C32(0x4ba90180), + SPH_C32(0xe1e0c000), SPH_C32(0x42c60000), SPH_C32(0xaa1f0000), + SPH_C32(0x87f157d1), SPH_C32(0x3a1e8f0a), SPH_C32(0xdd0dee02), + SPH_C32(0x59f9a55a) }, + { SPH_C32(0xde6d01bc), SPH_C32(0x0d030000), SPH_C32(0x42df0000), + SPH_C32(0x34280000), SPH_C32(0x8edd567e), SPH_C32(0x5c7b6c4e), + SPH_C32(0x75eb2dbe), SPH_C32(0x9edc067d), SPH_C32(0xedd60181), + SPH_C32(0x90d74000), SPH_C32(0x5b3a0000), SPH_C32(0x3cc40000), + SPH_C32(0xbd7a3a2c), SPH_C32(0xd1d421f9), SPH_C32(0xf160a98d), + SPH_C32(0xf577c9d2) }, + { SPH_C32(0x8e9201b8), SPH_C32(0x48774000), SPH_C32(0x7f240000), + SPH_C32(0x2dce0000), SPH_C32(0x95610078), SPH_C32(0xbd091713), + SPH_C32(0x9443e128), SPH_C32(0xe5c7d0c4), SPH_C32(0x1b560184), + SPH_C32(0xa4948000), SPH_C32(0x7f3d0000), SPH_C32(0xb3f90000), + SPH_C32(0x9c4d01d7), SPH_C32(0xdb6cf457), SPH_C32(0x3ca52294), + SPH_C32(0x22e273e3) }, + { SPH_C32(0x781201bd), SPH_C32(0x7c348000), SPH_C32(0x5b230000), + SPH_C32(0xa2f30000), SPH_C32(0xb4563b83), SPH_C32(0xb7b1c2bd), + SPH_C32(0x59866a31), SPH_C32(0x32526af5), SPH_C32(0xbd290185), + SPH_C32(0xd5a30000), SPH_C32(0x66c10000), SPH_C32(0x25220000), + SPH_C32(0xa6c66c2a), SPH_C32(0x30a65aa4), SPH_C32(0x10c8651b), + SPH_C32(0x8e6c1f6b) }, + { SPH_C32(0x0bf201b0), SPH_C32(0x7bb4c000), SPH_C32(0x00a10000), + SPH_C32(0xf5ae0000), SPH_C32(0x51313656), SPH_C32(0x679f0936), + SPH_C32(0x5a9fc1ed), SPH_C32(0x2019e776), SPH_C32(0xbcdc0189), + SPH_C32(0x2edc0000), SPH_C32(0x81100000), SPH_C32(0xae8d0000), + SPH_C32(0x85644e78), SPH_C32(0xc2f6b9b0), SPH_C32(0xa78a1f4c), + SPH_C32(0xc7ef3d40) }, + { SPH_C32(0xfd7201b5), SPH_C32(0x4ff70000), SPH_C32(0x24a60000), + SPH_C32(0x7a930000), SPH_C32(0x70060dad), SPH_C32(0x6d27dc98), + SPH_C32(0x975a4af4), SPH_C32(0xf78c5d47), SPH_C32(0x1aa30188), + SPH_C32(0x5feb8000), SPH_C32(0x98ec0000), SPH_C32(0x38560000), + SPH_C32(0xbfef2385), SPH_C32(0x293c1743), SPH_C32(0x8be758c3), + SPH_C32(0x6b6151c8) }, + { SPH_C32(0xad8d01b1), SPH_C32(0x0a834000), SPH_C32(0x195d0000), + SPH_C32(0x63750000), SPH_C32(0x6bba5bab), SPH_C32(0x8c55a7c5), + SPH_C32(0x76f28662), SPH_C32(0x8c978bfe), SPH_C32(0xec23018d), + SPH_C32(0x6ba84000), SPH_C32(0xbceb0000), SPH_C32(0xb76b0000), + SPH_C32(0x9ed8187e), SPH_C32(0x2384c2ed), SPH_C32(0x4622d3da), + SPH_C32(0xbcf4ebf9) }, + { SPH_C32(0x5b0d01b4), SPH_C32(0x3ec08000), SPH_C32(0x3d5a0000), + SPH_C32(0xec480000), SPH_C32(0x4a8d6050), SPH_C32(0x86ed726b), + SPH_C32(0xbb370d7b), SPH_C32(0x5b0231cf), SPH_C32(0x4a5c018c), + SPH_C32(0x1a9fc000), SPH_C32(0xa5170000), SPH_C32(0x21b00000), + SPH_C32(0xa4537583), SPH_C32(0xc84e6c1e), SPH_C32(0x6a4f9455), + SPH_C32(0x107a8771) }, + { SPH_C32(0xfc8701b9), SPH_C32(0xb4880000), SPH_C32(0xc3770000), + SPH_C32(0xf13c0000), SPH_C32(0x53a42fff), SPH_C32(0x9f773f8c), + SPH_C32(0x201830a3), SPH_C32(0xbe0f7f6c), SPH_C32(0x68b60189), + SPH_C32(0xa314c000), SPH_C32(0x24bf0000), SPH_C32(0xe4a40000), + SPH_C32(0x792a0c02), SPH_C32(0x0b423fdc), SPH_C32(0x3fbc8948), + SPH_C32(0x30a9fe60) }, + { SPH_C32(0x0a0701bc), SPH_C32(0x80cbc000), SPH_C32(0xe7700000), + SPH_C32(0x7e010000), SPH_C32(0x72931404), SPH_C32(0x95cfea22), + SPH_C32(0xedddbbba), SPH_C32(0x699ac55d), SPH_C32(0xcec90188), + SPH_C32(0xd2234000), SPH_C32(0x3d430000), SPH_C32(0x727f0000), + SPH_C32(0x43a161ff), SPH_C32(0xe088912f), SPH_C32(0x13d1cec7), + SPH_C32(0x9c2792e8) }, + { SPH_C32(0x5af801b8), SPH_C32(0xc5bf8000), SPH_C32(0xda8b0000), + SPH_C32(0x67e70000), SPH_C32(0x692f4202), SPH_C32(0x74bd917f), + SPH_C32(0x0c75772c), SPH_C32(0x128113e4), SPH_C32(0x3849018d), + SPH_C32(0xe6608000), SPH_C32(0x19440000), SPH_C32(0xfd420000), + SPH_C32(0x62965a04), SPH_C32(0xea304481), SPH_C32(0xde1445de), + SPH_C32(0x4bb228d9) }, + { SPH_C32(0xac7801bd), SPH_C32(0xf1fc4000), SPH_C32(0xfe8c0000), + SPH_C32(0xe8da0000), SPH_C32(0x481879f9), SPH_C32(0x7e0544d1), + SPH_C32(0xc1b0fc35), SPH_C32(0xc514a9d5), SPH_C32(0x9e36018c), + SPH_C32(0x97570000), SPH_C32(0x00b80000), SPH_C32(0x6b990000), + SPH_C32(0x581d37f9), SPH_C32(0x01faea72), SPH_C32(0xf2790251), + SPH_C32(0xe73c4451) } +}; + +static const sph_u32 T512_16[256][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x0c720000), SPH_C32(0x49e50f00), SPH_C32(0x42790000), + SPH_C32(0x5cea0000), SPH_C32(0x33aa301a), SPH_C32(0x15822514), + SPH_C32(0x95a34b7b), SPH_C32(0xb44b0090), SPH_C32(0xfe220000), + SPH_C32(0xa7580500), SPH_C32(0x25d10000), SPH_C32(0xf7600000), + SPH_C32(0x893178da), SPH_C32(0x1fd4f860), SPH_C32(0x4ed0a315), + SPH_C32(0xa123ff9f) }, + { SPH_C32(0xfe220000), SPH_C32(0xa7580500), SPH_C32(0x25d10000), + SPH_C32(0xf7600000), SPH_C32(0x893178da), SPH_C32(0x1fd4f860), + SPH_C32(0x4ed0a315), SPH_C32(0xa123ff9f), SPH_C32(0xf2500000), + SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), SPH_C32(0xab8a0000), + SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), SPH_C32(0xdb73e86e), + SPH_C32(0x1568ff0f) }, + { SPH_C32(0xf2500000), SPH_C32(0xeebd0a00), SPH_C32(0x67a80000), + SPH_C32(0xab8a0000), SPH_C32(0xba9b48c0), SPH_C32(0x0a56dd74), + SPH_C32(0xdb73e86e), SPH_C32(0x1568ff0f), SPH_C32(0x0c720000), + SPH_C32(0x49e50f00), SPH_C32(0x42790000), SPH_C32(0x5cea0000), + SPH_C32(0x33aa301a), SPH_C32(0x15822514), SPH_C32(0x95a34b7b), + SPH_C32(0xb44b0090) }, + { SPH_C32(0x45180000), SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), + SPH_C32(0x3b480000), SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), + SPH_C32(0x16bca6b0), SPH_C32(0xdf33f4df), SPH_C32(0xb83d0000), + SPH_C32(0x16710600), SPH_C32(0x379a0000), SPH_C32(0xf5b10000), + SPH_C32(0x228161ac), SPH_C32(0xae48f145), SPH_C32(0x66241616), + SPH_C32(0xc5c1eb3e) }, + { SPH_C32(0x496a0000), SPH_C32(0xec501800), SPH_C32(0xbb130000), + SPH_C32(0x67a20000), SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), + SPH_C32(0x831fedcb), SPH_C32(0x6b78f44f), SPH_C32(0x461f0000), + SPH_C32(0xb1290300), SPH_C32(0x124b0000), SPH_C32(0x02d10000), + SPH_C32(0xabb01976), SPH_C32(0xb19c0925), SPH_C32(0x28f4b503), + SPH_C32(0x64e214a1) }, + { SPH_C32(0xbb3a0000), SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), + SPH_C32(0xcc280000), SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), + SPH_C32(0x586c05a5), SPH_C32(0x7e100b40), SPH_C32(0x4a6d0000), + SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), SPH_C32(0x5e3b0000), + SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), SPH_C32(0xbd57fe78), + SPH_C32(0xd0a91431) }, + { SPH_C32(0xb7480000), SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), + SPH_C32(0x90c20000), SPH_C32(0xa4575cec), SPH_C32(0x294548a2), + SPH_C32(0xcdcf4ede), SPH_C32(0xca5b0bd0), SPH_C32(0xb44f0000), + SPH_C32(0x5f940900), SPH_C32(0x75e30000), SPH_C32(0xa95b0000), + SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), SPH_C32(0xf3875d6d), + SPH_C32(0x718aebae) }, + { SPH_C32(0xb83d0000), SPH_C32(0x16710600), SPH_C32(0x379a0000), + SPH_C32(0xf5b10000), SPH_C32(0x228161ac), SPH_C32(0xae48f145), + SPH_C32(0x66241616), SPH_C32(0xc5c1eb3e), SPH_C32(0xfd250000), + SPH_C32(0xb3c41100), SPH_C32(0xcef00000), SPH_C32(0xcef90000), + SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), SPH_C32(0x7098b0a6), + SPH_C32(0x1af21fe1) }, + { SPH_C32(0xb44f0000), SPH_C32(0x5f940900), SPH_C32(0x75e30000), + SPH_C32(0xa95b0000), SPH_C32(0x112b51b6), SPH_C32(0xbbcad451), + SPH_C32(0xf3875d6d), SPH_C32(0x718aebae), SPH_C32(0x03070000), + SPH_C32(0x149c1400), SPH_C32(0xeb210000), SPH_C32(0x39990000), + SPH_C32(0xb57c0d5a), SPH_C32(0x928f9cf3), SPH_C32(0x3e4813b3), + SPH_C32(0xbbd1e07e) }, + { SPH_C32(0x461f0000), SPH_C32(0xb1290300), SPH_C32(0x124b0000), + SPH_C32(0x02d10000), SPH_C32(0xabb01976), SPH_C32(0xb19c0925), + SPH_C32(0x28f4b503), SPH_C32(0x64e214a1), SPH_C32(0x0f750000), + SPH_C32(0x5d791b00), SPH_C32(0xa9580000), SPH_C32(0x65730000), + SPH_C32(0x86d63d40), SPH_C32(0x870db9e7), SPH_C32(0xabeb58c8), + SPH_C32(0x0f9ae0ee) }, + { SPH_C32(0x4a6d0000), SPH_C32(0xf8cc0c00), SPH_C32(0x50320000), + SPH_C32(0x5e3b0000), SPH_C32(0x981a296c), SPH_C32(0xa41e2c31), + SPH_C32(0xbd57fe78), SPH_C32(0xd0a91431), SPH_C32(0xf1570000), + SPH_C32(0xfa211e00), SPH_C32(0x8c890000), SPH_C32(0x92130000), + SPH_C32(0x0fe7459a), SPH_C32(0x98d94187), SPH_C32(0xe53bfbdd), + SPH_C32(0xaeb91f71) }, + { SPH_C32(0xfd250000), SPH_C32(0xb3c41100), SPH_C32(0xcef00000), + SPH_C32(0xcef90000), SPH_C32(0x3c4d7580), SPH_C32(0x8d5b6493), + SPH_C32(0x7098b0a6), SPH_C32(0x1af21fe1), SPH_C32(0x45180000), + SPH_C32(0xa5b51700), SPH_C32(0xf96a0000), SPH_C32(0x3b480000), + SPH_C32(0x1ecc142c), SPH_C32(0x231395d6), SPH_C32(0x16bca6b0), + SPH_C32(0xdf33f4df) }, + { SPH_C32(0xf1570000), SPH_C32(0xfa211e00), SPH_C32(0x8c890000), + SPH_C32(0x92130000), SPH_C32(0x0fe7459a), SPH_C32(0x98d94187), + SPH_C32(0xe53bfbdd), SPH_C32(0xaeb91f71), SPH_C32(0xbb3a0000), + SPH_C32(0x02ed1200), SPH_C32(0xdcbb0000), SPH_C32(0xcc280000), + SPH_C32(0x97fd6cf6), SPH_C32(0x3cc76db6), SPH_C32(0x586c05a5), + SPH_C32(0x7e100b40) }, + { SPH_C32(0x03070000), SPH_C32(0x149c1400), SPH_C32(0xeb210000), + SPH_C32(0x39990000), SPH_C32(0xb57c0d5a), SPH_C32(0x928f9cf3), + SPH_C32(0x3e4813b3), SPH_C32(0xbbd1e07e), SPH_C32(0xb7480000), + SPH_C32(0x4b081d00), SPH_C32(0x9ec20000), SPH_C32(0x90c20000), + SPH_C32(0xa4575cec), SPH_C32(0x294548a2), SPH_C32(0xcdcf4ede), + SPH_C32(0xca5b0bd0) }, + { SPH_C32(0x0f750000), SPH_C32(0x5d791b00), SPH_C32(0xa9580000), + SPH_C32(0x65730000), SPH_C32(0x86d63d40), SPH_C32(0x870db9e7), + SPH_C32(0xabeb58c8), SPH_C32(0x0f9ae0ee), SPH_C32(0x496a0000), + SPH_C32(0xec501800), SPH_C32(0xbb130000), SPH_C32(0x67a20000), + SPH_C32(0x2d662436), SPH_C32(0x3691b0c2), SPH_C32(0x831fedcb), + SPH_C32(0x6b78f44f) }, + { SPH_C32(0x75a40000), SPH_C32(0xc28b2700), SPH_C32(0x94a40000), + SPH_C32(0x90f50000), SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), + SPH_C32(0x1767c483), SPH_C32(0xaedf667e), SPH_C32(0xd1660000), + SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), SPH_C32(0xf6940000), + SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), SPH_C32(0xb4431b17), + SPH_C32(0x857f3c2b) }, + { SPH_C32(0x79d60000), SPH_C32(0x8b6e2800), SPH_C32(0xd6dd0000), + SPH_C32(0xcc1f0000), SPH_C32(0xc8d267fa), SPH_C32(0x5c4c2eba), + SPH_C32(0x82c48ff8), SPH_C32(0x1a9466ee), SPH_C32(0x2f440000), + SPH_C32(0xbce40600), SPH_C32(0xbb3d0000), SPH_C32(0x01f40000), + SPH_C32(0x8a333dfd), SPH_C32(0xd0a40492), SPH_C32(0xfa93b802), + SPH_C32(0x245cc3b4) }, + { SPH_C32(0x8b860000), SPH_C32(0x65d32200), SPH_C32(0xb1750000), + SPH_C32(0x67950000), SPH_C32(0x72492f3a), SPH_C32(0x561af3ce), + SPH_C32(0x59b76796), SPH_C32(0x0ffc99e1), SPH_C32(0x23360000), + SPH_C32(0xf5010900), SPH_C32(0xf9440000), SPH_C32(0x5d1e0000), + SPH_C32(0xb9990de7), SPH_C32(0xc5262186), SPH_C32(0x6f30f379), + SPH_C32(0x9017c324) }, + { SPH_C32(0x87f40000), SPH_C32(0x2c362d00), SPH_C32(0xf30c0000), + SPH_C32(0x3b7f0000), SPH_C32(0x41e31f20), SPH_C32(0x4398d6da), + SPH_C32(0xcc142ced), SPH_C32(0xbbb79971), SPH_C32(0xdd140000), + SPH_C32(0x52590c00), SPH_C32(0xdc950000), SPH_C32(0xaa7e0000), + SPH_C32(0x30a8753d), SPH_C32(0xdaf2d9e6), SPH_C32(0x21e0506c), + SPH_C32(0x31343cbb) }, + { SPH_C32(0x30bc0000), SPH_C32(0x673e3000), SPH_C32(0x6dce0000), + SPH_C32(0xabbd0000), SPH_C32(0xe5b443cc), SPH_C32(0x6add9e78), + SPH_C32(0x01db6233), SPH_C32(0x71ec92a1), SPH_C32(0x695b0000), + SPH_C32(0x0dcd0500), SPH_C32(0xa9760000), SPH_C32(0x03250000), + SPH_C32(0x2183248b), SPH_C32(0x61380db7), SPH_C32(0xd2670d01), + SPH_C32(0x40bed715) }, + { SPH_C32(0x3cce0000), SPH_C32(0x2edb3f00), SPH_C32(0x2fb70000), + SPH_C32(0xf7570000), SPH_C32(0xd61e73d6), SPH_C32(0x7f5fbb6c), + SPH_C32(0x94782948), SPH_C32(0xc5a79231), SPH_C32(0x97790000), + SPH_C32(0xaa950000), SPH_C32(0x8ca70000), SPH_C32(0xf4450000), + SPH_C32(0xa8b25c51), SPH_C32(0x7eecf5d7), SPH_C32(0x9cb7ae14), + SPH_C32(0xe19d288a) }, + { SPH_C32(0xce9e0000), SPH_C32(0xc0663500), SPH_C32(0x481f0000), + SPH_C32(0x5cdd0000), SPH_C32(0x6c853b16), SPH_C32(0x75096618), + SPH_C32(0x4f0bc126), SPH_C32(0xd0cf6d3e), SPH_C32(0x9b0b0000), + SPH_C32(0xe3700f00), SPH_C32(0xcede0000), SPH_C32(0xa8af0000), + SPH_C32(0x9b186c4b), SPH_C32(0x6b6ed0c3), SPH_C32(0x0914e56f), + SPH_C32(0x55d6281a) }, + { SPH_C32(0xc2ec0000), SPH_C32(0x89833a00), SPH_C32(0x0a660000), + SPH_C32(0x00370000), SPH_C32(0x5f2f0b0c), SPH_C32(0x608b430c), + SPH_C32(0xdaa88a5d), SPH_C32(0x64846dae), SPH_C32(0x65290000), + SPH_C32(0x44280a00), SPH_C32(0xeb0f0000), SPH_C32(0x5fcf0000), + SPH_C32(0x12291491), SPH_C32(0x74ba28a3), SPH_C32(0x47c4467a), + SPH_C32(0xf4f5d785) }, + { SPH_C32(0xcd990000), SPH_C32(0xd4fa2100), SPH_C32(0xa33e0000), + SPH_C32(0x65440000), SPH_C32(0xd9f9364c), SPH_C32(0xe786faeb), + SPH_C32(0x7143d295), SPH_C32(0x6b1e8d40), SPH_C32(0x2c430000), + SPH_C32(0xa8781200), SPH_C32(0x501c0000), SPH_C32(0x386d0000), + SPH_C32(0x3f4f30a7), SPH_C32(0x422b9861), SPH_C32(0xc4dbabb1), + SPH_C32(0x9f8d23ca) }, + { SPH_C32(0xc1eb0000), SPH_C32(0x9d1f2e00), SPH_C32(0xe1470000), + SPH_C32(0x39ae0000), SPH_C32(0xea530656), SPH_C32(0xf204dfff), + SPH_C32(0xe4e099ee), SPH_C32(0xdf558dd0), SPH_C32(0xd2610000), + SPH_C32(0x0f201700), SPH_C32(0x75cd0000), SPH_C32(0xcf0d0000), + SPH_C32(0xb67e487d), SPH_C32(0x5dff6001), SPH_C32(0x8a0b08a4), + SPH_C32(0x3eaedc55) }, + { SPH_C32(0x33bb0000), SPH_C32(0x73a22400), SPH_C32(0x86ef0000), + SPH_C32(0x92240000), SPH_C32(0x50c84e96), SPH_C32(0xf852028b), + SPH_C32(0x3f937180), SPH_C32(0xca3d72df), SPH_C32(0xde130000), + SPH_C32(0x46c51800), SPH_C32(0x37b40000), SPH_C32(0x93e70000), + SPH_C32(0x85d47867), SPH_C32(0x487d4515), SPH_C32(0x1fa843df), + SPH_C32(0x8ae5dcc5) }, + { SPH_C32(0x3fc90000), SPH_C32(0x3a472b00), SPH_C32(0xc4960000), + SPH_C32(0xcece0000), SPH_C32(0x63627e8c), SPH_C32(0xedd0279f), + SPH_C32(0xaa303afb), SPH_C32(0x7e76724f), SPH_C32(0x20310000), + SPH_C32(0xe19d1d00), SPH_C32(0x12650000), SPH_C32(0x64870000), + SPH_C32(0x0ce500bd), SPH_C32(0x57a9bd75), SPH_C32(0x5178e0ca), + SPH_C32(0x2bc6235a) }, + { SPH_C32(0x88810000), SPH_C32(0x714f3600), SPH_C32(0x5a540000), + SPH_C32(0x5e0c0000), SPH_C32(0xc7352260), SPH_C32(0xc4956f3d), + SPH_C32(0x67ff7425), SPH_C32(0xb42d799f), SPH_C32(0x947e0000), + SPH_C32(0xbe091400), SPH_C32(0x67860000), SPH_C32(0xcddc0000), + SPH_C32(0x1dce510b), SPH_C32(0xec636924), SPH_C32(0xa2ffbda7), + SPH_C32(0x5a4cc8f4) }, + { SPH_C32(0x84f30000), SPH_C32(0x38aa3900), SPH_C32(0x182d0000), + SPH_C32(0x02e60000), SPH_C32(0xf49f127a), SPH_C32(0xd1174a29), + SPH_C32(0xf25c3f5e), SPH_C32(0x0066790f), SPH_C32(0x6a5c0000), + SPH_C32(0x19511100), SPH_C32(0x42570000), SPH_C32(0x3abc0000), + SPH_C32(0x94ff29d1), SPH_C32(0xf3b79144), SPH_C32(0xec2f1eb2), + SPH_C32(0xfb6f376b) }, + { SPH_C32(0x76a30000), SPH_C32(0xd6173300), SPH_C32(0x7f850000), + SPH_C32(0xa96c0000), SPH_C32(0x4e045aba), SPH_C32(0xdb41975d), + SPH_C32(0x292fd730), SPH_C32(0x150e8600), SPH_C32(0x662e0000), + SPH_C32(0x50b41e00), SPH_C32(0x002e0000), SPH_C32(0x66560000), + SPH_C32(0xa75519cb), SPH_C32(0xe635b450), SPH_C32(0x798c55c9), + SPH_C32(0x4f2437fb) }, + { SPH_C32(0x7ad10000), SPH_C32(0x9ff23c00), SPH_C32(0x3dfc0000), + SPH_C32(0xf5860000), SPH_C32(0x7dae6aa0), SPH_C32(0xcec3b249), + SPH_C32(0xbc8c9c4b), SPH_C32(0xa1458690), SPH_C32(0x980c0000), + SPH_C32(0xf7ec1b00), SPH_C32(0x25ff0000), SPH_C32(0x91360000), + SPH_C32(0x2e646111), SPH_C32(0xf9e14c30), SPH_C32(0x375cf6dc), + SPH_C32(0xee07c864) }, + { SPH_C32(0xd1660000), SPH_C32(0x1bbc0300), SPH_C32(0x9eec0000), + SPH_C32(0xf6940000), SPH_C32(0x03024527), SPH_C32(0xcf70fcf2), + SPH_C32(0xb4431b17), SPH_C32(0x857f3c2b), SPH_C32(0xa4c20000), + SPH_C32(0xd9372400), SPH_C32(0x0a480000), SPH_C32(0x66610000), + SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), SPH_C32(0xa324df94), + SPH_C32(0x2ba05a55) }, + { SPH_C32(0xdd140000), SPH_C32(0x52590c00), SPH_C32(0xdc950000), + SPH_C32(0xaa7e0000), SPH_C32(0x30a8753d), SPH_C32(0xdaf2d9e6), + SPH_C32(0x21e0506c), SPH_C32(0x31343cbb), SPH_C32(0x5ae00000), + SPH_C32(0x7e6f2100), SPH_C32(0x2f990000), SPH_C32(0x91010000), + SPH_C32(0x714b6a1d), SPH_C32(0x996a0f3c), SPH_C32(0xedf47c81), + SPH_C32(0x8a83a5ca) }, + { SPH_C32(0x2f440000), SPH_C32(0xbce40600), SPH_C32(0xbb3d0000), + SPH_C32(0x01f40000), SPH_C32(0x8a333dfd), SPH_C32(0xd0a40492), + SPH_C32(0xfa93b802), SPH_C32(0x245cc3b4), SPH_C32(0x56920000), + SPH_C32(0x378a2e00), SPH_C32(0x6de00000), SPH_C32(0xcdeb0000), + SPH_C32(0x42e15a07), SPH_C32(0x8ce82a28), SPH_C32(0x785737fa), + SPH_C32(0x3ec8a55a) }, + { SPH_C32(0x23360000), SPH_C32(0xf5010900), SPH_C32(0xf9440000), + SPH_C32(0x5d1e0000), SPH_C32(0xb9990de7), SPH_C32(0xc5262186), + SPH_C32(0x6f30f379), SPH_C32(0x9017c324), SPH_C32(0xa8b00000), + SPH_C32(0x90d22b00), SPH_C32(0x48310000), SPH_C32(0x3a8b0000), + SPH_C32(0xcbd022dd), SPH_C32(0x933cd248), SPH_C32(0x368794ef), + SPH_C32(0x9feb5ac5) }, + { SPH_C32(0x947e0000), SPH_C32(0xbe091400), SPH_C32(0x67860000), + SPH_C32(0xcddc0000), SPH_C32(0x1dce510b), SPH_C32(0xec636924), + SPH_C32(0xa2ffbda7), SPH_C32(0x5a4cc8f4), SPH_C32(0x1cff0000), + SPH_C32(0xcf462200), SPH_C32(0x3dd20000), SPH_C32(0x93d00000), + SPH_C32(0xdafb736b), SPH_C32(0x28f60619), SPH_C32(0xc500c982), + SPH_C32(0xee61b16b) }, + { SPH_C32(0x980c0000), SPH_C32(0xf7ec1b00), SPH_C32(0x25ff0000), + SPH_C32(0x91360000), SPH_C32(0x2e646111), SPH_C32(0xf9e14c30), + SPH_C32(0x375cf6dc), SPH_C32(0xee07c864), SPH_C32(0xe2dd0000), + SPH_C32(0x681e2700), SPH_C32(0x18030000), SPH_C32(0x64b00000), + SPH_C32(0x53ca0bb1), SPH_C32(0x3722fe79), SPH_C32(0x8bd06a97), + SPH_C32(0x4f424ef4) }, + { SPH_C32(0x6a5c0000), SPH_C32(0x19511100), SPH_C32(0x42570000), + SPH_C32(0x3abc0000), SPH_C32(0x94ff29d1), SPH_C32(0xf3b79144), + SPH_C32(0xec2f1eb2), SPH_C32(0xfb6f376b), SPH_C32(0xeeaf0000), + SPH_C32(0x21fb2800), SPH_C32(0x5a7a0000), SPH_C32(0x385a0000), + SPH_C32(0x60603bab), SPH_C32(0x22a0db6d), SPH_C32(0x1e7321ec), + SPH_C32(0xfb094e64) }, + { SPH_C32(0x662e0000), SPH_C32(0x50b41e00), SPH_C32(0x002e0000), + SPH_C32(0x66560000), SPH_C32(0xa75519cb), SPH_C32(0xe635b450), + SPH_C32(0x798c55c9), SPH_C32(0x4f2437fb), SPH_C32(0x108d0000), + SPH_C32(0x86a32d00), SPH_C32(0x7fab0000), SPH_C32(0xcf3a0000), + SPH_C32(0xe9514371), SPH_C32(0x3d74230d), SPH_C32(0x50a382f9), + SPH_C32(0x5a2ab1fb) }, + { SPH_C32(0x695b0000), SPH_C32(0x0dcd0500), SPH_C32(0xa9760000), + SPH_C32(0x03250000), SPH_C32(0x2183248b), SPH_C32(0x61380db7), + SPH_C32(0xd2670d01), SPH_C32(0x40bed715), SPH_C32(0x59e70000), + SPH_C32(0x6af33500), SPH_C32(0xc4b80000), SPH_C32(0xa8980000), + SPH_C32(0xc4376747), SPH_C32(0x0be593cf), SPH_C32(0xd3bc6f32), + SPH_C32(0x315245b4) }, + { SPH_C32(0x65290000), SPH_C32(0x44280a00), SPH_C32(0xeb0f0000), + SPH_C32(0x5fcf0000), SPH_C32(0x12291491), SPH_C32(0x74ba28a3), + SPH_C32(0x47c4467a), SPH_C32(0xf4f5d785), SPH_C32(0xa7c50000), + SPH_C32(0xcdab3000), SPH_C32(0xe1690000), SPH_C32(0x5ff80000), + SPH_C32(0x4d061f9d), SPH_C32(0x14316baf), SPH_C32(0x9d6ccc27), + SPH_C32(0x9071ba2b) }, + { SPH_C32(0x97790000), SPH_C32(0xaa950000), SPH_C32(0x8ca70000), + SPH_C32(0xf4450000), SPH_C32(0xa8b25c51), SPH_C32(0x7eecf5d7), + SPH_C32(0x9cb7ae14), SPH_C32(0xe19d288a), SPH_C32(0xabb70000), + SPH_C32(0x844e3f00), SPH_C32(0xa3100000), SPH_C32(0x03120000), + SPH_C32(0x7eac2f87), SPH_C32(0x01b34ebb), SPH_C32(0x08cf875c), + SPH_C32(0x243ababb) }, + { SPH_C32(0x9b0b0000), SPH_C32(0xe3700f00), SPH_C32(0xcede0000), + SPH_C32(0xa8af0000), SPH_C32(0x9b186c4b), SPH_C32(0x6b6ed0c3), + SPH_C32(0x0914e56f), SPH_C32(0x55d6281a), SPH_C32(0x55950000), + SPH_C32(0x23163a00), SPH_C32(0x86c10000), SPH_C32(0xf4720000), + SPH_C32(0xf79d575d), SPH_C32(0x1e67b6db), SPH_C32(0x461f2449), + SPH_C32(0x85194524) }, + { SPH_C32(0x2c430000), SPH_C32(0xa8781200), SPH_C32(0x501c0000), + SPH_C32(0x386d0000), SPH_C32(0x3f4f30a7), SPH_C32(0x422b9861), + SPH_C32(0xc4dbabb1), SPH_C32(0x9f8d23ca), SPH_C32(0xe1da0000), + SPH_C32(0x7c823300), SPH_C32(0xf3220000), SPH_C32(0x5d290000), + SPH_C32(0xe6b606eb), SPH_C32(0xa5ad628a), SPH_C32(0xb5987924), + SPH_C32(0xf493ae8a) }, + { SPH_C32(0x20310000), SPH_C32(0xe19d1d00), SPH_C32(0x12650000), + SPH_C32(0x64870000), SPH_C32(0x0ce500bd), SPH_C32(0x57a9bd75), + SPH_C32(0x5178e0ca), SPH_C32(0x2bc6235a), SPH_C32(0x1ff80000), + SPH_C32(0xdbda3600), SPH_C32(0xd6f30000), SPH_C32(0xaa490000), + SPH_C32(0x6f877e31), SPH_C32(0xba799aea), SPH_C32(0xfb48da31), + SPH_C32(0x55b05115) }, + { SPH_C32(0xd2610000), SPH_C32(0x0f201700), SPH_C32(0x75cd0000), + SPH_C32(0xcf0d0000), SPH_C32(0xb67e487d), SPH_C32(0x5dff6001), + SPH_C32(0x8a0b08a4), SPH_C32(0x3eaedc55), SPH_C32(0x138a0000), + SPH_C32(0x923f3900), SPH_C32(0x948a0000), SPH_C32(0xf6a30000), + SPH_C32(0x5c2d4e2b), SPH_C32(0xaffbbffe), SPH_C32(0x6eeb914a), + SPH_C32(0xe1fb5185) }, + { SPH_C32(0xde130000), SPH_C32(0x46c51800), SPH_C32(0x37b40000), + SPH_C32(0x93e70000), SPH_C32(0x85d47867), SPH_C32(0x487d4515), + SPH_C32(0x1fa843df), SPH_C32(0x8ae5dcc5), SPH_C32(0xeda80000), + SPH_C32(0x35673c00), SPH_C32(0xb15b0000), SPH_C32(0x01c30000), + SPH_C32(0xd51c36f1), SPH_C32(0xb02f479e), SPH_C32(0x203b325f), + SPH_C32(0x40d8ae1a) }, + { SPH_C32(0xa4c20000), SPH_C32(0xd9372400), SPH_C32(0x0a480000), + SPH_C32(0x66610000), SPH_C32(0xf87a12c7), SPH_C32(0x86bef75c), + SPH_C32(0xa324df94), SPH_C32(0x2ba05a55), SPH_C32(0x75a40000), + SPH_C32(0xc28b2700), SPH_C32(0x94a40000), SPH_C32(0x90f50000), + SPH_C32(0xfb7857e0), SPH_C32(0x49ce0bae), SPH_C32(0x1767c483), + SPH_C32(0xaedf667e) }, + { SPH_C32(0xa8b00000), SPH_C32(0x90d22b00), SPH_C32(0x48310000), + SPH_C32(0x3a8b0000), SPH_C32(0xcbd022dd), SPH_C32(0x933cd248), + SPH_C32(0x368794ef), SPH_C32(0x9feb5ac5), SPH_C32(0x8b860000), + SPH_C32(0x65d32200), SPH_C32(0xb1750000), SPH_C32(0x67950000), + SPH_C32(0x72492f3a), SPH_C32(0x561af3ce), SPH_C32(0x59b76796), + SPH_C32(0x0ffc99e1) }, + { SPH_C32(0x5ae00000), SPH_C32(0x7e6f2100), SPH_C32(0x2f990000), + SPH_C32(0x91010000), SPH_C32(0x714b6a1d), SPH_C32(0x996a0f3c), + SPH_C32(0xedf47c81), SPH_C32(0x8a83a5ca), SPH_C32(0x87f40000), + SPH_C32(0x2c362d00), SPH_C32(0xf30c0000), SPH_C32(0x3b7f0000), + SPH_C32(0x41e31f20), SPH_C32(0x4398d6da), SPH_C32(0xcc142ced), + SPH_C32(0xbbb79971) }, + { SPH_C32(0x56920000), SPH_C32(0x378a2e00), SPH_C32(0x6de00000), + SPH_C32(0xcdeb0000), SPH_C32(0x42e15a07), SPH_C32(0x8ce82a28), + SPH_C32(0x785737fa), SPH_C32(0x3ec8a55a), SPH_C32(0x79d60000), + SPH_C32(0x8b6e2800), SPH_C32(0xd6dd0000), SPH_C32(0xcc1f0000), + SPH_C32(0xc8d267fa), SPH_C32(0x5c4c2eba), SPH_C32(0x82c48ff8), + SPH_C32(0x1a9466ee) }, + { SPH_C32(0xe1da0000), SPH_C32(0x7c823300), SPH_C32(0xf3220000), + SPH_C32(0x5d290000), SPH_C32(0xe6b606eb), SPH_C32(0xa5ad628a), + SPH_C32(0xb5987924), SPH_C32(0xf493ae8a), SPH_C32(0xcd990000), + SPH_C32(0xd4fa2100), SPH_C32(0xa33e0000), SPH_C32(0x65440000), + SPH_C32(0xd9f9364c), SPH_C32(0xe786faeb), SPH_C32(0x7143d295), + SPH_C32(0x6b1e8d40) }, + { SPH_C32(0xeda80000), SPH_C32(0x35673c00), SPH_C32(0xb15b0000), + SPH_C32(0x01c30000), SPH_C32(0xd51c36f1), SPH_C32(0xb02f479e), + SPH_C32(0x203b325f), SPH_C32(0x40d8ae1a), SPH_C32(0x33bb0000), + SPH_C32(0x73a22400), SPH_C32(0x86ef0000), SPH_C32(0x92240000), + SPH_C32(0x50c84e96), SPH_C32(0xf852028b), SPH_C32(0x3f937180), + SPH_C32(0xca3d72df) }, + { SPH_C32(0x1ff80000), SPH_C32(0xdbda3600), SPH_C32(0xd6f30000), + SPH_C32(0xaa490000), SPH_C32(0x6f877e31), SPH_C32(0xba799aea), + SPH_C32(0xfb48da31), SPH_C32(0x55b05115), SPH_C32(0x3fc90000), + SPH_C32(0x3a472b00), SPH_C32(0xc4960000), SPH_C32(0xcece0000), + SPH_C32(0x63627e8c), SPH_C32(0xedd0279f), SPH_C32(0xaa303afb), + SPH_C32(0x7e76724f) }, + { SPH_C32(0x138a0000), SPH_C32(0x923f3900), SPH_C32(0x948a0000), + SPH_C32(0xf6a30000), SPH_C32(0x5c2d4e2b), SPH_C32(0xaffbbffe), + SPH_C32(0x6eeb914a), SPH_C32(0xe1fb5185), SPH_C32(0xc1eb0000), + SPH_C32(0x9d1f2e00), SPH_C32(0xe1470000), SPH_C32(0x39ae0000), + SPH_C32(0xea530656), SPH_C32(0xf204dfff), SPH_C32(0xe4e099ee), + SPH_C32(0xdf558dd0) }, + { SPH_C32(0x1cff0000), SPH_C32(0xcf462200), SPH_C32(0x3dd20000), + SPH_C32(0x93d00000), SPH_C32(0xdafb736b), SPH_C32(0x28f60619), + SPH_C32(0xc500c982), SPH_C32(0xee61b16b), SPH_C32(0x88810000), + SPH_C32(0x714f3600), SPH_C32(0x5a540000), SPH_C32(0x5e0c0000), + SPH_C32(0xc7352260), SPH_C32(0xc4956f3d), SPH_C32(0x67ff7425), + SPH_C32(0xb42d799f) }, + { SPH_C32(0x108d0000), SPH_C32(0x86a32d00), SPH_C32(0x7fab0000), + SPH_C32(0xcf3a0000), SPH_C32(0xe9514371), SPH_C32(0x3d74230d), + SPH_C32(0x50a382f9), SPH_C32(0x5a2ab1fb), SPH_C32(0x76a30000), + SPH_C32(0xd6173300), SPH_C32(0x7f850000), SPH_C32(0xa96c0000), + SPH_C32(0x4e045aba), SPH_C32(0xdb41975d), SPH_C32(0x292fd730), + SPH_C32(0x150e8600) }, + { SPH_C32(0xe2dd0000), SPH_C32(0x681e2700), SPH_C32(0x18030000), + SPH_C32(0x64b00000), SPH_C32(0x53ca0bb1), SPH_C32(0x3722fe79), + SPH_C32(0x8bd06a97), SPH_C32(0x4f424ef4), SPH_C32(0x7ad10000), + SPH_C32(0x9ff23c00), SPH_C32(0x3dfc0000), SPH_C32(0xf5860000), + SPH_C32(0x7dae6aa0), SPH_C32(0xcec3b249), SPH_C32(0xbc8c9c4b), + SPH_C32(0xa1458690) }, + { SPH_C32(0xeeaf0000), SPH_C32(0x21fb2800), SPH_C32(0x5a7a0000), + SPH_C32(0x385a0000), SPH_C32(0x60603bab), SPH_C32(0x22a0db6d), + SPH_C32(0x1e7321ec), SPH_C32(0xfb094e64), SPH_C32(0x84f30000), + SPH_C32(0x38aa3900), SPH_C32(0x182d0000), SPH_C32(0x02e60000), + SPH_C32(0xf49f127a), SPH_C32(0xd1174a29), SPH_C32(0xf25c3f5e), + SPH_C32(0x0066790f) }, + { SPH_C32(0x59e70000), SPH_C32(0x6af33500), SPH_C32(0xc4b80000), + SPH_C32(0xa8980000), SPH_C32(0xc4376747), SPH_C32(0x0be593cf), + SPH_C32(0xd3bc6f32), SPH_C32(0x315245b4), SPH_C32(0x30bc0000), + SPH_C32(0x673e3000), SPH_C32(0x6dce0000), SPH_C32(0xabbd0000), + SPH_C32(0xe5b443cc), SPH_C32(0x6add9e78), SPH_C32(0x01db6233), + SPH_C32(0x71ec92a1) }, + { SPH_C32(0x55950000), SPH_C32(0x23163a00), SPH_C32(0x86c10000), + SPH_C32(0xf4720000), SPH_C32(0xf79d575d), SPH_C32(0x1e67b6db), + SPH_C32(0x461f2449), SPH_C32(0x85194524), SPH_C32(0xce9e0000), + SPH_C32(0xc0663500), SPH_C32(0x481f0000), SPH_C32(0x5cdd0000), + SPH_C32(0x6c853b16), SPH_C32(0x75096618), SPH_C32(0x4f0bc126), + SPH_C32(0xd0cf6d3e) }, + { SPH_C32(0xa7c50000), SPH_C32(0xcdab3000), SPH_C32(0xe1690000), + SPH_C32(0x5ff80000), SPH_C32(0x4d061f9d), SPH_C32(0x14316baf), + SPH_C32(0x9d6ccc27), SPH_C32(0x9071ba2b), SPH_C32(0xc2ec0000), + SPH_C32(0x89833a00), SPH_C32(0x0a660000), SPH_C32(0x00370000), + SPH_C32(0x5f2f0b0c), SPH_C32(0x608b430c), SPH_C32(0xdaa88a5d), + SPH_C32(0x64846dae) }, + { SPH_C32(0xabb70000), SPH_C32(0x844e3f00), SPH_C32(0xa3100000), + SPH_C32(0x03120000), SPH_C32(0x7eac2f87), SPH_C32(0x01b34ebb), + SPH_C32(0x08cf875c), SPH_C32(0x243ababb), SPH_C32(0x3cce0000), + SPH_C32(0x2edb3f00), SPH_C32(0x2fb70000), SPH_C32(0xf7570000), + SPH_C32(0xd61e73d6), SPH_C32(0x7f5fbb6c), SPH_C32(0x94782948), + SPH_C32(0xc5a79231) }, + { SPH_C32(0x75c90003), SPH_C32(0x0e10c000), SPH_C32(0xd1200000), + SPH_C32(0xbaea0000), SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), + SPH_C32(0xbb28761d), SPH_C32(0x00b72e2b), SPH_C32(0xeecf0001), + SPH_C32(0x6f564000), SPH_C32(0xf33e0000), SPH_C32(0xa79e0000), + SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), SPH_C32(0x4a3b40ba), + SPH_C32(0xfeabf254) }, + { SPH_C32(0x79bb0003), SPH_C32(0x47f5cf00), SPH_C32(0x93590000), + SPH_C32(0xe6000000), SPH_C32(0xb86e1f24), SPH_C32(0x92da9243), + SPH_C32(0x2e8b3d66), SPH_C32(0xb4fc2ebb), SPH_C32(0x10ed0001), + SPH_C32(0xc80e4500), SPH_C32(0xd6ef0000), SPH_C32(0x50fe0000), + SPH_C32(0x34840ac3), SPH_C32(0xa8c513a5), SPH_C32(0x04ebe3af), + SPH_C32(0x5f880dcb) }, + { SPH_C32(0x8beb0003), SPH_C32(0xa948c500), SPH_C32(0xf4f10000), + SPH_C32(0x4d8a0000), SPH_C32(0x02f557e4), SPH_C32(0x988c4f37), + SPH_C32(0xf5f8d508), SPH_C32(0xa194d1b4), SPH_C32(0x1c9f0001), + SPH_C32(0x81eb4a00), SPH_C32(0x94960000), SPH_C32(0x0c140000), + SPH_C32(0x072e3ad9), SPH_C32(0xbd4736b1), SPH_C32(0x9148a8d4), + SPH_C32(0xebc30d5b) }, + { SPH_C32(0x87990003), SPH_C32(0xe0adca00), SPH_C32(0xb6880000), + SPH_C32(0x11600000), SPH_C32(0x315f67fe), SPH_C32(0x8d0e6a23), + SPH_C32(0x605b9e73), SPH_C32(0x15dfd124), SPH_C32(0xe2bd0001), + SPH_C32(0x26b34f00), SPH_C32(0xb1470000), SPH_C32(0xfb740000), + SPH_C32(0x8e1f4203), SPH_C32(0xa293ced1), SPH_C32(0xdf980bc1), + SPH_C32(0x4ae0f2c4) }, + { SPH_C32(0x30d10003), SPH_C32(0xaba5d700), SPH_C32(0x284a0000), + SPH_C32(0x81a20000), SPH_C32(0x95083b12), SPH_C32(0xa44b2281), + SPH_C32(0xad94d0ad), SPH_C32(0xdf84daf4), SPH_C32(0x56f20001), + SPH_C32(0x79274600), SPH_C32(0xc4a40000), SPH_C32(0x522f0000), + SPH_C32(0x9f3413b5), SPH_C32(0x19591a80), SPH_C32(0x2c1f56ac), + SPH_C32(0x3b6a196a) }, + { SPH_C32(0x3ca30003), SPH_C32(0xe240d800), SPH_C32(0x6a330000), + SPH_C32(0xdd480000), SPH_C32(0xa6a20b08), SPH_C32(0xb1c90795), + SPH_C32(0x38379bd6), SPH_C32(0x6bcfda64), SPH_C32(0xa8d00001), + SPH_C32(0xde7f4300), SPH_C32(0xe1750000), SPH_C32(0xa54f0000), + SPH_C32(0x16056b6f), SPH_C32(0x068de2e0), SPH_C32(0x62cff5b9), + SPH_C32(0x9a49e6f5) }, + { SPH_C32(0xcef30003), SPH_C32(0x0cfdd200), SPH_C32(0x0d9b0000), + SPH_C32(0x76c20000), SPH_C32(0x1c3943c8), SPH_C32(0xbb9fdae1), + SPH_C32(0xe34473b8), SPH_C32(0x7ea7256b), SPH_C32(0xa4a20001), + SPH_C32(0x979a4c00), SPH_C32(0xa30c0000), SPH_C32(0xf9a50000), + SPH_C32(0x25af5b75), SPH_C32(0x130fc7f4), SPH_C32(0xf76cbec2), + SPH_C32(0x2e02e665) }, + { SPH_C32(0xc2810003), SPH_C32(0x4518dd00), SPH_C32(0x4fe20000), + SPH_C32(0x2a280000), SPH_C32(0x2f9373d2), SPH_C32(0xae1dfff5), + SPH_C32(0x76e738c3), SPH_C32(0xcaec25fb), SPH_C32(0x5a800001), + SPH_C32(0x30c24900), SPH_C32(0x86dd0000), SPH_C32(0x0ec50000), + SPH_C32(0xac9e23af), SPH_C32(0x0cdb3f94), SPH_C32(0xb9bc1dd7), + SPH_C32(0x8f2119fa) }, + { SPH_C32(0xcdf40003), SPH_C32(0x1861c600), SPH_C32(0xe6ba0000), + SPH_C32(0x4f5b0000), SPH_C32(0xa9454e92), SPH_C32(0x29104612), + SPH_C32(0xdd0c600b), SPH_C32(0xc576c515), SPH_C32(0x13ea0001), + SPH_C32(0xdc925100), SPH_C32(0x3dce0000), SPH_C32(0x69670000), + SPH_C32(0x81f80799), SPH_C32(0x3a4a8f56), SPH_C32(0x3aa3f01c), + SPH_C32(0xe459edb5) }, + { SPH_C32(0xc1860003), SPH_C32(0x5184c900), SPH_C32(0xa4c30000), + SPH_C32(0x13b10000), SPH_C32(0x9aef7e88), SPH_C32(0x3c926306), + SPH_C32(0x48af2b70), SPH_C32(0x713dc585), SPH_C32(0xedc80001), + SPH_C32(0x7bca5400), SPH_C32(0x181f0000), SPH_C32(0x9e070000), + SPH_C32(0x08c97f43), SPH_C32(0x259e7736), SPH_C32(0x74735309), + SPH_C32(0x457a122a) }, + { SPH_C32(0x33d60003), SPH_C32(0xbf39c300), SPH_C32(0xc36b0000), + SPH_C32(0xb83b0000), SPH_C32(0x20743648), SPH_C32(0x36c4be72), + SPH_C32(0x93dcc31e), SPH_C32(0x64553a8a), SPH_C32(0xe1ba0001), + SPH_C32(0x322f5b00), SPH_C32(0x5a660000), SPH_C32(0xc2ed0000), + SPH_C32(0x3b634f59), SPH_C32(0x301c5222), SPH_C32(0xe1d01872), + SPH_C32(0xf13112ba) }, + { SPH_C32(0x3fa40003), SPH_C32(0xf6dccc00), SPH_C32(0x81120000), + SPH_C32(0xe4d10000), SPH_C32(0x13de0652), SPH_C32(0x23469b66), + SPH_C32(0x067f8865), SPH_C32(0xd01e3a1a), SPH_C32(0x1f980001), + SPH_C32(0x95775e00), SPH_C32(0x7fb70000), SPH_C32(0x358d0000), + SPH_C32(0xb2523783), SPH_C32(0x2fc8aa42), SPH_C32(0xaf00bb67), + SPH_C32(0x5012ed25) }, + { SPH_C32(0x88ec0003), SPH_C32(0xbdd4d100), SPH_C32(0x1fd00000), + SPH_C32(0x74130000), SPH_C32(0xb7895abe), SPH_C32(0x0a03d3c4), + SPH_C32(0xcbb0c6bb), SPH_C32(0x1a4531ca), SPH_C32(0xabd70001), + SPH_C32(0xcae35700), SPH_C32(0x0a540000), SPH_C32(0x9cd60000), + SPH_C32(0xa3796635), SPH_C32(0x94027e13), SPH_C32(0x5c87e60a), + SPH_C32(0x2198068b) }, + { SPH_C32(0x849e0003), SPH_C32(0xf431de00), SPH_C32(0x5da90000), + SPH_C32(0x28f90000), SPH_C32(0x84236aa4), SPH_C32(0x1f81f6d0), + SPH_C32(0x5e138dc0), SPH_C32(0xae0e315a), SPH_C32(0x55f50001), + SPH_C32(0x6dbb5200), SPH_C32(0x2f850000), SPH_C32(0x6bb60000), + SPH_C32(0x2a481eef), SPH_C32(0x8bd68673), SPH_C32(0x1257451f), + SPH_C32(0x80bbf914) }, + { SPH_C32(0x76ce0003), SPH_C32(0x1a8cd400), SPH_C32(0x3a010000), + SPH_C32(0x83730000), SPH_C32(0x3eb82264), SPH_C32(0x15d72ba4), + SPH_C32(0x856065ae), SPH_C32(0xbb66ce55), SPH_C32(0x59870001), + SPH_C32(0x245e5d00), SPH_C32(0x6dfc0000), SPH_C32(0x375c0000), + SPH_C32(0x19e22ef5), SPH_C32(0x9e54a367), SPH_C32(0x87f40e64), + SPH_C32(0x34f0f984) }, + { SPH_C32(0x7abc0003), SPH_C32(0x5369db00), SPH_C32(0x78780000), + SPH_C32(0xdf990000), SPH_C32(0x0d12127e), SPH_C32(0x00550eb0), + SPH_C32(0x10c32ed5), SPH_C32(0x0f2dcec5), SPH_C32(0xa7a50001), + SPH_C32(0x83065800), SPH_C32(0x482d0000), SPH_C32(0xc03c0000), + SPH_C32(0x90d3562f), SPH_C32(0x81805b07), SPH_C32(0xc924ad71), + SPH_C32(0x95d3061b) }, + { SPH_C32(0x006d0003), SPH_C32(0xcc9be700), SPH_C32(0x45840000), + SPH_C32(0x2a1f0000), SPH_C32(0x70bc78de), SPH_C32(0xce96bcf9), + SPH_C32(0xac4fb29e), SPH_C32(0xae684855), SPH_C32(0x3fa90001), + SPH_C32(0x74ea4300), SPH_C32(0x6dd20000), SPH_C32(0x510a0000), + SPH_C32(0xbeb7373e), SPH_C32(0x78611737), SPH_C32(0xfe785bad), + SPH_C32(0x7bd4ce7f) }, + { SPH_C32(0x0c1f0003), SPH_C32(0x857ee800), SPH_C32(0x07fd0000), + SPH_C32(0x76f50000), SPH_C32(0x431648c4), SPH_C32(0xdb1499ed), + SPH_C32(0x39ecf9e5), SPH_C32(0x1a2348c5), SPH_C32(0xc18b0001), + SPH_C32(0xd3b24600), SPH_C32(0x48030000), SPH_C32(0xa66a0000), + SPH_C32(0x37864fe4), SPH_C32(0x67b5ef57), SPH_C32(0xb0a8f8b8), + SPH_C32(0xdaf731e0) }, + { SPH_C32(0xfe4f0003), SPH_C32(0x6bc3e200), SPH_C32(0x60550000), + SPH_C32(0xdd7f0000), SPH_C32(0xf98d0004), SPH_C32(0xd1424499), + SPH_C32(0xe29f118b), SPH_C32(0x0f4bb7ca), SPH_C32(0xcdf90001), + SPH_C32(0x9a574900), SPH_C32(0x0a7a0000), SPH_C32(0xfa800000), + SPH_C32(0x042c7ffe), SPH_C32(0x7237ca43), SPH_C32(0x250bb3c3), + SPH_C32(0x6ebc3170) }, + { SPH_C32(0xf23d0003), SPH_C32(0x2226ed00), SPH_C32(0x222c0000), + SPH_C32(0x81950000), SPH_C32(0xca27301e), SPH_C32(0xc4c0618d), + SPH_C32(0x773c5af0), SPH_C32(0xbb00b75a), SPH_C32(0x33db0001), + SPH_C32(0x3d0f4c00), SPH_C32(0x2fab0000), SPH_C32(0x0de00000), + SPH_C32(0x8d1d0724), SPH_C32(0x6de33223), SPH_C32(0x6bdb10d6), + SPH_C32(0xcf9fceef) }, + { SPH_C32(0x45750003), SPH_C32(0x692ef000), SPH_C32(0xbcee0000), + SPH_C32(0x11570000), SPH_C32(0x6e706cf2), SPH_C32(0xed85292f), + SPH_C32(0xbaf3142e), SPH_C32(0x715bbc8a), SPH_C32(0x87940001), + SPH_C32(0x629b4500), SPH_C32(0x5a480000), SPH_C32(0xa4bb0000), + SPH_C32(0x9c365692), SPH_C32(0xd629e672), SPH_C32(0x985c4dbb), + SPH_C32(0xbe152541) }, + { SPH_C32(0x49070003), SPH_C32(0x20cbff00), SPH_C32(0xfe970000), + SPH_C32(0x4dbd0000), SPH_C32(0x5dda5ce8), SPH_C32(0xf8070c3b), + SPH_C32(0x2f505f55), SPH_C32(0xc510bc1a), SPH_C32(0x79b60001), + SPH_C32(0xc5c34000), SPH_C32(0x7f990000), SPH_C32(0x53db0000), + SPH_C32(0x15072e48), SPH_C32(0xc9fd1e12), SPH_C32(0xd68ceeae), + SPH_C32(0x1f36dade) }, + { SPH_C32(0xbb570003), SPH_C32(0xce76f500), SPH_C32(0x993f0000), + SPH_C32(0xe6370000), SPH_C32(0xe7411428), SPH_C32(0xf251d14f), + SPH_C32(0xf423b73b), SPH_C32(0xd0784315), SPH_C32(0x75c40001), + SPH_C32(0x8c264f00), SPH_C32(0x3de00000), SPH_C32(0x0f310000), + SPH_C32(0x26ad1e52), SPH_C32(0xdc7f3b06), SPH_C32(0x432fa5d5), + SPH_C32(0xab7dda4e) }, + { SPH_C32(0xb7250003), SPH_C32(0x8793fa00), SPH_C32(0xdb460000), + SPH_C32(0xbadd0000), SPH_C32(0xd4eb2432), SPH_C32(0xe7d3f45b), + SPH_C32(0x6180fc40), SPH_C32(0x64334385), SPH_C32(0x8be60001), + SPH_C32(0x2b7e4a00), SPH_C32(0x18310000), SPH_C32(0xf8510000), + SPH_C32(0xaf9c6688), SPH_C32(0xc3abc366), SPH_C32(0x0dff06c0), + SPH_C32(0x0a5e25d1) }, + { SPH_C32(0xb8500003), SPH_C32(0xdaeae100), SPH_C32(0x721e0000), + SPH_C32(0xdfae0000), SPH_C32(0x523d1972), SPH_C32(0x60de4dbc), + SPH_C32(0xca6ba488), SPH_C32(0x6ba9a36b), SPH_C32(0xc28c0001), + SPH_C32(0xc72e5200), SPH_C32(0xa3220000), SPH_C32(0x9ff30000), + SPH_C32(0x82fa42be), SPH_C32(0xf53a73a4), SPH_C32(0x8ee0eb0b), + SPH_C32(0x6126d19e) }, + { SPH_C32(0xb4220003), SPH_C32(0x930fee00), SPH_C32(0x30670000), + SPH_C32(0x83440000), SPH_C32(0x61972968), SPH_C32(0x755c68a8), + SPH_C32(0x5fc8eff3), SPH_C32(0xdfe2a3fb), SPH_C32(0x3cae0001), + SPH_C32(0x60765700), SPH_C32(0x86f30000), SPH_C32(0x68930000), + SPH_C32(0x0bcb3a64), SPH_C32(0xeaee8bc4), SPH_C32(0xc030481e), + SPH_C32(0xc0052e01) }, + { SPH_C32(0x46720003), SPH_C32(0x7db2e400), SPH_C32(0x57cf0000), + SPH_C32(0x28ce0000), SPH_C32(0xdb0c61a8), SPH_C32(0x7f0ab5dc), + SPH_C32(0x84bb079d), SPH_C32(0xca8a5cf4), SPH_C32(0x30dc0001), + SPH_C32(0x29935800), SPH_C32(0xc48a0000), SPH_C32(0x34790000), + SPH_C32(0x38610a7e), SPH_C32(0xff6caed0), SPH_C32(0x55930365), + SPH_C32(0x744e2e91) }, + { SPH_C32(0x4a000003), SPH_C32(0x3457eb00), SPH_C32(0x15b60000), + SPH_C32(0x74240000), SPH_C32(0xe8a651b2), SPH_C32(0x6a8890c8), + SPH_C32(0x11184ce6), SPH_C32(0x7ec15c64), SPH_C32(0xcefe0001), + SPH_C32(0x8ecb5d00), SPH_C32(0xe15b0000), SPH_C32(0xc3190000), + SPH_C32(0xb15072a4), SPH_C32(0xe0b856b0), SPH_C32(0x1b43a070), + SPH_C32(0xd56dd10e) }, + { SPH_C32(0xfd480003), SPH_C32(0x7f5ff600), SPH_C32(0x8b740000), + SPH_C32(0xe4e60000), SPH_C32(0x4cf10d5e), SPH_C32(0x43cdd86a), + SPH_C32(0xdcd70238), SPH_C32(0xb49a57b4), SPH_C32(0x7ab10001), + SPH_C32(0xd15f5400), SPH_C32(0x94b80000), SPH_C32(0x6a420000), + SPH_C32(0xa07b2312), SPH_C32(0x5b7282e1), SPH_C32(0xe8c4fd1d), + SPH_C32(0xa4e73aa0) }, + { SPH_C32(0xf13a0003), SPH_C32(0x36baf900), SPH_C32(0xc90d0000), + SPH_C32(0xb80c0000), SPH_C32(0x7f5b3d44), SPH_C32(0x564ffd7e), + SPH_C32(0x49744943), SPH_C32(0x00d15724), SPH_C32(0x84930001), + SPH_C32(0x76075100), SPH_C32(0xb1690000), SPH_C32(0x9d220000), + SPH_C32(0x294a5bc8), SPH_C32(0x44a67a81), SPH_C32(0xa6145e08), + SPH_C32(0x05c4c53f) }, + { SPH_C32(0x036a0003), SPH_C32(0xd807f300), SPH_C32(0xaea50000), + SPH_C32(0x13860000), SPH_C32(0xc5c07584), SPH_C32(0x5c19200a), + SPH_C32(0x9207a12d), SPH_C32(0x15b9a82b), SPH_C32(0x88e10001), + SPH_C32(0x3fe25e00), SPH_C32(0xf3100000), SPH_C32(0xc1c80000), + SPH_C32(0x1ae06bd2), SPH_C32(0x51245f95), SPH_C32(0x33b71573), + SPH_C32(0xb18fc5af) }, + { SPH_C32(0x0f180003), SPH_C32(0x91e2fc00), SPH_C32(0xecdc0000), + SPH_C32(0x4f6c0000), SPH_C32(0xf66a459e), SPH_C32(0x499b051e), + SPH_C32(0x07a4ea56), SPH_C32(0xa1f2a8bb), SPH_C32(0x76c30001), + SPH_C32(0x98ba5b00), SPH_C32(0xd6c10000), SPH_C32(0x36a80000), + SPH_C32(0x93d11308), SPH_C32(0x4ef0a7f5), SPH_C32(0x7d67b666), + SPH_C32(0x10ac3a30) }, + { SPH_C32(0xa4af0003), SPH_C32(0x15acc300), SPH_C32(0x4fcc0000), + SPH_C32(0x4c7e0000), SPH_C32(0x88c66a19), SPH_C32(0x48284ba5), + SPH_C32(0x0f6b6d0a), SPH_C32(0x85c81200), SPH_C32(0x4a0d0001), + SPH_C32(0xb6616400), SPH_C32(0xf9760000), SPH_C32(0xc1ff0000), + SPH_C32(0x45cf60de), SPH_C32(0x31af1c99), SPH_C32(0xe91f9f2e), + SPH_C32(0xd50ba801) }, + { SPH_C32(0xa8dd0003), SPH_C32(0x5c49cc00), SPH_C32(0x0db50000), + SPH_C32(0x10940000), SPH_C32(0xbb6c5a03), SPH_C32(0x5daa6eb1), + SPH_C32(0x9ac82671), SPH_C32(0x31831290), SPH_C32(0xb42f0001), + SPH_C32(0x11396100), SPH_C32(0xdca70000), SPH_C32(0x369f0000), + SPH_C32(0xccfe1804), SPH_C32(0x2e7be4f9), SPH_C32(0xa7cf3c3b), + SPH_C32(0x7428579e) }, + { SPH_C32(0x5a8d0003), SPH_C32(0xb2f4c600), SPH_C32(0x6a1d0000), + SPH_C32(0xbb1e0000), SPH_C32(0x01f712c3), SPH_C32(0x57fcb3c5), + SPH_C32(0x41bbce1f), SPH_C32(0x24ebed9f), SPH_C32(0xb85d0001), + SPH_C32(0x58dc6e00), SPH_C32(0x9ede0000), SPH_C32(0x6a750000), + SPH_C32(0xff54281e), SPH_C32(0x3bf9c1ed), SPH_C32(0x326c7740), + SPH_C32(0xc063570e) }, + { SPH_C32(0x56ff0003), SPH_C32(0xfb11c900), SPH_C32(0x28640000), + SPH_C32(0xe7f40000), SPH_C32(0x325d22d9), SPH_C32(0x427e96d1), + SPH_C32(0xd4188564), SPH_C32(0x90a0ed0f), SPH_C32(0x467f0001), + SPH_C32(0xff846b00), SPH_C32(0xbb0f0000), SPH_C32(0x9d150000), + SPH_C32(0x766550c4), SPH_C32(0x242d398d), SPH_C32(0x7cbcd455), + SPH_C32(0x6140a891) }, + { SPH_C32(0xe1b70003), SPH_C32(0xb019d400), SPH_C32(0xb6a60000), + SPH_C32(0x77360000), SPH_C32(0x960a7e35), SPH_C32(0x6b3bde73), + SPH_C32(0x19d7cbba), SPH_C32(0x5afbe6df), SPH_C32(0xf2300001), + SPH_C32(0xa0106200), SPH_C32(0xceec0000), SPH_C32(0x344e0000), + SPH_C32(0x674e0172), SPH_C32(0x9fe7eddc), SPH_C32(0x8f3b8938), + SPH_C32(0x10ca433f) }, + { SPH_C32(0xedc50003), SPH_C32(0xf9fcdb00), SPH_C32(0xf4df0000), + SPH_C32(0x2bdc0000), SPH_C32(0xa5a04e2f), SPH_C32(0x7eb9fb67), + SPH_C32(0x8c7480c1), SPH_C32(0xeeb0e64f), SPH_C32(0x0c120001), + SPH_C32(0x07486700), SPH_C32(0xeb3d0000), SPH_C32(0xc32e0000), + SPH_C32(0xee7f79a8), SPH_C32(0x803315bc), SPH_C32(0xc1eb2a2d), + SPH_C32(0xb1e9bca0) }, + { SPH_C32(0x1f950003), SPH_C32(0x1741d100), SPH_C32(0x93770000), + SPH_C32(0x80560000), SPH_C32(0x1f3b06ef), SPH_C32(0x74ef2613), + SPH_C32(0x570768af), SPH_C32(0xfbd81940), SPH_C32(0x00600001), + SPH_C32(0x4ead6800), SPH_C32(0xa9440000), SPH_C32(0x9fc40000), + SPH_C32(0xddd549b2), SPH_C32(0x95b130a8), SPH_C32(0x54486156), + SPH_C32(0x05a2bc30) }, + { SPH_C32(0x13e70003), SPH_C32(0x5ea4de00), SPH_C32(0xd10e0000), + SPH_C32(0xdcbc0000), SPH_C32(0x2c9136f5), SPH_C32(0x616d0307), + SPH_C32(0xc2a423d4), SPH_C32(0x4f9319d0), SPH_C32(0xfe420001), + SPH_C32(0xe9f56d00), SPH_C32(0x8c950000), SPH_C32(0x68a40000), + SPH_C32(0x54e43168), SPH_C32(0x8a65c8c8), SPH_C32(0x1a98c243), + SPH_C32(0xa48143af) }, + { SPH_C32(0x1c920003), SPH_C32(0x03ddc500), SPH_C32(0x78560000), + SPH_C32(0xb9cf0000), SPH_C32(0xaa470bb5), SPH_C32(0xe660bae0), + SPH_C32(0x694f7b1c), SPH_C32(0x4009f93e), SPH_C32(0xb7280001), + SPH_C32(0x05a57500), SPH_C32(0x37860000), SPH_C32(0x0f060000), + SPH_C32(0x7982155e), SPH_C32(0xbcf4780a), SPH_C32(0x99872f88), + SPH_C32(0xcff9b7e0) }, + { SPH_C32(0x10e00003), SPH_C32(0x4a38ca00), SPH_C32(0x3a2f0000), + SPH_C32(0xe5250000), SPH_C32(0x99ed3baf), SPH_C32(0xf3e29ff4), + SPH_C32(0xfcec3067), SPH_C32(0xf442f9ae), SPH_C32(0x490a0001), + SPH_C32(0xa2fd7000), SPH_C32(0x12570000), SPH_C32(0xf8660000), + SPH_C32(0xf0b36d84), SPH_C32(0xa320806a), SPH_C32(0xd7578c9d), + SPH_C32(0x6eda487f) }, + { SPH_C32(0xe2b00003), SPH_C32(0xa485c000), SPH_C32(0x5d870000), + SPH_C32(0x4eaf0000), SPH_C32(0x2376736f), SPH_C32(0xf9b44280), + SPH_C32(0x279fd809), SPH_C32(0xe12a06a1), SPH_C32(0x45780001), + SPH_C32(0xeb187f00), SPH_C32(0x502e0000), SPH_C32(0xa48c0000), + SPH_C32(0xc3195d9e), SPH_C32(0xb6a2a57e), SPH_C32(0x42f4c7e6), + SPH_C32(0xda9148ef) }, + { SPH_C32(0xeec20003), SPH_C32(0xed60cf00), SPH_C32(0x1ffe0000), + SPH_C32(0x12450000), SPH_C32(0x10dc4375), SPH_C32(0xec366794), + SPH_C32(0xb23c9372), SPH_C32(0x55610631), SPH_C32(0xbb5a0001), + SPH_C32(0x4c407a00), SPH_C32(0x75ff0000), SPH_C32(0x53ec0000), + SPH_C32(0x4a282544), SPH_C32(0xa9765d1e), SPH_C32(0x0c2464f3), + SPH_C32(0x7bb2b770) }, + { SPH_C32(0x598a0003), SPH_C32(0xa668d200), SPH_C32(0x813c0000), + SPH_C32(0x82870000), SPH_C32(0xb48b1f99), SPH_C32(0xc5732f36), + SPH_C32(0x7ff3ddac), SPH_C32(0x9f3a0de1), SPH_C32(0x0f150001), + SPH_C32(0x13d47300), SPH_C32(0x001c0000), SPH_C32(0xfab70000), + SPH_C32(0x5b0374f2), SPH_C32(0x12bc894f), SPH_C32(0xffa3399e), + SPH_C32(0x0a385cde) }, + { SPH_C32(0x55f80003), SPH_C32(0xef8ddd00), SPH_C32(0xc3450000), + SPH_C32(0xde6d0000), SPH_C32(0x87212f83), SPH_C32(0xd0f10a22), + SPH_C32(0xea5096d7), SPH_C32(0x2b710d71), SPH_C32(0xf1370001), + SPH_C32(0xb48c7600), SPH_C32(0x25cd0000), SPH_C32(0x0dd70000), + SPH_C32(0xd2320c28), SPH_C32(0x0d68712f), SPH_C32(0xb1739a8b), + SPH_C32(0xab1ba341) }, + { SPH_C32(0xa7a80003), SPH_C32(0x0130d700), SPH_C32(0xa4ed0000), + SPH_C32(0x75e70000), SPH_C32(0x3dba6743), SPH_C32(0xdaa7d756), + SPH_C32(0x31237eb9), SPH_C32(0x3e19f27e), SPH_C32(0xfd450001), + SPH_C32(0xfd697900), SPH_C32(0x67b40000), SPH_C32(0x513d0000), + SPH_C32(0xe1983c32), SPH_C32(0x18ea543b), SPH_C32(0x24d0d1f0), + SPH_C32(0x1f50a3d1) }, + { SPH_C32(0xabda0003), SPH_C32(0x48d5d800), SPH_C32(0xe6940000), + SPH_C32(0x290d0000), SPH_C32(0x0e105759), SPH_C32(0xcf25f242), + SPH_C32(0xa48035c2), SPH_C32(0x8a52f2ee), SPH_C32(0x03670001), + SPH_C32(0x5a317c00), SPH_C32(0x42650000), SPH_C32(0xa65d0000), + SPH_C32(0x68a944e8), SPH_C32(0x073eac5b), SPH_C32(0x6a0072e5), + SPH_C32(0xbe735c4e) }, + { SPH_C32(0xd10b0003), SPH_C32(0xd727e400), SPH_C32(0xdb680000), + SPH_C32(0xdc8b0000), SPH_C32(0x73be3df9), SPH_C32(0x01e6400b), + SPH_C32(0x180ca989), SPH_C32(0x2b17747e), SPH_C32(0x9b6b0001), + SPH_C32(0xaddd6700), SPH_C32(0x679a0000), SPH_C32(0x376b0000), + SPH_C32(0x46cd25f9), SPH_C32(0xfedfe06b), SPH_C32(0x5d5c8439), + SPH_C32(0x5074942a) }, + { SPH_C32(0xdd790003), SPH_C32(0x9ec2eb00), SPH_C32(0x99110000), + SPH_C32(0x80610000), SPH_C32(0x40140de3), SPH_C32(0x1464651f), + SPH_C32(0x8dafe2f2), SPH_C32(0x9f5c74ee), SPH_C32(0x65490001), + SPH_C32(0x0a856200), SPH_C32(0x424b0000), SPH_C32(0xc00b0000), + SPH_C32(0xcffc5d23), SPH_C32(0xe10b180b), SPH_C32(0x138c272c), + SPH_C32(0xf1576bb5) }, + { SPH_C32(0x2f290003), SPH_C32(0x707fe100), SPH_C32(0xfeb90000), + SPH_C32(0x2beb0000), SPH_C32(0xfa8f4523), SPH_C32(0x1e32b86b), + SPH_C32(0x56dc0a9c), SPH_C32(0x8a348be1), SPH_C32(0x693b0001), + SPH_C32(0x43606d00), SPH_C32(0x00320000), SPH_C32(0x9ce10000), + SPH_C32(0xfc566d39), SPH_C32(0xf4893d1f), SPH_C32(0x862f6c57), + SPH_C32(0x451c6b25) }, + { SPH_C32(0x235b0003), SPH_C32(0x399aee00), SPH_C32(0xbcc00000), + SPH_C32(0x77010000), SPH_C32(0xc9257539), SPH_C32(0x0bb09d7f), + SPH_C32(0xc37f41e7), SPH_C32(0x3e7f8b71), SPH_C32(0x97190001), + SPH_C32(0xe4386800), SPH_C32(0x25e30000), SPH_C32(0x6b810000), + SPH_C32(0x756715e3), SPH_C32(0xeb5dc57f), SPH_C32(0xc8ffcf42), + SPH_C32(0xe43f94ba) }, + { SPH_C32(0x94130003), SPH_C32(0x7292f300), SPH_C32(0x22020000), + SPH_C32(0xe7c30000), SPH_C32(0x6d7229d5), SPH_C32(0x22f5d5dd), + SPH_C32(0x0eb00f39), SPH_C32(0xf42480a1), SPH_C32(0x23560001), + SPH_C32(0xbbac6100), SPH_C32(0x50000000), SPH_C32(0xc2da0000), + SPH_C32(0x644c4455), SPH_C32(0x5097112e), SPH_C32(0x3b78922f), + SPH_C32(0x95b57f14) }, + { SPH_C32(0x98610003), SPH_C32(0x3b77fc00), SPH_C32(0x607b0000), + SPH_C32(0xbb290000), SPH_C32(0x5ed819cf), SPH_C32(0x3777f0c9), + SPH_C32(0x9b134442), SPH_C32(0x406f8031), SPH_C32(0xdd740001), + SPH_C32(0x1cf46400), SPH_C32(0x75d10000), SPH_C32(0x35ba0000), + SPH_C32(0xed7d3c8f), SPH_C32(0x4f43e94e), SPH_C32(0x75a8313a), + SPH_C32(0x3496808b) }, + { SPH_C32(0x6a310003), SPH_C32(0xd5caf600), SPH_C32(0x07d30000), + SPH_C32(0x10a30000), SPH_C32(0xe443510f), SPH_C32(0x3d212dbd), + SPH_C32(0x4060ac2c), SPH_C32(0x55077f3e), SPH_C32(0xd1060001), + SPH_C32(0x55116b00), SPH_C32(0x37a80000), SPH_C32(0x69500000), + SPH_C32(0xded70c95), SPH_C32(0x5ac1cc5a), SPH_C32(0xe00b7a41), + SPH_C32(0x80dd801b) }, + { SPH_C32(0x66430003), SPH_C32(0x9c2ff900), SPH_C32(0x45aa0000), + SPH_C32(0x4c490000), SPH_C32(0xd7e96115), SPH_C32(0x28a308a9), + SPH_C32(0xd5c3e757), SPH_C32(0xe14c7fae), SPH_C32(0x2f240001), + SPH_C32(0xf2496e00), SPH_C32(0x12790000), SPH_C32(0x9e300000), + SPH_C32(0x57e6744f), SPH_C32(0x4515343a), SPH_C32(0xaedbd954), + SPH_C32(0x21fe7f84) }, + { SPH_C32(0x69360003), SPH_C32(0xc156e200), SPH_C32(0xecf20000), + SPH_C32(0x293a0000), SPH_C32(0x513f5c55), SPH_C32(0xafaeb14e), + SPH_C32(0x7e28bf9f), SPH_C32(0xeed69f40), SPH_C32(0x664e0001), + SPH_C32(0x1e197600), SPH_C32(0xa96a0000), SPH_C32(0xf9920000), + SPH_C32(0x7a805079), SPH_C32(0x738484f8), SPH_C32(0x2dc4349f), + SPH_C32(0x4a868bcb) }, + { SPH_C32(0x65440003), SPH_C32(0x88b3ed00), SPH_C32(0xae8b0000), + SPH_C32(0x75d00000), SPH_C32(0x62956c4f), SPH_C32(0xba2c945a), + SPH_C32(0xeb8bf4e4), SPH_C32(0x5a9d9fd0), SPH_C32(0x986c0001), + SPH_C32(0xb9417300), SPH_C32(0x8cbb0000), SPH_C32(0x0ef20000), + SPH_C32(0xf3b128a3), SPH_C32(0x6c507c98), SPH_C32(0x6314978a), + SPH_C32(0xeba57454) }, + { SPH_C32(0x97140003), SPH_C32(0x660ee700), SPH_C32(0xc9230000), + SPH_C32(0xde5a0000), SPH_C32(0xd80e248f), SPH_C32(0xb07a492e), + SPH_C32(0x30f81c8a), SPH_C32(0x4ff560df), SPH_C32(0x941e0001), + SPH_C32(0xf0a47c00), SPH_C32(0xcec20000), SPH_C32(0x52180000), + SPH_C32(0xc01b18b9), SPH_C32(0x79d2598c), SPH_C32(0xf6b7dcf1), + SPH_C32(0x5fee74c4) }, + { SPH_C32(0x9b660003), SPH_C32(0x2febe800), SPH_C32(0x8b5a0000), + SPH_C32(0x82b00000), SPH_C32(0xeba41495), SPH_C32(0xa5f86c3a), + SPH_C32(0xa55b57f1), SPH_C32(0xfbbe604f), SPH_C32(0x6a3c0001), + SPH_C32(0x57fc7900), SPH_C32(0xeb130000), SPH_C32(0xa5780000), + SPH_C32(0x492a6063), SPH_C32(0x6606a1ec), SPH_C32(0xb8677fe4), + SPH_C32(0xfecd8b5b) }, + { SPH_C32(0x2c2e0003), SPH_C32(0x64e3f500), SPH_C32(0x15980000), + SPH_C32(0x12720000), SPH_C32(0x4ff34879), SPH_C32(0x8cbd2498), + SPH_C32(0x6894192f), SPH_C32(0x31e56b9f), SPH_C32(0xde730001), + SPH_C32(0x08687000), SPH_C32(0x9ef00000), SPH_C32(0x0c230000), + SPH_C32(0x580131d5), SPH_C32(0xddcc75bd), SPH_C32(0x4be02289), + SPH_C32(0x8f4760f5) }, + { SPH_C32(0x205c0003), SPH_C32(0x2d06fa00), SPH_C32(0x57e10000), + SPH_C32(0x4e980000), SPH_C32(0x7c597863), SPH_C32(0x993f018c), + SPH_C32(0xfd375254), SPH_C32(0x85ae6b0f), SPH_C32(0x20510001), + SPH_C32(0xaf307500), SPH_C32(0xbb210000), SPH_C32(0xfb430000), + SPH_C32(0xd130490f), SPH_C32(0xc2188ddd), SPH_C32(0x0530819c), + SPH_C32(0x2e649f6a) }, + { SPH_C32(0xd20c0003), SPH_C32(0xc3bbf000), SPH_C32(0x30490000), + SPH_C32(0xe5120000), SPH_C32(0xc6c230a3), SPH_C32(0x9369dcf8), + SPH_C32(0x2644ba3a), SPH_C32(0x90c69400), SPH_C32(0x2c230001), + SPH_C32(0xe6d57a00), SPH_C32(0xf9580000), SPH_C32(0xa7a90000), + SPH_C32(0xe29a7915), SPH_C32(0xd79aa8c9), SPH_C32(0x9093cae7), + SPH_C32(0x9a2f9ffa) }, + { SPH_C32(0xde7e0003), SPH_C32(0x8a5eff00), SPH_C32(0x72300000), + SPH_C32(0xb9f80000), SPH_C32(0xf56800b9), SPH_C32(0x86ebf9ec), + SPH_C32(0xb3e7f141), SPH_C32(0x248d9490), SPH_C32(0xd2010001), + SPH_C32(0x418d7f00), SPH_C32(0xdc890000), SPH_C32(0x50c90000), + SPH_C32(0x6bab01cf), SPH_C32(0xc84e50a9), SPH_C32(0xde4369f2), + SPH_C32(0x3b0c6065) }, + { SPH_C32(0xeecf0001), SPH_C32(0x6f564000), SPH_C32(0xf33e0000), + SPH_C32(0xa79e0000), SPH_C32(0xbdb57219), SPH_C32(0xb711ebc5), + SPH_C32(0x4a3b40ba), SPH_C32(0xfeabf254), SPH_C32(0x9b060002), + SPH_C32(0x61468000), SPH_C32(0x221e0000), SPH_C32(0x1d740000), + SPH_C32(0x36715d27), SPH_C32(0x30495c92), SPH_C32(0xf11336a7), + SPH_C32(0xfe1cdc7f) }, + { SPH_C32(0xe2bd0001), SPH_C32(0x26b34f00), SPH_C32(0xb1470000), + SPH_C32(0xfb740000), SPH_C32(0x8e1f4203), SPH_C32(0xa293ced1), + SPH_C32(0xdf980bc1), SPH_C32(0x4ae0f2c4), SPH_C32(0x65240002), + SPH_C32(0xc61e8500), SPH_C32(0x07cf0000), SPH_C32(0xea140000), + SPH_C32(0xbf4025fd), SPH_C32(0x2f9da4f2), SPH_C32(0xbfc395b2), + SPH_C32(0x5f3f23e0) }, + { SPH_C32(0x10ed0001), SPH_C32(0xc80e4500), SPH_C32(0xd6ef0000), + SPH_C32(0x50fe0000), SPH_C32(0x34840ac3), SPH_C32(0xa8c513a5), + SPH_C32(0x04ebe3af), SPH_C32(0x5f880dcb), SPH_C32(0x69560002), + SPH_C32(0x8ffb8a00), SPH_C32(0x45b60000), SPH_C32(0xb6fe0000), + SPH_C32(0x8cea15e7), SPH_C32(0x3a1f81e6), SPH_C32(0x2a60dec9), + SPH_C32(0xeb742370) }, + { SPH_C32(0x1c9f0001), SPH_C32(0x81eb4a00), SPH_C32(0x94960000), + SPH_C32(0x0c140000), SPH_C32(0x072e3ad9), SPH_C32(0xbd4736b1), + SPH_C32(0x9148a8d4), SPH_C32(0xebc30d5b), SPH_C32(0x97740002), + SPH_C32(0x28a38f00), SPH_C32(0x60670000), SPH_C32(0x419e0000), + SPH_C32(0x05db6d3d), SPH_C32(0x25cb7986), SPH_C32(0x64b07ddc), + SPH_C32(0x4a57dcef) }, + { SPH_C32(0xabd70001), SPH_C32(0xcae35700), SPH_C32(0x0a540000), + SPH_C32(0x9cd60000), SPH_C32(0xa3796635), SPH_C32(0x94027e13), + SPH_C32(0x5c87e60a), SPH_C32(0x2198068b), SPH_C32(0x233b0002), + SPH_C32(0x77378600), SPH_C32(0x15840000), SPH_C32(0xe8c50000), + SPH_C32(0x14f03c8b), SPH_C32(0x9e01add7), SPH_C32(0x973720b1), + SPH_C32(0x3bdd3741) }, + { SPH_C32(0xa7a50001), SPH_C32(0x83065800), SPH_C32(0x482d0000), + SPH_C32(0xc03c0000), SPH_C32(0x90d3562f), SPH_C32(0x81805b07), + SPH_C32(0xc924ad71), SPH_C32(0x95d3061b), SPH_C32(0xdd190002), + SPH_C32(0xd06f8300), SPH_C32(0x30550000), SPH_C32(0x1fa50000), + SPH_C32(0x9dc14451), SPH_C32(0x81d555b7), SPH_C32(0xd9e783a4), + SPH_C32(0x9afec8de) }, + { SPH_C32(0x55f50001), SPH_C32(0x6dbb5200), SPH_C32(0x2f850000), + SPH_C32(0x6bb60000), SPH_C32(0x2a481eef), SPH_C32(0x8bd68673), + SPH_C32(0x1257451f), SPH_C32(0x80bbf914), SPH_C32(0xd16b0002), + SPH_C32(0x998a8c00), SPH_C32(0x722c0000), SPH_C32(0x434f0000), + SPH_C32(0xae6b744b), SPH_C32(0x945770a3), SPH_C32(0x4c44c8df), + SPH_C32(0x2eb5c84e) }, + { SPH_C32(0x59870001), SPH_C32(0x245e5d00), SPH_C32(0x6dfc0000), + SPH_C32(0x375c0000), SPH_C32(0x19e22ef5), SPH_C32(0x9e54a367), + SPH_C32(0x87f40e64), SPH_C32(0x34f0f984), SPH_C32(0x2f490002), + SPH_C32(0x3ed28900), SPH_C32(0x57fd0000), SPH_C32(0xb42f0000), + SPH_C32(0x275a0c91), SPH_C32(0x8b8388c3), SPH_C32(0x02946bca), + SPH_C32(0x8f9637d1) }, + { SPH_C32(0x56f20001), SPH_C32(0x79274600), SPH_C32(0xc4a40000), + SPH_C32(0x522f0000), SPH_C32(0x9f3413b5), SPH_C32(0x19591a80), + SPH_C32(0x2c1f56ac), SPH_C32(0x3b6a196a), SPH_C32(0x66230002), + SPH_C32(0xd2829100), SPH_C32(0xecee0000), SPH_C32(0xd38d0000), + SPH_C32(0x0a3c28a7), SPH_C32(0xbd123801), SPH_C32(0x818b8601), + SPH_C32(0xe4eec39e) }, + { SPH_C32(0x5a800001), SPH_C32(0x30c24900), SPH_C32(0x86dd0000), + SPH_C32(0x0ec50000), SPH_C32(0xac9e23af), SPH_C32(0x0cdb3f94), + SPH_C32(0xb9bc1dd7), SPH_C32(0x8f2119fa), SPH_C32(0x98010002), + SPH_C32(0x75da9400), SPH_C32(0xc93f0000), SPH_C32(0x24ed0000), + SPH_C32(0x830d507d), SPH_C32(0xa2c6c061), SPH_C32(0xcf5b2514), + SPH_C32(0x45cd3c01) }, + { SPH_C32(0xa8d00001), SPH_C32(0xde7f4300), SPH_C32(0xe1750000), + SPH_C32(0xa54f0000), SPH_C32(0x16056b6f), SPH_C32(0x068de2e0), + SPH_C32(0x62cff5b9), SPH_C32(0x9a49e6f5), SPH_C32(0x94730002), + SPH_C32(0x3c3f9b00), SPH_C32(0x8b460000), SPH_C32(0x78070000), + SPH_C32(0xb0a76067), SPH_C32(0xb744e575), SPH_C32(0x5af86e6f), + SPH_C32(0xf1863c91) }, + { SPH_C32(0xa4a20001), SPH_C32(0x979a4c00), SPH_C32(0xa30c0000), + SPH_C32(0xf9a50000), SPH_C32(0x25af5b75), SPH_C32(0x130fc7f4), + SPH_C32(0xf76cbec2), SPH_C32(0x2e02e665), SPH_C32(0x6a510002), + SPH_C32(0x9b679e00), SPH_C32(0xae970000), SPH_C32(0x8f670000), + SPH_C32(0x399618bd), SPH_C32(0xa8901d15), SPH_C32(0x1428cd7a), + SPH_C32(0x50a5c30e) }, + { SPH_C32(0x13ea0001), SPH_C32(0xdc925100), SPH_C32(0x3dce0000), + SPH_C32(0x69670000), SPH_C32(0x81f80799), SPH_C32(0x3a4a8f56), + SPH_C32(0x3aa3f01c), SPH_C32(0xe459edb5), SPH_C32(0xde1e0002), + SPH_C32(0xc4f39700), SPH_C32(0xdb740000), SPH_C32(0x263c0000), + SPH_C32(0x28bd490b), SPH_C32(0x135ac944), SPH_C32(0xe7af9017), + SPH_C32(0x212f28a0) }, + { SPH_C32(0x1f980001), SPH_C32(0x95775e00), SPH_C32(0x7fb70000), + SPH_C32(0x358d0000), SPH_C32(0xb2523783), SPH_C32(0x2fc8aa42), + SPH_C32(0xaf00bb67), SPH_C32(0x5012ed25), SPH_C32(0x203c0002), + SPH_C32(0x63ab9200), SPH_C32(0xfea50000), SPH_C32(0xd15c0000), + SPH_C32(0xa18c31d1), SPH_C32(0x0c8e3124), SPH_C32(0xa97f3302), + SPH_C32(0x800cd73f) }, + { SPH_C32(0xedc80001), SPH_C32(0x7bca5400), SPH_C32(0x181f0000), + SPH_C32(0x9e070000), SPH_C32(0x08c97f43), SPH_C32(0x259e7736), + SPH_C32(0x74735309), SPH_C32(0x457a122a), SPH_C32(0x2c4e0002), + SPH_C32(0x2a4e9d00), SPH_C32(0xbcdc0000), SPH_C32(0x8db60000), + SPH_C32(0x922601cb), SPH_C32(0x190c1430), SPH_C32(0x3cdc7879), + SPH_C32(0x3447d7af) }, + { SPH_C32(0xe1ba0001), SPH_C32(0x322f5b00), SPH_C32(0x5a660000), + SPH_C32(0xc2ed0000), SPH_C32(0x3b634f59), SPH_C32(0x301c5222), + SPH_C32(0xe1d01872), SPH_C32(0xf13112ba), SPH_C32(0xd26c0002), + SPH_C32(0x8d169800), SPH_C32(0x990d0000), SPH_C32(0x7ad60000), + SPH_C32(0x1b177911), SPH_C32(0x06d8ec50), SPH_C32(0x720cdb6c), + SPH_C32(0x95642830) }, + { SPH_C32(0x9b6b0001), SPH_C32(0xaddd6700), SPH_C32(0x679a0000), + SPH_C32(0x376b0000), SPH_C32(0x46cd25f9), SPH_C32(0xfedfe06b), + SPH_C32(0x5d5c8439), SPH_C32(0x5074942a), SPH_C32(0x4a600002), + SPH_C32(0x7afa8300), SPH_C32(0xbcf20000), SPH_C32(0xebe00000), + SPH_C32(0x35731800), SPH_C32(0xff39a060), SPH_C32(0x45502db0), + SPH_C32(0x7b63e054) }, + { SPH_C32(0x97190001), SPH_C32(0xe4386800), SPH_C32(0x25e30000), + SPH_C32(0x6b810000), SPH_C32(0x756715e3), SPH_C32(0xeb5dc57f), + SPH_C32(0xc8ffcf42), SPH_C32(0xe43f94ba), SPH_C32(0xb4420002), + SPH_C32(0xdda28600), SPH_C32(0x99230000), SPH_C32(0x1c800000), + SPH_C32(0xbc4260da), SPH_C32(0xe0ed5800), SPH_C32(0x0b808ea5), + SPH_C32(0xda401fcb) }, + { SPH_C32(0x65490001), SPH_C32(0x0a856200), SPH_C32(0x424b0000), + SPH_C32(0xc00b0000), SPH_C32(0xcffc5d23), SPH_C32(0xe10b180b), + SPH_C32(0x138c272c), SPH_C32(0xf1576bb5), SPH_C32(0xb8300002), + SPH_C32(0x94478900), SPH_C32(0xdb5a0000), SPH_C32(0x406a0000), + SPH_C32(0x8fe850c0), SPH_C32(0xf56f7d14), SPH_C32(0x9e23c5de), + SPH_C32(0x6e0b1f5b) }, + { SPH_C32(0x693b0001), SPH_C32(0x43606d00), SPH_C32(0x00320000), + SPH_C32(0x9ce10000), SPH_C32(0xfc566d39), SPH_C32(0xf4893d1f), + SPH_C32(0x862f6c57), SPH_C32(0x451c6b25), SPH_C32(0x46120002), + SPH_C32(0x331f8c00), SPH_C32(0xfe8b0000), SPH_C32(0xb70a0000), + SPH_C32(0x06d9281a), SPH_C32(0xeabb8574), SPH_C32(0xd0f366cb), + SPH_C32(0xcf28e0c4) }, + { SPH_C32(0xde730001), SPH_C32(0x08687000), SPH_C32(0x9ef00000), + SPH_C32(0x0c230000), SPH_C32(0x580131d5), SPH_C32(0xddcc75bd), + SPH_C32(0x4be02289), SPH_C32(0x8f4760f5), SPH_C32(0xf25d0002), + SPH_C32(0x6c8b8500), SPH_C32(0x8b680000), SPH_C32(0x1e510000), + SPH_C32(0x17f279ac), SPH_C32(0x51715125), SPH_C32(0x23743ba6), + SPH_C32(0xbea20b6a) }, + { SPH_C32(0xd2010001), SPH_C32(0x418d7f00), SPH_C32(0xdc890000), + SPH_C32(0x50c90000), SPH_C32(0x6bab01cf), SPH_C32(0xc84e50a9), + SPH_C32(0xde4369f2), SPH_C32(0x3b0c6065), SPH_C32(0x0c7f0002), + SPH_C32(0xcbd38000), SPH_C32(0xaeb90000), SPH_C32(0xe9310000), + SPH_C32(0x9ec30176), SPH_C32(0x4ea5a945), SPH_C32(0x6da498b3), + SPH_C32(0x1f81f4f5) }, + { SPH_C32(0x20510001), SPH_C32(0xaf307500), SPH_C32(0xbb210000), + SPH_C32(0xfb430000), SPH_C32(0xd130490f), SPH_C32(0xc2188ddd), + SPH_C32(0x0530819c), SPH_C32(0x2e649f6a), SPH_C32(0x000d0002), + SPH_C32(0x82368f00), SPH_C32(0xecc00000), SPH_C32(0xb5db0000), + SPH_C32(0xad69316c), SPH_C32(0x5b278c51), SPH_C32(0xf807d3c8), + SPH_C32(0xabcaf465) }, + { SPH_C32(0x2c230001), SPH_C32(0xe6d57a00), SPH_C32(0xf9580000), + SPH_C32(0xa7a90000), SPH_C32(0xe29a7915), SPH_C32(0xd79aa8c9), + SPH_C32(0x9093cae7), SPH_C32(0x9a2f9ffa), SPH_C32(0xfe2f0002), + SPH_C32(0x256e8a00), SPH_C32(0xc9110000), SPH_C32(0x42bb0000), + SPH_C32(0x245849b6), SPH_C32(0x44f37431), SPH_C32(0xb6d770dd), + SPH_C32(0x0ae90bfa) }, + { SPH_C32(0x23560001), SPH_C32(0xbbac6100), SPH_C32(0x50000000), + SPH_C32(0xc2da0000), SPH_C32(0x644c4455), SPH_C32(0x5097112e), + SPH_C32(0x3b78922f), SPH_C32(0x95b57f14), SPH_C32(0xb7450002), + SPH_C32(0xc93e9200), SPH_C32(0x72020000), SPH_C32(0x25190000), + SPH_C32(0x093e6d80), SPH_C32(0x7262c4f3), SPH_C32(0x35c89d16), + SPH_C32(0x6191ffb5) }, + { SPH_C32(0x2f240001), SPH_C32(0xf2496e00), SPH_C32(0x12790000), + SPH_C32(0x9e300000), SPH_C32(0x57e6744f), SPH_C32(0x4515343a), + SPH_C32(0xaedbd954), SPH_C32(0x21fe7f84), SPH_C32(0x49670002), + SPH_C32(0x6e669700), SPH_C32(0x57d30000), SPH_C32(0xd2790000), + SPH_C32(0x800f155a), SPH_C32(0x6db63c93), SPH_C32(0x7b183e03), + SPH_C32(0xc0b2002a) }, + { SPH_C32(0xdd740001), SPH_C32(0x1cf46400), SPH_C32(0x75d10000), + SPH_C32(0x35ba0000), SPH_C32(0xed7d3c8f), SPH_C32(0x4f43e94e), + SPH_C32(0x75a8313a), SPH_C32(0x3496808b), SPH_C32(0x45150002), + SPH_C32(0x27839800), SPH_C32(0x15aa0000), SPH_C32(0x8e930000), + SPH_C32(0xb3a52540), SPH_C32(0x78341987), SPH_C32(0xeebb7578), + SPH_C32(0x74f900ba) }, + { SPH_C32(0xd1060001), SPH_C32(0x55116b00), SPH_C32(0x37a80000), + SPH_C32(0x69500000), SPH_C32(0xded70c95), SPH_C32(0x5ac1cc5a), + SPH_C32(0xe00b7a41), SPH_C32(0x80dd801b), SPH_C32(0xbb370002), + SPH_C32(0x80db9d00), SPH_C32(0x307b0000), SPH_C32(0x79f30000), + SPH_C32(0x3a945d9a), SPH_C32(0x67e0e1e7), SPH_C32(0xa06bd66d), + SPH_C32(0xd5daff25) }, + { SPH_C32(0x664e0001), SPH_C32(0x1e197600), SPH_C32(0xa96a0000), + SPH_C32(0xf9920000), SPH_C32(0x7a805079), SPH_C32(0x738484f8), + SPH_C32(0x2dc4349f), SPH_C32(0x4a868bcb), SPH_C32(0x0f780002), + SPH_C32(0xdf4f9400), SPH_C32(0x45980000), SPH_C32(0xd0a80000), + SPH_C32(0x2bbf0c2c), SPH_C32(0xdc2a35b6), SPH_C32(0x53ec8b00), + SPH_C32(0xa450148b) }, + { SPH_C32(0x6a3c0001), SPH_C32(0x57fc7900), SPH_C32(0xeb130000), + SPH_C32(0xa5780000), SPH_C32(0x492a6063), SPH_C32(0x6606a1ec), + SPH_C32(0xb8677fe4), SPH_C32(0xfecd8b5b), SPH_C32(0xf15a0002), + SPH_C32(0x78179100), SPH_C32(0x60490000), SPH_C32(0x27c80000), + SPH_C32(0xa28e74f6), SPH_C32(0xc3fecdd6), SPH_C32(0x1d3c2815), + SPH_C32(0x0573eb14) }, + { SPH_C32(0x986c0001), SPH_C32(0xb9417300), SPH_C32(0x8cbb0000), + SPH_C32(0x0ef20000), SPH_C32(0xf3b128a3), SPH_C32(0x6c507c98), + SPH_C32(0x6314978a), SPH_C32(0xeba57454), SPH_C32(0xfd280002), + SPH_C32(0x31f29e00), SPH_C32(0x22300000), SPH_C32(0x7b220000), + SPH_C32(0x912444ec), SPH_C32(0xd67ce8c2), SPH_C32(0x889f636e), + SPH_C32(0xb138eb84) }, + { SPH_C32(0x941e0001), SPH_C32(0xf0a47c00), SPH_C32(0xcec20000), + SPH_C32(0x52180000), SPH_C32(0xc01b18b9), SPH_C32(0x79d2598c), + SPH_C32(0xf6b7dcf1), SPH_C32(0x5fee74c4), SPH_C32(0x030a0002), + SPH_C32(0x96aa9b00), SPH_C32(0x07e10000), SPH_C32(0x8c420000), + SPH_C32(0x18153c36), SPH_C32(0xc9a810a2), SPH_C32(0xc64fc07b), + SPH_C32(0x101b141b) }, + { SPH_C32(0x3fa90001), SPH_C32(0x74ea4300), SPH_C32(0x6dd20000), + SPH_C32(0x510a0000), SPH_C32(0xbeb7373e), SPH_C32(0x78611737), + SPH_C32(0xfe785bad), SPH_C32(0x7bd4ce7f), SPH_C32(0x3fc40002), + SPH_C32(0xb871a400), SPH_C32(0x28560000), SPH_C32(0x7b150000), + SPH_C32(0xce0b4fe0), SPH_C32(0xb6f7abce), SPH_C32(0x5237e933), + SPH_C32(0xd5bc862a) }, + { SPH_C32(0x33db0001), SPH_C32(0x3d0f4c00), SPH_C32(0x2fab0000), + SPH_C32(0x0de00000), SPH_C32(0x8d1d0724), SPH_C32(0x6de33223), + SPH_C32(0x6bdb10d6), SPH_C32(0xcf9fceef), SPH_C32(0xc1e60002), + SPH_C32(0x1f29a100), SPH_C32(0x0d870000), SPH_C32(0x8c750000), + SPH_C32(0x473a373a), SPH_C32(0xa92353ae), SPH_C32(0x1ce74a26), + SPH_C32(0x749f79b5) }, + { SPH_C32(0xc18b0001), SPH_C32(0xd3b24600), SPH_C32(0x48030000), + SPH_C32(0xa66a0000), SPH_C32(0x37864fe4), SPH_C32(0x67b5ef57), + SPH_C32(0xb0a8f8b8), SPH_C32(0xdaf731e0), SPH_C32(0xcd940002), + SPH_C32(0x56ccae00), SPH_C32(0x4ffe0000), SPH_C32(0xd09f0000), + SPH_C32(0x74900720), SPH_C32(0xbca176ba), SPH_C32(0x8944015d), + SPH_C32(0xc0d47925) }, + { SPH_C32(0xcdf90001), SPH_C32(0x9a574900), SPH_C32(0x0a7a0000), + SPH_C32(0xfa800000), SPH_C32(0x042c7ffe), SPH_C32(0x7237ca43), + SPH_C32(0x250bb3c3), SPH_C32(0x6ebc3170), SPH_C32(0x33b60002), + SPH_C32(0xf194ab00), SPH_C32(0x6a2f0000), SPH_C32(0x27ff0000), + SPH_C32(0xfda17ffa), SPH_C32(0xa3758eda), SPH_C32(0xc794a248), + SPH_C32(0x61f786ba) }, + { SPH_C32(0x7ab10001), SPH_C32(0xd15f5400), SPH_C32(0x94b80000), + SPH_C32(0x6a420000), SPH_C32(0xa07b2312), SPH_C32(0x5b7282e1), + SPH_C32(0xe8c4fd1d), SPH_C32(0xa4e73aa0), SPH_C32(0x87f90002), + SPH_C32(0xae00a200), SPH_C32(0x1fcc0000), SPH_C32(0x8ea40000), + SPH_C32(0xec8a2e4c), SPH_C32(0x18bf5a8b), SPH_C32(0x3413ff25), + SPH_C32(0x107d6d14) }, + { SPH_C32(0x76c30001), SPH_C32(0x98ba5b00), SPH_C32(0xd6c10000), + SPH_C32(0x36a80000), SPH_C32(0x93d11308), SPH_C32(0x4ef0a7f5), + SPH_C32(0x7d67b666), SPH_C32(0x10ac3a30), SPH_C32(0x79db0002), + SPH_C32(0x0958a700), SPH_C32(0x3a1d0000), SPH_C32(0x79c40000), + SPH_C32(0x65bb5696), SPH_C32(0x076ba2eb), SPH_C32(0x7ac35c30), + SPH_C32(0xb15e928b) }, + { SPH_C32(0x84930001), SPH_C32(0x76075100), SPH_C32(0xb1690000), + SPH_C32(0x9d220000), SPH_C32(0x294a5bc8), SPH_C32(0x44a67a81), + SPH_C32(0xa6145e08), SPH_C32(0x05c4c53f), SPH_C32(0x75a90002), + SPH_C32(0x40bda800), SPH_C32(0x78640000), SPH_C32(0x252e0000), + SPH_C32(0x5611668c), SPH_C32(0x12e987ff), SPH_C32(0xef60174b), + SPH_C32(0x0515921b) }, + { SPH_C32(0x88e10001), SPH_C32(0x3fe25e00), SPH_C32(0xf3100000), + SPH_C32(0xc1c80000), SPH_C32(0x1ae06bd2), SPH_C32(0x51245f95), + SPH_C32(0x33b71573), SPH_C32(0xb18fc5af), SPH_C32(0x8b8b0002), + SPH_C32(0xe7e5ad00), SPH_C32(0x5db50000), SPH_C32(0xd24e0000), + SPH_C32(0xdf201e56), SPH_C32(0x0d3d7f9f), SPH_C32(0xa1b0b45e), + SPH_C32(0xa4366d84) }, + { SPH_C32(0x87940001), SPH_C32(0x629b4500), SPH_C32(0x5a480000), + SPH_C32(0xa4bb0000), SPH_C32(0x9c365692), SPH_C32(0xd629e672), + SPH_C32(0x985c4dbb), SPH_C32(0xbe152541), SPH_C32(0xc2e10002), + SPH_C32(0x0bb5b500), SPH_C32(0xe6a60000), SPH_C32(0xb5ec0000), + SPH_C32(0xf2463a60), SPH_C32(0x3baccf5d), SPH_C32(0x22af5995), + SPH_C32(0xcf4e99cb) }, + { SPH_C32(0x8be60001), SPH_C32(0x2b7e4a00), SPH_C32(0x18310000), + SPH_C32(0xf8510000), SPH_C32(0xaf9c6688), SPH_C32(0xc3abc366), + SPH_C32(0x0dff06c0), SPH_C32(0x0a5e25d1), SPH_C32(0x3cc30002), + SPH_C32(0xacedb000), SPH_C32(0xc3770000), SPH_C32(0x428c0000), + SPH_C32(0x7b7742ba), SPH_C32(0x2478373d), SPH_C32(0x6c7ffa80), + SPH_C32(0x6e6d6654) }, + { SPH_C32(0x79b60001), SPH_C32(0xc5c34000), SPH_C32(0x7f990000), + SPH_C32(0x53db0000), SPH_C32(0x15072e48), SPH_C32(0xc9fd1e12), + SPH_C32(0xd68ceeae), SPH_C32(0x1f36dade), SPH_C32(0x30b10002), + SPH_C32(0xe508bf00), SPH_C32(0x810e0000), SPH_C32(0x1e660000), + SPH_C32(0x48dd72a0), SPH_C32(0x31fa1229), SPH_C32(0xf9dcb1fb), + SPH_C32(0xda2666c4) }, + { SPH_C32(0x75c40001), SPH_C32(0x8c264f00), SPH_C32(0x3de00000), + SPH_C32(0x0f310000), SPH_C32(0x26ad1e52), SPH_C32(0xdc7f3b06), + SPH_C32(0x432fa5d5), SPH_C32(0xab7dda4e), SPH_C32(0xce930002), + SPH_C32(0x4250ba00), SPH_C32(0xa4df0000), SPH_C32(0xe9060000), + SPH_C32(0xc1ec0a7a), SPH_C32(0x2e2eea49), SPH_C32(0xb70c12ee), + SPH_C32(0x7b05995b) }, + { SPH_C32(0xc28c0001), SPH_C32(0xc72e5200), SPH_C32(0xa3220000), + SPH_C32(0x9ff30000), SPH_C32(0x82fa42be), SPH_C32(0xf53a73a4), + SPH_C32(0x8ee0eb0b), SPH_C32(0x6126d19e), SPH_C32(0x7adc0002), + SPH_C32(0x1dc4b300), SPH_C32(0xd13c0000), SPH_C32(0x405d0000), + SPH_C32(0xd0c75bcc), SPH_C32(0x95e43e18), SPH_C32(0x448b4f83), + SPH_C32(0x0a8f72f5) }, + { SPH_C32(0xcefe0001), SPH_C32(0x8ecb5d00), SPH_C32(0xe15b0000), + SPH_C32(0xc3190000), SPH_C32(0xb15072a4), SPH_C32(0xe0b856b0), + SPH_C32(0x1b43a070), SPH_C32(0xd56dd10e), SPH_C32(0x84fe0002), + SPH_C32(0xba9cb600), SPH_C32(0xf4ed0000), SPH_C32(0xb73d0000), + SPH_C32(0x59f62316), SPH_C32(0x8a30c678), SPH_C32(0x0a5bec96), + SPH_C32(0xabac8d6a) }, + { SPH_C32(0x3cae0001), SPH_C32(0x60765700), SPH_C32(0x86f30000), + SPH_C32(0x68930000), SPH_C32(0x0bcb3a64), SPH_C32(0xeaee8bc4), + SPH_C32(0xc030481e), SPH_C32(0xc0052e01), SPH_C32(0x888c0002), + SPH_C32(0xf379b900), SPH_C32(0xb6940000), SPH_C32(0xebd70000), + SPH_C32(0x6a5c130c), SPH_C32(0x9fb2e36c), SPH_C32(0x9ff8a7ed), + SPH_C32(0x1fe78dfa) }, + { SPH_C32(0x30dc0001), SPH_C32(0x29935800), SPH_C32(0xc48a0000), + SPH_C32(0x34790000), SPH_C32(0x38610a7e), SPH_C32(0xff6caed0), + SPH_C32(0x55930365), SPH_C32(0x744e2e91), SPH_C32(0x76ae0002), + SPH_C32(0x5421bc00), SPH_C32(0x93450000), SPH_C32(0x1cb70000), + SPH_C32(0xe36d6bd6), SPH_C32(0x80661b0c), SPH_C32(0xd12804f8), + SPH_C32(0xbec47265) }, + { SPH_C32(0x4a0d0001), SPH_C32(0xb6616400), SPH_C32(0xf9760000), + SPH_C32(0xc1ff0000), SPH_C32(0x45cf60de), SPH_C32(0x31af1c99), + SPH_C32(0xe91f9f2e), SPH_C32(0xd50ba801), SPH_C32(0xeea20002), + SPH_C32(0xa3cda700), SPH_C32(0xb6ba0000), SPH_C32(0x8d810000), + SPH_C32(0xcd090ac7), SPH_C32(0x7987573c), SPH_C32(0xe674f224), + SPH_C32(0x50c3ba01) }, + { SPH_C32(0x467f0001), SPH_C32(0xff846b00), SPH_C32(0xbb0f0000), + SPH_C32(0x9d150000), SPH_C32(0x766550c4), SPH_C32(0x242d398d), + SPH_C32(0x7cbcd455), SPH_C32(0x6140a891), SPH_C32(0x10800002), + SPH_C32(0x0495a200), SPH_C32(0x936b0000), SPH_C32(0x7ae10000), + SPH_C32(0x4438721d), SPH_C32(0x6653af5c), SPH_C32(0xa8a45131), + SPH_C32(0xf1e0459e) }, + { SPH_C32(0xb42f0001), SPH_C32(0x11396100), SPH_C32(0xdca70000), + SPH_C32(0x369f0000), SPH_C32(0xccfe1804), SPH_C32(0x2e7be4f9), + SPH_C32(0xa7cf3c3b), SPH_C32(0x7428579e), SPH_C32(0x1cf20002), + SPH_C32(0x4d70ad00), SPH_C32(0xd1120000), SPH_C32(0x260b0000), + SPH_C32(0x77924207), SPH_C32(0x73d18a48), SPH_C32(0x3d071a4a), + SPH_C32(0x45ab450e) }, + { SPH_C32(0xb85d0001), SPH_C32(0x58dc6e00), SPH_C32(0x9ede0000), + SPH_C32(0x6a750000), SPH_C32(0xff54281e), SPH_C32(0x3bf9c1ed), + SPH_C32(0x326c7740), SPH_C32(0xc063570e), SPH_C32(0xe2d00002), + SPH_C32(0xea28a800), SPH_C32(0xf4c30000), SPH_C32(0xd16b0000), + SPH_C32(0xfea33add), SPH_C32(0x6c057228), SPH_C32(0x73d7b95f), + SPH_C32(0xe488ba91) }, + { SPH_C32(0x0f150001), SPH_C32(0x13d47300), SPH_C32(0x001c0000), + SPH_C32(0xfab70000), SPH_C32(0x5b0374f2), SPH_C32(0x12bc894f), + SPH_C32(0xffa3399e), SPH_C32(0x0a385cde), SPH_C32(0x569f0002), + SPH_C32(0xb5bca100), SPH_C32(0x81200000), SPH_C32(0x78300000), + SPH_C32(0xef886b6b), SPH_C32(0xd7cfa679), SPH_C32(0x8050e432), + SPH_C32(0x9502513f) }, + { SPH_C32(0x03670001), SPH_C32(0x5a317c00), SPH_C32(0x42650000), + SPH_C32(0xa65d0000), SPH_C32(0x68a944e8), SPH_C32(0x073eac5b), + SPH_C32(0x6a0072e5), SPH_C32(0xbe735c4e), SPH_C32(0xa8bd0002), + SPH_C32(0x12e4a400), SPH_C32(0xa4f10000), SPH_C32(0x8f500000), + SPH_C32(0x66b913b1), SPH_C32(0xc81b5e19), SPH_C32(0xce804727), + SPH_C32(0x3421aea0) }, + { SPH_C32(0xf1370001), SPH_C32(0xb48c7600), SPH_C32(0x25cd0000), + SPH_C32(0x0dd70000), SPH_C32(0xd2320c28), SPH_C32(0x0d68712f), + SPH_C32(0xb1739a8b), SPH_C32(0xab1ba341), SPH_C32(0xa4cf0002), + SPH_C32(0x5b01ab00), SPH_C32(0xe6880000), SPH_C32(0xd3ba0000), + SPH_C32(0x551323ab), SPH_C32(0xdd997b0d), SPH_C32(0x5b230c5c), + SPH_C32(0x806aae30) }, + { SPH_C32(0xfd450001), SPH_C32(0xfd697900), SPH_C32(0x67b40000), + SPH_C32(0x513d0000), SPH_C32(0xe1983c32), SPH_C32(0x18ea543b), + SPH_C32(0x24d0d1f0), SPH_C32(0x1f50a3d1), SPH_C32(0x5aed0002), + SPH_C32(0xfc59ae00), SPH_C32(0xc3590000), SPH_C32(0x24da0000), + SPH_C32(0xdc225b71), SPH_C32(0xc24d836d), SPH_C32(0x15f3af49), + SPH_C32(0x214951af) }, + { SPH_C32(0xf2300001), SPH_C32(0xa0106200), SPH_C32(0xceec0000), + SPH_C32(0x344e0000), SPH_C32(0x674e0172), SPH_C32(0x9fe7eddc), + SPH_C32(0x8f3b8938), SPH_C32(0x10ca433f), SPH_C32(0x13870002), + SPH_C32(0x1009b600), SPH_C32(0x784a0000), SPH_C32(0x43780000), + SPH_C32(0xf1447f47), SPH_C32(0xf4dc33af), SPH_C32(0x96ec4282), + SPH_C32(0x4a31a5e0) }, + { SPH_C32(0xfe420001), SPH_C32(0xe9f56d00), SPH_C32(0x8c950000), + SPH_C32(0x68a40000), SPH_C32(0x54e43168), SPH_C32(0x8a65c8c8), + SPH_C32(0x1a98c243), SPH_C32(0xa48143af), SPH_C32(0xeda50002), + SPH_C32(0xb751b300), SPH_C32(0x5d9b0000), SPH_C32(0xb4180000), + SPH_C32(0x7875079d), SPH_C32(0xeb08cbcf), SPH_C32(0xd83ce197), + SPH_C32(0xeb125a7f) }, + { SPH_C32(0x0c120001), SPH_C32(0x07486700), SPH_C32(0xeb3d0000), + SPH_C32(0xc32e0000), SPH_C32(0xee7f79a8), SPH_C32(0x803315bc), + SPH_C32(0xc1eb2a2d), SPH_C32(0xb1e9bca0), SPH_C32(0xe1d70002), + SPH_C32(0xfeb4bc00), SPH_C32(0x1fe20000), SPH_C32(0xe8f20000), + SPH_C32(0x4bdf3787), SPH_C32(0xfe8aeedb), SPH_C32(0x4d9faaec), + SPH_C32(0x5f595aef) }, + { SPH_C32(0x00600001), SPH_C32(0x4ead6800), SPH_C32(0xa9440000), + SPH_C32(0x9fc40000), SPH_C32(0xddd549b2), SPH_C32(0x95b130a8), + SPH_C32(0x54486156), SPH_C32(0x05a2bc30), SPH_C32(0x1ff50002), + SPH_C32(0x59ecb900), SPH_C32(0x3a330000), SPH_C32(0x1f920000), + SPH_C32(0xc2ee4f5d), SPH_C32(0xe15e16bb), SPH_C32(0x034f09f9), + SPH_C32(0xfe7aa570) }, + { SPH_C32(0xb7280001), SPH_C32(0x05a57500), SPH_C32(0x37860000), + SPH_C32(0x0f060000), SPH_C32(0x7982155e), SPH_C32(0xbcf4780a), + SPH_C32(0x99872f88), SPH_C32(0xcff9b7e0), SPH_C32(0xabba0002), + SPH_C32(0x0678b000), SPH_C32(0x4fd00000), SPH_C32(0xb6c90000), + SPH_C32(0xd3c51eeb), SPH_C32(0x5a94c2ea), SPH_C32(0xf0c85494), + SPH_C32(0x8ff04ede) }, + { SPH_C32(0xbb5a0001), SPH_C32(0x4c407a00), SPH_C32(0x75ff0000), + SPH_C32(0x53ec0000), SPH_C32(0x4a282544), SPH_C32(0xa9765d1e), + SPH_C32(0x0c2464f3), SPH_C32(0x7bb2b770), SPH_C32(0x55980002), + SPH_C32(0xa120b500), SPH_C32(0x6a010000), SPH_C32(0x41a90000), + SPH_C32(0x5af46631), SPH_C32(0x45403a8a), SPH_C32(0xbe18f781), + SPH_C32(0x2ed3b141) }, + { SPH_C32(0x490a0001), SPH_C32(0xa2fd7000), SPH_C32(0x12570000), + SPH_C32(0xf8660000), SPH_C32(0xf0b36d84), SPH_C32(0xa320806a), + SPH_C32(0xd7578c9d), SPH_C32(0x6eda487f), SPH_C32(0x59ea0002), + SPH_C32(0xe8c5ba00), SPH_C32(0x28780000), SPH_C32(0x1d430000), + SPH_C32(0x695e562b), SPH_C32(0x50c21f9e), SPH_C32(0x2bbbbcfa), + SPH_C32(0x9a98b1d1) }, + { SPH_C32(0x45780001), SPH_C32(0xeb187f00), SPH_C32(0x502e0000), + SPH_C32(0xa48c0000), SPH_C32(0xc3195d9e), SPH_C32(0xb6a2a57e), + SPH_C32(0x42f4c7e6), SPH_C32(0xda9148ef), SPH_C32(0xa7c80002), + SPH_C32(0x4f9dbf00), SPH_C32(0x0da90000), SPH_C32(0xea230000), + SPH_C32(0xe06f2ef1), SPH_C32(0x4f16e7fe), SPH_C32(0x656b1fef), + SPH_C32(0x3bbb4e4e) }, + { SPH_C32(0x9b060002), SPH_C32(0x61468000), SPH_C32(0x221e0000), + SPH_C32(0x1d740000), SPH_C32(0x36715d27), SPH_C32(0x30495c92), + SPH_C32(0xf11336a7), SPH_C32(0xfe1cdc7f), SPH_C32(0x75c90003), + SPH_C32(0x0e10c000), SPH_C32(0xd1200000), SPH_C32(0xbaea0000), + SPH_C32(0x8bc42f3e), SPH_C32(0x8758b757), SPH_C32(0xbb28761d), + SPH_C32(0x00b72e2b) }, + { SPH_C32(0x97740002), SPH_C32(0x28a38f00), SPH_C32(0x60670000), + SPH_C32(0x419e0000), SPH_C32(0x05db6d3d), SPH_C32(0x25cb7986), + SPH_C32(0x64b07ddc), SPH_C32(0x4a57dcef), SPH_C32(0x8beb0003), + SPH_C32(0xa948c500), SPH_C32(0xf4f10000), SPH_C32(0x4d8a0000), + SPH_C32(0x02f557e4), SPH_C32(0x988c4f37), SPH_C32(0xf5f8d508), + SPH_C32(0xa194d1b4) }, + { SPH_C32(0x65240002), SPH_C32(0xc61e8500), SPH_C32(0x07cf0000), + SPH_C32(0xea140000), SPH_C32(0xbf4025fd), SPH_C32(0x2f9da4f2), + SPH_C32(0xbfc395b2), SPH_C32(0x5f3f23e0), SPH_C32(0x87990003), + SPH_C32(0xe0adca00), SPH_C32(0xb6880000), SPH_C32(0x11600000), + SPH_C32(0x315f67fe), SPH_C32(0x8d0e6a23), SPH_C32(0x605b9e73), + SPH_C32(0x15dfd124) }, + { SPH_C32(0x69560002), SPH_C32(0x8ffb8a00), SPH_C32(0x45b60000), + SPH_C32(0xb6fe0000), SPH_C32(0x8cea15e7), SPH_C32(0x3a1f81e6), + SPH_C32(0x2a60dec9), SPH_C32(0xeb742370), SPH_C32(0x79bb0003), + SPH_C32(0x47f5cf00), SPH_C32(0x93590000), SPH_C32(0xe6000000), + SPH_C32(0xb86e1f24), SPH_C32(0x92da9243), SPH_C32(0x2e8b3d66), + SPH_C32(0xb4fc2ebb) }, + { SPH_C32(0xde1e0002), SPH_C32(0xc4f39700), SPH_C32(0xdb740000), + SPH_C32(0x263c0000), SPH_C32(0x28bd490b), SPH_C32(0x135ac944), + SPH_C32(0xe7af9017), SPH_C32(0x212f28a0), SPH_C32(0xcdf40003), + SPH_C32(0x1861c600), SPH_C32(0xe6ba0000), SPH_C32(0x4f5b0000), + SPH_C32(0xa9454e92), SPH_C32(0x29104612), SPH_C32(0xdd0c600b), + SPH_C32(0xc576c515) }, + { SPH_C32(0xd26c0002), SPH_C32(0x8d169800), SPH_C32(0x990d0000), + SPH_C32(0x7ad60000), SPH_C32(0x1b177911), SPH_C32(0x06d8ec50), + SPH_C32(0x720cdb6c), SPH_C32(0x95642830), SPH_C32(0x33d60003), + SPH_C32(0xbf39c300), SPH_C32(0xc36b0000), SPH_C32(0xb83b0000), + SPH_C32(0x20743648), SPH_C32(0x36c4be72), SPH_C32(0x93dcc31e), + SPH_C32(0x64553a8a) }, + { SPH_C32(0x203c0002), SPH_C32(0x63ab9200), SPH_C32(0xfea50000), + SPH_C32(0xd15c0000), SPH_C32(0xa18c31d1), SPH_C32(0x0c8e3124), + SPH_C32(0xa97f3302), SPH_C32(0x800cd73f), SPH_C32(0x3fa40003), + SPH_C32(0xf6dccc00), SPH_C32(0x81120000), SPH_C32(0xe4d10000), + SPH_C32(0x13de0652), SPH_C32(0x23469b66), SPH_C32(0x067f8865), + SPH_C32(0xd01e3a1a) }, + { SPH_C32(0x2c4e0002), SPH_C32(0x2a4e9d00), SPH_C32(0xbcdc0000), + SPH_C32(0x8db60000), SPH_C32(0x922601cb), SPH_C32(0x190c1430), + SPH_C32(0x3cdc7879), SPH_C32(0x3447d7af), SPH_C32(0xc1860003), + SPH_C32(0x5184c900), SPH_C32(0xa4c30000), SPH_C32(0x13b10000), + SPH_C32(0x9aef7e88), SPH_C32(0x3c926306), SPH_C32(0x48af2b70), + SPH_C32(0x713dc585) }, + { SPH_C32(0x233b0002), SPH_C32(0x77378600), SPH_C32(0x15840000), + SPH_C32(0xe8c50000), SPH_C32(0x14f03c8b), SPH_C32(0x9e01add7), + SPH_C32(0x973720b1), SPH_C32(0x3bdd3741), SPH_C32(0x88ec0003), + SPH_C32(0xbdd4d100), SPH_C32(0x1fd00000), SPH_C32(0x74130000), + SPH_C32(0xb7895abe), SPH_C32(0x0a03d3c4), SPH_C32(0xcbb0c6bb), + SPH_C32(0x1a4531ca) }, + { SPH_C32(0x2f490002), SPH_C32(0x3ed28900), SPH_C32(0x57fd0000), + SPH_C32(0xb42f0000), SPH_C32(0x275a0c91), SPH_C32(0x8b8388c3), + SPH_C32(0x02946bca), SPH_C32(0x8f9637d1), SPH_C32(0x76ce0003), + SPH_C32(0x1a8cd400), SPH_C32(0x3a010000), SPH_C32(0x83730000), + SPH_C32(0x3eb82264), SPH_C32(0x15d72ba4), SPH_C32(0x856065ae), + SPH_C32(0xbb66ce55) }, + { SPH_C32(0xdd190002), SPH_C32(0xd06f8300), SPH_C32(0x30550000), + SPH_C32(0x1fa50000), SPH_C32(0x9dc14451), SPH_C32(0x81d555b7), + SPH_C32(0xd9e783a4), SPH_C32(0x9afec8de), SPH_C32(0x7abc0003), + SPH_C32(0x5369db00), SPH_C32(0x78780000), SPH_C32(0xdf990000), + SPH_C32(0x0d12127e), SPH_C32(0x00550eb0), SPH_C32(0x10c32ed5), + SPH_C32(0x0f2dcec5) }, + { SPH_C32(0xd16b0002), SPH_C32(0x998a8c00), SPH_C32(0x722c0000), + SPH_C32(0x434f0000), SPH_C32(0xae6b744b), SPH_C32(0x945770a3), + SPH_C32(0x4c44c8df), SPH_C32(0x2eb5c84e), SPH_C32(0x849e0003), + SPH_C32(0xf431de00), SPH_C32(0x5da90000), SPH_C32(0x28f90000), + SPH_C32(0x84236aa4), SPH_C32(0x1f81f6d0), SPH_C32(0x5e138dc0), + SPH_C32(0xae0e315a) }, + { SPH_C32(0x66230002), SPH_C32(0xd2829100), SPH_C32(0xecee0000), + SPH_C32(0xd38d0000), SPH_C32(0x0a3c28a7), SPH_C32(0xbd123801), + SPH_C32(0x818b8601), SPH_C32(0xe4eec39e), SPH_C32(0x30d10003), + SPH_C32(0xaba5d700), SPH_C32(0x284a0000), SPH_C32(0x81a20000), + SPH_C32(0x95083b12), SPH_C32(0xa44b2281), SPH_C32(0xad94d0ad), + SPH_C32(0xdf84daf4) }, + { SPH_C32(0x6a510002), SPH_C32(0x9b679e00), SPH_C32(0xae970000), + SPH_C32(0x8f670000), SPH_C32(0x399618bd), SPH_C32(0xa8901d15), + SPH_C32(0x1428cd7a), SPH_C32(0x50a5c30e), SPH_C32(0xcef30003), + SPH_C32(0x0cfdd200), SPH_C32(0x0d9b0000), SPH_C32(0x76c20000), + SPH_C32(0x1c3943c8), SPH_C32(0xbb9fdae1), SPH_C32(0xe34473b8), + SPH_C32(0x7ea7256b) }, + { SPH_C32(0x98010002), SPH_C32(0x75da9400), SPH_C32(0xc93f0000), + SPH_C32(0x24ed0000), SPH_C32(0x830d507d), SPH_C32(0xa2c6c061), + SPH_C32(0xcf5b2514), SPH_C32(0x45cd3c01), SPH_C32(0xc2810003), + SPH_C32(0x4518dd00), SPH_C32(0x4fe20000), SPH_C32(0x2a280000), + SPH_C32(0x2f9373d2), SPH_C32(0xae1dfff5), SPH_C32(0x76e738c3), + SPH_C32(0xcaec25fb) }, + { SPH_C32(0x94730002), SPH_C32(0x3c3f9b00), SPH_C32(0x8b460000), + SPH_C32(0x78070000), SPH_C32(0xb0a76067), SPH_C32(0xb744e575), + SPH_C32(0x5af86e6f), SPH_C32(0xf1863c91), SPH_C32(0x3ca30003), + SPH_C32(0xe240d800), SPH_C32(0x6a330000), SPH_C32(0xdd480000), + SPH_C32(0xa6a20b08), SPH_C32(0xb1c90795), SPH_C32(0x38379bd6), + SPH_C32(0x6bcfda64) }, + { SPH_C32(0xeea20002), SPH_C32(0xa3cda700), SPH_C32(0xb6ba0000), + SPH_C32(0x8d810000), SPH_C32(0xcd090ac7), SPH_C32(0x7987573c), + SPH_C32(0xe674f224), SPH_C32(0x50c3ba01), SPH_C32(0xa4af0003), + SPH_C32(0x15acc300), SPH_C32(0x4fcc0000), SPH_C32(0x4c7e0000), + SPH_C32(0x88c66a19), SPH_C32(0x48284ba5), SPH_C32(0x0f6b6d0a), + SPH_C32(0x85c81200) }, + { SPH_C32(0xe2d00002), SPH_C32(0xea28a800), SPH_C32(0xf4c30000), + SPH_C32(0xd16b0000), SPH_C32(0xfea33add), SPH_C32(0x6c057228), + SPH_C32(0x73d7b95f), SPH_C32(0xe488ba91), SPH_C32(0x5a8d0003), + SPH_C32(0xb2f4c600), SPH_C32(0x6a1d0000), SPH_C32(0xbb1e0000), + SPH_C32(0x01f712c3), SPH_C32(0x57fcb3c5), SPH_C32(0x41bbce1f), + SPH_C32(0x24ebed9f) }, + { SPH_C32(0x10800002), SPH_C32(0x0495a200), SPH_C32(0x936b0000), + SPH_C32(0x7ae10000), SPH_C32(0x4438721d), SPH_C32(0x6653af5c), + SPH_C32(0xa8a45131), SPH_C32(0xf1e0459e), SPH_C32(0x56ff0003), + SPH_C32(0xfb11c900), SPH_C32(0x28640000), SPH_C32(0xe7f40000), + SPH_C32(0x325d22d9), SPH_C32(0x427e96d1), SPH_C32(0xd4188564), + SPH_C32(0x90a0ed0f) }, + { SPH_C32(0x1cf20002), SPH_C32(0x4d70ad00), SPH_C32(0xd1120000), + SPH_C32(0x260b0000), SPH_C32(0x77924207), SPH_C32(0x73d18a48), + SPH_C32(0x3d071a4a), SPH_C32(0x45ab450e), SPH_C32(0xa8dd0003), + SPH_C32(0x5c49cc00), SPH_C32(0x0db50000), SPH_C32(0x10940000), + SPH_C32(0xbb6c5a03), SPH_C32(0x5daa6eb1), SPH_C32(0x9ac82671), + SPH_C32(0x31831290) }, + { SPH_C32(0xabba0002), SPH_C32(0x0678b000), SPH_C32(0x4fd00000), + SPH_C32(0xb6c90000), SPH_C32(0xd3c51eeb), SPH_C32(0x5a94c2ea), + SPH_C32(0xf0c85494), SPH_C32(0x8ff04ede), SPH_C32(0x1c920003), + SPH_C32(0x03ddc500), SPH_C32(0x78560000), SPH_C32(0xb9cf0000), + SPH_C32(0xaa470bb5), SPH_C32(0xe660bae0), SPH_C32(0x694f7b1c), + SPH_C32(0x4009f93e) }, + { SPH_C32(0xa7c80002), SPH_C32(0x4f9dbf00), SPH_C32(0x0da90000), + SPH_C32(0xea230000), SPH_C32(0xe06f2ef1), SPH_C32(0x4f16e7fe), + SPH_C32(0x656b1fef), SPH_C32(0x3bbb4e4e), SPH_C32(0xe2b00003), + SPH_C32(0xa485c000), SPH_C32(0x5d870000), SPH_C32(0x4eaf0000), + SPH_C32(0x2376736f), SPH_C32(0xf9b44280), SPH_C32(0x279fd809), + SPH_C32(0xe12a06a1) }, + { SPH_C32(0x55980002), SPH_C32(0xa120b500), SPH_C32(0x6a010000), + SPH_C32(0x41a90000), SPH_C32(0x5af46631), SPH_C32(0x45403a8a), + SPH_C32(0xbe18f781), SPH_C32(0x2ed3b141), SPH_C32(0xeec20003), + SPH_C32(0xed60cf00), SPH_C32(0x1ffe0000), SPH_C32(0x12450000), + SPH_C32(0x10dc4375), SPH_C32(0xec366794), SPH_C32(0xb23c9372), + SPH_C32(0x55610631) }, + { SPH_C32(0x59ea0002), SPH_C32(0xe8c5ba00), SPH_C32(0x28780000), + SPH_C32(0x1d430000), SPH_C32(0x695e562b), SPH_C32(0x50c21f9e), + SPH_C32(0x2bbbbcfa), SPH_C32(0x9a98b1d1), SPH_C32(0x10e00003), + SPH_C32(0x4a38ca00), SPH_C32(0x3a2f0000), SPH_C32(0xe5250000), + SPH_C32(0x99ed3baf), SPH_C32(0xf3e29ff4), SPH_C32(0xfcec3067), + SPH_C32(0xf442f9ae) }, + { SPH_C32(0x569f0002), SPH_C32(0xb5bca100), SPH_C32(0x81200000), + SPH_C32(0x78300000), SPH_C32(0xef886b6b), SPH_C32(0xd7cfa679), + SPH_C32(0x8050e432), SPH_C32(0x9502513f), SPH_C32(0x598a0003), + SPH_C32(0xa668d200), SPH_C32(0x813c0000), SPH_C32(0x82870000), + SPH_C32(0xb48b1f99), SPH_C32(0xc5732f36), SPH_C32(0x7ff3ddac), + SPH_C32(0x9f3a0de1) }, + { SPH_C32(0x5aed0002), SPH_C32(0xfc59ae00), SPH_C32(0xc3590000), + SPH_C32(0x24da0000), SPH_C32(0xdc225b71), SPH_C32(0xc24d836d), + SPH_C32(0x15f3af49), SPH_C32(0x214951af), SPH_C32(0xa7a80003), + SPH_C32(0x0130d700), SPH_C32(0xa4ed0000), SPH_C32(0x75e70000), + SPH_C32(0x3dba6743), SPH_C32(0xdaa7d756), SPH_C32(0x31237eb9), + SPH_C32(0x3e19f27e) }, + { SPH_C32(0xa8bd0002), SPH_C32(0x12e4a400), SPH_C32(0xa4f10000), + SPH_C32(0x8f500000), SPH_C32(0x66b913b1), SPH_C32(0xc81b5e19), + SPH_C32(0xce804727), SPH_C32(0x3421aea0), SPH_C32(0xabda0003), + SPH_C32(0x48d5d800), SPH_C32(0xe6940000), SPH_C32(0x290d0000), + SPH_C32(0x0e105759), SPH_C32(0xcf25f242), SPH_C32(0xa48035c2), + SPH_C32(0x8a52f2ee) }, + { SPH_C32(0xa4cf0002), SPH_C32(0x5b01ab00), SPH_C32(0xe6880000), + SPH_C32(0xd3ba0000), SPH_C32(0x551323ab), SPH_C32(0xdd997b0d), + SPH_C32(0x5b230c5c), SPH_C32(0x806aae30), SPH_C32(0x55f80003), + SPH_C32(0xef8ddd00), SPH_C32(0xc3450000), SPH_C32(0xde6d0000), + SPH_C32(0x87212f83), SPH_C32(0xd0f10a22), SPH_C32(0xea5096d7), + SPH_C32(0x2b710d71) }, + { SPH_C32(0x13870002), SPH_C32(0x1009b600), SPH_C32(0x784a0000), + SPH_C32(0x43780000), SPH_C32(0xf1447f47), SPH_C32(0xf4dc33af), + SPH_C32(0x96ec4282), SPH_C32(0x4a31a5e0), SPH_C32(0xe1b70003), + SPH_C32(0xb019d400), SPH_C32(0xb6a60000), SPH_C32(0x77360000), + SPH_C32(0x960a7e35), SPH_C32(0x6b3bde73), SPH_C32(0x19d7cbba), + SPH_C32(0x5afbe6df) }, + { SPH_C32(0x1ff50002), SPH_C32(0x59ecb900), SPH_C32(0x3a330000), + SPH_C32(0x1f920000), SPH_C32(0xc2ee4f5d), SPH_C32(0xe15e16bb), + SPH_C32(0x034f09f9), SPH_C32(0xfe7aa570), SPH_C32(0x1f950003), + SPH_C32(0x1741d100), SPH_C32(0x93770000), SPH_C32(0x80560000), + SPH_C32(0x1f3b06ef), SPH_C32(0x74ef2613), SPH_C32(0x570768af), + SPH_C32(0xfbd81940) }, + { SPH_C32(0xeda50002), SPH_C32(0xb751b300), SPH_C32(0x5d9b0000), + SPH_C32(0xb4180000), SPH_C32(0x7875079d), SPH_C32(0xeb08cbcf), + SPH_C32(0xd83ce197), SPH_C32(0xeb125a7f), SPH_C32(0x13e70003), + SPH_C32(0x5ea4de00), SPH_C32(0xd10e0000), SPH_C32(0xdcbc0000), + SPH_C32(0x2c9136f5), SPH_C32(0x616d0307), SPH_C32(0xc2a423d4), + SPH_C32(0x4f9319d0) }, + { SPH_C32(0xe1d70002), SPH_C32(0xfeb4bc00), SPH_C32(0x1fe20000), + SPH_C32(0xe8f20000), SPH_C32(0x4bdf3787), SPH_C32(0xfe8aeedb), + SPH_C32(0x4d9faaec), SPH_C32(0x5f595aef), SPH_C32(0xedc50003), + SPH_C32(0xf9fcdb00), SPH_C32(0xf4df0000), SPH_C32(0x2bdc0000), + SPH_C32(0xa5a04e2f), SPH_C32(0x7eb9fb67), SPH_C32(0x8c7480c1), + SPH_C32(0xeeb0e64f) }, + { SPH_C32(0x4a600002), SPH_C32(0x7afa8300), SPH_C32(0xbcf20000), + SPH_C32(0xebe00000), SPH_C32(0x35731800), SPH_C32(0xff39a060), + SPH_C32(0x45502db0), SPH_C32(0x7b63e054), SPH_C32(0xd10b0003), + SPH_C32(0xd727e400), SPH_C32(0xdb680000), SPH_C32(0xdc8b0000), + SPH_C32(0x73be3df9), SPH_C32(0x01e6400b), SPH_C32(0x180ca989), + SPH_C32(0x2b17747e) }, + { SPH_C32(0x46120002), SPH_C32(0x331f8c00), SPH_C32(0xfe8b0000), + SPH_C32(0xb70a0000), SPH_C32(0x06d9281a), SPH_C32(0xeabb8574), + SPH_C32(0xd0f366cb), SPH_C32(0xcf28e0c4), SPH_C32(0x2f290003), + SPH_C32(0x707fe100), SPH_C32(0xfeb90000), SPH_C32(0x2beb0000), + SPH_C32(0xfa8f4523), SPH_C32(0x1e32b86b), SPH_C32(0x56dc0a9c), + SPH_C32(0x8a348be1) }, + { SPH_C32(0xb4420002), SPH_C32(0xdda28600), SPH_C32(0x99230000), + SPH_C32(0x1c800000), SPH_C32(0xbc4260da), SPH_C32(0xe0ed5800), + SPH_C32(0x0b808ea5), SPH_C32(0xda401fcb), SPH_C32(0x235b0003), + SPH_C32(0x399aee00), SPH_C32(0xbcc00000), SPH_C32(0x77010000), + SPH_C32(0xc9257539), SPH_C32(0x0bb09d7f), SPH_C32(0xc37f41e7), + SPH_C32(0x3e7f8b71) }, + { SPH_C32(0xb8300002), SPH_C32(0x94478900), SPH_C32(0xdb5a0000), + SPH_C32(0x406a0000), SPH_C32(0x8fe850c0), SPH_C32(0xf56f7d14), + SPH_C32(0x9e23c5de), SPH_C32(0x6e0b1f5b), SPH_C32(0xdd790003), + SPH_C32(0x9ec2eb00), SPH_C32(0x99110000), SPH_C32(0x80610000), + SPH_C32(0x40140de3), SPH_C32(0x1464651f), SPH_C32(0x8dafe2f2), + SPH_C32(0x9f5c74ee) }, + { SPH_C32(0x0f780002), SPH_C32(0xdf4f9400), SPH_C32(0x45980000), + SPH_C32(0xd0a80000), SPH_C32(0x2bbf0c2c), SPH_C32(0xdc2a35b6), + SPH_C32(0x53ec8b00), SPH_C32(0xa450148b), SPH_C32(0x69360003), + SPH_C32(0xc156e200), SPH_C32(0xecf20000), SPH_C32(0x293a0000), + SPH_C32(0x513f5c55), SPH_C32(0xafaeb14e), SPH_C32(0x7e28bf9f), + SPH_C32(0xeed69f40) }, + { SPH_C32(0x030a0002), SPH_C32(0x96aa9b00), SPH_C32(0x07e10000), + SPH_C32(0x8c420000), SPH_C32(0x18153c36), SPH_C32(0xc9a810a2), + SPH_C32(0xc64fc07b), SPH_C32(0x101b141b), SPH_C32(0x97140003), + SPH_C32(0x660ee700), SPH_C32(0xc9230000), SPH_C32(0xde5a0000), + SPH_C32(0xd80e248f), SPH_C32(0xb07a492e), SPH_C32(0x30f81c8a), + SPH_C32(0x4ff560df) }, + { SPH_C32(0xf15a0002), SPH_C32(0x78179100), SPH_C32(0x60490000), + SPH_C32(0x27c80000), SPH_C32(0xa28e74f6), SPH_C32(0xc3fecdd6), + SPH_C32(0x1d3c2815), SPH_C32(0x0573eb14), SPH_C32(0x9b660003), + SPH_C32(0x2febe800), SPH_C32(0x8b5a0000), SPH_C32(0x82b00000), + SPH_C32(0xeba41495), SPH_C32(0xa5f86c3a), SPH_C32(0xa55b57f1), + SPH_C32(0xfbbe604f) }, + { SPH_C32(0xfd280002), SPH_C32(0x31f29e00), SPH_C32(0x22300000), + SPH_C32(0x7b220000), SPH_C32(0x912444ec), SPH_C32(0xd67ce8c2), + SPH_C32(0x889f636e), SPH_C32(0xb138eb84), SPH_C32(0x65440003), + SPH_C32(0x88b3ed00), SPH_C32(0xae8b0000), SPH_C32(0x75d00000), + SPH_C32(0x62956c4f), SPH_C32(0xba2c945a), SPH_C32(0xeb8bf4e4), + SPH_C32(0x5a9d9fd0) }, + { SPH_C32(0xf25d0002), SPH_C32(0x6c8b8500), SPH_C32(0x8b680000), + SPH_C32(0x1e510000), SPH_C32(0x17f279ac), SPH_C32(0x51715125), + SPH_C32(0x23743ba6), SPH_C32(0xbea20b6a), SPH_C32(0x2c2e0003), + SPH_C32(0x64e3f500), SPH_C32(0x15980000), SPH_C32(0x12720000), + SPH_C32(0x4ff34879), SPH_C32(0x8cbd2498), SPH_C32(0x6894192f), + SPH_C32(0x31e56b9f) }, + { SPH_C32(0xfe2f0002), SPH_C32(0x256e8a00), SPH_C32(0xc9110000), + SPH_C32(0x42bb0000), SPH_C32(0x245849b6), SPH_C32(0x44f37431), + SPH_C32(0xb6d770dd), SPH_C32(0x0ae90bfa), SPH_C32(0xd20c0003), + SPH_C32(0xc3bbf000), SPH_C32(0x30490000), SPH_C32(0xe5120000), + SPH_C32(0xc6c230a3), SPH_C32(0x9369dcf8), SPH_C32(0x2644ba3a), + SPH_C32(0x90c69400) }, + { SPH_C32(0x0c7f0002), SPH_C32(0xcbd38000), SPH_C32(0xaeb90000), + SPH_C32(0xe9310000), SPH_C32(0x9ec30176), SPH_C32(0x4ea5a945), + SPH_C32(0x6da498b3), SPH_C32(0x1f81f4f5), SPH_C32(0xde7e0003), + SPH_C32(0x8a5eff00), SPH_C32(0x72300000), SPH_C32(0xb9f80000), + SPH_C32(0xf56800b9), SPH_C32(0x86ebf9ec), SPH_C32(0xb3e7f141), + SPH_C32(0x248d9490) }, + { SPH_C32(0x000d0002), SPH_C32(0x82368f00), SPH_C32(0xecc00000), + SPH_C32(0xb5db0000), SPH_C32(0xad69316c), SPH_C32(0x5b278c51), + SPH_C32(0xf807d3c8), SPH_C32(0xabcaf465), SPH_C32(0x205c0003), + SPH_C32(0x2d06fa00), SPH_C32(0x57e10000), SPH_C32(0x4e980000), + SPH_C32(0x7c597863), SPH_C32(0x993f018c), SPH_C32(0xfd375254), + SPH_C32(0x85ae6b0f) }, + { SPH_C32(0xb7450002), SPH_C32(0xc93e9200), SPH_C32(0x72020000), + SPH_C32(0x25190000), SPH_C32(0x093e6d80), SPH_C32(0x7262c4f3), + SPH_C32(0x35c89d16), SPH_C32(0x6191ffb5), SPH_C32(0x94130003), + SPH_C32(0x7292f300), SPH_C32(0x22020000), SPH_C32(0xe7c30000), + SPH_C32(0x6d7229d5), SPH_C32(0x22f5d5dd), SPH_C32(0x0eb00f39), + SPH_C32(0xf42480a1) }, + { SPH_C32(0xbb370002), SPH_C32(0x80db9d00), SPH_C32(0x307b0000), + SPH_C32(0x79f30000), SPH_C32(0x3a945d9a), SPH_C32(0x67e0e1e7), + SPH_C32(0xa06bd66d), SPH_C32(0xd5daff25), SPH_C32(0x6a310003), + SPH_C32(0xd5caf600), SPH_C32(0x07d30000), SPH_C32(0x10a30000), + SPH_C32(0xe443510f), SPH_C32(0x3d212dbd), SPH_C32(0x4060ac2c), + SPH_C32(0x55077f3e) }, + { SPH_C32(0x49670002), SPH_C32(0x6e669700), SPH_C32(0x57d30000), + SPH_C32(0xd2790000), SPH_C32(0x800f155a), SPH_C32(0x6db63c93), + SPH_C32(0x7b183e03), SPH_C32(0xc0b2002a), SPH_C32(0x66430003), + SPH_C32(0x9c2ff900), SPH_C32(0x45aa0000), SPH_C32(0x4c490000), + SPH_C32(0xd7e96115), SPH_C32(0x28a308a9), SPH_C32(0xd5c3e757), + SPH_C32(0xe14c7fae) }, + { SPH_C32(0x45150002), SPH_C32(0x27839800), SPH_C32(0x15aa0000), + SPH_C32(0x8e930000), SPH_C32(0xb3a52540), SPH_C32(0x78341987), + SPH_C32(0xeebb7578), SPH_C32(0x74f900ba), SPH_C32(0x98610003), + SPH_C32(0x3b77fc00), SPH_C32(0x607b0000), SPH_C32(0xbb290000), + SPH_C32(0x5ed819cf), SPH_C32(0x3777f0c9), SPH_C32(0x9b134442), + SPH_C32(0x406f8031) }, + { SPH_C32(0x3fc40002), SPH_C32(0xb871a400), SPH_C32(0x28560000), + SPH_C32(0x7b150000), SPH_C32(0xce0b4fe0), SPH_C32(0xb6f7abce), + SPH_C32(0x5237e933), SPH_C32(0xd5bc862a), SPH_C32(0x006d0003), + SPH_C32(0xcc9be700), SPH_C32(0x45840000), SPH_C32(0x2a1f0000), + SPH_C32(0x70bc78de), SPH_C32(0xce96bcf9), SPH_C32(0xac4fb29e), + SPH_C32(0xae684855) }, + { SPH_C32(0x33b60002), SPH_C32(0xf194ab00), SPH_C32(0x6a2f0000), + SPH_C32(0x27ff0000), SPH_C32(0xfda17ffa), SPH_C32(0xa3758eda), + SPH_C32(0xc794a248), SPH_C32(0x61f786ba), SPH_C32(0xfe4f0003), + SPH_C32(0x6bc3e200), SPH_C32(0x60550000), SPH_C32(0xdd7f0000), + SPH_C32(0xf98d0004), SPH_C32(0xd1424499), SPH_C32(0xe29f118b), + SPH_C32(0x0f4bb7ca) }, + { SPH_C32(0xc1e60002), SPH_C32(0x1f29a100), SPH_C32(0x0d870000), + SPH_C32(0x8c750000), SPH_C32(0x473a373a), SPH_C32(0xa92353ae), + SPH_C32(0x1ce74a26), SPH_C32(0x749f79b5), SPH_C32(0xf23d0003), + SPH_C32(0x2226ed00), SPH_C32(0x222c0000), SPH_C32(0x81950000), + SPH_C32(0xca27301e), SPH_C32(0xc4c0618d), SPH_C32(0x773c5af0), + SPH_C32(0xbb00b75a) }, + { SPH_C32(0xcd940002), SPH_C32(0x56ccae00), SPH_C32(0x4ffe0000), + SPH_C32(0xd09f0000), SPH_C32(0x74900720), SPH_C32(0xbca176ba), + SPH_C32(0x8944015d), SPH_C32(0xc0d47925), SPH_C32(0x0c1f0003), + SPH_C32(0x857ee800), SPH_C32(0x07fd0000), SPH_C32(0x76f50000), + SPH_C32(0x431648c4), SPH_C32(0xdb1499ed), SPH_C32(0x39ecf9e5), + SPH_C32(0x1a2348c5) }, + { SPH_C32(0x7adc0002), SPH_C32(0x1dc4b300), SPH_C32(0xd13c0000), + SPH_C32(0x405d0000), SPH_C32(0xd0c75bcc), SPH_C32(0x95e43e18), + SPH_C32(0x448b4f83), SPH_C32(0x0a8f72f5), SPH_C32(0xb8500003), + SPH_C32(0xdaeae100), SPH_C32(0x721e0000), SPH_C32(0xdfae0000), + SPH_C32(0x523d1972), SPH_C32(0x60de4dbc), SPH_C32(0xca6ba488), + SPH_C32(0x6ba9a36b) }, + { SPH_C32(0x76ae0002), SPH_C32(0x5421bc00), SPH_C32(0x93450000), + SPH_C32(0x1cb70000), SPH_C32(0xe36d6bd6), SPH_C32(0x80661b0c), + SPH_C32(0xd12804f8), SPH_C32(0xbec47265), SPH_C32(0x46720003), + SPH_C32(0x7db2e400), SPH_C32(0x57cf0000), SPH_C32(0x28ce0000), + SPH_C32(0xdb0c61a8), SPH_C32(0x7f0ab5dc), SPH_C32(0x84bb079d), + SPH_C32(0xca8a5cf4) }, + { SPH_C32(0x84fe0002), SPH_C32(0xba9cb600), SPH_C32(0xf4ed0000), + SPH_C32(0xb73d0000), SPH_C32(0x59f62316), SPH_C32(0x8a30c678), + SPH_C32(0x0a5bec96), SPH_C32(0xabac8d6a), SPH_C32(0x4a000003), + SPH_C32(0x3457eb00), SPH_C32(0x15b60000), SPH_C32(0x74240000), + SPH_C32(0xe8a651b2), SPH_C32(0x6a8890c8), SPH_C32(0x11184ce6), + SPH_C32(0x7ec15c64) }, + { SPH_C32(0x888c0002), SPH_C32(0xf379b900), SPH_C32(0xb6940000), + SPH_C32(0xebd70000), SPH_C32(0x6a5c130c), SPH_C32(0x9fb2e36c), + SPH_C32(0x9ff8a7ed), SPH_C32(0x1fe78dfa), SPH_C32(0xb4220003), + SPH_C32(0x930fee00), SPH_C32(0x30670000), SPH_C32(0x83440000), + SPH_C32(0x61972968), SPH_C32(0x755c68a8), SPH_C32(0x5fc8eff3), + SPH_C32(0xdfe2a3fb) }, + { SPH_C32(0x87f90002), SPH_C32(0xae00a200), SPH_C32(0x1fcc0000), + SPH_C32(0x8ea40000), SPH_C32(0xec8a2e4c), SPH_C32(0x18bf5a8b), + SPH_C32(0x3413ff25), SPH_C32(0x107d6d14), SPH_C32(0xfd480003), + SPH_C32(0x7f5ff600), SPH_C32(0x8b740000), SPH_C32(0xe4e60000), + SPH_C32(0x4cf10d5e), SPH_C32(0x43cdd86a), SPH_C32(0xdcd70238), + SPH_C32(0xb49a57b4) }, + { SPH_C32(0x8b8b0002), SPH_C32(0xe7e5ad00), SPH_C32(0x5db50000), + SPH_C32(0xd24e0000), SPH_C32(0xdf201e56), SPH_C32(0x0d3d7f9f), + SPH_C32(0xa1b0b45e), SPH_C32(0xa4366d84), SPH_C32(0x036a0003), + SPH_C32(0xd807f300), SPH_C32(0xaea50000), SPH_C32(0x13860000), + SPH_C32(0xc5c07584), SPH_C32(0x5c19200a), SPH_C32(0x9207a12d), + SPH_C32(0x15b9a82b) }, + { SPH_C32(0x79db0002), SPH_C32(0x0958a700), SPH_C32(0x3a1d0000), + SPH_C32(0x79c40000), SPH_C32(0x65bb5696), SPH_C32(0x076ba2eb), + SPH_C32(0x7ac35c30), SPH_C32(0xb15e928b), SPH_C32(0x0f180003), + SPH_C32(0x91e2fc00), SPH_C32(0xecdc0000), SPH_C32(0x4f6c0000), + SPH_C32(0xf66a459e), SPH_C32(0x499b051e), SPH_C32(0x07a4ea56), + SPH_C32(0xa1f2a8bb) }, + { SPH_C32(0x75a90002), SPH_C32(0x40bda800), SPH_C32(0x78640000), + SPH_C32(0x252e0000), SPH_C32(0x5611668c), SPH_C32(0x12e987ff), + SPH_C32(0xef60174b), SPH_C32(0x0515921b), SPH_C32(0xf13a0003), + SPH_C32(0x36baf900), SPH_C32(0xc90d0000), SPH_C32(0xb80c0000), + SPH_C32(0x7f5b3d44), SPH_C32(0x564ffd7e), SPH_C32(0x49744943), + SPH_C32(0x00d15724) }, + { SPH_C32(0xc2e10002), SPH_C32(0x0bb5b500), SPH_C32(0xe6a60000), + SPH_C32(0xb5ec0000), SPH_C32(0xf2463a60), SPH_C32(0x3baccf5d), + SPH_C32(0x22af5995), SPH_C32(0xcf4e99cb), SPH_C32(0x45750003), + SPH_C32(0x692ef000), SPH_C32(0xbcee0000), SPH_C32(0x11570000), + SPH_C32(0x6e706cf2), SPH_C32(0xed85292f), SPH_C32(0xbaf3142e), + SPH_C32(0x715bbc8a) }, + { SPH_C32(0xce930002), SPH_C32(0x4250ba00), SPH_C32(0xa4df0000), + SPH_C32(0xe9060000), SPH_C32(0xc1ec0a7a), SPH_C32(0x2e2eea49), + SPH_C32(0xb70c12ee), SPH_C32(0x7b05995b), SPH_C32(0xbb570003), + SPH_C32(0xce76f500), SPH_C32(0x993f0000), SPH_C32(0xe6370000), + SPH_C32(0xe7411428), SPH_C32(0xf251d14f), SPH_C32(0xf423b73b), + SPH_C32(0xd0784315) }, + { SPH_C32(0x3cc30002), SPH_C32(0xacedb000), SPH_C32(0xc3770000), + SPH_C32(0x428c0000), SPH_C32(0x7b7742ba), SPH_C32(0x2478373d), + SPH_C32(0x6c7ffa80), SPH_C32(0x6e6d6654), SPH_C32(0xb7250003), + SPH_C32(0x8793fa00), SPH_C32(0xdb460000), SPH_C32(0xbadd0000), + SPH_C32(0xd4eb2432), SPH_C32(0xe7d3f45b), SPH_C32(0x6180fc40), + SPH_C32(0x64334385) }, + { SPH_C32(0x30b10002), SPH_C32(0xe508bf00), SPH_C32(0x810e0000), + SPH_C32(0x1e660000), SPH_C32(0x48dd72a0), SPH_C32(0x31fa1229), + SPH_C32(0xf9dcb1fb), SPH_C32(0xda2666c4), SPH_C32(0x49070003), + SPH_C32(0x20cbff00), SPH_C32(0xfe970000), SPH_C32(0x4dbd0000), + SPH_C32(0x5dda5ce8), SPH_C32(0xf8070c3b), SPH_C32(0x2f505f55), + SPH_C32(0xc510bc1a) } +}; + +static const sph_u32 T512_24[256][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x86790000), SPH_C32(0x3f390002), SPH_C32(0xe19ae000), + SPH_C32(0x98560000), SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), + SPH_C32(0xd3dd4944), SPH_C32(0x161ddab9), SPH_C32(0x30b70000), + SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), SPH_C32(0x42c40000), + SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), SPH_C32(0x21afa1ea), + SPH_C32(0xb0a51834) }, + { SPH_C32(0x30b70000), SPH_C32(0xe5d00000), SPH_C32(0xf4f46000), + SPH_C32(0x42c40000), SPH_C32(0x63b83d6a), SPH_C32(0x78ba9460), + SPH_C32(0x21afa1ea), SPH_C32(0xb0a51834), SPH_C32(0xb6ce0000), + SPH_C32(0xdae90002), SPH_C32(0x156e8000), SPH_C32(0xda920000), + SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), SPH_C32(0xf272e8ae), + SPH_C32(0xa6b8c28d) }, + { SPH_C32(0xb6ce0000), SPH_C32(0xdae90002), SPH_C32(0x156e8000), + SPH_C32(0xda920000), SPH_C32(0xf6dd5a64), SPH_C32(0x36325c8a), + SPH_C32(0xf272e8ae), SPH_C32(0xa6b8c28d), SPH_C32(0x86790000), + SPH_C32(0x3f390002), SPH_C32(0xe19ae000), SPH_C32(0x98560000), + SPH_C32(0x9565670e), SPH_C32(0x4e88c8ea), SPH_C32(0xd3dd4944), + SPH_C32(0x161ddab9) }, + { SPH_C32(0x14190000), SPH_C32(0x23ca003c), SPH_C32(0x50df0000), + SPH_C32(0x44b60000), SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), + SPH_C32(0x61e610b0), SPH_C32(0xdbcadb80), SPH_C32(0xe3430000), + SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), SPH_C32(0xaa4e0000), + SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), SPH_C32(0x123db156), + SPH_C32(0x3a4e99d7) }, + { SPH_C32(0x92600000), SPH_C32(0x1cf3003e), SPH_C32(0xb145e000), + SPH_C32(0xdce00000), SPH_C32(0x8e0900be), SPH_C32(0x727b649f), + SPH_C32(0xb23b59f4), SPH_C32(0xcdd70139), SPH_C32(0xd3f40000), + SPH_C32(0xdf9e0014), SPH_C32(0x06326000), SPH_C32(0xe88a0000), + SPH_C32(0xb8a67fcc), SPH_C32(0x5dd12a75), SPH_C32(0x339210bc), + SPH_C32(0x8aeb81e3) }, + { SPH_C32(0x24ae0000), SPH_C32(0xc61a003c), SPH_C32(0xa42b6000), + SPH_C32(0x06720000), SPH_C32(0x78d45ada), SPH_C32(0x44493815), + SPH_C32(0x4049b15a), SPH_C32(0x6b6fc3b4), SPH_C32(0x558d0000), + SPH_C32(0xe0a70016), SPH_C32(0xe7a88000), SPH_C32(0x70dc0000), + SPH_C32(0x2dc318c2), SPH_C32(0x1359e29f), SPH_C32(0xe04f59f8), + SPH_C32(0x9cf65b5a) }, + { SPH_C32(0xa2d70000), SPH_C32(0xf923003e), SPH_C32(0x45b18000), + SPH_C32(0x9e240000), SPH_C32(0xedb13dd4), SPH_C32(0x0ac1f0ff), + SPH_C32(0x9394f81e), SPH_C32(0x7d72190d), SPH_C32(0x653a0000), + SPH_C32(0x05770016), SPH_C32(0x135ce000), SPH_C32(0x32180000), + SPH_C32(0x4e7b25a8), SPH_C32(0x6be376ff), SPH_C32(0xc1e0f812), + SPH_C32(0x2c53436e) }, + { SPH_C32(0xe3430000), SPH_C32(0x3a4e0014), SPH_C32(0xf2c60000), + SPH_C32(0xaa4e0000), SPH_C32(0xdb1e42a6), SPH_C32(0x256bbe15), + SPH_C32(0x123db156), SPH_C32(0x3a4e99d7), SPH_C32(0xf75a0000), + SPH_C32(0x19840028), SPH_C32(0xa2190000), SPH_C32(0xeef80000), + SPH_C32(0xc0722516), SPH_C32(0x19981260), SPH_C32(0x73dba1e6), + SPH_C32(0xe1844257) }, + { SPH_C32(0x653a0000), SPH_C32(0x05770016), SPH_C32(0x135ce000), + SPH_C32(0x32180000), SPH_C32(0x4e7b25a8), SPH_C32(0x6be376ff), + SPH_C32(0xc1e0f812), SPH_C32(0x2c53436e), SPH_C32(0xc7ed0000), + SPH_C32(0xfc540028), SPH_C32(0x56ed6000), SPH_C32(0xac3c0000), + SPH_C32(0xa3ca187c), SPH_C32(0x61228600), SPH_C32(0x5274000c), + SPH_C32(0x51215a63) }, + { SPH_C32(0xd3f40000), SPH_C32(0xdf9e0014), SPH_C32(0x06326000), + SPH_C32(0xe88a0000), SPH_C32(0xb8a67fcc), SPH_C32(0x5dd12a75), + SPH_C32(0x339210bc), SPH_C32(0x8aeb81e3), SPH_C32(0x41940000), + SPH_C32(0xc36d002a), SPH_C32(0xb7778000), SPH_C32(0x346a0000), + SPH_C32(0x36af7f72), SPH_C32(0x2faa4eea), SPH_C32(0x81a94948), + SPH_C32(0x473c80da) }, + { SPH_C32(0x558d0000), SPH_C32(0xe0a70016), SPH_C32(0xe7a88000), + SPH_C32(0x70dc0000), SPH_C32(0x2dc318c2), SPH_C32(0x1359e29f), + SPH_C32(0xe04f59f8), SPH_C32(0x9cf65b5a), SPH_C32(0x71230000), + SPH_C32(0x26bd002a), SPH_C32(0x4383e000), SPH_C32(0x76ae0000), + SPH_C32(0x55174218), SPH_C32(0x5710da8a), SPH_C32(0xa006e8a2), + SPH_C32(0xf79998ee) }, + { SPH_C32(0xf75a0000), SPH_C32(0x19840028), SPH_C32(0xa2190000), + SPH_C32(0xeef80000), SPH_C32(0xc0722516), SPH_C32(0x19981260), + SPH_C32(0x73dba1e6), SPH_C32(0xe1844257), SPH_C32(0x14190000), + SPH_C32(0x23ca003c), SPH_C32(0x50df0000), SPH_C32(0x44b60000), + SPH_C32(0x1b6c67b0), SPH_C32(0x3cf3ac75), SPH_C32(0x61e610b0), + SPH_C32(0xdbcadb80) }, + { SPH_C32(0x71230000), SPH_C32(0x26bd002a), SPH_C32(0x4383e000), + SPH_C32(0x76ae0000), SPH_C32(0x55174218), SPH_C32(0x5710da8a), + SPH_C32(0xa006e8a2), SPH_C32(0xf79998ee), SPH_C32(0x24ae0000), + SPH_C32(0xc61a003c), SPH_C32(0xa42b6000), SPH_C32(0x06720000), + SPH_C32(0x78d45ada), SPH_C32(0x44493815), SPH_C32(0x4049b15a), + SPH_C32(0x6b6fc3b4) }, + { SPH_C32(0xc7ed0000), SPH_C32(0xfc540028), SPH_C32(0x56ed6000), + SPH_C32(0xac3c0000), SPH_C32(0xa3ca187c), SPH_C32(0x61228600), + SPH_C32(0x5274000c), SPH_C32(0x51215a63), SPH_C32(0xa2d70000), + SPH_C32(0xf923003e), SPH_C32(0x45b18000), SPH_C32(0x9e240000), + SPH_C32(0xedb13dd4), SPH_C32(0x0ac1f0ff), SPH_C32(0x9394f81e), + SPH_C32(0x7d72190d) }, + { SPH_C32(0x41940000), SPH_C32(0xc36d002a), SPH_C32(0xb7778000), + SPH_C32(0x346a0000), SPH_C32(0x36af7f72), SPH_C32(0x2faa4eea), + SPH_C32(0x81a94948), SPH_C32(0x473c80da), SPH_C32(0x92600000), + SPH_C32(0x1cf3003e), SPH_C32(0xb145e000), SPH_C32(0xdce00000), + SPH_C32(0x8e0900be), SPH_C32(0x727b649f), SPH_C32(0xb23b59f4), + SPH_C32(0xcdd70139) }, + { SPH_C32(0x54500000), SPH_C32(0x0671005c), SPH_C32(0x25ae0000), + SPH_C32(0x6a1e0000), SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), + SPH_C32(0xbfba18c3), SPH_C32(0x7e715d17), SPH_C32(0xbc8d0000), + SPH_C32(0xfc3b0018), SPH_C32(0x19830000), SPH_C32(0xd10b0000), + SPH_C32(0xae1878c4), SPH_C32(0x42a69856), SPH_C32(0x0012da37), + SPH_C32(0x2c3b504e) }, + { SPH_C32(0xd2290000), SPH_C32(0x3948005e), SPH_C32(0xc434e000), + SPH_C32(0xf2480000), SPH_C32(0xbbc029d1), SPH_C32(0x28c64df8), + SPH_C32(0x6c675187), SPH_C32(0x686c87ae), SPH_C32(0x8c3a0000), + SPH_C32(0x19eb0018), SPH_C32(0xed776000), SPH_C32(0x93cf0000), + SPH_C32(0xcda045ae), SPH_C32(0x3a1c0c36), SPH_C32(0x21bd7bdd), + SPH_C32(0x9c9e487a) }, + { SPH_C32(0x64e70000), SPH_C32(0xe3a1005c), SPH_C32(0xd15a6000), + SPH_C32(0x28da0000), SPH_C32(0x4d1d73b5), SPH_C32(0x1ef41172), + SPH_C32(0x9e15b929), SPH_C32(0xced44523), SPH_C32(0x0a430000), + SPH_C32(0x26d2001a), SPH_C32(0x0ced8000), SPH_C32(0x0b990000), + SPH_C32(0x58c522a0), SPH_C32(0x7494c4dc), SPH_C32(0xf2603299), + SPH_C32(0x8a8392c3) }, + { SPH_C32(0xe29e0000), SPH_C32(0xdc98005e), SPH_C32(0x30c08000), + SPH_C32(0xb08c0000), SPH_C32(0xd87814bb), SPH_C32(0x507cd998), + SPH_C32(0x4dc8f06d), SPH_C32(0xd8c99f9a), SPH_C32(0x3af40000), + SPH_C32(0xc302001a), SPH_C32(0xf819e000), SPH_C32(0x495d0000), + SPH_C32(0x3b7d1fca), SPH_C32(0x0c2e50bc), SPH_C32(0xd3cf9373), + SPH_C32(0x3a268af7) }, + { SPH_C32(0x40490000), SPH_C32(0x25bb0060), SPH_C32(0x75710000), + SPH_C32(0x2ea80000), SPH_C32(0x35c9296f), SPH_C32(0x5abd2967), + SPH_C32(0xde5c0873), SPH_C32(0xa5bb8697), SPH_C32(0x5fce0000), + SPH_C32(0xc675000c), SPH_C32(0xeb450000), SPH_C32(0x7b450000), + SPH_C32(0x75063a62), SPH_C32(0x67cd2643), SPH_C32(0x122f6b61), + SPH_C32(0x1675c999) }, + { SPH_C32(0xc6300000), SPH_C32(0x1a820062), SPH_C32(0x94ebe000), + SPH_C32(0xb6fe0000), SPH_C32(0xa0ac4e61), SPH_C32(0x1435e18d), + SPH_C32(0x0d814137), SPH_C32(0xb3a65c2e), SPH_C32(0x6f790000), + SPH_C32(0x23a5000c), SPH_C32(0x1fb16000), SPH_C32(0x39810000), + SPH_C32(0x16be0708), SPH_C32(0x1f77b223), SPH_C32(0x3380ca8b), + SPH_C32(0xa6d0d1ad) }, + { SPH_C32(0x70fe0000), SPH_C32(0xc06b0060), SPH_C32(0x81856000), + SPH_C32(0x6c6c0000), SPH_C32(0x56711405), SPH_C32(0x2207bd07), + SPH_C32(0xfff3a999), SPH_C32(0x151e9ea3), SPH_C32(0xe9000000), + SPH_C32(0x1c9c000e), SPH_C32(0xfe2b8000), SPH_C32(0xa1d70000), + SPH_C32(0x83db6006), SPH_C32(0x51ff7ac9), SPH_C32(0xe05d83cf), + SPH_C32(0xb0cd0b14) }, + { SPH_C32(0xf6870000), SPH_C32(0xff520062), SPH_C32(0x601f8000), + SPH_C32(0xf43a0000), SPH_C32(0xc314730b), SPH_C32(0x6c8f75ed), + SPH_C32(0x2c2ee0dd), SPH_C32(0x0303441a), SPH_C32(0xd9b70000), + SPH_C32(0xf94c000e), SPH_C32(0x0adfe000), SPH_C32(0xe3130000), + SPH_C32(0xe0635d6c), SPH_C32(0x2945eea9), SPH_C32(0xc1f22225), + SPH_C32(0x00681320) }, + { SPH_C32(0xb7130000), SPH_C32(0x3c3f0048), SPH_C32(0xd7680000), + SPH_C32(0xc0500000), SPH_C32(0xf5bb0c79), SPH_C32(0x43253b07), + SPH_C32(0xad87a995), SPH_C32(0x443fc4c0), SPH_C32(0x4bd70000), + SPH_C32(0xe5bf0030), SPH_C32(0xbb9a0000), SPH_C32(0x3ff30000), + SPH_C32(0x6e6a5dd2), SPH_C32(0x5b3e8a36), SPH_C32(0x73c97bd1), + SPH_C32(0xcdbf1219) }, + { SPH_C32(0x316a0000), SPH_C32(0x0306004a), SPH_C32(0x36f2e000), + SPH_C32(0x58060000), SPH_C32(0x60de6b77), SPH_C32(0x0dadf3ed), + SPH_C32(0x7e5ae0d1), SPH_C32(0x52221e79), SPH_C32(0x7b600000), + SPH_C32(0x006f0030), SPH_C32(0x4f6e6000), SPH_C32(0x7d370000), + SPH_C32(0x0dd260b8), SPH_C32(0x23841e56), SPH_C32(0x5266da3b), + SPH_C32(0x7d1a0a2d) }, + { SPH_C32(0x87a40000), SPH_C32(0xd9ef0048), SPH_C32(0x239c6000), + SPH_C32(0x82940000), SPH_C32(0x96033113), SPH_C32(0x3b9faf67), + SPH_C32(0x8c28087f), SPH_C32(0xf49adcf4), SPH_C32(0xfd190000), + SPH_C32(0x3f560032), SPH_C32(0xaef48000), SPH_C32(0xe5610000), + SPH_C32(0x98b707b6), SPH_C32(0x6d0cd6bc), SPH_C32(0x81bb937f), + SPH_C32(0x6b07d094) }, + { SPH_C32(0x01dd0000), SPH_C32(0xe6d6004a), SPH_C32(0xc2068000), + SPH_C32(0x1ac20000), SPH_C32(0x0366561d), SPH_C32(0x7517678d), + SPH_C32(0x5ff5413b), SPH_C32(0xe287064d), SPH_C32(0xcdae0000), + SPH_C32(0xda860032), SPH_C32(0x5a00e000), SPH_C32(0xa7a50000), + SPH_C32(0xfb0f3adc), SPH_C32(0x15b642dc), SPH_C32(0xa0143295), + SPH_C32(0xdba2c8a0) }, + { SPH_C32(0xa30a0000), SPH_C32(0x1ff50074), SPH_C32(0x87b70000), + SPH_C32(0x84e60000), SPH_C32(0xeed76bc9), SPH_C32(0x7fd69772), + SPH_C32(0xcc61b925), SPH_C32(0x9ff51f40), SPH_C32(0xa8940000), + SPH_C32(0xdff10024), SPH_C32(0x495c0000), SPH_C32(0x95bd0000), + SPH_C32(0xb5741f74), SPH_C32(0x7e553423), SPH_C32(0x61f4ca87), + SPH_C32(0xf7f18bce) }, + { SPH_C32(0x25730000), SPH_C32(0x20cc0076), SPH_C32(0x662de000), + SPH_C32(0x1cb00000), SPH_C32(0x7bb20cc7), SPH_C32(0x315e5f98), + SPH_C32(0x1fbcf061), SPH_C32(0x89e8c5f9), SPH_C32(0x98230000), + SPH_C32(0x3a210024), SPH_C32(0xbda86000), SPH_C32(0xd7790000), + SPH_C32(0xd6cc221e), SPH_C32(0x06efa043), SPH_C32(0x405b6b6d), + SPH_C32(0x475493fa) }, + { SPH_C32(0x93bd0000), SPH_C32(0xfa250074), SPH_C32(0x73436000), + SPH_C32(0xc6220000), SPH_C32(0x8d6f56a3), SPH_C32(0x076c0312), + SPH_C32(0xedce18cf), SPH_C32(0x2f500774), SPH_C32(0x1e5a0000), + SPH_C32(0x05180026), SPH_C32(0x5c328000), SPH_C32(0x4f2f0000), + SPH_C32(0x43a94510), SPH_C32(0x486768a9), SPH_C32(0x93862229), + SPH_C32(0x51494943) }, + { SPH_C32(0x15c40000), SPH_C32(0xc51c0076), SPH_C32(0x92d98000), + SPH_C32(0x5e740000), SPH_C32(0x180a31ad), SPH_C32(0x49e4cbf8), + SPH_C32(0x3e13518b), SPH_C32(0x394dddcd), SPH_C32(0x2eed0000), + SPH_C32(0xe0c80026), SPH_C32(0xa8c6e000), SPH_C32(0x0deb0000), + SPH_C32(0x2011787a), SPH_C32(0x30ddfcc9), SPH_C32(0xb22983c3), + SPH_C32(0xe1ec5177) }, + { SPH_C32(0xbc8d0000), SPH_C32(0xfc3b0018), SPH_C32(0x19830000), + SPH_C32(0xd10b0000), SPH_C32(0xae1878c4), SPH_C32(0x42a69856), + SPH_C32(0x0012da37), SPH_C32(0x2c3b504e), SPH_C32(0xe8dd0000), + SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), SPH_C32(0xbb150000), + SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), SPH_C32(0xbfa8c2f4), + SPH_C32(0x524a0d59) }, + { SPH_C32(0x3af40000), SPH_C32(0xc302001a), SPH_C32(0xf819e000), + SPH_C32(0x495d0000), SPH_C32(0x3b7d1fca), SPH_C32(0x0c2e50bc), + SPH_C32(0xd3cf9373), SPH_C32(0x3a268af7), SPH_C32(0xd86a0000), + SPH_C32(0x1f9a0044), SPH_C32(0xc8d96000), SPH_C32(0xf9d10000), + SPH_C32(0xe3050b71), SPH_C32(0x5c528924), SPH_C32(0x9e07631e), + SPH_C32(0xe2ef156d) }, + { SPH_C32(0x8c3a0000), SPH_C32(0x19eb0018), SPH_C32(0xed776000), + SPH_C32(0x93cf0000), SPH_C32(0xcda045ae), SPH_C32(0x3a1c0c36), + SPH_C32(0x21bd7bdd), SPH_C32(0x9c9e487a), SPH_C32(0x5e130000), + SPH_C32(0x20a30046), SPH_C32(0x29438000), SPH_C32(0x61870000), + SPH_C32(0x76606c7f), SPH_C32(0x12da41ce), SPH_C32(0x4dda2a5a), + SPH_C32(0xf4f2cfd4) }, + { SPH_C32(0x0a430000), SPH_C32(0x26d2001a), SPH_C32(0x0ced8000), + SPH_C32(0x0b990000), SPH_C32(0x58c522a0), SPH_C32(0x7494c4dc), + SPH_C32(0xf2603299), SPH_C32(0x8a8392c3), SPH_C32(0x6ea40000), + SPH_C32(0xc5730046), SPH_C32(0xddb7e000), SPH_C32(0x23430000), + SPH_C32(0x15d85115), SPH_C32(0x6a60d5ae), SPH_C32(0x6c758bb0), + SPH_C32(0x4457d7e0) }, + { SPH_C32(0xa8940000), SPH_C32(0xdff10024), SPH_C32(0x495c0000), + SPH_C32(0x95bd0000), SPH_C32(0xb5741f74), SPH_C32(0x7e553423), + SPH_C32(0x61f4ca87), SPH_C32(0xf7f18bce), SPH_C32(0x0b9e0000), + SPH_C32(0xc0040050), SPH_C32(0xceeb0000), SPH_C32(0x115b0000), + SPH_C32(0x5ba374bd), SPH_C32(0x0183a351), SPH_C32(0xad9573a2), + SPH_C32(0x6804948e) }, + { SPH_C32(0x2eed0000), SPH_C32(0xe0c80026), SPH_C32(0xa8c6e000), + SPH_C32(0x0deb0000), SPH_C32(0x2011787a), SPH_C32(0x30ddfcc9), + SPH_C32(0xb22983c3), SPH_C32(0xe1ec5177), SPH_C32(0x3b290000), + SPH_C32(0x25d40050), SPH_C32(0x3a1f6000), SPH_C32(0x539f0000), + SPH_C32(0x381b49d7), SPH_C32(0x79393731), SPH_C32(0x8c3ad248), + SPH_C32(0xd8a18cba) }, + { SPH_C32(0x98230000), SPH_C32(0x3a210024), SPH_C32(0xbda86000), + SPH_C32(0xd7790000), SPH_C32(0xd6cc221e), SPH_C32(0x06efa043), + SPH_C32(0x405b6b6d), SPH_C32(0x475493fa), SPH_C32(0xbd500000), + SPH_C32(0x1aed0052), SPH_C32(0xdb858000), SPH_C32(0xcbc90000), + SPH_C32(0xad7e2ed9), SPH_C32(0x37b1ffdb), SPH_C32(0x5fe79b0c), + SPH_C32(0xcebc5603) }, + { SPH_C32(0x1e5a0000), SPH_C32(0x05180026), SPH_C32(0x5c328000), + SPH_C32(0x4f2f0000), SPH_C32(0x43a94510), SPH_C32(0x486768a9), + SPH_C32(0x93862229), SPH_C32(0x51494943), SPH_C32(0x8de70000), + SPH_C32(0xff3d0052), SPH_C32(0x2f71e000), SPH_C32(0x890d0000), + SPH_C32(0xcec613b3), SPH_C32(0x4f0b6bbb), SPH_C32(0x7e483ae6), + SPH_C32(0x7e194e37) }, + { SPH_C32(0x5fce0000), SPH_C32(0xc675000c), SPH_C32(0xeb450000), + SPH_C32(0x7b450000), SPH_C32(0x75063a62), SPH_C32(0x67cd2643), + SPH_C32(0x122f6b61), SPH_C32(0x1675c999), SPH_C32(0x1f870000), + SPH_C32(0xe3ce006c), SPH_C32(0x9e340000), SPH_C32(0x55ed0000), + SPH_C32(0x40cf130d), SPH_C32(0x3d700f24), SPH_C32(0xcc736312), + SPH_C32(0xb3ce4f0e) }, + { SPH_C32(0xd9b70000), SPH_C32(0xf94c000e), SPH_C32(0x0adfe000), + SPH_C32(0xe3130000), SPH_C32(0xe0635d6c), SPH_C32(0x2945eea9), + SPH_C32(0xc1f22225), SPH_C32(0x00681320), SPH_C32(0x2f300000), + SPH_C32(0x061e006c), SPH_C32(0x6ac06000), SPH_C32(0x17290000), + SPH_C32(0x23772e67), SPH_C32(0x45ca9b44), SPH_C32(0xeddcc2f8), + SPH_C32(0x036b573a) }, + { SPH_C32(0x6f790000), SPH_C32(0x23a5000c), SPH_C32(0x1fb16000), + SPH_C32(0x39810000), SPH_C32(0x16be0708), SPH_C32(0x1f77b223), + SPH_C32(0x3380ca8b), SPH_C32(0xa6d0d1ad), SPH_C32(0xa9490000), + SPH_C32(0x3927006e), SPH_C32(0x8b5a8000), SPH_C32(0x8f7f0000), + SPH_C32(0xb6124969), SPH_C32(0x0b4253ae), SPH_C32(0x3e018bbc), + SPH_C32(0x15768d83) }, + { SPH_C32(0xe9000000), SPH_C32(0x1c9c000e), SPH_C32(0xfe2b8000), + SPH_C32(0xa1d70000), SPH_C32(0x83db6006), SPH_C32(0x51ff7ac9), + SPH_C32(0xe05d83cf), SPH_C32(0xb0cd0b14), SPH_C32(0x99fe0000), + SPH_C32(0xdcf7006e), SPH_C32(0x7faee000), SPH_C32(0xcdbb0000), + SPH_C32(0xd5aa7403), SPH_C32(0x73f8c7ce), SPH_C32(0x1fae2a56), + SPH_C32(0xa5d395b7) }, + { SPH_C32(0x4bd70000), SPH_C32(0xe5bf0030), SPH_C32(0xbb9a0000), + SPH_C32(0x3ff30000), SPH_C32(0x6e6a5dd2), SPH_C32(0x5b3e8a36), + SPH_C32(0x73c97bd1), SPH_C32(0xcdbf1219), SPH_C32(0xfcc40000), + SPH_C32(0xd9800078), SPH_C32(0x6cf20000), SPH_C32(0xffa30000), + SPH_C32(0x9bd151ab), SPH_C32(0x181bb131), SPH_C32(0xde4ed244), + SPH_C32(0x8980d6d9) }, + { SPH_C32(0xcdae0000), SPH_C32(0xda860032), SPH_C32(0x5a00e000), + SPH_C32(0xa7a50000), SPH_C32(0xfb0f3adc), SPH_C32(0x15b642dc), + SPH_C32(0xa0143295), SPH_C32(0xdba2c8a0), SPH_C32(0xcc730000), + SPH_C32(0x3c500078), SPH_C32(0x98066000), SPH_C32(0xbd670000), + SPH_C32(0xf8696cc1), SPH_C32(0x60a12551), SPH_C32(0xffe173ae), + SPH_C32(0x3925ceed) }, + { SPH_C32(0x7b600000), SPH_C32(0x006f0030), SPH_C32(0x4f6e6000), + SPH_C32(0x7d370000), SPH_C32(0x0dd260b8), SPH_C32(0x23841e56), + SPH_C32(0x5266da3b), SPH_C32(0x7d1a0a2d), SPH_C32(0x4a0a0000), + SPH_C32(0x0369007a), SPH_C32(0x799c8000), SPH_C32(0x25310000), + SPH_C32(0x6d0c0bcf), SPH_C32(0x2e29edbb), SPH_C32(0x2c3c3aea), + SPH_C32(0x2f381454) }, + { SPH_C32(0xfd190000), SPH_C32(0x3f560032), SPH_C32(0xaef48000), + SPH_C32(0xe5610000), SPH_C32(0x98b707b6), SPH_C32(0x6d0cd6bc), + SPH_C32(0x81bb937f), SPH_C32(0x6b07d094), SPH_C32(0x7abd0000), + SPH_C32(0xe6b9007a), SPH_C32(0x8d68e000), SPH_C32(0x67f50000), + SPH_C32(0x0eb436a5), SPH_C32(0x569379db), SPH_C32(0x0d939b00), + SPH_C32(0x9f9d0c60) }, + { SPH_C32(0xe8dd0000), SPH_C32(0xfa4a0044), SPH_C32(0x3c2d0000), + SPH_C32(0xbb150000), SPH_C32(0x80bd361b), SPH_C32(0x24e81d44), + SPH_C32(0xbfa8c2f4), SPH_C32(0x524a0d59), SPH_C32(0x54500000), + SPH_C32(0x0671005c), SPH_C32(0x25ae0000), SPH_C32(0x6a1e0000), + SPH_C32(0x2ea54edf), SPH_C32(0x664e8512), SPH_C32(0xbfba18c3), + SPH_C32(0x7e715d17) }, + { SPH_C32(0x6ea40000), SPH_C32(0xc5730046), SPH_C32(0xddb7e000), + SPH_C32(0x23430000), SPH_C32(0x15d85115), SPH_C32(0x6a60d5ae), + SPH_C32(0x6c758bb0), SPH_C32(0x4457d7e0), SPH_C32(0x64e70000), + SPH_C32(0xe3a1005c), SPH_C32(0xd15a6000), SPH_C32(0x28da0000), + SPH_C32(0x4d1d73b5), SPH_C32(0x1ef41172), SPH_C32(0x9e15b929), + SPH_C32(0xced44523) }, + { SPH_C32(0xd86a0000), SPH_C32(0x1f9a0044), SPH_C32(0xc8d96000), + SPH_C32(0xf9d10000), SPH_C32(0xe3050b71), SPH_C32(0x5c528924), + SPH_C32(0x9e07631e), SPH_C32(0xe2ef156d), SPH_C32(0xe29e0000), + SPH_C32(0xdc98005e), SPH_C32(0x30c08000), SPH_C32(0xb08c0000), + SPH_C32(0xd87814bb), SPH_C32(0x507cd998), SPH_C32(0x4dc8f06d), + SPH_C32(0xd8c99f9a) }, + { SPH_C32(0x5e130000), SPH_C32(0x20a30046), SPH_C32(0x29438000), + SPH_C32(0x61870000), SPH_C32(0x76606c7f), SPH_C32(0x12da41ce), + SPH_C32(0x4dda2a5a), SPH_C32(0xf4f2cfd4), SPH_C32(0xd2290000), + SPH_C32(0x3948005e), SPH_C32(0xc434e000), SPH_C32(0xf2480000), + SPH_C32(0xbbc029d1), SPH_C32(0x28c64df8), SPH_C32(0x6c675187), + SPH_C32(0x686c87ae) }, + { SPH_C32(0xfcc40000), SPH_C32(0xd9800078), SPH_C32(0x6cf20000), + SPH_C32(0xffa30000), SPH_C32(0x9bd151ab), SPH_C32(0x181bb131), + SPH_C32(0xde4ed244), SPH_C32(0x8980d6d9), SPH_C32(0xb7130000), + SPH_C32(0x3c3f0048), SPH_C32(0xd7680000), SPH_C32(0xc0500000), + SPH_C32(0xf5bb0c79), SPH_C32(0x43253b07), SPH_C32(0xad87a995), + SPH_C32(0x443fc4c0) }, + { SPH_C32(0x7abd0000), SPH_C32(0xe6b9007a), SPH_C32(0x8d68e000), + SPH_C32(0x67f50000), SPH_C32(0x0eb436a5), SPH_C32(0x569379db), + SPH_C32(0x0d939b00), SPH_C32(0x9f9d0c60), SPH_C32(0x87a40000), + SPH_C32(0xd9ef0048), SPH_C32(0x239c6000), SPH_C32(0x82940000), + SPH_C32(0x96033113), SPH_C32(0x3b9faf67), SPH_C32(0x8c28087f), + SPH_C32(0xf49adcf4) }, + { SPH_C32(0xcc730000), SPH_C32(0x3c500078), SPH_C32(0x98066000), + SPH_C32(0xbd670000), SPH_C32(0xf8696cc1), SPH_C32(0x60a12551), + SPH_C32(0xffe173ae), SPH_C32(0x3925ceed), SPH_C32(0x01dd0000), + SPH_C32(0xe6d6004a), SPH_C32(0xc2068000), SPH_C32(0x1ac20000), + SPH_C32(0x0366561d), SPH_C32(0x7517678d), SPH_C32(0x5ff5413b), + SPH_C32(0xe287064d) }, + { SPH_C32(0x4a0a0000), SPH_C32(0x0369007a), SPH_C32(0x799c8000), + SPH_C32(0x25310000), SPH_C32(0x6d0c0bcf), SPH_C32(0x2e29edbb), + SPH_C32(0x2c3c3aea), SPH_C32(0x2f381454), SPH_C32(0x316a0000), + SPH_C32(0x0306004a), SPH_C32(0x36f2e000), SPH_C32(0x58060000), + SPH_C32(0x60de6b77), SPH_C32(0x0dadf3ed), SPH_C32(0x7e5ae0d1), + SPH_C32(0x52221e79) }, + { SPH_C32(0x0b9e0000), SPH_C32(0xc0040050), SPH_C32(0xceeb0000), + SPH_C32(0x115b0000), SPH_C32(0x5ba374bd), SPH_C32(0x0183a351), + SPH_C32(0xad9573a2), SPH_C32(0x6804948e), SPH_C32(0xa30a0000), + SPH_C32(0x1ff50074), SPH_C32(0x87b70000), SPH_C32(0x84e60000), + SPH_C32(0xeed76bc9), SPH_C32(0x7fd69772), SPH_C32(0xcc61b925), + SPH_C32(0x9ff51f40) }, + { SPH_C32(0x8de70000), SPH_C32(0xff3d0052), SPH_C32(0x2f71e000), + SPH_C32(0x890d0000), SPH_C32(0xcec613b3), SPH_C32(0x4f0b6bbb), + SPH_C32(0x7e483ae6), SPH_C32(0x7e194e37), SPH_C32(0x93bd0000), + SPH_C32(0xfa250074), SPH_C32(0x73436000), SPH_C32(0xc6220000), + SPH_C32(0x8d6f56a3), SPH_C32(0x076c0312), SPH_C32(0xedce18cf), + SPH_C32(0x2f500774) }, + { SPH_C32(0x3b290000), SPH_C32(0x25d40050), SPH_C32(0x3a1f6000), + SPH_C32(0x539f0000), SPH_C32(0x381b49d7), SPH_C32(0x79393731), + SPH_C32(0x8c3ad248), SPH_C32(0xd8a18cba), SPH_C32(0x15c40000), + SPH_C32(0xc51c0076), SPH_C32(0x92d98000), SPH_C32(0x5e740000), + SPH_C32(0x180a31ad), SPH_C32(0x49e4cbf8), SPH_C32(0x3e13518b), + SPH_C32(0x394dddcd) }, + { SPH_C32(0xbd500000), SPH_C32(0x1aed0052), SPH_C32(0xdb858000), + SPH_C32(0xcbc90000), SPH_C32(0xad7e2ed9), SPH_C32(0x37b1ffdb), + SPH_C32(0x5fe79b0c), SPH_C32(0xcebc5603), SPH_C32(0x25730000), + SPH_C32(0x20cc0076), SPH_C32(0x662de000), SPH_C32(0x1cb00000), + SPH_C32(0x7bb20cc7), SPH_C32(0x315e5f98), SPH_C32(0x1fbcf061), + SPH_C32(0x89e8c5f9) }, + { SPH_C32(0x1f870000), SPH_C32(0xe3ce006c), SPH_C32(0x9e340000), + SPH_C32(0x55ed0000), SPH_C32(0x40cf130d), SPH_C32(0x3d700f24), + SPH_C32(0xcc736312), SPH_C32(0xb3ce4f0e), SPH_C32(0x40490000), + SPH_C32(0x25bb0060), SPH_C32(0x75710000), SPH_C32(0x2ea80000), + SPH_C32(0x35c9296f), SPH_C32(0x5abd2967), SPH_C32(0xde5c0873), + SPH_C32(0xa5bb8697) }, + { SPH_C32(0x99fe0000), SPH_C32(0xdcf7006e), SPH_C32(0x7faee000), + SPH_C32(0xcdbb0000), SPH_C32(0xd5aa7403), SPH_C32(0x73f8c7ce), + SPH_C32(0x1fae2a56), SPH_C32(0xa5d395b7), SPH_C32(0x70fe0000), + SPH_C32(0xc06b0060), SPH_C32(0x81856000), SPH_C32(0x6c6c0000), + SPH_C32(0x56711405), SPH_C32(0x2207bd07), SPH_C32(0xfff3a999), + SPH_C32(0x151e9ea3) }, + { SPH_C32(0x2f300000), SPH_C32(0x061e006c), SPH_C32(0x6ac06000), + SPH_C32(0x17290000), SPH_C32(0x23772e67), SPH_C32(0x45ca9b44), + SPH_C32(0xeddcc2f8), SPH_C32(0x036b573a), SPH_C32(0xf6870000), + SPH_C32(0xff520062), SPH_C32(0x601f8000), SPH_C32(0xf43a0000), + SPH_C32(0xc314730b), SPH_C32(0x6c8f75ed), SPH_C32(0x2c2ee0dd), + SPH_C32(0x0303441a) }, + { SPH_C32(0xa9490000), SPH_C32(0x3927006e), SPH_C32(0x8b5a8000), + SPH_C32(0x8f7f0000), SPH_C32(0xb6124969), SPH_C32(0x0b4253ae), + SPH_C32(0x3e018bbc), SPH_C32(0x15768d83), SPH_C32(0xc6300000), + SPH_C32(0x1a820062), SPH_C32(0x94ebe000), SPH_C32(0xb6fe0000), + SPH_C32(0xa0ac4e61), SPH_C32(0x1435e18d), SPH_C32(0x0d814137), + SPH_C32(0xb3a65c2e) }, + { SPH_C32(0x69510000), SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), + SPH_C32(0xac2f0000), SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), + SPH_C32(0x87ec287c), SPH_C32(0xbce1a3ce), SPH_C32(0xc6730000), + SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), SPH_C32(0x218d0000), + SPH_C32(0x23111587), SPH_C32(0x7913512f), SPH_C32(0x1d28ac88), + SPH_C32(0x378dd173) }, + { SPH_C32(0xef280000), SPH_C32(0xebd8009e), SPH_C32(0x22b9e000), + SPH_C32(0x34790000), SPH_C32(0x71f06ca0), SPH_C32(0x802cdd36), + SPH_C32(0x54316138), SPH_C32(0xaafc7977), SPH_C32(0xf6c40000), + SPH_C32(0x4a5d000c), SPH_C32(0x50356000), SPH_C32(0x63490000), + SPH_C32(0x40a928ed), SPH_C32(0x01a9c54f), SPH_C32(0x3c870d62), + SPH_C32(0x8728c947) }, + { SPH_C32(0x59e60000), SPH_C32(0x3131009c), SPH_C32(0x37d76000), + SPH_C32(0xeeeb0000), SPH_C32(0x872d36c4), SPH_C32(0xb61e81bc), + SPH_C32(0xa6438996), SPH_C32(0x0c44bbfa), SPH_C32(0x70bd0000), + SPH_C32(0x7564000e), SPH_C32(0xb1af8000), SPH_C32(0xfb1f0000), + SPH_C32(0xd5cc4fe3), SPH_C32(0x4f210da5), SPH_C32(0xef5a4426), + SPH_C32(0x913513fe) }, + { SPH_C32(0xdf9f0000), SPH_C32(0x0e08009e), SPH_C32(0xd64d8000), + SPH_C32(0x76bd0000), SPH_C32(0x124851ca), SPH_C32(0xf8964956), + SPH_C32(0x759ec0d2), SPH_C32(0x1a596143), SPH_C32(0x400a0000), + SPH_C32(0x90b4000e), SPH_C32(0x455be000), SPH_C32(0xb9db0000), + SPH_C32(0xb6747289), SPH_C32(0x379b99c5), SPH_C32(0xcef5e5cc), + SPH_C32(0x21900bca) }, + { SPH_C32(0x7d480000), SPH_C32(0xf72b00a0), SPH_C32(0x93fc0000), + SPH_C32(0xe8990000), SPH_C32(0xfff96c1e), SPH_C32(0xf257b9a9), + SPH_C32(0xe60a38cc), SPH_C32(0x672b784e), SPH_C32(0x25300000), + SPH_C32(0x95c30018), SPH_C32(0x56070000), SPH_C32(0x8bc30000), + SPH_C32(0xf80f5721), SPH_C32(0x5c78ef3a), SPH_C32(0x0f151dde), + SPH_C32(0x0dc348a4) }, + { SPH_C32(0xfb310000), SPH_C32(0xc81200a2), SPH_C32(0x7266e000), + SPH_C32(0x70cf0000), SPH_C32(0x6a9c0b10), SPH_C32(0xbcdf7143), + SPH_C32(0x35d77188), SPH_C32(0x7136a2f7), SPH_C32(0x15870000), + SPH_C32(0x70130018), SPH_C32(0xa2f36000), SPH_C32(0xc9070000), + SPH_C32(0x9bb76a4b), SPH_C32(0x24c27b5a), SPH_C32(0x2ebabc34), + SPH_C32(0xbd665090) }, + { SPH_C32(0x4dff0000), SPH_C32(0x12fb00a0), SPH_C32(0x67086000), + SPH_C32(0xaa5d0000), SPH_C32(0x9c415174), SPH_C32(0x8aed2dc9), + SPH_C32(0xc7a59926), SPH_C32(0xd78e607a), SPH_C32(0x93fe0000), + SPH_C32(0x4f2a001a), SPH_C32(0x43698000), SPH_C32(0x51510000), + SPH_C32(0x0ed20d45), SPH_C32(0x6a4ab3b0), SPH_C32(0xfd67f570), + SPH_C32(0xab7b8a29) }, + { SPH_C32(0xcb860000), SPH_C32(0x2dc200a2), SPH_C32(0x86928000), + SPH_C32(0x320b0000), SPH_C32(0x0924367a), SPH_C32(0xc465e523), + SPH_C32(0x1478d062), SPH_C32(0xc193bac3), SPH_C32(0xa3490000), + SPH_C32(0xaafa001a), SPH_C32(0xb79de000), SPH_C32(0x13950000), + SPH_C32(0x6d6a302f), SPH_C32(0x12f027d0), SPH_C32(0xdcc8549a), + SPH_C32(0x1bde921d) }, + { SPH_C32(0x8a120000), SPH_C32(0xeeaf0088), SPH_C32(0x31e50000), + SPH_C32(0x06610000), SPH_C32(0x3f8b4908), SPH_C32(0xebcfabc9), + SPH_C32(0x95d1992a), SPH_C32(0x86af3a19), SPH_C32(0x31290000), + SPH_C32(0xb6090024), SPH_C32(0x06d80000), SPH_C32(0xcf750000), + SPH_C32(0xe3633091), SPH_C32(0x608b434f), SPH_C32(0x6ef30d6e), + SPH_C32(0xd6099324) }, + { SPH_C32(0x0c6b0000), SPH_C32(0xd196008a), SPH_C32(0xd07fe000), + SPH_C32(0x9e370000), SPH_C32(0xaaee2e06), SPH_C32(0xa5476323), + SPH_C32(0x460cd06e), SPH_C32(0x90b2e0a0), SPH_C32(0x019e0000), + SPH_C32(0x53d90024), SPH_C32(0xf22c6000), SPH_C32(0x8db10000), + SPH_C32(0x80db0dfb), SPH_C32(0x1831d72f), SPH_C32(0x4f5cac84), + SPH_C32(0x66ac8b10) }, + { SPH_C32(0xbaa50000), SPH_C32(0x0b7f0088), SPH_C32(0xc5116000), + SPH_C32(0x44a50000), SPH_C32(0x5c337462), SPH_C32(0x93753fa9), + SPH_C32(0xb47e38c0), SPH_C32(0x360a222d), SPH_C32(0x87e70000), + SPH_C32(0x6ce00026), SPH_C32(0x13b68000), SPH_C32(0x15e70000), + SPH_C32(0x15be6af5), SPH_C32(0x56b91fc5), SPH_C32(0x9c81e5c0), + SPH_C32(0x70b151a9) }, + { SPH_C32(0x3cdc0000), SPH_C32(0x3446008a), SPH_C32(0x248b8000), + SPH_C32(0xdcf30000), SPH_C32(0xc956136c), SPH_C32(0xddfdf743), + SPH_C32(0x67a37184), SPH_C32(0x2017f894), SPH_C32(0xb7500000), + SPH_C32(0x89300026), SPH_C32(0xe742e000), SPH_C32(0x57230000), + SPH_C32(0x7606579f), SPH_C32(0x2e038ba5), SPH_C32(0xbd2e442a), + SPH_C32(0xc014499d) }, + { SPH_C32(0x9e0b0000), SPH_C32(0xcd6500b4), SPH_C32(0x613a0000), + SPH_C32(0x42d70000), SPH_C32(0x24e72eb8), SPH_C32(0xd73c07bc), + SPH_C32(0xf437899a), SPH_C32(0x5d65e199), SPH_C32(0xd26a0000), + SPH_C32(0x8c470030), SPH_C32(0xf41e0000), SPH_C32(0x653b0000), + SPH_C32(0x387d7237), SPH_C32(0x45e0fd5a), SPH_C32(0x7ccebc38), + SPH_C32(0xec470af3) }, + { SPH_C32(0x18720000), SPH_C32(0xf25c00b6), SPH_C32(0x80a0e000), + SPH_C32(0xda810000), SPH_C32(0xb18249b6), SPH_C32(0x99b4cf56), + SPH_C32(0x27eac0de), SPH_C32(0x4b783b20), SPH_C32(0xe2dd0000), + SPH_C32(0x69970030), SPH_C32(0x00ea6000), SPH_C32(0x27ff0000), + SPH_C32(0x5bc54f5d), SPH_C32(0x3d5a693a), SPH_C32(0x5d611dd2), + SPH_C32(0x5ce212c7) }, + { SPH_C32(0xaebc0000), SPH_C32(0x28b500b4), SPH_C32(0x95ce6000), + SPH_C32(0x00130000), SPH_C32(0x475f13d2), SPH_C32(0xaf8693dc), + SPH_C32(0xd5982870), SPH_C32(0xedc0f9ad), SPH_C32(0x64a40000), + SPH_C32(0x56ae0032), SPH_C32(0xe1708000), SPH_C32(0xbfa90000), + SPH_C32(0xcea02853), SPH_C32(0x73d2a1d0), SPH_C32(0x8ebc5496), + SPH_C32(0x4affc87e) }, + { SPH_C32(0x28c50000), SPH_C32(0x178c00b6), SPH_C32(0x74548000), + SPH_C32(0x98450000), SPH_C32(0xd23a74dc), SPH_C32(0xe10e5b36), + SPH_C32(0x06456134), SPH_C32(0xfbdd2314), SPH_C32(0x54130000), + SPH_C32(0xb37e0032), SPH_C32(0x1584e000), SPH_C32(0xfd6d0000), + SPH_C32(0xad181539), SPH_C32(0x0b6835b0), SPH_C32(0xaf13f57c), + SPH_C32(0xfa5ad04a) }, + { SPH_C32(0x3d010000), SPH_C32(0xd29000c0), SPH_C32(0xe68d0000), + SPH_C32(0xc6310000), SPH_C32(0xca304571), SPH_C32(0xa8ea90ce), + SPH_C32(0x385630bf), SPH_C32(0xc290fed9), SPH_C32(0x7afe0000), + SPH_C32(0x53b60014), SPH_C32(0xbd420000), SPH_C32(0xf0860000), + SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), SPH_C32(0x1d3a76bf), + SPH_C32(0x1bb6813d) }, + { SPH_C32(0xbb780000), SPH_C32(0xeda900c2), SPH_C32(0x0717e000), + SPH_C32(0x5e670000), SPH_C32(0x5f55227f), SPH_C32(0xe6625824), + SPH_C32(0xeb8b79fb), SPH_C32(0xd48d2460), SPH_C32(0x4a490000), + SPH_C32(0xb6660014), SPH_C32(0x49b66000), SPH_C32(0xb2420000), + SPH_C32(0xeeb15029), SPH_C32(0x430f5d19), SPH_C32(0x3c95d755), + SPH_C32(0xab139909) }, + { SPH_C32(0x0db60000), SPH_C32(0x374000c0), SPH_C32(0x12796000), + SPH_C32(0x84f50000), SPH_C32(0xa988781b), SPH_C32(0xd05004ae), + SPH_C32(0x19f99155), SPH_C32(0x7235e6ed), SPH_C32(0xcc300000), + SPH_C32(0x895f0016), SPH_C32(0xa82c8000), SPH_C32(0x2a140000), + SPH_C32(0x7bd43727), SPH_C32(0x0d8795f3), SPH_C32(0xef489e11), + SPH_C32(0xbd0e43b0) }, + { SPH_C32(0x8bcf0000), SPH_C32(0x087900c2), SPH_C32(0xf3e38000), + SPH_C32(0x1ca30000), SPH_C32(0x3ced1f15), SPH_C32(0x9ed8cc44), + SPH_C32(0xca24d811), SPH_C32(0x64283c54), SPH_C32(0xfc870000), + SPH_C32(0x6c8f0016), SPH_C32(0x5cd8e000), SPH_C32(0x68d00000), + SPH_C32(0x186c0a4d), SPH_C32(0x753d0193), SPH_C32(0xcee73ffb), + SPH_C32(0x0dab5b84) }, + { SPH_C32(0x29180000), SPH_C32(0xf15a00fc), SPH_C32(0xb6520000), + SPH_C32(0x82870000), SPH_C32(0xd15c22c1), SPH_C32(0x94193cbb), + SPH_C32(0x59b0200f), SPH_C32(0x195a2559), SPH_C32(0x99bd0000), + SPH_C32(0x69f80000), SPH_C32(0x4f840000), SPH_C32(0x5ac80000), + SPH_C32(0x56172fe5), SPH_C32(0x1ede776c), SPH_C32(0x0f07c7e9), + SPH_C32(0x21f818ea) }, + { SPH_C32(0xaf610000), SPH_C32(0xce6300fe), SPH_C32(0x57c8e000), + SPH_C32(0x1ad10000), SPH_C32(0x443945cf), SPH_C32(0xda91f451), + SPH_C32(0x8a6d694b), SPH_C32(0x0f47ffe0), SPH_C32(0xa90a0000), + SPH_C32(0x8c280000), SPH_C32(0xbb706000), SPH_C32(0x180c0000), + SPH_C32(0x35af128f), SPH_C32(0x6664e30c), SPH_C32(0x2ea86603), + SPH_C32(0x915d00de) }, + { SPH_C32(0x19af0000), SPH_C32(0x148a00fc), SPH_C32(0x42a66000), + SPH_C32(0xc0430000), SPH_C32(0xb2e41fab), SPH_C32(0xeca3a8db), + SPH_C32(0x781f81e5), SPH_C32(0xa9ff3d6d), SPH_C32(0x2f730000), + SPH_C32(0xb3110002), SPH_C32(0x5aea8000), SPH_C32(0x805a0000), + SPH_C32(0xa0ca7581), SPH_C32(0x28ec2be6), SPH_C32(0xfd752f47), + SPH_C32(0x8740da67) }, + { SPH_C32(0x9fd60000), SPH_C32(0x2bb300fe), SPH_C32(0xa33c8000), + SPH_C32(0x58150000), SPH_C32(0x278178a5), SPH_C32(0xa22b6031), + SPH_C32(0xabc2c8a1), SPH_C32(0xbfe2e7d4), SPH_C32(0x1fc40000), + SPH_C32(0x56c10002), SPH_C32(0xae1ee000), SPH_C32(0xc29e0000), + SPH_C32(0xc37248eb), SPH_C32(0x5056bf86), SPH_C32(0xdcda8ead), + SPH_C32(0x37e5c253) }, + { SPH_C32(0xde420000), SPH_C32(0xe8de00d4), SPH_C32(0x144b0000), + SPH_C32(0x6c7f0000), SPH_C32(0x112e07d7), SPH_C32(0x8d812edb), + SPH_C32(0x2a6b81e9), SPH_C32(0xf8de670e), SPH_C32(0x8da40000), + SPH_C32(0x4a32003c), SPH_C32(0x1f5b0000), SPH_C32(0x1e7e0000), + SPH_C32(0x4d7b4855), SPH_C32(0x222ddb19), SPH_C32(0x6ee1d759), + SPH_C32(0xfa32c36a) }, + { SPH_C32(0x583b0000), SPH_C32(0xd7e700d6), SPH_C32(0xf5d1e000), + SPH_C32(0xf4290000), SPH_C32(0x844b60d9), SPH_C32(0xc309e631), + SPH_C32(0xf9b6c8ad), SPH_C32(0xeec3bdb7), SPH_C32(0xbd130000), + SPH_C32(0xafe2003c), SPH_C32(0xebaf6000), SPH_C32(0x5cba0000), + SPH_C32(0x2ec3753f), SPH_C32(0x5a974f79), SPH_C32(0x4f4e76b3), + SPH_C32(0x4a97db5e) }, + { SPH_C32(0xeef50000), SPH_C32(0x0d0e00d4), SPH_C32(0xe0bf6000), + SPH_C32(0x2ebb0000), SPH_C32(0x72963abd), SPH_C32(0xf53bbabb), + SPH_C32(0x0bc42003), SPH_C32(0x487b7f3a), SPH_C32(0x3b6a0000), + SPH_C32(0x90db003e), SPH_C32(0x0a358000), SPH_C32(0xc4ec0000), + SPH_C32(0xbba61231), SPH_C32(0x141f8793), SPH_C32(0x9c933ff7), + SPH_C32(0x5c8a01e7) }, + { SPH_C32(0x688c0000), SPH_C32(0x323700d6), SPH_C32(0x01258000), + SPH_C32(0xb6ed0000), SPH_C32(0xe7f35db3), SPH_C32(0xbbb37251), + SPH_C32(0xd8196947), SPH_C32(0x5e66a583), SPH_C32(0x0bdd0000), + SPH_C32(0x750b003e), SPH_C32(0xfec1e000), SPH_C32(0x86280000), + SPH_C32(0xd81e2f5b), SPH_C32(0x6ca513f3), SPH_C32(0xbd3c9e1d), + SPH_C32(0xec2f19d3) }, + { SPH_C32(0xca5b0000), SPH_C32(0xcb1400e8), SPH_C32(0x44940000), + SPH_C32(0x28c90000), SPH_C32(0x0a426067), SPH_C32(0xb17282ae), + SPH_C32(0x4b8d9159), SPH_C32(0x2314bc8e), SPH_C32(0x6ee70000), + SPH_C32(0x707c0028), SPH_C32(0xed9d0000), SPH_C32(0xb4300000), + SPH_C32(0x96650af3), SPH_C32(0x0746650c), SPH_C32(0x7cdc660f), + SPH_C32(0xc07c5abd) }, + { SPH_C32(0x4c220000), SPH_C32(0xf42d00ea), SPH_C32(0xa50ee000), + SPH_C32(0xb09f0000), SPH_C32(0x9f270769), SPH_C32(0xfffa4a44), + SPH_C32(0x9850d81d), SPH_C32(0x35096637), SPH_C32(0x5e500000), + SPH_C32(0x95ac0028), SPH_C32(0x19696000), SPH_C32(0xf6f40000), + SPH_C32(0xf5dd3799), SPH_C32(0x7ffcf16c), SPH_C32(0x5d73c7e5), + SPH_C32(0x70d94289) }, + { SPH_C32(0xfaec0000), SPH_C32(0x2ec400e8), SPH_C32(0xb0606000), + SPH_C32(0x6a0d0000), SPH_C32(0x69fa5d0d), SPH_C32(0xc9c816ce), + SPH_C32(0x6a2230b3), SPH_C32(0x93b1a4ba), SPH_C32(0xd8290000), + SPH_C32(0xaa95002a), SPH_C32(0xf8f38000), SPH_C32(0x6ea20000), + SPH_C32(0x60b85097), SPH_C32(0x31743986), SPH_C32(0x8eae8ea1), + SPH_C32(0x66c49830) }, + { SPH_C32(0x7c950000), SPH_C32(0x11fd00ea), SPH_C32(0x51fa8000), + SPH_C32(0xf25b0000), SPH_C32(0xfc9f3a03), SPH_C32(0x8740de24), + SPH_C32(0xb9ff79f7), SPH_C32(0x85ac7e03), SPH_C32(0xe89e0000), + SPH_C32(0x4f45002a), SPH_C32(0x0c07e000), SPH_C32(0x2c660000), + SPH_C32(0x03006dfd), SPH_C32(0x49ceade6), SPH_C32(0xaf012f4b), + SPH_C32(0xd6618004) }, + { SPH_C32(0xd5dc0000), SPH_C32(0x28da0084), SPH_C32(0xdaa00000), + SPH_C32(0x7d240000), SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), + SPH_C32(0x87fef24b), SPH_C32(0x90daf380), SPH_C32(0x2eae0000), + SPH_C32(0x55c70048), SPH_C32(0x98ec0000), SPH_C32(0x9a980000), + SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), SPH_C32(0xa2806e7c), + SPH_C32(0x65c7dc2a) }, + { SPH_C32(0x53a50000), SPH_C32(0x17e30086), SPH_C32(0x3b3ae000), + SPH_C32(0xe5720000), SPH_C32(0xdfe81464), SPH_C32(0xc28a4560), + SPH_C32(0x5423bb0f), SPH_C32(0x86c72939), SPH_C32(0x1e190000), + SPH_C32(0xb0170048), SPH_C32(0x6c186000), SPH_C32(0xd85c0000), + SPH_C32(0xc0141ef6), SPH_C32(0x2541d80b), SPH_C32(0x832fcf96), + SPH_C32(0xd562c41e) }, + { SPH_C32(0xe56b0000), SPH_C32(0xcd0a0084), SPH_C32(0x2e546000), + SPH_C32(0x3fe00000), SPH_C32(0x29354e00), SPH_C32(0xf4b819ea), + SPH_C32(0xa65153a1), SPH_C32(0x207febb4), SPH_C32(0x98600000), + SPH_C32(0x8f2e004a), SPH_C32(0x8d828000), SPH_C32(0x400a0000), + SPH_C32(0x557179f8), SPH_C32(0x6bc910e1), SPH_C32(0x50f286d2), + SPH_C32(0xc37f1ea7) }, + { SPH_C32(0x63120000), SPH_C32(0xf2330086), SPH_C32(0xcfce8000), + SPH_C32(0xa7b60000), SPH_C32(0xbc50290e), SPH_C32(0xba30d100), + SPH_C32(0x758c1ae5), SPH_C32(0x3662310d), SPH_C32(0xa8d70000), + SPH_C32(0x6afe004a), SPH_C32(0x7976e000), SPH_C32(0x02ce0000), + SPH_C32(0x36c94492), SPH_C32(0x13738481), SPH_C32(0x715d2738), + SPH_C32(0x73da0693) }, + { SPH_C32(0xc1c50000), SPH_C32(0x0b1000b8), SPH_C32(0x8a7f0000), + SPH_C32(0x39920000), SPH_C32(0x51e114da), SPH_C32(0xb0f121ff), + SPH_C32(0xe618e2fb), SPH_C32(0x4b102800), SPH_C32(0xcded0000), + SPH_C32(0x6f89005c), SPH_C32(0x6a2a0000), SPH_C32(0x30d60000), + SPH_C32(0x78b2613a), SPH_C32(0x7890f27e), SPH_C32(0xb0bddf2a), + SPH_C32(0x5f8945fd) }, + { SPH_C32(0x47bc0000), SPH_C32(0x342900ba), SPH_C32(0x6be5e000), + SPH_C32(0xa1c40000), SPH_C32(0xc48473d4), SPH_C32(0xfe79e915), + SPH_C32(0x35c5abbf), SPH_C32(0x5d0df2b9), SPH_C32(0xfd5a0000), + SPH_C32(0x8a59005c), SPH_C32(0x9ede6000), SPH_C32(0x72120000), + SPH_C32(0x1b0a5c50), SPH_C32(0x002a661e), SPH_C32(0x91127ec0), + SPH_C32(0xef2c5dc9) }, + { SPH_C32(0xf1720000), SPH_C32(0xeec000b8), SPH_C32(0x7e8b6000), + SPH_C32(0x7b560000), SPH_C32(0x325929b0), SPH_C32(0xc84bb59f), + SPH_C32(0xc7b74311), SPH_C32(0xfbb53034), SPH_C32(0x7b230000), + SPH_C32(0xb560005e), SPH_C32(0x7f448000), SPH_C32(0xea440000), + SPH_C32(0x8e6f3b5e), SPH_C32(0x4ea2aef4), SPH_C32(0x42cf3784), + SPH_C32(0xf9318770) }, + { SPH_C32(0x770b0000), SPH_C32(0xd1f900ba), SPH_C32(0x9f118000), + SPH_C32(0xe3000000), SPH_C32(0xa73c4ebe), SPH_C32(0x86c37d75), + SPH_C32(0x146a0a55), SPH_C32(0xeda8ea8d), SPH_C32(0x4b940000), + SPH_C32(0x50b0005e), SPH_C32(0x8bb0e000), SPH_C32(0xa8800000), + SPH_C32(0xedd70634), SPH_C32(0x36183a94), SPH_C32(0x6360966e), + SPH_C32(0x49949f44) }, + { SPH_C32(0x369f0000), SPH_C32(0x12940090), SPH_C32(0x28660000), + SPH_C32(0xd76a0000), SPH_C32(0x919331cc), SPH_C32(0xa969339f), + SPH_C32(0x95c3431d), SPH_C32(0xaa946a57), SPH_C32(0xd9f40000), + SPH_C32(0x4c430060), SPH_C32(0x3af50000), SPH_C32(0x74600000), + SPH_C32(0x63de068a), SPH_C32(0x44635e0b), SPH_C32(0xd15bcf9a), + SPH_C32(0x84439e7d) }, + { SPH_C32(0xb0e60000), SPH_C32(0x2dad0092), SPH_C32(0xc9fce000), + SPH_C32(0x4f3c0000), SPH_C32(0x04f656c2), SPH_C32(0xe7e1fb75), + SPH_C32(0x461e0a59), SPH_C32(0xbc89b0ee), SPH_C32(0xe9430000), + SPH_C32(0xa9930060), SPH_C32(0xce016000), SPH_C32(0x36a40000), + SPH_C32(0x00663be0), SPH_C32(0x3cd9ca6b), SPH_C32(0xf0f46e70), + SPH_C32(0x34e68649) }, + { SPH_C32(0x06280000), SPH_C32(0xf7440090), SPH_C32(0xdc926000), + SPH_C32(0x95ae0000), SPH_C32(0xf22b0ca6), SPH_C32(0xd1d3a7ff), + SPH_C32(0xb46ce2f7), SPH_C32(0x1a317263), SPH_C32(0x6f3a0000), + SPH_C32(0x96aa0062), SPH_C32(0x2f9b8000), SPH_C32(0xaef20000), + SPH_C32(0x95035cee), SPH_C32(0x72510281), SPH_C32(0x23292734), + SPH_C32(0x22fb5cf0) }, + { SPH_C32(0x80510000), SPH_C32(0xc87d0092), SPH_C32(0x3d088000), + SPH_C32(0x0df80000), SPH_C32(0x674e6ba8), SPH_C32(0x9f5b6f15), + SPH_C32(0x67b1abb3), SPH_C32(0x0c2ca8da), SPH_C32(0x5f8d0000), + SPH_C32(0x737a0062), SPH_C32(0xdb6fe000), SPH_C32(0xec360000), + SPH_C32(0xf6bb6184), SPH_C32(0x0aeb96e1), SPH_C32(0x028686de), + SPH_C32(0x925e44c4) }, + { SPH_C32(0x22860000), SPH_C32(0x315e00ac), SPH_C32(0x78b90000), + SPH_C32(0x93dc0000), SPH_C32(0x8aff567c), SPH_C32(0x959a9fea), + SPH_C32(0xf42553ad), SPH_C32(0x715eb1d7), SPH_C32(0x3ab70000), + SPH_C32(0x760d0074), SPH_C32(0xc8330000), SPH_C32(0xde2e0000), + SPH_C32(0xb8c0442c), SPH_C32(0x6108e01e), SPH_C32(0xc3667ecc), + SPH_C32(0xbe0d07aa) }, + { SPH_C32(0xa4ff0000), SPH_C32(0x0e6700ae), SPH_C32(0x9923e000), + SPH_C32(0x0b8a0000), SPH_C32(0x1f9a3172), SPH_C32(0xdb125700), + SPH_C32(0x27f81ae9), SPH_C32(0x67436b6e), SPH_C32(0x0a000000), + SPH_C32(0x93dd0074), SPH_C32(0x3cc76000), SPH_C32(0x9cea0000), + SPH_C32(0xdb787946), SPH_C32(0x19b2747e), SPH_C32(0xe2c9df26), + SPH_C32(0x0ea81f9e) }, + { SPH_C32(0x12310000), SPH_C32(0xd48e00ac), SPH_C32(0x8c4d6000), + SPH_C32(0xd1180000), SPH_C32(0xe9476b16), SPH_C32(0xed200b8a), + SPH_C32(0xd58af247), SPH_C32(0xc1fba9e3), SPH_C32(0x8c790000), + SPH_C32(0xace40076), SPH_C32(0xdd5d8000), SPH_C32(0x04bc0000), + SPH_C32(0x4e1d1e48), SPH_C32(0x573abc94), SPH_C32(0x31149662), + SPH_C32(0x18b5c527) }, + { SPH_C32(0x94480000), SPH_C32(0xebb700ae), SPH_C32(0x6dd78000), + SPH_C32(0x494e0000), SPH_C32(0x7c220c18), SPH_C32(0xa3a8c360), + SPH_C32(0x0657bb03), SPH_C32(0xd7e6735a), SPH_C32(0xbcce0000), + SPH_C32(0x49340076), SPH_C32(0x29a9e000), SPH_C32(0x46780000), + SPH_C32(0x2da52322), SPH_C32(0x2f8028f4), SPH_C32(0x10bb3788), + SPH_C32(0xa810dd13) }, + { SPH_C32(0x818c0000), SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), + SPH_C32(0x173a0000), SPH_C32(0x64283db5), SPH_C32(0xea4c0898), + SPH_C32(0x3844ea88), SPH_C32(0xeeabae97), SPH_C32(0x92230000), + SPH_C32(0xa9fc0050), SPH_C32(0x816f0000), SPH_C32(0x4b930000), + SPH_C32(0x0db45b58), SPH_C32(0x1f5dd43d), SPH_C32(0xa292b44b), + SPH_C32(0x49fc8c64) }, + { SPH_C32(0x07f50000), SPH_C32(0x119200da), SPH_C32(0x1e94e000), + SPH_C32(0x8f6c0000), SPH_C32(0xf14d5abb), SPH_C32(0xa4c4c072), + SPH_C32(0xeb99a3cc), SPH_C32(0xf8b6742e), SPH_C32(0xa2940000), + SPH_C32(0x4c2c0050), SPH_C32(0x759b6000), SPH_C32(0x09570000), + SPH_C32(0x6e0c6632), SPH_C32(0x67e7405d), SPH_C32(0x833d15a1), + SPH_C32(0xf9599450) }, + { SPH_C32(0xb13b0000), SPH_C32(0xcb7b00d8), SPH_C32(0x0bfa6000), + SPH_C32(0x55fe0000), SPH_C32(0x079000df), SPH_C32(0x92f69cf8), + SPH_C32(0x19eb4b62), SPH_C32(0x5e0eb6a3), SPH_C32(0x24ed0000), + SPH_C32(0x73150052), SPH_C32(0x94018000), SPH_C32(0x91010000), + SPH_C32(0xfb69013c), SPH_C32(0x296f88b7), SPH_C32(0x50e05ce5), + SPH_C32(0xef444ee9) }, + { SPH_C32(0x37420000), SPH_C32(0xf44200da), SPH_C32(0xea608000), + SPH_C32(0xcda80000), SPH_C32(0x92f567d1), SPH_C32(0xdc7e5412), + SPH_C32(0xca360226), SPH_C32(0x48136c1a), SPH_C32(0x145a0000), + SPH_C32(0x96c50052), SPH_C32(0x60f5e000), SPH_C32(0xd3c50000), + SPH_C32(0x98d13c56), SPH_C32(0x51d51cd7), SPH_C32(0x714ffd0f), + SPH_C32(0x5fe156dd) }, + { SPH_C32(0x95950000), SPH_C32(0x0d6100e4), SPH_C32(0xafd10000), + SPH_C32(0x538c0000), SPH_C32(0x7f445a05), SPH_C32(0xd6bfa4ed), + SPH_C32(0x59a2fa38), SPH_C32(0x35617517), SPH_C32(0x71600000), + SPH_C32(0x93b20044), SPH_C32(0x73a90000), SPH_C32(0xe1dd0000), + SPH_C32(0xd6aa19fe), SPH_C32(0x3a366a28), SPH_C32(0xb0af051d), + SPH_C32(0x73b215b3) }, + { SPH_C32(0x13ec0000), SPH_C32(0x325800e6), SPH_C32(0x4e4be000), + SPH_C32(0xcbda0000), SPH_C32(0xea213d0b), SPH_C32(0x98376c07), + SPH_C32(0x8a7fb37c), SPH_C32(0x237cafae), SPH_C32(0x41d70000), + SPH_C32(0x76620044), SPH_C32(0x875d6000), SPH_C32(0xa3190000), + SPH_C32(0xb5122494), SPH_C32(0x428cfe48), SPH_C32(0x9100a4f7), + SPH_C32(0xc3170d87) }, + { SPH_C32(0xa5220000), SPH_C32(0xe8b100e4), SPH_C32(0x5b256000), + SPH_C32(0x11480000), SPH_C32(0x1cfc676f), SPH_C32(0xae05308d), + SPH_C32(0x780d5bd2), SPH_C32(0x85c46d23), SPH_C32(0xc7ae0000), + SPH_C32(0x495b0046), SPH_C32(0x66c78000), SPH_C32(0x3b4f0000), + SPH_C32(0x2077439a), SPH_C32(0x0c0436a2), SPH_C32(0x42ddedb3), + SPH_C32(0xd50ad73e) }, + { SPH_C32(0x235b0000), SPH_C32(0xd78800e6), SPH_C32(0xbabf8000), + SPH_C32(0x891e0000), SPH_C32(0x89990061), SPH_C32(0xe08df867), + SPH_C32(0xabd01296), SPH_C32(0x93d9b79a), SPH_C32(0xf7190000), + SPH_C32(0xac8b0046), SPH_C32(0x9233e000), SPH_C32(0x798b0000), + SPH_C32(0x43cf7ef0), SPH_C32(0x74bea2c2), SPH_C32(0x63724c59), + SPH_C32(0x65afcf0a) }, + { SPH_C32(0x62cf0000), SPH_C32(0x14e500cc), SPH_C32(0x0dc80000), + SPH_C32(0xbd740000), SPH_C32(0xbf367f13), SPH_C32(0xcf27b68d), + SPH_C32(0x2a795bde), SPH_C32(0xd4e53740), SPH_C32(0x65790000), + SPH_C32(0xb0780078), SPH_C32(0x23760000), SPH_C32(0xa56b0000), + SPH_C32(0xcdc67e4e), SPH_C32(0x06c5c65d), SPH_C32(0xd14915ad), + SPH_C32(0xa878ce33) }, + { SPH_C32(0xe4b60000), SPH_C32(0x2bdc00ce), SPH_C32(0xec52e000), + SPH_C32(0x25220000), SPH_C32(0x2a53181d), SPH_C32(0x81af7e67), + SPH_C32(0xf9a4129a), SPH_C32(0xc2f8edf9), SPH_C32(0x55ce0000), + SPH_C32(0x55a80078), SPH_C32(0xd7826000), SPH_C32(0xe7af0000), + SPH_C32(0xae7e4324), SPH_C32(0x7e7f523d), SPH_C32(0xf0e6b447), + SPH_C32(0x18ddd607) }, + { SPH_C32(0x52780000), SPH_C32(0xf13500cc), SPH_C32(0xf93c6000), + SPH_C32(0xffb00000), SPH_C32(0xdc8e4279), SPH_C32(0xb79d22ed), + SPH_C32(0x0bd6fa34), SPH_C32(0x64402f74), SPH_C32(0xd3b70000), + SPH_C32(0x6a91007a), SPH_C32(0x36188000), SPH_C32(0x7ff90000), + SPH_C32(0x3b1b242a), SPH_C32(0x30f79ad7), SPH_C32(0x233bfd03), + SPH_C32(0x0ec00cbe) }, + { SPH_C32(0xd4010000), SPH_C32(0xce0c00ce), SPH_C32(0x18a68000), + SPH_C32(0x67e60000), SPH_C32(0x49eb2577), SPH_C32(0xf915ea07), + SPH_C32(0xd80bb370), SPH_C32(0x725df5cd), SPH_C32(0xe3000000), + SPH_C32(0x8f41007a), SPH_C32(0xc2ece000), SPH_C32(0x3d3d0000), + SPH_C32(0x58a31940), SPH_C32(0x484d0eb7), SPH_C32(0x02945ce9), + SPH_C32(0xbe65148a) }, + { SPH_C32(0x76d60000), SPH_C32(0x372f00f0), SPH_C32(0x5d170000), + SPH_C32(0xf9c20000), SPH_C32(0xa45a18a3), SPH_C32(0xf3d41af8), + SPH_C32(0x4b9f4b6e), SPH_C32(0x0f2fecc0), SPH_C32(0x863a0000), + SPH_C32(0x8a36006c), SPH_C32(0xd1b00000), SPH_C32(0x0f250000), + SPH_C32(0x16d83ce8), SPH_C32(0x23ae7848), SPH_C32(0xc374a4fb), + SPH_C32(0x923657e4) }, + { SPH_C32(0xf0af0000), SPH_C32(0x081600f2), SPH_C32(0xbc8de000), + SPH_C32(0x61940000), SPH_C32(0x313f7fad), SPH_C32(0xbd5cd212), + SPH_C32(0x9842022a), SPH_C32(0x19323679), SPH_C32(0xb68d0000), + SPH_C32(0x6fe6006c), SPH_C32(0x25446000), SPH_C32(0x4de10000), + SPH_C32(0x75600182), SPH_C32(0x5b14ec28), SPH_C32(0xe2db0511), + SPH_C32(0x22934fd0) }, + { SPH_C32(0x46610000), SPH_C32(0xd2ff00f0), SPH_C32(0xa9e36000), + SPH_C32(0xbb060000), SPH_C32(0xc7e225c9), SPH_C32(0x8b6e8e98), + SPH_C32(0x6a30ea84), SPH_C32(0xbf8af4f4), SPH_C32(0x30f40000), + SPH_C32(0x50df006e), SPH_C32(0xc4de8000), SPH_C32(0xd5b70000), + SPH_C32(0xe005668c), SPH_C32(0x159c24c2), SPH_C32(0x31064c55), + SPH_C32(0x348e9569) }, + { SPH_C32(0xc0180000), SPH_C32(0xedc600f2), SPH_C32(0x48798000), + SPH_C32(0x23500000), SPH_C32(0x528742c7), SPH_C32(0xc5e64672), + SPH_C32(0xb9eda3c0), SPH_C32(0xa9972e4d), SPH_C32(0x00430000), + SPH_C32(0xb50f006e), SPH_C32(0x302ae000), SPH_C32(0x97730000), + SPH_C32(0x83bd5be6), SPH_C32(0x6d26b0a2), SPH_C32(0x10a9edbf), + SPH_C32(0x842b8d5d) }, + { SPH_C32(0xc6730000), SPH_C32(0xaf8d000c), SPH_C32(0xa4c10000), + SPH_C32(0x218d0000), SPH_C32(0x23111587), SPH_C32(0x7913512f), + SPH_C32(0x1d28ac88), SPH_C32(0x378dd173), SPH_C32(0xaf220000), + SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), SPH_C32(0x8da20000), + SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), SPH_C32(0x9ac484f4), + SPH_C32(0x8b6c72bd) }, + { SPH_C32(0x400a0000), SPH_C32(0x90b4000e), SPH_C32(0x455be000), + SPH_C32(0xb9db0000), SPH_C32(0xb6747289), SPH_C32(0x379b99c5), + SPH_C32(0xcef5e5cc), SPH_C32(0x21900bca), SPH_C32(0x9f950000), + SPH_C32(0x9ebc0090), SPH_C32(0x93166000), SPH_C32(0xcf660000), + SPH_C32(0xa43c2343), SPH_C32(0xcf0dd093), SPH_C32(0xbb6b251e), + SPH_C32(0x3bc96a89) }, + { SPH_C32(0xf6c40000), SPH_C32(0x4a5d000c), SPH_C32(0x50356000), + SPH_C32(0x63490000), SPH_C32(0x40a928ed), SPH_C32(0x01a9c54f), + SPH_C32(0x3c870d62), SPH_C32(0x8728c947), SPH_C32(0x19ec0000), + SPH_C32(0xa1850092), SPH_C32(0x728c8000), SPH_C32(0x57300000), + SPH_C32(0x3159444d), SPH_C32(0x81851879), SPH_C32(0x68b66c5a), + SPH_C32(0x2dd4b030) }, + { SPH_C32(0x70bd0000), SPH_C32(0x7564000e), SPH_C32(0xb1af8000), + SPH_C32(0xfb1f0000), SPH_C32(0xd5cc4fe3), SPH_C32(0x4f210da5), + SPH_C32(0xef5a4426), SPH_C32(0x913513fe), SPH_C32(0x295b0000), + SPH_C32(0x44550092), SPH_C32(0x8678e000), SPH_C32(0x15f40000), + SPH_C32(0x52e17927), SPH_C32(0xf93f8c19), SPH_C32(0x4919cdb0), + SPH_C32(0x9d71a804) }, + { SPH_C32(0xd26a0000), SPH_C32(0x8c470030), SPH_C32(0xf41e0000), + SPH_C32(0x653b0000), SPH_C32(0x387d7237), SPH_C32(0x45e0fd5a), + SPH_C32(0x7ccebc38), SPH_C32(0xec470af3), SPH_C32(0x4c610000), + SPH_C32(0x41220084), SPH_C32(0x95240000), SPH_C32(0x27ec0000), + SPH_C32(0x1c9a5c8f), SPH_C32(0x92dcfae6), SPH_C32(0x88f935a2), + SPH_C32(0xb122eb6a) }, + { SPH_C32(0x54130000), SPH_C32(0xb37e0032), SPH_C32(0x1584e000), + SPH_C32(0xfd6d0000), SPH_C32(0xad181539), SPH_C32(0x0b6835b0), + SPH_C32(0xaf13f57c), SPH_C32(0xfa5ad04a), SPH_C32(0x7cd60000), + SPH_C32(0xa4f20084), SPH_C32(0x61d06000), SPH_C32(0x65280000), + SPH_C32(0x7f2261e5), SPH_C32(0xea666e86), SPH_C32(0xa9569448), + SPH_C32(0x0187f35e) }, + { SPH_C32(0xe2dd0000), SPH_C32(0x69970030), SPH_C32(0x00ea6000), + SPH_C32(0x27ff0000), SPH_C32(0x5bc54f5d), SPH_C32(0x3d5a693a), + SPH_C32(0x5d611dd2), SPH_C32(0x5ce212c7), SPH_C32(0xfaaf0000), + SPH_C32(0x9bcb0086), SPH_C32(0x804a8000), SPH_C32(0xfd7e0000), + SPH_C32(0xea4706eb), SPH_C32(0xa4eea66c), SPH_C32(0x7a8bdd0c), + SPH_C32(0x179a29e7) }, + { SPH_C32(0x64a40000), SPH_C32(0x56ae0032), SPH_C32(0xe1708000), + SPH_C32(0xbfa90000), SPH_C32(0xcea02853), SPH_C32(0x73d2a1d0), + SPH_C32(0x8ebc5496), SPH_C32(0x4affc87e), SPH_C32(0xca180000), + SPH_C32(0x7e1b0086), SPH_C32(0x74bee000), SPH_C32(0xbfba0000), + SPH_C32(0x89ff3b81), SPH_C32(0xdc54320c), SPH_C32(0x5b247ce6), + SPH_C32(0xa73f31d3) }, + { SPH_C32(0x25300000), SPH_C32(0x95c30018), SPH_C32(0x56070000), + SPH_C32(0x8bc30000), SPH_C32(0xf80f5721), SPH_C32(0x5c78ef3a), + SPH_C32(0x0f151dde), SPH_C32(0x0dc348a4), SPH_C32(0x58780000), + SPH_C32(0x62e800b8), SPH_C32(0xc5fb0000), SPH_C32(0x635a0000), + SPH_C32(0x07f63b3f), SPH_C32(0xae2f5693), SPH_C32(0xe91f2512), + SPH_C32(0x6ae830ea) }, + { SPH_C32(0xa3490000), SPH_C32(0xaafa001a), SPH_C32(0xb79de000), + SPH_C32(0x13950000), SPH_C32(0x6d6a302f), SPH_C32(0x12f027d0), + SPH_C32(0xdcc8549a), SPH_C32(0x1bde921d), SPH_C32(0x68cf0000), + SPH_C32(0x873800b8), SPH_C32(0x310f6000), SPH_C32(0x219e0000), + SPH_C32(0x644e0655), SPH_C32(0xd695c2f3), SPH_C32(0xc8b084f8), + SPH_C32(0xda4d28de) }, + { SPH_C32(0x15870000), SPH_C32(0x70130018), SPH_C32(0xa2f36000), + SPH_C32(0xc9070000), SPH_C32(0x9bb76a4b), SPH_C32(0x24c27b5a), + SPH_C32(0x2ebabc34), SPH_C32(0xbd665090), SPH_C32(0xeeb60000), + SPH_C32(0xb80100ba), SPH_C32(0xd0958000), SPH_C32(0xb9c80000), + SPH_C32(0xf12b615b), SPH_C32(0x981d0a19), SPH_C32(0x1b6dcdbc), + SPH_C32(0xcc50f267) }, + { SPH_C32(0x93fe0000), SPH_C32(0x4f2a001a), SPH_C32(0x43698000), + SPH_C32(0x51510000), SPH_C32(0x0ed20d45), SPH_C32(0x6a4ab3b0), + SPH_C32(0xfd67f570), SPH_C32(0xab7b8a29), SPH_C32(0xde010000), + SPH_C32(0x5dd100ba), SPH_C32(0x2461e000), SPH_C32(0xfb0c0000), + SPH_C32(0x92935c31), SPH_C32(0xe0a79e79), SPH_C32(0x3ac26c56), + SPH_C32(0x7cf5ea53) }, + { SPH_C32(0x31290000), SPH_C32(0xb6090024), SPH_C32(0x06d80000), + SPH_C32(0xcf750000), SPH_C32(0xe3633091), SPH_C32(0x608b434f), + SPH_C32(0x6ef30d6e), SPH_C32(0xd6099324), SPH_C32(0xbb3b0000), + SPH_C32(0x58a600ac), SPH_C32(0x373d0000), SPH_C32(0xc9140000), + SPH_C32(0xdce87999), SPH_C32(0x8b44e886), SPH_C32(0xfb229444), + SPH_C32(0x50a6a93d) }, + { SPH_C32(0xb7500000), SPH_C32(0x89300026), SPH_C32(0xe742e000), + SPH_C32(0x57230000), SPH_C32(0x7606579f), SPH_C32(0x2e038ba5), + SPH_C32(0xbd2e442a), SPH_C32(0xc014499d), SPH_C32(0x8b8c0000), + SPH_C32(0xbd7600ac), SPH_C32(0xc3c96000), SPH_C32(0x8bd00000), + SPH_C32(0xbf5044f3), SPH_C32(0xf3fe7ce6), SPH_C32(0xda8d35ae), + SPH_C32(0xe003b109) }, + { SPH_C32(0x019e0000), SPH_C32(0x53d90024), SPH_C32(0xf22c6000), + SPH_C32(0x8db10000), SPH_C32(0x80db0dfb), SPH_C32(0x1831d72f), + SPH_C32(0x4f5cac84), SPH_C32(0x66ac8b10), SPH_C32(0x0df50000), + SPH_C32(0x824f00ae), SPH_C32(0x22538000), SPH_C32(0x13860000), + SPH_C32(0x2a3523fd), SPH_C32(0xbd76b40c), SPH_C32(0x09507cea), + SPH_C32(0xf61e6bb0) }, + { SPH_C32(0x87e70000), SPH_C32(0x6ce00026), SPH_C32(0x13b68000), + SPH_C32(0x15e70000), SPH_C32(0x15be6af5), SPH_C32(0x56b91fc5), + SPH_C32(0x9c81e5c0), SPH_C32(0x70b151a9), SPH_C32(0x3d420000), + SPH_C32(0x679f00ae), SPH_C32(0xd6a7e000), SPH_C32(0x51420000), + SPH_C32(0x498d1e97), SPH_C32(0xc5cc206c), SPH_C32(0x28ffdd00), + SPH_C32(0x46bb7384) }, + { SPH_C32(0x92230000), SPH_C32(0xa9fc0050), SPH_C32(0x816f0000), + SPH_C32(0x4b930000), SPH_C32(0x0db45b58), SPH_C32(0x1f5dd43d), + SPH_C32(0xa292b44b), SPH_C32(0x49fc8c64), SPH_C32(0x13af0000), + SPH_C32(0x87570088), SPH_C32(0x7e610000), SPH_C32(0x5ca90000), + SPH_C32(0x699c66ed), SPH_C32(0xf511dca5), SPH_C32(0x9ad65ec3), + SPH_C32(0xa75722f3) }, + { SPH_C32(0x145a0000), SPH_C32(0x96c50052), SPH_C32(0x60f5e000), + SPH_C32(0xd3c50000), SPH_C32(0x98d13c56), SPH_C32(0x51d51cd7), + SPH_C32(0x714ffd0f), SPH_C32(0x5fe156dd), SPH_C32(0x23180000), + SPH_C32(0x62870088), SPH_C32(0x8a956000), SPH_C32(0x1e6d0000), + SPH_C32(0x0a245b87), SPH_C32(0x8dab48c5), SPH_C32(0xbb79ff29), + SPH_C32(0x17f23ac7) }, + { SPH_C32(0xa2940000), SPH_C32(0x4c2c0050), SPH_C32(0x759b6000), + SPH_C32(0x09570000), SPH_C32(0x6e0c6632), SPH_C32(0x67e7405d), + SPH_C32(0x833d15a1), SPH_C32(0xf9599450), SPH_C32(0xa5610000), + SPH_C32(0x5dbe008a), SPH_C32(0x6b0f8000), SPH_C32(0x863b0000), + SPH_C32(0x9f413c89), SPH_C32(0xc323802f), SPH_C32(0x68a4b66d), + SPH_C32(0x01efe07e) }, + { SPH_C32(0x24ed0000), SPH_C32(0x73150052), SPH_C32(0x94018000), + SPH_C32(0x91010000), SPH_C32(0xfb69013c), SPH_C32(0x296f88b7), + SPH_C32(0x50e05ce5), SPH_C32(0xef444ee9), SPH_C32(0x95d60000), + SPH_C32(0xb86e008a), SPH_C32(0x9ffbe000), SPH_C32(0xc4ff0000), + SPH_C32(0xfcf901e3), SPH_C32(0xbb99144f), SPH_C32(0x490b1787), + SPH_C32(0xb14af84a) }, + { SPH_C32(0x863a0000), SPH_C32(0x8a36006c), SPH_C32(0xd1b00000), + SPH_C32(0x0f250000), SPH_C32(0x16d83ce8), SPH_C32(0x23ae7848), + SPH_C32(0xc374a4fb), SPH_C32(0x923657e4), SPH_C32(0xf0ec0000), + SPH_C32(0xbd19009c), SPH_C32(0x8ca70000), SPH_C32(0xf6e70000), + SPH_C32(0xb282244b), SPH_C32(0xd07a62b0), SPH_C32(0x88ebef95), + SPH_C32(0x9d19bb24) }, + { SPH_C32(0x00430000), SPH_C32(0xb50f006e), SPH_C32(0x302ae000), + SPH_C32(0x97730000), SPH_C32(0x83bd5be6), SPH_C32(0x6d26b0a2), + SPH_C32(0x10a9edbf), SPH_C32(0x842b8d5d), SPH_C32(0xc05b0000), + SPH_C32(0x58c9009c), SPH_C32(0x78536000), SPH_C32(0xb4230000), + SPH_C32(0xd13a1921), SPH_C32(0xa8c0f6d0), SPH_C32(0xa9444e7f), + SPH_C32(0x2dbca310) }, + { SPH_C32(0xb68d0000), SPH_C32(0x6fe6006c), SPH_C32(0x25446000), + SPH_C32(0x4de10000), SPH_C32(0x75600182), SPH_C32(0x5b14ec28), + SPH_C32(0xe2db0511), SPH_C32(0x22934fd0), SPH_C32(0x46220000), + SPH_C32(0x67f0009e), SPH_C32(0x99c98000), SPH_C32(0x2c750000), + SPH_C32(0x445f7e2f), SPH_C32(0xe6483e3a), SPH_C32(0x7a99073b), + SPH_C32(0x3ba179a9) }, + { SPH_C32(0x30f40000), SPH_C32(0x50df006e), SPH_C32(0xc4de8000), + SPH_C32(0xd5b70000), SPH_C32(0xe005668c), SPH_C32(0x159c24c2), + SPH_C32(0x31064c55), SPH_C32(0x348e9569), SPH_C32(0x76950000), + SPH_C32(0x8220009e), SPH_C32(0x6d3de000), SPH_C32(0x6eb10000), + SPH_C32(0x27e74345), SPH_C32(0x9ef2aa5a), SPH_C32(0x5b36a6d1), + SPH_C32(0x8b04619d) }, + { SPH_C32(0x71600000), SPH_C32(0x93b20044), SPH_C32(0x73a90000), + SPH_C32(0xe1dd0000), SPH_C32(0xd6aa19fe), SPH_C32(0x3a366a28), + SPH_C32(0xb0af051d), SPH_C32(0x73b215b3), SPH_C32(0xe4f50000), + SPH_C32(0x9ed300a0), SPH_C32(0xdc780000), SPH_C32(0xb2510000), + SPH_C32(0xa9ee43fb), SPH_C32(0xec89cec5), SPH_C32(0xe90dff25), + SPH_C32(0x46d360a4) }, + { SPH_C32(0xf7190000), SPH_C32(0xac8b0046), SPH_C32(0x9233e000), + SPH_C32(0x798b0000), SPH_C32(0x43cf7ef0), SPH_C32(0x74bea2c2), + SPH_C32(0x63724c59), SPH_C32(0x65afcf0a), SPH_C32(0xd4420000), + SPH_C32(0x7b0300a0), SPH_C32(0x288c6000), SPH_C32(0xf0950000), + SPH_C32(0xca567e91), SPH_C32(0x94335aa5), SPH_C32(0xc8a25ecf), + SPH_C32(0xf6767890) }, + { SPH_C32(0x41d70000), SPH_C32(0x76620044), SPH_C32(0x875d6000), + SPH_C32(0xa3190000), SPH_C32(0xb5122494), SPH_C32(0x428cfe48), + SPH_C32(0x9100a4f7), SPH_C32(0xc3170d87), SPH_C32(0x523b0000), + SPH_C32(0x443a00a2), SPH_C32(0xc9168000), SPH_C32(0x68c30000), + SPH_C32(0x5f33199f), SPH_C32(0xdabb924f), SPH_C32(0x1b7f178b), + SPH_C32(0xe06ba229) }, + { SPH_C32(0xc7ae0000), SPH_C32(0x495b0046), SPH_C32(0x66c78000), + SPH_C32(0x3b4f0000), SPH_C32(0x2077439a), SPH_C32(0x0c0436a2), + SPH_C32(0x42ddedb3), SPH_C32(0xd50ad73e), SPH_C32(0x628c0000), + SPH_C32(0xa1ea00a2), SPH_C32(0x3de2e000), SPH_C32(0x2a070000), + SPH_C32(0x3c8b24f5), SPH_C32(0xa201062f), SPH_C32(0x3ad0b661), + SPH_C32(0x50ceba1d) }, + { SPH_C32(0x65790000), SPH_C32(0xb0780078), SPH_C32(0x23760000), + SPH_C32(0xa56b0000), SPH_C32(0xcdc67e4e), SPH_C32(0x06c5c65d), + SPH_C32(0xd14915ad), SPH_C32(0xa878ce33), SPH_C32(0x07b60000), + SPH_C32(0xa49d00b4), SPH_C32(0x2ebe0000), SPH_C32(0x181f0000), + SPH_C32(0x72f0015d), SPH_C32(0xc9e270d0), SPH_C32(0xfb304e73), + SPH_C32(0x7c9df973) }, + { SPH_C32(0xe3000000), SPH_C32(0x8f41007a), SPH_C32(0xc2ece000), + SPH_C32(0x3d3d0000), SPH_C32(0x58a31940), SPH_C32(0x484d0eb7), + SPH_C32(0x02945ce9), SPH_C32(0xbe65148a), SPH_C32(0x37010000), + SPH_C32(0x414d00b4), SPH_C32(0xda4a6000), SPH_C32(0x5adb0000), + SPH_C32(0x11483c37), SPH_C32(0xb158e4b0), SPH_C32(0xda9fef99), + SPH_C32(0xcc38e147) }, + { SPH_C32(0x55ce0000), SPH_C32(0x55a80078), SPH_C32(0xd7826000), + SPH_C32(0xe7af0000), SPH_C32(0xae7e4324), SPH_C32(0x7e7f523d), + SPH_C32(0xf0e6b447), SPH_C32(0x18ddd607), SPH_C32(0xb1780000), + SPH_C32(0x7e7400b6), SPH_C32(0x3bd08000), SPH_C32(0xc28d0000), + SPH_C32(0x842d5b39), SPH_C32(0xffd02c5a), SPH_C32(0x0942a6dd), + SPH_C32(0xda253bfe) }, + { SPH_C32(0xd3b70000), SPH_C32(0x6a91007a), SPH_C32(0x36188000), + SPH_C32(0x7ff90000), SPH_C32(0x3b1b242a), SPH_C32(0x30f79ad7), + SPH_C32(0x233bfd03), SPH_C32(0x0ec00cbe), SPH_C32(0x81cf0000), + SPH_C32(0x9ba400b6), SPH_C32(0xcf24e000), SPH_C32(0x80490000), + SPH_C32(0xe7956653), SPH_C32(0x876ab83a), SPH_C32(0x28ed0737), + SPH_C32(0x6a8023ca) }, + { SPH_C32(0x7afe0000), SPH_C32(0x53b60014), SPH_C32(0xbd420000), + SPH_C32(0xf0860000), SPH_C32(0x8d096d43), SPH_C32(0x3bb5c979), + SPH_C32(0x1d3a76bf), SPH_C32(0x1bb6813d), SPH_C32(0x47ff0000), + SPH_C32(0x812600d4), SPH_C32(0x5bcf0000), SPH_C32(0x36b70000), + SPH_C32(0x47392832), SPH_C32(0x935f59b7), SPH_C32(0x256c4600), + SPH_C32(0xd9267fe4) }, + { SPH_C32(0xfc870000), SPH_C32(0x6c8f0016), SPH_C32(0x5cd8e000), + SPH_C32(0x68d00000), SPH_C32(0x186c0a4d), SPH_C32(0x753d0193), + SPH_C32(0xcee73ffb), SPH_C32(0x0dab5b84), SPH_C32(0x77480000), + SPH_C32(0x64f600d4), SPH_C32(0xaf3b6000), SPH_C32(0x74730000), + SPH_C32(0x24811558), SPH_C32(0xebe5cdd7), SPH_C32(0x04c3e7ea), + SPH_C32(0x698367d0) }, + { SPH_C32(0x4a490000), SPH_C32(0xb6660014), SPH_C32(0x49b66000), + SPH_C32(0xb2420000), SPH_C32(0xeeb15029), SPH_C32(0x430f5d19), + SPH_C32(0x3c95d755), SPH_C32(0xab139909), SPH_C32(0xf1310000), + SPH_C32(0x5bcf00d6), SPH_C32(0x4ea18000), SPH_C32(0xec250000), + SPH_C32(0xb1e47256), SPH_C32(0xa56d053d), SPH_C32(0xd71eaeae), + SPH_C32(0x7f9ebd69) }, + { SPH_C32(0xcc300000), SPH_C32(0x895f0016), SPH_C32(0xa82c8000), + SPH_C32(0x2a140000), SPH_C32(0x7bd43727), SPH_C32(0x0d8795f3), + SPH_C32(0xef489e11), SPH_C32(0xbd0e43b0), SPH_C32(0xc1860000), + SPH_C32(0xbe1f00d6), SPH_C32(0xba55e000), SPH_C32(0xaee10000), + SPH_C32(0xd25c4f3c), SPH_C32(0xddd7915d), SPH_C32(0xf6b10f44), + SPH_C32(0xcf3ba55d) }, + { SPH_C32(0x6ee70000), SPH_C32(0x707c0028), SPH_C32(0xed9d0000), + SPH_C32(0xb4300000), SPH_C32(0x96650af3), SPH_C32(0x0746650c), + SPH_C32(0x7cdc660f), SPH_C32(0xc07c5abd), SPH_C32(0xa4bc0000), + SPH_C32(0xbb6800c0), SPH_C32(0xa9090000), SPH_C32(0x9cf90000), + SPH_C32(0x9c276a94), SPH_C32(0xb634e7a2), SPH_C32(0x3751f756), + SPH_C32(0xe368e633) }, + { SPH_C32(0xe89e0000), SPH_C32(0x4f45002a), SPH_C32(0x0c07e000), + SPH_C32(0x2c660000), SPH_C32(0x03006dfd), SPH_C32(0x49ceade6), + SPH_C32(0xaf012f4b), SPH_C32(0xd6618004), SPH_C32(0x940b0000), + SPH_C32(0x5eb800c0), SPH_C32(0x5dfd6000), SPH_C32(0xde3d0000), + SPH_C32(0xff9f57fe), SPH_C32(0xce8e73c2), SPH_C32(0x16fe56bc), + SPH_C32(0x53cdfe07) }, + { SPH_C32(0x5e500000), SPH_C32(0x95ac0028), SPH_C32(0x19696000), + SPH_C32(0xf6f40000), SPH_C32(0xf5dd3799), SPH_C32(0x7ffcf16c), + SPH_C32(0x5d73c7e5), SPH_C32(0x70d94289), SPH_C32(0x12720000), + SPH_C32(0x618100c2), SPH_C32(0xbc678000), SPH_C32(0x466b0000), + SPH_C32(0x6afa30f0), SPH_C32(0x8006bb28), SPH_C32(0xc5231ff8), + SPH_C32(0x45d024be) }, + { SPH_C32(0xd8290000), SPH_C32(0xaa95002a), SPH_C32(0xf8f38000), + SPH_C32(0x6ea20000), SPH_C32(0x60b85097), SPH_C32(0x31743986), + SPH_C32(0x8eae8ea1), SPH_C32(0x66c49830), SPH_C32(0x22c50000), + SPH_C32(0x845100c2), SPH_C32(0x4893e000), SPH_C32(0x04af0000), + SPH_C32(0x09420d9a), SPH_C32(0xf8bc2f48), SPH_C32(0xe48cbe12), + SPH_C32(0xf5753c8a) }, + { SPH_C32(0x99bd0000), SPH_C32(0x69f80000), SPH_C32(0x4f840000), + SPH_C32(0x5ac80000), SPH_C32(0x56172fe5), SPH_C32(0x1ede776c), + SPH_C32(0x0f07c7e9), SPH_C32(0x21f818ea), SPH_C32(0xb0a50000), + SPH_C32(0x98a200fc), SPH_C32(0xf9d60000), SPH_C32(0xd84f0000), + SPH_C32(0x874b0d24), SPH_C32(0x8ac74bd7), SPH_C32(0x56b7e7e6), + SPH_C32(0x38a23db3) }, + { SPH_C32(0x1fc40000), SPH_C32(0x56c10002), SPH_C32(0xae1ee000), + SPH_C32(0xc29e0000), SPH_C32(0xc37248eb), SPH_C32(0x5056bf86), + SPH_C32(0xdcda8ead), SPH_C32(0x37e5c253), SPH_C32(0x80120000), + SPH_C32(0x7d7200fc), SPH_C32(0x0d226000), SPH_C32(0x9a8b0000), + SPH_C32(0xe4f3304e), SPH_C32(0xf27ddfb7), SPH_C32(0x7718460c), + SPH_C32(0x88072587) }, + { SPH_C32(0xa90a0000), SPH_C32(0x8c280000), SPH_C32(0xbb706000), + SPH_C32(0x180c0000), SPH_C32(0x35af128f), SPH_C32(0x6664e30c), + SPH_C32(0x2ea86603), SPH_C32(0x915d00de), SPH_C32(0x066b0000), + SPH_C32(0x424b00fe), SPH_C32(0xecb88000), SPH_C32(0x02dd0000), + SPH_C32(0x71965740), SPH_C32(0xbcf5175d), SPH_C32(0xa4c50f48), + SPH_C32(0x9e1aff3e) }, + { SPH_C32(0x2f730000), SPH_C32(0xb3110002), SPH_C32(0x5aea8000), + SPH_C32(0x805a0000), SPH_C32(0xa0ca7581), SPH_C32(0x28ec2be6), + SPH_C32(0xfd752f47), SPH_C32(0x8740da67), SPH_C32(0x36dc0000), + SPH_C32(0xa79b00fe), SPH_C32(0x184ce000), SPH_C32(0x40190000), + SPH_C32(0x122e6a2a), SPH_C32(0xc44f833d), SPH_C32(0x856aaea2), + SPH_C32(0x2ebfe70a) }, + { SPH_C32(0x8da40000), SPH_C32(0x4a32003c), SPH_C32(0x1f5b0000), + SPH_C32(0x1e7e0000), SPH_C32(0x4d7b4855), SPH_C32(0x222ddb19), + SPH_C32(0x6ee1d759), SPH_C32(0xfa32c36a), SPH_C32(0x53e60000), + SPH_C32(0xa2ec00e8), SPH_C32(0x0b100000), SPH_C32(0x72010000), + SPH_C32(0x5c554f82), SPH_C32(0xafacf5c2), SPH_C32(0x448a56b0), + SPH_C32(0x02eca464) }, + { SPH_C32(0x0bdd0000), SPH_C32(0x750b003e), SPH_C32(0xfec1e000), + SPH_C32(0x86280000), SPH_C32(0xd81e2f5b), SPH_C32(0x6ca513f3), + SPH_C32(0xbd3c9e1d), SPH_C32(0xec2f19d3), SPH_C32(0x63510000), + SPH_C32(0x473c00e8), SPH_C32(0xffe46000), SPH_C32(0x30c50000), + SPH_C32(0x3fed72e8), SPH_C32(0xd71661a2), SPH_C32(0x6525f75a), + SPH_C32(0xb249bc50) }, + { SPH_C32(0xbd130000), SPH_C32(0xafe2003c), SPH_C32(0xebaf6000), + SPH_C32(0x5cba0000), SPH_C32(0x2ec3753f), SPH_C32(0x5a974f79), + SPH_C32(0x4f4e76b3), SPH_C32(0x4a97db5e), SPH_C32(0xe5280000), + SPH_C32(0x780500ea), SPH_C32(0x1e7e8000), SPH_C32(0xa8930000), + SPH_C32(0xaa8815e6), SPH_C32(0x999ea948), SPH_C32(0xb6f8be1e), + SPH_C32(0xa45466e9) }, + { SPH_C32(0x3b6a0000), SPH_C32(0x90db003e), SPH_C32(0x0a358000), + SPH_C32(0xc4ec0000), SPH_C32(0xbba61231), SPH_C32(0x141f8793), + SPH_C32(0x9c933ff7), SPH_C32(0x5c8a01e7), SPH_C32(0xd59f0000), + SPH_C32(0x9dd500ea), SPH_C32(0xea8ae000), SPH_C32(0xea570000), + SPH_C32(0xc930288c), SPH_C32(0xe1243d28), SPH_C32(0x97571ff4), + SPH_C32(0x14f17edd) }, + { SPH_C32(0x2eae0000), SPH_C32(0x55c70048), SPH_C32(0x98ec0000), + SPH_C32(0x9a980000), SPH_C32(0xa3ac239c), SPH_C32(0x5dfb4c6b), + SPH_C32(0xa2806e7c), SPH_C32(0x65c7dc2a), SPH_C32(0xfb720000), + SPH_C32(0x7d1d00cc), SPH_C32(0x424c0000), SPH_C32(0xe7bc0000), + SPH_C32(0xe92150f6), SPH_C32(0xd1f9c1e1), SPH_C32(0x257e9c37), + SPH_C32(0xf51d2faa) }, + { SPH_C32(0xa8d70000), SPH_C32(0x6afe004a), SPH_C32(0x7976e000), + SPH_C32(0x02ce0000), SPH_C32(0x36c94492), SPH_C32(0x13738481), + SPH_C32(0x715d2738), SPH_C32(0x73da0693), SPH_C32(0xcbc50000), + SPH_C32(0x98cd00cc), SPH_C32(0xb6b86000), SPH_C32(0xa5780000), + SPH_C32(0x8a996d9c), SPH_C32(0xa9435581), SPH_C32(0x04d13ddd), + SPH_C32(0x45b8379e) }, + { SPH_C32(0x1e190000), SPH_C32(0xb0170048), SPH_C32(0x6c186000), + SPH_C32(0xd85c0000), SPH_C32(0xc0141ef6), SPH_C32(0x2541d80b), + SPH_C32(0x832fcf96), SPH_C32(0xd562c41e), SPH_C32(0x4dbc0000), + SPH_C32(0xa7f400ce), SPH_C32(0x57228000), SPH_C32(0x3d2e0000), + SPH_C32(0x1ffc0a92), SPH_C32(0xe7cb9d6b), SPH_C32(0xd70c7499), + SPH_C32(0x53a5ed27) }, + { SPH_C32(0x98600000), SPH_C32(0x8f2e004a), SPH_C32(0x8d828000), + SPH_C32(0x400a0000), SPH_C32(0x557179f8), SPH_C32(0x6bc910e1), + SPH_C32(0x50f286d2), SPH_C32(0xc37f1ea7), SPH_C32(0x7d0b0000), + SPH_C32(0x422400ce), SPH_C32(0xa3d6e000), SPH_C32(0x7fea0000), + SPH_C32(0x7c4437f8), SPH_C32(0x9f71090b), SPH_C32(0xf6a3d573), + SPH_C32(0xe300f513) }, + { SPH_C32(0x3ab70000), SPH_C32(0x760d0074), SPH_C32(0xc8330000), + SPH_C32(0xde2e0000), SPH_C32(0xb8c0442c), SPH_C32(0x6108e01e), + SPH_C32(0xc3667ecc), SPH_C32(0xbe0d07aa), SPH_C32(0x18310000), + SPH_C32(0x475300d8), SPH_C32(0xb08a0000), SPH_C32(0x4df20000), + SPH_C32(0x323f1250), SPH_C32(0xf4927ff4), SPH_C32(0x37432d61), + SPH_C32(0xcf53b67d) }, + { SPH_C32(0xbcce0000), SPH_C32(0x49340076), SPH_C32(0x29a9e000), + SPH_C32(0x46780000), SPH_C32(0x2da52322), SPH_C32(0x2f8028f4), + SPH_C32(0x10bb3788), SPH_C32(0xa810dd13), SPH_C32(0x28860000), + SPH_C32(0xa28300d8), SPH_C32(0x447e6000), SPH_C32(0x0f360000), + SPH_C32(0x51872f3a), SPH_C32(0x8c28eb94), SPH_C32(0x16ec8c8b), + SPH_C32(0x7ff6ae49) }, + { SPH_C32(0x0a000000), SPH_C32(0x93dd0074), SPH_C32(0x3cc76000), + SPH_C32(0x9cea0000), SPH_C32(0xdb787946), SPH_C32(0x19b2747e), + SPH_C32(0xe2c9df26), SPH_C32(0x0ea81f9e), SPH_C32(0xaeff0000), + SPH_C32(0x9dba00da), SPH_C32(0xa5e48000), SPH_C32(0x97600000), + SPH_C32(0xc4e24834), SPH_C32(0xc2a0237e), SPH_C32(0xc531c5cf), + SPH_C32(0x69eb74f0) }, + { SPH_C32(0x8c790000), SPH_C32(0xace40076), SPH_C32(0xdd5d8000), + SPH_C32(0x04bc0000), SPH_C32(0x4e1d1e48), SPH_C32(0x573abc94), + SPH_C32(0x31149662), SPH_C32(0x18b5c527), SPH_C32(0x9e480000), + SPH_C32(0x786a00da), SPH_C32(0x5110e000), SPH_C32(0xd5a40000), + SPH_C32(0xa75a755e), SPH_C32(0xba1ab71e), SPH_C32(0xe49e6425), + SPH_C32(0xd94e6cc4) }, + { SPH_C32(0xcded0000), SPH_C32(0x6f89005c), SPH_C32(0x6a2a0000), + SPH_C32(0x30d60000), SPH_C32(0x78b2613a), SPH_C32(0x7890f27e), + SPH_C32(0xb0bddf2a), SPH_C32(0x5f8945fd), SPH_C32(0x0c280000), + SPH_C32(0x649900e4), SPH_C32(0xe0550000), SPH_C32(0x09440000), + SPH_C32(0x295375e0), SPH_C32(0xc861d381), SPH_C32(0x56a53dd1), + SPH_C32(0x14996dfd) }, + { SPH_C32(0x4b940000), SPH_C32(0x50b0005e), SPH_C32(0x8bb0e000), + SPH_C32(0xa8800000), SPH_C32(0xedd70634), SPH_C32(0x36183a94), + SPH_C32(0x6360966e), SPH_C32(0x49949f44), SPH_C32(0x3c9f0000), + SPH_C32(0x814900e4), SPH_C32(0x14a16000), SPH_C32(0x4b800000), + SPH_C32(0x4aeb488a), SPH_C32(0xb0db47e1), SPH_C32(0x770a9c3b), + SPH_C32(0xa43c75c9) }, + { SPH_C32(0xfd5a0000), SPH_C32(0x8a59005c), SPH_C32(0x9ede6000), + SPH_C32(0x72120000), SPH_C32(0x1b0a5c50), SPH_C32(0x002a661e), + SPH_C32(0x91127ec0), SPH_C32(0xef2c5dc9), SPH_C32(0xbae60000), + SPH_C32(0xbe7000e6), SPH_C32(0xf53b8000), SPH_C32(0xd3d60000), + SPH_C32(0xdf8e2f84), SPH_C32(0xfe538f0b), SPH_C32(0xa4d7d57f), + SPH_C32(0xb221af70) }, + { SPH_C32(0x7b230000), SPH_C32(0xb560005e), SPH_C32(0x7f448000), + SPH_C32(0xea440000), SPH_C32(0x8e6f3b5e), SPH_C32(0x4ea2aef4), + SPH_C32(0x42cf3784), SPH_C32(0xf9318770), SPH_C32(0x8a510000), + SPH_C32(0x5ba000e6), SPH_C32(0x01cfe000), SPH_C32(0x91120000), + SPH_C32(0xbc3612ee), SPH_C32(0x86e91b6b), SPH_C32(0x85787495), + SPH_C32(0x0284b744) }, + { SPH_C32(0xd9f40000), SPH_C32(0x4c430060), SPH_C32(0x3af50000), + SPH_C32(0x74600000), SPH_C32(0x63de068a), SPH_C32(0x44635e0b), + SPH_C32(0xd15bcf9a), SPH_C32(0x84439e7d), SPH_C32(0xef6b0000), + SPH_C32(0x5ed700f0), SPH_C32(0x12930000), SPH_C32(0xa30a0000), + SPH_C32(0xf24d3746), SPH_C32(0xed0a6d94), SPH_C32(0x44988c87), + SPH_C32(0x2ed7f42a) }, + { SPH_C32(0x5f8d0000), SPH_C32(0x737a0062), SPH_C32(0xdb6fe000), + SPH_C32(0xec360000), SPH_C32(0xf6bb6184), SPH_C32(0x0aeb96e1), + SPH_C32(0x028686de), SPH_C32(0x925e44c4), SPH_C32(0xdfdc0000), + SPH_C32(0xbb0700f0), SPH_C32(0xe6676000), SPH_C32(0xe1ce0000), + SPH_C32(0x91f50a2c), SPH_C32(0x95b0f9f4), SPH_C32(0x65372d6d), + SPH_C32(0x9e72ec1e) }, + { SPH_C32(0xe9430000), SPH_C32(0xa9930060), SPH_C32(0xce016000), + SPH_C32(0x36a40000), SPH_C32(0x00663be0), SPH_C32(0x3cd9ca6b), + SPH_C32(0xf0f46e70), SPH_C32(0x34e68649), SPH_C32(0x59a50000), + SPH_C32(0x843e00f2), SPH_C32(0x07fd8000), SPH_C32(0x79980000), + SPH_C32(0x04906d22), SPH_C32(0xdb38311e), SPH_C32(0xb6ea6429), + SPH_C32(0x886f36a7) }, + { SPH_C32(0x6f3a0000), SPH_C32(0x96aa0062), SPH_C32(0x2f9b8000), + SPH_C32(0xaef20000), SPH_C32(0x95035cee), SPH_C32(0x72510281), + SPH_C32(0x23292734), SPH_C32(0x22fb5cf0), SPH_C32(0x69120000), + SPH_C32(0x61ee00f2), SPH_C32(0xf309e000), SPH_C32(0x3b5c0000), + SPH_C32(0x67285048), SPH_C32(0xa382a57e), SPH_C32(0x9745c5c3), + SPH_C32(0x38ca2e93) }, + { SPH_C32(0xaf220000), SPH_C32(0x7b6c0090), SPH_C32(0x67e20000), + SPH_C32(0x8da20000), SPH_C32(0xc7841e29), SPH_C32(0xb7b744f3), + SPH_C32(0x9ac484f4), SPH_C32(0x8b6c72bd), SPH_C32(0x69510000), + SPH_C32(0xd4e1009c), SPH_C32(0xc3230000), SPH_C32(0xac2f0000), + SPH_C32(0xe4950bae), SPH_C32(0xcea415dc), SPH_C32(0x87ec287c), + SPH_C32(0xbce1a3ce) }, + { SPH_C32(0x295b0000), SPH_C32(0x44550092), SPH_C32(0x8678e000), + SPH_C32(0x15f40000), SPH_C32(0x52e17927), SPH_C32(0xf93f8c19), + SPH_C32(0x4919cdb0), SPH_C32(0x9d71a804), SPH_C32(0x59e60000), + SPH_C32(0x3131009c), SPH_C32(0x37d76000), SPH_C32(0xeeeb0000), + SPH_C32(0x872d36c4), SPH_C32(0xb61e81bc), SPH_C32(0xa6438996), + SPH_C32(0x0c44bbfa) }, + { SPH_C32(0x9f950000), SPH_C32(0x9ebc0090), SPH_C32(0x93166000), + SPH_C32(0xcf660000), SPH_C32(0xa43c2343), SPH_C32(0xcf0dd093), + SPH_C32(0xbb6b251e), SPH_C32(0x3bc96a89), SPH_C32(0xdf9f0000), + SPH_C32(0x0e08009e), SPH_C32(0xd64d8000), SPH_C32(0x76bd0000), + SPH_C32(0x124851ca), SPH_C32(0xf8964956), SPH_C32(0x759ec0d2), + SPH_C32(0x1a596143) }, + { SPH_C32(0x19ec0000), SPH_C32(0xa1850092), SPH_C32(0x728c8000), + SPH_C32(0x57300000), SPH_C32(0x3159444d), SPH_C32(0x81851879), + SPH_C32(0x68b66c5a), SPH_C32(0x2dd4b030), SPH_C32(0xef280000), + SPH_C32(0xebd8009e), SPH_C32(0x22b9e000), SPH_C32(0x34790000), + SPH_C32(0x71f06ca0), SPH_C32(0x802cdd36), SPH_C32(0x54316138), + SPH_C32(0xaafc7977) }, + { SPH_C32(0xbb3b0000), SPH_C32(0x58a600ac), SPH_C32(0x373d0000), + SPH_C32(0xc9140000), SPH_C32(0xdce87999), SPH_C32(0x8b44e886), + SPH_C32(0xfb229444), SPH_C32(0x50a6a93d), SPH_C32(0x8a120000), + SPH_C32(0xeeaf0088), SPH_C32(0x31e50000), SPH_C32(0x06610000), + SPH_C32(0x3f8b4908), SPH_C32(0xebcfabc9), SPH_C32(0x95d1992a), + SPH_C32(0x86af3a19) }, + { SPH_C32(0x3d420000), SPH_C32(0x679f00ae), SPH_C32(0xd6a7e000), + SPH_C32(0x51420000), SPH_C32(0x498d1e97), SPH_C32(0xc5cc206c), + SPH_C32(0x28ffdd00), SPH_C32(0x46bb7384), SPH_C32(0xbaa50000), + SPH_C32(0x0b7f0088), SPH_C32(0xc5116000), SPH_C32(0x44a50000), + SPH_C32(0x5c337462), SPH_C32(0x93753fa9), SPH_C32(0xb47e38c0), + SPH_C32(0x360a222d) }, + { SPH_C32(0x8b8c0000), SPH_C32(0xbd7600ac), SPH_C32(0xc3c96000), + SPH_C32(0x8bd00000), SPH_C32(0xbf5044f3), SPH_C32(0xf3fe7ce6), + SPH_C32(0xda8d35ae), SPH_C32(0xe003b109), SPH_C32(0x3cdc0000), + SPH_C32(0x3446008a), SPH_C32(0x248b8000), SPH_C32(0xdcf30000), + SPH_C32(0xc956136c), SPH_C32(0xddfdf743), SPH_C32(0x67a37184), + SPH_C32(0x2017f894) }, + { SPH_C32(0x0df50000), SPH_C32(0x824f00ae), SPH_C32(0x22538000), + SPH_C32(0x13860000), SPH_C32(0x2a3523fd), SPH_C32(0xbd76b40c), + SPH_C32(0x09507cea), SPH_C32(0xf61e6bb0), SPH_C32(0x0c6b0000), + SPH_C32(0xd196008a), SPH_C32(0xd07fe000), SPH_C32(0x9e370000), + SPH_C32(0xaaee2e06), SPH_C32(0xa5476323), SPH_C32(0x460cd06e), + SPH_C32(0x90b2e0a0) }, + { SPH_C32(0x4c610000), SPH_C32(0x41220084), SPH_C32(0x95240000), + SPH_C32(0x27ec0000), SPH_C32(0x1c9a5c8f), SPH_C32(0x92dcfae6), + SPH_C32(0x88f935a2), SPH_C32(0xb122eb6a), SPH_C32(0x9e0b0000), + SPH_C32(0xcd6500b4), SPH_C32(0x613a0000), SPH_C32(0x42d70000), + SPH_C32(0x24e72eb8), SPH_C32(0xd73c07bc), SPH_C32(0xf437899a), + SPH_C32(0x5d65e199) }, + { SPH_C32(0xca180000), SPH_C32(0x7e1b0086), SPH_C32(0x74bee000), + SPH_C32(0xbfba0000), SPH_C32(0x89ff3b81), SPH_C32(0xdc54320c), + SPH_C32(0x5b247ce6), SPH_C32(0xa73f31d3), SPH_C32(0xaebc0000), + SPH_C32(0x28b500b4), SPH_C32(0x95ce6000), SPH_C32(0x00130000), + SPH_C32(0x475f13d2), SPH_C32(0xaf8693dc), SPH_C32(0xd5982870), + SPH_C32(0xedc0f9ad) }, + { SPH_C32(0x7cd60000), SPH_C32(0xa4f20084), SPH_C32(0x61d06000), + SPH_C32(0x65280000), SPH_C32(0x7f2261e5), SPH_C32(0xea666e86), + SPH_C32(0xa9569448), SPH_C32(0x0187f35e), SPH_C32(0x28c50000), + SPH_C32(0x178c00b6), SPH_C32(0x74548000), SPH_C32(0x98450000), + SPH_C32(0xd23a74dc), SPH_C32(0xe10e5b36), SPH_C32(0x06456134), + SPH_C32(0xfbdd2314) }, + { SPH_C32(0xfaaf0000), SPH_C32(0x9bcb0086), SPH_C32(0x804a8000), + SPH_C32(0xfd7e0000), SPH_C32(0xea4706eb), SPH_C32(0xa4eea66c), + SPH_C32(0x7a8bdd0c), SPH_C32(0x179a29e7), SPH_C32(0x18720000), + SPH_C32(0xf25c00b6), SPH_C32(0x80a0e000), SPH_C32(0xda810000), + SPH_C32(0xb18249b6), SPH_C32(0x99b4cf56), SPH_C32(0x27eac0de), + SPH_C32(0x4b783b20) }, + { SPH_C32(0x58780000), SPH_C32(0x62e800b8), SPH_C32(0xc5fb0000), + SPH_C32(0x635a0000), SPH_C32(0x07f63b3f), SPH_C32(0xae2f5693), + SPH_C32(0xe91f2512), SPH_C32(0x6ae830ea), SPH_C32(0x7d480000), + SPH_C32(0xf72b00a0), SPH_C32(0x93fc0000), SPH_C32(0xe8990000), + SPH_C32(0xfff96c1e), SPH_C32(0xf257b9a9), SPH_C32(0xe60a38cc), + SPH_C32(0x672b784e) }, + { SPH_C32(0xde010000), SPH_C32(0x5dd100ba), SPH_C32(0x2461e000), + SPH_C32(0xfb0c0000), SPH_C32(0x92935c31), SPH_C32(0xe0a79e79), + SPH_C32(0x3ac26c56), SPH_C32(0x7cf5ea53), SPH_C32(0x4dff0000), + SPH_C32(0x12fb00a0), SPH_C32(0x67086000), SPH_C32(0xaa5d0000), + SPH_C32(0x9c415174), SPH_C32(0x8aed2dc9), SPH_C32(0xc7a59926), + SPH_C32(0xd78e607a) }, + { SPH_C32(0x68cf0000), SPH_C32(0x873800b8), SPH_C32(0x310f6000), + SPH_C32(0x219e0000), SPH_C32(0x644e0655), SPH_C32(0xd695c2f3), + SPH_C32(0xc8b084f8), SPH_C32(0xda4d28de), SPH_C32(0xcb860000), + SPH_C32(0x2dc200a2), SPH_C32(0x86928000), SPH_C32(0x320b0000), + SPH_C32(0x0924367a), SPH_C32(0xc465e523), SPH_C32(0x1478d062), + SPH_C32(0xc193bac3) }, + { SPH_C32(0xeeb60000), SPH_C32(0xb80100ba), SPH_C32(0xd0958000), + SPH_C32(0xb9c80000), SPH_C32(0xf12b615b), SPH_C32(0x981d0a19), + SPH_C32(0x1b6dcdbc), SPH_C32(0xcc50f267), SPH_C32(0xfb310000), + SPH_C32(0xc81200a2), SPH_C32(0x7266e000), SPH_C32(0x70cf0000), + SPH_C32(0x6a9c0b10), SPH_C32(0xbcdf7143), SPH_C32(0x35d77188), + SPH_C32(0x7136a2f7) }, + { SPH_C32(0xfb720000), SPH_C32(0x7d1d00cc), SPH_C32(0x424c0000), + SPH_C32(0xe7bc0000), SPH_C32(0xe92150f6), SPH_C32(0xd1f9c1e1), + SPH_C32(0x257e9c37), SPH_C32(0xf51d2faa), SPH_C32(0xd5dc0000), + SPH_C32(0x28da0084), SPH_C32(0xdaa00000), SPH_C32(0x7d240000), + SPH_C32(0x4a8d736a), SPH_C32(0x8c028d8a), SPH_C32(0x87fef24b), + SPH_C32(0x90daf380) }, + { SPH_C32(0x7d0b0000), SPH_C32(0x422400ce), SPH_C32(0xa3d6e000), + SPH_C32(0x7fea0000), SPH_C32(0x7c4437f8), SPH_C32(0x9f71090b), + SPH_C32(0xf6a3d573), SPH_C32(0xe300f513), SPH_C32(0xe56b0000), + SPH_C32(0xcd0a0084), SPH_C32(0x2e546000), SPH_C32(0x3fe00000), + SPH_C32(0x29354e00), SPH_C32(0xf4b819ea), SPH_C32(0xa65153a1), + SPH_C32(0x207febb4) }, + { SPH_C32(0xcbc50000), SPH_C32(0x98cd00cc), SPH_C32(0xb6b86000), + SPH_C32(0xa5780000), SPH_C32(0x8a996d9c), SPH_C32(0xa9435581), + SPH_C32(0x04d13ddd), SPH_C32(0x45b8379e), SPH_C32(0x63120000), + SPH_C32(0xf2330086), SPH_C32(0xcfce8000), SPH_C32(0xa7b60000), + SPH_C32(0xbc50290e), SPH_C32(0xba30d100), SPH_C32(0x758c1ae5), + SPH_C32(0x3662310d) }, + { SPH_C32(0x4dbc0000), SPH_C32(0xa7f400ce), SPH_C32(0x57228000), + SPH_C32(0x3d2e0000), SPH_C32(0x1ffc0a92), SPH_C32(0xe7cb9d6b), + SPH_C32(0xd70c7499), SPH_C32(0x53a5ed27), SPH_C32(0x53a50000), + SPH_C32(0x17e30086), SPH_C32(0x3b3ae000), SPH_C32(0xe5720000), + SPH_C32(0xdfe81464), SPH_C32(0xc28a4560), SPH_C32(0x5423bb0f), + SPH_C32(0x86c72939) }, + { SPH_C32(0xef6b0000), SPH_C32(0x5ed700f0), SPH_C32(0x12930000), + SPH_C32(0xa30a0000), SPH_C32(0xf24d3746), SPH_C32(0xed0a6d94), + SPH_C32(0x44988c87), SPH_C32(0x2ed7f42a), SPH_C32(0x369f0000), + SPH_C32(0x12940090), SPH_C32(0x28660000), SPH_C32(0xd76a0000), + SPH_C32(0x919331cc), SPH_C32(0xa969339f), SPH_C32(0x95c3431d), + SPH_C32(0xaa946a57) }, + { SPH_C32(0x69120000), SPH_C32(0x61ee00f2), SPH_C32(0xf309e000), + SPH_C32(0x3b5c0000), SPH_C32(0x67285048), SPH_C32(0xa382a57e), + SPH_C32(0x9745c5c3), SPH_C32(0x38ca2e93), SPH_C32(0x06280000), + SPH_C32(0xf7440090), SPH_C32(0xdc926000), SPH_C32(0x95ae0000), + SPH_C32(0xf22b0ca6), SPH_C32(0xd1d3a7ff), SPH_C32(0xb46ce2f7), + SPH_C32(0x1a317263) }, + { SPH_C32(0xdfdc0000), SPH_C32(0xbb0700f0), SPH_C32(0xe6676000), + SPH_C32(0xe1ce0000), SPH_C32(0x91f50a2c), SPH_C32(0x95b0f9f4), + SPH_C32(0x65372d6d), SPH_C32(0x9e72ec1e), SPH_C32(0x80510000), + SPH_C32(0xc87d0092), SPH_C32(0x3d088000), SPH_C32(0x0df80000), + SPH_C32(0x674e6ba8), SPH_C32(0x9f5b6f15), SPH_C32(0x67b1abb3), + SPH_C32(0x0c2ca8da) }, + { SPH_C32(0x59a50000), SPH_C32(0x843e00f2), SPH_C32(0x07fd8000), + SPH_C32(0x79980000), SPH_C32(0x04906d22), SPH_C32(0xdb38311e), + SPH_C32(0xb6ea6429), SPH_C32(0x886f36a7), SPH_C32(0xb0e60000), + SPH_C32(0x2dad0092), SPH_C32(0xc9fce000), SPH_C32(0x4f3c0000), + SPH_C32(0x04f656c2), SPH_C32(0xe7e1fb75), SPH_C32(0x461e0a59), + SPH_C32(0xbc89b0ee) }, + { SPH_C32(0x18310000), SPH_C32(0x475300d8), SPH_C32(0xb08a0000), + SPH_C32(0x4df20000), SPH_C32(0x323f1250), SPH_C32(0xf4927ff4), + SPH_C32(0x37432d61), SPH_C32(0xcf53b67d), SPH_C32(0x22860000), + SPH_C32(0x315e00ac), SPH_C32(0x78b90000), SPH_C32(0x93dc0000), + SPH_C32(0x8aff567c), SPH_C32(0x959a9fea), SPH_C32(0xf42553ad), + SPH_C32(0x715eb1d7) }, + { SPH_C32(0x9e480000), SPH_C32(0x786a00da), SPH_C32(0x5110e000), + SPH_C32(0xd5a40000), SPH_C32(0xa75a755e), SPH_C32(0xba1ab71e), + SPH_C32(0xe49e6425), SPH_C32(0xd94e6cc4), SPH_C32(0x12310000), + SPH_C32(0xd48e00ac), SPH_C32(0x8c4d6000), SPH_C32(0xd1180000), + SPH_C32(0xe9476b16), SPH_C32(0xed200b8a), SPH_C32(0xd58af247), + SPH_C32(0xc1fba9e3) }, + { SPH_C32(0x28860000), SPH_C32(0xa28300d8), SPH_C32(0x447e6000), + SPH_C32(0x0f360000), SPH_C32(0x51872f3a), SPH_C32(0x8c28eb94), + SPH_C32(0x16ec8c8b), SPH_C32(0x7ff6ae49), SPH_C32(0x94480000), + SPH_C32(0xebb700ae), SPH_C32(0x6dd78000), SPH_C32(0x494e0000), + SPH_C32(0x7c220c18), SPH_C32(0xa3a8c360), SPH_C32(0x0657bb03), + SPH_C32(0xd7e6735a) }, + { SPH_C32(0xaeff0000), SPH_C32(0x9dba00da), SPH_C32(0xa5e48000), + SPH_C32(0x97600000), SPH_C32(0xc4e24834), SPH_C32(0xc2a0237e), + SPH_C32(0xc531c5cf), SPH_C32(0x69eb74f0), SPH_C32(0xa4ff0000), + SPH_C32(0x0e6700ae), SPH_C32(0x9923e000), SPH_C32(0x0b8a0000), + SPH_C32(0x1f9a3172), SPH_C32(0xdb125700), SPH_C32(0x27f81ae9), + SPH_C32(0x67436b6e) }, + { SPH_C32(0x0c280000), SPH_C32(0x649900e4), SPH_C32(0xe0550000), + SPH_C32(0x09440000), SPH_C32(0x295375e0), SPH_C32(0xc861d381), + SPH_C32(0x56a53dd1), SPH_C32(0x14996dfd), SPH_C32(0xc1c50000), + SPH_C32(0x0b1000b8), SPH_C32(0x8a7f0000), SPH_C32(0x39920000), + SPH_C32(0x51e114da), SPH_C32(0xb0f121ff), SPH_C32(0xe618e2fb), + SPH_C32(0x4b102800) }, + { SPH_C32(0x8a510000), SPH_C32(0x5ba000e6), SPH_C32(0x01cfe000), + SPH_C32(0x91120000), SPH_C32(0xbc3612ee), SPH_C32(0x86e91b6b), + SPH_C32(0x85787495), SPH_C32(0x0284b744), SPH_C32(0xf1720000), + SPH_C32(0xeec000b8), SPH_C32(0x7e8b6000), SPH_C32(0x7b560000), + SPH_C32(0x325929b0), SPH_C32(0xc84bb59f), SPH_C32(0xc7b74311), + SPH_C32(0xfbb53034) }, + { SPH_C32(0x3c9f0000), SPH_C32(0x814900e4), SPH_C32(0x14a16000), + SPH_C32(0x4b800000), SPH_C32(0x4aeb488a), SPH_C32(0xb0db47e1), + SPH_C32(0x770a9c3b), SPH_C32(0xa43c75c9), SPH_C32(0x770b0000), + SPH_C32(0xd1f900ba), SPH_C32(0x9f118000), SPH_C32(0xe3000000), + SPH_C32(0xa73c4ebe), SPH_C32(0x86c37d75), SPH_C32(0x146a0a55), + SPH_C32(0xeda8ea8d) }, + { SPH_C32(0xbae60000), SPH_C32(0xbe7000e6), SPH_C32(0xf53b8000), + SPH_C32(0xd3d60000), SPH_C32(0xdf8e2f84), SPH_C32(0xfe538f0b), + SPH_C32(0xa4d7d57f), SPH_C32(0xb221af70), SPH_C32(0x47bc0000), + SPH_C32(0x342900ba), SPH_C32(0x6be5e000), SPH_C32(0xa1c40000), + SPH_C32(0xc48473d4), SPH_C32(0xfe79e915), SPH_C32(0x35c5abbf), + SPH_C32(0x5d0df2b9) }, + { SPH_C32(0x13af0000), SPH_C32(0x87570088), SPH_C32(0x7e610000), + SPH_C32(0x5ca90000), SPH_C32(0x699c66ed), SPH_C32(0xf511dca5), + SPH_C32(0x9ad65ec3), SPH_C32(0xa75722f3), SPH_C32(0x818c0000), + SPH_C32(0x2eab00d8), SPH_C32(0xff0e0000), SPH_C32(0x173a0000), + SPH_C32(0x64283db5), SPH_C32(0xea4c0898), SPH_C32(0x3844ea88), + SPH_C32(0xeeabae97) }, + { SPH_C32(0x95d60000), SPH_C32(0xb86e008a), SPH_C32(0x9ffbe000), + SPH_C32(0xc4ff0000), SPH_C32(0xfcf901e3), SPH_C32(0xbb99144f), + SPH_C32(0x490b1787), SPH_C32(0xb14af84a), SPH_C32(0xb13b0000), + SPH_C32(0xcb7b00d8), SPH_C32(0x0bfa6000), SPH_C32(0x55fe0000), + SPH_C32(0x079000df), SPH_C32(0x92f69cf8), SPH_C32(0x19eb4b62), + SPH_C32(0x5e0eb6a3) }, + { SPH_C32(0x23180000), SPH_C32(0x62870088), SPH_C32(0x8a956000), + SPH_C32(0x1e6d0000), SPH_C32(0x0a245b87), SPH_C32(0x8dab48c5), + SPH_C32(0xbb79ff29), SPH_C32(0x17f23ac7), SPH_C32(0x37420000), + SPH_C32(0xf44200da), SPH_C32(0xea608000), SPH_C32(0xcda80000), + SPH_C32(0x92f567d1), SPH_C32(0xdc7e5412), SPH_C32(0xca360226), + SPH_C32(0x48136c1a) }, + { SPH_C32(0xa5610000), SPH_C32(0x5dbe008a), SPH_C32(0x6b0f8000), + SPH_C32(0x863b0000), SPH_C32(0x9f413c89), SPH_C32(0xc323802f), + SPH_C32(0x68a4b66d), SPH_C32(0x01efe07e), SPH_C32(0x07f50000), + SPH_C32(0x119200da), SPH_C32(0x1e94e000), SPH_C32(0x8f6c0000), + SPH_C32(0xf14d5abb), SPH_C32(0xa4c4c072), SPH_C32(0xeb99a3cc), + SPH_C32(0xf8b6742e) }, + { SPH_C32(0x07b60000), SPH_C32(0xa49d00b4), SPH_C32(0x2ebe0000), + SPH_C32(0x181f0000), SPH_C32(0x72f0015d), SPH_C32(0xc9e270d0), + SPH_C32(0xfb304e73), SPH_C32(0x7c9df973), SPH_C32(0x62cf0000), + SPH_C32(0x14e500cc), SPH_C32(0x0dc80000), SPH_C32(0xbd740000), + SPH_C32(0xbf367f13), SPH_C32(0xcf27b68d), SPH_C32(0x2a795bde), + SPH_C32(0xd4e53740) }, + { SPH_C32(0x81cf0000), SPH_C32(0x9ba400b6), SPH_C32(0xcf24e000), + SPH_C32(0x80490000), SPH_C32(0xe7956653), SPH_C32(0x876ab83a), + SPH_C32(0x28ed0737), SPH_C32(0x6a8023ca), SPH_C32(0x52780000), + SPH_C32(0xf13500cc), SPH_C32(0xf93c6000), SPH_C32(0xffb00000), + SPH_C32(0xdc8e4279), SPH_C32(0xb79d22ed), SPH_C32(0x0bd6fa34), + SPH_C32(0x64402f74) }, + { SPH_C32(0x37010000), SPH_C32(0x414d00b4), SPH_C32(0xda4a6000), + SPH_C32(0x5adb0000), SPH_C32(0x11483c37), SPH_C32(0xb158e4b0), + SPH_C32(0xda9fef99), SPH_C32(0xcc38e147), SPH_C32(0xd4010000), + SPH_C32(0xce0c00ce), SPH_C32(0x18a68000), SPH_C32(0x67e60000), + SPH_C32(0x49eb2577), SPH_C32(0xf915ea07), SPH_C32(0xd80bb370), + SPH_C32(0x725df5cd) }, + { SPH_C32(0xb1780000), SPH_C32(0x7e7400b6), SPH_C32(0x3bd08000), + SPH_C32(0xc28d0000), SPH_C32(0x842d5b39), SPH_C32(0xffd02c5a), + SPH_C32(0x0942a6dd), SPH_C32(0xda253bfe), SPH_C32(0xe4b60000), + SPH_C32(0x2bdc00ce), SPH_C32(0xec52e000), SPH_C32(0x25220000), + SPH_C32(0x2a53181d), SPH_C32(0x81af7e67), SPH_C32(0xf9a4129a), + SPH_C32(0xc2f8edf9) }, + { SPH_C32(0xf0ec0000), SPH_C32(0xbd19009c), SPH_C32(0x8ca70000), + SPH_C32(0xf6e70000), SPH_C32(0xb282244b), SPH_C32(0xd07a62b0), + SPH_C32(0x88ebef95), SPH_C32(0x9d19bb24), SPH_C32(0x76d60000), + SPH_C32(0x372f00f0), SPH_C32(0x5d170000), SPH_C32(0xf9c20000), + SPH_C32(0xa45a18a3), SPH_C32(0xf3d41af8), SPH_C32(0x4b9f4b6e), + SPH_C32(0x0f2fecc0) }, + { SPH_C32(0x76950000), SPH_C32(0x8220009e), SPH_C32(0x6d3de000), + SPH_C32(0x6eb10000), SPH_C32(0x27e74345), SPH_C32(0x9ef2aa5a), + SPH_C32(0x5b36a6d1), SPH_C32(0x8b04619d), SPH_C32(0x46610000), + SPH_C32(0xd2ff00f0), SPH_C32(0xa9e36000), SPH_C32(0xbb060000), + SPH_C32(0xc7e225c9), SPH_C32(0x8b6e8e98), SPH_C32(0x6a30ea84), + SPH_C32(0xbf8af4f4) }, + { SPH_C32(0xc05b0000), SPH_C32(0x58c9009c), SPH_C32(0x78536000), + SPH_C32(0xb4230000), SPH_C32(0xd13a1921), SPH_C32(0xa8c0f6d0), + SPH_C32(0xa9444e7f), SPH_C32(0x2dbca310), SPH_C32(0xc0180000), + SPH_C32(0xedc600f2), SPH_C32(0x48798000), SPH_C32(0x23500000), + SPH_C32(0x528742c7), SPH_C32(0xc5e64672), SPH_C32(0xb9eda3c0), + SPH_C32(0xa9972e4d) }, + { SPH_C32(0x46220000), SPH_C32(0x67f0009e), SPH_C32(0x99c98000), + SPH_C32(0x2c750000), SPH_C32(0x445f7e2f), SPH_C32(0xe6483e3a), + SPH_C32(0x7a99073b), SPH_C32(0x3ba179a9), SPH_C32(0xf0af0000), + SPH_C32(0x081600f2), SPH_C32(0xbc8de000), SPH_C32(0x61940000), + SPH_C32(0x313f7fad), SPH_C32(0xbd5cd212), SPH_C32(0x9842022a), + SPH_C32(0x19323679) }, + { SPH_C32(0xe4f50000), SPH_C32(0x9ed300a0), SPH_C32(0xdc780000), + SPH_C32(0xb2510000), SPH_C32(0xa9ee43fb), SPH_C32(0xec89cec5), + SPH_C32(0xe90dff25), SPH_C32(0x46d360a4), SPH_C32(0x95950000), + SPH_C32(0x0d6100e4), SPH_C32(0xafd10000), SPH_C32(0x538c0000), + SPH_C32(0x7f445a05), SPH_C32(0xd6bfa4ed), SPH_C32(0x59a2fa38), + SPH_C32(0x35617517) }, + { SPH_C32(0x628c0000), SPH_C32(0xa1ea00a2), SPH_C32(0x3de2e000), + SPH_C32(0x2a070000), SPH_C32(0x3c8b24f5), SPH_C32(0xa201062f), + SPH_C32(0x3ad0b661), SPH_C32(0x50ceba1d), SPH_C32(0xa5220000), + SPH_C32(0xe8b100e4), SPH_C32(0x5b256000), SPH_C32(0x11480000), + SPH_C32(0x1cfc676f), SPH_C32(0xae05308d), SPH_C32(0x780d5bd2), + SPH_C32(0x85c46d23) }, + { SPH_C32(0xd4420000), SPH_C32(0x7b0300a0), SPH_C32(0x288c6000), + SPH_C32(0xf0950000), SPH_C32(0xca567e91), SPH_C32(0x94335aa5), + SPH_C32(0xc8a25ecf), SPH_C32(0xf6767890), SPH_C32(0x235b0000), + SPH_C32(0xd78800e6), SPH_C32(0xbabf8000), SPH_C32(0x891e0000), + SPH_C32(0x89990061), SPH_C32(0xe08df867), SPH_C32(0xabd01296), + SPH_C32(0x93d9b79a) }, + { SPH_C32(0x523b0000), SPH_C32(0x443a00a2), SPH_C32(0xc9168000), + SPH_C32(0x68c30000), SPH_C32(0x5f33199f), SPH_C32(0xdabb924f), + SPH_C32(0x1b7f178b), SPH_C32(0xe06ba229), SPH_C32(0x13ec0000), + SPH_C32(0x325800e6), SPH_C32(0x4e4be000), SPH_C32(0xcbda0000), + SPH_C32(0xea213d0b), SPH_C32(0x98376c07), SPH_C32(0x8a7fb37c), + SPH_C32(0x237cafae) }, + { SPH_C32(0x47ff0000), SPH_C32(0x812600d4), SPH_C32(0x5bcf0000), + SPH_C32(0x36b70000), SPH_C32(0x47392832), SPH_C32(0x935f59b7), + SPH_C32(0x256c4600), SPH_C32(0xd9267fe4), SPH_C32(0x3d010000), + SPH_C32(0xd29000c0), SPH_C32(0xe68d0000), SPH_C32(0xc6310000), + SPH_C32(0xca304571), SPH_C32(0xa8ea90ce), SPH_C32(0x385630bf), + SPH_C32(0xc290fed9) }, + { SPH_C32(0xc1860000), SPH_C32(0xbe1f00d6), SPH_C32(0xba55e000), + SPH_C32(0xaee10000), SPH_C32(0xd25c4f3c), SPH_C32(0xddd7915d), + SPH_C32(0xf6b10f44), SPH_C32(0xcf3ba55d), SPH_C32(0x0db60000), + SPH_C32(0x374000c0), SPH_C32(0x12796000), SPH_C32(0x84f50000), + SPH_C32(0xa988781b), SPH_C32(0xd05004ae), SPH_C32(0x19f99155), + SPH_C32(0x7235e6ed) }, + { SPH_C32(0x77480000), SPH_C32(0x64f600d4), SPH_C32(0xaf3b6000), + SPH_C32(0x74730000), SPH_C32(0x24811558), SPH_C32(0xebe5cdd7), + SPH_C32(0x04c3e7ea), SPH_C32(0x698367d0), SPH_C32(0x8bcf0000), + SPH_C32(0x087900c2), SPH_C32(0xf3e38000), SPH_C32(0x1ca30000), + SPH_C32(0x3ced1f15), SPH_C32(0x9ed8cc44), SPH_C32(0xca24d811), + SPH_C32(0x64283c54) }, + { SPH_C32(0xf1310000), SPH_C32(0x5bcf00d6), SPH_C32(0x4ea18000), + SPH_C32(0xec250000), SPH_C32(0xb1e47256), SPH_C32(0xa56d053d), + SPH_C32(0xd71eaeae), SPH_C32(0x7f9ebd69), SPH_C32(0xbb780000), + SPH_C32(0xeda900c2), SPH_C32(0x0717e000), SPH_C32(0x5e670000), + SPH_C32(0x5f55227f), SPH_C32(0xe6625824), SPH_C32(0xeb8b79fb), + SPH_C32(0xd48d2460) }, + { SPH_C32(0x53e60000), SPH_C32(0xa2ec00e8), SPH_C32(0x0b100000), + SPH_C32(0x72010000), SPH_C32(0x5c554f82), SPH_C32(0xafacf5c2), + SPH_C32(0x448a56b0), SPH_C32(0x02eca464), SPH_C32(0xde420000), + SPH_C32(0xe8de00d4), SPH_C32(0x144b0000), SPH_C32(0x6c7f0000), + SPH_C32(0x112e07d7), SPH_C32(0x8d812edb), SPH_C32(0x2a6b81e9), + SPH_C32(0xf8de670e) }, + { SPH_C32(0xd59f0000), SPH_C32(0x9dd500ea), SPH_C32(0xea8ae000), + SPH_C32(0xea570000), SPH_C32(0xc930288c), SPH_C32(0xe1243d28), + SPH_C32(0x97571ff4), SPH_C32(0x14f17edd), SPH_C32(0xeef50000), + SPH_C32(0x0d0e00d4), SPH_C32(0xe0bf6000), SPH_C32(0x2ebb0000), + SPH_C32(0x72963abd), SPH_C32(0xf53bbabb), SPH_C32(0x0bc42003), + SPH_C32(0x487b7f3a) }, + { SPH_C32(0x63510000), SPH_C32(0x473c00e8), SPH_C32(0xffe46000), + SPH_C32(0x30c50000), SPH_C32(0x3fed72e8), SPH_C32(0xd71661a2), + SPH_C32(0x6525f75a), SPH_C32(0xb249bc50), SPH_C32(0x688c0000), + SPH_C32(0x323700d6), SPH_C32(0x01258000), SPH_C32(0xb6ed0000), + SPH_C32(0xe7f35db3), SPH_C32(0xbbb37251), SPH_C32(0xd8196947), + SPH_C32(0x5e66a583) }, + { SPH_C32(0xe5280000), SPH_C32(0x780500ea), SPH_C32(0x1e7e8000), + SPH_C32(0xa8930000), SPH_C32(0xaa8815e6), SPH_C32(0x999ea948), + SPH_C32(0xb6f8be1e), SPH_C32(0xa45466e9), SPH_C32(0x583b0000), + SPH_C32(0xd7e700d6), SPH_C32(0xf5d1e000), SPH_C32(0xf4290000), + SPH_C32(0x844b60d9), SPH_C32(0xc309e631), SPH_C32(0xf9b6c8ad), + SPH_C32(0xeec3bdb7) }, + { SPH_C32(0xa4bc0000), SPH_C32(0xbb6800c0), SPH_C32(0xa9090000), + SPH_C32(0x9cf90000), SPH_C32(0x9c276a94), SPH_C32(0xb634e7a2), + SPH_C32(0x3751f756), SPH_C32(0xe368e633), SPH_C32(0xca5b0000), + SPH_C32(0xcb1400e8), SPH_C32(0x44940000), SPH_C32(0x28c90000), + SPH_C32(0x0a426067), SPH_C32(0xb17282ae), SPH_C32(0x4b8d9159), + SPH_C32(0x2314bc8e) }, + { SPH_C32(0x22c50000), SPH_C32(0x845100c2), SPH_C32(0x4893e000), + SPH_C32(0x04af0000), SPH_C32(0x09420d9a), SPH_C32(0xf8bc2f48), + SPH_C32(0xe48cbe12), SPH_C32(0xf5753c8a), SPH_C32(0xfaec0000), + SPH_C32(0x2ec400e8), SPH_C32(0xb0606000), SPH_C32(0x6a0d0000), + SPH_C32(0x69fa5d0d), SPH_C32(0xc9c816ce), SPH_C32(0x6a2230b3), + SPH_C32(0x93b1a4ba) }, + { SPH_C32(0x940b0000), SPH_C32(0x5eb800c0), SPH_C32(0x5dfd6000), + SPH_C32(0xde3d0000), SPH_C32(0xff9f57fe), SPH_C32(0xce8e73c2), + SPH_C32(0x16fe56bc), SPH_C32(0x53cdfe07), SPH_C32(0x7c950000), + SPH_C32(0x11fd00ea), SPH_C32(0x51fa8000), SPH_C32(0xf25b0000), + SPH_C32(0xfc9f3a03), SPH_C32(0x8740de24), SPH_C32(0xb9ff79f7), + SPH_C32(0x85ac7e03) }, + { SPH_C32(0x12720000), SPH_C32(0x618100c2), SPH_C32(0xbc678000), + SPH_C32(0x466b0000), SPH_C32(0x6afa30f0), SPH_C32(0x8006bb28), + SPH_C32(0xc5231ff8), SPH_C32(0x45d024be), SPH_C32(0x4c220000), + SPH_C32(0xf42d00ea), SPH_C32(0xa50ee000), SPH_C32(0xb09f0000), + SPH_C32(0x9f270769), SPH_C32(0xfffa4a44), SPH_C32(0x9850d81d), + SPH_C32(0x35096637) }, + { SPH_C32(0xb0a50000), SPH_C32(0x98a200fc), SPH_C32(0xf9d60000), + SPH_C32(0xd84f0000), SPH_C32(0x874b0d24), SPH_C32(0x8ac74bd7), + SPH_C32(0x56b7e7e6), SPH_C32(0x38a23db3), SPH_C32(0x29180000), + SPH_C32(0xf15a00fc), SPH_C32(0xb6520000), SPH_C32(0x82870000), + SPH_C32(0xd15c22c1), SPH_C32(0x94193cbb), SPH_C32(0x59b0200f), + SPH_C32(0x195a2559) }, + { SPH_C32(0x36dc0000), SPH_C32(0xa79b00fe), SPH_C32(0x184ce000), + SPH_C32(0x40190000), SPH_C32(0x122e6a2a), SPH_C32(0xc44f833d), + SPH_C32(0x856aaea2), SPH_C32(0x2ebfe70a), SPH_C32(0x19af0000), + SPH_C32(0x148a00fc), SPH_C32(0x42a66000), SPH_C32(0xc0430000), + SPH_C32(0xb2e41fab), SPH_C32(0xeca3a8db), SPH_C32(0x781f81e5), + SPH_C32(0xa9ff3d6d) }, + { SPH_C32(0x80120000), SPH_C32(0x7d7200fc), SPH_C32(0x0d226000), + SPH_C32(0x9a8b0000), SPH_C32(0xe4f3304e), SPH_C32(0xf27ddfb7), + SPH_C32(0x7718460c), SPH_C32(0x88072587), SPH_C32(0x9fd60000), + SPH_C32(0x2bb300fe), SPH_C32(0xa33c8000), SPH_C32(0x58150000), + SPH_C32(0x278178a5), SPH_C32(0xa22b6031), SPH_C32(0xabc2c8a1), + SPH_C32(0xbfe2e7d4) }, + { SPH_C32(0x066b0000), SPH_C32(0x424b00fe), SPH_C32(0xecb88000), + SPH_C32(0x02dd0000), SPH_C32(0x71965740), SPH_C32(0xbcf5175d), + SPH_C32(0xa4c50f48), SPH_C32(0x9e1aff3e), SPH_C32(0xaf610000), + SPH_C32(0xce6300fe), SPH_C32(0x57c8e000), SPH_C32(0x1ad10000), + SPH_C32(0x443945cf), SPH_C32(0xda91f451), SPH_C32(0x8a6d694b), + SPH_C32(0x0f47ffe0) } +}; + +static const sph_u32 T512_32[256][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xcc140000), SPH_C32(0xa5630000), SPH_C32(0x5ab90780), + SPH_C32(0x3b500000), SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), + SPH_C32(0x694348c1), SPH_C32(0xca5a87fe), SPH_C32(0x819e0000), + SPH_C32(0xec570000), SPH_C32(0x66320280), SPH_C32(0x95f30000), + SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), SPH_C32(0xe65aa22d), + SPH_C32(0x8e67b7fa) }, + { SPH_C32(0x819e0000), SPH_C32(0xec570000), SPH_C32(0x66320280), + SPH_C32(0x95f30000), SPH_C32(0x5da92802), SPH_C32(0x48f43cbc), + SPH_C32(0xe65aa22d), SPH_C32(0x8e67b7fa), SPH_C32(0x4d8a0000), + SPH_C32(0x49340000), SPH_C32(0x3c8b0500), SPH_C32(0xaea30000), + SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), SPH_C32(0x8f19eaec), + SPH_C32(0x443d3004) }, + { SPH_C32(0x4d8a0000), SPH_C32(0x49340000), SPH_C32(0x3c8b0500), + SPH_C32(0xaea30000), SPH_C32(0x16793bfd), SPH_C32(0xcf6f08a4), + SPH_C32(0x8f19eaec), SPH_C32(0x443d3004), SPH_C32(0xcc140000), + SPH_C32(0xa5630000), SPH_C32(0x5ab90780), SPH_C32(0x3b500000), + SPH_C32(0x4bd013ff), SPH_C32(0x879b3418), SPH_C32(0x694348c1), + SPH_C32(0xca5a87fe) }, + { SPH_C32(0x78230000), SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), + SPH_C32(0x90a50000), SPH_C32(0x713e2879), SPH_C32(0x7ee98924), + SPH_C32(0xf08ca062), SPH_C32(0x636f8bab), SPH_C32(0x02af0000), + SPH_C32(0xb7280000), SPH_C32(0xba1c0300), SPH_C32(0x56980000), + SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), SPH_C32(0xa95c149a), + SPH_C32(0xf4f6ea7b) }, + { SPH_C32(0xb4370000), SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), + SPH_C32(0xabf50000), SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), + SPH_C32(0x99cfe8a3), SPH_C32(0xa9350c55), SPH_C32(0x83310000), + SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), SPH_C32(0xc36b0000), + SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), SPH_C32(0x4f06b6b7), + SPH_C32(0x7a915d81) }, + { SPH_C32(0xf9bd0000), SPH_C32(0xfeab0000), SPH_C32(0xcf080900), + SPH_C32(0x05560000), SPH_C32(0x2c97007b), SPH_C32(0x361db598), + SPH_C32(0x16d6024f), SPH_C32(0xed083c51), SPH_C32(0x4f250000), + SPH_C32(0xfe1c0000), SPH_C32(0x86970600), SPH_C32(0xf83b0000), + SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), SPH_C32(0x2645fe76), + SPH_C32(0xb0cbda7f) }, + { SPH_C32(0x35a90000), SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), + SPH_C32(0x3e060000), SPH_C32(0x67471384), SPH_C32(0xb1868180), + SPH_C32(0x7f954a8e), SPH_C32(0x2752bbaf), SPH_C32(0xcebb0000), + SPH_C32(0x124b0000), SPH_C32(0xe0a50480), SPH_C32(0x6dc80000), + SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), SPH_C32(0xc01f5c5b), + SPH_C32(0x3eac6d85) }, + { SPH_C32(0x02af0000), SPH_C32(0xb7280000), SPH_C32(0xba1c0300), + SPH_C32(0x56980000), SPH_C32(0xba8d45d3), SPH_C32(0x8048c667), + SPH_C32(0xa95c149a), SPH_C32(0xf4f6ea7b), SPH_C32(0x7a8c0000), + SPH_C32(0xa5d40000), SPH_C32(0x13260880), SPH_C32(0xc63d0000), + SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), SPH_C32(0x59d0b4f8), + SPH_C32(0x979961d0) }, + { SPH_C32(0xcebb0000), SPH_C32(0x124b0000), SPH_C32(0xe0a50480), + SPH_C32(0x6dc80000), SPH_C32(0xf15d562c), SPH_C32(0x07d3f27f), + SPH_C32(0xc01f5c5b), SPH_C32(0x3eac6d85), SPH_C32(0xfb120000), + SPH_C32(0x49830000), SPH_C32(0x75140a00), SPH_C32(0x53ce0000), + SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), SPH_C32(0xbf8a16d5), + SPH_C32(0x19fed62a) }, + { SPH_C32(0x83310000), SPH_C32(0x5b7f0000), SPH_C32(0xdc2e0180), + SPH_C32(0xc36b0000), SPH_C32(0xe7246dd1), SPH_C32(0xc8bcfadb), + SPH_C32(0x4f06b6b7), SPH_C32(0x7a915d81), SPH_C32(0x37060000), + SPH_C32(0xece00000), SPH_C32(0x2fad0d80), SPH_C32(0x689e0000), + SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), SPH_C32(0xd6c95e14), + SPH_C32(0xd3a451d4) }, + { SPH_C32(0x4f250000), SPH_C32(0xfe1c0000), SPH_C32(0x86970600), + SPH_C32(0xf83b0000), SPH_C32(0xacf47e2e), SPH_C32(0x4f27cec3), + SPH_C32(0x2645fe76), SPH_C32(0xb0cbda7f), SPH_C32(0xb6980000), + SPH_C32(0x00b70000), SPH_C32(0x499f0f00), SPH_C32(0xfd6d0000), + SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), SPH_C32(0x3093fc39), + SPH_C32(0x5dc3e62e) }, + { SPH_C32(0x7a8c0000), SPH_C32(0xa5d40000), SPH_C32(0x13260880), + SPH_C32(0xc63d0000), SPH_C32(0xcbb36daa), SPH_C32(0xfea14f43), + SPH_C32(0x59d0b4f8), SPH_C32(0x979961d0), SPH_C32(0x78230000), + SPH_C32(0x12fc0000), SPH_C32(0xa93a0b80), SPH_C32(0x90a50000), + SPH_C32(0x713e2879), SPH_C32(0x7ee98924), SPH_C32(0xf08ca062), + SPH_C32(0x636f8bab) }, + { SPH_C32(0xb6980000), SPH_C32(0x00b70000), SPH_C32(0x499f0f00), + SPH_C32(0xfd6d0000), SPH_C32(0x80637e55), SPH_C32(0x793a7b5b), + SPH_C32(0x3093fc39), SPH_C32(0x5dc3e62e), SPH_C32(0xf9bd0000), + SPH_C32(0xfeab0000), SPH_C32(0xcf080900), SPH_C32(0x05560000), + SPH_C32(0x2c97007b), SPH_C32(0x361db598), SPH_C32(0x16d6024f), + SPH_C32(0xed083c51) }, + { SPH_C32(0xfb120000), SPH_C32(0x49830000), SPH_C32(0x75140a00), + SPH_C32(0x53ce0000), SPH_C32(0x961a45a8), SPH_C32(0xb65573ff), + SPH_C32(0xbf8a16d5), SPH_C32(0x19fed62a), SPH_C32(0x35a90000), + SPH_C32(0x5bc80000), SPH_C32(0x95b10e80), SPH_C32(0x3e060000), + SPH_C32(0x67471384), SPH_C32(0xb1868180), SPH_C32(0x7f954a8e), + SPH_C32(0x2752bbaf) }, + { SPH_C32(0x37060000), SPH_C32(0xece00000), SPH_C32(0x2fad0d80), + SPH_C32(0x689e0000), SPH_C32(0xddca5657), SPH_C32(0x31ce47e7), + SPH_C32(0xd6c95e14), SPH_C32(0xd3a451d4), SPH_C32(0xb4370000), + SPH_C32(0xb79f0000), SPH_C32(0xf3830c00), SPH_C32(0xabf50000), + SPH_C32(0x3aee3b86), SPH_C32(0xf972bd3c), SPH_C32(0x99cfe8a3), + SPH_C32(0xa9350c55) }, + { SPH_C32(0xac480000), SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), + SPH_C32(0x03430000), SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), + SPH_C32(0xfe72c7fe), SPH_C32(0x91e478f6), SPH_C32(0x1e4e0000), + SPH_C32(0xdecf0000), SPH_C32(0x6df80180), SPH_C32(0x77240000), + SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), SPH_C32(0xcda31812), + SPH_C32(0x98aa496e) }, + { SPH_C32(0x605c0000), SPH_C32(0xbec50000), SPH_C32(0x1f421400), + SPH_C32(0x38130000), SPH_C32(0x11552295), SPH_C32(0x982964ae), + SPH_C32(0x97318f3f), SPH_C32(0x5bbeff08), SPH_C32(0x9fd00000), + SPH_C32(0x32980000), SPH_C32(0x0bca0300), SPH_C32(0xe2d70000), + SPH_C32(0xb1ee2f9c), SPH_C32(0xbc5455f2), SPH_C32(0x2bf9ba3f), + SPH_C32(0x16cdfe94) }, + { SPH_C32(0x2dd60000), SPH_C32(0xf7f10000), SPH_C32(0x23c91100), + SPH_C32(0x96b00000), SPH_C32(0x072c1968), SPH_C32(0x57466c0a), + SPH_C32(0x182865d3), SPH_C32(0x1f83cf0c), SPH_C32(0x53c40000), + SPH_C32(0x97fb0000), SPH_C32(0x51730480), SPH_C32(0xd9870000), + SPH_C32(0xfa3e3c63), SPH_C32(0x3bcf61ea), SPH_C32(0x42baf2fe), + SPH_C32(0xdc97796a) }, + { SPH_C32(0xe1c20000), SPH_C32(0x52920000), SPH_C32(0x79701680), + SPH_C32(0xade00000), SPH_C32(0x4cfc0a97), SPH_C32(0xd0dd5812), + SPH_C32(0x716b2d12), SPH_C32(0xd5d948f2), SPH_C32(0xd25a0000), + SPH_C32(0x7bac0000), SPH_C32(0x37410600), SPH_C32(0x4c740000), + SPH_C32(0xa7971461), SPH_C32(0x733b5d56), SPH_C32(0xa4e050d3), + SPH_C32(0x52f0ce90) }, + { SPH_C32(0xd46b0000), SPH_C32(0x095a0000), SPH_C32(0xecc11800), + SPH_C32(0x93e60000), SPH_C32(0x2bbb1913), SPH_C32(0x615bd992), + SPH_C32(0x0efe679c), SPH_C32(0xf28bf35d), SPH_C32(0x1ce10000), + SPH_C32(0x69e70000), SPH_C32(0xd7e40280), SPH_C32(0x21bc0000), + SPH_C32(0x56ca424d), SPH_C32(0x74e8af29), SPH_C32(0x64ff0c88), + SPH_C32(0x6c5ca315) }, + { SPH_C32(0x187f0000), SPH_C32(0xac390000), SPH_C32(0xb6781f80), + SPH_C32(0xa8b60000), SPH_C32(0x606b0aec), SPH_C32(0xe6c0ed8a), + SPH_C32(0x67bd2f5d), SPH_C32(0x38d174a3), SPH_C32(0x9d7f0000), + SPH_C32(0x85b00000), SPH_C32(0xb1d60000), SPH_C32(0xb44f0000), + SPH_C32(0x0b636a4f), SPH_C32(0x3c1c9395), SPH_C32(0x82a5aea5), + SPH_C32(0xe23b14ef) }, + { SPH_C32(0x55f50000), SPH_C32(0xe50d0000), SPH_C32(0x8af31a80), + SPH_C32(0x06150000), SPH_C32(0x76123111), SPH_C32(0x29afe52e), + SPH_C32(0xe8a4c5b1), SPH_C32(0x7cec44a7), SPH_C32(0x516b0000), + SPH_C32(0x20d30000), SPH_C32(0xeb6f0780), SPH_C32(0x8f1f0000), + SPH_C32(0x40b379b0), SPH_C32(0xbb87a78d), SPH_C32(0xebe6e664), + SPH_C32(0x28619311) }, + { SPH_C32(0x99e10000), SPH_C32(0x406e0000), SPH_C32(0xd04a1d00), + SPH_C32(0x3d450000), SPH_C32(0x3dc222ee), SPH_C32(0xae34d136), + SPH_C32(0x81e78d70), SPH_C32(0xb6b6c359), SPH_C32(0xd0f50000), + SPH_C32(0xcc840000), SPH_C32(0x8d5d0500), SPH_C32(0x1aec0000), + SPH_C32(0x1d1a51b2), SPH_C32(0xf3739b31), SPH_C32(0x0dbc4449), + SPH_C32(0xa60624eb) }, + { SPH_C32(0xaee70000), SPH_C32(0xac8e0000), SPH_C32(0xffe71080), + SPH_C32(0x55db0000), SPH_C32(0xe00874b9), SPH_C32(0x9ffa96d1), + SPH_C32(0x572ed364), SPH_C32(0x6512928d), SPH_C32(0x64c20000), + SPH_C32(0x7b1b0000), SPH_C32(0x7ede0900), SPH_C32(0xb1190000), + SPH_C32(0x27f46a34), SPH_C32(0x0a01260d), SPH_C32(0x9473acea), + SPH_C32(0x0f3328be) }, + { SPH_C32(0x62f30000), SPH_C32(0x09ed0000), SPH_C32(0xa55e1700), + SPH_C32(0x6e8b0000), SPH_C32(0xabd86746), SPH_C32(0x1861a2c9), + SPH_C32(0x3e6d9ba5), SPH_C32(0xaf481573), SPH_C32(0xe55c0000), + SPH_C32(0x974c0000), SPH_C32(0x18ec0b80), SPH_C32(0x24ea0000), + SPH_C32(0x7a5d4236), SPH_C32(0x42f51ab1), SPH_C32(0x72290ec7), + SPH_C32(0x81549f44) }, + { SPH_C32(0x2f790000), SPH_C32(0x40d90000), SPH_C32(0x99d51200), + SPH_C32(0xc0280000), SPH_C32(0xbda15cbb), SPH_C32(0xd70eaa6d), + SPH_C32(0xb1747149), SPH_C32(0xeb752577), SPH_C32(0x29480000), + SPH_C32(0x322f0000), SPH_C32(0x42550c00), SPH_C32(0x1fba0000), + SPH_C32(0x318d51c9), SPH_C32(0xc56e2ea9), SPH_C32(0x1b6a4606), + SPH_C32(0x4b0e18ba) }, + { SPH_C32(0xe36d0000), SPH_C32(0xe5ba0000), SPH_C32(0xc36c1580), + SPH_C32(0xfb780000), SPH_C32(0xf6714f44), SPH_C32(0x50959e75), + SPH_C32(0xd8373988), SPH_C32(0x212fa289), SPH_C32(0xa8d60000), + SPH_C32(0xde780000), SPH_C32(0x24670e80), SPH_C32(0x8a490000), + SPH_C32(0x6c2479cb), SPH_C32(0x8d9a1215), SPH_C32(0xfd30e42b), + SPH_C32(0xc569af40) }, + { SPH_C32(0xd6c40000), SPH_C32(0xbe720000), SPH_C32(0x56dd1b00), + SPH_C32(0xc57e0000), SPH_C32(0x91365cc0), SPH_C32(0xe1131ff5), + SPH_C32(0xa7a27306), SPH_C32(0x067d1926), SPH_C32(0x666d0000), + SPH_C32(0xcc330000), SPH_C32(0xc4c20a00), SPH_C32(0xe7810000), + SPH_C32(0x9d792fe7), SPH_C32(0x8a49e06a), SPH_C32(0x3d2fb870), + SPH_C32(0xfbc5c2c5) }, + { SPH_C32(0x1ad00000), SPH_C32(0x1b110000), SPH_C32(0x0c641c80), + SPH_C32(0xfe2e0000), SPH_C32(0xdae64f3f), SPH_C32(0x66882bed), + SPH_C32(0xcee13bc7), SPH_C32(0xcc279ed8), SPH_C32(0xe7f30000), + SPH_C32(0x20640000), SPH_C32(0xa2f00880), SPH_C32(0x72720000), + SPH_C32(0xc0d007e5), SPH_C32(0xc2bddcd6), SPH_C32(0xdb751a5d), + SPH_C32(0x75a2753f) }, + { SPH_C32(0x575a0000), SPH_C32(0x52250000), SPH_C32(0x30ef1980), + SPH_C32(0x508d0000), SPH_C32(0xcc9f74c2), SPH_C32(0xa9e72349), + SPH_C32(0x41f8d12b), SPH_C32(0x881aaedc), SPH_C32(0x2be70000), + SPH_C32(0x85070000), SPH_C32(0xf8490f00), SPH_C32(0x49220000), + SPH_C32(0x8b00141a), SPH_C32(0x4526e8ce), SPH_C32(0xb236529c), + SPH_C32(0xbff8f2c1) }, + { SPH_C32(0x9b4e0000), SPH_C32(0xf7460000), SPH_C32(0x6a561e00), + SPH_C32(0x6bdd0000), SPH_C32(0x874f673d), SPH_C32(0x2e7c1751), + SPH_C32(0x28bb99ea), SPH_C32(0x42402922), SPH_C32(0xaa790000), + SPH_C32(0x69500000), SPH_C32(0x9e7b0d80), SPH_C32(0xdcd10000), + SPH_C32(0xd6a93c18), SPH_C32(0x0dd2d472), SPH_C32(0x546cf0b1), + SPH_C32(0x319f453b) }, + { SPH_C32(0x1e4e0000), SPH_C32(0xdecf0000), SPH_C32(0x6df80180), + SPH_C32(0x77240000), SPH_C32(0xec47079e), SPH_C32(0xf4a0694e), + SPH_C32(0xcda31812), SPH_C32(0x98aa496e), SPH_C32(0xb2060000), + SPH_C32(0xc5690000), SPH_C32(0x28031200), SPH_C32(0x74670000), + SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), SPH_C32(0x33d1dfec), + SPH_C32(0x094e3198) }, + { SPH_C32(0xd25a0000), SPH_C32(0x7bac0000), SPH_C32(0x37410600), + SPH_C32(0x4c740000), SPH_C32(0xa7971461), SPH_C32(0x733b5d56), + SPH_C32(0xa4e050d3), SPH_C32(0x52f0ce90), SPH_C32(0x33980000), + SPH_C32(0x293e0000), SPH_C32(0x4e311080), SPH_C32(0xe1940000), + SPH_C32(0xeb6b1ef6), SPH_C32(0xa3e60544), SPH_C32(0xd58b7dc1), + SPH_C32(0x87298662) }, + { SPH_C32(0x9fd00000), SPH_C32(0x32980000), SPH_C32(0x0bca0300), + SPH_C32(0xe2d70000), SPH_C32(0xb1ee2f9c), SPH_C32(0xbc5455f2), + SPH_C32(0x2bf9ba3f), SPH_C32(0x16cdfe94), SPH_C32(0xff8c0000), + SPH_C32(0x8c5d0000), SPH_C32(0x14881700), SPH_C32(0xdac40000), + SPH_C32(0xa0bb0d09), SPH_C32(0x247d315c), SPH_C32(0xbcc83500), + SPH_C32(0x4d73019c) }, + { SPH_C32(0x53c40000), SPH_C32(0x97fb0000), SPH_C32(0x51730480), + SPH_C32(0xd9870000), SPH_C32(0xfa3e3c63), SPH_C32(0x3bcf61ea), + SPH_C32(0x42baf2fe), SPH_C32(0xdc97796a), SPH_C32(0x7e120000), + SPH_C32(0x600a0000), SPH_C32(0x72ba1580), SPH_C32(0x4f370000), + SPH_C32(0xfd12250b), SPH_C32(0x6c890de0), SPH_C32(0x5a92972d), + SPH_C32(0xc314b666) }, + { SPH_C32(0x666d0000), SPH_C32(0xcc330000), SPH_C32(0xc4c20a00), + SPH_C32(0xe7810000), SPH_C32(0x9d792fe7), SPH_C32(0x8a49e06a), + SPH_C32(0x3d2fb870), SPH_C32(0xfbc5c2c5), SPH_C32(0xb0a90000), + SPH_C32(0x72410000), SPH_C32(0x921f1100), SPH_C32(0x22ff0000), + SPH_C32(0x0c4f7327), SPH_C32(0x6b5aff9f), SPH_C32(0x9a8dcb76), + SPH_C32(0xfdb8dbe3) }, + { SPH_C32(0xaa790000), SPH_C32(0x69500000), SPH_C32(0x9e7b0d80), + SPH_C32(0xdcd10000), SPH_C32(0xd6a93c18), SPH_C32(0x0dd2d472), + SPH_C32(0x546cf0b1), SPH_C32(0x319f453b), SPH_C32(0x31370000), + SPH_C32(0x9e160000), SPH_C32(0xf42d1380), SPH_C32(0xb70c0000), + SPH_C32(0x51e65b25), SPH_C32(0x23aec323), SPH_C32(0x7cd7695b), + SPH_C32(0x73df6c19) }, + { SPH_C32(0xe7f30000), SPH_C32(0x20640000), SPH_C32(0xa2f00880), + SPH_C32(0x72720000), SPH_C32(0xc0d007e5), SPH_C32(0xc2bddcd6), + SPH_C32(0xdb751a5d), SPH_C32(0x75a2753f), SPH_C32(0xfd230000), + SPH_C32(0x3b750000), SPH_C32(0xae941400), SPH_C32(0x8c5c0000), + SPH_C32(0x1a3648da), SPH_C32(0xa435f73b), SPH_C32(0x1594219a), + SPH_C32(0xb985ebe7) }, + { SPH_C32(0x2be70000), SPH_C32(0x85070000), SPH_C32(0xf8490f00), + SPH_C32(0x49220000), SPH_C32(0x8b00141a), SPH_C32(0x4526e8ce), + SPH_C32(0xb236529c), SPH_C32(0xbff8f2c1), SPH_C32(0x7cbd0000), + SPH_C32(0xd7220000), SPH_C32(0xc8a61680), SPH_C32(0x19af0000), + SPH_C32(0x479f60d8), SPH_C32(0xecc1cb87), SPH_C32(0xf3ce83b7), + SPH_C32(0x37e25c1d) }, + { SPH_C32(0x1ce10000), SPH_C32(0x69e70000), SPH_C32(0xd7e40280), + SPH_C32(0x21bc0000), SPH_C32(0x56ca424d), SPH_C32(0x74e8af29), + SPH_C32(0x64ff0c88), SPH_C32(0x6c5ca315), SPH_C32(0xc88a0000), + SPH_C32(0x60bd0000), SPH_C32(0x3b251a80), SPH_C32(0xb25a0000), + SPH_C32(0x7d715b5e), SPH_C32(0x15b376bb), SPH_C32(0x6a016b14), + SPH_C32(0x9ed75048) }, + { SPH_C32(0xd0f50000), SPH_C32(0xcc840000), SPH_C32(0x8d5d0500), + SPH_C32(0x1aec0000), SPH_C32(0x1d1a51b2), SPH_C32(0xf3739b31), + SPH_C32(0x0dbc4449), SPH_C32(0xa60624eb), SPH_C32(0x49140000), + SPH_C32(0x8cea0000), SPH_C32(0x5d171800), SPH_C32(0x27a90000), + SPH_C32(0x20d8735c), SPH_C32(0x5d474a07), SPH_C32(0x8c5bc939), + SPH_C32(0x10b0e7b2) }, + { SPH_C32(0x9d7f0000), SPH_C32(0x85b00000), SPH_C32(0xb1d60000), + SPH_C32(0xb44f0000), SPH_C32(0x0b636a4f), SPH_C32(0x3c1c9395), + SPH_C32(0x82a5aea5), SPH_C32(0xe23b14ef), SPH_C32(0x85000000), + SPH_C32(0x29890000), SPH_C32(0x07ae1f80), SPH_C32(0x1cf90000), + SPH_C32(0x6b0860a3), SPH_C32(0xdadc7e1f), SPH_C32(0xe51881f8), + SPH_C32(0xdaea604c) }, + { SPH_C32(0x516b0000), SPH_C32(0x20d30000), SPH_C32(0xeb6f0780), + SPH_C32(0x8f1f0000), SPH_C32(0x40b379b0), SPH_C32(0xbb87a78d), + SPH_C32(0xebe6e664), SPH_C32(0x28619311), SPH_C32(0x049e0000), + SPH_C32(0xc5de0000), SPH_C32(0x619c1d00), SPH_C32(0x890a0000), + SPH_C32(0x36a148a1), SPH_C32(0x922842a3), SPH_C32(0x034223d5), + SPH_C32(0x548dd7b6) }, + { SPH_C32(0x64c20000), SPH_C32(0x7b1b0000), SPH_C32(0x7ede0900), + SPH_C32(0xb1190000), SPH_C32(0x27f46a34), SPH_C32(0x0a01260d), + SPH_C32(0x9473acea), SPH_C32(0x0f3328be), SPH_C32(0xca250000), + SPH_C32(0xd7950000), SPH_C32(0x81391980), SPH_C32(0xe4c20000), + SPH_C32(0xc7fc1e8d), SPH_C32(0x95fbb0dc), SPH_C32(0xc35d7f8e), + SPH_C32(0x6a21ba33) }, + { SPH_C32(0xa8d60000), SPH_C32(0xde780000), SPH_C32(0x24670e80), + SPH_C32(0x8a490000), SPH_C32(0x6c2479cb), SPH_C32(0x8d9a1215), + SPH_C32(0xfd30e42b), SPH_C32(0xc569af40), SPH_C32(0x4bbb0000), + SPH_C32(0x3bc20000), SPH_C32(0xe70b1b00), SPH_C32(0x71310000), + SPH_C32(0x9a55368f), SPH_C32(0xdd0f8c60), SPH_C32(0x2507dda3), + SPH_C32(0xe4460dc9) }, + { SPH_C32(0xe55c0000), SPH_C32(0x974c0000), SPH_C32(0x18ec0b80), + SPH_C32(0x24ea0000), SPH_C32(0x7a5d4236), SPH_C32(0x42f51ab1), + SPH_C32(0x72290ec7), SPH_C32(0x81549f44), SPH_C32(0x87af0000), + SPH_C32(0x9ea10000), SPH_C32(0xbdb21c80), SPH_C32(0x4a610000), + SPH_C32(0xd1852570), SPH_C32(0x5a94b878), SPH_C32(0x4c449562), + SPH_C32(0x2e1c8a37) }, + { SPH_C32(0x29480000), SPH_C32(0x322f0000), SPH_C32(0x42550c00), + SPH_C32(0x1fba0000), SPH_C32(0x318d51c9), SPH_C32(0xc56e2ea9), + SPH_C32(0x1b6a4606), SPH_C32(0x4b0e18ba), SPH_C32(0x06310000), + SPH_C32(0x72f60000), SPH_C32(0xdb801e00), SPH_C32(0xdf920000), + SPH_C32(0x8c2c0d72), SPH_C32(0x126084c4), SPH_C32(0xaa1e374f), + SPH_C32(0xa07b3dcd) }, + { SPH_C32(0xb2060000), SPH_C32(0xc5690000), SPH_C32(0x28031200), + SPH_C32(0x74670000), SPH_C32(0xb6c236f4), SPH_C32(0xeb1239f8), + SPH_C32(0x33d1dfec), SPH_C32(0x094e3198), SPH_C32(0xac480000), + SPH_C32(0x1ba60000), SPH_C32(0x45fb1380), SPH_C32(0x03430000), + SPH_C32(0x5a85316a), SPH_C32(0x1fb250b6), SPH_C32(0xfe72c7fe), + SPH_C32(0x91e478f6) }, + { SPH_C32(0x7e120000), SPH_C32(0x600a0000), SPH_C32(0x72ba1580), + SPH_C32(0x4f370000), SPH_C32(0xfd12250b), SPH_C32(0x6c890de0), + SPH_C32(0x5a92972d), SPH_C32(0xc314b666), SPH_C32(0x2dd60000), + SPH_C32(0xf7f10000), SPH_C32(0x23c91100), SPH_C32(0x96b00000), + SPH_C32(0x072c1968), SPH_C32(0x57466c0a), SPH_C32(0x182865d3), + SPH_C32(0x1f83cf0c) }, + { SPH_C32(0x33980000), SPH_C32(0x293e0000), SPH_C32(0x4e311080), + SPH_C32(0xe1940000), SPH_C32(0xeb6b1ef6), SPH_C32(0xa3e60544), + SPH_C32(0xd58b7dc1), SPH_C32(0x87298662), SPH_C32(0xe1c20000), + SPH_C32(0x52920000), SPH_C32(0x79701680), SPH_C32(0xade00000), + SPH_C32(0x4cfc0a97), SPH_C32(0xd0dd5812), SPH_C32(0x716b2d12), + SPH_C32(0xd5d948f2) }, + { SPH_C32(0xff8c0000), SPH_C32(0x8c5d0000), SPH_C32(0x14881700), + SPH_C32(0xdac40000), SPH_C32(0xa0bb0d09), SPH_C32(0x247d315c), + SPH_C32(0xbcc83500), SPH_C32(0x4d73019c), SPH_C32(0x605c0000), + SPH_C32(0xbec50000), SPH_C32(0x1f421400), SPH_C32(0x38130000), + SPH_C32(0x11552295), SPH_C32(0x982964ae), SPH_C32(0x97318f3f), + SPH_C32(0x5bbeff08) }, + { SPH_C32(0xca250000), SPH_C32(0xd7950000), SPH_C32(0x81391980), + SPH_C32(0xe4c20000), SPH_C32(0xc7fc1e8d), SPH_C32(0x95fbb0dc), + SPH_C32(0xc35d7f8e), SPH_C32(0x6a21ba33), SPH_C32(0xaee70000), + SPH_C32(0xac8e0000), SPH_C32(0xffe71080), SPH_C32(0x55db0000), + SPH_C32(0xe00874b9), SPH_C32(0x9ffa96d1), SPH_C32(0x572ed364), + SPH_C32(0x6512928d) }, + { SPH_C32(0x06310000), SPH_C32(0x72f60000), SPH_C32(0xdb801e00), + SPH_C32(0xdf920000), SPH_C32(0x8c2c0d72), SPH_C32(0x126084c4), + SPH_C32(0xaa1e374f), SPH_C32(0xa07b3dcd), SPH_C32(0x2f790000), + SPH_C32(0x40d90000), SPH_C32(0x99d51200), SPH_C32(0xc0280000), + SPH_C32(0xbda15cbb), SPH_C32(0xd70eaa6d), SPH_C32(0xb1747149), + SPH_C32(0xeb752577) }, + { SPH_C32(0x4bbb0000), SPH_C32(0x3bc20000), SPH_C32(0xe70b1b00), + SPH_C32(0x71310000), SPH_C32(0x9a55368f), SPH_C32(0xdd0f8c60), + SPH_C32(0x2507dda3), SPH_C32(0xe4460dc9), SPH_C32(0xe36d0000), + SPH_C32(0xe5ba0000), SPH_C32(0xc36c1580), SPH_C32(0xfb780000), + SPH_C32(0xf6714f44), SPH_C32(0x50959e75), SPH_C32(0xd8373988), + SPH_C32(0x212fa289) }, + { SPH_C32(0x87af0000), SPH_C32(0x9ea10000), SPH_C32(0xbdb21c80), + SPH_C32(0x4a610000), SPH_C32(0xd1852570), SPH_C32(0x5a94b878), + SPH_C32(0x4c449562), SPH_C32(0x2e1c8a37), SPH_C32(0x62f30000), + SPH_C32(0x09ed0000), SPH_C32(0xa55e1700), SPH_C32(0x6e8b0000), + SPH_C32(0xabd86746), SPH_C32(0x1861a2c9), SPH_C32(0x3e6d9ba5), + SPH_C32(0xaf481573) }, + { SPH_C32(0xb0a90000), SPH_C32(0x72410000), SPH_C32(0x921f1100), + SPH_C32(0x22ff0000), SPH_C32(0x0c4f7327), SPH_C32(0x6b5aff9f), + SPH_C32(0x9a8dcb76), SPH_C32(0xfdb8dbe3), SPH_C32(0xd6c40000), + SPH_C32(0xbe720000), SPH_C32(0x56dd1b00), SPH_C32(0xc57e0000), + SPH_C32(0x91365cc0), SPH_C32(0xe1131ff5), SPH_C32(0xa7a27306), + SPH_C32(0x067d1926) }, + { SPH_C32(0x7cbd0000), SPH_C32(0xd7220000), SPH_C32(0xc8a61680), + SPH_C32(0x19af0000), SPH_C32(0x479f60d8), SPH_C32(0xecc1cb87), + SPH_C32(0xf3ce83b7), SPH_C32(0x37e25c1d), SPH_C32(0x575a0000), + SPH_C32(0x52250000), SPH_C32(0x30ef1980), SPH_C32(0x508d0000), + SPH_C32(0xcc9f74c2), SPH_C32(0xa9e72349), SPH_C32(0x41f8d12b), + SPH_C32(0x881aaedc) }, + { SPH_C32(0x31370000), SPH_C32(0x9e160000), SPH_C32(0xf42d1380), + SPH_C32(0xb70c0000), SPH_C32(0x51e65b25), SPH_C32(0x23aec323), + SPH_C32(0x7cd7695b), SPH_C32(0x73df6c19), SPH_C32(0x9b4e0000), + SPH_C32(0xf7460000), SPH_C32(0x6a561e00), SPH_C32(0x6bdd0000), + SPH_C32(0x874f673d), SPH_C32(0x2e7c1751), SPH_C32(0x28bb99ea), + SPH_C32(0x42402922) }, + { SPH_C32(0xfd230000), SPH_C32(0x3b750000), SPH_C32(0xae941400), + SPH_C32(0x8c5c0000), SPH_C32(0x1a3648da), SPH_C32(0xa435f73b), + SPH_C32(0x1594219a), SPH_C32(0xb985ebe7), SPH_C32(0x1ad00000), + SPH_C32(0x1b110000), SPH_C32(0x0c641c80), SPH_C32(0xfe2e0000), + SPH_C32(0xdae64f3f), SPH_C32(0x66882bed), SPH_C32(0xcee13bc7), + SPH_C32(0xcc279ed8) }, + { SPH_C32(0xc88a0000), SPH_C32(0x60bd0000), SPH_C32(0x3b251a80), + SPH_C32(0xb25a0000), SPH_C32(0x7d715b5e), SPH_C32(0x15b376bb), + SPH_C32(0x6a016b14), SPH_C32(0x9ed75048), SPH_C32(0xd46b0000), + SPH_C32(0x095a0000), SPH_C32(0xecc11800), SPH_C32(0x93e60000), + SPH_C32(0x2bbb1913), SPH_C32(0x615bd992), SPH_C32(0x0efe679c), + SPH_C32(0xf28bf35d) }, + { SPH_C32(0x049e0000), SPH_C32(0xc5de0000), SPH_C32(0x619c1d00), + SPH_C32(0x890a0000), SPH_C32(0x36a148a1), SPH_C32(0x922842a3), + SPH_C32(0x034223d5), SPH_C32(0x548dd7b6), SPH_C32(0x55f50000), + SPH_C32(0xe50d0000), SPH_C32(0x8af31a80), SPH_C32(0x06150000), + SPH_C32(0x76123111), SPH_C32(0x29afe52e), SPH_C32(0xe8a4c5b1), + SPH_C32(0x7cec44a7) }, + { SPH_C32(0x49140000), SPH_C32(0x8cea0000), SPH_C32(0x5d171800), + SPH_C32(0x27a90000), SPH_C32(0x20d8735c), SPH_C32(0x5d474a07), + SPH_C32(0x8c5bc939), SPH_C32(0x10b0e7b2), SPH_C32(0x99e10000), + SPH_C32(0x406e0000), SPH_C32(0xd04a1d00), SPH_C32(0x3d450000), + SPH_C32(0x3dc222ee), SPH_C32(0xae34d136), SPH_C32(0x81e78d70), + SPH_C32(0xb6b6c359) }, + { SPH_C32(0x85000000), SPH_C32(0x29890000), SPH_C32(0x07ae1f80), + SPH_C32(0x1cf90000), SPH_C32(0x6b0860a3), SPH_C32(0xdadc7e1f), + SPH_C32(0xe51881f8), SPH_C32(0xdaea604c), SPH_C32(0x187f0000), + SPH_C32(0xac390000), SPH_C32(0xb6781f80), SPH_C32(0xa8b60000), + SPH_C32(0x606b0aec), SPH_C32(0xe6c0ed8a), SPH_C32(0x67bd2f5d), + SPH_C32(0x38d174a3) }, + { SPH_C32(0xaec30000), SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), + SPH_C32(0x2c150000), SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), + SPH_C32(0xab92f78f), SPH_C32(0xa312567b), SPH_C32(0xdb250000), + SPH_C32(0x09290000), SPH_C32(0x49aac000), SPH_C32(0x81e10000), + SPH_C32(0xcafe6b59), SPH_C32(0x42793431), SPH_C32(0x43566b76), + SPH_C32(0xe86cba2e) }, + { SPH_C32(0x62d70000), SPH_C32(0x392c0001), SPH_C32(0x2368e780), + SPH_C32(0x17450000), SPH_C32(0x0e1c664c), SPH_C32(0xe1cb832e), + SPH_C32(0xc2d1bf4e), SPH_C32(0x6948d185), SPH_C32(0x5abb0000), + SPH_C32(0xe57e0000), SPH_C32(0x2f98c280), SPH_C32(0x14120000), + SPH_C32(0x9757435b), SPH_C32(0x0a8d088d), SPH_C32(0xa50cc95b), + SPH_C32(0x660b0dd4) }, + { SPH_C32(0x2f5d0000), SPH_C32(0x70180001), SPH_C32(0x1fe3e280), + SPH_C32(0xb9e60000), SPH_C32(0x18655db1), SPH_C32(0x2ea48b8a), + SPH_C32(0x4dc855a2), SPH_C32(0x2d75e181), SPH_C32(0x96af0000), + SPH_C32(0x401d0000), SPH_C32(0x7521c500), SPH_C32(0x2f420000), + SPH_C32(0xdc8750a4), SPH_C32(0x8d163c95), SPH_C32(0xcc4f819a), + SPH_C32(0xac518a2a) }, + { SPH_C32(0xe3490000), SPH_C32(0xd57b0001), SPH_C32(0x455ae500), + SPH_C32(0x82b60000), SPH_C32(0x53b54e4e), SPH_C32(0xa93fbf92), + SPH_C32(0x248b1d63), SPH_C32(0xe72f667f), SPH_C32(0x17310000), + SPH_C32(0xac4a0000), SPH_C32(0x1313c780), SPH_C32(0xbab10000), + SPH_C32(0x812e78a6), SPH_C32(0xc5e20029), SPH_C32(0x2a1523b7), + SPH_C32(0x22363dd0) }, + { SPH_C32(0xd6e00000), SPH_C32(0x8eb30001), SPH_C32(0xd0ebeb80), + SPH_C32(0xbcb00000), SPH_C32(0x34f25dca), SPH_C32(0x18b93e12), + SPH_C32(0x5b1e57ed), SPH_C32(0xc07dddd0), SPH_C32(0xd98a0000), + SPH_C32(0xbe010000), SPH_C32(0xf3b6c300), SPH_C32(0xd7790000), + SPH_C32(0x70732e8a), SPH_C32(0xc231f256), SPH_C32(0xea0a7fec), + SPH_C32(0x1c9a5055) }, + { SPH_C32(0x1af40000), SPH_C32(0x2bd00001), SPH_C32(0x8a52ec00), + SPH_C32(0x87e00000), SPH_C32(0x7f224e35), SPH_C32(0x9f220a0a), + SPH_C32(0x325d1f2c), SPH_C32(0x0a275a2e), SPH_C32(0x58140000), + SPH_C32(0x52560000), SPH_C32(0x9584c180), SPH_C32(0x428a0000), + SPH_C32(0x2dda0688), SPH_C32(0x8ac5ceea), SPH_C32(0x0c50ddc1), + SPH_C32(0x92fde7af) }, + { SPH_C32(0x577e0000), SPH_C32(0x62e40001), SPH_C32(0xb6d9e900), + SPH_C32(0x29430000), SPH_C32(0x695b75c8), SPH_C32(0x504d02ae), + SPH_C32(0xbd44f5c0), SPH_C32(0x4e1a6a2a), SPH_C32(0x94000000), + SPH_C32(0xf7350000), SPH_C32(0xcf3dc600), SPH_C32(0x79da0000), + SPH_C32(0x660a1577), SPH_C32(0x0d5efaf2), SPH_C32(0x65139500), + SPH_C32(0x58a76051) }, + { SPH_C32(0x9b6a0000), SPH_C32(0xc7870001), SPH_C32(0xec60ee80), + SPH_C32(0x12130000), SPH_C32(0x228b6637), SPH_C32(0xd7d636b6), + SPH_C32(0xd407bd01), SPH_C32(0x8440edd4), SPH_C32(0x159e0000), + SPH_C32(0x1b620000), SPH_C32(0xa90fc480), SPH_C32(0xec290000), + SPH_C32(0x3ba33d75), SPH_C32(0x45aac64e), SPH_C32(0x8349372d), + SPH_C32(0xd6c0d7ab) }, + { SPH_C32(0xac6c0000), SPH_C32(0x2b670001), SPH_C32(0xc3cde300), + SPH_C32(0x7a8d0000), SPH_C32(0xff413060), SPH_C32(0xe6187151), + SPH_C32(0x02cee315), SPH_C32(0x57e4bc00), SPH_C32(0xa1a90000), + SPH_C32(0xacfd0000), SPH_C32(0x5a8cc880), SPH_C32(0x47dc0000), + SPH_C32(0x014d06f3), SPH_C32(0xbcd87b72), SPH_C32(0x1a86df8e), + SPH_C32(0x7ff5dbfe) }, + { SPH_C32(0x60780000), SPH_C32(0x8e040001), SPH_C32(0x9974e480), + SPH_C32(0x41dd0000), SPH_C32(0xb491239f), SPH_C32(0x61834549), + SPH_C32(0x6b8dabd4), SPH_C32(0x9dbe3bfe), SPH_C32(0x20370000), + SPH_C32(0x40aa0000), SPH_C32(0x3cbeca00), SPH_C32(0xd22f0000), + SPH_C32(0x5ce42ef1), SPH_C32(0xf42c47ce), SPH_C32(0xfcdc7da3), + SPH_C32(0xf1926c04) }, + { SPH_C32(0x2df20000), SPH_C32(0xc7300001), SPH_C32(0xa5ffe180), + SPH_C32(0xef7e0000), SPH_C32(0xa2e81862), SPH_C32(0xaeec4ded), + SPH_C32(0xe4944138), SPH_C32(0xd9830bfa), SPH_C32(0xec230000), + SPH_C32(0xe5c90000), SPH_C32(0x6607cd80), SPH_C32(0xe97f0000), + SPH_C32(0x17343d0e), SPH_C32(0x73b773d6), SPH_C32(0x959f3562), + SPH_C32(0x3bc8ebfa) }, + { SPH_C32(0xe1e60000), SPH_C32(0x62530001), SPH_C32(0xff46e600), + SPH_C32(0xd42e0000), SPH_C32(0xe9380b9d), SPH_C32(0x297779f5), + SPH_C32(0x8dd709f9), SPH_C32(0x13d98c04), SPH_C32(0x6dbd0000), + SPH_C32(0x099e0000), SPH_C32(0x0035cf00), SPH_C32(0x7c8c0000), + SPH_C32(0x4a9d150c), SPH_C32(0x3b434f6a), SPH_C32(0x73c5974f), + SPH_C32(0xb5af5c00) }, + { SPH_C32(0xd44f0000), SPH_C32(0x399b0001), SPH_C32(0x6af7e880), + SPH_C32(0xea280000), SPH_C32(0x8e7f1819), SPH_C32(0x98f1f875), + SPH_C32(0xf2424377), SPH_C32(0x348b37ab), SPH_C32(0xa3060000), + SPH_C32(0x1bd50000), SPH_C32(0xe090cb80), SPH_C32(0x11440000), + SPH_C32(0xbbc04320), SPH_C32(0x3c90bd15), SPH_C32(0xb3dacb14), + SPH_C32(0x8b033185) }, + { SPH_C32(0x185b0000), SPH_C32(0x9cf80001), SPH_C32(0x304eef00), + SPH_C32(0xd1780000), SPH_C32(0xc5af0be6), SPH_C32(0x1f6acc6d), + SPH_C32(0x9b010bb6), SPH_C32(0xfed1b055), SPH_C32(0x22980000), + SPH_C32(0xf7820000), SPH_C32(0x86a2c900), SPH_C32(0x84b70000), + SPH_C32(0xe6696b22), SPH_C32(0x746481a9), SPH_C32(0x55806939), + SPH_C32(0x0564867f) }, + { SPH_C32(0x55d10000), SPH_C32(0xd5cc0001), SPH_C32(0x0cc5ea00), + SPH_C32(0x7fdb0000), SPH_C32(0xd3d6301b), SPH_C32(0xd005c4c9), + SPH_C32(0x1418e15a), SPH_C32(0xbaec8051), SPH_C32(0xee8c0000), + SPH_C32(0x52e10000), SPH_C32(0xdc1bce80), SPH_C32(0xbfe70000), + SPH_C32(0xadb978dd), SPH_C32(0xf3ffb5b1), SPH_C32(0x3cc321f8), + SPH_C32(0xcf3e0181) }, + { SPH_C32(0x99c50000), SPH_C32(0x70af0001), SPH_C32(0x567ced80), + SPH_C32(0x448b0000), SPH_C32(0x980623e4), SPH_C32(0x579ef0d1), + SPH_C32(0x7d5ba99b), SPH_C32(0x70b607af), SPH_C32(0x6f120000), + SPH_C32(0xbeb60000), SPH_C32(0xba29cc00), SPH_C32(0x2a140000), + SPH_C32(0xf01050df), SPH_C32(0xbb0b890d), SPH_C32(0xda9983d5), + SPH_C32(0x4159b67b) }, + { SPH_C32(0x028b0000), SPH_C32(0x87e90001), SPH_C32(0x3c2af380), + SPH_C32(0x2f560000), SPH_C32(0x1f4944d9), SPH_C32(0x79e2e780), + SPH_C32(0x55e03071), SPH_C32(0x32f62e8d), SPH_C32(0xc56b0000), + SPH_C32(0xd7e60000), SPH_C32(0x2452c180), SPH_C32(0xf6c50000), + SPH_C32(0x26b96cc7), SPH_C32(0xb6d95d7f), SPH_C32(0x8ef57364), + SPH_C32(0x70c6f340) }, + { SPH_C32(0xce9f0000), SPH_C32(0x228a0001), SPH_C32(0x6693f400), + SPH_C32(0x14060000), SPH_C32(0x54995726), SPH_C32(0xfe79d398), + SPH_C32(0x3ca378b0), SPH_C32(0xf8aca973), SPH_C32(0x44f50000), + SPH_C32(0x3bb10000), SPH_C32(0x4260c300), SPH_C32(0x63360000), + SPH_C32(0x7b1044c5), SPH_C32(0xfe2d61c3), SPH_C32(0x68afd149), + SPH_C32(0xfea144ba) }, + { SPH_C32(0x83150000), SPH_C32(0x6bbe0001), SPH_C32(0x5a18f100), + SPH_C32(0xbaa50000), SPH_C32(0x42e06cdb), SPH_C32(0x3116db3c), + SPH_C32(0xb3ba925c), SPH_C32(0xbc919977), SPH_C32(0x88e10000), + SPH_C32(0x9ed20000), SPH_C32(0x18d9c480), SPH_C32(0x58660000), + SPH_C32(0x30c0573a), SPH_C32(0x79b655db), SPH_C32(0x01ec9988), + SPH_C32(0x34fbc344) }, + { SPH_C32(0x4f010000), SPH_C32(0xcedd0001), SPH_C32(0x00a1f680), + SPH_C32(0x81f50000), SPH_C32(0x09307f24), SPH_C32(0xb68def24), + SPH_C32(0xdaf9da9d), SPH_C32(0x76cb1e89), SPH_C32(0x097f0000), + SPH_C32(0x72850000), SPH_C32(0x7eebc600), SPH_C32(0xcd950000), + SPH_C32(0x6d697f38), SPH_C32(0x31426967), SPH_C32(0xe7b63ba5), + SPH_C32(0xba9c74be) }, + { SPH_C32(0x7aa80000), SPH_C32(0x95150001), SPH_C32(0x9510f800), + SPH_C32(0xbff30000), SPH_C32(0x6e776ca0), SPH_C32(0x070b6ea4), + SPH_C32(0xa56c9013), SPH_C32(0x5199a526), SPH_C32(0xc7c40000), + SPH_C32(0x60ce0000), SPH_C32(0x9e4ec280), SPH_C32(0xa05d0000), + SPH_C32(0x9c342914), SPH_C32(0x36919b18), SPH_C32(0x27a967fe), + SPH_C32(0x8430193b) }, + { SPH_C32(0xb6bc0000), SPH_C32(0x30760001), SPH_C32(0xcfa9ff80), + SPH_C32(0x84a30000), SPH_C32(0x25a77f5f), SPH_C32(0x80905abc), + SPH_C32(0xcc2fd8d2), SPH_C32(0x9bc322d8), SPH_C32(0x465a0000), + SPH_C32(0x8c990000), SPH_C32(0xf87cc000), SPH_C32(0x35ae0000), + SPH_C32(0xc19d0116), SPH_C32(0x7e65a7a4), SPH_C32(0xc1f3c5d3), + SPH_C32(0x0a57aec1) }, + { SPH_C32(0xfb360000), SPH_C32(0x79420001), SPH_C32(0xf322fa80), + SPH_C32(0x2a000000), SPH_C32(0x33de44a2), SPH_C32(0x4fff5218), + SPH_C32(0x4336323e), SPH_C32(0xdffe12dc), SPH_C32(0x8a4e0000), + SPH_C32(0x29fa0000), SPH_C32(0xa2c5c780), SPH_C32(0x0efe0000), + SPH_C32(0x8a4d12e9), SPH_C32(0xf9fe93bc), SPH_C32(0xa8b08d12), + SPH_C32(0xc00d293f) }, + { SPH_C32(0x37220000), SPH_C32(0xdc210001), SPH_C32(0xa99bfd00), + SPH_C32(0x11500000), SPH_C32(0x780e575d), SPH_C32(0xc8646600), + SPH_C32(0x2a757aff), SPH_C32(0x15a49522), SPH_C32(0x0bd00000), + SPH_C32(0xc5ad0000), SPH_C32(0xc4f7c500), SPH_C32(0x9b0d0000), + SPH_C32(0xd7e43aeb), SPH_C32(0xb10aaf00), SPH_C32(0x4eea2f3f), + SPH_C32(0x4e6a9ec5) }, + { SPH_C32(0x00240000), SPH_C32(0x30c10001), SPH_C32(0x8636f080), + SPH_C32(0x79ce0000), SPH_C32(0xa5c4010a), SPH_C32(0xf9aa21e7), + SPH_C32(0xfcbc24eb), SPH_C32(0xc600c4f6), SPH_C32(0xbfe70000), + SPH_C32(0x72320000), SPH_C32(0x3774c900), SPH_C32(0x30f80000), + SPH_C32(0xed0a016d), SPH_C32(0x4878123c), SPH_C32(0xd725c79c), + SPH_C32(0xe75f9290) }, + { SPH_C32(0xcc300000), SPH_C32(0x95a20001), SPH_C32(0xdc8ff700), + SPH_C32(0x429e0000), SPH_C32(0xee1412f5), SPH_C32(0x7e3115ff), + SPH_C32(0x95ff6c2a), SPH_C32(0x0c5a4308), SPH_C32(0x3e790000), + SPH_C32(0x9e650000), SPH_C32(0x5146cb80), SPH_C32(0xa50b0000), + SPH_C32(0xb0a3296f), SPH_C32(0x008c2e80), SPH_C32(0x317f65b1), + SPH_C32(0x6938256a) }, + { SPH_C32(0x81ba0000), SPH_C32(0xdc960001), SPH_C32(0xe004f200), + SPH_C32(0xec3d0000), SPH_C32(0xf86d2908), SPH_C32(0xb15e1d5b), + SPH_C32(0x1ae686c6), SPH_C32(0x4867730c), SPH_C32(0xf26d0000), + SPH_C32(0x3b060000), SPH_C32(0x0bffcc00), SPH_C32(0x9e5b0000), + SPH_C32(0xfb733a90), SPH_C32(0x87171a98), SPH_C32(0x583c2d70), + SPH_C32(0xa362a294) }, + { SPH_C32(0x4dae0000), SPH_C32(0x79f50001), SPH_C32(0xbabdf580), + SPH_C32(0xd76d0000), SPH_C32(0xb3bd3af7), SPH_C32(0x36c52943), + SPH_C32(0x73a5ce07), SPH_C32(0x823df4f2), SPH_C32(0x73f30000), + SPH_C32(0xd7510000), SPH_C32(0x6dcdce80), SPH_C32(0x0ba80000), + SPH_C32(0xa6da1292), SPH_C32(0xcfe32624), SPH_C32(0xbe668f5d), + SPH_C32(0x2d05156e) }, + { SPH_C32(0x78070000), SPH_C32(0x223d0001), SPH_C32(0x2f0cfb00), + SPH_C32(0xe96b0000), SPH_C32(0xd4fa2973), SPH_C32(0x8743a8c3), + SPH_C32(0x0c308489), SPH_C32(0xa56f4f5d), SPH_C32(0xbd480000), + SPH_C32(0xc51a0000), SPH_C32(0x8d68ca00), SPH_C32(0x66600000), + SPH_C32(0x578744be), SPH_C32(0xc830d45b), SPH_C32(0x7e79d306), + SPH_C32(0x13a978eb) }, + { SPH_C32(0xb4130000), SPH_C32(0x875e0001), SPH_C32(0x75b5fc80), + SPH_C32(0xd23b0000), SPH_C32(0x9f2a3a8c), SPH_C32(0x00d89cdb), + SPH_C32(0x6573cc48), SPH_C32(0x6f35c8a3), SPH_C32(0x3cd60000), + SPH_C32(0x294d0000), SPH_C32(0xeb5ac880), SPH_C32(0xf3930000), + SPH_C32(0x0a2e6cbc), SPH_C32(0x80c4e8e7), SPH_C32(0x9823712b), + SPH_C32(0x9dcecf11) }, + { SPH_C32(0xf9990000), SPH_C32(0xce6a0001), SPH_C32(0x493ef980), + SPH_C32(0x7c980000), SPH_C32(0x89530171), SPH_C32(0xcfb7947f), + SPH_C32(0xea6a26a4), SPH_C32(0x2b08f8a7), SPH_C32(0xf0c20000), + SPH_C32(0x8c2e0000), SPH_C32(0xb1e3cf00), SPH_C32(0xc8c30000), + SPH_C32(0x41fe7f43), SPH_C32(0x075fdcff), SPH_C32(0xf16039ea), + SPH_C32(0x579448ef) }, + { SPH_C32(0x358d0000), SPH_C32(0x6b090001), SPH_C32(0x1387fe00), + SPH_C32(0x47c80000), SPH_C32(0xc283128e), SPH_C32(0x482ca067), + SPH_C32(0x83296e65), SPH_C32(0xe1527f59), SPH_C32(0x715c0000), + SPH_C32(0x60790000), SPH_C32(0xd7d1cd80), SPH_C32(0x5d300000), + SPH_C32(0x1c575741), SPH_C32(0x4fabe043), SPH_C32(0x173a9bc7), + SPH_C32(0xd9f3ff15) }, + { SPH_C32(0xb08d0000), SPH_C32(0x42800001), SPH_C32(0x1429e180), + SPH_C32(0x5b310000), SPH_C32(0xa98b722d), SPH_C32(0x92f0de78), + SPH_C32(0x6631ef9d), SPH_C32(0x3bb81f15), SPH_C32(0x69230000), + SPH_C32(0xcc400000), SPH_C32(0x61a9d200), SPH_C32(0xf5860000), + SPH_C32(0x7c3c5dad), SPH_C32(0xa96b0dc9), SPH_C32(0x7087b49a), + SPH_C32(0xe1228bb6) }, + { SPH_C32(0x7c990000), SPH_C32(0xe7e30001), SPH_C32(0x4e90e600), + SPH_C32(0x60610000), SPH_C32(0xe25b61d2), SPH_C32(0x156bea60), + SPH_C32(0x0f72a75c), SPH_C32(0xf1e298eb), SPH_C32(0xe8bd0000), + SPH_C32(0x20170000), SPH_C32(0x079bd080), SPH_C32(0x60750000), + SPH_C32(0x219575af), SPH_C32(0xe19f3175), SPH_C32(0x96dd16b7), + SPH_C32(0x6f453c4c) }, + { SPH_C32(0x31130000), SPH_C32(0xaed70001), SPH_C32(0x721be300), + SPH_C32(0xcec20000), SPH_C32(0xf4225a2f), SPH_C32(0xda04e2c4), + SPH_C32(0x806b4db0), SPH_C32(0xb5dfa8ef), SPH_C32(0x24a90000), + SPH_C32(0x85740000), SPH_C32(0x5d22d700), SPH_C32(0x5b250000), + SPH_C32(0x6a456650), SPH_C32(0x6604056d), SPH_C32(0xff9e5e76), + SPH_C32(0xa51fbbb2) }, + { SPH_C32(0xfd070000), SPH_C32(0x0bb40001), SPH_C32(0x28a2e480), + SPH_C32(0xf5920000), SPH_C32(0xbff249d0), SPH_C32(0x5d9fd6dc), + SPH_C32(0xe9280571), SPH_C32(0x7f852f11), SPH_C32(0xa5370000), + SPH_C32(0x69230000), SPH_C32(0x3b10d580), SPH_C32(0xced60000), + SPH_C32(0x37ec4e52), SPH_C32(0x2ef039d1), SPH_C32(0x19c4fc5b), + SPH_C32(0x2b780c48) }, + { SPH_C32(0xc8ae0000), SPH_C32(0x507c0001), SPH_C32(0xbd13ea00), + SPH_C32(0xcb940000), SPH_C32(0xd8b55a54), SPH_C32(0xec19575c), + SPH_C32(0x96bd4fff), SPH_C32(0x58d794be), SPH_C32(0x6b8c0000), + SPH_C32(0x7b680000), SPH_C32(0xdbb5d100), SPH_C32(0xa31e0000), + SPH_C32(0xc6b1187e), SPH_C32(0x2923cbae), SPH_C32(0xd9dba000), + SPH_C32(0x15d461cd) }, + { SPH_C32(0x04ba0000), SPH_C32(0xf51f0001), SPH_C32(0xe7aaed80), + SPH_C32(0xf0c40000), SPH_C32(0x936549ab), SPH_C32(0x6b826344), + SPH_C32(0xfffe073e), SPH_C32(0x928d1340), SPH_C32(0xea120000), + SPH_C32(0x973f0000), SPH_C32(0xbd87d380), SPH_C32(0x36ed0000), + SPH_C32(0x9b18307c), SPH_C32(0x61d7f712), SPH_C32(0x3f81022d), + SPH_C32(0x9bb3d637) }, + { SPH_C32(0x49300000), SPH_C32(0xbc2b0001), SPH_C32(0xdb21e880), + SPH_C32(0x5e670000), SPH_C32(0x851c7256), SPH_C32(0xa4ed6be0), + SPH_C32(0x70e7edd2), SPH_C32(0xd6b02344), SPH_C32(0x26060000), + SPH_C32(0x325c0000), SPH_C32(0xe73ed400), SPH_C32(0x0dbd0000), + SPH_C32(0xd0c82383), SPH_C32(0xe64cc30a), SPH_C32(0x56c24aec), + SPH_C32(0x51e951c9) }, + { SPH_C32(0x85240000), SPH_C32(0x19480001), SPH_C32(0x8198ef00), + SPH_C32(0x65370000), SPH_C32(0xcecc61a9), SPH_C32(0x23765ff8), + SPH_C32(0x19a4a513), SPH_C32(0x1ceaa4ba), SPH_C32(0xa7980000), + SPH_C32(0xde0b0000), SPH_C32(0x810cd680), SPH_C32(0x984e0000), + SPH_C32(0x8d610b81), SPH_C32(0xaeb8ffb6), SPH_C32(0xb098e8c1), + SPH_C32(0xdf8ee633) }, + { SPH_C32(0xb2220000), SPH_C32(0xf5a80001), SPH_C32(0xae35e280), + SPH_C32(0x0da90000), SPH_C32(0x130637fe), SPH_C32(0x12b8181f), + SPH_C32(0xcf6dfb07), SPH_C32(0xcf4ef56e), SPH_C32(0x13af0000), + SPH_C32(0x69940000), SPH_C32(0x728fda80), SPH_C32(0x33bb0000), + SPH_C32(0xb78f3007), SPH_C32(0x57ca428a), SPH_C32(0x29570062), + SPH_C32(0x76bbea66) }, + { SPH_C32(0x7e360000), SPH_C32(0x50cb0001), SPH_C32(0xf48ce500), + SPH_C32(0x36f90000), SPH_C32(0x58d62401), SPH_C32(0x95232c07), + SPH_C32(0xa62eb3c6), SPH_C32(0x05147290), SPH_C32(0x92310000), + SPH_C32(0x85c30000), SPH_C32(0x14bdd800), SPH_C32(0xa6480000), + SPH_C32(0xea261805), SPH_C32(0x1f3e7e36), SPH_C32(0xcf0da24f), + SPH_C32(0xf8dc5d9c) }, + { SPH_C32(0x33bc0000), SPH_C32(0x19ff0001), SPH_C32(0xc807e000), + SPH_C32(0x985a0000), SPH_C32(0x4eaf1ffc), SPH_C32(0x5a4c24a3), + SPH_C32(0x2937592a), SPH_C32(0x41294294), SPH_C32(0x5e250000), + SPH_C32(0x20a00000), SPH_C32(0x4e04df80), SPH_C32(0x9d180000), + SPH_C32(0xa1f60bfa), SPH_C32(0x98a54a2e), SPH_C32(0xa64eea8e), + SPH_C32(0x3286da62) }, + { SPH_C32(0xffa80000), SPH_C32(0xbc9c0001), SPH_C32(0x92bee780), + SPH_C32(0xa30a0000), SPH_C32(0x057f0c03), SPH_C32(0xddd710bb), + SPH_C32(0x407411eb), SPH_C32(0x8b73c56a), SPH_C32(0xdfbb0000), + SPH_C32(0xccf70000), SPH_C32(0x2836dd00), SPH_C32(0x08eb0000), + SPH_C32(0xfc5f23f8), SPH_C32(0xd0517692), SPH_C32(0x401448a3), + SPH_C32(0xbce16d98) }, + { SPH_C32(0xca010000), SPH_C32(0xe7540001), SPH_C32(0x070fe900), + SPH_C32(0x9d0c0000), SPH_C32(0x62381f87), SPH_C32(0x6c51913b), + SPH_C32(0x3fe15b65), SPH_C32(0xac217ec5), SPH_C32(0x11000000), + SPH_C32(0xdebc0000), SPH_C32(0xc893d980), SPH_C32(0x65230000), + SPH_C32(0x0d0275d4), SPH_C32(0xd78284ed), SPH_C32(0x800b14f8), + SPH_C32(0x824d001d) }, + { SPH_C32(0x06150000), SPH_C32(0x42370001), SPH_C32(0x5db6ee80), + SPH_C32(0xa65c0000), SPH_C32(0x29e80c78), SPH_C32(0xebcaa523), + SPH_C32(0x56a213a4), SPH_C32(0x667bf93b), SPH_C32(0x909e0000), + SPH_C32(0x32eb0000), SPH_C32(0xaea1db00), SPH_C32(0xf0d00000), + SPH_C32(0x50ab5dd6), SPH_C32(0x9f76b851), SPH_C32(0x6651b6d5), + SPH_C32(0x0c2ab7e7) }, + { SPH_C32(0x4b9f0000), SPH_C32(0x0b030001), SPH_C32(0x613deb80), + SPH_C32(0x08ff0000), SPH_C32(0x3f913785), SPH_C32(0x24a5ad87), + SPH_C32(0xd9bbf948), SPH_C32(0x2246c93f), SPH_C32(0x5c8a0000), + SPH_C32(0x97880000), SPH_C32(0xf418dc80), SPH_C32(0xcb800000), + SPH_C32(0x1b7b4e29), SPH_C32(0x18ed8c49), SPH_C32(0x0f12fe14), + SPH_C32(0xc6703019) }, + { SPH_C32(0x878b0000), SPH_C32(0xae600001), SPH_C32(0x3b84ec00), + SPH_C32(0x33af0000), SPH_C32(0x7441247a), SPH_C32(0xa33e999f), + SPH_C32(0xb0f8b189), SPH_C32(0xe81c4ec1), SPH_C32(0xdd140000), + SPH_C32(0x7bdf0000), SPH_C32(0x922ade00), SPH_C32(0x5e730000), + SPH_C32(0x46d2662b), SPH_C32(0x5019b0f5), SPH_C32(0xe9485c39), + SPH_C32(0x481787e3) }, + { SPH_C32(0x1cc50000), SPH_C32(0x59260001), SPH_C32(0x51d2f200), + SPH_C32(0x58720000), SPH_C32(0xf30e4347), SPH_C32(0x8d428ece), + SPH_C32(0x98432863), SPH_C32(0xaa5c67e3), SPH_C32(0x776d0000), + SPH_C32(0x128f0000), SPH_C32(0x0c51d380), SPH_C32(0x82a20000), + SPH_C32(0x907b5a33), SPH_C32(0x5dcb6487), SPH_C32(0xbd24ac88), + SPH_C32(0x7988c2d8) }, + { SPH_C32(0xd0d10000), SPH_C32(0xfc450001), SPH_C32(0x0b6bf580), + SPH_C32(0x63220000), SPH_C32(0xb8de50b8), SPH_C32(0x0ad9bad6), + SPH_C32(0xf10060a2), SPH_C32(0x6006e01d), SPH_C32(0xf6f30000), + SPH_C32(0xfed80000), SPH_C32(0x6a63d100), SPH_C32(0x17510000), + SPH_C32(0xcdd27231), SPH_C32(0x153f583b), SPH_C32(0x5b7e0ea5), + SPH_C32(0xf7ef7522) }, + { SPH_C32(0x9d5b0000), SPH_C32(0xb5710001), SPH_C32(0x37e0f080), + SPH_C32(0xcd810000), SPH_C32(0xaea76b45), SPH_C32(0xc5b6b272), + SPH_C32(0x7e198a4e), SPH_C32(0x243bd019), SPH_C32(0x3ae70000), + SPH_C32(0x5bbb0000), SPH_C32(0x30dad680), SPH_C32(0x2c010000), + SPH_C32(0x860261ce), SPH_C32(0x92a46c23), SPH_C32(0x323d4664), + SPH_C32(0x3db5f2dc) }, + { SPH_C32(0x514f0000), SPH_C32(0x10120001), SPH_C32(0x6d59f700), + SPH_C32(0xf6d10000), SPH_C32(0xe57778ba), SPH_C32(0x422d866a), + SPH_C32(0x175ac28f), SPH_C32(0xee6157e7), SPH_C32(0xbb790000), + SPH_C32(0xb7ec0000), SPH_C32(0x56e8d400), SPH_C32(0xb9f20000), + SPH_C32(0xdbab49cc), SPH_C32(0xda50509f), SPH_C32(0xd467e449), + SPH_C32(0xb3d24526) }, + { SPH_C32(0x64e60000), SPH_C32(0x4bda0001), SPH_C32(0xf8e8f980), + SPH_C32(0xc8d70000), SPH_C32(0x82306b3e), SPH_C32(0xf3ab07ea), + SPH_C32(0x68cf8801), SPH_C32(0xc933ec48), SPH_C32(0x75c20000), + SPH_C32(0xa5a70000), SPH_C32(0xb64dd080), SPH_C32(0xd43a0000), + SPH_C32(0x2af61fe0), SPH_C32(0xdd83a2e0), SPH_C32(0x1478b812), + SPH_C32(0x8d7e28a3) }, + { SPH_C32(0xa8f20000), SPH_C32(0xeeb90001), SPH_C32(0xa251fe00), + SPH_C32(0xf3870000), SPH_C32(0xc9e078c1), SPH_C32(0x743033f2), + SPH_C32(0x018cc0c0), SPH_C32(0x03696bb6), SPH_C32(0xf45c0000), + SPH_C32(0x49f00000), SPH_C32(0xd07fd200), SPH_C32(0x41c90000), + SPH_C32(0x775f37e2), SPH_C32(0x95779e5c), SPH_C32(0xf2221a3f), + SPH_C32(0x03199f59) }, + { SPH_C32(0xe5780000), SPH_C32(0xa78d0001), SPH_C32(0x9edafb00), + SPH_C32(0x5d240000), SPH_C32(0xdf99433c), SPH_C32(0xbb5f3b56), + SPH_C32(0x8e952a2c), SPH_C32(0x47545bb2), SPH_C32(0x38480000), + SPH_C32(0xec930000), SPH_C32(0x8ac6d580), SPH_C32(0x7a990000), + SPH_C32(0x3c8f241d), SPH_C32(0x12ecaa44), SPH_C32(0x9b6152fe), + SPH_C32(0xc94318a7) }, + { SPH_C32(0x296c0000), SPH_C32(0x02ee0001), SPH_C32(0xc463fc80), + SPH_C32(0x66740000), SPH_C32(0x944950c3), SPH_C32(0x3cc40f4e), + SPH_C32(0xe7d662ed), SPH_C32(0x8d0edc4c), SPH_C32(0xb9d60000), + SPH_C32(0x00c40000), SPH_C32(0xecf4d700), SPH_C32(0xef6a0000), + SPH_C32(0x61260c1f), SPH_C32(0x5a1896f8), SPH_C32(0x7d3bf0d3), + SPH_C32(0x4724af5d) }, + { SPH_C32(0x1e6a0000), SPH_C32(0xee0e0001), SPH_C32(0xebcef100), + SPH_C32(0x0eea0000), SPH_C32(0x49830694), SPH_C32(0x0d0a48a9), + SPH_C32(0x311f3cf9), SPH_C32(0x5eaa8d98), SPH_C32(0x0de10000), + SPH_C32(0xb75b0000), SPH_C32(0x1f77db00), SPH_C32(0x449f0000), + SPH_C32(0x5bc83799), SPH_C32(0xa36a2bc4), SPH_C32(0xe4f41870), + SPH_C32(0xee11a308) }, + { SPH_C32(0xd27e0000), SPH_C32(0x4b6d0001), SPH_C32(0xb177f680), + SPH_C32(0x35ba0000), SPH_C32(0x0253156b), SPH_C32(0x8a917cb1), + SPH_C32(0x585c7438), SPH_C32(0x94f00a66), SPH_C32(0x8c7f0000), + SPH_C32(0x5b0c0000), SPH_C32(0x7945d980), SPH_C32(0xd16c0000), + SPH_C32(0x06611f9b), SPH_C32(0xeb9e1778), SPH_C32(0x02aeba5d), + SPH_C32(0x607614f2) }, + { SPH_C32(0x9ff40000), SPH_C32(0x02590001), SPH_C32(0x8dfcf380), + SPH_C32(0x9b190000), SPH_C32(0x142a2e96), SPH_C32(0x45fe7415), + SPH_C32(0xd7459ed4), SPH_C32(0xd0cd3a62), SPH_C32(0x406b0000), + SPH_C32(0xfe6f0000), SPH_C32(0x23fcde00), SPH_C32(0xea3c0000), + SPH_C32(0x4db10c64), SPH_C32(0x6c052360), SPH_C32(0x6bedf29c), + SPH_C32(0xaa2c930c) }, + { SPH_C32(0x53e00000), SPH_C32(0xa73a0001), SPH_C32(0xd745f400), + SPH_C32(0xa0490000), SPH_C32(0x5ffa3d69), SPH_C32(0xc265400d), + SPH_C32(0xbe06d615), SPH_C32(0x1a97bd9c), SPH_C32(0xc1f50000), + SPH_C32(0x12380000), SPH_C32(0x45cedc80), SPH_C32(0x7fcf0000), + SPH_C32(0x10182466), SPH_C32(0x24f11fdc), SPH_C32(0x8db750b1), + SPH_C32(0x244b24f6) }, + { SPH_C32(0x66490000), SPH_C32(0xfcf20001), SPH_C32(0x42f4fa80), + SPH_C32(0x9e4f0000), SPH_C32(0x38bd2eed), SPH_C32(0x73e3c18d), + SPH_C32(0xc1939c9b), SPH_C32(0x3dc50633), SPH_C32(0x0f4e0000), + SPH_C32(0x00730000), SPH_C32(0xa56bd800), SPH_C32(0x12070000), + SPH_C32(0xe145724a), SPH_C32(0x2322eda3), SPH_C32(0x4da80cea), + SPH_C32(0x1ae74973) }, + { SPH_C32(0xaa5d0000), SPH_C32(0x59910001), SPH_C32(0x184dfd00), + SPH_C32(0xa51f0000), SPH_C32(0x736d3d12), SPH_C32(0xf478f595), + SPH_C32(0xa8d0d45a), SPH_C32(0xf79f81cd), SPH_C32(0x8ed00000), + SPH_C32(0xec240000), SPH_C32(0xc359da80), SPH_C32(0x87f40000), + SPH_C32(0xbcec5a48), SPH_C32(0x6bd6d11f), SPH_C32(0xabf2aec7), + SPH_C32(0x9480fe89) }, + { SPH_C32(0xe7d70000), SPH_C32(0x10a50001), SPH_C32(0x24c6f800), + SPH_C32(0x0bbc0000), SPH_C32(0x651406ef), SPH_C32(0x3b17fd31), + SPH_C32(0x27c93eb6), SPH_C32(0xb3a2b1c9), SPH_C32(0x42c40000), + SPH_C32(0x49470000), SPH_C32(0x99e0dd00), SPH_C32(0xbca40000), + SPH_C32(0xf73c49b7), SPH_C32(0xec4de507), SPH_C32(0xc2b1e606), + SPH_C32(0x5eda7977) }, + { SPH_C32(0x2bc30000), SPH_C32(0xb5c60001), SPH_C32(0x7e7fff80), + SPH_C32(0x30ec0000), SPH_C32(0x2ec41510), SPH_C32(0xbc8cc929), + SPH_C32(0x4e8a7677), SPH_C32(0x79f83637), SPH_C32(0xc35a0000), + SPH_C32(0xa5100000), SPH_C32(0xffd2df80), SPH_C32(0x29570000), + SPH_C32(0xaa9561b5), SPH_C32(0xa4b9d9bb), SPH_C32(0x24eb442b), + SPH_C32(0xd0bdce8d) }, + { SPH_C32(0xdb250000), SPH_C32(0x09290000), SPH_C32(0x49aac000), + SPH_C32(0x81e10000), SPH_C32(0xcafe6b59), SPH_C32(0x42793431), + SPH_C32(0x43566b76), SPH_C32(0xe86cba2e), SPH_C32(0x75e60000), + SPH_C32(0x95660001), SPH_C32(0x307b2000), SPH_C32(0xadf40000), + SPH_C32(0x8f321eea), SPH_C32(0x24298307), SPH_C32(0xe8c49cf9), + SPH_C32(0x4b7eec55) }, + { SPH_C32(0x17310000), SPH_C32(0xac4a0000), SPH_C32(0x1313c780), + SPH_C32(0xbab10000), SPH_C32(0x812e78a6), SPH_C32(0xc5e20029), + SPH_C32(0x2a1523b7), SPH_C32(0x22363dd0), SPH_C32(0xf4780000), + SPH_C32(0x79310001), SPH_C32(0x56492280), SPH_C32(0x38070000), + SPH_C32(0xd29b36e8), SPH_C32(0x6cddbfbb), SPH_C32(0x0e9e3ed4), + SPH_C32(0xc5195baf) }, + { SPH_C32(0x5abb0000), SPH_C32(0xe57e0000), SPH_C32(0x2f98c280), + SPH_C32(0x14120000), SPH_C32(0x9757435b), SPH_C32(0x0a8d088d), + SPH_C32(0xa50cc95b), SPH_C32(0x660b0dd4), SPH_C32(0x386c0000), + SPH_C32(0xdc520001), SPH_C32(0x0cf02500), SPH_C32(0x03570000), + SPH_C32(0x994b2517), SPH_C32(0xeb468ba3), SPH_C32(0x67dd7615), + SPH_C32(0x0f43dc51) }, + { SPH_C32(0x96af0000), SPH_C32(0x401d0000), SPH_C32(0x7521c500), + SPH_C32(0x2f420000), SPH_C32(0xdc8750a4), SPH_C32(0x8d163c95), + SPH_C32(0xcc4f819a), SPH_C32(0xac518a2a), SPH_C32(0xb9f20000), + SPH_C32(0x30050001), SPH_C32(0x6ac22780), SPH_C32(0x96a40000), + SPH_C32(0xc4e20d15), SPH_C32(0xa3b2b71f), SPH_C32(0x8187d438), + SPH_C32(0x81246bab) }, + { SPH_C32(0xa3060000), SPH_C32(0x1bd50000), SPH_C32(0xe090cb80), + SPH_C32(0x11440000), SPH_C32(0xbbc04320), SPH_C32(0x3c90bd15), + SPH_C32(0xb3dacb14), SPH_C32(0x8b033185), SPH_C32(0x77490000), + SPH_C32(0x224e0001), SPH_C32(0x8a672300), SPH_C32(0xfb6c0000), + SPH_C32(0x35bf5b39), SPH_C32(0xa4614560), SPH_C32(0x41988863), + SPH_C32(0xbf88062e) }, + { SPH_C32(0x6f120000), SPH_C32(0xbeb60000), SPH_C32(0xba29cc00), + SPH_C32(0x2a140000), SPH_C32(0xf01050df), SPH_C32(0xbb0b890d), + SPH_C32(0xda9983d5), SPH_C32(0x4159b67b), SPH_C32(0xf6d70000), + SPH_C32(0xce190001), SPH_C32(0xec552180), SPH_C32(0x6e9f0000), + SPH_C32(0x6816733b), SPH_C32(0xec9579dc), SPH_C32(0xa7c22a4e), + SPH_C32(0x31efb1d4) }, + { SPH_C32(0x22980000), SPH_C32(0xf7820000), SPH_C32(0x86a2c900), + SPH_C32(0x84b70000), SPH_C32(0xe6696b22), SPH_C32(0x746481a9), + SPH_C32(0x55806939), SPH_C32(0x0564867f), SPH_C32(0x3ac30000), + SPH_C32(0x6b7a0001), SPH_C32(0xb6ec2600), SPH_C32(0x55cf0000), + SPH_C32(0x23c660c4), SPH_C32(0x6b0e4dc4), SPH_C32(0xce81628f), + SPH_C32(0xfbb5362a) }, + { SPH_C32(0xee8c0000), SPH_C32(0x52e10000), SPH_C32(0xdc1bce80), + SPH_C32(0xbfe70000), SPH_C32(0xadb978dd), SPH_C32(0xf3ffb5b1), + SPH_C32(0x3cc321f8), SPH_C32(0xcf3e0181), SPH_C32(0xbb5d0000), + SPH_C32(0x872d0001), SPH_C32(0xd0de2480), SPH_C32(0xc03c0000), + SPH_C32(0x7e6f48c6), SPH_C32(0x23fa7178), SPH_C32(0x28dbc0a2), + SPH_C32(0x75d281d0) }, + { SPH_C32(0xd98a0000), SPH_C32(0xbe010000), SPH_C32(0xf3b6c300), + SPH_C32(0xd7790000), SPH_C32(0x70732e8a), SPH_C32(0xc231f256), + SPH_C32(0xea0a7fec), SPH_C32(0x1c9a5055), SPH_C32(0x0f6a0000), + SPH_C32(0x30b20001), SPH_C32(0x235d2880), SPH_C32(0x6bc90000), + SPH_C32(0x44817340), SPH_C32(0xda88cc44), SPH_C32(0xb1142801), + SPH_C32(0xdce78d85) }, + { SPH_C32(0x159e0000), SPH_C32(0x1b620000), SPH_C32(0xa90fc480), + SPH_C32(0xec290000), SPH_C32(0x3ba33d75), SPH_C32(0x45aac64e), + SPH_C32(0x8349372d), SPH_C32(0xd6c0d7ab), SPH_C32(0x8ef40000), + SPH_C32(0xdce50001), SPH_C32(0x456f2a00), SPH_C32(0xfe3a0000), + SPH_C32(0x19285b42), SPH_C32(0x927cf0f8), SPH_C32(0x574e8a2c), + SPH_C32(0x52803a7f) }, + { SPH_C32(0x58140000), SPH_C32(0x52560000), SPH_C32(0x9584c180), + SPH_C32(0x428a0000), SPH_C32(0x2dda0688), SPH_C32(0x8ac5ceea), + SPH_C32(0x0c50ddc1), SPH_C32(0x92fde7af), SPH_C32(0x42e00000), + SPH_C32(0x79860001), SPH_C32(0x1fd62d80), SPH_C32(0xc56a0000), + SPH_C32(0x52f848bd), SPH_C32(0x15e7c4e0), SPH_C32(0x3e0dc2ed), + SPH_C32(0x98dabd81) }, + { SPH_C32(0x94000000), SPH_C32(0xf7350000), SPH_C32(0xcf3dc600), + SPH_C32(0x79da0000), SPH_C32(0x660a1577), SPH_C32(0x0d5efaf2), + SPH_C32(0x65139500), SPH_C32(0x58a76051), SPH_C32(0xc37e0000), + SPH_C32(0x95d10001), SPH_C32(0x79e42f00), SPH_C32(0x50990000), + SPH_C32(0x0f5160bf), SPH_C32(0x5d13f85c), SPH_C32(0xd85760c0), + SPH_C32(0x16bd0a7b) }, + { SPH_C32(0xa1a90000), SPH_C32(0xacfd0000), SPH_C32(0x5a8cc880), + SPH_C32(0x47dc0000), SPH_C32(0x014d06f3), SPH_C32(0xbcd87b72), + SPH_C32(0x1a86df8e), SPH_C32(0x7ff5dbfe), SPH_C32(0x0dc50000), + SPH_C32(0x879a0001), SPH_C32(0x99412b80), SPH_C32(0x3d510000), + SPH_C32(0xfe0c3693), SPH_C32(0x5ac00a23), SPH_C32(0x18483c9b), + SPH_C32(0x281167fe) }, + { SPH_C32(0x6dbd0000), SPH_C32(0x099e0000), SPH_C32(0x0035cf00), + SPH_C32(0x7c8c0000), SPH_C32(0x4a9d150c), SPH_C32(0x3b434f6a), + SPH_C32(0x73c5974f), SPH_C32(0xb5af5c00), SPH_C32(0x8c5b0000), + SPH_C32(0x6bcd0001), SPH_C32(0xff732900), SPH_C32(0xa8a20000), + SPH_C32(0xa3a51e91), SPH_C32(0x1234369f), SPH_C32(0xfe129eb6), + SPH_C32(0xa676d004) }, + { SPH_C32(0x20370000), SPH_C32(0x40aa0000), SPH_C32(0x3cbeca00), + SPH_C32(0xd22f0000), SPH_C32(0x5ce42ef1), SPH_C32(0xf42c47ce), + SPH_C32(0xfcdc7da3), SPH_C32(0xf1926c04), SPH_C32(0x404f0000), + SPH_C32(0xceae0001), SPH_C32(0xa5ca2e80), SPH_C32(0x93f20000), + SPH_C32(0xe8750d6e), SPH_C32(0x95af0287), SPH_C32(0x9751d677), + SPH_C32(0x6c2c57fa) }, + { SPH_C32(0xec230000), SPH_C32(0xe5c90000), SPH_C32(0x6607cd80), + SPH_C32(0xe97f0000), SPH_C32(0x17343d0e), SPH_C32(0x73b773d6), + SPH_C32(0x959f3562), SPH_C32(0x3bc8ebfa), SPH_C32(0xc1d10000), + SPH_C32(0x22f90001), SPH_C32(0xc3f82c00), SPH_C32(0x06010000), + SPH_C32(0xb5dc256c), SPH_C32(0xdd5b3e3b), SPH_C32(0x710b745a), + SPH_C32(0xe24be000) }, + { SPH_C32(0x776d0000), SPH_C32(0x128f0000), SPH_C32(0x0c51d380), + SPH_C32(0x82a20000), SPH_C32(0x907b5a33), SPH_C32(0x5dcb6487), + SPH_C32(0xbd24ac88), SPH_C32(0x7988c2d8), SPH_C32(0x6ba80000), + SPH_C32(0x4ba90001), SPH_C32(0x5d832180), SPH_C32(0xdad00000), + SPH_C32(0x63751974), SPH_C32(0xd089ea49), SPH_C32(0x256784eb), + SPH_C32(0xd3d4a53b) }, + { SPH_C32(0xbb790000), SPH_C32(0xb7ec0000), SPH_C32(0x56e8d400), + SPH_C32(0xb9f20000), SPH_C32(0xdbab49cc), SPH_C32(0xda50509f), + SPH_C32(0xd467e449), SPH_C32(0xb3d24526), SPH_C32(0xea360000), + SPH_C32(0xa7fe0001), SPH_C32(0x3bb12300), SPH_C32(0x4f230000), + SPH_C32(0x3edc3176), SPH_C32(0x987dd6f5), SPH_C32(0xc33d26c6), + SPH_C32(0x5db312c1) }, + { SPH_C32(0xf6f30000), SPH_C32(0xfed80000), SPH_C32(0x6a63d100), + SPH_C32(0x17510000), SPH_C32(0xcdd27231), SPH_C32(0x153f583b), + SPH_C32(0x5b7e0ea5), SPH_C32(0xf7ef7522), SPH_C32(0x26220000), + SPH_C32(0x029d0001), SPH_C32(0x61082480), SPH_C32(0x74730000), + SPH_C32(0x750c2289), SPH_C32(0x1fe6e2ed), SPH_C32(0xaa7e6e07), + SPH_C32(0x97e9953f) }, + { SPH_C32(0x3ae70000), SPH_C32(0x5bbb0000), SPH_C32(0x30dad680), + SPH_C32(0x2c010000), SPH_C32(0x860261ce), SPH_C32(0x92a46c23), + SPH_C32(0x323d4664), SPH_C32(0x3db5f2dc), SPH_C32(0xa7bc0000), + SPH_C32(0xeeca0001), SPH_C32(0x073a2600), SPH_C32(0xe1800000), + SPH_C32(0x28a50a8b), SPH_C32(0x5712de51), SPH_C32(0x4c24cc2a), + SPH_C32(0x198e22c5) }, + { SPH_C32(0x0f4e0000), SPH_C32(0x00730000), SPH_C32(0xa56bd800), + SPH_C32(0x12070000), SPH_C32(0xe145724a), SPH_C32(0x2322eda3), + SPH_C32(0x4da80cea), SPH_C32(0x1ae74973), SPH_C32(0x69070000), + SPH_C32(0xfc810001), SPH_C32(0xe79f2280), SPH_C32(0x8c480000), + SPH_C32(0xd9f85ca7), SPH_C32(0x50c12c2e), SPH_C32(0x8c3b9071), + SPH_C32(0x27224f40) }, + { SPH_C32(0xc35a0000), SPH_C32(0xa5100000), SPH_C32(0xffd2df80), + SPH_C32(0x29570000), SPH_C32(0xaa9561b5), SPH_C32(0xa4b9d9bb), + SPH_C32(0x24eb442b), SPH_C32(0xd0bdce8d), SPH_C32(0xe8990000), + SPH_C32(0x10d60001), SPH_C32(0x81ad2000), SPH_C32(0x19bb0000), + SPH_C32(0x845174a5), SPH_C32(0x18351092), SPH_C32(0x6a61325c), + SPH_C32(0xa945f8ba) }, + { SPH_C32(0x8ed00000), SPH_C32(0xec240000), SPH_C32(0xc359da80), + SPH_C32(0x87f40000), SPH_C32(0xbcec5a48), SPH_C32(0x6bd6d11f), + SPH_C32(0xabf2aec7), SPH_C32(0x9480fe89), SPH_C32(0x248d0000), + SPH_C32(0xb5b50001), SPH_C32(0xdb142780), SPH_C32(0x22eb0000), + SPH_C32(0xcf81675a), SPH_C32(0x9fae248a), SPH_C32(0x03227a9d), + SPH_C32(0x631f7f44) }, + { SPH_C32(0x42c40000), SPH_C32(0x49470000), SPH_C32(0x99e0dd00), + SPH_C32(0xbca40000), SPH_C32(0xf73c49b7), SPH_C32(0xec4de507), + SPH_C32(0xc2b1e606), SPH_C32(0x5eda7977), SPH_C32(0xa5130000), + SPH_C32(0x59e20001), SPH_C32(0xbd262500), SPH_C32(0xb7180000), + SPH_C32(0x92284f58), SPH_C32(0xd75a1836), SPH_C32(0xe578d8b0), + SPH_C32(0xed78c8be) }, + { SPH_C32(0x75c20000), SPH_C32(0xa5a70000), SPH_C32(0xb64dd080), + SPH_C32(0xd43a0000), SPH_C32(0x2af61fe0), SPH_C32(0xdd83a2e0), + SPH_C32(0x1478b812), SPH_C32(0x8d7e28a3), SPH_C32(0x11240000), + SPH_C32(0xee7d0001), SPH_C32(0x4ea52900), SPH_C32(0x1ced0000), + SPH_C32(0xa8c674de), SPH_C32(0x2e28a50a), SPH_C32(0x7cb73013), + SPH_C32(0x444dc4eb) }, + { SPH_C32(0xb9d60000), SPH_C32(0x00c40000), SPH_C32(0xecf4d700), + SPH_C32(0xef6a0000), SPH_C32(0x61260c1f), SPH_C32(0x5a1896f8), + SPH_C32(0x7d3bf0d3), SPH_C32(0x4724af5d), SPH_C32(0x90ba0000), + SPH_C32(0x022a0001), SPH_C32(0x28972b80), SPH_C32(0x891e0000), + SPH_C32(0xf56f5cdc), SPH_C32(0x66dc99b6), SPH_C32(0x9aed923e), + SPH_C32(0xca2a7311) }, + { SPH_C32(0xf45c0000), SPH_C32(0x49f00000), SPH_C32(0xd07fd200), + SPH_C32(0x41c90000), SPH_C32(0x775f37e2), SPH_C32(0x95779e5c), + SPH_C32(0xf2221a3f), SPH_C32(0x03199f59), SPH_C32(0x5cae0000), + SPH_C32(0xa7490001), SPH_C32(0x722e2c00), SPH_C32(0xb24e0000), + SPH_C32(0xbebf4f23), SPH_C32(0xe147adae), SPH_C32(0xf3aedaff), + SPH_C32(0x0070f4ef) }, + { SPH_C32(0x38480000), SPH_C32(0xec930000), SPH_C32(0x8ac6d580), + SPH_C32(0x7a990000), SPH_C32(0x3c8f241d), SPH_C32(0x12ecaa44), + SPH_C32(0x9b6152fe), SPH_C32(0xc94318a7), SPH_C32(0xdd300000), + SPH_C32(0x4b1e0001), SPH_C32(0x141c2e80), SPH_C32(0x27bd0000), + SPH_C32(0xe3166721), SPH_C32(0xa9b39112), SPH_C32(0x15f478d2), + SPH_C32(0x8e174315) }, + { SPH_C32(0x0de10000), SPH_C32(0xb75b0000), SPH_C32(0x1f77db00), + SPH_C32(0x449f0000), SPH_C32(0x5bc83799), SPH_C32(0xa36a2bc4), + SPH_C32(0xe4f41870), SPH_C32(0xee11a308), SPH_C32(0x138b0000), + SPH_C32(0x59550001), SPH_C32(0xf4b92a00), SPH_C32(0x4a750000), + SPH_C32(0x124b310d), SPH_C32(0xae60636d), SPH_C32(0xd5eb2489), + SPH_C32(0xb0bb2e90) }, + { SPH_C32(0xc1f50000), SPH_C32(0x12380000), SPH_C32(0x45cedc80), + SPH_C32(0x7fcf0000), SPH_C32(0x10182466), SPH_C32(0x24f11fdc), + SPH_C32(0x8db750b1), SPH_C32(0x244b24f6), SPH_C32(0x92150000), + SPH_C32(0xb5020001), SPH_C32(0x928b2880), SPH_C32(0xdf860000), + SPH_C32(0x4fe2190f), SPH_C32(0xe6945fd1), SPH_C32(0x33b186a4), + SPH_C32(0x3edc996a) }, + { SPH_C32(0x8c7f0000), SPH_C32(0x5b0c0000), SPH_C32(0x7945d980), + SPH_C32(0xd16c0000), SPH_C32(0x06611f9b), SPH_C32(0xeb9e1778), + SPH_C32(0x02aeba5d), SPH_C32(0x607614f2), SPH_C32(0x5e010000), + SPH_C32(0x10610001), SPH_C32(0xc8322f00), SPH_C32(0xe4d60000), + SPH_C32(0x04320af0), SPH_C32(0x610f6bc9), SPH_C32(0x5af2ce65), + SPH_C32(0xf4861e94) }, + { SPH_C32(0x406b0000), SPH_C32(0xfe6f0000), SPH_C32(0x23fcde00), + SPH_C32(0xea3c0000), SPH_C32(0x4db10c64), SPH_C32(0x6c052360), + SPH_C32(0x6bedf29c), SPH_C32(0xaa2c930c), SPH_C32(0xdf9f0000), + SPH_C32(0xfc360001), SPH_C32(0xae002d80), SPH_C32(0x71250000), + SPH_C32(0x599b22f2), SPH_C32(0x29fb5775), SPH_C32(0xbca86c48), + SPH_C32(0x7ae1a96e) }, + { SPH_C32(0xc56b0000), SPH_C32(0xd7e60000), SPH_C32(0x2452c180), + SPH_C32(0xf6c50000), SPH_C32(0x26b96cc7), SPH_C32(0xb6d95d7f), + SPH_C32(0x8ef57364), SPH_C32(0x70c6f340), SPH_C32(0xc7e00000), + SPH_C32(0x500f0001), SPH_C32(0x18783200), SPH_C32(0xd9930000), + SPH_C32(0x39f0281e), SPH_C32(0xcf3bbaff), SPH_C32(0xdb154315), + SPH_C32(0x4230ddcd) }, + { SPH_C32(0x097f0000), SPH_C32(0x72850000), SPH_C32(0x7eebc600), + SPH_C32(0xcd950000), SPH_C32(0x6d697f38), SPH_C32(0x31426967), + SPH_C32(0xe7b63ba5), SPH_C32(0xba9c74be), SPH_C32(0x467e0000), + SPH_C32(0xbc580001), SPH_C32(0x7e4a3080), SPH_C32(0x4c600000), + SPH_C32(0x6459001c), SPH_C32(0x87cf8643), SPH_C32(0x3d4fe138), + SPH_C32(0xcc576a37) }, + { SPH_C32(0x44f50000), SPH_C32(0x3bb10000), SPH_C32(0x4260c300), + SPH_C32(0x63360000), SPH_C32(0x7b1044c5), SPH_C32(0xfe2d61c3), + SPH_C32(0x68afd149), SPH_C32(0xfea144ba), SPH_C32(0x8a6a0000), + SPH_C32(0x193b0001), SPH_C32(0x24f33700), SPH_C32(0x77300000), + SPH_C32(0x2f8913e3), SPH_C32(0x0054b25b), SPH_C32(0x540ca9f9), + SPH_C32(0x060dedc9) }, + { SPH_C32(0x88e10000), SPH_C32(0x9ed20000), SPH_C32(0x18d9c480), + SPH_C32(0x58660000), SPH_C32(0x30c0573a), SPH_C32(0x79b655db), + SPH_C32(0x01ec9988), SPH_C32(0x34fbc344), SPH_C32(0x0bf40000), + SPH_C32(0xf56c0001), SPH_C32(0x42c13580), SPH_C32(0xe2c30000), + SPH_C32(0x72203be1), SPH_C32(0x48a08ee7), SPH_C32(0xb2560bd4), + SPH_C32(0x886a5a33) }, + { SPH_C32(0xbd480000), SPH_C32(0xc51a0000), SPH_C32(0x8d68ca00), + SPH_C32(0x66600000), SPH_C32(0x578744be), SPH_C32(0xc830d45b), + SPH_C32(0x7e79d306), SPH_C32(0x13a978eb), SPH_C32(0xc54f0000), + SPH_C32(0xe7270001), SPH_C32(0xa2643100), SPH_C32(0x8f0b0000), + SPH_C32(0x837d6dcd), SPH_C32(0x4f737c98), SPH_C32(0x7249578f), + SPH_C32(0xb6c637b6) }, + { SPH_C32(0x715c0000), SPH_C32(0x60790000), SPH_C32(0xd7d1cd80), + SPH_C32(0x5d300000), SPH_C32(0x1c575741), SPH_C32(0x4fabe043), + SPH_C32(0x173a9bc7), SPH_C32(0xd9f3ff15), SPH_C32(0x44d10000), + SPH_C32(0x0b700001), SPH_C32(0xc4563380), SPH_C32(0x1af80000), + SPH_C32(0xded445cf), SPH_C32(0x07874024), SPH_C32(0x9413f5a2), + SPH_C32(0x38a1804c) }, + { SPH_C32(0x3cd60000), SPH_C32(0x294d0000), SPH_C32(0xeb5ac880), + SPH_C32(0xf3930000), SPH_C32(0x0a2e6cbc), SPH_C32(0x80c4e8e7), + SPH_C32(0x9823712b), SPH_C32(0x9dcecf11), SPH_C32(0x88c50000), + SPH_C32(0xae130001), SPH_C32(0x9eef3400), SPH_C32(0x21a80000), + SPH_C32(0x95045630), SPH_C32(0x801c743c), SPH_C32(0xfd50bd63), + SPH_C32(0xf2fb07b2) }, + { SPH_C32(0xf0c20000), SPH_C32(0x8c2e0000), SPH_C32(0xb1e3cf00), + SPH_C32(0xc8c30000), SPH_C32(0x41fe7f43), SPH_C32(0x075fdcff), + SPH_C32(0xf16039ea), SPH_C32(0x579448ef), SPH_C32(0x095b0000), + SPH_C32(0x42440001), SPH_C32(0xf8dd3680), SPH_C32(0xb45b0000), + SPH_C32(0xc8ad7e32), SPH_C32(0xc8e84880), SPH_C32(0x1b0a1f4e), + SPH_C32(0x7c9cb048) }, + { SPH_C32(0xc7c40000), SPH_C32(0x60ce0000), SPH_C32(0x9e4ec280), + SPH_C32(0xa05d0000), SPH_C32(0x9c342914), SPH_C32(0x36919b18), + SPH_C32(0x27a967fe), SPH_C32(0x8430193b), SPH_C32(0xbd6c0000), + SPH_C32(0xf5db0001), SPH_C32(0x0b5e3a80), SPH_C32(0x1fae0000), + SPH_C32(0xf24345b4), SPH_C32(0x319af5bc), SPH_C32(0x82c5f7ed), + SPH_C32(0xd5a9bc1d) }, + { SPH_C32(0x0bd00000), SPH_C32(0xc5ad0000), SPH_C32(0xc4f7c500), + SPH_C32(0x9b0d0000), SPH_C32(0xd7e43aeb), SPH_C32(0xb10aaf00), + SPH_C32(0x4eea2f3f), SPH_C32(0x4e6a9ec5), SPH_C32(0x3cf20000), + SPH_C32(0x198c0001), SPH_C32(0x6d6c3800), SPH_C32(0x8a5d0000), + SPH_C32(0xafea6db6), SPH_C32(0x796ec900), SPH_C32(0x649f55c0), + SPH_C32(0x5bce0be7) }, + { SPH_C32(0x465a0000), SPH_C32(0x8c990000), SPH_C32(0xf87cc000), + SPH_C32(0x35ae0000), SPH_C32(0xc19d0116), SPH_C32(0x7e65a7a4), + SPH_C32(0xc1f3c5d3), SPH_C32(0x0a57aec1), SPH_C32(0xf0e60000), + SPH_C32(0xbcef0001), SPH_C32(0x37d53f80), SPH_C32(0xb10d0000), + SPH_C32(0xe43a7e49), SPH_C32(0xfef5fd18), SPH_C32(0x0ddc1d01), + SPH_C32(0x91948c19) }, + { SPH_C32(0x8a4e0000), SPH_C32(0x29fa0000), SPH_C32(0xa2c5c780), + SPH_C32(0x0efe0000), SPH_C32(0x8a4d12e9), SPH_C32(0xf9fe93bc), + SPH_C32(0xa8b08d12), SPH_C32(0xc00d293f), SPH_C32(0x71780000), + SPH_C32(0x50b80001), SPH_C32(0x51e73d00), SPH_C32(0x24fe0000), + SPH_C32(0xb993564b), SPH_C32(0xb601c1a4), SPH_C32(0xeb86bf2c), + SPH_C32(0x1ff33be3) }, + { SPH_C32(0xbfe70000), SPH_C32(0x72320000), SPH_C32(0x3774c900), + SPH_C32(0x30f80000), SPH_C32(0xed0a016d), SPH_C32(0x4878123c), + SPH_C32(0xd725c79c), SPH_C32(0xe75f9290), SPH_C32(0xbfc30000), + SPH_C32(0x42f30001), SPH_C32(0xb1423980), SPH_C32(0x49360000), + SPH_C32(0x48ce0067), SPH_C32(0xb1d233db), SPH_C32(0x2b99e377), + SPH_C32(0x215f5666) }, + { SPH_C32(0x73f30000), SPH_C32(0xd7510000), SPH_C32(0x6dcdce80), + SPH_C32(0x0ba80000), SPH_C32(0xa6da1292), SPH_C32(0xcfe32624), + SPH_C32(0xbe668f5d), SPH_C32(0x2d05156e), SPH_C32(0x3e5d0000), + SPH_C32(0xaea40001), SPH_C32(0xd7703b00), SPH_C32(0xdcc50000), + SPH_C32(0x15672865), SPH_C32(0xf9260f67), SPH_C32(0xcdc3415a), + SPH_C32(0xaf38e19c) }, + { SPH_C32(0x3e790000), SPH_C32(0x9e650000), SPH_C32(0x5146cb80), + SPH_C32(0xa50b0000), SPH_C32(0xb0a3296f), SPH_C32(0x008c2e80), + SPH_C32(0x317f65b1), SPH_C32(0x6938256a), SPH_C32(0xf2490000), + SPH_C32(0x0bc70001), SPH_C32(0x8dc93c80), SPH_C32(0xe7950000), + SPH_C32(0x5eb73b9a), SPH_C32(0x7ebd3b7f), SPH_C32(0xa480099b), + SPH_C32(0x65626662) }, + { SPH_C32(0xf26d0000), SPH_C32(0x3b060000), SPH_C32(0x0bffcc00), + SPH_C32(0x9e5b0000), SPH_C32(0xfb733a90), SPH_C32(0x87171a98), + SPH_C32(0x583c2d70), SPH_C32(0xa362a294), SPH_C32(0x73d70000), + SPH_C32(0xe7900001), SPH_C32(0xebfb3e00), SPH_C32(0x72660000), + SPH_C32(0x031e1398), SPH_C32(0x364907c3), SPH_C32(0x42daabb6), + SPH_C32(0xeb05d198) }, + { SPH_C32(0x69230000), SPH_C32(0xcc400000), SPH_C32(0x61a9d200), + SPH_C32(0xf5860000), SPH_C32(0x7c3c5dad), SPH_C32(0xa96b0dc9), + SPH_C32(0x7087b49a), SPH_C32(0xe1228bb6), SPH_C32(0xd9ae0000), + SPH_C32(0x8ec00001), SPH_C32(0x75803380), SPH_C32(0xaeb70000), + SPH_C32(0xd5b72f80), SPH_C32(0x3b9bd3b1), SPH_C32(0x16b65b07), + SPH_C32(0xda9a94a3) }, + { SPH_C32(0xa5370000), SPH_C32(0x69230000), SPH_C32(0x3b10d580), + SPH_C32(0xced60000), SPH_C32(0x37ec4e52), SPH_C32(0x2ef039d1), + SPH_C32(0x19c4fc5b), SPH_C32(0x2b780c48), SPH_C32(0x58300000), + SPH_C32(0x62970001), SPH_C32(0x13b23100), SPH_C32(0x3b440000), + SPH_C32(0x881e0782), SPH_C32(0x736fef0d), SPH_C32(0xf0ecf92a), + SPH_C32(0x54fd2359) }, + { SPH_C32(0xe8bd0000), SPH_C32(0x20170000), SPH_C32(0x079bd080), + SPH_C32(0x60750000), SPH_C32(0x219575af), SPH_C32(0xe19f3175), + SPH_C32(0x96dd16b7), SPH_C32(0x6f453c4c), SPH_C32(0x94240000), + SPH_C32(0xc7f40001), SPH_C32(0x490b3680), SPH_C32(0x00140000), + SPH_C32(0xc3ce147d), SPH_C32(0xf4f4db15), SPH_C32(0x99afb1eb), + SPH_C32(0x9ea7a4a7) }, + { SPH_C32(0x24a90000), SPH_C32(0x85740000), SPH_C32(0x5d22d700), + SPH_C32(0x5b250000), SPH_C32(0x6a456650), SPH_C32(0x6604056d), + SPH_C32(0xff9e5e76), SPH_C32(0xa51fbbb2), SPH_C32(0x15ba0000), + SPH_C32(0x2ba30001), SPH_C32(0x2f393400), SPH_C32(0x95e70000), + SPH_C32(0x9e673c7f), SPH_C32(0xbc00e7a9), SPH_C32(0x7ff513c6), + SPH_C32(0x10c0135d) }, + { SPH_C32(0x11000000), SPH_C32(0xdebc0000), SPH_C32(0xc893d980), + SPH_C32(0x65230000), SPH_C32(0x0d0275d4), SPH_C32(0xd78284ed), + SPH_C32(0x800b14f8), SPH_C32(0x824d001d), SPH_C32(0xdb010000), + SPH_C32(0x39e80001), SPH_C32(0xcf9c3080), SPH_C32(0xf82f0000), + SPH_C32(0x6f3a6a53), SPH_C32(0xbbd315d6), SPH_C32(0xbfea4f9d), + SPH_C32(0x2e6c7ed8) }, + { SPH_C32(0xdd140000), SPH_C32(0x7bdf0000), SPH_C32(0x922ade00), + SPH_C32(0x5e730000), SPH_C32(0x46d2662b), SPH_C32(0x5019b0f5), + SPH_C32(0xe9485c39), SPH_C32(0x481787e3), SPH_C32(0x5a9f0000), + SPH_C32(0xd5bf0001), SPH_C32(0xa9ae3200), SPH_C32(0x6ddc0000), + SPH_C32(0x32934251), SPH_C32(0xf327296a), SPH_C32(0x59b0edb0), + SPH_C32(0xa00bc922) }, + { SPH_C32(0x909e0000), SPH_C32(0x32eb0000), SPH_C32(0xaea1db00), + SPH_C32(0xf0d00000), SPH_C32(0x50ab5dd6), SPH_C32(0x9f76b851), + SPH_C32(0x6651b6d5), SPH_C32(0x0c2ab7e7), SPH_C32(0x968b0000), + SPH_C32(0x70dc0001), SPH_C32(0xf3173580), SPH_C32(0x568c0000), + SPH_C32(0x794351ae), SPH_C32(0x74bc1d72), SPH_C32(0x30f3a571), + SPH_C32(0x6a514edc) }, + { SPH_C32(0x5c8a0000), SPH_C32(0x97880000), SPH_C32(0xf418dc80), + SPH_C32(0xcb800000), SPH_C32(0x1b7b4e29), SPH_C32(0x18ed8c49), + SPH_C32(0x0f12fe14), SPH_C32(0xc6703019), SPH_C32(0x17150000), + SPH_C32(0x9c8b0001), SPH_C32(0x95253700), SPH_C32(0xc37f0000), + SPH_C32(0x24ea79ac), SPH_C32(0x3c4821ce), SPH_C32(0xd6a9075c), + SPH_C32(0xe436f926) }, + { SPH_C32(0x6b8c0000), SPH_C32(0x7b680000), SPH_C32(0xdbb5d100), + SPH_C32(0xa31e0000), SPH_C32(0xc6b1187e), SPH_C32(0x2923cbae), + SPH_C32(0xd9dba000), SPH_C32(0x15d461cd), SPH_C32(0xa3220000), + SPH_C32(0x2b140001), SPH_C32(0x66a63b00), SPH_C32(0x688a0000), + SPH_C32(0x1e04422a), SPH_C32(0xc53a9cf2), SPH_C32(0x4f66efff), + SPH_C32(0x4d03f573) }, + { SPH_C32(0xa7980000), SPH_C32(0xde0b0000), SPH_C32(0x810cd680), + SPH_C32(0x984e0000), SPH_C32(0x8d610b81), SPH_C32(0xaeb8ffb6), + SPH_C32(0xb098e8c1), SPH_C32(0xdf8ee633), SPH_C32(0x22bc0000), + SPH_C32(0xc7430001), SPH_C32(0x00943980), SPH_C32(0xfd790000), + SPH_C32(0x43ad6a28), SPH_C32(0x8dcea04e), SPH_C32(0xa93c4dd2), + SPH_C32(0xc3644289) }, + { SPH_C32(0xea120000), SPH_C32(0x973f0000), SPH_C32(0xbd87d380), + SPH_C32(0x36ed0000), SPH_C32(0x9b18307c), SPH_C32(0x61d7f712), + SPH_C32(0x3f81022d), SPH_C32(0x9bb3d637), SPH_C32(0xeea80000), + SPH_C32(0x62200001), SPH_C32(0x5a2d3e00), SPH_C32(0xc6290000), + SPH_C32(0x087d79d7), SPH_C32(0x0a559456), SPH_C32(0xc07f0513), + SPH_C32(0x093ec577) }, + { SPH_C32(0x26060000), SPH_C32(0x325c0000), SPH_C32(0xe73ed400), + SPH_C32(0x0dbd0000), SPH_C32(0xd0c82383), SPH_C32(0xe64cc30a), + SPH_C32(0x56c24aec), SPH_C32(0x51e951c9), SPH_C32(0x6f360000), + SPH_C32(0x8e770001), SPH_C32(0x3c1f3c80), SPH_C32(0x53da0000), + SPH_C32(0x55d451d5), SPH_C32(0x42a1a8ea), SPH_C32(0x2625a73e), + SPH_C32(0x8759728d) }, + { SPH_C32(0x13af0000), SPH_C32(0x69940000), SPH_C32(0x728fda80), + SPH_C32(0x33bb0000), SPH_C32(0xb78f3007), SPH_C32(0x57ca428a), + SPH_C32(0x29570062), SPH_C32(0x76bbea66), SPH_C32(0xa18d0000), + SPH_C32(0x9c3c0001), SPH_C32(0xdcba3800), SPH_C32(0x3e120000), + SPH_C32(0xa48907f9), SPH_C32(0x45725a95), SPH_C32(0xe63afb65), + SPH_C32(0xb9f51f08) }, + { SPH_C32(0xdfbb0000), SPH_C32(0xccf70000), SPH_C32(0x2836dd00), + SPH_C32(0x08eb0000), SPH_C32(0xfc5f23f8), SPH_C32(0xd0517692), + SPH_C32(0x401448a3), SPH_C32(0xbce16d98), SPH_C32(0x20130000), + SPH_C32(0x706b0001), SPH_C32(0xba883a80), SPH_C32(0xabe10000), + SPH_C32(0xf9202ffb), SPH_C32(0x0d866629), SPH_C32(0x00605948), + SPH_C32(0x3792a8f2) }, + { SPH_C32(0x92310000), SPH_C32(0x85c30000), SPH_C32(0x14bdd800), + SPH_C32(0xa6480000), SPH_C32(0xea261805), SPH_C32(0x1f3e7e36), + SPH_C32(0xcf0da24f), SPH_C32(0xf8dc5d9c), SPH_C32(0xec070000), + SPH_C32(0xd5080001), SPH_C32(0xe0313d00), SPH_C32(0x90b10000), + SPH_C32(0xb2f03c04), SPH_C32(0x8a1d5231), SPH_C32(0x69231189), + SPH_C32(0xfdc82f0c) }, + { SPH_C32(0x5e250000), SPH_C32(0x20a00000), SPH_C32(0x4e04df80), + SPH_C32(0x9d180000), SPH_C32(0xa1f60bfa), SPH_C32(0x98a54a2e), + SPH_C32(0xa64eea8e), SPH_C32(0x3286da62), SPH_C32(0x6d990000), + SPH_C32(0x395f0001), SPH_C32(0x86033f80), SPH_C32(0x05420000), + SPH_C32(0xef591406), SPH_C32(0xc2e96e8d), SPH_C32(0x8f79b3a4), + SPH_C32(0x73af98f6) }, + { SPH_C32(0x75e60000), SPH_C32(0x95660001), SPH_C32(0x307b2000), + SPH_C32(0xadf40000), SPH_C32(0x8f321eea), SPH_C32(0x24298307), + SPH_C32(0xe8c49cf9), SPH_C32(0x4b7eec55), SPH_C32(0xaec30000), + SPH_C32(0x9c4f0001), SPH_C32(0x79d1e000), SPH_C32(0x2c150000), + SPH_C32(0x45cc75b3), SPH_C32(0x6650b736), SPH_C32(0xab92f78f), + SPH_C32(0xa312567b) }, + { SPH_C32(0xb9f20000), SPH_C32(0x30050001), SPH_C32(0x6ac22780), + SPH_C32(0x96a40000), SPH_C32(0xc4e20d15), SPH_C32(0xa3b2b71f), + SPH_C32(0x8187d438), SPH_C32(0x81246bab), SPH_C32(0x2f5d0000), + SPH_C32(0x70180001), SPH_C32(0x1fe3e280), SPH_C32(0xb9e60000), + SPH_C32(0x18655db1), SPH_C32(0x2ea48b8a), SPH_C32(0x4dc855a2), + SPH_C32(0x2d75e181) }, + { SPH_C32(0xf4780000), SPH_C32(0x79310001), SPH_C32(0x56492280), + SPH_C32(0x38070000), SPH_C32(0xd29b36e8), SPH_C32(0x6cddbfbb), + SPH_C32(0x0e9e3ed4), SPH_C32(0xc5195baf), SPH_C32(0xe3490000), + SPH_C32(0xd57b0001), SPH_C32(0x455ae500), SPH_C32(0x82b60000), + SPH_C32(0x53b54e4e), SPH_C32(0xa93fbf92), SPH_C32(0x248b1d63), + SPH_C32(0xe72f667f) }, + { SPH_C32(0x386c0000), SPH_C32(0xdc520001), SPH_C32(0x0cf02500), + SPH_C32(0x03570000), SPH_C32(0x994b2517), SPH_C32(0xeb468ba3), + SPH_C32(0x67dd7615), SPH_C32(0x0f43dc51), SPH_C32(0x62d70000), + SPH_C32(0x392c0001), SPH_C32(0x2368e780), SPH_C32(0x17450000), + SPH_C32(0x0e1c664c), SPH_C32(0xe1cb832e), SPH_C32(0xc2d1bf4e), + SPH_C32(0x6948d185) }, + { SPH_C32(0x0dc50000), SPH_C32(0x879a0001), SPH_C32(0x99412b80), + SPH_C32(0x3d510000), SPH_C32(0xfe0c3693), SPH_C32(0x5ac00a23), + SPH_C32(0x18483c9b), SPH_C32(0x281167fe), SPH_C32(0xac6c0000), + SPH_C32(0x2b670001), SPH_C32(0xc3cde300), SPH_C32(0x7a8d0000), + SPH_C32(0xff413060), SPH_C32(0xe6187151), SPH_C32(0x02cee315), + SPH_C32(0x57e4bc00) }, + { SPH_C32(0xc1d10000), SPH_C32(0x22f90001), SPH_C32(0xc3f82c00), + SPH_C32(0x06010000), SPH_C32(0xb5dc256c), SPH_C32(0xdd5b3e3b), + SPH_C32(0x710b745a), SPH_C32(0xe24be000), SPH_C32(0x2df20000), + SPH_C32(0xc7300001), SPH_C32(0xa5ffe180), SPH_C32(0xef7e0000), + SPH_C32(0xa2e81862), SPH_C32(0xaeec4ded), SPH_C32(0xe4944138), + SPH_C32(0xd9830bfa) }, + { SPH_C32(0x8c5b0000), SPH_C32(0x6bcd0001), SPH_C32(0xff732900), + SPH_C32(0xa8a20000), SPH_C32(0xa3a51e91), SPH_C32(0x1234369f), + SPH_C32(0xfe129eb6), SPH_C32(0xa676d004), SPH_C32(0xe1e60000), + SPH_C32(0x62530001), SPH_C32(0xff46e600), SPH_C32(0xd42e0000), + SPH_C32(0xe9380b9d), SPH_C32(0x297779f5), SPH_C32(0x8dd709f9), + SPH_C32(0x13d98c04) }, + { SPH_C32(0x404f0000), SPH_C32(0xceae0001), SPH_C32(0xa5ca2e80), + SPH_C32(0x93f20000), SPH_C32(0xe8750d6e), SPH_C32(0x95af0287), + SPH_C32(0x9751d677), SPH_C32(0x6c2c57fa), SPH_C32(0x60780000), + SPH_C32(0x8e040001), SPH_C32(0x9974e480), SPH_C32(0x41dd0000), + SPH_C32(0xb491239f), SPH_C32(0x61834549), SPH_C32(0x6b8dabd4), + SPH_C32(0x9dbe3bfe) }, + { SPH_C32(0x77490000), SPH_C32(0x224e0001), SPH_C32(0x8a672300), + SPH_C32(0xfb6c0000), SPH_C32(0x35bf5b39), SPH_C32(0xa4614560), + SPH_C32(0x41988863), SPH_C32(0xbf88062e), SPH_C32(0xd44f0000), + SPH_C32(0x399b0001), SPH_C32(0x6af7e880), SPH_C32(0xea280000), + SPH_C32(0x8e7f1819), SPH_C32(0x98f1f875), SPH_C32(0xf2424377), + SPH_C32(0x348b37ab) }, + { SPH_C32(0xbb5d0000), SPH_C32(0x872d0001), SPH_C32(0xd0de2480), + SPH_C32(0xc03c0000), SPH_C32(0x7e6f48c6), SPH_C32(0x23fa7178), + SPH_C32(0x28dbc0a2), SPH_C32(0x75d281d0), SPH_C32(0x55d10000), + SPH_C32(0xd5cc0001), SPH_C32(0x0cc5ea00), SPH_C32(0x7fdb0000), + SPH_C32(0xd3d6301b), SPH_C32(0xd005c4c9), SPH_C32(0x1418e15a), + SPH_C32(0xbaec8051) }, + { SPH_C32(0xf6d70000), SPH_C32(0xce190001), SPH_C32(0xec552180), + SPH_C32(0x6e9f0000), SPH_C32(0x6816733b), SPH_C32(0xec9579dc), + SPH_C32(0xa7c22a4e), SPH_C32(0x31efb1d4), SPH_C32(0x99c50000), + SPH_C32(0x70af0001), SPH_C32(0x567ced80), SPH_C32(0x448b0000), + SPH_C32(0x980623e4), SPH_C32(0x579ef0d1), SPH_C32(0x7d5ba99b), + SPH_C32(0x70b607af) }, + { SPH_C32(0x3ac30000), SPH_C32(0x6b7a0001), SPH_C32(0xb6ec2600), + SPH_C32(0x55cf0000), SPH_C32(0x23c660c4), SPH_C32(0x6b0e4dc4), + SPH_C32(0xce81628f), SPH_C32(0xfbb5362a), SPH_C32(0x185b0000), + SPH_C32(0x9cf80001), SPH_C32(0x304eef00), SPH_C32(0xd1780000), + SPH_C32(0xc5af0be6), SPH_C32(0x1f6acc6d), SPH_C32(0x9b010bb6), + SPH_C32(0xfed1b055) }, + { SPH_C32(0x0f6a0000), SPH_C32(0x30b20001), SPH_C32(0x235d2880), + SPH_C32(0x6bc90000), SPH_C32(0x44817340), SPH_C32(0xda88cc44), + SPH_C32(0xb1142801), SPH_C32(0xdce78d85), SPH_C32(0xd6e00000), + SPH_C32(0x8eb30001), SPH_C32(0xd0ebeb80), SPH_C32(0xbcb00000), + SPH_C32(0x34f25dca), SPH_C32(0x18b93e12), SPH_C32(0x5b1e57ed), + SPH_C32(0xc07dddd0) }, + { SPH_C32(0xc37e0000), SPH_C32(0x95d10001), SPH_C32(0x79e42f00), + SPH_C32(0x50990000), SPH_C32(0x0f5160bf), SPH_C32(0x5d13f85c), + SPH_C32(0xd85760c0), SPH_C32(0x16bd0a7b), SPH_C32(0x577e0000), + SPH_C32(0x62e40001), SPH_C32(0xb6d9e900), SPH_C32(0x29430000), + SPH_C32(0x695b75c8), SPH_C32(0x504d02ae), SPH_C32(0xbd44f5c0), + SPH_C32(0x4e1a6a2a) }, + { SPH_C32(0x8ef40000), SPH_C32(0xdce50001), SPH_C32(0x456f2a00), + SPH_C32(0xfe3a0000), SPH_C32(0x19285b42), SPH_C32(0x927cf0f8), + SPH_C32(0x574e8a2c), SPH_C32(0x52803a7f), SPH_C32(0x9b6a0000), + SPH_C32(0xc7870001), SPH_C32(0xec60ee80), SPH_C32(0x12130000), + SPH_C32(0x228b6637), SPH_C32(0xd7d636b6), SPH_C32(0xd407bd01), + SPH_C32(0x8440edd4) }, + { SPH_C32(0x42e00000), SPH_C32(0x79860001), SPH_C32(0x1fd62d80), + SPH_C32(0xc56a0000), SPH_C32(0x52f848bd), SPH_C32(0x15e7c4e0), + SPH_C32(0x3e0dc2ed), SPH_C32(0x98dabd81), SPH_C32(0x1af40000), + SPH_C32(0x2bd00001), SPH_C32(0x8a52ec00), SPH_C32(0x87e00000), + SPH_C32(0x7f224e35), SPH_C32(0x9f220a0a), SPH_C32(0x325d1f2c), + SPH_C32(0x0a275a2e) }, + { SPH_C32(0xd9ae0000), SPH_C32(0x8ec00001), SPH_C32(0x75803380), + SPH_C32(0xaeb70000), SPH_C32(0xd5b72f80), SPH_C32(0x3b9bd3b1), + SPH_C32(0x16b65b07), SPH_C32(0xda9a94a3), SPH_C32(0xb08d0000), + SPH_C32(0x42800001), SPH_C32(0x1429e180), SPH_C32(0x5b310000), + SPH_C32(0xa98b722d), SPH_C32(0x92f0de78), SPH_C32(0x6631ef9d), + SPH_C32(0x3bb81f15) }, + { SPH_C32(0x15ba0000), SPH_C32(0x2ba30001), SPH_C32(0x2f393400), + SPH_C32(0x95e70000), SPH_C32(0x9e673c7f), SPH_C32(0xbc00e7a9), + SPH_C32(0x7ff513c6), SPH_C32(0x10c0135d), SPH_C32(0x31130000), + SPH_C32(0xaed70001), SPH_C32(0x721be300), SPH_C32(0xcec20000), + SPH_C32(0xf4225a2f), SPH_C32(0xda04e2c4), SPH_C32(0x806b4db0), + SPH_C32(0xb5dfa8ef) }, + { SPH_C32(0x58300000), SPH_C32(0x62970001), SPH_C32(0x13b23100), + SPH_C32(0x3b440000), SPH_C32(0x881e0782), SPH_C32(0x736fef0d), + SPH_C32(0xf0ecf92a), SPH_C32(0x54fd2359), SPH_C32(0xfd070000), + SPH_C32(0x0bb40001), SPH_C32(0x28a2e480), SPH_C32(0xf5920000), + SPH_C32(0xbff249d0), SPH_C32(0x5d9fd6dc), SPH_C32(0xe9280571), + SPH_C32(0x7f852f11) }, + { SPH_C32(0x94240000), SPH_C32(0xc7f40001), SPH_C32(0x490b3680), + SPH_C32(0x00140000), SPH_C32(0xc3ce147d), SPH_C32(0xf4f4db15), + SPH_C32(0x99afb1eb), SPH_C32(0x9ea7a4a7), SPH_C32(0x7c990000), + SPH_C32(0xe7e30001), SPH_C32(0x4e90e600), SPH_C32(0x60610000), + SPH_C32(0xe25b61d2), SPH_C32(0x156bea60), SPH_C32(0x0f72a75c), + SPH_C32(0xf1e298eb) }, + { SPH_C32(0xa18d0000), SPH_C32(0x9c3c0001), SPH_C32(0xdcba3800), + SPH_C32(0x3e120000), SPH_C32(0xa48907f9), SPH_C32(0x45725a95), + SPH_C32(0xe63afb65), SPH_C32(0xb9f51f08), SPH_C32(0xb2220000), + SPH_C32(0xf5a80001), SPH_C32(0xae35e280), SPH_C32(0x0da90000), + SPH_C32(0x130637fe), SPH_C32(0x12b8181f), SPH_C32(0xcf6dfb07), + SPH_C32(0xcf4ef56e) }, + { SPH_C32(0x6d990000), SPH_C32(0x395f0001), SPH_C32(0x86033f80), + SPH_C32(0x05420000), SPH_C32(0xef591406), SPH_C32(0xc2e96e8d), + SPH_C32(0x8f79b3a4), SPH_C32(0x73af98f6), SPH_C32(0x33bc0000), + SPH_C32(0x19ff0001), SPH_C32(0xc807e000), SPH_C32(0x985a0000), + SPH_C32(0x4eaf1ffc), SPH_C32(0x5a4c24a3), SPH_C32(0x2937592a), + SPH_C32(0x41294294) }, + { SPH_C32(0x20130000), SPH_C32(0x706b0001), SPH_C32(0xba883a80), + SPH_C32(0xabe10000), SPH_C32(0xf9202ffb), SPH_C32(0x0d866629), + SPH_C32(0x00605948), SPH_C32(0x3792a8f2), SPH_C32(0xffa80000), + SPH_C32(0xbc9c0001), SPH_C32(0x92bee780), SPH_C32(0xa30a0000), + SPH_C32(0x057f0c03), SPH_C32(0xddd710bb), SPH_C32(0x407411eb), + SPH_C32(0x8b73c56a) }, + { SPH_C32(0xec070000), SPH_C32(0xd5080001), SPH_C32(0xe0313d00), + SPH_C32(0x90b10000), SPH_C32(0xb2f03c04), SPH_C32(0x8a1d5231), + SPH_C32(0x69231189), SPH_C32(0xfdc82f0c), SPH_C32(0x7e360000), + SPH_C32(0x50cb0001), SPH_C32(0xf48ce500), SPH_C32(0x36f90000), + SPH_C32(0x58d62401), SPH_C32(0x95232c07), SPH_C32(0xa62eb3c6), + SPH_C32(0x05147290) }, + { SPH_C32(0xdb010000), SPH_C32(0x39e80001), SPH_C32(0xcf9c3080), + SPH_C32(0xf82f0000), SPH_C32(0x6f3a6a53), SPH_C32(0xbbd315d6), + SPH_C32(0xbfea4f9d), SPH_C32(0x2e6c7ed8), SPH_C32(0xca010000), + SPH_C32(0xe7540001), SPH_C32(0x070fe900), SPH_C32(0x9d0c0000), + SPH_C32(0x62381f87), SPH_C32(0x6c51913b), SPH_C32(0x3fe15b65), + SPH_C32(0xac217ec5) }, + { SPH_C32(0x17150000), SPH_C32(0x9c8b0001), SPH_C32(0x95253700), + SPH_C32(0xc37f0000), SPH_C32(0x24ea79ac), SPH_C32(0x3c4821ce), + SPH_C32(0xd6a9075c), SPH_C32(0xe436f926), SPH_C32(0x4b9f0000), + SPH_C32(0x0b030001), SPH_C32(0x613deb80), SPH_C32(0x08ff0000), + SPH_C32(0x3f913785), SPH_C32(0x24a5ad87), SPH_C32(0xd9bbf948), + SPH_C32(0x2246c93f) }, + { SPH_C32(0x5a9f0000), SPH_C32(0xd5bf0001), SPH_C32(0xa9ae3200), + SPH_C32(0x6ddc0000), SPH_C32(0x32934251), SPH_C32(0xf327296a), + SPH_C32(0x59b0edb0), SPH_C32(0xa00bc922), SPH_C32(0x878b0000), + SPH_C32(0xae600001), SPH_C32(0x3b84ec00), SPH_C32(0x33af0000), + SPH_C32(0x7441247a), SPH_C32(0xa33e999f), SPH_C32(0xb0f8b189), + SPH_C32(0xe81c4ec1) }, + { SPH_C32(0x968b0000), SPH_C32(0x70dc0001), SPH_C32(0xf3173580), + SPH_C32(0x568c0000), SPH_C32(0x794351ae), SPH_C32(0x74bc1d72), + SPH_C32(0x30f3a571), SPH_C32(0x6a514edc), SPH_C32(0x06150000), + SPH_C32(0x42370001), SPH_C32(0x5db6ee80), SPH_C32(0xa65c0000), + SPH_C32(0x29e80c78), SPH_C32(0xebcaa523), SPH_C32(0x56a213a4), + SPH_C32(0x667bf93b) }, + { SPH_C32(0xa3220000), SPH_C32(0x2b140001), SPH_C32(0x66a63b00), + SPH_C32(0x688a0000), SPH_C32(0x1e04422a), SPH_C32(0xc53a9cf2), + SPH_C32(0x4f66efff), SPH_C32(0x4d03f573), SPH_C32(0xc8ae0000), + SPH_C32(0x507c0001), SPH_C32(0xbd13ea00), SPH_C32(0xcb940000), + SPH_C32(0xd8b55a54), SPH_C32(0xec19575c), SPH_C32(0x96bd4fff), + SPH_C32(0x58d794be) }, + { SPH_C32(0x6f360000), SPH_C32(0x8e770001), SPH_C32(0x3c1f3c80), + SPH_C32(0x53da0000), SPH_C32(0x55d451d5), SPH_C32(0x42a1a8ea), + SPH_C32(0x2625a73e), SPH_C32(0x8759728d), SPH_C32(0x49300000), + SPH_C32(0xbc2b0001), SPH_C32(0xdb21e880), SPH_C32(0x5e670000), + SPH_C32(0x851c7256), SPH_C32(0xa4ed6be0), SPH_C32(0x70e7edd2), + SPH_C32(0xd6b02344) }, + { SPH_C32(0x22bc0000), SPH_C32(0xc7430001), SPH_C32(0x00943980), + SPH_C32(0xfd790000), SPH_C32(0x43ad6a28), SPH_C32(0x8dcea04e), + SPH_C32(0xa93c4dd2), SPH_C32(0xc3644289), SPH_C32(0x85240000), + SPH_C32(0x19480001), SPH_C32(0x8198ef00), SPH_C32(0x65370000), + SPH_C32(0xcecc61a9), SPH_C32(0x23765ff8), SPH_C32(0x19a4a513), + SPH_C32(0x1ceaa4ba) }, + { SPH_C32(0xeea80000), SPH_C32(0x62200001), SPH_C32(0x5a2d3e00), + SPH_C32(0xc6290000), SPH_C32(0x087d79d7), SPH_C32(0x0a559456), + SPH_C32(0xc07f0513), SPH_C32(0x093ec577), SPH_C32(0x04ba0000), + SPH_C32(0xf51f0001), SPH_C32(0xe7aaed80), SPH_C32(0xf0c40000), + SPH_C32(0x936549ab), SPH_C32(0x6b826344), SPH_C32(0xfffe073e), + SPH_C32(0x928d1340) }, + { SPH_C32(0x6ba80000), SPH_C32(0x4ba90001), SPH_C32(0x5d832180), + SPH_C32(0xdad00000), SPH_C32(0x63751974), SPH_C32(0xd089ea49), + SPH_C32(0x256784eb), SPH_C32(0xd3d4a53b), SPH_C32(0x1cc50000), + SPH_C32(0x59260001), SPH_C32(0x51d2f200), SPH_C32(0x58720000), + SPH_C32(0xf30e4347), SPH_C32(0x8d428ece), SPH_C32(0x98432863), + SPH_C32(0xaa5c67e3) }, + { SPH_C32(0xa7bc0000), SPH_C32(0xeeca0001), SPH_C32(0x073a2600), + SPH_C32(0xe1800000), SPH_C32(0x28a50a8b), SPH_C32(0x5712de51), + SPH_C32(0x4c24cc2a), SPH_C32(0x198e22c5), SPH_C32(0x9d5b0000), + SPH_C32(0xb5710001), SPH_C32(0x37e0f080), SPH_C32(0xcd810000), + SPH_C32(0xaea76b45), SPH_C32(0xc5b6b272), SPH_C32(0x7e198a4e), + SPH_C32(0x243bd019) }, + { SPH_C32(0xea360000), SPH_C32(0xa7fe0001), SPH_C32(0x3bb12300), + SPH_C32(0x4f230000), SPH_C32(0x3edc3176), SPH_C32(0x987dd6f5), + SPH_C32(0xc33d26c6), SPH_C32(0x5db312c1), SPH_C32(0x514f0000), + SPH_C32(0x10120001), SPH_C32(0x6d59f700), SPH_C32(0xf6d10000), + SPH_C32(0xe57778ba), SPH_C32(0x422d866a), SPH_C32(0x175ac28f), + SPH_C32(0xee6157e7) }, + { SPH_C32(0x26220000), SPH_C32(0x029d0001), SPH_C32(0x61082480), + SPH_C32(0x74730000), SPH_C32(0x750c2289), SPH_C32(0x1fe6e2ed), + SPH_C32(0xaa7e6e07), SPH_C32(0x97e9953f), SPH_C32(0xd0d10000), + SPH_C32(0xfc450001), SPH_C32(0x0b6bf580), SPH_C32(0x63220000), + SPH_C32(0xb8de50b8), SPH_C32(0x0ad9bad6), SPH_C32(0xf10060a2), + SPH_C32(0x6006e01d) }, + { SPH_C32(0x138b0000), SPH_C32(0x59550001), SPH_C32(0xf4b92a00), + SPH_C32(0x4a750000), SPH_C32(0x124b310d), SPH_C32(0xae60636d), + SPH_C32(0xd5eb2489), SPH_C32(0xb0bb2e90), SPH_C32(0x1e6a0000), + SPH_C32(0xee0e0001), SPH_C32(0xebcef100), SPH_C32(0x0eea0000), + SPH_C32(0x49830694), SPH_C32(0x0d0a48a9), SPH_C32(0x311f3cf9), + SPH_C32(0x5eaa8d98) }, + { SPH_C32(0xdf9f0000), SPH_C32(0xfc360001), SPH_C32(0xae002d80), + SPH_C32(0x71250000), SPH_C32(0x599b22f2), SPH_C32(0x29fb5775), + SPH_C32(0xbca86c48), SPH_C32(0x7ae1a96e), SPH_C32(0x9ff40000), + SPH_C32(0x02590001), SPH_C32(0x8dfcf380), SPH_C32(0x9b190000), + SPH_C32(0x142a2e96), SPH_C32(0x45fe7415), SPH_C32(0xd7459ed4), + SPH_C32(0xd0cd3a62) }, + { SPH_C32(0x92150000), SPH_C32(0xb5020001), SPH_C32(0x928b2880), + SPH_C32(0xdf860000), SPH_C32(0x4fe2190f), SPH_C32(0xe6945fd1), + SPH_C32(0x33b186a4), SPH_C32(0x3edc996a), SPH_C32(0x53e00000), + SPH_C32(0xa73a0001), SPH_C32(0xd745f400), SPH_C32(0xa0490000), + SPH_C32(0x5ffa3d69), SPH_C32(0xc265400d), SPH_C32(0xbe06d615), + SPH_C32(0x1a97bd9c) }, + { SPH_C32(0x5e010000), SPH_C32(0x10610001), SPH_C32(0xc8322f00), + SPH_C32(0xe4d60000), SPH_C32(0x04320af0), SPH_C32(0x610f6bc9), + SPH_C32(0x5af2ce65), SPH_C32(0xf4861e94), SPH_C32(0xd27e0000), + SPH_C32(0x4b6d0001), SPH_C32(0xb177f680), SPH_C32(0x35ba0000), + SPH_C32(0x0253156b), SPH_C32(0x8a917cb1), SPH_C32(0x585c7438), + SPH_C32(0x94f00a66) }, + { SPH_C32(0x69070000), SPH_C32(0xfc810001), SPH_C32(0xe79f2280), + SPH_C32(0x8c480000), SPH_C32(0xd9f85ca7), SPH_C32(0x50c12c2e), + SPH_C32(0x8c3b9071), SPH_C32(0x27224f40), SPH_C32(0x66490000), + SPH_C32(0xfcf20001), SPH_C32(0x42f4fa80), SPH_C32(0x9e4f0000), + SPH_C32(0x38bd2eed), SPH_C32(0x73e3c18d), SPH_C32(0xc1939c9b), + SPH_C32(0x3dc50633) }, + { SPH_C32(0xa5130000), SPH_C32(0x59e20001), SPH_C32(0xbd262500), + SPH_C32(0xb7180000), SPH_C32(0x92284f58), SPH_C32(0xd75a1836), + SPH_C32(0xe578d8b0), SPH_C32(0xed78c8be), SPH_C32(0xe7d70000), + SPH_C32(0x10a50001), SPH_C32(0x24c6f800), SPH_C32(0x0bbc0000), + SPH_C32(0x651406ef), SPH_C32(0x3b17fd31), SPH_C32(0x27c93eb6), + SPH_C32(0xb3a2b1c9) }, + { SPH_C32(0xe8990000), SPH_C32(0x10d60001), SPH_C32(0x81ad2000), + SPH_C32(0x19bb0000), SPH_C32(0x845174a5), SPH_C32(0x18351092), + SPH_C32(0x6a61325c), SPH_C32(0xa945f8ba), SPH_C32(0x2bc30000), + SPH_C32(0xb5c60001), SPH_C32(0x7e7fff80), SPH_C32(0x30ec0000), + SPH_C32(0x2ec41510), SPH_C32(0xbc8cc929), SPH_C32(0x4e8a7677), + SPH_C32(0x79f83637) }, + { SPH_C32(0x248d0000), SPH_C32(0xb5b50001), SPH_C32(0xdb142780), + SPH_C32(0x22eb0000), SPH_C32(0xcf81675a), SPH_C32(0x9fae248a), + SPH_C32(0x03227a9d), SPH_C32(0x631f7f44), SPH_C32(0xaa5d0000), + SPH_C32(0x59910001), SPH_C32(0x184dfd00), SPH_C32(0xa51f0000), + SPH_C32(0x736d3d12), SPH_C32(0xf478f595), SPH_C32(0xa8d0d45a), + SPH_C32(0xf79f81cd) }, + { SPH_C32(0x11240000), SPH_C32(0xee7d0001), SPH_C32(0x4ea52900), + SPH_C32(0x1ced0000), SPH_C32(0xa8c674de), SPH_C32(0x2e28a50a), + SPH_C32(0x7cb73013), SPH_C32(0x444dc4eb), SPH_C32(0x64e60000), + SPH_C32(0x4bda0001), SPH_C32(0xf8e8f980), SPH_C32(0xc8d70000), + SPH_C32(0x82306b3e), SPH_C32(0xf3ab07ea), SPH_C32(0x68cf8801), + SPH_C32(0xc933ec48) }, + { SPH_C32(0xdd300000), SPH_C32(0x4b1e0001), SPH_C32(0x141c2e80), + SPH_C32(0x27bd0000), SPH_C32(0xe3166721), SPH_C32(0xa9b39112), + SPH_C32(0x15f478d2), SPH_C32(0x8e174315), SPH_C32(0xe5780000), + SPH_C32(0xa78d0001), SPH_C32(0x9edafb00), SPH_C32(0x5d240000), + SPH_C32(0xdf99433c), SPH_C32(0xbb5f3b56), SPH_C32(0x8e952a2c), + SPH_C32(0x47545bb2) }, + { SPH_C32(0x90ba0000), SPH_C32(0x022a0001), SPH_C32(0x28972b80), + SPH_C32(0x891e0000), SPH_C32(0xf56f5cdc), SPH_C32(0x66dc99b6), + SPH_C32(0x9aed923e), SPH_C32(0xca2a7311), SPH_C32(0x296c0000), + SPH_C32(0x02ee0001), SPH_C32(0xc463fc80), SPH_C32(0x66740000), + SPH_C32(0x944950c3), SPH_C32(0x3cc40f4e), SPH_C32(0xe7d662ed), + SPH_C32(0x8d0edc4c) }, + { SPH_C32(0x5cae0000), SPH_C32(0xa7490001), SPH_C32(0x722e2c00), + SPH_C32(0xb24e0000), SPH_C32(0xbebf4f23), SPH_C32(0xe147adae), + SPH_C32(0xf3aedaff), SPH_C32(0x0070f4ef), SPH_C32(0xa8f20000), + SPH_C32(0xeeb90001), SPH_C32(0xa251fe00), SPH_C32(0xf3870000), + SPH_C32(0xc9e078c1), SPH_C32(0x743033f2), SPH_C32(0x018cc0c0), + SPH_C32(0x03696bb6) }, + { SPH_C32(0xc7e00000), SPH_C32(0x500f0001), SPH_C32(0x18783200), + SPH_C32(0xd9930000), SPH_C32(0x39f0281e), SPH_C32(0xcf3bbaff), + SPH_C32(0xdb154315), SPH_C32(0x4230ddcd), SPH_C32(0x028b0000), + SPH_C32(0x87e90001), SPH_C32(0x3c2af380), SPH_C32(0x2f560000), + SPH_C32(0x1f4944d9), SPH_C32(0x79e2e780), SPH_C32(0x55e03071), + SPH_C32(0x32f62e8d) }, + { SPH_C32(0x0bf40000), SPH_C32(0xf56c0001), SPH_C32(0x42c13580), + SPH_C32(0xe2c30000), SPH_C32(0x72203be1), SPH_C32(0x48a08ee7), + SPH_C32(0xb2560bd4), SPH_C32(0x886a5a33), SPH_C32(0x83150000), + SPH_C32(0x6bbe0001), SPH_C32(0x5a18f100), SPH_C32(0xbaa50000), + SPH_C32(0x42e06cdb), SPH_C32(0x3116db3c), SPH_C32(0xb3ba925c), + SPH_C32(0xbc919977) }, + { SPH_C32(0x467e0000), SPH_C32(0xbc580001), SPH_C32(0x7e4a3080), + SPH_C32(0x4c600000), SPH_C32(0x6459001c), SPH_C32(0x87cf8643), + SPH_C32(0x3d4fe138), SPH_C32(0xcc576a37), SPH_C32(0x4f010000), + SPH_C32(0xcedd0001), SPH_C32(0x00a1f680), SPH_C32(0x81f50000), + SPH_C32(0x09307f24), SPH_C32(0xb68def24), SPH_C32(0xdaf9da9d), + SPH_C32(0x76cb1e89) }, + { SPH_C32(0x8a6a0000), SPH_C32(0x193b0001), SPH_C32(0x24f33700), + SPH_C32(0x77300000), SPH_C32(0x2f8913e3), SPH_C32(0x0054b25b), + SPH_C32(0x540ca9f9), SPH_C32(0x060dedc9), SPH_C32(0xce9f0000), + SPH_C32(0x228a0001), SPH_C32(0x6693f400), SPH_C32(0x14060000), + SPH_C32(0x54995726), SPH_C32(0xfe79d398), SPH_C32(0x3ca378b0), + SPH_C32(0xf8aca973) }, + { SPH_C32(0xbfc30000), SPH_C32(0x42f30001), SPH_C32(0xb1423980), + SPH_C32(0x49360000), SPH_C32(0x48ce0067), SPH_C32(0xb1d233db), + SPH_C32(0x2b99e377), SPH_C32(0x215f5666), SPH_C32(0x00240000), + SPH_C32(0x30c10001), SPH_C32(0x8636f080), SPH_C32(0x79ce0000), + SPH_C32(0xa5c4010a), SPH_C32(0xf9aa21e7), SPH_C32(0xfcbc24eb), + SPH_C32(0xc600c4f6) }, + { SPH_C32(0x73d70000), SPH_C32(0xe7900001), SPH_C32(0xebfb3e00), + SPH_C32(0x72660000), SPH_C32(0x031e1398), SPH_C32(0x364907c3), + SPH_C32(0x42daabb6), SPH_C32(0xeb05d198), SPH_C32(0x81ba0000), + SPH_C32(0xdc960001), SPH_C32(0xe004f200), SPH_C32(0xec3d0000), + SPH_C32(0xf86d2908), SPH_C32(0xb15e1d5b), SPH_C32(0x1ae686c6), + SPH_C32(0x4867730c) }, + { SPH_C32(0x3e5d0000), SPH_C32(0xaea40001), SPH_C32(0xd7703b00), + SPH_C32(0xdcc50000), SPH_C32(0x15672865), SPH_C32(0xf9260f67), + SPH_C32(0xcdc3415a), SPH_C32(0xaf38e19c), SPH_C32(0x4dae0000), + SPH_C32(0x79f50001), SPH_C32(0xbabdf580), SPH_C32(0xd76d0000), + SPH_C32(0xb3bd3af7), SPH_C32(0x36c52943), SPH_C32(0x73a5ce07), + SPH_C32(0x823df4f2) }, + { SPH_C32(0xf2490000), SPH_C32(0x0bc70001), SPH_C32(0x8dc93c80), + SPH_C32(0xe7950000), SPH_C32(0x5eb73b9a), SPH_C32(0x7ebd3b7f), + SPH_C32(0xa480099b), SPH_C32(0x65626662), SPH_C32(0xcc300000), + SPH_C32(0x95a20001), SPH_C32(0xdc8ff700), SPH_C32(0x429e0000), + SPH_C32(0xee1412f5), SPH_C32(0x7e3115ff), SPH_C32(0x95ff6c2a), + SPH_C32(0x0c5a4308) }, + { SPH_C32(0xc54f0000), SPH_C32(0xe7270001), SPH_C32(0xa2643100), + SPH_C32(0x8f0b0000), SPH_C32(0x837d6dcd), SPH_C32(0x4f737c98), + SPH_C32(0x7249578f), SPH_C32(0xb6c637b6), SPH_C32(0x78070000), + SPH_C32(0x223d0001), SPH_C32(0x2f0cfb00), SPH_C32(0xe96b0000), + SPH_C32(0xd4fa2973), SPH_C32(0x8743a8c3), SPH_C32(0x0c308489), + SPH_C32(0xa56f4f5d) }, + { SPH_C32(0x095b0000), SPH_C32(0x42440001), SPH_C32(0xf8dd3680), + SPH_C32(0xb45b0000), SPH_C32(0xc8ad7e32), SPH_C32(0xc8e84880), + SPH_C32(0x1b0a1f4e), SPH_C32(0x7c9cb048), SPH_C32(0xf9990000), + SPH_C32(0xce6a0001), SPH_C32(0x493ef980), SPH_C32(0x7c980000), + SPH_C32(0x89530171), SPH_C32(0xcfb7947f), SPH_C32(0xea6a26a4), + SPH_C32(0x2b08f8a7) }, + { SPH_C32(0x44d10000), SPH_C32(0x0b700001), SPH_C32(0xc4563380), + SPH_C32(0x1af80000), SPH_C32(0xded445cf), SPH_C32(0x07874024), + SPH_C32(0x9413f5a2), SPH_C32(0x38a1804c), SPH_C32(0x358d0000), + SPH_C32(0x6b090001), SPH_C32(0x1387fe00), SPH_C32(0x47c80000), + SPH_C32(0xc283128e), SPH_C32(0x482ca067), SPH_C32(0x83296e65), + SPH_C32(0xe1527f59) }, + { SPH_C32(0x88c50000), SPH_C32(0xae130001), SPH_C32(0x9eef3400), + SPH_C32(0x21a80000), SPH_C32(0x95045630), SPH_C32(0x801c743c), + SPH_C32(0xfd50bd63), SPH_C32(0xf2fb07b2), SPH_C32(0xb4130000), + SPH_C32(0x875e0001), SPH_C32(0x75b5fc80), SPH_C32(0xd23b0000), + SPH_C32(0x9f2a3a8c), SPH_C32(0x00d89cdb), SPH_C32(0x6573cc48), + SPH_C32(0x6f35c8a3) }, + { SPH_C32(0xbd6c0000), SPH_C32(0xf5db0001), SPH_C32(0x0b5e3a80), + SPH_C32(0x1fae0000), SPH_C32(0xf24345b4), SPH_C32(0x319af5bc), + SPH_C32(0x82c5f7ed), SPH_C32(0xd5a9bc1d), SPH_C32(0x7aa80000), + SPH_C32(0x95150001), SPH_C32(0x9510f800), SPH_C32(0xbff30000), + SPH_C32(0x6e776ca0), SPH_C32(0x070b6ea4), SPH_C32(0xa56c9013), + SPH_C32(0x5199a526) }, + { SPH_C32(0x71780000), SPH_C32(0x50b80001), SPH_C32(0x51e73d00), + SPH_C32(0x24fe0000), SPH_C32(0xb993564b), SPH_C32(0xb601c1a4), + SPH_C32(0xeb86bf2c), SPH_C32(0x1ff33be3), SPH_C32(0xfb360000), + SPH_C32(0x79420001), SPH_C32(0xf322fa80), SPH_C32(0x2a000000), + SPH_C32(0x33de44a2), SPH_C32(0x4fff5218), SPH_C32(0x4336323e), + SPH_C32(0xdffe12dc) }, + { SPH_C32(0x3cf20000), SPH_C32(0x198c0001), SPH_C32(0x6d6c3800), + SPH_C32(0x8a5d0000), SPH_C32(0xafea6db6), SPH_C32(0x796ec900), + SPH_C32(0x649f55c0), SPH_C32(0x5bce0be7), SPH_C32(0x37220000), + SPH_C32(0xdc210001), SPH_C32(0xa99bfd00), SPH_C32(0x11500000), + SPH_C32(0x780e575d), SPH_C32(0xc8646600), SPH_C32(0x2a757aff), + SPH_C32(0x15a49522) }, + { SPH_C32(0xf0e60000), SPH_C32(0xbcef0001), SPH_C32(0x37d53f80), + SPH_C32(0xb10d0000), SPH_C32(0xe43a7e49), SPH_C32(0xfef5fd18), + SPH_C32(0x0ddc1d01), SPH_C32(0x91948c19), SPH_C32(0xb6bc0000), + SPH_C32(0x30760001), SPH_C32(0xcfa9ff80), SPH_C32(0x84a30000), + SPH_C32(0x25a77f5f), SPH_C32(0x80905abc), SPH_C32(0xcc2fd8d2), + SPH_C32(0x9bc322d8) } +}; + +static const sph_u32 T512_40[256][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x58430000), SPH_C32(0x807e0000), SPH_C32(0x78330001), + SPH_C32(0xc66b3800), SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), + SPH_C32(0xac73fe6f), SPH_C32(0x3a4479b1), SPH_C32(0x1d5a0000), + SPH_C32(0x2b720000), SPH_C32(0x488d0000), SPH_C32(0xaf611800), + SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), SPH_C32(0x81a20429), + SPH_C32(0x1e7536a6) }, + { SPH_C32(0x1d5a0000), SPH_C32(0x2b720000), SPH_C32(0x488d0000), + SPH_C32(0xaf611800), SPH_C32(0x25cb2ec5), SPH_C32(0xc879bfd0), + SPH_C32(0x81a20429), SPH_C32(0x1e7536a6), SPH_C32(0x45190000), + SPH_C32(0xab0c0000), SPH_C32(0x30be0001), SPH_C32(0x690a2000), + SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), SPH_C32(0x2dd1fa46), + SPH_C32(0x24314f17) }, + { SPH_C32(0x45190000), SPH_C32(0xab0c0000), SPH_C32(0x30be0001), + SPH_C32(0x690a2000), SPH_C32(0xc2fc7219), SPH_C32(0xb1d4800d), + SPH_C32(0x2dd1fa46), SPH_C32(0x24314f17), SPH_C32(0x58430000), + SPH_C32(0x807e0000), SPH_C32(0x78330001), SPH_C32(0xc66b3800), + SPH_C32(0xe7375cdc), SPH_C32(0x79ad3fdd), SPH_C32(0xac73fe6f), + SPH_C32(0x3a4479b1) }, + { SPH_C32(0xa53b0000), SPH_C32(0x14260000), SPH_C32(0x4e30001e), + SPH_C32(0x7cae0000), SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), + SPH_C32(0xf73168d8), SPH_C32(0x0b1b4946), SPH_C32(0x07ed0000), + SPH_C32(0xb2500000), SPH_C32(0x8774000a), SPH_C32(0x970d0000), + SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), SPH_C32(0xf4786222), + SPH_C32(0x9075b1ce) }, + { SPH_C32(0xfd780000), SPH_C32(0x94580000), SPH_C32(0x3603001f), + SPH_C32(0xbac53800), SPH_C32(0x68a95109), SPH_C32(0x017295e0), + SPH_C32(0x5b4296b7), SPH_C32(0x315f30f7), SPH_C32(0x1ab70000), + SPH_C32(0x99220000), SPH_C32(0xcff9000a), SPH_C32(0x386c1800), + SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), SPH_C32(0x75da660b), + SPH_C32(0x8e008768) }, + { SPH_C32(0xb8610000), SPH_C32(0x3f540000), SPH_C32(0x06bd001e), + SPH_C32(0xd3cf1800), SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), + SPH_C32(0x76936cf1), SPH_C32(0x156e7fe0), SPH_C32(0x42f40000), + SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), SPH_C32(0xfe072000), + SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), SPH_C32(0xd9a99864), + SPH_C32(0xb444fed9) }, + { SPH_C32(0xe0220000), SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), + SPH_C32(0x15a42000), SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), + SPH_C32(0xdae0929e), SPH_C32(0x2f2a0651), SPH_C32(0x5fae0000), + SPH_C32(0x322e0000), SPH_C32(0xff47000b), SPH_C32(0x51663800), + SPH_C32(0xa4457f72), SPH_C32(0x316a5179), SPH_C32(0x580b9c4d), + SPH_C32(0xaa31c87f) }, + { SPH_C32(0x07ed0000), SPH_C32(0xb2500000), SPH_C32(0x8774000a), + SPH_C32(0x970d0000), SPH_C32(0x437223ae), SPH_C32(0x48c76ea4), + SPH_C32(0xf4786222), SPH_C32(0x9075b1ce), SPH_C32(0xa2d60000), + SPH_C32(0xa6760000), SPH_C32(0xc9440014), SPH_C32(0xeba30000), + SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), SPH_C32(0x03490afa), + SPH_C32(0x9b6ef888) }, + { SPH_C32(0x5fae0000), SPH_C32(0x322e0000), SPH_C32(0xff47000b), + SPH_C32(0x51663800), SPH_C32(0xa4457f72), SPH_C32(0x316a5179), + SPH_C32(0x580b9c4d), SPH_C32(0xaa31c87f), SPH_C32(0xbf8c0000), + SPH_C32(0x8d040000), SPH_C32(0x81c90014), SPH_C32(0x44c21800), + SPH_C32(0xe92700be), SPH_C32(0xf8617b49), SPH_C32(0x82eb0ed3), + SPH_C32(0x851bce2e) }, + { SPH_C32(0x1ab70000), SPH_C32(0x99220000), SPH_C32(0xcff9000a), + SPH_C32(0x386c1800), SPH_C32(0x66b90d6b), SPH_C32(0x80bed174), + SPH_C32(0x75da660b), SPH_C32(0x8e008768), SPH_C32(0xe7cf0000), + SPH_C32(0x0d7a0000), SPH_C32(0xf9fa0015), SPH_C32(0x82a92000), + SPH_C32(0x0e105c62), SPH_C32(0x81cc4494), SPH_C32(0x2e98f0bc), + SPH_C32(0xbf5fb79f) }, + { SPH_C32(0x42f40000), SPH_C32(0x195c0000), SPH_C32(0xb7ca000b), + SPH_C32(0xfe072000), SPH_C32(0x818e51b7), SPH_C32(0xf913eea9), + SPH_C32(0xd9a99864), SPH_C32(0xb444fed9), SPH_C32(0xfa950000), + SPH_C32(0x26080000), SPH_C32(0xb1770015), SPH_C32(0x2dc83800), + SPH_C32(0x2bdb72a7), SPH_C32(0x49b5fb44), SPH_C32(0xaf3af495), + SPH_C32(0xa12a8139) }, + { SPH_C32(0xa2d60000), SPH_C32(0xa6760000), SPH_C32(0xc9440014), + SPH_C32(0xeba30000), SPH_C32(0xccec2e7b), SPH_C32(0x3018c499), + SPH_C32(0x03490afa), SPH_C32(0x9b6ef888), SPH_C32(0xa53b0000), + SPH_C32(0x14260000), SPH_C32(0x4e30001e), SPH_C32(0x7cae0000), + SPH_C32(0x8f9e0dd5), SPH_C32(0x78dfaa3d), SPH_C32(0xf73168d8), + SPH_C32(0x0b1b4946) }, + { SPH_C32(0xfa950000), SPH_C32(0x26080000), SPH_C32(0xb1770015), + SPH_C32(0x2dc83800), SPH_C32(0x2bdb72a7), SPH_C32(0x49b5fb44), + SPH_C32(0xaf3af495), SPH_C32(0xa12a8139), SPH_C32(0xb8610000), + SPH_C32(0x3f540000), SPH_C32(0x06bd001e), SPH_C32(0xd3cf1800), + SPH_C32(0xaa552310), SPH_C32(0xb0a615ed), SPH_C32(0x76936cf1), + SPH_C32(0x156e7fe0) }, + { SPH_C32(0xbf8c0000), SPH_C32(0x8d040000), SPH_C32(0x81c90014), + SPH_C32(0x44c21800), SPH_C32(0xe92700be), SPH_C32(0xf8617b49), + SPH_C32(0x82eb0ed3), SPH_C32(0x851bce2e), SPH_C32(0xe0220000), + SPH_C32(0xbf2a0000), SPH_C32(0x7e8e001f), SPH_C32(0x15a42000), + SPH_C32(0x4d627fcc), SPH_C32(0xc90b2a30), SPH_C32(0xdae0929e), + SPH_C32(0x2f2a0651) }, + { SPH_C32(0xe7cf0000), SPH_C32(0x0d7a0000), SPH_C32(0xf9fa0015), + SPH_C32(0x82a92000), SPH_C32(0x0e105c62), SPH_C32(0x81cc4494), + SPH_C32(0x2e98f0bc), SPH_C32(0xbf5fb79f), SPH_C32(0xfd780000), + SPH_C32(0x94580000), SPH_C32(0x3603001f), SPH_C32(0xbac53800), + SPH_C32(0x68a95109), SPH_C32(0x017295e0), SPH_C32(0x5b4296b7), + SPH_C32(0x315f30f7) }, + { SPH_C32(0x88980000), SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), + SPH_C32(0xfb4e0000), SPH_C32(0xf158079a), SPH_C32(0x61ae9167), + SPH_C32(0xa895706c), SPH_C32(0xe6107494), SPH_C32(0x0bc20000), + SPH_C32(0xdb630000), SPH_C32(0x7e88000c), SPH_C32(0x15860000), + SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), SPH_C32(0xf460449e), + SPH_C32(0xd8b61463) }, + { SPH_C32(0xd0db0000), SPH_C32(0x9fea0000), SPH_C32(0x07fc002f), + SPH_C32(0x3d253800), SPH_C32(0x166f5b46), SPH_C32(0x1803aeba), + SPH_C32(0x04e68e03), SPH_C32(0xdc540d25), SPH_C32(0x16980000), + SPH_C32(0xf0110000), SPH_C32(0x3605000c), SPH_C32(0xbae71800), + SPH_C32(0xb4366636), SPH_C32(0xbdf80493), SPH_C32(0x75c240b7), + SPH_C32(0xc6c322c5) }, + { SPH_C32(0x95c20000), SPH_C32(0x34e60000), SPH_C32(0x3742002e), + SPH_C32(0x542f1800), SPH_C32(0xd493295f), SPH_C32(0xa9d72eb7), + SPH_C32(0x29377445), SPH_C32(0xf8654232), SPH_C32(0x4edb0000), + SPH_C32(0x706f0000), SPH_C32(0x4e36000d), SPH_C32(0x7c8c2000), + SPH_C32(0x53013aea), SPH_C32(0xc4553b4e), SPH_C32(0xd9b1bed8), + SPH_C32(0xfc875b74) }, + { SPH_C32(0xcd810000), SPH_C32(0xb4980000), SPH_C32(0x4f71002f), + SPH_C32(0x92442000), SPH_C32(0x33a47583), SPH_C32(0xd07a116a), + SPH_C32(0x85448a2a), SPH_C32(0xc2213b83), SPH_C32(0x53810000), + SPH_C32(0x5b1d0000), SPH_C32(0x06bb000d), SPH_C32(0xd3ed3800), + SPH_C32(0x76ca142f), SPH_C32(0x0c2c849e), SPH_C32(0x5813baf1), + SPH_C32(0xe2f26dd2) }, + { SPH_C32(0x2da30000), SPH_C32(0x0bb20000), SPH_C32(0x31ff0030), + SPH_C32(0x87e00000), SPH_C32(0x7ec60a4f), SPH_C32(0x19713b5a), + SPH_C32(0x5fa418b4), SPH_C32(0xed0b3dd2), SPH_C32(0x0c2f0000), + SPH_C32(0x69330000), SPH_C32(0xf9fc0006), SPH_C32(0x828b0000), + SPH_C32(0xd28f6b5d), SPH_C32(0x3d46d5e7), SPH_C32(0x001826bc), + SPH_C32(0x48c3a5ad) }, + { SPH_C32(0x75e00000), SPH_C32(0x8bcc0000), SPH_C32(0x49cc0031), + SPH_C32(0x418b3800), SPH_C32(0x99f15693), SPH_C32(0x60dc0487), + SPH_C32(0xf3d7e6db), SPH_C32(0xd74f4463), SPH_C32(0x11750000), + SPH_C32(0x42410000), SPH_C32(0xb1710006), SPH_C32(0x2dea1800), + SPH_C32(0xf7444598), SPH_C32(0xf53f6a37), SPH_C32(0x81ba2295), + SPH_C32(0x56b6930b) }, + { SPH_C32(0x30f90000), SPH_C32(0x20c00000), SPH_C32(0x79720030), + SPH_C32(0x28811800), SPH_C32(0x5b0d248a), SPH_C32(0xd108848a), + SPH_C32(0xde061c9d), SPH_C32(0xf37e0b74), SPH_C32(0x49360000), + SPH_C32(0xc23f0000), SPH_C32(0xc9420007), SPH_C32(0xeb812000), + SPH_C32(0x10731944), SPH_C32(0x8c9255ea), SPH_C32(0x2dc9dcfa), + SPH_C32(0x6cf2eaba) }, + { SPH_C32(0x68ba0000), SPH_C32(0xa0be0000), SPH_C32(0x01410031), + SPH_C32(0xeeea2000), SPH_C32(0xbc3a7856), SPH_C32(0xa8a5bb57), + SPH_C32(0x7275e2f2), SPH_C32(0xc93a72c5), SPH_C32(0x546c0000), + SPH_C32(0xe94d0000), SPH_C32(0x81cf0007), SPH_C32(0x44e03800), + SPH_C32(0x35b83781), SPH_C32(0x44ebea3a), SPH_C32(0xac6bd8d3), + SPH_C32(0x7287dc1c) }, + { SPH_C32(0x8f750000), SPH_C32(0xadc40000), SPH_C32(0xf8bb0024), + SPH_C32(0x6c430000), SPH_C32(0xb22a2434), SPH_C32(0x2969ffc3), + SPH_C32(0x5ced124e), SPH_C32(0x7665c55a), SPH_C32(0xa9140000), + SPH_C32(0x7d150000), SPH_C32(0xb7cc0018), SPH_C32(0xfe250000), + SPH_C32(0x5d116688), SPH_C32(0x45997fda), SPH_C32(0xf7294e64), + SPH_C32(0x43d8eceb) }, + { SPH_C32(0xd7360000), SPH_C32(0x2dba0000), SPH_C32(0x80880025), + SPH_C32(0xaa283800), SPH_C32(0x551d78e8), SPH_C32(0x50c4c01e), + SPH_C32(0xf09eec21), SPH_C32(0x4c21bceb), SPH_C32(0xb44e0000), + SPH_C32(0x56670000), SPH_C32(0xff410018), SPH_C32(0x51441800), + SPH_C32(0x78da484d), SPH_C32(0x8de0c00a), SPH_C32(0x768b4a4d), + SPH_C32(0x5dadda4d) }, + { SPH_C32(0x922f0000), SPH_C32(0x86b60000), SPH_C32(0xb0360024), + SPH_C32(0xc3221800), SPH_C32(0x97e10af1), SPH_C32(0xe1104013), + SPH_C32(0xdd4f1667), SPH_C32(0x6810f3fc), SPH_C32(0xec0d0000), + SPH_C32(0xd6190000), SPH_C32(0x87720019), SPH_C32(0x972f2000), + SPH_C32(0x9fed1491), SPH_C32(0xf44dffd7), SPH_C32(0xdaf8b422), + SPH_C32(0x67e9a3fc) }, + { SPH_C32(0xca6c0000), SPH_C32(0x06c80000), SPH_C32(0xc8050025), + SPH_C32(0x05492000), SPH_C32(0x70d6562d), SPH_C32(0x98bd7fce), + SPH_C32(0x713ce808), SPH_C32(0x52548a4d), SPH_C32(0xf1570000), + SPH_C32(0xfd6b0000), SPH_C32(0xcfff0019), SPH_C32(0x384e3800), + SPH_C32(0xba263a54), SPH_C32(0x3c344007), SPH_C32(0x5b5ab00b), + SPH_C32(0x799c955a) }, + { SPH_C32(0x2a4e0000), SPH_C32(0xb9e20000), SPH_C32(0xb68b003a), + SPH_C32(0x10ed0000), SPH_C32(0x3db429e1), SPH_C32(0x51b655fe), + SPH_C32(0xabdc7a96), SPH_C32(0x7d7e8c1c), SPH_C32(0xaef90000), + SPH_C32(0xcf450000), SPH_C32(0x30b80012), SPH_C32(0x69280000), + SPH_C32(0x1e634526), SPH_C32(0x0d5e117e), SPH_C32(0x03512c46), + SPH_C32(0xd3ad5d25) }, + { SPH_C32(0x720d0000), SPH_C32(0x399c0000), SPH_C32(0xceb8003b), + SPH_C32(0xd6863800), SPH_C32(0xda83753d), SPH_C32(0x281b6a23), + SPH_C32(0x07af84f9), SPH_C32(0x473af5ad), SPH_C32(0xb3a30000), + SPH_C32(0xe4370000), SPH_C32(0x78350012), SPH_C32(0xc6491800), + SPH_C32(0x3ba86be3), SPH_C32(0xc527aeae), SPH_C32(0x82f3286f), + SPH_C32(0xcdd86b83) }, + { SPH_C32(0x37140000), SPH_C32(0x92900000), SPH_C32(0xfe06003a), + SPH_C32(0xbf8c1800), SPH_C32(0x187f0724), SPH_C32(0x99cfea2e), + SPH_C32(0x2a7e7ebf), SPH_C32(0x630bbaba), SPH_C32(0xebe00000), + SPH_C32(0x64490000), SPH_C32(0x00060013), SPH_C32(0x00222000), + SPH_C32(0xdc9f373f), SPH_C32(0xbc8a9173), SPH_C32(0x2e80d600), + SPH_C32(0xf79c1232) }, + { SPH_C32(0x6f570000), SPH_C32(0x12ee0000), SPH_C32(0x8635003b), + SPH_C32(0x79e72000), SPH_C32(0xff485bf8), SPH_C32(0xe062d5f3), + SPH_C32(0x860d80d0), SPH_C32(0x594fc30b), SPH_C32(0xf6ba0000), + SPH_C32(0x4f3b0000), SPH_C32(0x488b0013), SPH_C32(0xaf433800), + SPH_C32(0xf95419fa), SPH_C32(0x74f32ea3), SPH_C32(0xaf22d229), + SPH_C32(0xe9e92494) }, + { SPH_C32(0x0bc20000), SPH_C32(0xdb630000), SPH_C32(0x7e88000c), + SPH_C32(0x15860000), SPH_C32(0x91fd48f3), SPH_C32(0x7581bb43), + SPH_C32(0xf460449e), SPH_C32(0xd8b61463), SPH_C32(0x835a0000), + SPH_C32(0xc4f70000), SPH_C32(0x01470022), SPH_C32(0xeec80000), + SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), SPH_C32(0x5cf534f2), + SPH_C32(0x3ea660f7) }, + { SPH_C32(0x53810000), SPH_C32(0x5b1d0000), SPH_C32(0x06bb000d), + SPH_C32(0xd3ed3800), SPH_C32(0x76ca142f), SPH_C32(0x0c2c849e), + SPH_C32(0x5813baf1), SPH_C32(0xe2f26dd2), SPH_C32(0x9e000000), + SPH_C32(0xef850000), SPH_C32(0x49ca0022), SPH_C32(0x41a91800), + SPH_C32(0x456e61ac), SPH_C32(0xdc5695f4), SPH_C32(0xdd5730db), + SPH_C32(0x20d35651) }, + { SPH_C32(0x16980000), SPH_C32(0xf0110000), SPH_C32(0x3605000c), + SPH_C32(0xbae71800), SPH_C32(0xb4366636), SPH_C32(0xbdf80493), + SPH_C32(0x75c240b7), SPH_C32(0xc6c322c5), SPH_C32(0xc6430000), + SPH_C32(0x6ffb0000), SPH_C32(0x31f90023), SPH_C32(0x87c22000), + SPH_C32(0xa2593d70), SPH_C32(0xa5fbaa29), SPH_C32(0x7124ceb4), + SPH_C32(0x1a972fe0) }, + { SPH_C32(0x4edb0000), SPH_C32(0x706f0000), SPH_C32(0x4e36000d), + SPH_C32(0x7c8c2000), SPH_C32(0x53013aea), SPH_C32(0xc4553b4e), + SPH_C32(0xd9b1bed8), SPH_C32(0xfc875b74), SPH_C32(0xdb190000), + SPH_C32(0x44890000), SPH_C32(0x79740023), SPH_C32(0x28a33800), + SPH_C32(0x879213b5), SPH_C32(0x6d8215f9), SPH_C32(0xf086ca9d), + SPH_C32(0x04e21946) }, + { SPH_C32(0xaef90000), SPH_C32(0xcf450000), SPH_C32(0x30b80012), + SPH_C32(0x69280000), SPH_C32(0x1e634526), SPH_C32(0x0d5e117e), + SPH_C32(0x03512c46), SPH_C32(0xd3ad5d25), SPH_C32(0x84b70000), + SPH_C32(0x76a70000), SPH_C32(0x86330028), SPH_C32(0x79c50000), + SPH_C32(0x23d76cc7), SPH_C32(0x5ce84480), SPH_C32(0xa88d56d0), + SPH_C32(0xaed3d139) }, + { SPH_C32(0xf6ba0000), SPH_C32(0x4f3b0000), SPH_C32(0x488b0013), + SPH_C32(0xaf433800), SPH_C32(0xf95419fa), SPH_C32(0x74f32ea3), + SPH_C32(0xaf22d229), SPH_C32(0xe9e92494), SPH_C32(0x99ed0000), + SPH_C32(0x5dd50000), SPH_C32(0xcebe0028), SPH_C32(0xd6a41800), + SPH_C32(0x061c4202), SPH_C32(0x9491fb50), SPH_C32(0x292f52f9), + SPH_C32(0xb0a6e79f) }, + { SPH_C32(0xb3a30000), SPH_C32(0xe4370000), SPH_C32(0x78350012), + SPH_C32(0xc6491800), SPH_C32(0x3ba86be3), SPH_C32(0xc527aeae), + SPH_C32(0x82f3286f), SPH_C32(0xcdd86b83), SPH_C32(0xc1ae0000), + SPH_C32(0xddab0000), SPH_C32(0xb68d0029), SPH_C32(0x10cf2000), + SPH_C32(0xe12b1ede), SPH_C32(0xed3cc48d), SPH_C32(0x855cac96), + SPH_C32(0x8ae29e2e) }, + { SPH_C32(0xebe00000), SPH_C32(0x64490000), SPH_C32(0x00060013), + SPH_C32(0x00222000), SPH_C32(0xdc9f373f), SPH_C32(0xbc8a9173), + SPH_C32(0x2e80d600), SPH_C32(0xf79c1232), SPH_C32(0xdcf40000), + SPH_C32(0xf6d90000), SPH_C32(0xfe000029), SPH_C32(0xbfae3800), + SPH_C32(0xc4e0301b), SPH_C32(0x25457b5d), SPH_C32(0x04fea8bf), + SPH_C32(0x9497a888) }, + { SPH_C32(0x0c2f0000), SPH_C32(0x69330000), SPH_C32(0xf9fc0006), + SPH_C32(0x828b0000), SPH_C32(0xd28f6b5d), SPH_C32(0x3d46d5e7), + SPH_C32(0x001826bc), SPH_C32(0x48c3a5ad), SPH_C32(0x218c0000), + SPH_C32(0x62810000), SPH_C32(0xc8030036), SPH_C32(0x056b0000), + SPH_C32(0xac496112), SPH_C32(0x2437eebd), SPH_C32(0x5fbc3e08), + SPH_C32(0xa5c8987f) }, + { SPH_C32(0x546c0000), SPH_C32(0xe94d0000), SPH_C32(0x81cf0007), + SPH_C32(0x44e03800), SPH_C32(0x35b83781), SPH_C32(0x44ebea3a), + SPH_C32(0xac6bd8d3), SPH_C32(0x7287dc1c), SPH_C32(0x3cd60000), + SPH_C32(0x49f30000), SPH_C32(0x808e0036), SPH_C32(0xaa0a1800), + SPH_C32(0x89824fd7), SPH_C32(0xec4e516d), SPH_C32(0xde1e3a21), + SPH_C32(0xbbbdaed9) }, + { SPH_C32(0x11750000), SPH_C32(0x42410000), SPH_C32(0xb1710006), + SPH_C32(0x2dea1800), SPH_C32(0xf7444598), SPH_C32(0xf53f6a37), + SPH_C32(0x81ba2295), SPH_C32(0x56b6930b), SPH_C32(0x64950000), + SPH_C32(0xc98d0000), SPH_C32(0xf8bd0037), SPH_C32(0x6c612000), + SPH_C32(0x6eb5130b), SPH_C32(0x95e36eb0), SPH_C32(0x726dc44e), + SPH_C32(0x81f9d768) }, + { SPH_C32(0x49360000), SPH_C32(0xc23f0000), SPH_C32(0xc9420007), + SPH_C32(0xeb812000), SPH_C32(0x10731944), SPH_C32(0x8c9255ea), + SPH_C32(0x2dc9dcfa), SPH_C32(0x6cf2eaba), SPH_C32(0x79cf0000), + SPH_C32(0xe2ff0000), SPH_C32(0xb0300037), SPH_C32(0xc3003800), + SPH_C32(0x4b7e3dce), SPH_C32(0x5d9ad160), SPH_C32(0xf3cfc067), + SPH_C32(0x9f8ce1ce) }, + { SPH_C32(0xa9140000), SPH_C32(0x7d150000), SPH_C32(0xb7cc0018), + SPH_C32(0xfe250000), SPH_C32(0x5d116688), SPH_C32(0x45997fda), + SPH_C32(0xf7294e64), SPH_C32(0x43d8eceb), SPH_C32(0x26610000), + SPH_C32(0xd0d10000), SPH_C32(0x4f77003c), SPH_C32(0x92660000), + SPH_C32(0xef3b42bc), SPH_C32(0x6cf08019), SPH_C32(0xabc45c2a), + SPH_C32(0x35bd29b1) }, + { SPH_C32(0xf1570000), SPH_C32(0xfd6b0000), SPH_C32(0xcfff0019), + SPH_C32(0x384e3800), SPH_C32(0xba263a54), SPH_C32(0x3c344007), + SPH_C32(0x5b5ab00b), SPH_C32(0x799c955a), SPH_C32(0x3b3b0000), + SPH_C32(0xfba30000), SPH_C32(0x07fa003c), SPH_C32(0x3d071800), + SPH_C32(0xcaf06c79), SPH_C32(0xa4893fc9), SPH_C32(0x2a665803), + SPH_C32(0x2bc81f17) }, + { SPH_C32(0xb44e0000), SPH_C32(0x56670000), SPH_C32(0xff410018), + SPH_C32(0x51441800), SPH_C32(0x78da484d), SPH_C32(0x8de0c00a), + SPH_C32(0x768b4a4d), SPH_C32(0x5dadda4d), SPH_C32(0x63780000), + SPH_C32(0x7bdd0000), SPH_C32(0x7fc9003d), SPH_C32(0xfb6c2000), + SPH_C32(0x2dc730a5), SPH_C32(0xdd240014), SPH_C32(0x8615a66c), + SPH_C32(0x118c66a6) }, + { SPH_C32(0xec0d0000), SPH_C32(0xd6190000), SPH_C32(0x87720019), + SPH_C32(0x972f2000), SPH_C32(0x9fed1491), SPH_C32(0xf44dffd7), + SPH_C32(0xdaf8b422), SPH_C32(0x67e9a3fc), SPH_C32(0x7e220000), + SPH_C32(0x50af0000), SPH_C32(0x3744003d), SPH_C32(0x540d3800), + SPH_C32(0x080c1e60), SPH_C32(0x155dbfc4), SPH_C32(0x07b7a245), + SPH_C32(0x0ff95000) }, + { SPH_C32(0x835a0000), SPH_C32(0xc4f70000), SPH_C32(0x01470022), + SPH_C32(0xeec80000), SPH_C32(0x60a54f69), SPH_C32(0x142f2a24), + SPH_C32(0x5cf534f2), SPH_C32(0x3ea660f7), SPH_C32(0x88980000), + SPH_C32(0x1f940000), SPH_C32(0x7fcf002e), SPH_C32(0xfb4e0000), + SPH_C32(0xf158079a), SPH_C32(0x61ae9167), SPH_C32(0xa895706c), + SPH_C32(0xe6107494) }, + { SPH_C32(0xdb190000), SPH_C32(0x44890000), SPH_C32(0x79740023), + SPH_C32(0x28a33800), SPH_C32(0x879213b5), SPH_C32(0x6d8215f9), + SPH_C32(0xf086ca9d), SPH_C32(0x04e21946), SPH_C32(0x95c20000), + SPH_C32(0x34e60000), SPH_C32(0x3742002e), SPH_C32(0x542f1800), + SPH_C32(0xd493295f), SPH_C32(0xa9d72eb7), SPH_C32(0x29377445), + SPH_C32(0xf8654232) }, + { SPH_C32(0x9e000000), SPH_C32(0xef850000), SPH_C32(0x49ca0022), + SPH_C32(0x41a91800), SPH_C32(0x456e61ac), SPH_C32(0xdc5695f4), + SPH_C32(0xdd5730db), SPH_C32(0x20d35651), SPH_C32(0xcd810000), + SPH_C32(0xb4980000), SPH_C32(0x4f71002f), SPH_C32(0x92442000), + SPH_C32(0x33a47583), SPH_C32(0xd07a116a), SPH_C32(0x85448a2a), + SPH_C32(0xc2213b83) }, + { SPH_C32(0xc6430000), SPH_C32(0x6ffb0000), SPH_C32(0x31f90023), + SPH_C32(0x87c22000), SPH_C32(0xa2593d70), SPH_C32(0xa5fbaa29), + SPH_C32(0x7124ceb4), SPH_C32(0x1a972fe0), SPH_C32(0xd0db0000), + SPH_C32(0x9fea0000), SPH_C32(0x07fc002f), SPH_C32(0x3d253800), + SPH_C32(0x166f5b46), SPH_C32(0x1803aeba), SPH_C32(0x04e68e03), + SPH_C32(0xdc540d25) }, + { SPH_C32(0x26610000), SPH_C32(0xd0d10000), SPH_C32(0x4f77003c), + SPH_C32(0x92660000), SPH_C32(0xef3b42bc), SPH_C32(0x6cf08019), + SPH_C32(0xabc45c2a), SPH_C32(0x35bd29b1), SPH_C32(0x8f750000), + SPH_C32(0xadc40000), SPH_C32(0xf8bb0024), SPH_C32(0x6c430000), + SPH_C32(0xb22a2434), SPH_C32(0x2969ffc3), SPH_C32(0x5ced124e), + SPH_C32(0x7665c55a) }, + { SPH_C32(0x7e220000), SPH_C32(0x50af0000), SPH_C32(0x3744003d), + SPH_C32(0x540d3800), SPH_C32(0x080c1e60), SPH_C32(0x155dbfc4), + SPH_C32(0x07b7a245), SPH_C32(0x0ff95000), SPH_C32(0x922f0000), + SPH_C32(0x86b60000), SPH_C32(0xb0360024), SPH_C32(0xc3221800), + SPH_C32(0x97e10af1), SPH_C32(0xe1104013), SPH_C32(0xdd4f1667), + SPH_C32(0x6810f3fc) }, + { SPH_C32(0x3b3b0000), SPH_C32(0xfba30000), SPH_C32(0x07fa003c), + SPH_C32(0x3d071800), SPH_C32(0xcaf06c79), SPH_C32(0xa4893fc9), + SPH_C32(0x2a665803), SPH_C32(0x2bc81f17), SPH_C32(0xca6c0000), + SPH_C32(0x06c80000), SPH_C32(0xc8050025), SPH_C32(0x05492000), + SPH_C32(0x70d6562d), SPH_C32(0x98bd7fce), SPH_C32(0x713ce808), + SPH_C32(0x52548a4d) }, + { SPH_C32(0x63780000), SPH_C32(0x7bdd0000), SPH_C32(0x7fc9003d), + SPH_C32(0xfb6c2000), SPH_C32(0x2dc730a5), SPH_C32(0xdd240014), + SPH_C32(0x8615a66c), SPH_C32(0x118c66a6), SPH_C32(0xd7360000), + SPH_C32(0x2dba0000), SPH_C32(0x80880025), SPH_C32(0xaa283800), + SPH_C32(0x551d78e8), SPH_C32(0x50c4c01e), SPH_C32(0xf09eec21), + SPH_C32(0x4c21bceb) }, + { SPH_C32(0x84b70000), SPH_C32(0x76a70000), SPH_C32(0x86330028), + SPH_C32(0x79c50000), SPH_C32(0x23d76cc7), SPH_C32(0x5ce84480), + SPH_C32(0xa88d56d0), SPH_C32(0xaed3d139), SPH_C32(0x2a4e0000), + SPH_C32(0xb9e20000), SPH_C32(0xb68b003a), SPH_C32(0x10ed0000), + SPH_C32(0x3db429e1), SPH_C32(0x51b655fe), SPH_C32(0xabdc7a96), + SPH_C32(0x7d7e8c1c) }, + { SPH_C32(0xdcf40000), SPH_C32(0xf6d90000), SPH_C32(0xfe000029), + SPH_C32(0xbfae3800), SPH_C32(0xc4e0301b), SPH_C32(0x25457b5d), + SPH_C32(0x04fea8bf), SPH_C32(0x9497a888), SPH_C32(0x37140000), + SPH_C32(0x92900000), SPH_C32(0xfe06003a), SPH_C32(0xbf8c1800), + SPH_C32(0x187f0724), SPH_C32(0x99cfea2e), SPH_C32(0x2a7e7ebf), + SPH_C32(0x630bbaba) }, + { SPH_C32(0x99ed0000), SPH_C32(0x5dd50000), SPH_C32(0xcebe0028), + SPH_C32(0xd6a41800), SPH_C32(0x061c4202), SPH_C32(0x9491fb50), + SPH_C32(0x292f52f9), SPH_C32(0xb0a6e79f), SPH_C32(0x6f570000), + SPH_C32(0x12ee0000), SPH_C32(0x8635003b), SPH_C32(0x79e72000), + SPH_C32(0xff485bf8), SPH_C32(0xe062d5f3), SPH_C32(0x860d80d0), + SPH_C32(0x594fc30b) }, + { SPH_C32(0xc1ae0000), SPH_C32(0xddab0000), SPH_C32(0xb68d0029), + SPH_C32(0x10cf2000), SPH_C32(0xe12b1ede), SPH_C32(0xed3cc48d), + SPH_C32(0x855cac96), SPH_C32(0x8ae29e2e), SPH_C32(0x720d0000), + SPH_C32(0x399c0000), SPH_C32(0xceb8003b), SPH_C32(0xd6863800), + SPH_C32(0xda83753d), SPH_C32(0x281b6a23), SPH_C32(0x07af84f9), + SPH_C32(0x473af5ad) }, + { SPH_C32(0x218c0000), SPH_C32(0x62810000), SPH_C32(0xc8030036), + SPH_C32(0x056b0000), SPH_C32(0xac496112), SPH_C32(0x2437eebd), + SPH_C32(0x5fbc3e08), SPH_C32(0xa5c8987f), SPH_C32(0x2da30000), + SPH_C32(0x0bb20000), SPH_C32(0x31ff0030), SPH_C32(0x87e00000), + SPH_C32(0x7ec60a4f), SPH_C32(0x19713b5a), SPH_C32(0x5fa418b4), + SPH_C32(0xed0b3dd2) }, + { SPH_C32(0x79cf0000), SPH_C32(0xe2ff0000), SPH_C32(0xb0300037), + SPH_C32(0xc3003800), SPH_C32(0x4b7e3dce), SPH_C32(0x5d9ad160), + SPH_C32(0xf3cfc067), SPH_C32(0x9f8ce1ce), SPH_C32(0x30f90000), + SPH_C32(0x20c00000), SPH_C32(0x79720030), SPH_C32(0x28811800), + SPH_C32(0x5b0d248a), SPH_C32(0xd108848a), SPH_C32(0xde061c9d), + SPH_C32(0xf37e0b74) }, + { SPH_C32(0x3cd60000), SPH_C32(0x49f30000), SPH_C32(0x808e0036), + SPH_C32(0xaa0a1800), SPH_C32(0x89824fd7), SPH_C32(0xec4e516d), + SPH_C32(0xde1e3a21), SPH_C32(0xbbbdaed9), SPH_C32(0x68ba0000), + SPH_C32(0xa0be0000), SPH_C32(0x01410031), SPH_C32(0xeeea2000), + SPH_C32(0xbc3a7856), SPH_C32(0xa8a5bb57), SPH_C32(0x7275e2f2), + SPH_C32(0xc93a72c5) }, + { SPH_C32(0x64950000), SPH_C32(0xc98d0000), SPH_C32(0xf8bd0037), + SPH_C32(0x6c612000), SPH_C32(0x6eb5130b), SPH_C32(0x95e36eb0), + SPH_C32(0x726dc44e), SPH_C32(0x81f9d768), SPH_C32(0x75e00000), + SPH_C32(0x8bcc0000), SPH_C32(0x49cc0031), SPH_C32(0x418b3800), + SPH_C32(0x99f15693), SPH_C32(0x60dc0487), SPH_C32(0xf3d7e6db), + SPH_C32(0xd74f4463) }, + { SPH_C32(0x52500000), SPH_C32(0x29540000), SPH_C32(0x6a61004e), + SPH_C32(0xf0ff0000), SPH_C32(0x9a317eec), SPH_C32(0x452341ce), + SPH_C32(0xcf568fe5), SPH_C32(0x5303130f), SPH_C32(0x538d0000), + SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), SPH_C32(0x56ff0000), + SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), SPH_C32(0xa9444018), + SPH_C32(0x7f975691) }, + { SPH_C32(0x0a130000), SPH_C32(0xa92a0000), SPH_C32(0x1252004f), + SPH_C32(0x36943800), SPH_C32(0x7d062230), SPH_C32(0x3c8e7e13), + SPH_C32(0x6325718a), SPH_C32(0x69476abe), SPH_C32(0x4ed70000), + SPH_C32(0x828e0000), SPH_C32(0xd67a0006), SPH_C32(0xf99e1800), + SPH_C32(0x2f2f2e8b), SPH_C32(0x5abc7229), SPH_C32(0x28e64431), + SPH_C32(0x61e26037) }, + { SPH_C32(0x4f0a0000), SPH_C32(0x02260000), SPH_C32(0x22ec004e), + SPH_C32(0x5f9e1800), SPH_C32(0xbffa5029), SPH_C32(0x8d5afe1e), + SPH_C32(0x4ef48bcc), SPH_C32(0x4d7625a9), SPH_C32(0x16940000), + SPH_C32(0x02f00000), SPH_C32(0xae490007), SPH_C32(0x3ff52000), + SPH_C32(0xc8187257), SPH_C32(0x23114df4), SPH_C32(0x8495ba5e), + SPH_C32(0x5ba61986) }, + { SPH_C32(0x17490000), SPH_C32(0x82580000), SPH_C32(0x5adf004f), + SPH_C32(0x99f52000), SPH_C32(0x58cd0cf5), SPH_C32(0xf4f7c1c3), + SPH_C32(0xe28775a3), SPH_C32(0x77325c18), SPH_C32(0x0bce0000), + SPH_C32(0x29820000), SPH_C32(0xe6c40007), SPH_C32(0x90943800), + SPH_C32(0xedd35c92), SPH_C32(0xeb68f224), SPH_C32(0x0537be77), + SPH_C32(0x45d32f20) }, + { SPH_C32(0xf76b0000), SPH_C32(0x3d720000), SPH_C32(0x24510050), + SPH_C32(0x8c510000), SPH_C32(0x15af7339), SPH_C32(0x3dfcebf3), + SPH_C32(0x3867e73d), SPH_C32(0x58185a49), SPH_C32(0x54600000), + SPH_C32(0x1bac0000), SPH_C32(0x1983000c), SPH_C32(0xc1f20000), + SPH_C32(0x499623e0), SPH_C32(0xda02a35d), SPH_C32(0x5d3c223a), + SPH_C32(0xefe2e75f) }, + { SPH_C32(0xaf280000), SPH_C32(0xbd0c0000), SPH_C32(0x5c620051), + SPH_C32(0x4a3a3800), SPH_C32(0xf2982fe5), SPH_C32(0x4451d42e), + SPH_C32(0x94141952), SPH_C32(0x625c23f8), SPH_C32(0x493a0000), + SPH_C32(0x30de0000), SPH_C32(0x510e000c), SPH_C32(0x6e931800), + SPH_C32(0x6c5d0d25), SPH_C32(0x127b1c8d), SPH_C32(0xdc9e2613), + SPH_C32(0xf197d1f9) }, + { SPH_C32(0xea310000), SPH_C32(0x16000000), SPH_C32(0x6cdc0050), + SPH_C32(0x23301800), SPH_C32(0x30645dfc), SPH_C32(0xf5855423), + SPH_C32(0xb9c5e314), SPH_C32(0x466d6cef), SPH_C32(0x11790000), + SPH_C32(0xb0a00000), SPH_C32(0x293d000d), SPH_C32(0xa8f82000), + SPH_C32(0x8b6a51f9), SPH_C32(0x6bd62350), SPH_C32(0x70edd87c), + SPH_C32(0xcbd3a848) }, + { SPH_C32(0xb2720000), SPH_C32(0x967e0000), SPH_C32(0x14ef0051), + SPH_C32(0xe55b2000), SPH_C32(0xd7530120), SPH_C32(0x8c286bfe), + SPH_C32(0x15b61d7b), SPH_C32(0x7c29155e), SPH_C32(0x0c230000), + SPH_C32(0x9bd20000), SPH_C32(0x61b0000d), SPH_C32(0x07993800), + SPH_C32(0xaea17f3c), SPH_C32(0xa3af9c80), SPH_C32(0xf14fdc55), + SPH_C32(0xd5a69eee) }, + { SPH_C32(0x55bd0000), SPH_C32(0x9b040000), SPH_C32(0xed150044), + SPH_C32(0x67f20000), SPH_C32(0xd9435d42), SPH_C32(0x0de42f6a), + SPH_C32(0x3b2eedc7), SPH_C32(0xc376a2c1), SPH_C32(0xf15b0000), + SPH_C32(0x0f8a0000), SPH_C32(0x57b30012), SPH_C32(0xbd5c0000), + SPH_C32(0xc6082e35), SPH_C32(0xa2dd0960), SPH_C32(0xaa0d4ae2), + SPH_C32(0xe4f9ae19) }, + { SPH_C32(0x0dfe0000), SPH_C32(0x1b7a0000), SPH_C32(0x95260045), + SPH_C32(0xa1993800), SPH_C32(0x3e74019e), SPH_C32(0x744910b7), + SPH_C32(0x975d13a8), SPH_C32(0xf932db70), SPH_C32(0xec010000), + SPH_C32(0x24f80000), SPH_C32(0x1f3e0012), SPH_C32(0x123d1800), + SPH_C32(0xe3c300f0), SPH_C32(0x6aa4b6b0), SPH_C32(0x2baf4ecb), + SPH_C32(0xfa8c98bf) }, + { SPH_C32(0x48e70000), SPH_C32(0xb0760000), SPH_C32(0xa5980044), + SPH_C32(0xc8931800), SPH_C32(0xfc887387), SPH_C32(0xc59d90ba), + SPH_C32(0xba8ce9ee), SPH_C32(0xdd039467), SPH_C32(0xb4420000), + SPH_C32(0xa4860000), SPH_C32(0x670d0013), SPH_C32(0xd4562000), + SPH_C32(0x04f45c2c), SPH_C32(0x1309896d), SPH_C32(0x87dcb0a4), + SPH_C32(0xc0c8e10e) }, + { SPH_C32(0x10a40000), SPH_C32(0x30080000), SPH_C32(0xddab0045), + SPH_C32(0x0ef82000), SPH_C32(0x1bbf2f5b), SPH_C32(0xbc30af67), + SPH_C32(0x16ff1781), SPH_C32(0xe747edd6), SPH_C32(0xa9180000), + SPH_C32(0x8ff40000), SPH_C32(0x2f800013), SPH_C32(0x7b373800), + SPH_C32(0x213f72e9), SPH_C32(0xdb7036bd), SPH_C32(0x067eb48d), + SPH_C32(0xdebdd7a8) }, + { SPH_C32(0xf0860000), SPH_C32(0x8f220000), SPH_C32(0xa325005a), + SPH_C32(0x1b5c0000), SPH_C32(0x56dd5097), SPH_C32(0x753b8557), + SPH_C32(0xcc1f851f), SPH_C32(0xc86deb87), SPH_C32(0xf6b60000), + SPH_C32(0xbdda0000), SPH_C32(0xd0c70018), SPH_C32(0x2a510000), + SPH_C32(0x857a0d9b), SPH_C32(0xea1a67c4), SPH_C32(0x5e7528c0), + SPH_C32(0x748c1fd7) }, + { SPH_C32(0xa8c50000), SPH_C32(0x0f5c0000), SPH_C32(0xdb16005b), + SPH_C32(0xdd373800), SPH_C32(0xb1ea0c4b), SPH_C32(0x0c96ba8a), + SPH_C32(0x606c7b70), SPH_C32(0xf2299236), SPH_C32(0xebec0000), + SPH_C32(0x96a80000), SPH_C32(0x984a0018), SPH_C32(0x85301800), + SPH_C32(0xa0b1235e), SPH_C32(0x2263d814), SPH_C32(0xdfd72ce9), + SPH_C32(0x6af92971) }, + { SPH_C32(0xeddc0000), SPH_C32(0xa4500000), SPH_C32(0xeba8005a), + SPH_C32(0xb43d1800), SPH_C32(0x73167e52), SPH_C32(0xbd423a87), + SPH_C32(0x4dbd8136), SPH_C32(0xd618dd21), SPH_C32(0xb3af0000), + SPH_C32(0x16d60000), SPH_C32(0xe0790019), SPH_C32(0x435b2000), + SPH_C32(0x47867f82), SPH_C32(0x5bcee7c9), SPH_C32(0x73a4d286), + SPH_C32(0x50bd50c0) }, + { SPH_C32(0xb59f0000), SPH_C32(0x242e0000), SPH_C32(0x939b005b), + SPH_C32(0x72562000), SPH_C32(0x9421228e), SPH_C32(0xc4ef055a), + SPH_C32(0xe1ce7f59), SPH_C32(0xec5ca490), SPH_C32(0xaef50000), + SPH_C32(0x3da40000), SPH_C32(0xa8f40019), SPH_C32(0xec3a3800), + SPH_C32(0x624d5147), SPH_C32(0x93b75819), SPH_C32(0xf206d6af), + SPH_C32(0x4ec86666) }, + { SPH_C32(0xdac80000), SPH_C32(0x36c00000), SPH_C32(0x15ae0060), + SPH_C32(0x0bb10000), SPH_C32(0x6b697976), SPH_C32(0x248dd0a9), + SPH_C32(0x67c3ff89), SPH_C32(0xb513679b), SPH_C32(0x584f0000), + SPH_C32(0x729f0000), SPH_C32(0xe07f000a), SPH_C32(0x43790000), + SPH_C32(0x9b1948bd), SPH_C32(0xe74476ba), SPH_C32(0x5d240486), + SPH_C32(0xa72142f2) }, + { SPH_C32(0x828b0000), SPH_C32(0xb6be0000), SPH_C32(0x6d9d0061), + SPH_C32(0xcdda3800), SPH_C32(0x8c5e25aa), SPH_C32(0x5d20ef74), + SPH_C32(0xcbb001e6), SPH_C32(0x8f571e2a), SPH_C32(0x45150000), + SPH_C32(0x59ed0000), SPH_C32(0xa8f2000a), SPH_C32(0xec181800), + SPH_C32(0xbed26678), SPH_C32(0x2f3dc96a), SPH_C32(0xdc8600af), + SPH_C32(0xb9547454) }, + { SPH_C32(0xc7920000), SPH_C32(0x1db20000), SPH_C32(0x5d230060), + SPH_C32(0xa4d01800), SPH_C32(0x4ea257b3), SPH_C32(0xecf46f79), + SPH_C32(0xe661fba0), SPH_C32(0xab66513d), SPH_C32(0x1d560000), + SPH_C32(0xd9930000), SPH_C32(0xd0c1000b), SPH_C32(0x2a732000), + SPH_C32(0x59e53aa4), SPH_C32(0x5690f6b7), SPH_C32(0x70f5fec0), + SPH_C32(0x83100de5) }, + { SPH_C32(0x9fd10000), SPH_C32(0x9dcc0000), SPH_C32(0x25100061), + SPH_C32(0x62bb2000), SPH_C32(0xa9950b6f), SPH_C32(0x955950a4), + SPH_C32(0x4a1205cf), SPH_C32(0x9122288c), SPH_C32(0x000c0000), + SPH_C32(0xf2e10000), SPH_C32(0x984c000b), SPH_C32(0x85123800), + SPH_C32(0x7c2e1461), SPH_C32(0x9ee94967), SPH_C32(0xf157fae9), + SPH_C32(0x9d653b43) }, + { SPH_C32(0x7ff30000), SPH_C32(0x22e60000), SPH_C32(0x5b9e007e), + SPH_C32(0x771f0000), SPH_C32(0xe4f774a3), SPH_C32(0x5c527a94), + SPH_C32(0x90f29751), SPH_C32(0xbe082edd), SPH_C32(0x5fa20000), + SPH_C32(0xc0cf0000), SPH_C32(0x670b0000), SPH_C32(0xd4740000), + SPH_C32(0xd86b6b13), SPH_C32(0xaf83181e), SPH_C32(0xa95c66a4), + SPH_C32(0x3754f33c) }, + { SPH_C32(0x27b00000), SPH_C32(0xa2980000), SPH_C32(0x23ad007f), + SPH_C32(0xb1743800), SPH_C32(0x03c0287f), SPH_C32(0x25ff4549), + SPH_C32(0x3c81693e), SPH_C32(0x844c576c), SPH_C32(0x42f80000), + SPH_C32(0xebbd0000), SPH_C32(0x2f860000), SPH_C32(0x7b151800), + SPH_C32(0xfda045d6), SPH_C32(0x67faa7ce), SPH_C32(0x28fe628d), + SPH_C32(0x2921c59a) }, + { SPH_C32(0x62a90000), SPH_C32(0x09940000), SPH_C32(0x1313007e), + SPH_C32(0xd87e1800), SPH_C32(0xc13c5a66), SPH_C32(0x942bc544), + SPH_C32(0x11509378), SPH_C32(0xa07d187b), SPH_C32(0x1abb0000), + SPH_C32(0x6bc30000), SPH_C32(0x57b50001), SPH_C32(0xbd7e2000), + SPH_C32(0x1a97190a), SPH_C32(0x1e579813), SPH_C32(0x848d9ce2), + SPH_C32(0x1365bc2b) }, + { SPH_C32(0x3aea0000), SPH_C32(0x89ea0000), SPH_C32(0x6b20007f), + SPH_C32(0x1e152000), SPH_C32(0x260b06ba), SPH_C32(0xed86fa99), + SPH_C32(0xbd236d17), SPH_C32(0x9a3961ca), SPH_C32(0x07e10000), + SPH_C32(0x40b10000), SPH_C32(0x1f380001), SPH_C32(0x121f3800), + SPH_C32(0x3f5c37cf), SPH_C32(0xd62e27c3), SPH_C32(0x052f98cb), + SPH_C32(0x0d108a8d) }, + { SPH_C32(0xdd250000), SPH_C32(0x84900000), SPH_C32(0x92da006a), + SPH_C32(0x9cbc0000), SPH_C32(0x281b5ad8), SPH_C32(0x6c4abe0d), + SPH_C32(0x93bb9dab), SPH_C32(0x2566d655), SPH_C32(0xfa990000), + SPH_C32(0xd4e90000), SPH_C32(0x293b001e), SPH_C32(0xa8da0000), + SPH_C32(0x57f566c6), SPH_C32(0xd75cb223), SPH_C32(0x5e6d0e7c), + SPH_C32(0x3c4fba7a) }, + { SPH_C32(0x85660000), SPH_C32(0x04ee0000), SPH_C32(0xeae9006b), + SPH_C32(0x5ad73800), SPH_C32(0xcf2c0604), SPH_C32(0x15e781d0), + SPH_C32(0x3fc863c4), SPH_C32(0x1f22afe4), SPH_C32(0xe7c30000), + SPH_C32(0xff9b0000), SPH_C32(0x61b6001e), SPH_C32(0x07bb1800), + SPH_C32(0x723e4803), SPH_C32(0x1f250df3), SPH_C32(0xdfcf0a55), + SPH_C32(0x223a8cdc) }, + { SPH_C32(0xc07f0000), SPH_C32(0xafe20000), SPH_C32(0xda57006a), + SPH_C32(0x33dd1800), SPH_C32(0x0dd0741d), SPH_C32(0xa43301dd), + SPH_C32(0x12199982), SPH_C32(0x3b13e0f3), SPH_C32(0xbf800000), + SPH_C32(0x7fe50000), SPH_C32(0x1985001f), SPH_C32(0xc1d02000), + SPH_C32(0x950914df), SPH_C32(0x6688322e), SPH_C32(0x73bcf43a), + SPH_C32(0x187ef56d) }, + { SPH_C32(0x983c0000), SPH_C32(0x2f9c0000), SPH_C32(0xa264006b), + SPH_C32(0xf5b62000), SPH_C32(0xeae728c1), SPH_C32(0xdd9e3e00), + SPH_C32(0xbe6a67ed), SPH_C32(0x01579942), SPH_C32(0xa2da0000), + SPH_C32(0x54970000), SPH_C32(0x5108001f), SPH_C32(0x6eb13800), + SPH_C32(0xb0c23a1a), SPH_C32(0xaef18dfe), SPH_C32(0xf21ef013), + SPH_C32(0x060bc3cb) }, + { SPH_C32(0x781e0000), SPH_C32(0x90b60000), SPH_C32(0xdcea0074), + SPH_C32(0xe0120000), SPH_C32(0xa785570d), SPH_C32(0x14951430), + SPH_C32(0x648af573), SPH_C32(0x2e7d9f13), SPH_C32(0xfd740000), + SPH_C32(0x66b90000), SPH_C32(0xae4f0014), SPH_C32(0x3fd70000), + SPH_C32(0x14874568), SPH_C32(0x9f9bdc87), SPH_C32(0xaa156c5e), + SPH_C32(0xac3a0bb4) }, + { SPH_C32(0x205d0000), SPH_C32(0x10c80000), SPH_C32(0xa4d90075), + SPH_C32(0x26793800), SPH_C32(0x40b20bd1), SPH_C32(0x6d382bed), + SPH_C32(0xc8f90b1c), SPH_C32(0x1439e6a2), SPH_C32(0xe02e0000), + SPH_C32(0x4dcb0000), SPH_C32(0xe6c20014), SPH_C32(0x90b61800), + SPH_C32(0x314c6bad), SPH_C32(0x57e26357), SPH_C32(0x2bb76877), + SPH_C32(0xb24f3d12) }, + { SPH_C32(0x65440000), SPH_C32(0xbbc40000), SPH_C32(0x94670074), + SPH_C32(0x4f731800), SPH_C32(0x824e79c8), SPH_C32(0xdcecabe0), + SPH_C32(0xe528f15a), SPH_C32(0x3008a9b5), SPH_C32(0xb86d0000), + SPH_C32(0xcdb50000), SPH_C32(0x9ef10015), SPH_C32(0x56dd2000), + SPH_C32(0xd67b3771), SPH_C32(0x2e4f5c8a), SPH_C32(0x87c49618), + SPH_C32(0x880b44a3) }, + { SPH_C32(0x3d070000), SPH_C32(0x3bba0000), SPH_C32(0xec540075), + SPH_C32(0x89182000), SPH_C32(0x65792514), SPH_C32(0xa541943d), + SPH_C32(0x495b0f35), SPH_C32(0x0a4cd004), SPH_C32(0xa5370000), + SPH_C32(0xe6c70000), SPH_C32(0xd67c0015), SPH_C32(0xf9bc3800), + SPH_C32(0xf3b019b4), SPH_C32(0xe636e35a), SPH_C32(0x06669231), + SPH_C32(0x967e7205) }, + { SPH_C32(0x59920000), SPH_C32(0xf2370000), SPH_C32(0x14e90042), + SPH_C32(0xe5790000), SPH_C32(0x0bcc361f), SPH_C32(0x30a2fa8d), + SPH_C32(0x3b36cb7b), SPH_C32(0x8bb5076c), SPH_C32(0xd0d70000), + SPH_C32(0x6d0b0000), SPH_C32(0x9fb00024), SPH_C32(0xb8370000), + SPH_C32(0x6a414f27), SPH_C32(0x86eae7dd), SPH_C32(0xf5b174ea), + SPH_C32(0x41313666) }, + { SPH_C32(0x01d10000), SPH_C32(0x72490000), SPH_C32(0x6cda0043), + SPH_C32(0x23123800), SPH_C32(0xecfb6ac3), SPH_C32(0x490fc550), + SPH_C32(0x97453514), SPH_C32(0xb1f17edd), SPH_C32(0xcd8d0000), + SPH_C32(0x46790000), SPH_C32(0xd73d0024), SPH_C32(0x17561800), + SPH_C32(0x4f8a61e2), SPH_C32(0x4e93580d), SPH_C32(0x741370c3), + SPH_C32(0x5f4400c0) }, + { SPH_C32(0x44c80000), SPH_C32(0xd9450000), SPH_C32(0x5c640042), + SPH_C32(0x4a181800), SPH_C32(0x2e0718da), SPH_C32(0xf8db455d), + SPH_C32(0xba94cf52), SPH_C32(0x95c031ca), SPH_C32(0x95ce0000), + SPH_C32(0xc6070000), SPH_C32(0xaf0e0025), SPH_C32(0xd13d2000), + SPH_C32(0xa8bd3d3e), SPH_C32(0x373e67d0), SPH_C32(0xd8608eac), + SPH_C32(0x65007971) }, + { SPH_C32(0x1c8b0000), SPH_C32(0x593b0000), SPH_C32(0x24570043), + SPH_C32(0x8c732000), SPH_C32(0xc9304406), SPH_C32(0x81767a80), + SPH_C32(0x16e7313d), SPH_C32(0xaf84487b), SPH_C32(0x88940000), + SPH_C32(0xed750000), SPH_C32(0xe7830025), SPH_C32(0x7e5c3800), + SPH_C32(0x8d7613fb), SPH_C32(0xff47d800), SPH_C32(0x59c28a85), + SPH_C32(0x7b754fd7) }, + { SPH_C32(0xfca90000), SPH_C32(0xe6110000), SPH_C32(0x5ad9005c), + SPH_C32(0x99d70000), SPH_C32(0x84523bca), SPH_C32(0x487d50b0), + SPH_C32(0xcc07a3a3), SPH_C32(0x80ae4e2a), SPH_C32(0xd73a0000), + SPH_C32(0xdf5b0000), SPH_C32(0x18c4002e), SPH_C32(0x2f3a0000), + SPH_C32(0x29336c89), SPH_C32(0xce2d8979), SPH_C32(0x01c916c8), + SPH_C32(0xd14487a8) }, + { SPH_C32(0xa4ea0000), SPH_C32(0x666f0000), SPH_C32(0x22ea005d), + SPH_C32(0x5fbc3800), SPH_C32(0x63656716), SPH_C32(0x31d06f6d), + SPH_C32(0x60745dcc), SPH_C32(0xbaea379b), SPH_C32(0xca600000), + SPH_C32(0xf4290000), SPH_C32(0x5049002e), SPH_C32(0x805b1800), + SPH_C32(0x0cf8424c), SPH_C32(0x065436a9), SPH_C32(0x806b12e1), + SPH_C32(0xcf31b10e) }, + { SPH_C32(0xe1f30000), SPH_C32(0xcd630000), SPH_C32(0x1254005c), + SPH_C32(0x36b61800), SPH_C32(0xa199150f), SPH_C32(0x8004ef60), + SPH_C32(0x4da5a78a), SPH_C32(0x9edb788c), SPH_C32(0x92230000), + SPH_C32(0x74570000), SPH_C32(0x287a002f), SPH_C32(0x46302000), + SPH_C32(0xebcf1e90), SPH_C32(0x7ff90974), SPH_C32(0x2c18ec8e), + SPH_C32(0xf575c8bf) }, + { SPH_C32(0xb9b00000), SPH_C32(0x4d1d0000), SPH_C32(0x6a67005d), + SPH_C32(0xf0dd2000), SPH_C32(0x46ae49d3), SPH_C32(0xf9a9d0bd), + SPH_C32(0xe1d659e5), SPH_C32(0xa49f013d), SPH_C32(0x8f790000), + SPH_C32(0x5f250000), SPH_C32(0x60f7002f), SPH_C32(0xe9513800), + SPH_C32(0xce043055), SPH_C32(0xb780b6a4), SPH_C32(0xadbae8a7), + SPH_C32(0xeb00fe19) }, + { SPH_C32(0x5e7f0000), SPH_C32(0x40670000), SPH_C32(0x939d0048), + SPH_C32(0x72740000), SPH_C32(0x48be15b1), SPH_C32(0x78659429), + SPH_C32(0xcf4ea959), SPH_C32(0x1bc0b6a2), SPH_C32(0x72010000), + SPH_C32(0xcb7d0000), SPH_C32(0x56f40030), SPH_C32(0x53940000), + SPH_C32(0xa6ad615c), SPH_C32(0xb6f22344), SPH_C32(0xf6f87e10), + SPH_C32(0xda5fceee) }, + { SPH_C32(0x063c0000), SPH_C32(0xc0190000), SPH_C32(0xebae0049), + SPH_C32(0xb41f3800), SPH_C32(0xaf89496d), SPH_C32(0x01c8abf4), + SPH_C32(0x633d5736), SPH_C32(0x2184cf13), SPH_C32(0x6f5b0000), + SPH_C32(0xe00f0000), SPH_C32(0x1e790030), SPH_C32(0xfcf51800), + SPH_C32(0x83664f99), SPH_C32(0x7e8b9c94), SPH_C32(0x775a7a39), + SPH_C32(0xc42af848) }, + { SPH_C32(0x43250000), SPH_C32(0x6b150000), SPH_C32(0xdb100048), + SPH_C32(0xdd151800), SPH_C32(0x6d753b74), SPH_C32(0xb01c2bf9), + SPH_C32(0x4eecad70), SPH_C32(0x05b58004), SPH_C32(0x37180000), + SPH_C32(0x60710000), SPH_C32(0x664a0031), SPH_C32(0x3a9e2000), + SPH_C32(0x64511345), SPH_C32(0x0726a349), SPH_C32(0xdb298456), + SPH_C32(0xfe6e81f9) }, + { SPH_C32(0x1b660000), SPH_C32(0xeb6b0000), SPH_C32(0xa3230049), + SPH_C32(0x1b7e2000), SPH_C32(0x8a4267a8), SPH_C32(0xc9b11424), + SPH_C32(0xe29f531f), SPH_C32(0x3ff1f9b5), SPH_C32(0x2a420000), + SPH_C32(0x4b030000), SPH_C32(0x2ec70031), SPH_C32(0x95ff3800), + SPH_C32(0x419a3d80), SPH_C32(0xcf5f1c99), SPH_C32(0x5a8b807f), + SPH_C32(0xe01bb75f) }, + { SPH_C32(0xfb440000), SPH_C32(0x54410000), SPH_C32(0xddad0056), + SPH_C32(0x0eda0000), SPH_C32(0xc7201864), SPH_C32(0x00ba3e14), + SPH_C32(0x387fc181), SPH_C32(0x10dbffe4), SPH_C32(0x75ec0000), + SPH_C32(0x792d0000), SPH_C32(0xd180003a), SPH_C32(0xc4990000), + SPH_C32(0xe5df42f2), SPH_C32(0xfe354de0), SPH_C32(0x02801c32), + SPH_C32(0x4a2a7f20) }, + { SPH_C32(0xa3070000), SPH_C32(0xd43f0000), SPH_C32(0xa59e0057), + SPH_C32(0xc8b13800), SPH_C32(0x201744b8), SPH_C32(0x791701c9), + SPH_C32(0x940c3fee), SPH_C32(0x2a9f8655), SPH_C32(0x68b60000), + SPH_C32(0x525f0000), SPH_C32(0x990d003a), SPH_C32(0x6bf81800), + SPH_C32(0xc0146c37), SPH_C32(0x364cf230), SPH_C32(0x8322181b), + SPH_C32(0x545f4986) }, + { SPH_C32(0xe61e0000), SPH_C32(0x7f330000), SPH_C32(0x95200056), + SPH_C32(0xa1bb1800), SPH_C32(0xe2eb36a1), SPH_C32(0xc8c381c4), + SPH_C32(0xb9ddc5a8), SPH_C32(0x0eaec942), SPH_C32(0x30f50000), + SPH_C32(0xd2210000), SPH_C32(0xe13e003b), SPH_C32(0xad932000), + SPH_C32(0x272330eb), SPH_C32(0x4fe1cded), SPH_C32(0x2f51e674), + SPH_C32(0x6e1b3037) }, + { SPH_C32(0xbe5d0000), SPH_C32(0xff4d0000), SPH_C32(0xed130057), + SPH_C32(0x67d02000), SPH_C32(0x05dc6a7d), SPH_C32(0xb16ebe19), + SPH_C32(0x15ae3bc7), SPH_C32(0x34eab0f3), SPH_C32(0x2daf0000), + SPH_C32(0xf9530000), SPH_C32(0xa9b3003b), SPH_C32(0x02f23800), + SPH_C32(0x02e81e2e), SPH_C32(0x8798723d), SPH_C32(0xaef3e25d), + SPH_C32(0x706e0691) }, + { SPH_C32(0xd10a0000), SPH_C32(0xeda30000), SPH_C32(0x6b26006c), + SPH_C32(0x1e370000), SPH_C32(0xfa943185), SPH_C32(0x510c6bea), + SPH_C32(0x93a3bb17), SPH_C32(0x6da573f8), SPH_C32(0xdb150000), + SPH_C32(0xb6680000), SPH_C32(0xe1380028), SPH_C32(0xadb10000), + SPH_C32(0xfbbc07d4), SPH_C32(0xf36b5c9e), SPH_C32(0x01d13074), + SPH_C32(0x99872205) }, + { SPH_C32(0x89490000), SPH_C32(0x6ddd0000), SPH_C32(0x1315006d), + SPH_C32(0xd85c3800), SPH_C32(0x1da36d59), SPH_C32(0x28a15437), + SPH_C32(0x3fd04578), SPH_C32(0x57e10a49), SPH_C32(0xc64f0000), + SPH_C32(0x9d1a0000), SPH_C32(0xa9b50028), SPH_C32(0x02d01800), + SPH_C32(0xde772911), SPH_C32(0x3b12e34e), SPH_C32(0x8073345d), + SPH_C32(0x87f214a3) }, + { SPH_C32(0xcc500000), SPH_C32(0xc6d10000), SPH_C32(0x23ab006c), + SPH_C32(0xb1561800), SPH_C32(0xdf5f1f40), SPH_C32(0x9975d43a), + SPH_C32(0x1201bf3e), SPH_C32(0x73d0455e), SPH_C32(0x9e0c0000), + SPH_C32(0x1d640000), SPH_C32(0xd1860029), SPH_C32(0xc4bb2000), + SPH_C32(0x394075cd), SPH_C32(0x42bfdc93), SPH_C32(0x2c00ca32), + SPH_C32(0xbdb66d12) }, + { SPH_C32(0x94130000), SPH_C32(0x46af0000), SPH_C32(0x5b98006d), + SPH_C32(0x773d2000), SPH_C32(0x3868439c), SPH_C32(0xe0d8ebe7), + SPH_C32(0xbe724151), SPH_C32(0x49943cef), SPH_C32(0x83560000), + SPH_C32(0x36160000), SPH_C32(0x990b0029), SPH_C32(0x6bda3800), + SPH_C32(0x1c8b5b08), SPH_C32(0x8ac66343), SPH_C32(0xada2ce1b), + SPH_C32(0xa3c35bb4) }, + { SPH_C32(0x74310000), SPH_C32(0xf9850000), SPH_C32(0x25160072), + SPH_C32(0x62990000), SPH_C32(0x750a3c50), SPH_C32(0x29d3c1d7), + SPH_C32(0x6492d3cf), SPH_C32(0x66be3abe), SPH_C32(0xdcf80000), + SPH_C32(0x04380000), SPH_C32(0x664c0022), SPH_C32(0x3abc0000), + SPH_C32(0xb8ce247a), SPH_C32(0xbbac323a), SPH_C32(0xf5a95256), + SPH_C32(0x09f293cb) }, + { SPH_C32(0x2c720000), SPH_C32(0x79fb0000), SPH_C32(0x5d250073), + SPH_C32(0xa4f23800), SPH_C32(0x923d608c), SPH_C32(0x507efe0a), + SPH_C32(0xc8e12da0), SPH_C32(0x5cfa430f), SPH_C32(0xc1a20000), + SPH_C32(0x2f4a0000), SPH_C32(0x2ec10022), SPH_C32(0x95dd1800), + SPH_C32(0x9d050abf), SPH_C32(0x73d58dea), SPH_C32(0x740b567f), + SPH_C32(0x1787a56d) }, + { SPH_C32(0x696b0000), SPH_C32(0xd2f70000), SPH_C32(0x6d9b0072), + SPH_C32(0xcdf81800), SPH_C32(0x50c11295), SPH_C32(0xe1aa7e07), + SPH_C32(0xe530d7e6), SPH_C32(0x78cb0c18), SPH_C32(0x99e10000), + SPH_C32(0xaf340000), SPH_C32(0x56f20023), SPH_C32(0x53b62000), + SPH_C32(0x7a325663), SPH_C32(0x0a78b237), SPH_C32(0xd878a810), + SPH_C32(0x2dc3dcdc) }, + { SPH_C32(0x31280000), SPH_C32(0x52890000), SPH_C32(0x15a80073), + SPH_C32(0x0b932000), SPH_C32(0xb7f64e49), SPH_C32(0x980741da), + SPH_C32(0x49432989), SPH_C32(0x428f75a9), SPH_C32(0x84bb0000), + SPH_C32(0x84460000), SPH_C32(0x1e7f0023), SPH_C32(0xfcd73800), + SPH_C32(0x5ff978a6), SPH_C32(0xc2010de7), SPH_C32(0x59daac39), + SPH_C32(0x33b6ea7a) }, + { SPH_C32(0xd6e70000), SPH_C32(0x5ff30000), SPH_C32(0xec520066), + SPH_C32(0x893a0000), SPH_C32(0xb9e6122b), SPH_C32(0x19cb054e), + SPH_C32(0x67dbd935), SPH_C32(0xfdd0c236), SPH_C32(0x79c30000), + SPH_C32(0x101e0000), SPH_C32(0x287c003c), SPH_C32(0x46120000), + SPH_C32(0x375029af), SPH_C32(0xc3739807), SPH_C32(0x02983a8e), + SPH_C32(0x02e9da8d) }, + { SPH_C32(0x8ea40000), SPH_C32(0xdf8d0000), SPH_C32(0x94610067), + SPH_C32(0x4f513800), SPH_C32(0x5ed14ef7), SPH_C32(0x60663a93), + SPH_C32(0xcba8275a), SPH_C32(0xc794bb87), SPH_C32(0x64990000), + SPH_C32(0x3b6c0000), SPH_C32(0x60f1003c), SPH_C32(0xe9731800), + SPH_C32(0x129b076a), SPH_C32(0x0b0a27d7), SPH_C32(0x833a3ea7), + SPH_C32(0x1c9cec2b) }, + { SPH_C32(0xcbbd0000), SPH_C32(0x74810000), SPH_C32(0xa4df0066), + SPH_C32(0x265b1800), SPH_C32(0x9c2d3cee), SPH_C32(0xd1b2ba9e), + SPH_C32(0xe679dd1c), SPH_C32(0xe3a5f490), SPH_C32(0x3cda0000), + SPH_C32(0xbb120000), SPH_C32(0x18c2003d), SPH_C32(0x2f182000), + SPH_C32(0xf5ac5bb6), SPH_C32(0x72a7180a), SPH_C32(0x2f49c0c8), + SPH_C32(0x26d8959a) }, + { SPH_C32(0x93fe0000), SPH_C32(0xf4ff0000), SPH_C32(0xdcec0067), + SPH_C32(0xe0302000), SPH_C32(0x7b1a6032), SPH_C32(0xa81f8543), + SPH_C32(0x4a0a2373), SPH_C32(0xd9e18d21), SPH_C32(0x21800000), + SPH_C32(0x90600000), SPH_C32(0x504f003d), SPH_C32(0x80793800), + SPH_C32(0xd0677573), SPH_C32(0xbadea7da), SPH_C32(0xaeebc4e1), + SPH_C32(0x38ada33c) }, + { SPH_C32(0x73dc0000), SPH_C32(0x4bd50000), SPH_C32(0xa2620078), + SPH_C32(0xf5940000), SPH_C32(0x36781ffe), SPH_C32(0x6114af73), + SPH_C32(0x90eab1ed), SPH_C32(0xf6cb8b70), SPH_C32(0x7e2e0000), + SPH_C32(0xa24e0000), SPH_C32(0xaf080036), SPH_C32(0xd11f0000), + SPH_C32(0x74220a01), SPH_C32(0x8bb4f6a3), SPH_C32(0xf6e058ac), + SPH_C32(0x929c6b43) }, + { SPH_C32(0x2b9f0000), SPH_C32(0xcbab0000), SPH_C32(0xda510079), + SPH_C32(0x33ff3800), SPH_C32(0xd14f4322), SPH_C32(0x18b990ae), + SPH_C32(0x3c994f82), SPH_C32(0xcc8ff2c1), SPH_C32(0x63740000), + SPH_C32(0x893c0000), SPH_C32(0xe7850036), SPH_C32(0x7e7e1800), + SPH_C32(0x51e924c4), SPH_C32(0x43cd4973), SPH_C32(0x77425c85), + SPH_C32(0x8ce95de5) }, + { SPH_C32(0x6e860000), SPH_C32(0x60a70000), SPH_C32(0xeaef0078), + SPH_C32(0x5af51800), SPH_C32(0x13b3313b), SPH_C32(0xa96d10a3), + SPH_C32(0x1148b5c4), SPH_C32(0xe8bebdd6), SPH_C32(0x3b370000), + SPH_C32(0x09420000), SPH_C32(0x9fb60037), SPH_C32(0xb8152000), + SPH_C32(0xb6de7818), SPH_C32(0x3a6076ae), SPH_C32(0xdb31a2ea), + SPH_C32(0xb6ad2454) }, + { SPH_C32(0x36c50000), SPH_C32(0xe0d90000), SPH_C32(0x92dc0079), + SPH_C32(0x9c9e2000), SPH_C32(0xf4846de7), SPH_C32(0xd0c02f7e), + SPH_C32(0xbd3b4bab), SPH_C32(0xd2fac467), SPH_C32(0x266d0000), + SPH_C32(0x22300000), SPH_C32(0xd73b0037), SPH_C32(0x17743800), + SPH_C32(0x931556dd), SPH_C32(0xf219c97e), SPH_C32(0x5a93a6c3), + SPH_C32(0xa8d812f2) }, + { SPH_C32(0x538d0000), SPH_C32(0xa9fc0000), SPH_C32(0x9ef70006), + SPH_C32(0x56ff0000), SPH_C32(0x0ae4004e), SPH_C32(0x92c5cdf9), + SPH_C32(0xa9444018), SPH_C32(0x7f975691), SPH_C32(0x01dd0000), + SPH_C32(0x80a80000), SPH_C32(0xf4960048), SPH_C32(0xa6000000), + SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), SPH_C32(0x6612cffd), + SPH_C32(0x2c94459e) }, + { SPH_C32(0x0bce0000), SPH_C32(0x29820000), SPH_C32(0xe6c40007), + SPH_C32(0x90943800), SPH_C32(0xedd35c92), SPH_C32(0xeb68f224), + SPH_C32(0x0537be77), SPH_C32(0x45d32f20), SPH_C32(0x1c870000), + SPH_C32(0xabda0000), SPH_C32(0xbc1b0048), SPH_C32(0x09611800), + SPH_C32(0xb51e5067), SPH_C32(0x1f9f33e7), SPH_C32(0xe7b0cbd4), + SPH_C32(0x32e17338) }, + { SPH_C32(0x4ed70000), SPH_C32(0x828e0000), SPH_C32(0xd67a0006), + SPH_C32(0xf99e1800), SPH_C32(0x2f2f2e8b), SPH_C32(0x5abc7229), + SPH_C32(0x28e64431), SPH_C32(0x61e26037), SPH_C32(0x44c40000), + SPH_C32(0x2ba40000), SPH_C32(0xc4280049), SPH_C32(0xcf0a2000), + SPH_C32(0x52290cbb), SPH_C32(0x66320c3a), SPH_C32(0x4bc335bb), + SPH_C32(0x08a50a89) }, + { SPH_C32(0x16940000), SPH_C32(0x02f00000), SPH_C32(0xae490007), + SPH_C32(0x3ff52000), SPH_C32(0xc8187257), SPH_C32(0x23114df4), + SPH_C32(0x8495ba5e), SPH_C32(0x5ba61986), SPH_C32(0x599e0000), + SPH_C32(0x00d60000), SPH_C32(0x8ca50049), SPH_C32(0x606b3800), + SPH_C32(0x77e2227e), SPH_C32(0xae4bb3ea), SPH_C32(0xca613192), + SPH_C32(0x16d03c2f) }, + { SPH_C32(0xf6b60000), SPH_C32(0xbdda0000), SPH_C32(0xd0c70018), + SPH_C32(0x2a510000), SPH_C32(0x857a0d9b), SPH_C32(0xea1a67c4), + SPH_C32(0x5e7528c0), SPH_C32(0x748c1fd7), SPH_C32(0x06300000), + SPH_C32(0x32f80000), SPH_C32(0x73e20042), SPH_C32(0x310d0000), + SPH_C32(0xd3a75d0c), SPH_C32(0x9f21e293), SPH_C32(0x926aaddf), + SPH_C32(0xbce1f450) }, + { SPH_C32(0xaef50000), SPH_C32(0x3da40000), SPH_C32(0xa8f40019), + SPH_C32(0xec3a3800), SPH_C32(0x624d5147), SPH_C32(0x93b75819), + SPH_C32(0xf206d6af), SPH_C32(0x4ec86666), SPH_C32(0x1b6a0000), + SPH_C32(0x198a0000), SPH_C32(0x3b6f0042), SPH_C32(0x9e6c1800), + SPH_C32(0xf66c73c9), SPH_C32(0x57585d43), SPH_C32(0x13c8a9f6), + SPH_C32(0xa294c2f6) }, + { SPH_C32(0xebec0000), SPH_C32(0x96a80000), SPH_C32(0x984a0018), + SPH_C32(0x85301800), SPH_C32(0xa0b1235e), SPH_C32(0x2263d814), + SPH_C32(0xdfd72ce9), SPH_C32(0x6af92971), SPH_C32(0x43290000), + SPH_C32(0x99f40000), SPH_C32(0x435c0043), SPH_C32(0x58072000), + SPH_C32(0x115b2f15), SPH_C32(0x2ef5629e), SPH_C32(0xbfbb5799), + SPH_C32(0x98d0bb47) }, + { SPH_C32(0xb3af0000), SPH_C32(0x16d60000), SPH_C32(0xe0790019), + SPH_C32(0x435b2000), SPH_C32(0x47867f82), SPH_C32(0x5bcee7c9), + SPH_C32(0x73a4d286), SPH_C32(0x50bd50c0), SPH_C32(0x5e730000), + SPH_C32(0xb2860000), SPH_C32(0x0bd10043), SPH_C32(0xf7663800), + SPH_C32(0x349001d0), SPH_C32(0xe68cdd4e), SPH_C32(0x3e1953b0), + SPH_C32(0x86a58de1) }, + { SPH_C32(0x54600000), SPH_C32(0x1bac0000), SPH_C32(0x1983000c), + SPH_C32(0xc1f20000), SPH_C32(0x499623e0), SPH_C32(0xda02a35d), + SPH_C32(0x5d3c223a), SPH_C32(0xefe2e75f), SPH_C32(0xa30b0000), + SPH_C32(0x26de0000), SPH_C32(0x3dd2005c), SPH_C32(0x4da30000), + SPH_C32(0x5c3950d9), SPH_C32(0xe7fe48ae), SPH_C32(0x655bc507), + SPH_C32(0xb7fabd16) }, + { SPH_C32(0x0c230000), SPH_C32(0x9bd20000), SPH_C32(0x61b0000d), + SPH_C32(0x07993800), SPH_C32(0xaea17f3c), SPH_C32(0xa3af9c80), + SPH_C32(0xf14fdc55), SPH_C32(0xd5a69eee), SPH_C32(0xbe510000), + SPH_C32(0x0dac0000), SPH_C32(0x755f005c), SPH_C32(0xe2c21800), + SPH_C32(0x79f27e1c), SPH_C32(0x2f87f77e), SPH_C32(0xe4f9c12e), + SPH_C32(0xa98f8bb0) }, + { SPH_C32(0x493a0000), SPH_C32(0x30de0000), SPH_C32(0x510e000c), + SPH_C32(0x6e931800), SPH_C32(0x6c5d0d25), SPH_C32(0x127b1c8d), + SPH_C32(0xdc9e2613), SPH_C32(0xf197d1f9), SPH_C32(0xe6120000), + SPH_C32(0x8dd20000), SPH_C32(0x0d6c005d), SPH_C32(0x24a92000), + SPH_C32(0x9ec522c0), SPH_C32(0x562ac8a3), SPH_C32(0x488a3f41), + SPH_C32(0x93cbf201) }, + { SPH_C32(0x11790000), SPH_C32(0xb0a00000), SPH_C32(0x293d000d), + SPH_C32(0xa8f82000), SPH_C32(0x8b6a51f9), SPH_C32(0x6bd62350), + SPH_C32(0x70edd87c), SPH_C32(0xcbd3a848), SPH_C32(0xfb480000), + SPH_C32(0xa6a00000), SPH_C32(0x45e1005d), SPH_C32(0x8bc83800), + SPH_C32(0xbb0e0c05), SPH_C32(0x9e537773), SPH_C32(0xc9283b68), + SPH_C32(0x8dbec4a7) }, + { SPH_C32(0xf15b0000), SPH_C32(0x0f8a0000), SPH_C32(0x57b30012), + SPH_C32(0xbd5c0000), SPH_C32(0xc6082e35), SPH_C32(0xa2dd0960), + SPH_C32(0xaa0d4ae2), SPH_C32(0xe4f9ae19), SPH_C32(0xa4e60000), + SPH_C32(0x948e0000), SPH_C32(0xbaa60056), SPH_C32(0xdaae0000), + SPH_C32(0x1f4b7377), SPH_C32(0xaf39260a), SPH_C32(0x9123a725), + SPH_C32(0x278f0cd8) }, + { SPH_C32(0xa9180000), SPH_C32(0x8ff40000), SPH_C32(0x2f800013), + SPH_C32(0x7b373800), SPH_C32(0x213f72e9), SPH_C32(0xdb7036bd), + SPH_C32(0x067eb48d), SPH_C32(0xdebdd7a8), SPH_C32(0xb9bc0000), + SPH_C32(0xbffc0000), SPH_C32(0xf22b0056), SPH_C32(0x75cf1800), + SPH_C32(0x3a805db2), SPH_C32(0x674099da), SPH_C32(0x1081a30c), + SPH_C32(0x39fa3a7e) }, + { SPH_C32(0xec010000), SPH_C32(0x24f80000), SPH_C32(0x1f3e0012), + SPH_C32(0x123d1800), SPH_C32(0xe3c300f0), SPH_C32(0x6aa4b6b0), + SPH_C32(0x2baf4ecb), SPH_C32(0xfa8c98bf), SPH_C32(0xe1ff0000), + SPH_C32(0x3f820000), SPH_C32(0x8a180057), SPH_C32(0xb3a42000), + SPH_C32(0xddb7016e), SPH_C32(0x1eeda607), SPH_C32(0xbcf25d63), + SPH_C32(0x03be43cf) }, + { SPH_C32(0xb4420000), SPH_C32(0xa4860000), SPH_C32(0x670d0013), + SPH_C32(0xd4562000), SPH_C32(0x04f45c2c), SPH_C32(0x1309896d), + SPH_C32(0x87dcb0a4), SPH_C32(0xc0c8e10e), SPH_C32(0xfca50000), + SPH_C32(0x14f00000), SPH_C32(0xc2950057), SPH_C32(0x1cc53800), + SPH_C32(0xf87c2fab), SPH_C32(0xd69419d7), SPH_C32(0x3d50594a), + SPH_C32(0x1dcb7569) }, + { SPH_C32(0xdb150000), SPH_C32(0xb6680000), SPH_C32(0xe1380028), + SPH_C32(0xadb10000), SPH_C32(0xfbbc07d4), SPH_C32(0xf36b5c9e), + SPH_C32(0x01d13074), SPH_C32(0x99872205), SPH_C32(0x0a1f0000), + SPH_C32(0x5bcb0000), SPH_C32(0x8a1e0044), SPH_C32(0xb3860000), + SPH_C32(0x01283651), SPH_C32(0xa2673774), SPH_C32(0x92728b63), + SPH_C32(0xf42251fd) }, + { SPH_C32(0x83560000), SPH_C32(0x36160000), SPH_C32(0x990b0029), + SPH_C32(0x6bda3800), SPH_C32(0x1c8b5b08), SPH_C32(0x8ac66343), + SPH_C32(0xada2ce1b), SPH_C32(0xa3c35bb4), SPH_C32(0x17450000), + SPH_C32(0x70b90000), SPH_C32(0xc2930044), SPH_C32(0x1ce71800), + SPH_C32(0x24e31894), SPH_C32(0x6a1e88a4), SPH_C32(0x13d08f4a), + SPH_C32(0xea57675b) }, + { SPH_C32(0xc64f0000), SPH_C32(0x9d1a0000), SPH_C32(0xa9b50028), + SPH_C32(0x02d01800), SPH_C32(0xde772911), SPH_C32(0x3b12e34e), + SPH_C32(0x8073345d), SPH_C32(0x87f214a3), SPH_C32(0x4f060000), + SPH_C32(0xf0c70000), SPH_C32(0xbaa00045), SPH_C32(0xda8c2000), + SPH_C32(0xc3d44448), SPH_C32(0x13b3b779), SPH_C32(0xbfa37125), + SPH_C32(0xd0131eea) }, + { SPH_C32(0x9e0c0000), SPH_C32(0x1d640000), SPH_C32(0xd1860029), + SPH_C32(0xc4bb2000), SPH_C32(0x394075cd), SPH_C32(0x42bfdc93), + SPH_C32(0x2c00ca32), SPH_C32(0xbdb66d12), SPH_C32(0x525c0000), + SPH_C32(0xdbb50000), SPH_C32(0xf22d0045), SPH_C32(0x75ed3800), + SPH_C32(0xe61f6a8d), SPH_C32(0xdbca08a9), SPH_C32(0x3e01750c), + SPH_C32(0xce66284c) }, + { SPH_C32(0x7e2e0000), SPH_C32(0xa24e0000), SPH_C32(0xaf080036), + SPH_C32(0xd11f0000), SPH_C32(0x74220a01), SPH_C32(0x8bb4f6a3), + SPH_C32(0xf6e058ac), SPH_C32(0x929c6b43), SPH_C32(0x0df20000), + SPH_C32(0xe99b0000), SPH_C32(0x0d6a004e), SPH_C32(0x248b0000), + SPH_C32(0x425a15ff), SPH_C32(0xeaa059d0), SPH_C32(0x660ae941), + SPH_C32(0x6457e033) }, + { SPH_C32(0x266d0000), SPH_C32(0x22300000), SPH_C32(0xd73b0037), + SPH_C32(0x17743800), SPH_C32(0x931556dd), SPH_C32(0xf219c97e), + SPH_C32(0x5a93a6c3), SPH_C32(0xa8d812f2), SPH_C32(0x10a80000), + SPH_C32(0xc2e90000), SPH_C32(0x45e7004e), SPH_C32(0x8bea1800), + SPH_C32(0x67913b3a), SPH_C32(0x22d9e600), SPH_C32(0xe7a8ed68), + SPH_C32(0x7a22d695) }, + { SPH_C32(0x63740000), SPH_C32(0x893c0000), SPH_C32(0xe7850036), + SPH_C32(0x7e7e1800), SPH_C32(0x51e924c4), SPH_C32(0x43cd4973), + SPH_C32(0x77425c85), SPH_C32(0x8ce95de5), SPH_C32(0x48eb0000), + SPH_C32(0x42970000), SPH_C32(0x3dd4004f), SPH_C32(0x4d812000), + SPH_C32(0x80a667e6), SPH_C32(0x5b74d9dd), SPH_C32(0x4bdb1307), + SPH_C32(0x4066af24) }, + { SPH_C32(0x3b370000), SPH_C32(0x09420000), SPH_C32(0x9fb60037), + SPH_C32(0xb8152000), SPH_C32(0xb6de7818), SPH_C32(0x3a6076ae), + SPH_C32(0xdb31a2ea), SPH_C32(0xb6ad2454), SPH_C32(0x55b10000), + SPH_C32(0x69e50000), SPH_C32(0x7559004f), SPH_C32(0xe2e03800), + SPH_C32(0xa56d4923), SPH_C32(0x930d660d), SPH_C32(0xca79172e), + SPH_C32(0x5e139982) }, + { SPH_C32(0xdcf80000), SPH_C32(0x04380000), SPH_C32(0x664c0022), + SPH_C32(0x3abc0000), SPH_C32(0xb8ce247a), SPH_C32(0xbbac323a), + SPH_C32(0xf5a95256), SPH_C32(0x09f293cb), SPH_C32(0xa8c90000), + SPH_C32(0xfdbd0000), SPH_C32(0x435a0050), SPH_C32(0x58250000), + SPH_C32(0xcdc4182a), SPH_C32(0x927ff3ed), SPH_C32(0x913b8199), + SPH_C32(0x6f4ca975) }, + { SPH_C32(0x84bb0000), SPH_C32(0x84460000), SPH_C32(0x1e7f0023), + SPH_C32(0xfcd73800), SPH_C32(0x5ff978a6), SPH_C32(0xc2010de7), + SPH_C32(0x59daac39), SPH_C32(0x33b6ea7a), SPH_C32(0xb5930000), + SPH_C32(0xd6cf0000), SPH_C32(0x0bd70050), SPH_C32(0xf7441800), + SPH_C32(0xe80f36ef), SPH_C32(0x5a064c3d), SPH_C32(0x109985b0), + SPH_C32(0x71399fd3) }, + { SPH_C32(0xc1a20000), SPH_C32(0x2f4a0000), SPH_C32(0x2ec10022), + SPH_C32(0x95dd1800), SPH_C32(0x9d050abf), SPH_C32(0x73d58dea), + SPH_C32(0x740b567f), SPH_C32(0x1787a56d), SPH_C32(0xedd00000), + SPH_C32(0x56b10000), SPH_C32(0x73e40051), SPH_C32(0x312f2000), + SPH_C32(0x0f386a33), SPH_C32(0x23ab73e0), SPH_C32(0xbcea7bdf), + SPH_C32(0x4b7de662) }, + { SPH_C32(0x99e10000), SPH_C32(0xaf340000), SPH_C32(0x56f20023), + SPH_C32(0x53b62000), SPH_C32(0x7a325663), SPH_C32(0x0a78b237), + SPH_C32(0xd878a810), SPH_C32(0x2dc3dcdc), SPH_C32(0xf08a0000), + SPH_C32(0x7dc30000), SPH_C32(0x3b690051), SPH_C32(0x9e4e3800), + SPH_C32(0x2af344f6), SPH_C32(0xebd2cc30), SPH_C32(0x3d487ff6), + SPH_C32(0x5508d0c4) }, + { SPH_C32(0x79c30000), SPH_C32(0x101e0000), SPH_C32(0x287c003c), + SPH_C32(0x46120000), SPH_C32(0x375029af), SPH_C32(0xc3739807), + SPH_C32(0x02983a8e), SPH_C32(0x02e9da8d), SPH_C32(0xaf240000), + SPH_C32(0x4fed0000), SPH_C32(0xc42e005a), SPH_C32(0xcf280000), + SPH_C32(0x8eb63b84), SPH_C32(0xdab89d49), SPH_C32(0x6543e3bb), + SPH_C32(0xff3918bb) }, + { SPH_C32(0x21800000), SPH_C32(0x90600000), SPH_C32(0x504f003d), + SPH_C32(0x80793800), SPH_C32(0xd0677573), SPH_C32(0xbadea7da), + SPH_C32(0xaeebc4e1), SPH_C32(0x38ada33c), SPH_C32(0xb27e0000), + SPH_C32(0x649f0000), SPH_C32(0x8ca3005a), SPH_C32(0x60491800), + SPH_C32(0xab7d1541), SPH_C32(0x12c12299), SPH_C32(0xe4e1e792), + SPH_C32(0xe14c2e1d) }, + { SPH_C32(0x64990000), SPH_C32(0x3b6c0000), SPH_C32(0x60f1003c), + SPH_C32(0xe9731800), SPH_C32(0x129b076a), SPH_C32(0x0b0a27d7), + SPH_C32(0x833a3ea7), SPH_C32(0x1c9cec2b), SPH_C32(0xea3d0000), + SPH_C32(0xe4e10000), SPH_C32(0xf490005b), SPH_C32(0xa6222000), + SPH_C32(0x4c4a499d), SPH_C32(0x6b6c1d44), SPH_C32(0x489219fd), + SPH_C32(0xdb0857ac) }, + { SPH_C32(0x3cda0000), SPH_C32(0xbb120000), SPH_C32(0x18c2003d), + SPH_C32(0x2f182000), SPH_C32(0xf5ac5bb6), SPH_C32(0x72a7180a), + SPH_C32(0x2f49c0c8), SPH_C32(0x26d8959a), SPH_C32(0xf7670000), + SPH_C32(0xcf930000), SPH_C32(0xbc1d005b), SPH_C32(0x09433800), + SPH_C32(0x69816758), SPH_C32(0xa315a294), SPH_C32(0xc9301dd4), + SPH_C32(0xc57d610a) }, + { SPH_C32(0x584f0000), SPH_C32(0x729f0000), SPH_C32(0xe07f000a), + SPH_C32(0x43790000), SPH_C32(0x9b1948bd), SPH_C32(0xe74476ba), + SPH_C32(0x5d240486), SPH_C32(0xa72142f2), SPH_C32(0x82870000), + SPH_C32(0x445f0000), SPH_C32(0xf5d1006a), SPH_C32(0x48c80000), + SPH_C32(0xf07031cb), SPH_C32(0xc3c9a613), SPH_C32(0x3ae7fb0f), + SPH_C32(0x12322569) }, + { SPH_C32(0x000c0000), SPH_C32(0xf2e10000), SPH_C32(0x984c000b), + SPH_C32(0x85123800), SPH_C32(0x7c2e1461), SPH_C32(0x9ee94967), + SPH_C32(0xf157fae9), SPH_C32(0x9d653b43), SPH_C32(0x9fdd0000), + SPH_C32(0x6f2d0000), SPH_C32(0xbd5c006a), SPH_C32(0xe7a91800), + SPH_C32(0xd5bb1f0e), SPH_C32(0x0bb019c3), SPH_C32(0xbb45ff26), + SPH_C32(0x0c4713cf) }, + { SPH_C32(0x45150000), SPH_C32(0x59ed0000), SPH_C32(0xa8f2000a), + SPH_C32(0xec181800), SPH_C32(0xbed26678), SPH_C32(0x2f3dc96a), + SPH_C32(0xdc8600af), SPH_C32(0xb9547454), SPH_C32(0xc79e0000), + SPH_C32(0xef530000), SPH_C32(0xc56f006b), SPH_C32(0x21c22000), + SPH_C32(0x328c43d2), SPH_C32(0x721d261e), SPH_C32(0x17360149), + SPH_C32(0x36036a7e) }, + { SPH_C32(0x1d560000), SPH_C32(0xd9930000), SPH_C32(0xd0c1000b), + SPH_C32(0x2a732000), SPH_C32(0x59e53aa4), SPH_C32(0x5690f6b7), + SPH_C32(0x70f5fec0), SPH_C32(0x83100de5), SPH_C32(0xdac40000), + SPH_C32(0xc4210000), SPH_C32(0x8de2006b), SPH_C32(0x8ea33800), + SPH_C32(0x17476d17), SPH_C32(0xba6499ce), SPH_C32(0x96940560), + SPH_C32(0x28765cd8) }, + { SPH_C32(0xfd740000), SPH_C32(0x66b90000), SPH_C32(0xae4f0014), + SPH_C32(0x3fd70000), SPH_C32(0x14874568), SPH_C32(0x9f9bdc87), + SPH_C32(0xaa156c5e), SPH_C32(0xac3a0bb4), SPH_C32(0x856a0000), + SPH_C32(0xf60f0000), SPH_C32(0x72a50060), SPH_C32(0xdfc50000), + SPH_C32(0xb3021265), SPH_C32(0x8b0ec8b7), SPH_C32(0xce9f992d), + SPH_C32(0x824794a7) }, + { SPH_C32(0xa5370000), SPH_C32(0xe6c70000), SPH_C32(0xd67c0015), + SPH_C32(0xf9bc3800), SPH_C32(0xf3b019b4), SPH_C32(0xe636e35a), + SPH_C32(0x06669231), SPH_C32(0x967e7205), SPH_C32(0x98300000), + SPH_C32(0xdd7d0000), SPH_C32(0x3a280060), SPH_C32(0x70a41800), + SPH_C32(0x96c93ca0), SPH_C32(0x43777767), SPH_C32(0x4f3d9d04), + SPH_C32(0x9c32a201) }, + { SPH_C32(0xe02e0000), SPH_C32(0x4dcb0000), SPH_C32(0xe6c20014), + SPH_C32(0x90b61800), SPH_C32(0x314c6bad), SPH_C32(0x57e26357), + SPH_C32(0x2bb76877), SPH_C32(0xb24f3d12), SPH_C32(0xc0730000), + SPH_C32(0x5d030000), SPH_C32(0x421b0061), SPH_C32(0xb6cf2000), + SPH_C32(0x71fe607c), SPH_C32(0x3ada48ba), SPH_C32(0xe34e636b), + SPH_C32(0xa676dbb0) }, + { SPH_C32(0xb86d0000), SPH_C32(0xcdb50000), SPH_C32(0x9ef10015), + SPH_C32(0x56dd2000), SPH_C32(0xd67b3771), SPH_C32(0x2e4f5c8a), + SPH_C32(0x87c49618), SPH_C32(0x880b44a3), SPH_C32(0xdd290000), + SPH_C32(0x76710000), SPH_C32(0x0a960061), SPH_C32(0x19ae3800), + SPH_C32(0x54354eb9), SPH_C32(0xf2a3f76a), SPH_C32(0x62ec6742), + SPH_C32(0xb803ed16) }, + { SPH_C32(0x5fa20000), SPH_C32(0xc0cf0000), SPH_C32(0x670b0000), + SPH_C32(0xd4740000), SPH_C32(0xd86b6b13), SPH_C32(0xaf83181e), + SPH_C32(0xa95c66a4), SPH_C32(0x3754f33c), SPH_C32(0x20510000), + SPH_C32(0xe2290000), SPH_C32(0x3c95007e), SPH_C32(0xa36b0000), + SPH_C32(0x3c9c1fb0), SPH_C32(0xf3d1628a), SPH_C32(0x39aef1f5), + SPH_C32(0x895cdde1) }, + { SPH_C32(0x07e10000), SPH_C32(0x40b10000), SPH_C32(0x1f380001), + SPH_C32(0x121f3800), SPH_C32(0x3f5c37cf), SPH_C32(0xd62e27c3), + SPH_C32(0x052f98cb), SPH_C32(0x0d108a8d), SPH_C32(0x3d0b0000), + SPH_C32(0xc95b0000), SPH_C32(0x7418007e), SPH_C32(0x0c0a1800), + SPH_C32(0x19573175), SPH_C32(0x3ba8dd5a), SPH_C32(0xb80cf5dc), + SPH_C32(0x9729eb47) }, + { SPH_C32(0x42f80000), SPH_C32(0xebbd0000), SPH_C32(0x2f860000), + SPH_C32(0x7b151800), SPH_C32(0xfda045d6), SPH_C32(0x67faa7ce), + SPH_C32(0x28fe628d), SPH_C32(0x2921c59a), SPH_C32(0x65480000), + SPH_C32(0x49250000), SPH_C32(0x0c2b007f), SPH_C32(0xca612000), + SPH_C32(0xfe606da9), SPH_C32(0x4205e287), SPH_C32(0x147f0bb3), + SPH_C32(0xad6d92f6) }, + { SPH_C32(0x1abb0000), SPH_C32(0x6bc30000), SPH_C32(0x57b50001), + SPH_C32(0xbd7e2000), SPH_C32(0x1a97190a), SPH_C32(0x1e579813), + SPH_C32(0x848d9ce2), SPH_C32(0x1365bc2b), SPH_C32(0x78120000), + SPH_C32(0x62570000), SPH_C32(0x44a6007f), SPH_C32(0x65003800), + SPH_C32(0xdbab436c), SPH_C32(0x8a7c5d57), SPH_C32(0x95dd0f9a), + SPH_C32(0xb318a450) }, + { SPH_C32(0xfa990000), SPH_C32(0xd4e90000), SPH_C32(0x293b001e), + SPH_C32(0xa8da0000), SPH_C32(0x57f566c6), SPH_C32(0xd75cb223), + SPH_C32(0x5e6d0e7c), SPH_C32(0x3c4fba7a), SPH_C32(0x27bc0000), + SPH_C32(0x50790000), SPH_C32(0xbbe10074), SPH_C32(0x34660000), + SPH_C32(0x7fee3c1e), SPH_C32(0xbb160c2e), SPH_C32(0xcdd693d7), + SPH_C32(0x19296c2f) }, + { SPH_C32(0xa2da0000), SPH_C32(0x54970000), SPH_C32(0x5108001f), + SPH_C32(0x6eb13800), SPH_C32(0xb0c23a1a), SPH_C32(0xaef18dfe), + SPH_C32(0xf21ef013), SPH_C32(0x060bc3cb), SPH_C32(0x3ae60000), + SPH_C32(0x7b0b0000), SPH_C32(0xf36c0074), SPH_C32(0x9b071800), + SPH_C32(0x5a2512db), SPH_C32(0x736fb3fe), SPH_C32(0x4c7497fe), + SPH_C32(0x075c5a89) }, + { SPH_C32(0xe7c30000), SPH_C32(0xff9b0000), SPH_C32(0x61b6001e), + SPH_C32(0x07bb1800), SPH_C32(0x723e4803), SPH_C32(0x1f250df3), + SPH_C32(0xdfcf0a55), SPH_C32(0x223a8cdc), SPH_C32(0x62a50000), + SPH_C32(0xfb750000), SPH_C32(0x8b5f0075), SPH_C32(0x5d6c2000), + SPH_C32(0xbd124e07), SPH_C32(0x0ac28c23), SPH_C32(0xe0076991), + SPH_C32(0x3d182338) }, + { SPH_C32(0xbf800000), SPH_C32(0x7fe50000), SPH_C32(0x1985001f), + SPH_C32(0xc1d02000), SPH_C32(0x950914df), SPH_C32(0x6688322e), + SPH_C32(0x73bcf43a), SPH_C32(0x187ef56d), SPH_C32(0x7fff0000), + SPH_C32(0xd0070000), SPH_C32(0xc3d20075), SPH_C32(0xf20d3800), + SPH_C32(0x98d960c2), SPH_C32(0xc2bb33f3), SPH_C32(0x61a56db8), + SPH_C32(0x236d159e) }, + { SPH_C32(0xd0d70000), SPH_C32(0x6d0b0000), SPH_C32(0x9fb00024), + SPH_C32(0xb8370000), SPH_C32(0x6a414f27), SPH_C32(0x86eae7dd), + SPH_C32(0xf5b174ea), SPH_C32(0x41313666), SPH_C32(0x89450000), + SPH_C32(0x9f3c0000), SPH_C32(0x8b590066), SPH_C32(0x5d4e0000), + SPH_C32(0x618d7938), SPH_C32(0xb6481d50), SPH_C32(0xce87bf91), + SPH_C32(0xca84310a) }, + { SPH_C32(0x88940000), SPH_C32(0xed750000), SPH_C32(0xe7830025), + SPH_C32(0x7e5c3800), SPH_C32(0x8d7613fb), SPH_C32(0xff47d800), + SPH_C32(0x59c28a85), SPH_C32(0x7b754fd7), SPH_C32(0x941f0000), + SPH_C32(0xb44e0000), SPH_C32(0xc3d40066), SPH_C32(0xf22f1800), + SPH_C32(0x444657fd), SPH_C32(0x7e31a280), SPH_C32(0x4f25bbb8), + SPH_C32(0xd4f107ac) }, + { SPH_C32(0xcd8d0000), SPH_C32(0x46790000), SPH_C32(0xd73d0024), + SPH_C32(0x17561800), SPH_C32(0x4f8a61e2), SPH_C32(0x4e93580d), + SPH_C32(0x741370c3), SPH_C32(0x5f4400c0), SPH_C32(0xcc5c0000), + SPH_C32(0x34300000), SPH_C32(0xbbe70067), SPH_C32(0x34442000), + SPH_C32(0xa3710b21), SPH_C32(0x079c9d5d), SPH_C32(0xe35645d7), + SPH_C32(0xeeb57e1d) }, + { SPH_C32(0x95ce0000), SPH_C32(0xc6070000), SPH_C32(0xaf0e0025), + SPH_C32(0xd13d2000), SPH_C32(0xa8bd3d3e), SPH_C32(0x373e67d0), + SPH_C32(0xd8608eac), SPH_C32(0x65007971), SPH_C32(0xd1060000), + SPH_C32(0x1f420000), SPH_C32(0xf36a0067), SPH_C32(0x9b253800), + SPH_C32(0x86ba25e4), SPH_C32(0xcfe5228d), SPH_C32(0x62f441fe), + SPH_C32(0xf0c048bb) }, + { SPH_C32(0x75ec0000), SPH_C32(0x792d0000), SPH_C32(0xd180003a), + SPH_C32(0xc4990000), SPH_C32(0xe5df42f2), SPH_C32(0xfe354de0), + SPH_C32(0x02801c32), SPH_C32(0x4a2a7f20), SPH_C32(0x8ea80000), + SPH_C32(0x2d6c0000), SPH_C32(0x0c2d006c), SPH_C32(0xca430000), + SPH_C32(0x22ff5a96), SPH_C32(0xfe8f73f4), SPH_C32(0x3affddb3), + SPH_C32(0x5af180c4) }, + { SPH_C32(0x2daf0000), SPH_C32(0xf9530000), SPH_C32(0xa9b3003b), + SPH_C32(0x02f23800), SPH_C32(0x02e81e2e), SPH_C32(0x8798723d), + SPH_C32(0xaef3e25d), SPH_C32(0x706e0691), SPH_C32(0x93f20000), + SPH_C32(0x061e0000), SPH_C32(0x44a0006c), SPH_C32(0x65221800), + SPH_C32(0x07347453), SPH_C32(0x36f6cc24), SPH_C32(0xbb5dd99a), + SPH_C32(0x4484b662) }, + { SPH_C32(0x68b60000), SPH_C32(0x525f0000), SPH_C32(0x990d003a), + SPH_C32(0x6bf81800), SPH_C32(0xc0146c37), SPH_C32(0x364cf230), + SPH_C32(0x8322181b), SPH_C32(0x545f4986), SPH_C32(0xcbb10000), + SPH_C32(0x86600000), SPH_C32(0x3c93006d), SPH_C32(0xa3492000), + SPH_C32(0xe003288f), SPH_C32(0x4f5bf3f9), SPH_C32(0x172e27f5), + SPH_C32(0x7ec0cfd3) }, + { SPH_C32(0x30f50000), SPH_C32(0xd2210000), SPH_C32(0xe13e003b), + SPH_C32(0xad932000), SPH_C32(0x272330eb), SPH_C32(0x4fe1cded), + SPH_C32(0x2f51e674), SPH_C32(0x6e1b3037), SPH_C32(0xd6eb0000), + SPH_C32(0xad120000), SPH_C32(0x741e006d), SPH_C32(0x0c283800), + SPH_C32(0xc5c8064a), SPH_C32(0x87224c29), SPH_C32(0x968c23dc), + SPH_C32(0x60b5f975) }, + { SPH_C32(0xd73a0000), SPH_C32(0xdf5b0000), SPH_C32(0x18c4002e), + SPH_C32(0x2f3a0000), SPH_C32(0x29336c89), SPH_C32(0xce2d8979), + SPH_C32(0x01c916c8), SPH_C32(0xd14487a8), SPH_C32(0x2b930000), + SPH_C32(0x394a0000), SPH_C32(0x421d0072), SPH_C32(0xb6ed0000), + SPH_C32(0xad615743), SPH_C32(0x8650d9c9), SPH_C32(0xcdceb56b), + SPH_C32(0x51eac982) }, + { SPH_C32(0x8f790000), SPH_C32(0x5f250000), SPH_C32(0x60f7002f), + SPH_C32(0xe9513800), SPH_C32(0xce043055), SPH_C32(0xb780b6a4), + SPH_C32(0xadbae8a7), SPH_C32(0xeb00fe19), SPH_C32(0x36c90000), + SPH_C32(0x12380000), SPH_C32(0x0a900072), SPH_C32(0x198c1800), + SPH_C32(0x88aa7986), SPH_C32(0x4e296619), SPH_C32(0x4c6cb142), + SPH_C32(0x4f9fff24) }, + { SPH_C32(0xca600000), SPH_C32(0xf4290000), SPH_C32(0x5049002e), + SPH_C32(0x805b1800), SPH_C32(0x0cf8424c), SPH_C32(0x065436a9), + SPH_C32(0x806b12e1), SPH_C32(0xcf31b10e), SPH_C32(0x6e8a0000), + SPH_C32(0x92460000), SPH_C32(0x72a30073), SPH_C32(0xdfe72000), + SPH_C32(0x6f9d255a), SPH_C32(0x378459c4), SPH_C32(0xe01f4f2d), + SPH_C32(0x75db8695) }, + { SPH_C32(0x92230000), SPH_C32(0x74570000), SPH_C32(0x287a002f), + SPH_C32(0x46302000), SPH_C32(0xebcf1e90), SPH_C32(0x7ff90974), + SPH_C32(0x2c18ec8e), SPH_C32(0xf575c8bf), SPH_C32(0x73d00000), + SPH_C32(0xb9340000), SPH_C32(0x3a2e0073), SPH_C32(0x70863800), + SPH_C32(0x4a560b9f), SPH_C32(0xfffde614), SPH_C32(0x61bd4b04), + SPH_C32(0x6baeb033) }, + { SPH_C32(0x72010000), SPH_C32(0xcb7d0000), SPH_C32(0x56f40030), + SPH_C32(0x53940000), SPH_C32(0xa6ad615c), SPH_C32(0xb6f22344), + SPH_C32(0xf6f87e10), SPH_C32(0xda5fceee), SPH_C32(0x2c7e0000), + SPH_C32(0x8b1a0000), SPH_C32(0xc5690078), SPH_C32(0x21e00000), + SPH_C32(0xee1374ed), SPH_C32(0xce97b76d), SPH_C32(0x39b6d749), + SPH_C32(0xc19f784c) }, + { SPH_C32(0x2a420000), SPH_C32(0x4b030000), SPH_C32(0x2ec70031), + SPH_C32(0x95ff3800), SPH_C32(0x419a3d80), SPH_C32(0xcf5f1c99), + SPH_C32(0x5a8b807f), SPH_C32(0xe01bb75f), SPH_C32(0x31240000), + SPH_C32(0xa0680000), SPH_C32(0x8de40078), SPH_C32(0x8e811800), + SPH_C32(0xcbd85a28), SPH_C32(0x06ee08bd), SPH_C32(0xb814d360), + SPH_C32(0xdfea4eea) }, + { SPH_C32(0x6f5b0000), SPH_C32(0xe00f0000), SPH_C32(0x1e790030), + SPH_C32(0xfcf51800), SPH_C32(0x83664f99), SPH_C32(0x7e8b9c94), + SPH_C32(0x775a7a39), SPH_C32(0xc42af848), SPH_C32(0x69670000), + SPH_C32(0x20160000), SPH_C32(0xf5d70079), SPH_C32(0x48ea2000), + SPH_C32(0x2cef06f4), SPH_C32(0x7f433760), SPH_C32(0x14672d0f), + SPH_C32(0xe5ae375b) }, + { SPH_C32(0x37180000), SPH_C32(0x60710000), SPH_C32(0x664a0031), + SPH_C32(0x3a9e2000), SPH_C32(0x64511345), SPH_C32(0x0726a349), + SPH_C32(0xdb298456), SPH_C32(0xfe6e81f9), SPH_C32(0x743d0000), + SPH_C32(0x0b640000), SPH_C32(0xbd5a0079), SPH_C32(0xe78b3800), + SPH_C32(0x09242831), SPH_C32(0xb73a88b0), SPH_C32(0x95c52926), + SPH_C32(0xfbdb01fd) }, + { SPH_C32(0x01dd0000), SPH_C32(0x80a80000), SPH_C32(0xf4960048), + SPH_C32(0xa6000000), SPH_C32(0x90d57ea2), SPH_C32(0xd7e68c37), + SPH_C32(0x6612cffd), SPH_C32(0x2c94459e), SPH_C32(0x52500000), + SPH_C32(0x29540000), SPH_C32(0x6a61004e), SPH_C32(0xf0ff0000), + SPH_C32(0x9a317eec), SPH_C32(0x452341ce), SPH_C32(0xcf568fe5), + SPH_C32(0x5303130f) }, + { SPH_C32(0x599e0000), SPH_C32(0x00d60000), SPH_C32(0x8ca50049), + SPH_C32(0x606b3800), SPH_C32(0x77e2227e), SPH_C32(0xae4bb3ea), + SPH_C32(0xca613192), SPH_C32(0x16d03c2f), SPH_C32(0x4f0a0000), + SPH_C32(0x02260000), SPH_C32(0x22ec004e), SPH_C32(0x5f9e1800), + SPH_C32(0xbffa5029), SPH_C32(0x8d5afe1e), SPH_C32(0x4ef48bcc), + SPH_C32(0x4d7625a9) }, + { SPH_C32(0x1c870000), SPH_C32(0xabda0000), SPH_C32(0xbc1b0048), + SPH_C32(0x09611800), SPH_C32(0xb51e5067), SPH_C32(0x1f9f33e7), + SPH_C32(0xe7b0cbd4), SPH_C32(0x32e17338), SPH_C32(0x17490000), + SPH_C32(0x82580000), SPH_C32(0x5adf004f), SPH_C32(0x99f52000), + SPH_C32(0x58cd0cf5), SPH_C32(0xf4f7c1c3), SPH_C32(0xe28775a3), + SPH_C32(0x77325c18) }, + { SPH_C32(0x44c40000), SPH_C32(0x2ba40000), SPH_C32(0xc4280049), + SPH_C32(0xcf0a2000), SPH_C32(0x52290cbb), SPH_C32(0x66320c3a), + SPH_C32(0x4bc335bb), SPH_C32(0x08a50a89), SPH_C32(0x0a130000), + SPH_C32(0xa92a0000), SPH_C32(0x1252004f), SPH_C32(0x36943800), + SPH_C32(0x7d062230), SPH_C32(0x3c8e7e13), SPH_C32(0x6325718a), + SPH_C32(0x69476abe) }, + { SPH_C32(0xa4e60000), SPH_C32(0x948e0000), SPH_C32(0xbaa60056), + SPH_C32(0xdaae0000), SPH_C32(0x1f4b7377), SPH_C32(0xaf39260a), + SPH_C32(0x9123a725), SPH_C32(0x278f0cd8), SPH_C32(0x55bd0000), + SPH_C32(0x9b040000), SPH_C32(0xed150044), SPH_C32(0x67f20000), + SPH_C32(0xd9435d42), SPH_C32(0x0de42f6a), SPH_C32(0x3b2eedc7), + SPH_C32(0xc376a2c1) }, + { SPH_C32(0xfca50000), SPH_C32(0x14f00000), SPH_C32(0xc2950057), + SPH_C32(0x1cc53800), SPH_C32(0xf87c2fab), SPH_C32(0xd69419d7), + SPH_C32(0x3d50594a), SPH_C32(0x1dcb7569), SPH_C32(0x48e70000), + SPH_C32(0xb0760000), SPH_C32(0xa5980044), SPH_C32(0xc8931800), + SPH_C32(0xfc887387), SPH_C32(0xc59d90ba), SPH_C32(0xba8ce9ee), + SPH_C32(0xdd039467) }, + { SPH_C32(0xb9bc0000), SPH_C32(0xbffc0000), SPH_C32(0xf22b0056), + SPH_C32(0x75cf1800), SPH_C32(0x3a805db2), SPH_C32(0x674099da), + SPH_C32(0x1081a30c), SPH_C32(0x39fa3a7e), SPH_C32(0x10a40000), + SPH_C32(0x30080000), SPH_C32(0xddab0045), SPH_C32(0x0ef82000), + SPH_C32(0x1bbf2f5b), SPH_C32(0xbc30af67), SPH_C32(0x16ff1781), + SPH_C32(0xe747edd6) }, + { SPH_C32(0xe1ff0000), SPH_C32(0x3f820000), SPH_C32(0x8a180057), + SPH_C32(0xb3a42000), SPH_C32(0xddb7016e), SPH_C32(0x1eeda607), + SPH_C32(0xbcf25d63), SPH_C32(0x03be43cf), SPH_C32(0x0dfe0000), + SPH_C32(0x1b7a0000), SPH_C32(0x95260045), SPH_C32(0xa1993800), + SPH_C32(0x3e74019e), SPH_C32(0x744910b7), SPH_C32(0x975d13a8), + SPH_C32(0xf932db70) }, + { SPH_C32(0x06300000), SPH_C32(0x32f80000), SPH_C32(0x73e20042), + SPH_C32(0x310d0000), SPH_C32(0xd3a75d0c), SPH_C32(0x9f21e293), + SPH_C32(0x926aaddf), SPH_C32(0xbce1f450), SPH_C32(0xf0860000), + SPH_C32(0x8f220000), SPH_C32(0xa325005a), SPH_C32(0x1b5c0000), + SPH_C32(0x56dd5097), SPH_C32(0x753b8557), SPH_C32(0xcc1f851f), + SPH_C32(0xc86deb87) }, + { SPH_C32(0x5e730000), SPH_C32(0xb2860000), SPH_C32(0x0bd10043), + SPH_C32(0xf7663800), SPH_C32(0x349001d0), SPH_C32(0xe68cdd4e), + SPH_C32(0x3e1953b0), SPH_C32(0x86a58de1), SPH_C32(0xeddc0000), + SPH_C32(0xa4500000), SPH_C32(0xeba8005a), SPH_C32(0xb43d1800), + SPH_C32(0x73167e52), SPH_C32(0xbd423a87), SPH_C32(0x4dbd8136), + SPH_C32(0xd618dd21) }, + { SPH_C32(0x1b6a0000), SPH_C32(0x198a0000), SPH_C32(0x3b6f0042), + SPH_C32(0x9e6c1800), SPH_C32(0xf66c73c9), SPH_C32(0x57585d43), + SPH_C32(0x13c8a9f6), SPH_C32(0xa294c2f6), SPH_C32(0xb59f0000), + SPH_C32(0x242e0000), SPH_C32(0x939b005b), SPH_C32(0x72562000), + SPH_C32(0x9421228e), SPH_C32(0xc4ef055a), SPH_C32(0xe1ce7f59), + SPH_C32(0xec5ca490) }, + { SPH_C32(0x43290000), SPH_C32(0x99f40000), SPH_C32(0x435c0043), + SPH_C32(0x58072000), SPH_C32(0x115b2f15), SPH_C32(0x2ef5629e), + SPH_C32(0xbfbb5799), SPH_C32(0x98d0bb47), SPH_C32(0xa8c50000), + SPH_C32(0x0f5c0000), SPH_C32(0xdb16005b), SPH_C32(0xdd373800), + SPH_C32(0xb1ea0c4b), SPH_C32(0x0c96ba8a), SPH_C32(0x606c7b70), + SPH_C32(0xf2299236) }, + { SPH_C32(0xa30b0000), SPH_C32(0x26de0000), SPH_C32(0x3dd2005c), + SPH_C32(0x4da30000), SPH_C32(0x5c3950d9), SPH_C32(0xe7fe48ae), + SPH_C32(0x655bc507), SPH_C32(0xb7fabd16), SPH_C32(0xf76b0000), + SPH_C32(0x3d720000), SPH_C32(0x24510050), SPH_C32(0x8c510000), + SPH_C32(0x15af7339), SPH_C32(0x3dfcebf3), SPH_C32(0x3867e73d), + SPH_C32(0x58185a49) }, + { SPH_C32(0xfb480000), SPH_C32(0xa6a00000), SPH_C32(0x45e1005d), + SPH_C32(0x8bc83800), SPH_C32(0xbb0e0c05), SPH_C32(0x9e537773), + SPH_C32(0xc9283b68), SPH_C32(0x8dbec4a7), SPH_C32(0xea310000), + SPH_C32(0x16000000), SPH_C32(0x6cdc0050), SPH_C32(0x23301800), + SPH_C32(0x30645dfc), SPH_C32(0xf5855423), SPH_C32(0xb9c5e314), + SPH_C32(0x466d6cef) }, + { SPH_C32(0xbe510000), SPH_C32(0x0dac0000), SPH_C32(0x755f005c), + SPH_C32(0xe2c21800), SPH_C32(0x79f27e1c), SPH_C32(0x2f87f77e), + SPH_C32(0xe4f9c12e), SPH_C32(0xa98f8bb0), SPH_C32(0xb2720000), + SPH_C32(0x967e0000), SPH_C32(0x14ef0051), SPH_C32(0xe55b2000), + SPH_C32(0xd7530120), SPH_C32(0x8c286bfe), SPH_C32(0x15b61d7b), + SPH_C32(0x7c29155e) }, + { SPH_C32(0xe6120000), SPH_C32(0x8dd20000), SPH_C32(0x0d6c005d), + SPH_C32(0x24a92000), SPH_C32(0x9ec522c0), SPH_C32(0x562ac8a3), + SPH_C32(0x488a3f41), SPH_C32(0x93cbf201), SPH_C32(0xaf280000), + SPH_C32(0xbd0c0000), SPH_C32(0x5c620051), SPH_C32(0x4a3a3800), + SPH_C32(0xf2982fe5), SPH_C32(0x4451d42e), SPH_C32(0x94141952), + SPH_C32(0x625c23f8) }, + { SPH_C32(0x89450000), SPH_C32(0x9f3c0000), SPH_C32(0x8b590066), + SPH_C32(0x5d4e0000), SPH_C32(0x618d7938), SPH_C32(0xb6481d50), + SPH_C32(0xce87bf91), SPH_C32(0xca84310a), SPH_C32(0x59920000), + SPH_C32(0xf2370000), SPH_C32(0x14e90042), SPH_C32(0xe5790000), + SPH_C32(0x0bcc361f), SPH_C32(0x30a2fa8d), SPH_C32(0x3b36cb7b), + SPH_C32(0x8bb5076c) }, + { SPH_C32(0xd1060000), SPH_C32(0x1f420000), SPH_C32(0xf36a0067), + SPH_C32(0x9b253800), SPH_C32(0x86ba25e4), SPH_C32(0xcfe5228d), + SPH_C32(0x62f441fe), SPH_C32(0xf0c048bb), SPH_C32(0x44c80000), + SPH_C32(0xd9450000), SPH_C32(0x5c640042), SPH_C32(0x4a181800), + SPH_C32(0x2e0718da), SPH_C32(0xf8db455d), SPH_C32(0xba94cf52), + SPH_C32(0x95c031ca) }, + { SPH_C32(0x941f0000), SPH_C32(0xb44e0000), SPH_C32(0xc3d40066), + SPH_C32(0xf22f1800), SPH_C32(0x444657fd), SPH_C32(0x7e31a280), + SPH_C32(0x4f25bbb8), SPH_C32(0xd4f107ac), SPH_C32(0x1c8b0000), + SPH_C32(0x593b0000), SPH_C32(0x24570043), SPH_C32(0x8c732000), + SPH_C32(0xc9304406), SPH_C32(0x81767a80), SPH_C32(0x16e7313d), + SPH_C32(0xaf84487b) }, + { SPH_C32(0xcc5c0000), SPH_C32(0x34300000), SPH_C32(0xbbe70067), + SPH_C32(0x34442000), SPH_C32(0xa3710b21), SPH_C32(0x079c9d5d), + SPH_C32(0xe35645d7), SPH_C32(0xeeb57e1d), SPH_C32(0x01d10000), + SPH_C32(0x72490000), SPH_C32(0x6cda0043), SPH_C32(0x23123800), + SPH_C32(0xecfb6ac3), SPH_C32(0x490fc550), SPH_C32(0x97453514), + SPH_C32(0xb1f17edd) }, + { SPH_C32(0x2c7e0000), SPH_C32(0x8b1a0000), SPH_C32(0xc5690078), + SPH_C32(0x21e00000), SPH_C32(0xee1374ed), SPH_C32(0xce97b76d), + SPH_C32(0x39b6d749), SPH_C32(0xc19f784c), SPH_C32(0x5e7f0000), + SPH_C32(0x40670000), SPH_C32(0x939d0048), SPH_C32(0x72740000), + SPH_C32(0x48be15b1), SPH_C32(0x78659429), SPH_C32(0xcf4ea959), + SPH_C32(0x1bc0b6a2) }, + { SPH_C32(0x743d0000), SPH_C32(0x0b640000), SPH_C32(0xbd5a0079), + SPH_C32(0xe78b3800), SPH_C32(0x09242831), SPH_C32(0xb73a88b0), + SPH_C32(0x95c52926), SPH_C32(0xfbdb01fd), SPH_C32(0x43250000), + SPH_C32(0x6b150000), SPH_C32(0xdb100048), SPH_C32(0xdd151800), + SPH_C32(0x6d753b74), SPH_C32(0xb01c2bf9), SPH_C32(0x4eecad70), + SPH_C32(0x05b58004) }, + { SPH_C32(0x31240000), SPH_C32(0xa0680000), SPH_C32(0x8de40078), + SPH_C32(0x8e811800), SPH_C32(0xcbd85a28), SPH_C32(0x06ee08bd), + SPH_C32(0xb814d360), SPH_C32(0xdfea4eea), SPH_C32(0x1b660000), + SPH_C32(0xeb6b0000), SPH_C32(0xa3230049), SPH_C32(0x1b7e2000), + SPH_C32(0x8a4267a8), SPH_C32(0xc9b11424), SPH_C32(0xe29f531f), + SPH_C32(0x3ff1f9b5) }, + { SPH_C32(0x69670000), SPH_C32(0x20160000), SPH_C32(0xf5d70079), + SPH_C32(0x48ea2000), SPH_C32(0x2cef06f4), SPH_C32(0x7f433760), + SPH_C32(0x14672d0f), SPH_C32(0xe5ae375b), SPH_C32(0x063c0000), + SPH_C32(0xc0190000), SPH_C32(0xebae0049), SPH_C32(0xb41f3800), + SPH_C32(0xaf89496d), SPH_C32(0x01c8abf4), SPH_C32(0x633d5736), + SPH_C32(0x2184cf13) }, + { SPH_C32(0x8ea80000), SPH_C32(0x2d6c0000), SPH_C32(0x0c2d006c), + SPH_C32(0xca430000), SPH_C32(0x22ff5a96), SPH_C32(0xfe8f73f4), + SPH_C32(0x3affddb3), SPH_C32(0x5af180c4), SPH_C32(0xfb440000), + SPH_C32(0x54410000), SPH_C32(0xddad0056), SPH_C32(0x0eda0000), + SPH_C32(0xc7201864), SPH_C32(0x00ba3e14), SPH_C32(0x387fc181), + SPH_C32(0x10dbffe4) }, + { SPH_C32(0xd6eb0000), SPH_C32(0xad120000), SPH_C32(0x741e006d), + SPH_C32(0x0c283800), SPH_C32(0xc5c8064a), SPH_C32(0x87224c29), + SPH_C32(0x968c23dc), SPH_C32(0x60b5f975), SPH_C32(0xe61e0000), + SPH_C32(0x7f330000), SPH_C32(0x95200056), SPH_C32(0xa1bb1800), + SPH_C32(0xe2eb36a1), SPH_C32(0xc8c381c4), SPH_C32(0xb9ddc5a8), + SPH_C32(0x0eaec942) }, + { SPH_C32(0x93f20000), SPH_C32(0x061e0000), SPH_C32(0x44a0006c), + SPH_C32(0x65221800), SPH_C32(0x07347453), SPH_C32(0x36f6cc24), + SPH_C32(0xbb5dd99a), SPH_C32(0x4484b662), SPH_C32(0xbe5d0000), + SPH_C32(0xff4d0000), SPH_C32(0xed130057), SPH_C32(0x67d02000), + SPH_C32(0x05dc6a7d), SPH_C32(0xb16ebe19), SPH_C32(0x15ae3bc7), + SPH_C32(0x34eab0f3) }, + { SPH_C32(0xcbb10000), SPH_C32(0x86600000), SPH_C32(0x3c93006d), + SPH_C32(0xa3492000), SPH_C32(0xe003288f), SPH_C32(0x4f5bf3f9), + SPH_C32(0x172e27f5), SPH_C32(0x7ec0cfd3), SPH_C32(0xa3070000), + SPH_C32(0xd43f0000), SPH_C32(0xa59e0057), SPH_C32(0xc8b13800), + SPH_C32(0x201744b8), SPH_C32(0x791701c9), SPH_C32(0x940c3fee), + SPH_C32(0x2a9f8655) }, + { SPH_C32(0x2b930000), SPH_C32(0x394a0000), SPH_C32(0x421d0072), + SPH_C32(0xb6ed0000), SPH_C32(0xad615743), SPH_C32(0x8650d9c9), + SPH_C32(0xcdceb56b), SPH_C32(0x51eac982), SPH_C32(0xfca90000), + SPH_C32(0xe6110000), SPH_C32(0x5ad9005c), SPH_C32(0x99d70000), + SPH_C32(0x84523bca), SPH_C32(0x487d50b0), SPH_C32(0xcc07a3a3), + SPH_C32(0x80ae4e2a) }, + { SPH_C32(0x73d00000), SPH_C32(0xb9340000), SPH_C32(0x3a2e0073), + SPH_C32(0x70863800), SPH_C32(0x4a560b9f), SPH_C32(0xfffde614), + SPH_C32(0x61bd4b04), SPH_C32(0x6baeb033), SPH_C32(0xe1f30000), + SPH_C32(0xcd630000), SPH_C32(0x1254005c), SPH_C32(0x36b61800), + SPH_C32(0xa199150f), SPH_C32(0x8004ef60), SPH_C32(0x4da5a78a), + SPH_C32(0x9edb788c) }, + { SPH_C32(0x36c90000), SPH_C32(0x12380000), SPH_C32(0x0a900072), + SPH_C32(0x198c1800), SPH_C32(0x88aa7986), SPH_C32(0x4e296619), + SPH_C32(0x4c6cb142), SPH_C32(0x4f9fff24), SPH_C32(0xb9b00000), + SPH_C32(0x4d1d0000), SPH_C32(0x6a67005d), SPH_C32(0xf0dd2000), + SPH_C32(0x46ae49d3), SPH_C32(0xf9a9d0bd), SPH_C32(0xe1d659e5), + SPH_C32(0xa49f013d) }, + { SPH_C32(0x6e8a0000), SPH_C32(0x92460000), SPH_C32(0x72a30073), + SPH_C32(0xdfe72000), SPH_C32(0x6f9d255a), SPH_C32(0x378459c4), + SPH_C32(0xe01f4f2d), SPH_C32(0x75db8695), SPH_C32(0xa4ea0000), + SPH_C32(0x666f0000), SPH_C32(0x22ea005d), SPH_C32(0x5fbc3800), + SPH_C32(0x63656716), SPH_C32(0x31d06f6d), SPH_C32(0x60745dcc), + SPH_C32(0xbaea379b) }, + { SPH_C32(0x0a1f0000), SPH_C32(0x5bcb0000), SPH_C32(0x8a1e0044), + SPH_C32(0xb3860000), SPH_C32(0x01283651), SPH_C32(0xa2673774), + SPH_C32(0x92728b63), SPH_C32(0xf42251fd), SPH_C32(0xd10a0000), + SPH_C32(0xeda30000), SPH_C32(0x6b26006c), SPH_C32(0x1e370000), + SPH_C32(0xfa943185), SPH_C32(0x510c6bea), SPH_C32(0x93a3bb17), + SPH_C32(0x6da573f8) }, + { SPH_C32(0x525c0000), SPH_C32(0xdbb50000), SPH_C32(0xf22d0045), + SPH_C32(0x75ed3800), SPH_C32(0xe61f6a8d), SPH_C32(0xdbca08a9), + SPH_C32(0x3e01750c), SPH_C32(0xce66284c), SPH_C32(0xcc500000), + SPH_C32(0xc6d10000), SPH_C32(0x23ab006c), SPH_C32(0xb1561800), + SPH_C32(0xdf5f1f40), SPH_C32(0x9975d43a), SPH_C32(0x1201bf3e), + SPH_C32(0x73d0455e) }, + { SPH_C32(0x17450000), SPH_C32(0x70b90000), SPH_C32(0xc2930044), + SPH_C32(0x1ce71800), SPH_C32(0x24e31894), SPH_C32(0x6a1e88a4), + SPH_C32(0x13d08f4a), SPH_C32(0xea57675b), SPH_C32(0x94130000), + SPH_C32(0x46af0000), SPH_C32(0x5b98006d), SPH_C32(0x773d2000), + SPH_C32(0x3868439c), SPH_C32(0xe0d8ebe7), SPH_C32(0xbe724151), + SPH_C32(0x49943cef) }, + { SPH_C32(0x4f060000), SPH_C32(0xf0c70000), SPH_C32(0xbaa00045), + SPH_C32(0xda8c2000), SPH_C32(0xc3d44448), SPH_C32(0x13b3b779), + SPH_C32(0xbfa37125), SPH_C32(0xd0131eea), SPH_C32(0x89490000), + SPH_C32(0x6ddd0000), SPH_C32(0x1315006d), SPH_C32(0xd85c3800), + SPH_C32(0x1da36d59), SPH_C32(0x28a15437), SPH_C32(0x3fd04578), + SPH_C32(0x57e10a49) }, + { SPH_C32(0xaf240000), SPH_C32(0x4fed0000), SPH_C32(0xc42e005a), + SPH_C32(0xcf280000), SPH_C32(0x8eb63b84), SPH_C32(0xdab89d49), + SPH_C32(0x6543e3bb), SPH_C32(0xff3918bb), SPH_C32(0xd6e70000), + SPH_C32(0x5ff30000), SPH_C32(0xec520066), SPH_C32(0x893a0000), + SPH_C32(0xb9e6122b), SPH_C32(0x19cb054e), SPH_C32(0x67dbd935), + SPH_C32(0xfdd0c236) }, + { SPH_C32(0xf7670000), SPH_C32(0xcf930000), SPH_C32(0xbc1d005b), + SPH_C32(0x09433800), SPH_C32(0x69816758), SPH_C32(0xa315a294), + SPH_C32(0xc9301dd4), SPH_C32(0xc57d610a), SPH_C32(0xcbbd0000), + SPH_C32(0x74810000), SPH_C32(0xa4df0066), SPH_C32(0x265b1800), + SPH_C32(0x9c2d3cee), SPH_C32(0xd1b2ba9e), SPH_C32(0xe679dd1c), + SPH_C32(0xe3a5f490) }, + { SPH_C32(0xb27e0000), SPH_C32(0x649f0000), SPH_C32(0x8ca3005a), + SPH_C32(0x60491800), SPH_C32(0xab7d1541), SPH_C32(0x12c12299), + SPH_C32(0xe4e1e792), SPH_C32(0xe14c2e1d), SPH_C32(0x93fe0000), + SPH_C32(0xf4ff0000), SPH_C32(0xdcec0067), SPH_C32(0xe0302000), + SPH_C32(0x7b1a6032), SPH_C32(0xa81f8543), SPH_C32(0x4a0a2373), + SPH_C32(0xd9e18d21) }, + { SPH_C32(0xea3d0000), SPH_C32(0xe4e10000), SPH_C32(0xf490005b), + SPH_C32(0xa6222000), SPH_C32(0x4c4a499d), SPH_C32(0x6b6c1d44), + SPH_C32(0x489219fd), SPH_C32(0xdb0857ac), SPH_C32(0x8ea40000), + SPH_C32(0xdf8d0000), SPH_C32(0x94610067), SPH_C32(0x4f513800), + SPH_C32(0x5ed14ef7), SPH_C32(0x60663a93), SPH_C32(0xcba8275a), + SPH_C32(0xc794bb87) }, + { SPH_C32(0x0df20000), SPH_C32(0xe99b0000), SPH_C32(0x0d6a004e), + SPH_C32(0x248b0000), SPH_C32(0x425a15ff), SPH_C32(0xeaa059d0), + SPH_C32(0x660ae941), SPH_C32(0x6457e033), SPH_C32(0x73dc0000), + SPH_C32(0x4bd50000), SPH_C32(0xa2620078), SPH_C32(0xf5940000), + SPH_C32(0x36781ffe), SPH_C32(0x6114af73), SPH_C32(0x90eab1ed), + SPH_C32(0xf6cb8b70) }, + { SPH_C32(0x55b10000), SPH_C32(0x69e50000), SPH_C32(0x7559004f), + SPH_C32(0xe2e03800), SPH_C32(0xa56d4923), SPH_C32(0x930d660d), + SPH_C32(0xca79172e), SPH_C32(0x5e139982), SPH_C32(0x6e860000), + SPH_C32(0x60a70000), SPH_C32(0xeaef0078), SPH_C32(0x5af51800), + SPH_C32(0x13b3313b), SPH_C32(0xa96d10a3), SPH_C32(0x1148b5c4), + SPH_C32(0xe8bebdd6) }, + { SPH_C32(0x10a80000), SPH_C32(0xc2e90000), SPH_C32(0x45e7004e), + SPH_C32(0x8bea1800), SPH_C32(0x67913b3a), SPH_C32(0x22d9e600), + SPH_C32(0xe7a8ed68), SPH_C32(0x7a22d695), SPH_C32(0x36c50000), + SPH_C32(0xe0d90000), SPH_C32(0x92dc0079), SPH_C32(0x9c9e2000), + SPH_C32(0xf4846de7), SPH_C32(0xd0c02f7e), SPH_C32(0xbd3b4bab), + SPH_C32(0xd2fac467) }, + { SPH_C32(0x48eb0000), SPH_C32(0x42970000), SPH_C32(0x3dd4004f), + SPH_C32(0x4d812000), SPH_C32(0x80a667e6), SPH_C32(0x5b74d9dd), + SPH_C32(0x4bdb1307), SPH_C32(0x4066af24), SPH_C32(0x2b9f0000), + SPH_C32(0xcbab0000), SPH_C32(0xda510079), SPH_C32(0x33ff3800), + SPH_C32(0xd14f4322), SPH_C32(0x18b990ae), SPH_C32(0x3c994f82), + SPH_C32(0xcc8ff2c1) }, + { SPH_C32(0xa8c90000), SPH_C32(0xfdbd0000), SPH_C32(0x435a0050), + SPH_C32(0x58250000), SPH_C32(0xcdc4182a), SPH_C32(0x927ff3ed), + SPH_C32(0x913b8199), SPH_C32(0x6f4ca975), SPH_C32(0x74310000), + SPH_C32(0xf9850000), SPH_C32(0x25160072), SPH_C32(0x62990000), + SPH_C32(0x750a3c50), SPH_C32(0x29d3c1d7), SPH_C32(0x6492d3cf), + SPH_C32(0x66be3abe) }, + { SPH_C32(0xf08a0000), SPH_C32(0x7dc30000), SPH_C32(0x3b690051), + SPH_C32(0x9e4e3800), SPH_C32(0x2af344f6), SPH_C32(0xebd2cc30), + SPH_C32(0x3d487ff6), SPH_C32(0x5508d0c4), SPH_C32(0x696b0000), + SPH_C32(0xd2f70000), SPH_C32(0x6d9b0072), SPH_C32(0xcdf81800), + SPH_C32(0x50c11295), SPH_C32(0xe1aa7e07), SPH_C32(0xe530d7e6), + SPH_C32(0x78cb0c18) }, + { SPH_C32(0xb5930000), SPH_C32(0xd6cf0000), SPH_C32(0x0bd70050), + SPH_C32(0xf7441800), SPH_C32(0xe80f36ef), SPH_C32(0x5a064c3d), + SPH_C32(0x109985b0), SPH_C32(0x71399fd3), SPH_C32(0x31280000), + SPH_C32(0x52890000), SPH_C32(0x15a80073), SPH_C32(0x0b932000), + SPH_C32(0xb7f64e49), SPH_C32(0x980741da), SPH_C32(0x49432989), + SPH_C32(0x428f75a9) }, + { SPH_C32(0xedd00000), SPH_C32(0x56b10000), SPH_C32(0x73e40051), + SPH_C32(0x312f2000), SPH_C32(0x0f386a33), SPH_C32(0x23ab73e0), + SPH_C32(0xbcea7bdf), SPH_C32(0x4b7de662), SPH_C32(0x2c720000), + SPH_C32(0x79fb0000), SPH_C32(0x5d250073), SPH_C32(0xa4f23800), + SPH_C32(0x923d608c), SPH_C32(0x507efe0a), SPH_C32(0xc8e12da0), + SPH_C32(0x5cfa430f) }, + { SPH_C32(0x82870000), SPH_C32(0x445f0000), SPH_C32(0xf5d1006a), + SPH_C32(0x48c80000), SPH_C32(0xf07031cb), SPH_C32(0xc3c9a613), + SPH_C32(0x3ae7fb0f), SPH_C32(0x12322569), SPH_C32(0xdac80000), + SPH_C32(0x36c00000), SPH_C32(0x15ae0060), SPH_C32(0x0bb10000), + SPH_C32(0x6b697976), SPH_C32(0x248dd0a9), SPH_C32(0x67c3ff89), + SPH_C32(0xb513679b) }, + { SPH_C32(0xdac40000), SPH_C32(0xc4210000), SPH_C32(0x8de2006b), + SPH_C32(0x8ea33800), SPH_C32(0x17476d17), SPH_C32(0xba6499ce), + SPH_C32(0x96940560), SPH_C32(0x28765cd8), SPH_C32(0xc7920000), + SPH_C32(0x1db20000), SPH_C32(0x5d230060), SPH_C32(0xa4d01800), + SPH_C32(0x4ea257b3), SPH_C32(0xecf46f79), SPH_C32(0xe661fba0), + SPH_C32(0xab66513d) }, + { SPH_C32(0x9fdd0000), SPH_C32(0x6f2d0000), SPH_C32(0xbd5c006a), + SPH_C32(0xe7a91800), SPH_C32(0xd5bb1f0e), SPH_C32(0x0bb019c3), + SPH_C32(0xbb45ff26), SPH_C32(0x0c4713cf), SPH_C32(0x9fd10000), + SPH_C32(0x9dcc0000), SPH_C32(0x25100061), SPH_C32(0x62bb2000), + SPH_C32(0xa9950b6f), SPH_C32(0x955950a4), SPH_C32(0x4a1205cf), + SPH_C32(0x9122288c) }, + { SPH_C32(0xc79e0000), SPH_C32(0xef530000), SPH_C32(0xc56f006b), + SPH_C32(0x21c22000), SPH_C32(0x328c43d2), SPH_C32(0x721d261e), + SPH_C32(0x17360149), SPH_C32(0x36036a7e), SPH_C32(0x828b0000), + SPH_C32(0xb6be0000), SPH_C32(0x6d9d0061), SPH_C32(0xcdda3800), + SPH_C32(0x8c5e25aa), SPH_C32(0x5d20ef74), SPH_C32(0xcbb001e6), + SPH_C32(0x8f571e2a) }, + { SPH_C32(0x27bc0000), SPH_C32(0x50790000), SPH_C32(0xbbe10074), + SPH_C32(0x34660000), SPH_C32(0x7fee3c1e), SPH_C32(0xbb160c2e), + SPH_C32(0xcdd693d7), SPH_C32(0x19296c2f), SPH_C32(0xdd250000), + SPH_C32(0x84900000), SPH_C32(0x92da006a), SPH_C32(0x9cbc0000), + SPH_C32(0x281b5ad8), SPH_C32(0x6c4abe0d), SPH_C32(0x93bb9dab), + SPH_C32(0x2566d655) }, + { SPH_C32(0x7fff0000), SPH_C32(0xd0070000), SPH_C32(0xc3d20075), + SPH_C32(0xf20d3800), SPH_C32(0x98d960c2), SPH_C32(0xc2bb33f3), + SPH_C32(0x61a56db8), SPH_C32(0x236d159e), SPH_C32(0xc07f0000), + SPH_C32(0xafe20000), SPH_C32(0xda57006a), SPH_C32(0x33dd1800), + SPH_C32(0x0dd0741d), SPH_C32(0xa43301dd), SPH_C32(0x12199982), + SPH_C32(0x3b13e0f3) }, + { SPH_C32(0x3ae60000), SPH_C32(0x7b0b0000), SPH_C32(0xf36c0074), + SPH_C32(0x9b071800), SPH_C32(0x5a2512db), SPH_C32(0x736fb3fe), + SPH_C32(0x4c7497fe), SPH_C32(0x075c5a89), SPH_C32(0x983c0000), + SPH_C32(0x2f9c0000), SPH_C32(0xa264006b), SPH_C32(0xf5b62000), + SPH_C32(0xeae728c1), SPH_C32(0xdd9e3e00), SPH_C32(0xbe6a67ed), + SPH_C32(0x01579942) }, + { SPH_C32(0x62a50000), SPH_C32(0xfb750000), SPH_C32(0x8b5f0075), + SPH_C32(0x5d6c2000), SPH_C32(0xbd124e07), SPH_C32(0x0ac28c23), + SPH_C32(0xe0076991), SPH_C32(0x3d182338), SPH_C32(0x85660000), + SPH_C32(0x04ee0000), SPH_C32(0xeae9006b), SPH_C32(0x5ad73800), + SPH_C32(0xcf2c0604), SPH_C32(0x15e781d0), SPH_C32(0x3fc863c4), + SPH_C32(0x1f22afe4) }, + { SPH_C32(0x856a0000), SPH_C32(0xf60f0000), SPH_C32(0x72a50060), + SPH_C32(0xdfc50000), SPH_C32(0xb3021265), SPH_C32(0x8b0ec8b7), + SPH_C32(0xce9f992d), SPH_C32(0x824794a7), SPH_C32(0x781e0000), + SPH_C32(0x90b60000), SPH_C32(0xdcea0074), SPH_C32(0xe0120000), + SPH_C32(0xa785570d), SPH_C32(0x14951430), SPH_C32(0x648af573), + SPH_C32(0x2e7d9f13) }, + { SPH_C32(0xdd290000), SPH_C32(0x76710000), SPH_C32(0x0a960061), + SPH_C32(0x19ae3800), SPH_C32(0x54354eb9), SPH_C32(0xf2a3f76a), + SPH_C32(0x62ec6742), SPH_C32(0xb803ed16), SPH_C32(0x65440000), + SPH_C32(0xbbc40000), SPH_C32(0x94670074), SPH_C32(0x4f731800), + SPH_C32(0x824e79c8), SPH_C32(0xdcecabe0), SPH_C32(0xe528f15a), + SPH_C32(0x3008a9b5) }, + { SPH_C32(0x98300000), SPH_C32(0xdd7d0000), SPH_C32(0x3a280060), + SPH_C32(0x70a41800), SPH_C32(0x96c93ca0), SPH_C32(0x43777767), + SPH_C32(0x4f3d9d04), SPH_C32(0x9c32a201), SPH_C32(0x3d070000), + SPH_C32(0x3bba0000), SPH_C32(0xec540075), SPH_C32(0x89182000), + SPH_C32(0x65792514), SPH_C32(0xa541943d), SPH_C32(0x495b0f35), + SPH_C32(0x0a4cd004) }, + { SPH_C32(0xc0730000), SPH_C32(0x5d030000), SPH_C32(0x421b0061), + SPH_C32(0xb6cf2000), SPH_C32(0x71fe607c), SPH_C32(0x3ada48ba), + SPH_C32(0xe34e636b), SPH_C32(0xa676dbb0), SPH_C32(0x205d0000), + SPH_C32(0x10c80000), SPH_C32(0xa4d90075), SPH_C32(0x26793800), + SPH_C32(0x40b20bd1), SPH_C32(0x6d382bed), SPH_C32(0xc8f90b1c), + SPH_C32(0x1439e6a2) }, + { SPH_C32(0x20510000), SPH_C32(0xe2290000), SPH_C32(0x3c95007e), + SPH_C32(0xa36b0000), SPH_C32(0x3c9c1fb0), SPH_C32(0xf3d1628a), + SPH_C32(0x39aef1f5), SPH_C32(0x895cdde1), SPH_C32(0x7ff30000), + SPH_C32(0x22e60000), SPH_C32(0x5b9e007e), SPH_C32(0x771f0000), + SPH_C32(0xe4f774a3), SPH_C32(0x5c527a94), SPH_C32(0x90f29751), + SPH_C32(0xbe082edd) }, + { SPH_C32(0x78120000), SPH_C32(0x62570000), SPH_C32(0x44a6007f), + SPH_C32(0x65003800), SPH_C32(0xdbab436c), SPH_C32(0x8a7c5d57), + SPH_C32(0x95dd0f9a), SPH_C32(0xb318a450), SPH_C32(0x62a90000), + SPH_C32(0x09940000), SPH_C32(0x1313007e), SPH_C32(0xd87e1800), + SPH_C32(0xc13c5a66), SPH_C32(0x942bc544), SPH_C32(0x11509378), + SPH_C32(0xa07d187b) }, + { SPH_C32(0x3d0b0000), SPH_C32(0xc95b0000), SPH_C32(0x7418007e), + SPH_C32(0x0c0a1800), SPH_C32(0x19573175), SPH_C32(0x3ba8dd5a), + SPH_C32(0xb80cf5dc), SPH_C32(0x9729eb47), SPH_C32(0x3aea0000), + SPH_C32(0x89ea0000), SPH_C32(0x6b20007f), SPH_C32(0x1e152000), + SPH_C32(0x260b06ba), SPH_C32(0xed86fa99), SPH_C32(0xbd236d17), + SPH_C32(0x9a3961ca) }, + { SPH_C32(0x65480000), SPH_C32(0x49250000), SPH_C32(0x0c2b007f), + SPH_C32(0xca612000), SPH_C32(0xfe606da9), SPH_C32(0x4205e287), + SPH_C32(0x147f0bb3), SPH_C32(0xad6d92f6), SPH_C32(0x27b00000), + SPH_C32(0xa2980000), SPH_C32(0x23ad007f), SPH_C32(0xb1743800), + SPH_C32(0x03c0287f), SPH_C32(0x25ff4549), SPH_C32(0x3c81693e), + SPH_C32(0x844c576c) } +}; + +static const sph_u32 T512_48[256][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0xe6280000), SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), + SPH_C32(0xd3d002e0), SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), + SPH_C32(0x289506b4), SPH_C32(0xd75a4897), SPH_C32(0xf0c50000), + SPH_C32(0x59230000), SPH_C32(0x45820000), SPH_C32(0xe18d00c0), + SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), SPH_C32(0xcbe0fe1c), + SPH_C32(0x56a7b19f) }, + { SPH_C32(0xf0c50000), SPH_C32(0x59230000), SPH_C32(0x45820000), + SPH_C32(0xe18d00c0), SPH_C32(0x3b6d0631), SPH_C32(0xc2ed5699), + SPH_C32(0xcbe0fe1c), SPH_C32(0x56a7b19f), SPH_C32(0x16ed0000), + SPH_C32(0x15680000), SPH_C32(0xedd70000), SPH_C32(0x325d0220), + SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), SPH_C32(0xe375f8a8), + SPH_C32(0x81fdf908) }, + { SPH_C32(0x16ed0000), SPH_C32(0x15680000), SPH_C32(0xedd70000), + SPH_C32(0x325d0220), SPH_C32(0xe30c3689), SPH_C32(0x5a4ae643), + SPH_C32(0xe375f8a8), SPH_C32(0x81fdf908), SPH_C32(0xe6280000), + SPH_C32(0x4c4b0000), SPH_C32(0xa8550000), SPH_C32(0xd3d002e0), + SPH_C32(0xd86130b8), SPH_C32(0x98a7b0da), SPH_C32(0x289506b4), + SPH_C32(0xd75a4897) }, + { SPH_C32(0xb4310000), SPH_C32(0x77330000), SPH_C32(0xb15d0000), + SPH_C32(0x7fd004e0), SPH_C32(0x78a26138), SPH_C32(0xd116c35d), + SPH_C32(0xd256d489), SPH_C32(0x4e6f74de), SPH_C32(0xe3060000), + SPH_C32(0xbdc10000), SPH_C32(0x87130000), SPH_C32(0xbff20060), + SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), SPH_C32(0x73c5ab06), + SPH_C32(0x5bd61539) }, + { SPH_C32(0x52190000), SPH_C32(0x3b780000), SPH_C32(0x19080000), + SPH_C32(0xac000600), SPH_C32(0xa0c35180), SPH_C32(0x49b17387), + SPH_C32(0xfac3d23d), SPH_C32(0x99353c49), SPH_C32(0x13c30000), + SPH_C32(0xe4e20000), SPH_C32(0xc2910000), SPH_C32(0x5e7f00a0), + SPH_C32(0x15d70c2b), SPH_C32(0x4f5861c8), SPH_C32(0xb825551a), + SPH_C32(0x0d71a4a6) }, + { SPH_C32(0x44f40000), SPH_C32(0x2e100000), SPH_C32(0xf4df0000), + SPH_C32(0x9e5d0420), SPH_C32(0x43cf6709), SPH_C32(0x13fb95c4), + SPH_C32(0x19b62a95), SPH_C32(0x18c8c541), SPH_C32(0xf5eb0000), + SPH_C32(0xa8a90000), SPH_C32(0x6ac40000), SPH_C32(0x8daf0240), + SPH_C32(0xcdb63c93), SPH_C32(0xd7ffd112), SPH_C32(0x90b053ae), + SPH_C32(0xda2bec31) }, + { SPH_C32(0xa2dc0000), SPH_C32(0x625b0000), SPH_C32(0x5c8a0000), + SPH_C32(0x4d8d06c0), SPH_C32(0x9bae57b1), SPH_C32(0x8b5c251e), + SPH_C32(0x31232c21), SPH_C32(0xcf928dd6), SPH_C32(0x052e0000), + SPH_C32(0xf18a0000), SPH_C32(0x2f460000), SPH_C32(0x6c220280), + SPH_C32(0xf6db3aa2), SPH_C32(0x1512878b), SPH_C32(0x5b50adb2), + SPH_C32(0x8c8c5dae) }, + { SPH_C32(0xe3060000), SPH_C32(0xbdc10000), SPH_C32(0x87130000), + SPH_C32(0xbff20060), SPH_C32(0x2eba0a1a), SPH_C32(0x8db53751), + SPH_C32(0x73c5ab06), SPH_C32(0x5bd61539), SPH_C32(0x57370000), + SPH_C32(0xcaf20000), SPH_C32(0x364e0000), SPH_C32(0xc0220480), + SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), SPH_C32(0xa1937f8f), + SPH_C32(0x15b961e7) }, + { SPH_C32(0x052e0000), SPH_C32(0xf18a0000), SPH_C32(0x2f460000), + SPH_C32(0x6c220280), SPH_C32(0xf6db3aa2), SPH_C32(0x1512878b), + SPH_C32(0x5b50adb2), SPH_C32(0x8c8c5dae), SPH_C32(0xa7f20000), + SPH_C32(0x93d10000), SPH_C32(0x73cc0000), SPH_C32(0x21af0440), + SPH_C32(0x6d756d13), SPH_C32(0x9e4ea295), SPH_C32(0x6a738193), + SPH_C32(0x431ed078) }, + { SPH_C32(0x13c30000), SPH_C32(0xe4e20000), SPH_C32(0xc2910000), + SPH_C32(0x5e7f00a0), SPH_C32(0x15d70c2b), SPH_C32(0x4f5861c8), + SPH_C32(0xb825551a), SPH_C32(0x0d71a4a6), SPH_C32(0x41da0000), + SPH_C32(0xdf9a0000), SPH_C32(0xdb990000), SPH_C32(0xf27f06a0), + SPH_C32(0xb5145dab), SPH_C32(0x06e9124f), SPH_C32(0x42e68727), + SPH_C32(0x944498ef) }, + { SPH_C32(0xf5eb0000), SPH_C32(0xa8a90000), SPH_C32(0x6ac40000), + SPH_C32(0x8daf0240), SPH_C32(0xcdb63c93), SPH_C32(0xd7ffd112), + SPH_C32(0x90b053ae), SPH_C32(0xda2bec31), SPH_C32(0xb11f0000), + SPH_C32(0x86b90000), SPH_C32(0x9e1b0000), SPH_C32(0x13f20660), + SPH_C32(0x8e795b9a), SPH_C32(0xc40444d6), SPH_C32(0x8906793b), + SPH_C32(0xc2e32970) }, + { SPH_C32(0x57370000), SPH_C32(0xcaf20000), SPH_C32(0x364e0000), + SPH_C32(0xc0220480), SPH_C32(0x56186b22), SPH_C32(0x5ca3f40c), + SPH_C32(0xa1937f8f), SPH_C32(0x15b961e7), SPH_C32(0xb4310000), + SPH_C32(0x77330000), SPH_C32(0xb15d0000), SPH_C32(0x7fd004e0), + SPH_C32(0x78a26138), SPH_C32(0xd116c35d), SPH_C32(0xd256d489), + SPH_C32(0x4e6f74de) }, + { SPH_C32(0xb11f0000), SPH_C32(0x86b90000), SPH_C32(0x9e1b0000), + SPH_C32(0x13f20660), SPH_C32(0x8e795b9a), SPH_C32(0xc40444d6), + SPH_C32(0x8906793b), SPH_C32(0xc2e32970), SPH_C32(0x44f40000), + SPH_C32(0x2e100000), SPH_C32(0xf4df0000), SPH_C32(0x9e5d0420), + SPH_C32(0x43cf6709), SPH_C32(0x13fb95c4), SPH_C32(0x19b62a95), + SPH_C32(0x18c8c541) }, + { SPH_C32(0xa7f20000), SPH_C32(0x93d10000), SPH_C32(0x73cc0000), + SPH_C32(0x21af0440), SPH_C32(0x6d756d13), SPH_C32(0x9e4ea295), + SPH_C32(0x6a738193), SPH_C32(0x431ed078), SPH_C32(0xa2dc0000), + SPH_C32(0x625b0000), SPH_C32(0x5c8a0000), SPH_C32(0x4d8d06c0), + SPH_C32(0x9bae57b1), SPH_C32(0x8b5c251e), SPH_C32(0x31232c21), + SPH_C32(0xcf928dd6) }, + { SPH_C32(0x41da0000), SPH_C32(0xdf9a0000), SPH_C32(0xdb990000), + SPH_C32(0xf27f06a0), SPH_C32(0xb5145dab), SPH_C32(0x06e9124f), + SPH_C32(0x42e68727), SPH_C32(0x944498ef), SPH_C32(0x52190000), + SPH_C32(0x3b780000), SPH_C32(0x19080000), SPH_C32(0xac000600), + SPH_C32(0xa0c35180), SPH_C32(0x49b17387), SPH_C32(0xfac3d23d), + SPH_C32(0x99353c49) }, + { SPH_C32(0x02f20000), SPH_C32(0xa2810000), SPH_C32(0x873f0000), + SPH_C32(0xe36c7800), SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), + SPH_C32(0xc4c23237), SPH_C32(0x7f32259e), SPH_C32(0xbadd0000), + SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), SPH_C32(0xf7282800), + SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), SPH_C32(0xea5a8d14), + SPH_C32(0x2a2c18f0) }, + { SPH_C32(0xe4da0000), SPH_C32(0xeeca0000), SPH_C32(0x2f6a0000), + SPH_C32(0x30bc7ae0), SPH_C32(0xc67c4457), SPH_C32(0x9f9a9b0c), + SPH_C32(0xec573483), SPH_C32(0xa8686d09), SPH_C32(0x4a180000), + SPH_C32(0x4a8e0000), SPH_C32(0xf2650000), SPH_C32(0x16a528c0), + SPH_C32(0xe428127c), SPH_C32(0xf4f795a3), SPH_C32(0x21ba7308), + SPH_C32(0x7c8ba96f) }, + { SPH_C32(0xf2370000), SPH_C32(0xfba20000), SPH_C32(0xc2bd0000), + SPH_C32(0x02e178c0), SPH_C32(0x257072de), SPH_C32(0xc5d07d4f), + SPH_C32(0x0f22cc2b), SPH_C32(0x29959401), SPH_C32(0xac300000), + SPH_C32(0x06c50000), SPH_C32(0x5a300000), SPH_C32(0xc5752a20), + SPH_C32(0x3c4922c4), SPH_C32(0x6c502579), SPH_C32(0x092f75bc), + SPH_C32(0xabd1e1f8) }, + { SPH_C32(0x141f0000), SPH_C32(0xb7e90000), SPH_C32(0x6ae80000), + SPH_C32(0xd1317a20), SPH_C32(0xfd114266), SPH_C32(0x5d77cd95), + SPH_C32(0x27b7ca9f), SPH_C32(0xfecfdc96), SPH_C32(0x5cf50000), + SPH_C32(0x5fe60000), SPH_C32(0x1fb20000), SPH_C32(0x24f82ae0), + SPH_C32(0x072424f5), SPH_C32(0xaebd73e0), SPH_C32(0xc2cf8ba0), + SPH_C32(0xfd765067) }, + { SPH_C32(0xb6c30000), SPH_C32(0xd5b20000), SPH_C32(0x36620000), + SPH_C32(0x9cbc7ce0), SPH_C32(0x66bf15d7), SPH_C32(0xd62be88b), + SPH_C32(0x1694e6be), SPH_C32(0x315d5140), SPH_C32(0x59db0000), + SPH_C32(0xae6c0000), SPH_C32(0x30f40000), SPH_C32(0x48da2860), + SPH_C32(0xf1ff1e57), SPH_C32(0xbbaff46b), SPH_C32(0x999f2612), + SPH_C32(0x71fa0dc9) }, + { SPH_C32(0x50eb0000), SPH_C32(0x99f90000), SPH_C32(0x9e370000), + SPH_C32(0x4f6c7e00), SPH_C32(0xbede256f), SPH_C32(0x4e8c5851), + SPH_C32(0x3e01e00a), SPH_C32(0xe60719d7), SPH_C32(0xa91e0000), + SPH_C32(0xf74f0000), SPH_C32(0x75760000), SPH_C32(0xa95728a0), + SPH_C32(0xca921866), SPH_C32(0x7942a2f2), SPH_C32(0x527fd80e), + SPH_C32(0x275dbc56) }, + { SPH_C32(0x46060000), SPH_C32(0x8c910000), SPH_C32(0x73e00000), + SPH_C32(0x7d317c20), SPH_C32(0x5dd213e6), SPH_C32(0x14c6be12), + SPH_C32(0xdd7418a2), SPH_C32(0x67fae0df), SPH_C32(0x4f360000), + SPH_C32(0xbb040000), SPH_C32(0xdd230000), SPH_C32(0x7a872a40), + SPH_C32(0x12f328de), SPH_C32(0xe1e51228), SPH_C32(0x7aeadeba), + SPH_C32(0xf007f4c1) }, + { SPH_C32(0xa02e0000), SPH_C32(0xc0da0000), SPH_C32(0xdbb50000), + SPH_C32(0xaee17ec0), SPH_C32(0x85b3235e), SPH_C32(0x8c610ec8), + SPH_C32(0xf5e11e16), SPH_C32(0xb0a0a848), SPH_C32(0xbff30000), + SPH_C32(0xe2270000), SPH_C32(0x98a10000), SPH_C32(0x9b0a2a80), + SPH_C32(0x299e2eef), SPH_C32(0x230844b1), SPH_C32(0xb10a20a6), + SPH_C32(0xa6a0455e) }, + { SPH_C32(0xe1f40000), SPH_C32(0x1f400000), SPH_C32(0x002c0000), + SPH_C32(0x5c9e7860), SPH_C32(0x30a77ef5), SPH_C32(0x8a881c87), + SPH_C32(0xb7079931), SPH_C32(0x24e430a7), SPH_C32(0xedea0000), + SPH_C32(0xd95f0000), SPH_C32(0x81a90000), SPH_C32(0x370a2c80), + SPH_C32(0x895d7f6f), SPH_C32(0x6ab93736), SPH_C32(0x4bc9f29b), + SPH_C32(0x3f957917) }, + { SPH_C32(0x07dc0000), SPH_C32(0x530b0000), SPH_C32(0xa8790000), + SPH_C32(0x8f4e7a80), SPH_C32(0xe8c64e4d), SPH_C32(0x122fac5d), + SPH_C32(0x9f929f85), SPH_C32(0xf3be7830), SPH_C32(0x1d2f0000), + SPH_C32(0x807c0000), SPH_C32(0xc42b0000), SPH_C32(0xd6872c40), + SPH_C32(0xb230795e), SPH_C32(0xa85461af), SPH_C32(0x80290c87), + SPH_C32(0x6932c888) }, + { SPH_C32(0x11310000), SPH_C32(0x46630000), SPH_C32(0x45ae0000), + SPH_C32(0xbd1378a0), SPH_C32(0x0bca78c4), SPH_C32(0x48654a1e), + SPH_C32(0x7ce7672d), SPH_C32(0x72438138), SPH_C32(0xfb070000), + SPH_C32(0xcc370000), SPH_C32(0x6c7e0000), SPH_C32(0x05572ea0), + SPH_C32(0x6a5149e6), SPH_C32(0x30f3d175), SPH_C32(0xa8bc0a33), + SPH_C32(0xbe68801f) }, + { SPH_C32(0xf7190000), SPH_C32(0x0a280000), SPH_C32(0xedfb0000), + SPH_C32(0x6ec37a40), SPH_C32(0xd3ab487c), SPH_C32(0xd0c2fac4), + SPH_C32(0x54726199), SPH_C32(0xa519c9af), SPH_C32(0x0bc20000), + SPH_C32(0x95140000), SPH_C32(0x29fc0000), SPH_C32(0xe4da2e60), + SPH_C32(0x513c4fd7), SPH_C32(0xf21e87ec), SPH_C32(0x635cf42f), + SPH_C32(0xe8cf3180) }, + { SPH_C32(0x55c50000), SPH_C32(0x68730000), SPH_C32(0xb1710000), + SPH_C32(0x234e7c80), SPH_C32(0x48051fcd), SPH_C32(0x5b9edfda), + SPH_C32(0x65514db8), SPH_C32(0x6a8b4479), SPH_C32(0x0eec0000), + SPH_C32(0x649e0000), SPH_C32(0x06ba0000), SPH_C32(0x88f82ce0), + SPH_C32(0xa7e77575), SPH_C32(0xe70c0067), SPH_C32(0x380c599d), + SPH_C32(0x64436c2e) }, + { SPH_C32(0xb3ed0000), SPH_C32(0x24380000), SPH_C32(0x19240000), + SPH_C32(0xf09e7e60), SPH_C32(0x90642f75), SPH_C32(0xc3396f00), + SPH_C32(0x4dc44b0c), SPH_C32(0xbdd10cee), SPH_C32(0xfe290000), + SPH_C32(0x3dbd0000), SPH_C32(0x43380000), SPH_C32(0x69752c20), + SPH_C32(0x9c8a7344), SPH_C32(0x25e156fe), SPH_C32(0xf3eca781), + SPH_C32(0x32e4ddb1) }, + { SPH_C32(0xa5000000), SPH_C32(0x31500000), SPH_C32(0xf4f30000), + SPH_C32(0xc2c37c40), SPH_C32(0x736819fc), SPH_C32(0x99738943), + SPH_C32(0xaeb1b3a4), SPH_C32(0x3c2cf5e6), SPH_C32(0x18010000), + SPH_C32(0x71f60000), SPH_C32(0xeb6d0000), SPH_C32(0xbaa52ec0), + SPH_C32(0x44eb43fc), SPH_C32(0xbd46e624), SPH_C32(0xdb79a135), + SPH_C32(0xe5be9526) }, + { SPH_C32(0x43280000), SPH_C32(0x7d1b0000), SPH_C32(0x5ca60000), + SPH_C32(0x11137ea0), SPH_C32(0xab092944), SPH_C32(0x01d43999), + SPH_C32(0x8624b510), SPH_C32(0xeb76bd71), SPH_C32(0xe8c40000), + SPH_C32(0x28d50000), SPH_C32(0xaeef0000), SPH_C32(0x5b282e00), + SPH_C32(0x7f8645cd), SPH_C32(0x7fabb0bd), SPH_C32(0x10995f29), + SPH_C32(0xb31924b9) }, + { SPH_C32(0xbadd0000), SPH_C32(0x13ad0000), SPH_C32(0xb7e70000), + SPH_C32(0xf7282800), SPH_C32(0xdf45144d), SPH_C32(0x361ac33a), + SPH_C32(0xea5a8d14), SPH_C32(0x2a2c18f0), SPH_C32(0xb82f0000), + SPH_C32(0xb12c0000), SPH_C32(0x30d80000), SPH_C32(0x14445000), + SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), SPH_C32(0x2e98bf23), + SPH_C32(0x551e3d6e) }, + { SPH_C32(0x5cf50000), SPH_C32(0x5fe60000), SPH_C32(0x1fb20000), + SPH_C32(0x24f82ae0), SPH_C32(0x072424f5), SPH_C32(0xaebd73e0), + SPH_C32(0xc2cf8ba0), SPH_C32(0xfd765067), SPH_C32(0x48ea0000), + SPH_C32(0xe80f0000), SPH_C32(0x755a0000), SPH_C32(0xf5c950c0), + SPH_C32(0xfa356693), SPH_C32(0xf3cabe75), SPH_C32(0xe578413f), + SPH_C32(0x03b98cf1) }, + { SPH_C32(0x4a180000), SPH_C32(0x4a8e0000), SPH_C32(0xf2650000), + SPH_C32(0x16a528c0), SPH_C32(0xe428127c), SPH_C32(0xf4f795a3), + SPH_C32(0x21ba7308), SPH_C32(0x7c8ba96f), SPH_C32(0xaec20000), + SPH_C32(0xa4440000), SPH_C32(0xdd0f0000), SPH_C32(0x26195220), + SPH_C32(0x2254562b), SPH_C32(0x6b6d0eaf), SPH_C32(0xcded478b), + SPH_C32(0xd4e3c466) }, + { SPH_C32(0xac300000), SPH_C32(0x06c50000), SPH_C32(0x5a300000), + SPH_C32(0xc5752a20), SPH_C32(0x3c4922c4), SPH_C32(0x6c502579), + SPH_C32(0x092f75bc), SPH_C32(0xabd1e1f8), SPH_C32(0x5e070000), + SPH_C32(0xfd670000), SPH_C32(0x988d0000), SPH_C32(0xc79452e0), + SPH_C32(0x1939501a), SPH_C32(0xa9805836), SPH_C32(0x060db997), + SPH_C32(0x824475f9) }, + { SPH_C32(0x0eec0000), SPH_C32(0x649e0000), SPH_C32(0x06ba0000), + SPH_C32(0x88f82ce0), SPH_C32(0xa7e77575), SPH_C32(0xe70c0067), + SPH_C32(0x380c599d), SPH_C32(0x64436c2e), SPH_C32(0x5b290000), + SPH_C32(0x0ced0000), SPH_C32(0xb7cb0000), SPH_C32(0xabb65060), + SPH_C32(0xefe26ab8), SPH_C32(0xbc92dfbd), SPH_C32(0x5d5d1425), + SPH_C32(0x0ec82857) }, + { SPH_C32(0xe8c40000), SPH_C32(0x28d50000), SPH_C32(0xaeef0000), + SPH_C32(0x5b282e00), SPH_C32(0x7f8645cd), SPH_C32(0x7fabb0bd), + SPH_C32(0x10995f29), SPH_C32(0xb31924b9), SPH_C32(0xabec0000), + SPH_C32(0x55ce0000), SPH_C32(0xf2490000), SPH_C32(0x4a3b50a0), + SPH_C32(0xd48f6c89), SPH_C32(0x7e7f8924), SPH_C32(0x96bdea39), + SPH_C32(0x586f99c8) }, + { SPH_C32(0xfe290000), SPH_C32(0x3dbd0000), SPH_C32(0x43380000), + SPH_C32(0x69752c20), SPH_C32(0x9c8a7344), SPH_C32(0x25e156fe), + SPH_C32(0xf3eca781), SPH_C32(0x32e4ddb1), SPH_C32(0x4dc40000), + SPH_C32(0x19850000), SPH_C32(0x5a1c0000), SPH_C32(0x99eb5240), + SPH_C32(0x0cee5c31), SPH_C32(0xe6d839fe), SPH_C32(0xbe28ec8d), + SPH_C32(0x8f35d15f) }, + { SPH_C32(0x18010000), SPH_C32(0x71f60000), SPH_C32(0xeb6d0000), + SPH_C32(0xbaa52ec0), SPH_C32(0x44eb43fc), SPH_C32(0xbd46e624), + SPH_C32(0xdb79a135), SPH_C32(0xe5be9526), SPH_C32(0xbd010000), + SPH_C32(0x40a60000), SPH_C32(0x1f9e0000), SPH_C32(0x78665280), + SPH_C32(0x37835a00), SPH_C32(0x24356f67), SPH_C32(0x75c81291), + SPH_C32(0xd99260c0) }, + { SPH_C32(0x59db0000), SPH_C32(0xae6c0000), SPH_C32(0x30f40000), + SPH_C32(0x48da2860), SPH_C32(0xf1ff1e57), SPH_C32(0xbbaff46b), + SPH_C32(0x999f2612), SPH_C32(0x71fa0dc9), SPH_C32(0xef180000), + SPH_C32(0x7bde0000), SPH_C32(0x06960000), SPH_C32(0xd4665480), + SPH_C32(0x97400b80), SPH_C32(0x6d841ce0), SPH_C32(0x8f0bc0ac), + SPH_C32(0x40a75c89) }, + { SPH_C32(0xbff30000), SPH_C32(0xe2270000), SPH_C32(0x98a10000), + SPH_C32(0x9b0a2a80), SPH_C32(0x299e2eef), SPH_C32(0x230844b1), + SPH_C32(0xb10a20a6), SPH_C32(0xa6a0455e), SPH_C32(0x1fdd0000), + SPH_C32(0x22fd0000), SPH_C32(0x43140000), SPH_C32(0x35eb5440), + SPH_C32(0xac2d0db1), SPH_C32(0xaf694a79), SPH_C32(0x44eb3eb0), + SPH_C32(0x1600ed16) }, + { SPH_C32(0xa91e0000), SPH_C32(0xf74f0000), SPH_C32(0x75760000), + SPH_C32(0xa95728a0), SPH_C32(0xca921866), SPH_C32(0x7942a2f2), + SPH_C32(0x527fd80e), SPH_C32(0x275dbc56), SPH_C32(0xf9f50000), + SPH_C32(0x6eb60000), SPH_C32(0xeb410000), SPH_C32(0xe63b56a0), + SPH_C32(0x744c3d09), SPH_C32(0x37cefaa3), SPH_C32(0x6c7e3804), + SPH_C32(0xc15aa581) }, + { SPH_C32(0x4f360000), SPH_C32(0xbb040000), SPH_C32(0xdd230000), + SPH_C32(0x7a872a40), SPH_C32(0x12f328de), SPH_C32(0xe1e51228), + SPH_C32(0x7aeadeba), SPH_C32(0xf007f4c1), SPH_C32(0x09300000), + SPH_C32(0x37950000), SPH_C32(0xaec30000), SPH_C32(0x07b65660), + SPH_C32(0x4f213b38), SPH_C32(0xf523ac3a), SPH_C32(0xa79ec618), + SPH_C32(0x97fd141e) }, + { SPH_C32(0xedea0000), SPH_C32(0xd95f0000), SPH_C32(0x81a90000), + SPH_C32(0x370a2c80), SPH_C32(0x895d7f6f), SPH_C32(0x6ab93736), + SPH_C32(0x4bc9f29b), SPH_C32(0x3f957917), SPH_C32(0x0c1e0000), + SPH_C32(0xc61f0000), SPH_C32(0x81850000), SPH_C32(0x6b9454e0), + SPH_C32(0xb9fa019a), SPH_C32(0xe0312bb1), SPH_C32(0xfcce6baa), + SPH_C32(0x1b7149b0) }, + { SPH_C32(0x0bc20000), SPH_C32(0x95140000), SPH_C32(0x29fc0000), + SPH_C32(0xe4da2e60), SPH_C32(0x513c4fd7), SPH_C32(0xf21e87ec), + SPH_C32(0x635cf42f), SPH_C32(0xe8cf3180), SPH_C32(0xfcdb0000), + SPH_C32(0x9f3c0000), SPH_C32(0xc4070000), SPH_C32(0x8a195420), + SPH_C32(0x829707ab), SPH_C32(0x22dc7d28), SPH_C32(0x372e95b6), + SPH_C32(0x4dd6f82f) }, + { SPH_C32(0x1d2f0000), SPH_C32(0x807c0000), SPH_C32(0xc42b0000), + SPH_C32(0xd6872c40), SPH_C32(0xb230795e), SPH_C32(0xa85461af), + SPH_C32(0x80290c87), SPH_C32(0x6932c888), SPH_C32(0x1af30000), + SPH_C32(0xd3770000), SPH_C32(0x6c520000), SPH_C32(0x59c956c0), + SPH_C32(0x5af63713), SPH_C32(0xba7bcdf2), SPH_C32(0x1fbb9302), + SPH_C32(0x9a8cb0b8) }, + { SPH_C32(0xfb070000), SPH_C32(0xcc370000), SPH_C32(0x6c7e0000), + SPH_C32(0x05572ea0), SPH_C32(0x6a5149e6), SPH_C32(0x30f3d175), + SPH_C32(0xa8bc0a33), SPH_C32(0xbe68801f), SPH_C32(0xea360000), + SPH_C32(0x8a540000), SPH_C32(0x29d00000), SPH_C32(0xb8445600), + SPH_C32(0x619b3122), SPH_C32(0x78969b6b), SPH_C32(0xd45b6d1e), + SPH_C32(0xcc2b0127) }, + { SPH_C32(0xb82f0000), SPH_C32(0xb12c0000), SPH_C32(0x30d80000), + SPH_C32(0x14445000), SPH_C32(0xc15860a2), SPH_C32(0x3127e8ec), + SPH_C32(0x2e98bf23), SPH_C32(0x551e3d6e), SPH_C32(0x02f20000), + SPH_C32(0xa2810000), SPH_C32(0x873f0000), SPH_C32(0xe36c7800), + SPH_C32(0x1e1d74ef), SPH_C32(0x073d2bd6), SPH_C32(0xc4c23237), + SPH_C32(0x7f32259e) }, + { SPH_C32(0x5e070000), SPH_C32(0xfd670000), SPH_C32(0x988d0000), + SPH_C32(0xc79452e0), SPH_C32(0x1939501a), SPH_C32(0xa9805836), + SPH_C32(0x060db997), SPH_C32(0x824475f9), SPH_C32(0xf2370000), + SPH_C32(0xfba20000), SPH_C32(0xc2bd0000), SPH_C32(0x02e178c0), + SPH_C32(0x257072de), SPH_C32(0xc5d07d4f), SPH_C32(0x0f22cc2b), + SPH_C32(0x29959401) }, + { SPH_C32(0x48ea0000), SPH_C32(0xe80f0000), SPH_C32(0x755a0000), + SPH_C32(0xf5c950c0), SPH_C32(0xfa356693), SPH_C32(0xf3cabe75), + SPH_C32(0xe578413f), SPH_C32(0x03b98cf1), SPH_C32(0x141f0000), + SPH_C32(0xb7e90000), SPH_C32(0x6ae80000), SPH_C32(0xd1317a20), + SPH_C32(0xfd114266), SPH_C32(0x5d77cd95), SPH_C32(0x27b7ca9f), + SPH_C32(0xfecfdc96) }, + { SPH_C32(0xaec20000), SPH_C32(0xa4440000), SPH_C32(0xdd0f0000), + SPH_C32(0x26195220), SPH_C32(0x2254562b), SPH_C32(0x6b6d0eaf), + SPH_C32(0xcded478b), SPH_C32(0xd4e3c466), SPH_C32(0xe4da0000), + SPH_C32(0xeeca0000), SPH_C32(0x2f6a0000), SPH_C32(0x30bc7ae0), + SPH_C32(0xc67c4457), SPH_C32(0x9f9a9b0c), SPH_C32(0xec573483), + SPH_C32(0xa8686d09) }, + { SPH_C32(0x0c1e0000), SPH_C32(0xc61f0000), SPH_C32(0x81850000), + SPH_C32(0x6b9454e0), SPH_C32(0xb9fa019a), SPH_C32(0xe0312bb1), + SPH_C32(0xfcce6baa), SPH_C32(0x1b7149b0), SPH_C32(0xe1f40000), + SPH_C32(0x1f400000), SPH_C32(0x002c0000), SPH_C32(0x5c9e7860), + SPH_C32(0x30a77ef5), SPH_C32(0x8a881c87), SPH_C32(0xb7079931), + SPH_C32(0x24e430a7) }, + { SPH_C32(0xea360000), SPH_C32(0x8a540000), SPH_C32(0x29d00000), + SPH_C32(0xb8445600), SPH_C32(0x619b3122), SPH_C32(0x78969b6b), + SPH_C32(0xd45b6d1e), SPH_C32(0xcc2b0127), SPH_C32(0x11310000), + SPH_C32(0x46630000), SPH_C32(0x45ae0000), SPH_C32(0xbd1378a0), + SPH_C32(0x0bca78c4), SPH_C32(0x48654a1e), SPH_C32(0x7ce7672d), + SPH_C32(0x72438138) }, + { SPH_C32(0xfcdb0000), SPH_C32(0x9f3c0000), SPH_C32(0xc4070000), + SPH_C32(0x8a195420), SPH_C32(0x829707ab), SPH_C32(0x22dc7d28), + SPH_C32(0x372e95b6), SPH_C32(0x4dd6f82f), SPH_C32(0xf7190000), + SPH_C32(0x0a280000), SPH_C32(0xedfb0000), SPH_C32(0x6ec37a40), + SPH_C32(0xd3ab487c), SPH_C32(0xd0c2fac4), SPH_C32(0x54726199), + SPH_C32(0xa519c9af) }, + { SPH_C32(0x1af30000), SPH_C32(0xd3770000), SPH_C32(0x6c520000), + SPH_C32(0x59c956c0), SPH_C32(0x5af63713), SPH_C32(0xba7bcdf2), + SPH_C32(0x1fbb9302), SPH_C32(0x9a8cb0b8), SPH_C32(0x07dc0000), + SPH_C32(0x530b0000), SPH_C32(0xa8790000), SPH_C32(0x8f4e7a80), + SPH_C32(0xe8c64e4d), SPH_C32(0x122fac5d), SPH_C32(0x9f929f85), + SPH_C32(0xf3be7830) }, + { SPH_C32(0x5b290000), SPH_C32(0x0ced0000), SPH_C32(0xb7cb0000), + SPH_C32(0xabb65060), SPH_C32(0xefe26ab8), SPH_C32(0xbc92dfbd), + SPH_C32(0x5d5d1425), SPH_C32(0x0ec82857), SPH_C32(0x55c50000), + SPH_C32(0x68730000), SPH_C32(0xb1710000), SPH_C32(0x234e7c80), + SPH_C32(0x48051fcd), SPH_C32(0x5b9edfda), SPH_C32(0x65514db8), + SPH_C32(0x6a8b4479) }, + { SPH_C32(0xbd010000), SPH_C32(0x40a60000), SPH_C32(0x1f9e0000), + SPH_C32(0x78665280), SPH_C32(0x37835a00), SPH_C32(0x24356f67), + SPH_C32(0x75c81291), SPH_C32(0xd99260c0), SPH_C32(0xa5000000), + SPH_C32(0x31500000), SPH_C32(0xf4f30000), SPH_C32(0xc2c37c40), + SPH_C32(0x736819fc), SPH_C32(0x99738943), SPH_C32(0xaeb1b3a4), + SPH_C32(0x3c2cf5e6) }, + { SPH_C32(0xabec0000), SPH_C32(0x55ce0000), SPH_C32(0xf2490000), + SPH_C32(0x4a3b50a0), SPH_C32(0xd48f6c89), SPH_C32(0x7e7f8924), + SPH_C32(0x96bdea39), SPH_C32(0x586f99c8), SPH_C32(0x43280000), + SPH_C32(0x7d1b0000), SPH_C32(0x5ca60000), SPH_C32(0x11137ea0), + SPH_C32(0xab092944), SPH_C32(0x01d43999), SPH_C32(0x8624b510), + SPH_C32(0xeb76bd71) }, + { SPH_C32(0x4dc40000), SPH_C32(0x19850000), SPH_C32(0x5a1c0000), + SPH_C32(0x99eb5240), SPH_C32(0x0cee5c31), SPH_C32(0xe6d839fe), + SPH_C32(0xbe28ec8d), SPH_C32(0x8f35d15f), SPH_C32(0xb3ed0000), + SPH_C32(0x24380000), SPH_C32(0x19240000), SPH_C32(0xf09e7e60), + SPH_C32(0x90642f75), SPH_C32(0xc3396f00), SPH_C32(0x4dc44b0c), + SPH_C32(0xbdd10cee) }, + { SPH_C32(0xef180000), SPH_C32(0x7bde0000), SPH_C32(0x06960000), + SPH_C32(0xd4665480), SPH_C32(0x97400b80), SPH_C32(0x6d841ce0), + SPH_C32(0x8f0bc0ac), SPH_C32(0x40a75c89), SPH_C32(0xb6c30000), + SPH_C32(0xd5b20000), SPH_C32(0x36620000), SPH_C32(0x9cbc7ce0), + SPH_C32(0x66bf15d7), SPH_C32(0xd62be88b), SPH_C32(0x1694e6be), + SPH_C32(0x315d5140) }, + { SPH_C32(0x09300000), SPH_C32(0x37950000), SPH_C32(0xaec30000), + SPH_C32(0x07b65660), SPH_C32(0x4f213b38), SPH_C32(0xf523ac3a), + SPH_C32(0xa79ec618), SPH_C32(0x97fd141e), SPH_C32(0x46060000), + SPH_C32(0x8c910000), SPH_C32(0x73e00000), SPH_C32(0x7d317c20), + SPH_C32(0x5dd213e6), SPH_C32(0x14c6be12), SPH_C32(0xdd7418a2), + SPH_C32(0x67fae0df) }, + { SPH_C32(0x1fdd0000), SPH_C32(0x22fd0000), SPH_C32(0x43140000), + SPH_C32(0x35eb5440), SPH_C32(0xac2d0db1), SPH_C32(0xaf694a79), + SPH_C32(0x44eb3eb0), SPH_C32(0x1600ed16), SPH_C32(0xa02e0000), + SPH_C32(0xc0da0000), SPH_C32(0xdbb50000), SPH_C32(0xaee17ec0), + SPH_C32(0x85b3235e), SPH_C32(0x8c610ec8), SPH_C32(0xf5e11e16), + SPH_C32(0xb0a0a848) }, + { SPH_C32(0xf9f50000), SPH_C32(0x6eb60000), SPH_C32(0xeb410000), + SPH_C32(0xe63b56a0), SPH_C32(0x744c3d09), SPH_C32(0x37cefaa3), + SPH_C32(0x6c7e3804), SPH_C32(0xc15aa581), SPH_C32(0x50eb0000), + SPH_C32(0x99f90000), SPH_C32(0x9e370000), SPH_C32(0x4f6c7e00), + SPH_C32(0xbede256f), SPH_C32(0x4e8c5851), SPH_C32(0x3e01e00a), + SPH_C32(0xe60719d7) }, + { SPH_C32(0x1e6c0000), SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), + SPH_C32(0xbcb6b800), SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), + SPH_C32(0x6a0c1bc8), SPH_C32(0xb99dc2eb), SPH_C32(0x92560000), + SPH_C32(0x1eda0000), SPH_C32(0xea510000), SPH_C32(0xe8b13000), + SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), SPH_C32(0xb15c2254), + SPH_C32(0x33c5244f) }, + { SPH_C32(0xf8440000), SPH_C32(0x88090000), SPH_C32(0x227b0000), + SPH_C32(0x6f66bae0), SPH_C32(0xf425230e), SPH_C32(0x135a6300), + SPH_C32(0x42991d7c), SPH_C32(0x6ec78a7c), SPH_C32(0x62930000), + SPH_C32(0x47f90000), SPH_C32(0xafd30000), SPH_C32(0x093c30c0), + SPH_C32(0x92585094), SPH_C32(0x29163700), SPH_C32(0x7abcdc48), + SPH_C32(0x656295d0) }, + { SPH_C32(0xeea90000), SPH_C32(0x9d610000), SPH_C32(0xcfac0000), + SPH_C32(0x5d3bb8c0), SPH_C32(0x17291587), SPH_C32(0x49108543), + SPH_C32(0xa1ece5d4), SPH_C32(0xef3a7374), SPH_C32(0x84bb0000), + SPH_C32(0x0bb20000), SPH_C32(0x07860000), SPH_C32(0xdaec3220), + SPH_C32(0x4a39602c), SPH_C32(0xb1b187da), SPH_C32(0x5229dafc), + SPH_C32(0xb238dd47) }, + { SPH_C32(0x08810000), SPH_C32(0xd12a0000), SPH_C32(0x67f90000), + SPH_C32(0x8eebba20), SPH_C32(0xcf48253f), SPH_C32(0xd1b73599), + SPH_C32(0x8979e360), SPH_C32(0x38603be3), SPH_C32(0x747e0000), + SPH_C32(0x52910000), SPH_C32(0x42040000), SPH_C32(0x3b6132e0), + SPH_C32(0x7154661d), SPH_C32(0x735cd143), SPH_C32(0x99c924e0), + SPH_C32(0xe49f6cd8) }, + { SPH_C32(0xaa5d0000), SPH_C32(0xb3710000), SPH_C32(0x3b730000), + SPH_C32(0xc366bce0), SPH_C32(0x54e6728e), SPH_C32(0x5aeb1087), + SPH_C32(0xb85acf41), SPH_C32(0xf7f2b635), SPH_C32(0x71500000), + SPH_C32(0xa31b0000), SPH_C32(0x6d420000), SPH_C32(0x57433060), + SPH_C32(0x878f5cbf), SPH_C32(0x664e56c8), SPH_C32(0xc2998952), + SPH_C32(0x68133176) }, + { SPH_C32(0x4c750000), SPH_C32(0xff3a0000), SPH_C32(0x93260000), + SPH_C32(0x10b6be00), SPH_C32(0x8c874236), SPH_C32(0xc24ca05d), + SPH_C32(0x90cfc9f5), SPH_C32(0x20a8fea2), SPH_C32(0x81950000), + SPH_C32(0xfa380000), SPH_C32(0x28c00000), SPH_C32(0xb6ce30a0), + SPH_C32(0xbce25a8e), SPH_C32(0xa4a30051), SPH_C32(0x0979774e), + SPH_C32(0x3eb480e9) }, + { SPH_C32(0x5a980000), SPH_C32(0xea520000), SPH_C32(0x7ef10000), + SPH_C32(0x22ebbc20), SPH_C32(0x6f8b74bf), SPH_C32(0x9806461e), + SPH_C32(0x73ba315d), SPH_C32(0xa15507aa), SPH_C32(0x67bd0000), + SPH_C32(0xb6730000), SPH_C32(0x80950000), SPH_C32(0x651e3240), + SPH_C32(0x64836a36), SPH_C32(0x3c04b08b), SPH_C32(0x21ec71fa), + SPH_C32(0xe9eec87e) }, + { SPH_C32(0xbcb00000), SPH_C32(0xa6190000), SPH_C32(0xd6a40000), + SPH_C32(0xf13bbec0), SPH_C32(0xb7ea4407), SPH_C32(0x00a1f6c4), + SPH_C32(0x5b2f37e9), SPH_C32(0x760f4f3d), SPH_C32(0x97780000), + SPH_C32(0xef500000), SPH_C32(0xc5170000), SPH_C32(0x84933280), + SPH_C32(0x5fee6c07), SPH_C32(0xfee9e612), SPH_C32(0xea0c8fe6), + SPH_C32(0xbf4979e1) }, + { SPH_C32(0xfd6a0000), SPH_C32(0x79830000), SPH_C32(0x0d3d0000), + SPH_C32(0x0344b860), SPH_C32(0x02fe19ac), SPH_C32(0x0648e48b), + SPH_C32(0x19c9b0ce), SPH_C32(0xe24bd7d2), SPH_C32(0xc5610000), + SPH_C32(0xd4280000), SPH_C32(0xdc1f0000), SPH_C32(0x28933480), + SPH_C32(0xff2d3d87), SPH_C32(0xb7589595), SPH_C32(0x10cf5ddb), + SPH_C32(0x267c45a8) }, + { SPH_C32(0x1b420000), SPH_C32(0x35c80000), SPH_C32(0xa5680000), + SPH_C32(0xd094ba80), SPH_C32(0xda9f2914), SPH_C32(0x9eef5451), + SPH_C32(0x315cb67a), SPH_C32(0x35119f45), SPH_C32(0x35a40000), + SPH_C32(0x8d0b0000), SPH_C32(0x999d0000), SPH_C32(0xc91e3440), + SPH_C32(0xc4403bb6), SPH_C32(0x75b5c30c), SPH_C32(0xdb2fa3c7), + SPH_C32(0x70dbf437) }, + { SPH_C32(0x0daf0000), SPH_C32(0x20a00000), SPH_C32(0x48bf0000), + SPH_C32(0xe2c9b8a0), SPH_C32(0x39931f9d), SPH_C32(0xc4a5b212), + SPH_C32(0xd2294ed2), SPH_C32(0xb4ec664d), SPH_C32(0xd38c0000), + SPH_C32(0xc1400000), SPH_C32(0x31c80000), SPH_C32(0x1ace36a0), + SPH_C32(0x1c210b0e), SPH_C32(0xed1273d6), SPH_C32(0xf3baa573), + SPH_C32(0xa781bca0) }, + { SPH_C32(0xeb870000), SPH_C32(0x6ceb0000), SPH_C32(0xe0ea0000), + SPH_C32(0x3119ba40), SPH_C32(0xe1f22f25), SPH_C32(0x5c0202c8), + SPH_C32(0xfabc4866), SPH_C32(0x63b62eda), SPH_C32(0x23490000), + SPH_C32(0x98630000), SPH_C32(0x744a0000), SPH_C32(0xfb433660), + SPH_C32(0x274c0d3f), SPH_C32(0x2fff254f), SPH_C32(0x385a5b6f), + SPH_C32(0xf1260d3f) }, + { SPH_C32(0x495b0000), SPH_C32(0x0eb00000), SPH_C32(0xbc600000), + SPH_C32(0x7c94bc80), SPH_C32(0x7a5c7894), SPH_C32(0xd75e27d6), + SPH_C32(0xcb9f6447), SPH_C32(0xac24a30c), SPH_C32(0x26670000), + SPH_C32(0x69e90000), SPH_C32(0x5b0c0000), SPH_C32(0x976134e0), + SPH_C32(0xd197379d), SPH_C32(0x3aeda2c4), SPH_C32(0x630af6dd), + SPH_C32(0x7daa5091) }, + { SPH_C32(0xaf730000), SPH_C32(0x42fb0000), SPH_C32(0x14350000), + SPH_C32(0xaf44be60), SPH_C32(0xa23d482c), SPH_C32(0x4ff9970c), + SPH_C32(0xe30a62f3), SPH_C32(0x7b7eeb9b), SPH_C32(0xd6a20000), + SPH_C32(0x30ca0000), SPH_C32(0x1e8e0000), SPH_C32(0x76ec3420), + SPH_C32(0xeafa31ac), SPH_C32(0xf800f45d), SPH_C32(0xa8ea08c1), + SPH_C32(0x2b0de10e) }, + { SPH_C32(0xb99e0000), SPH_C32(0x57930000), SPH_C32(0xf9e20000), + SPH_C32(0x9d19bc40), SPH_C32(0x41317ea5), SPH_C32(0x15b3714f), + SPH_C32(0x007f9a5b), SPH_C32(0xfa831293), SPH_C32(0x308a0000), + SPH_C32(0x7c810000), SPH_C32(0xb6db0000), SPH_C32(0xa53c36c0), + SPH_C32(0x329b0114), SPH_C32(0x60a74487), SPH_C32(0x807f0e75), + SPH_C32(0xfc57a999) }, + { SPH_C32(0x5fb60000), SPH_C32(0x1bd80000), SPH_C32(0x51b70000), + SPH_C32(0x4ec9bea0), SPH_C32(0x99504e1d), SPH_C32(0x8d14c195), + SPH_C32(0x28ea9cef), SPH_C32(0x2dd95a04), SPH_C32(0xc04f0000), + SPH_C32(0x25a20000), SPH_C32(0xf3590000), SPH_C32(0x44b13600), + SPH_C32(0x09f60725), SPH_C32(0xa24a121e), SPH_C32(0x4b9ff069), + SPH_C32(0xaaf01806) }, + { SPH_C32(0x1c9e0000), SPH_C32(0x66c30000), SPH_C32(0x0d110000), + SPH_C32(0x5fdac000), SPH_C32(0x32596759), SPH_C32(0x8cc0f80c), + SPH_C32(0xaece29ff), SPH_C32(0xc6afe775), SPH_C32(0x288b0000), + SPH_C32(0x0d770000), SPH_C32(0x5db60000), SPH_C32(0x1f991800), + SPH_C32(0x767042e8), SPH_C32(0xdde1a2a3), SPH_C32(0x5b06af40), + SPH_C32(0x19e93cbf) }, + { SPH_C32(0xfab60000), SPH_C32(0x2a880000), SPH_C32(0xa5440000), + SPH_C32(0x8c0ac2e0), SPH_C32(0xea3857e1), SPH_C32(0x146748d6), + SPH_C32(0x865b2f4b), SPH_C32(0x11f5afe2), SPH_C32(0xd84e0000), + SPH_C32(0x54540000), SPH_C32(0x18340000), SPH_C32(0xfe1418c0), + SPH_C32(0x4d1d44d9), SPH_C32(0x1f0cf43a), SPH_C32(0x90e6515c), + SPH_C32(0x4f4e8d20) }, + { SPH_C32(0xec5b0000), SPH_C32(0x3fe00000), SPH_C32(0x48930000), + SPH_C32(0xbe57c0c0), SPH_C32(0x09346168), SPH_C32(0x4e2dae95), + SPH_C32(0x652ed7e3), SPH_C32(0x900856ea), SPH_C32(0x3e660000), + SPH_C32(0x181f0000), SPH_C32(0xb0610000), SPH_C32(0x2dc41a20), + SPH_C32(0x957c7461), SPH_C32(0x87ab44e0), SPH_C32(0xb87357e8), + SPH_C32(0x9814c5b7) }, + { SPH_C32(0x0a730000), SPH_C32(0x73ab0000), SPH_C32(0xe0c60000), + SPH_C32(0x6d87c220), SPH_C32(0xd15551d0), SPH_C32(0xd68a1e4f), + SPH_C32(0x4dbbd157), SPH_C32(0x47521e7d), SPH_C32(0xcea30000), + SPH_C32(0x413c0000), SPH_C32(0xf5e30000), SPH_C32(0xcc491ae0), + SPH_C32(0xae117250), SPH_C32(0x45461279), SPH_C32(0x7393a9f4), + SPH_C32(0xceb37428) }, + { SPH_C32(0xa8af0000), SPH_C32(0x11f00000), SPH_C32(0xbc4c0000), + SPH_C32(0x200ac4e0), SPH_C32(0x4afb0661), SPH_C32(0x5dd63b51), + SPH_C32(0x7c98fd76), SPH_C32(0x88c093ab), SPH_C32(0xcb8d0000), + SPH_C32(0xb0b60000), SPH_C32(0xdaa50000), SPH_C32(0xa06b1860), + SPH_C32(0x58ca48f2), SPH_C32(0x505495f2), SPH_C32(0x28c30446), + SPH_C32(0x423f2986) }, + { SPH_C32(0x4e870000), SPH_C32(0x5dbb0000), SPH_C32(0x14190000), + SPH_C32(0xf3dac600), SPH_C32(0x929a36d9), SPH_C32(0xc5718b8b), + SPH_C32(0x540dfbc2), SPH_C32(0x5f9adb3c), SPH_C32(0x3b480000), + SPH_C32(0xe9950000), SPH_C32(0x9f270000), SPH_C32(0x41e618a0), + SPH_C32(0x63a74ec3), SPH_C32(0x92b9c36b), SPH_C32(0xe323fa5a), + SPH_C32(0x14989819) }, + { SPH_C32(0x586a0000), SPH_C32(0x48d30000), SPH_C32(0xf9ce0000), + SPH_C32(0xc187c420), SPH_C32(0x71960050), SPH_C32(0x9f3b6dc8), + SPH_C32(0xb778036a), SPH_C32(0xde672234), SPH_C32(0xdd600000), + SPH_C32(0xa5de0000), SPH_C32(0x37720000), SPH_C32(0x92361a40), + SPH_C32(0xbbc67e7b), SPH_C32(0x0a1e73b1), SPH_C32(0xcbb6fcee), + SPH_C32(0xc3c2d08e) }, + { SPH_C32(0xbe420000), SPH_C32(0x04980000), SPH_C32(0x519b0000), + SPH_C32(0x1257c6c0), SPH_C32(0xa9f730e8), SPH_C32(0x079cdd12), + SPH_C32(0x9fed05de), SPH_C32(0x093d6aa3), SPH_C32(0x2da50000), + SPH_C32(0xfcfd0000), SPH_C32(0x72f00000), SPH_C32(0x73bb1a80), + SPH_C32(0x80ab784a), SPH_C32(0xc8f32528), SPH_C32(0x005602f2), + SPH_C32(0x95656111) }, + { SPH_C32(0xff980000), SPH_C32(0xdb020000), SPH_C32(0x8a020000), + SPH_C32(0xe028c060), SPH_C32(0x1ce36d43), SPH_C32(0x0175cf5d), + SPH_C32(0xdd0b82f9), SPH_C32(0x9d79f24c), SPH_C32(0x7fbc0000), + SPH_C32(0xc7850000), SPH_C32(0x6bf80000), SPH_C32(0xdfbb1c80), + SPH_C32(0x206829ca), SPH_C32(0x814256af), SPH_C32(0xfa95d0cf), + SPH_C32(0x0c505d58) }, + { SPH_C32(0x19b00000), SPH_C32(0x97490000), SPH_C32(0x22570000), + SPH_C32(0x33f8c280), SPH_C32(0xc4825dfb), SPH_C32(0x99d27f87), + SPH_C32(0xf59e844d), SPH_C32(0x4a23badb), SPH_C32(0x8f790000), + SPH_C32(0x9ea60000), SPH_C32(0x2e7a0000), SPH_C32(0x3e361c40), + SPH_C32(0x1b052ffb), SPH_C32(0x43af0036), SPH_C32(0x31752ed3), + SPH_C32(0x5af7ecc7) }, + { SPH_C32(0x0f5d0000), SPH_C32(0x82210000), SPH_C32(0xcf800000), + SPH_C32(0x01a5c0a0), SPH_C32(0x278e6b72), SPH_C32(0xc39899c4), + SPH_C32(0x16eb7ce5), SPH_C32(0xcbde43d3), SPH_C32(0x69510000), + SPH_C32(0xd2ed0000), SPH_C32(0x862f0000), SPH_C32(0xede61ea0), + SPH_C32(0xc3641f43), SPH_C32(0xdb08b0ec), SPH_C32(0x19e02867), + SPH_C32(0x8dada450) }, + { SPH_C32(0xe9750000), SPH_C32(0xce6a0000), SPH_C32(0x67d50000), + SPH_C32(0xd275c240), SPH_C32(0xffef5bca), SPH_C32(0x5b3f291e), + SPH_C32(0x3e7e7a51), SPH_C32(0x1c840b44), SPH_C32(0x99940000), + SPH_C32(0x8bce0000), SPH_C32(0xc3ad0000), SPH_C32(0x0c6b1e60), + SPH_C32(0xf8091972), SPH_C32(0x19e5e675), SPH_C32(0xd200d67b), + SPH_C32(0xdb0a15cf) }, + { SPH_C32(0x4ba90000), SPH_C32(0xac310000), SPH_C32(0x3b5f0000), + SPH_C32(0x9ff8c480), SPH_C32(0x64410c7b), SPH_C32(0xd0630c00), + SPH_C32(0x0f5d5670), SPH_C32(0xd3168692), SPH_C32(0x9cba0000), + SPH_C32(0x7a440000), SPH_C32(0xeceb0000), SPH_C32(0x60491ce0), + SPH_C32(0x0ed223d0), SPH_C32(0x0cf761fe), SPH_C32(0x89507bc9), + SPH_C32(0x57864861) }, + { SPH_C32(0xad810000), SPH_C32(0xe07a0000), SPH_C32(0x930a0000), + SPH_C32(0x4c28c660), SPH_C32(0xbc203cc3), SPH_C32(0x48c4bcda), + SPH_C32(0x27c850c4), SPH_C32(0x044cce05), SPH_C32(0x6c7f0000), + SPH_C32(0x23670000), SPH_C32(0xa9690000), SPH_C32(0x81c41c20), + SPH_C32(0x35bf25e1), SPH_C32(0xce1a3767), SPH_C32(0x42b085d5), + SPH_C32(0x0121f9fe) }, + { SPH_C32(0xbb6c0000), SPH_C32(0xf5120000), SPH_C32(0x7edd0000), + SPH_C32(0x7e75c440), SPH_C32(0x5f2c0a4a), SPH_C32(0x128e5a99), + SPH_C32(0xc4bda86c), SPH_C32(0x85b1370d), SPH_C32(0x8a570000), + SPH_C32(0x6f2c0000), SPH_C32(0x013c0000), SPH_C32(0x52141ec0), + SPH_C32(0xedde1559), SPH_C32(0x56bd87bd), SPH_C32(0x6a258361), + SPH_C32(0xd67bb169) }, + { SPH_C32(0x5d440000), SPH_C32(0xb9590000), SPH_C32(0xd6880000), + SPH_C32(0xada5c6a0), SPH_C32(0x874d3af2), SPH_C32(0x8a29ea43), + SPH_C32(0xec28aed8), SPH_C32(0x52eb7f9a), SPH_C32(0x7a920000), + SPH_C32(0x360f0000), SPH_C32(0x44be0000), SPH_C32(0xb3991e00), + SPH_C32(0xd6b31368), SPH_C32(0x9450d124), SPH_C32(0xa1c57d7d), + SPH_C32(0x80dc00f6) }, + { SPH_C32(0xa4b10000), SPH_C32(0xd7ef0000), SPH_C32(0x3dc90000), + SPH_C32(0x4b9e9000), SPH_C32(0xf30107fb), SPH_C32(0xbde710e0), + SPH_C32(0x805696dc), SPH_C32(0x93b1da1b), SPH_C32(0x2a790000), + SPH_C32(0xaff60000), SPH_C32(0xda890000), SPH_C32(0xfcf56000), + SPH_C32(0x686d3607), SPH_C32(0xdadc8975), SPH_C32(0x9fc49d77), + SPH_C32(0x66db1921) }, + { SPH_C32(0x42990000), SPH_C32(0x9ba40000), SPH_C32(0x959c0000), + SPH_C32(0x984e92e0), SPH_C32(0x2b603743), SPH_C32(0x2540a03a), + SPH_C32(0xa8c39068), SPH_C32(0x44eb928c), SPH_C32(0xdabc0000), + SPH_C32(0xf6d50000), SPH_C32(0x9f0b0000), SPH_C32(0x1d7860c0), + SPH_C32(0x53003036), SPH_C32(0x1831dfec), SPH_C32(0x5424636b), + SPH_C32(0x307ca8be) }, + { SPH_C32(0x54740000), SPH_C32(0x8ecc0000), SPH_C32(0x784b0000), + SPH_C32(0xaa1390c0), SPH_C32(0xc86c01ca), SPH_C32(0x7f0a4679), + SPH_C32(0x4bb668c0), SPH_C32(0xc5166b84), SPH_C32(0x3c940000), + SPH_C32(0xba9e0000), SPH_C32(0x375e0000), SPH_C32(0xcea86220), + SPH_C32(0x8b61008e), SPH_C32(0x80966f36), SPH_C32(0x7cb165df), + SPH_C32(0xe726e029) }, + { SPH_C32(0xb25c0000), SPH_C32(0xc2870000), SPH_C32(0xd01e0000), + SPH_C32(0x79c39220), SPH_C32(0x100d3172), SPH_C32(0xe7adf6a3), + SPH_C32(0x63236e74), SPH_C32(0x124c2313), SPH_C32(0xcc510000), + SPH_C32(0xe3bd0000), SPH_C32(0x72dc0000), SPH_C32(0x2f2562e0), + SPH_C32(0xb00c06bf), SPH_C32(0x427b39af), SPH_C32(0xb7519bc3), + SPH_C32(0xb18151b6) }, + { SPH_C32(0x10800000), SPH_C32(0xa0dc0000), SPH_C32(0x8c940000), + SPH_C32(0x344e94e0), SPH_C32(0x8ba366c3), SPH_C32(0x6cf1d3bd), + SPH_C32(0x52004255), SPH_C32(0xdddeaec5), SPH_C32(0xc97f0000), + SPH_C32(0x12370000), SPH_C32(0x5d9a0000), SPH_C32(0x43076060), + SPH_C32(0x46d73c1d), SPH_C32(0x5769be24), SPH_C32(0xec013671), + SPH_C32(0x3d0d0c18) }, + { SPH_C32(0xf6a80000), SPH_C32(0xec970000), SPH_C32(0x24c10000), + SPH_C32(0xe79e9600), SPH_C32(0x53c2567b), SPH_C32(0xf4566367), + SPH_C32(0x7a9544e1), SPH_C32(0x0a84e652), SPH_C32(0x39ba0000), + SPH_C32(0x4b140000), SPH_C32(0x18180000), SPH_C32(0xa28a60a0), + SPH_C32(0x7dba3a2c), SPH_C32(0x9584e8bd), SPH_C32(0x27e1c86d), + SPH_C32(0x6baabd87) }, + { SPH_C32(0xe0450000), SPH_C32(0xf9ff0000), SPH_C32(0xc9160000), + SPH_C32(0xd5c39420), SPH_C32(0xb0ce60f2), SPH_C32(0xae1c8524), + SPH_C32(0x99e0bc49), SPH_C32(0x8b791f5a), SPH_C32(0xdf920000), + SPH_C32(0x075f0000), SPH_C32(0xb04d0000), SPH_C32(0x715a6240), + SPH_C32(0xa5db0a94), SPH_C32(0x0d235867), SPH_C32(0x0f74ced9), + SPH_C32(0xbcf0f510) }, + { SPH_C32(0x066d0000), SPH_C32(0xb5b40000), SPH_C32(0x61430000), + SPH_C32(0x061396c0), SPH_C32(0x68af504a), SPH_C32(0x36bb35fe), + SPH_C32(0xb175bafd), SPH_C32(0x5c2357cd), SPH_C32(0x2f570000), + SPH_C32(0x5e7c0000), SPH_C32(0xf5cf0000), SPH_C32(0x90d76280), + SPH_C32(0x9eb60ca5), SPH_C32(0xcfce0efe), SPH_C32(0xc49430c5), + SPH_C32(0xea57448f) }, + { SPH_C32(0x47b70000), SPH_C32(0x6a2e0000), SPH_C32(0xbada0000), + SPH_C32(0xf46c9060), SPH_C32(0xddbb0de1), SPH_C32(0x305227b1), + SPH_C32(0xf3933dda), SPH_C32(0xc867cf22), SPH_C32(0x7d4e0000), + SPH_C32(0x65040000), SPH_C32(0xecc70000), SPH_C32(0x3cd76480), + SPH_C32(0x3e755d25), SPH_C32(0x867f7d79), SPH_C32(0x3e57e2f8), + SPH_C32(0x736278c6) }, + { SPH_C32(0xa19f0000), SPH_C32(0x26650000), SPH_C32(0x128f0000), + SPH_C32(0x27bc9280), SPH_C32(0x05da3d59), SPH_C32(0xa8f5976b), + SPH_C32(0xdb063b6e), SPH_C32(0x1f3d87b5), SPH_C32(0x8d8b0000), + SPH_C32(0x3c270000), SPH_C32(0xa9450000), SPH_C32(0xdd5a6440), + SPH_C32(0x05185b14), SPH_C32(0x44922be0), SPH_C32(0xf5b71ce4), + SPH_C32(0x25c5c959) }, + { SPH_C32(0xb7720000), SPH_C32(0x330d0000), SPH_C32(0xff580000), + SPH_C32(0x15e190a0), SPH_C32(0xe6d60bd0), SPH_C32(0xf2bf7128), + SPH_C32(0x3873c3c6), SPH_C32(0x9ec07ebd), SPH_C32(0x6ba30000), + SPH_C32(0x706c0000), SPH_C32(0x01100000), SPH_C32(0x0e8a66a0), + SPH_C32(0xdd796bac), SPH_C32(0xdc359b3a), SPH_C32(0xdd221a50), + SPH_C32(0xf29f81ce) }, + { SPH_C32(0x515a0000), SPH_C32(0x7f460000), SPH_C32(0x570d0000), + SPH_C32(0xc6319240), SPH_C32(0x3eb73b68), SPH_C32(0x6a18c1f2), + SPH_C32(0x10e6c572), SPH_C32(0x499a362a), SPH_C32(0x9b660000), + SPH_C32(0x294f0000), SPH_C32(0x44920000), SPH_C32(0xef076660), + SPH_C32(0xe6146d9d), SPH_C32(0x1ed8cda3), SPH_C32(0x16c2e44c), + SPH_C32(0xa4383051) }, + { SPH_C32(0xf3860000), SPH_C32(0x1d1d0000), SPH_C32(0x0b870000), + SPH_C32(0x8bbc9480), SPH_C32(0xa5196cd9), SPH_C32(0xe144e4ec), + SPH_C32(0x21c5e953), SPH_C32(0x8608bbfc), SPH_C32(0x9e480000), + SPH_C32(0xd8c50000), SPH_C32(0x6bd40000), SPH_C32(0x832564e0), + SPH_C32(0x10cf573f), SPH_C32(0x0bca4a28), SPH_C32(0x4d9249fe), + SPH_C32(0x28b46dff) }, + { SPH_C32(0x15ae0000), SPH_C32(0x51560000), SPH_C32(0xa3d20000), + SPH_C32(0x586c9660), SPH_C32(0x7d785c61), SPH_C32(0x79e35436), + SPH_C32(0x0950efe7), SPH_C32(0x5152f36b), SPH_C32(0x6e8d0000), + SPH_C32(0x81e60000), SPH_C32(0x2e560000), SPH_C32(0x62a86420), + SPH_C32(0x2ba2510e), SPH_C32(0xc9271cb1), SPH_C32(0x8672b7e2), + SPH_C32(0x7e13dc60) }, + { SPH_C32(0x03430000), SPH_C32(0x443e0000), SPH_C32(0x4e050000), + SPH_C32(0x6a319440), SPH_C32(0x9e746ae8), SPH_C32(0x23a9b275), + SPH_C32(0xea25174f), SPH_C32(0xd0af0a63), SPH_C32(0x88a50000), + SPH_C32(0xcdad0000), SPH_C32(0x86030000), SPH_C32(0xb17866c0), + SPH_C32(0xf3c361b6), SPH_C32(0x5180ac6b), SPH_C32(0xaee7b156), + SPH_C32(0xa94994f7) }, + { SPH_C32(0xe56b0000), SPH_C32(0x08750000), SPH_C32(0xe6500000), + SPH_C32(0xb9e196a0), SPH_C32(0x46155a50), SPH_C32(0xbb0e02af), + SPH_C32(0xc2b011fb), SPH_C32(0x07f542f4), SPH_C32(0x78600000), + SPH_C32(0x948e0000), SPH_C32(0xc3810000), SPH_C32(0x50f56600), + SPH_C32(0xc8ae6787), SPH_C32(0x936dfaf2), SPH_C32(0x65074f4a), + SPH_C32(0xffee2568) }, + { SPH_C32(0xa6430000), SPH_C32(0x756e0000), SPH_C32(0xbaf60000), + SPH_C32(0xa8f2e800), SPH_C32(0xed1c7314), SPH_C32(0xbada3b36), + SPH_C32(0x4494a4eb), SPH_C32(0xec83ff85), SPH_C32(0x90a40000), + SPH_C32(0xbc5b0000), SPH_C32(0x6d6e0000), SPH_C32(0x0bdd4800), + SPH_C32(0xb728224a), SPH_C32(0xecc64a4f), SPH_C32(0x759e1063), + SPH_C32(0x4cf701d1) }, + { SPH_C32(0x406b0000), SPH_C32(0x39250000), SPH_C32(0x12a30000), + SPH_C32(0x7b22eae0), SPH_C32(0x357d43ac), SPH_C32(0x227d8bec), + SPH_C32(0x6c01a25f), SPH_C32(0x3bd9b712), SPH_C32(0x60610000), + SPH_C32(0xe5780000), SPH_C32(0x28ec0000), SPH_C32(0xea5048c0), + SPH_C32(0x8c45247b), SPH_C32(0x2e2b1cd6), SPH_C32(0xbe7eee7f), + SPH_C32(0x1a50b04e) }, + { SPH_C32(0x56860000), SPH_C32(0x2c4d0000), SPH_C32(0xff740000), + SPH_C32(0x497fe8c0), SPH_C32(0xd6717525), SPH_C32(0x78376daf), + SPH_C32(0x8f745af7), SPH_C32(0xba244e1a), SPH_C32(0x86490000), + SPH_C32(0xa9330000), SPH_C32(0x80b90000), SPH_C32(0x39804a20), + SPH_C32(0x542414c3), SPH_C32(0xb68cac0c), SPH_C32(0x96ebe8cb), + SPH_C32(0xcd0af8d9) }, + { SPH_C32(0xb0ae0000), SPH_C32(0x60060000), SPH_C32(0x57210000), + SPH_C32(0x9aafea20), SPH_C32(0x0e10459d), SPH_C32(0xe090dd75), + SPH_C32(0xa7e15c43), SPH_C32(0x6d7e068d), SPH_C32(0x768c0000), + SPH_C32(0xf0100000), SPH_C32(0xc53b0000), SPH_C32(0xd80d4ae0), + SPH_C32(0x6f4912f2), SPH_C32(0x7461fa95), SPH_C32(0x5d0b16d7), + SPH_C32(0x9bad4946) }, + { SPH_C32(0x12720000), SPH_C32(0x025d0000), SPH_C32(0x0bab0000), + SPH_C32(0xd722ece0), SPH_C32(0x95be122c), SPH_C32(0x6bccf86b), + SPH_C32(0x96c27062), SPH_C32(0xa2ec8b5b), SPH_C32(0x73a20000), + SPH_C32(0x019a0000), SPH_C32(0xea7d0000), SPH_C32(0xb42f4860), + SPH_C32(0x99922850), SPH_C32(0x61737d1e), SPH_C32(0x065bbb65), + SPH_C32(0x172114e8) }, + { SPH_C32(0xf45a0000), SPH_C32(0x4e160000), SPH_C32(0xa3fe0000), + SPH_C32(0x04f2ee00), SPH_C32(0x4ddf2294), SPH_C32(0xf36b48b1), + SPH_C32(0xbe5776d6), SPH_C32(0x75b6c3cc), SPH_C32(0x83670000), + SPH_C32(0x58b90000), SPH_C32(0xafff0000), SPH_C32(0x55a248a0), + SPH_C32(0xa2ff2e61), SPH_C32(0xa39e2b87), SPH_C32(0xcdbb4579), + SPH_C32(0x4186a577) }, + { SPH_C32(0xe2b70000), SPH_C32(0x5b7e0000), SPH_C32(0x4e290000), + SPH_C32(0x36afec20), SPH_C32(0xaed3141d), SPH_C32(0xa921aef2), + SPH_C32(0x5d228e7e), SPH_C32(0xf44b3ac4), SPH_C32(0x654f0000), + SPH_C32(0x14f20000), SPH_C32(0x07aa0000), SPH_C32(0x86724a40), + SPH_C32(0x7a9e1ed9), SPH_C32(0x3b399b5d), SPH_C32(0xe52e43cd), + SPH_C32(0x96dcede0) }, + { SPH_C32(0x049f0000), SPH_C32(0x17350000), SPH_C32(0xe67c0000), + SPH_C32(0xe57feec0), SPH_C32(0x76b224a5), SPH_C32(0x31861e28), + SPH_C32(0x75b788ca), SPH_C32(0x23117253), SPH_C32(0x958a0000), + SPH_C32(0x4dd10000), SPH_C32(0x42280000), SPH_C32(0x67ff4a80), + SPH_C32(0x41f318e8), SPH_C32(0xf9d4cdc4), SPH_C32(0x2ecebdd1), + SPH_C32(0xc07b5c7f) }, + { SPH_C32(0x45450000), SPH_C32(0xc8af0000), SPH_C32(0x3de50000), + SPH_C32(0x1700e860), SPH_C32(0xc3a6790e), SPH_C32(0x376f0c67), + SPH_C32(0x37510fed), SPH_C32(0xb755eabc), SPH_C32(0xc7930000), + SPH_C32(0x76a90000), SPH_C32(0x5b200000), SPH_C32(0xcbff4c80), + SPH_C32(0xe1304968), SPH_C32(0xb065be43), SPH_C32(0xd40d6fec), + SPH_C32(0x594e6036) }, + { SPH_C32(0xa36d0000), SPH_C32(0x84e40000), SPH_C32(0x95b00000), + SPH_C32(0xc4d0ea80), SPH_C32(0x1bc749b6), SPH_C32(0xafc8bcbd), + SPH_C32(0x1fc40959), SPH_C32(0x600fa22b), SPH_C32(0x37560000), + SPH_C32(0x2f8a0000), SPH_C32(0x1ea20000), SPH_C32(0x2a724c40), + SPH_C32(0xda5d4f59), SPH_C32(0x7288e8da), SPH_C32(0x1fed91f0), + SPH_C32(0x0fe9d1a9) }, + { SPH_C32(0xb5800000), SPH_C32(0x918c0000), SPH_C32(0x78670000), + SPH_C32(0xf68de8a0), SPH_C32(0xf8cb7f3f), SPH_C32(0xf5825afe), + SPH_C32(0xfcb1f1f1), SPH_C32(0xe1f25b23), SPH_C32(0xd17e0000), + SPH_C32(0x63c10000), SPH_C32(0xb6f70000), SPH_C32(0xf9a24ea0), + SPH_C32(0x023c7fe1), SPH_C32(0xea2f5800), SPH_C32(0x37789744), + SPH_C32(0xd8b3993e) }, + { SPH_C32(0x53a80000), SPH_C32(0xddc70000), SPH_C32(0xd0320000), + SPH_C32(0x255dea40), SPH_C32(0x20aa4f87), SPH_C32(0x6d25ea24), + SPH_C32(0xd424f745), SPH_C32(0x36a813b4), SPH_C32(0x21bb0000), + SPH_C32(0x3ae20000), SPH_C32(0xf3750000), SPH_C32(0x182f4e60), + SPH_C32(0x395179d0), SPH_C32(0x28c20e99), SPH_C32(0xfc986958), + SPH_C32(0x8e1428a1) }, + { SPH_C32(0xf1740000), SPH_C32(0xbf9c0000), SPH_C32(0x8cb80000), + SPH_C32(0x68d0ec80), SPH_C32(0xbb041836), SPH_C32(0xe679cf3a), + SPH_C32(0xe507db64), SPH_C32(0xf93a9e62), SPH_C32(0x24950000), + SPH_C32(0xcb680000), SPH_C32(0xdc330000), SPH_C32(0x740d4ce0), + SPH_C32(0xcf8a4372), SPH_C32(0x3dd08912), SPH_C32(0xa7c8c4ea), + SPH_C32(0x0298750f) }, + { SPH_C32(0x175c0000), SPH_C32(0xf3d70000), SPH_C32(0x24ed0000), + SPH_C32(0xbb00ee60), SPH_C32(0x6365288e), SPH_C32(0x7ede7fe0), + SPH_C32(0xcd92ddd0), SPH_C32(0x2e60d6f5), SPH_C32(0xd4500000), + SPH_C32(0x924b0000), SPH_C32(0x99b10000), SPH_C32(0x95804c20), + SPH_C32(0xf4e74543), SPH_C32(0xff3ddf8b), SPH_C32(0x6c283af6), + SPH_C32(0x543fc490) }, + { SPH_C32(0x01b10000), SPH_C32(0xe6bf0000), SPH_C32(0xc93a0000), + SPH_C32(0x895dec40), SPH_C32(0x80691e07), SPH_C32(0x249499a3), + SPH_C32(0x2ee72578), SPH_C32(0xaf9d2ffd), SPH_C32(0x32780000), + SPH_C32(0xde000000), SPH_C32(0x31e40000), SPH_C32(0x46504ec0), + SPH_C32(0x2c8675fb), SPH_C32(0x679a6f51), SPH_C32(0x44bd3c42), + SPH_C32(0x83658c07) }, + { SPH_C32(0xe7990000), SPH_C32(0xaaf40000), SPH_C32(0x616f0000), + SPH_C32(0x5a8deea0), SPH_C32(0x58082ebf), SPH_C32(0xbc332979), + SPH_C32(0x067223cc), SPH_C32(0x78c7676a), SPH_C32(0xc2bd0000), + SPH_C32(0x87230000), SPH_C32(0x74660000), SPH_C32(0xa7dd4e00), + SPH_C32(0x17eb73ca), SPH_C32(0xa57739c8), SPH_C32(0x8f5dc25e), + SPH_C32(0xd5c23d98) }, + { SPH_C32(0x92560000), SPH_C32(0x1eda0000), SPH_C32(0xea510000), + SPH_C32(0xe8b13000), SPH_C32(0xa93556a5), SPH_C32(0xebfb6199), + SPH_C32(0xb15c2254), SPH_C32(0x33c5244f), SPH_C32(0x8c3a0000), + SPH_C32(0xda980000), SPH_C32(0x607f0000), SPH_C32(0x54078800), + SPH_C32(0x85714513), SPH_C32(0x6006b243), SPH_C32(0xdb50399c), + SPH_C32(0x8a58e6a4) }, + { SPH_C32(0x747e0000), SPH_C32(0x52910000), SPH_C32(0x42040000), + SPH_C32(0x3b6132e0), SPH_C32(0x7154661d), SPH_C32(0x735cd143), + SPH_C32(0x99c924e0), SPH_C32(0xe49f6cd8), SPH_C32(0x7cff0000), + SPH_C32(0x83bb0000), SPH_C32(0x25fd0000), SPH_C32(0xb58a88c0), + SPH_C32(0xbe1c4322), SPH_C32(0xa2ebe4da), SPH_C32(0x10b0c780), + SPH_C32(0xdcff573b) }, + { SPH_C32(0x62930000), SPH_C32(0x47f90000), SPH_C32(0xafd30000), + SPH_C32(0x093c30c0), SPH_C32(0x92585094), SPH_C32(0x29163700), + SPH_C32(0x7abcdc48), SPH_C32(0x656295d0), SPH_C32(0x9ad70000), + SPH_C32(0xcff00000), SPH_C32(0x8da80000), SPH_C32(0x665a8a20), + SPH_C32(0x667d739a), SPH_C32(0x3a4c5400), SPH_C32(0x3825c134), + SPH_C32(0x0ba51fac) }, + { SPH_C32(0x84bb0000), SPH_C32(0x0bb20000), SPH_C32(0x07860000), + SPH_C32(0xdaec3220), SPH_C32(0x4a39602c), SPH_C32(0xb1b187da), + SPH_C32(0x5229dafc), SPH_C32(0xb238dd47), SPH_C32(0x6a120000), + SPH_C32(0x96d30000), SPH_C32(0xc82a0000), SPH_C32(0x87d78ae0), + SPH_C32(0x5d1075ab), SPH_C32(0xf8a10299), SPH_C32(0xf3c53f28), + SPH_C32(0x5d02ae33) }, + { SPH_C32(0x26670000), SPH_C32(0x69e90000), SPH_C32(0x5b0c0000), + SPH_C32(0x976134e0), SPH_C32(0xd197379d), SPH_C32(0x3aeda2c4), + SPH_C32(0x630af6dd), SPH_C32(0x7daa5091), SPH_C32(0x6f3c0000), + SPH_C32(0x67590000), SPH_C32(0xe76c0000), SPH_C32(0xebf58860), + SPH_C32(0xabcb4f09), SPH_C32(0xedb38512), SPH_C32(0xa895929a), + SPH_C32(0xd18ef39d) }, + { SPH_C32(0xc04f0000), SPH_C32(0x25a20000), SPH_C32(0xf3590000), + SPH_C32(0x44b13600), SPH_C32(0x09f60725), SPH_C32(0xa24a121e), + SPH_C32(0x4b9ff069), SPH_C32(0xaaf01806), SPH_C32(0x9ff90000), + SPH_C32(0x3e7a0000), SPH_C32(0xa2ee0000), SPH_C32(0x0a7888a0), + SPH_C32(0x90a64938), SPH_C32(0x2f5ed38b), SPH_C32(0x63756c86), + SPH_C32(0x87294202) }, + { SPH_C32(0xd6a20000), SPH_C32(0x30ca0000), SPH_C32(0x1e8e0000), + SPH_C32(0x76ec3420), SPH_C32(0xeafa31ac), SPH_C32(0xf800f45d), + SPH_C32(0xa8ea08c1), SPH_C32(0x2b0de10e), SPH_C32(0x79d10000), + SPH_C32(0x72310000), SPH_C32(0x0abb0000), SPH_C32(0xd9a88a40), + SPH_C32(0x48c77980), SPH_C32(0xb7f96351), SPH_C32(0x4be06a32), + SPH_C32(0x50730a95) }, + { SPH_C32(0x308a0000), SPH_C32(0x7c810000), SPH_C32(0xb6db0000), + SPH_C32(0xa53c36c0), SPH_C32(0x329b0114), SPH_C32(0x60a74487), + SPH_C32(0x807f0e75), SPH_C32(0xfc57a999), SPH_C32(0x89140000), + SPH_C32(0x2b120000), SPH_C32(0x4f390000), SPH_C32(0x38258a80), + SPH_C32(0x73aa7fb1), SPH_C32(0x751435c8), SPH_C32(0x8000942e), + SPH_C32(0x06d4bb0a) }, + { SPH_C32(0x71500000), SPH_C32(0xa31b0000), SPH_C32(0x6d420000), + SPH_C32(0x57433060), SPH_C32(0x878f5cbf), SPH_C32(0x664e56c8), + SPH_C32(0xc2998952), SPH_C32(0x68133176), SPH_C32(0xdb0d0000), + SPH_C32(0x106a0000), SPH_C32(0x56310000), SPH_C32(0x94258c80), + SPH_C32(0xd3692e31), SPH_C32(0x3ca5464f), SPH_C32(0x7ac34613), + SPH_C32(0x9fe18743) }, + { SPH_C32(0x97780000), SPH_C32(0xef500000), SPH_C32(0xc5170000), + SPH_C32(0x84933280), SPH_C32(0x5fee6c07), SPH_C32(0xfee9e612), + SPH_C32(0xea0c8fe6), SPH_C32(0xbf4979e1), SPH_C32(0x2bc80000), + SPH_C32(0x49490000), SPH_C32(0x13b30000), SPH_C32(0x75a88c40), + SPH_C32(0xe8042800), SPH_C32(0xfe4810d6), SPH_C32(0xb123b80f), + SPH_C32(0xc94636dc) }, + { SPH_C32(0x81950000), SPH_C32(0xfa380000), SPH_C32(0x28c00000), + SPH_C32(0xb6ce30a0), SPH_C32(0xbce25a8e), SPH_C32(0xa4a30051), + SPH_C32(0x0979774e), SPH_C32(0x3eb480e9), SPH_C32(0xcde00000), + SPH_C32(0x05020000), SPH_C32(0xbbe60000), SPH_C32(0xa6788ea0), + SPH_C32(0x306518b8), SPH_C32(0x66efa00c), SPH_C32(0x99b6bebb), + SPH_C32(0x1e1c7e4b) }, + { SPH_C32(0x67bd0000), SPH_C32(0xb6730000), SPH_C32(0x80950000), + SPH_C32(0x651e3240), SPH_C32(0x64836a36), SPH_C32(0x3c04b08b), + SPH_C32(0x21ec71fa), SPH_C32(0xe9eec87e), SPH_C32(0x3d250000), + SPH_C32(0x5c210000), SPH_C32(0xfe640000), SPH_C32(0x47f58e60), + SPH_C32(0x0b081e89), SPH_C32(0xa402f695), SPH_C32(0x525640a7), + SPH_C32(0x48bbcfd4) }, + { SPH_C32(0xc5610000), SPH_C32(0xd4280000), SPH_C32(0xdc1f0000), + SPH_C32(0x28933480), SPH_C32(0xff2d3d87), SPH_C32(0xb7589595), + SPH_C32(0x10cf5ddb), SPH_C32(0x267c45a8), SPH_C32(0x380b0000), + SPH_C32(0xadab0000), SPH_C32(0xd1220000), SPH_C32(0x2bd78ce0), + SPH_C32(0xfdd3242b), SPH_C32(0xb110711e), SPH_C32(0x0906ed15), + SPH_C32(0xc437927a) }, + { SPH_C32(0x23490000), SPH_C32(0x98630000), SPH_C32(0x744a0000), + SPH_C32(0xfb433660), SPH_C32(0x274c0d3f), SPH_C32(0x2fff254f), + SPH_C32(0x385a5b6f), SPH_C32(0xf1260d3f), SPH_C32(0xc8ce0000), + SPH_C32(0xf4880000), SPH_C32(0x94a00000), SPH_C32(0xca5a8c20), + SPH_C32(0xc6be221a), SPH_C32(0x73fd2787), SPH_C32(0xc2e61309), + SPH_C32(0x929023e5) }, + { SPH_C32(0x35a40000), SPH_C32(0x8d0b0000), SPH_C32(0x999d0000), + SPH_C32(0xc91e3440), SPH_C32(0xc4403bb6), SPH_C32(0x75b5c30c), + SPH_C32(0xdb2fa3c7), SPH_C32(0x70dbf437), SPH_C32(0x2ee60000), + SPH_C32(0xb8c30000), SPH_C32(0x3cf50000), SPH_C32(0x198a8ec0), + SPH_C32(0x1edf12a2), SPH_C32(0xeb5a975d), SPH_C32(0xea7315bd), + SPH_C32(0x45ca6b72) }, + { SPH_C32(0xd38c0000), SPH_C32(0xc1400000), SPH_C32(0x31c80000), + SPH_C32(0x1ace36a0), SPH_C32(0x1c210b0e), SPH_C32(0xed1273d6), + SPH_C32(0xf3baa573), SPH_C32(0xa781bca0), SPH_C32(0xde230000), + SPH_C32(0xe1e00000), SPH_C32(0x79770000), SPH_C32(0xf8078e00), + SPH_C32(0x25b21493), SPH_C32(0x29b7c1c4), SPH_C32(0x2193eba1), + SPH_C32(0x136ddaed) }, + { SPH_C32(0x90a40000), SPH_C32(0xbc5b0000), SPH_C32(0x6d6e0000), + SPH_C32(0x0bdd4800), SPH_C32(0xb728224a), SPH_C32(0xecc64a4f), + SPH_C32(0x759e1063), SPH_C32(0x4cf701d1), SPH_C32(0x36e70000), + SPH_C32(0xc9350000), SPH_C32(0xd7980000), SPH_C32(0xa32fa000), + SPH_C32(0x5a34515e), SPH_C32(0x561c7179), SPH_C32(0x310ab488), + SPH_C32(0xa074fe54) }, + { SPH_C32(0x768c0000), SPH_C32(0xf0100000), SPH_C32(0xc53b0000), + SPH_C32(0xd80d4ae0), SPH_C32(0x6f4912f2), SPH_C32(0x7461fa95), + SPH_C32(0x5d0b16d7), SPH_C32(0x9bad4946), SPH_C32(0xc6220000), + SPH_C32(0x90160000), SPH_C32(0x921a0000), SPH_C32(0x42a2a0c0), + SPH_C32(0x6159576f), SPH_C32(0x94f127e0), SPH_C32(0xfaea4a94), + SPH_C32(0xf6d34fcb) }, + { SPH_C32(0x60610000), SPH_C32(0xe5780000), SPH_C32(0x28ec0000), + SPH_C32(0xea5048c0), SPH_C32(0x8c45247b), SPH_C32(0x2e2b1cd6), + SPH_C32(0xbe7eee7f), SPH_C32(0x1a50b04e), SPH_C32(0x200a0000), + SPH_C32(0xdc5d0000), SPH_C32(0x3a4f0000), SPH_C32(0x9172a220), + SPH_C32(0xb93867d7), SPH_C32(0x0c56973a), SPH_C32(0xd27f4c20), + SPH_C32(0x2189075c) }, + { SPH_C32(0x86490000), SPH_C32(0xa9330000), SPH_C32(0x80b90000), + SPH_C32(0x39804a20), SPH_C32(0x542414c3), SPH_C32(0xb68cac0c), + SPH_C32(0x96ebe8cb), SPH_C32(0xcd0af8d9), SPH_C32(0xd0cf0000), + SPH_C32(0x857e0000), SPH_C32(0x7fcd0000), SPH_C32(0x70ffa2e0), + SPH_C32(0x825561e6), SPH_C32(0xcebbc1a3), SPH_C32(0x199fb23c), + SPH_C32(0x772eb6c3) }, + { SPH_C32(0x24950000), SPH_C32(0xcb680000), SPH_C32(0xdc330000), + SPH_C32(0x740d4ce0), SPH_C32(0xcf8a4372), SPH_C32(0x3dd08912), + SPH_C32(0xa7c8c4ea), SPH_C32(0x0298750f), SPH_C32(0xd5e10000), + SPH_C32(0x74f40000), SPH_C32(0x508b0000), SPH_C32(0x1cdda060), + SPH_C32(0x748e5b44), SPH_C32(0xdba94628), SPH_C32(0x42cf1f8e), + SPH_C32(0xfba2eb6d) }, + { SPH_C32(0xc2bd0000), SPH_C32(0x87230000), SPH_C32(0x74660000), + SPH_C32(0xa7dd4e00), SPH_C32(0x17eb73ca), SPH_C32(0xa57739c8), + SPH_C32(0x8f5dc25e), SPH_C32(0xd5c23d98), SPH_C32(0x25240000), + SPH_C32(0x2dd70000), SPH_C32(0x15090000), SPH_C32(0xfd50a0a0), + SPH_C32(0x4fe35d75), SPH_C32(0x194410b1), SPH_C32(0x892fe192), + SPH_C32(0xad055af2) }, + { SPH_C32(0xd4500000), SPH_C32(0x924b0000), SPH_C32(0x99b10000), + SPH_C32(0x95804c20), SPH_C32(0xf4e74543), SPH_C32(0xff3ddf8b), + SPH_C32(0x6c283af6), SPH_C32(0x543fc490), SPH_C32(0xc30c0000), + SPH_C32(0x619c0000), SPH_C32(0xbd5c0000), SPH_C32(0x2e80a240), + SPH_C32(0x97826dcd), SPH_C32(0x81e3a06b), SPH_C32(0xa1bae726), + SPH_C32(0x7a5f1265) }, + { SPH_C32(0x32780000), SPH_C32(0xde000000), SPH_C32(0x31e40000), + SPH_C32(0x46504ec0), SPH_C32(0x2c8675fb), SPH_C32(0x679a6f51), + SPH_C32(0x44bd3c42), SPH_C32(0x83658c07), SPH_C32(0x33c90000), + SPH_C32(0x38bf0000), SPH_C32(0xf8de0000), SPH_C32(0xcf0da280), + SPH_C32(0xacef6bfc), SPH_C32(0x430ef6f2), SPH_C32(0x6a5a193a), + SPH_C32(0x2cf8a3fa) }, + { SPH_C32(0x73a20000), SPH_C32(0x019a0000), SPH_C32(0xea7d0000), + SPH_C32(0xb42f4860), SPH_C32(0x99922850), SPH_C32(0x61737d1e), + SPH_C32(0x065bbb65), SPH_C32(0x172114e8), SPH_C32(0x61d00000), + SPH_C32(0x03c70000), SPH_C32(0xe1d60000), SPH_C32(0x630da480), + SPH_C32(0x0c2c3a7c), SPH_C32(0x0abf8575), SPH_C32(0x9099cb07), + SPH_C32(0xb5cd9fb3) }, + { SPH_C32(0x958a0000), SPH_C32(0x4dd10000), SPH_C32(0x42280000), + SPH_C32(0x67ff4a80), SPH_C32(0x41f318e8), SPH_C32(0xf9d4cdc4), + SPH_C32(0x2ecebdd1), SPH_C32(0xc07b5c7f), SPH_C32(0x91150000), + SPH_C32(0x5ae40000), SPH_C32(0xa4540000), SPH_C32(0x8280a440), + SPH_C32(0x37413c4d), SPH_C32(0xc852d3ec), SPH_C32(0x5b79351b), + SPH_C32(0xe36a2e2c) }, + { SPH_C32(0x83670000), SPH_C32(0x58b90000), SPH_C32(0xafff0000), + SPH_C32(0x55a248a0), SPH_C32(0xa2ff2e61), SPH_C32(0xa39e2b87), + SPH_C32(0xcdbb4579), SPH_C32(0x4186a577), SPH_C32(0x773d0000), + SPH_C32(0x16af0000), SPH_C32(0x0c010000), SPH_C32(0x5150a6a0), + SPH_C32(0xef200cf5), SPH_C32(0x50f56336), SPH_C32(0x73ec33af), + SPH_C32(0x343066bb) }, + { SPH_C32(0x654f0000), SPH_C32(0x14f20000), SPH_C32(0x07aa0000), + SPH_C32(0x86724a40), SPH_C32(0x7a9e1ed9), SPH_C32(0x3b399b5d), + SPH_C32(0xe52e43cd), SPH_C32(0x96dcede0), SPH_C32(0x87f80000), + SPH_C32(0x4f8c0000), SPH_C32(0x49830000), SPH_C32(0xb0dda660), + SPH_C32(0xd44d0ac4), SPH_C32(0x921835af), SPH_C32(0xb80ccdb3), + SPH_C32(0x6297d724) }, + { SPH_C32(0xc7930000), SPH_C32(0x76a90000), SPH_C32(0x5b200000), + SPH_C32(0xcbff4c80), SPH_C32(0xe1304968), SPH_C32(0xb065be43), + SPH_C32(0xd40d6fec), SPH_C32(0x594e6036), SPH_C32(0x82d60000), + SPH_C32(0xbe060000), SPH_C32(0x66c50000), SPH_C32(0xdcffa4e0), + SPH_C32(0x22963066), SPH_C32(0x870ab224), SPH_C32(0xe35c6001), + SPH_C32(0xee1b8a8a) }, + { SPH_C32(0x21bb0000), SPH_C32(0x3ae20000), SPH_C32(0xf3750000), + SPH_C32(0x182f4e60), SPH_C32(0x395179d0), SPH_C32(0x28c20e99), + SPH_C32(0xfc986958), SPH_C32(0x8e1428a1), SPH_C32(0x72130000), + SPH_C32(0xe7250000), SPH_C32(0x23470000), SPH_C32(0x3d72a420), + SPH_C32(0x19fb3657), SPH_C32(0x45e7e4bd), SPH_C32(0x28bc9e1d), + SPH_C32(0xb8bc3b15) }, + { SPH_C32(0x37560000), SPH_C32(0x2f8a0000), SPH_C32(0x1ea20000), + SPH_C32(0x2a724c40), SPH_C32(0xda5d4f59), SPH_C32(0x7288e8da), + SPH_C32(0x1fed91f0), SPH_C32(0x0fe9d1a9), SPH_C32(0x943b0000), + SPH_C32(0xab6e0000), SPH_C32(0x8b120000), SPH_C32(0xeea2a6c0), + SPH_C32(0xc19a06ef), SPH_C32(0xdd405467), SPH_C32(0x002998a9), + SPH_C32(0x6fe67382) }, + { SPH_C32(0xd17e0000), SPH_C32(0x63c10000), SPH_C32(0xb6f70000), + SPH_C32(0xf9a24ea0), SPH_C32(0x023c7fe1), SPH_C32(0xea2f5800), + SPH_C32(0x37789744), SPH_C32(0xd8b3993e), SPH_C32(0x64fe0000), + SPH_C32(0xf24d0000), SPH_C32(0xce900000), SPH_C32(0x0f2fa600), + SPH_C32(0xfaf700de), SPH_C32(0x1fad02fe), SPH_C32(0xcbc966b5), + SPH_C32(0x3941c21d) }, + { SPH_C32(0x288b0000), SPH_C32(0x0d770000), SPH_C32(0x5db60000), + SPH_C32(0x1f991800), SPH_C32(0x767042e8), SPH_C32(0xdde1a2a3), + SPH_C32(0x5b06af40), SPH_C32(0x19e93cbf), SPH_C32(0x34150000), + SPH_C32(0x6bb40000), SPH_C32(0x50a70000), SPH_C32(0x4043d800), + SPH_C32(0x442925b1), SPH_C32(0x51215aaf), SPH_C32(0xf5c886bf), + SPH_C32(0xdf46dbca) }, + { SPH_C32(0xcea30000), SPH_C32(0x413c0000), SPH_C32(0xf5e30000), + SPH_C32(0xcc491ae0), SPH_C32(0xae117250), SPH_C32(0x45461279), + SPH_C32(0x7393a9f4), SPH_C32(0xceb37428), SPH_C32(0xc4d00000), + SPH_C32(0x32970000), SPH_C32(0x15250000), SPH_C32(0xa1ced8c0), + SPH_C32(0x7f442380), SPH_C32(0x93cc0c36), SPH_C32(0x3e2878a3), + SPH_C32(0x89e16a55) }, + { SPH_C32(0xd84e0000), SPH_C32(0x54540000), SPH_C32(0x18340000), + SPH_C32(0xfe1418c0), SPH_C32(0x4d1d44d9), SPH_C32(0x1f0cf43a), + SPH_C32(0x90e6515c), SPH_C32(0x4f4e8d20), SPH_C32(0x22f80000), + SPH_C32(0x7edc0000), SPH_C32(0xbd700000), SPH_C32(0x721eda20), + SPH_C32(0xa7251338), SPH_C32(0x0b6bbcec), SPH_C32(0x16bd7e17), + SPH_C32(0x5ebb22c2) }, + { SPH_C32(0x3e660000), SPH_C32(0x181f0000), SPH_C32(0xb0610000), + SPH_C32(0x2dc41a20), SPH_C32(0x957c7461), SPH_C32(0x87ab44e0), + SPH_C32(0xb87357e8), SPH_C32(0x9814c5b7), SPH_C32(0xd23d0000), + SPH_C32(0x27ff0000), SPH_C32(0xf8f20000), SPH_C32(0x9393dae0), + SPH_C32(0x9c481509), SPH_C32(0xc986ea75), SPH_C32(0xdd5d800b), + SPH_C32(0x081c935d) }, + { SPH_C32(0x9cba0000), SPH_C32(0x7a440000), SPH_C32(0xeceb0000), + SPH_C32(0x60491ce0), SPH_C32(0x0ed223d0), SPH_C32(0x0cf761fe), + SPH_C32(0x89507bc9), SPH_C32(0x57864861), SPH_C32(0xd7130000), + SPH_C32(0xd6750000), SPH_C32(0xd7b40000), SPH_C32(0xffb1d860), + SPH_C32(0x6a932fab), SPH_C32(0xdc946dfe), SPH_C32(0x860d2db9), + SPH_C32(0x8490cef3) }, + { SPH_C32(0x7a920000), SPH_C32(0x360f0000), SPH_C32(0x44be0000), + SPH_C32(0xb3991e00), SPH_C32(0xd6b31368), SPH_C32(0x9450d124), + SPH_C32(0xa1c57d7d), SPH_C32(0x80dc00f6), SPH_C32(0x27d60000), + SPH_C32(0x8f560000), SPH_C32(0x92360000), SPH_C32(0x1e3cd8a0), + SPH_C32(0x51fe299a), SPH_C32(0x1e793b67), SPH_C32(0x4dedd3a5), + SPH_C32(0xd2377f6c) }, + { SPH_C32(0x6c7f0000), SPH_C32(0x23670000), SPH_C32(0xa9690000), + SPH_C32(0x81c41c20), SPH_C32(0x35bf25e1), SPH_C32(0xce1a3767), + SPH_C32(0x42b085d5), SPH_C32(0x0121f9fe), SPH_C32(0xc1fe0000), + SPH_C32(0xc31d0000), SPH_C32(0x3a630000), SPH_C32(0xcdecda40), + SPH_C32(0x899f1922), SPH_C32(0x86de8bbd), SPH_C32(0x6578d511), + SPH_C32(0x056d37fb) }, + { SPH_C32(0x8a570000), SPH_C32(0x6f2c0000), SPH_C32(0x013c0000), + SPH_C32(0x52141ec0), SPH_C32(0xedde1559), SPH_C32(0x56bd87bd), + SPH_C32(0x6a258361), SPH_C32(0xd67bb169), SPH_C32(0x313b0000), + SPH_C32(0x9a3e0000), SPH_C32(0x7fe10000), SPH_C32(0x2c61da80), + SPH_C32(0xb2f21f13), SPH_C32(0x4433dd24), SPH_C32(0xae982b0d), + SPH_C32(0x53ca8664) }, + { SPH_C32(0xcb8d0000), SPH_C32(0xb0b60000), SPH_C32(0xdaa50000), + SPH_C32(0xa06b1860), SPH_C32(0x58ca48f2), SPH_C32(0x505495f2), + SPH_C32(0x28c30446), SPH_C32(0x423f2986), SPH_C32(0x63220000), + SPH_C32(0xa1460000), SPH_C32(0x66e90000), SPH_C32(0x8061dc80), + SPH_C32(0x12314e93), SPH_C32(0x0d82aea3), SPH_C32(0x545bf930), + SPH_C32(0xcaffba2d) }, + { SPH_C32(0x2da50000), SPH_C32(0xfcfd0000), SPH_C32(0x72f00000), + SPH_C32(0x73bb1a80), SPH_C32(0x80ab784a), SPH_C32(0xc8f32528), + SPH_C32(0x005602f2), SPH_C32(0x95656111), SPH_C32(0x93e70000), + SPH_C32(0xf8650000), SPH_C32(0x236b0000), SPH_C32(0x61ecdc40), + SPH_C32(0x295c48a2), SPH_C32(0xcf6ff83a), SPH_C32(0x9fbb072c), + SPH_C32(0x9c580bb2) }, + { SPH_C32(0x3b480000), SPH_C32(0xe9950000), SPH_C32(0x9f270000), + SPH_C32(0x41e618a0), SPH_C32(0x63a74ec3), SPH_C32(0x92b9c36b), + SPH_C32(0xe323fa5a), SPH_C32(0x14989819), SPH_C32(0x75cf0000), + SPH_C32(0xb42e0000), SPH_C32(0x8b3e0000), SPH_C32(0xb23cdea0), + SPH_C32(0xf13d781a), SPH_C32(0x57c848e0), SPH_C32(0xb72e0198), + SPH_C32(0x4b024325) }, + { SPH_C32(0xdd600000), SPH_C32(0xa5de0000), SPH_C32(0x37720000), + SPH_C32(0x92361a40), SPH_C32(0xbbc67e7b), SPH_C32(0x0a1e73b1), + SPH_C32(0xcbb6fcee), SPH_C32(0xc3c2d08e), SPH_C32(0x850a0000), + SPH_C32(0xed0d0000), SPH_C32(0xcebc0000), SPH_C32(0x53b1de60), + SPH_C32(0xca507e2b), SPH_C32(0x95251e79), SPH_C32(0x7cceff84), + SPH_C32(0x1da5f2ba) }, + { SPH_C32(0x7fbc0000), SPH_C32(0xc7850000), SPH_C32(0x6bf80000), + SPH_C32(0xdfbb1c80), SPH_C32(0x206829ca), SPH_C32(0x814256af), + SPH_C32(0xfa95d0cf), SPH_C32(0x0c505d58), SPH_C32(0x80240000), + SPH_C32(0x1c870000), SPH_C32(0xe1fa0000), SPH_C32(0x3f93dce0), + SPH_C32(0x3c8b4489), SPH_C32(0x803799f2), SPH_C32(0x279e5236), + SPH_C32(0x9129af14) }, + { SPH_C32(0x99940000), SPH_C32(0x8bce0000), SPH_C32(0xc3ad0000), + SPH_C32(0x0c6b1e60), SPH_C32(0xf8091972), SPH_C32(0x19e5e675), + SPH_C32(0xd200d67b), SPH_C32(0xdb0a15cf), SPH_C32(0x70e10000), + SPH_C32(0x45a40000), SPH_C32(0xa4780000), SPH_C32(0xde1edc20), + SPH_C32(0x07e642b8), SPH_C32(0x42dacf6b), SPH_C32(0xec7eac2a), + SPH_C32(0xc78e1e8b) }, + { SPH_C32(0x8f790000), SPH_C32(0x9ea60000), SPH_C32(0x2e7a0000), + SPH_C32(0x3e361c40), SPH_C32(0x1b052ffb), SPH_C32(0x43af0036), + SPH_C32(0x31752ed3), SPH_C32(0x5af7ecc7), SPH_C32(0x96c90000), + SPH_C32(0x09ef0000), SPH_C32(0x0c2d0000), SPH_C32(0x0dcedec0), + SPH_C32(0xdf877200), SPH_C32(0xda7d7fb1), SPH_C32(0xc4ebaa9e), + SPH_C32(0x10d4561c) }, + { SPH_C32(0x69510000), SPH_C32(0xd2ed0000), SPH_C32(0x862f0000), + SPH_C32(0xede61ea0), SPH_C32(0xc3641f43), SPH_C32(0xdb08b0ec), + SPH_C32(0x19e02867), SPH_C32(0x8dada450), SPH_C32(0x660c0000), + SPH_C32(0x50cc0000), SPH_C32(0x49af0000), SPH_C32(0xec43de00), + SPH_C32(0xe4ea7431), SPH_C32(0x18902928), SPH_C32(0x0f0b5482), + SPH_C32(0x4673e783) }, + { SPH_C32(0x2a790000), SPH_C32(0xaff60000), SPH_C32(0xda890000), + SPH_C32(0xfcf56000), SPH_C32(0x686d3607), SPH_C32(0xdadc8975), + SPH_C32(0x9fc49d77), SPH_C32(0x66db1921), SPH_C32(0x8ec80000), + SPH_C32(0x78190000), SPH_C32(0xe7400000), SPH_C32(0xb76bf000), + SPH_C32(0x9b6c31fc), SPH_C32(0x673b9995), SPH_C32(0x1f920bab), + SPH_C32(0xf56ac33a) }, + { SPH_C32(0xcc510000), SPH_C32(0xe3bd0000), SPH_C32(0x72dc0000), + SPH_C32(0x2f2562e0), SPH_C32(0xb00c06bf), SPH_C32(0x427b39af), + SPH_C32(0xb7519bc3), SPH_C32(0xb18151b6), SPH_C32(0x7e0d0000), + SPH_C32(0x213a0000), SPH_C32(0xa2c20000), SPH_C32(0x56e6f0c0), + SPH_C32(0xa00137cd), SPH_C32(0xa5d6cf0c), SPH_C32(0xd472f5b7), + SPH_C32(0xa3cd72a5) }, + { SPH_C32(0xdabc0000), SPH_C32(0xf6d50000), SPH_C32(0x9f0b0000), + SPH_C32(0x1d7860c0), SPH_C32(0x53003036), SPH_C32(0x1831dfec), + SPH_C32(0x5424636b), SPH_C32(0x307ca8be), SPH_C32(0x98250000), + SPH_C32(0x6d710000), SPH_C32(0x0a970000), SPH_C32(0x8536f220), + SPH_C32(0x78600775), SPH_C32(0x3d717fd6), SPH_C32(0xfce7f303), + SPH_C32(0x74973a32) }, + { SPH_C32(0x3c940000), SPH_C32(0xba9e0000), SPH_C32(0x375e0000), + SPH_C32(0xcea86220), SPH_C32(0x8b61008e), SPH_C32(0x80966f36), + SPH_C32(0x7cb165df), SPH_C32(0xe726e029), SPH_C32(0x68e00000), + SPH_C32(0x34520000), SPH_C32(0x4f150000), SPH_C32(0x64bbf2e0), + SPH_C32(0x430d0144), SPH_C32(0xff9c294f), SPH_C32(0x37070d1f), + SPH_C32(0x22308bad) }, + { SPH_C32(0x9e480000), SPH_C32(0xd8c50000), SPH_C32(0x6bd40000), + SPH_C32(0x832564e0), SPH_C32(0x10cf573f), SPH_C32(0x0bca4a28), + SPH_C32(0x4d9249fe), SPH_C32(0x28b46dff), SPH_C32(0x6dce0000), + SPH_C32(0xc5d80000), SPH_C32(0x60530000), SPH_C32(0x0899f060), + SPH_C32(0xb5d63be6), SPH_C32(0xea8eaec4), SPH_C32(0x6c57a0ad), + SPH_C32(0xaebcd603) }, + { SPH_C32(0x78600000), SPH_C32(0x948e0000), SPH_C32(0xc3810000), + SPH_C32(0x50f56600), SPH_C32(0xc8ae6787), SPH_C32(0x936dfaf2), + SPH_C32(0x65074f4a), SPH_C32(0xffee2568), SPH_C32(0x9d0b0000), + SPH_C32(0x9cfb0000), SPH_C32(0x25d10000), SPH_C32(0xe914f0a0), + SPH_C32(0x8ebb3dd7), SPH_C32(0x2863f85d), SPH_C32(0xa7b75eb1), + SPH_C32(0xf81b679c) }, + { SPH_C32(0x6e8d0000), SPH_C32(0x81e60000), SPH_C32(0x2e560000), + SPH_C32(0x62a86420), SPH_C32(0x2ba2510e), SPH_C32(0xc9271cb1), + SPH_C32(0x8672b7e2), SPH_C32(0x7e13dc60), SPH_C32(0x7b230000), + SPH_C32(0xd0b00000), SPH_C32(0x8d840000), SPH_C32(0x3ac4f240), + SPH_C32(0x56da0d6f), SPH_C32(0xb0c44887), SPH_C32(0x8f225805), + SPH_C32(0x2f412f0b) }, + { SPH_C32(0x88a50000), SPH_C32(0xcdad0000), SPH_C32(0x86030000), + SPH_C32(0xb17866c0), SPH_C32(0xf3c361b6), SPH_C32(0x5180ac6b), + SPH_C32(0xaee7b156), SPH_C32(0xa94994f7), SPH_C32(0x8be60000), + SPH_C32(0x89930000), SPH_C32(0xc8060000), SPH_C32(0xdb49f280), + SPH_C32(0x6db70b5e), SPH_C32(0x72291e1e), SPH_C32(0x44c2a619), + SPH_C32(0x79e69e94) }, + { SPH_C32(0xc97f0000), SPH_C32(0x12370000), SPH_C32(0x5d9a0000), + SPH_C32(0x43076060), SPH_C32(0x46d73c1d), SPH_C32(0x5769be24), + SPH_C32(0xec013671), SPH_C32(0x3d0d0c18), SPH_C32(0xd9ff0000), + SPH_C32(0xb2eb0000), SPH_C32(0xd10e0000), SPH_C32(0x7749f480), + SPH_C32(0xcd745ade), SPH_C32(0x3b986d99), SPH_C32(0xbe017424), + SPH_C32(0xe0d3a2dd) }, + { SPH_C32(0x2f570000), SPH_C32(0x5e7c0000), SPH_C32(0xf5cf0000), + SPH_C32(0x90d76280), SPH_C32(0x9eb60ca5), SPH_C32(0xcfce0efe), + SPH_C32(0xc49430c5), SPH_C32(0xea57448f), SPH_C32(0x293a0000), + SPH_C32(0xebc80000), SPH_C32(0x948c0000), SPH_C32(0x96c4f440), + SPH_C32(0xf6195cef), SPH_C32(0xf9753b00), SPH_C32(0x75e18a38), + SPH_C32(0xb6741342) }, + { SPH_C32(0x39ba0000), SPH_C32(0x4b140000), SPH_C32(0x18180000), + SPH_C32(0xa28a60a0), SPH_C32(0x7dba3a2c), SPH_C32(0x9584e8bd), + SPH_C32(0x27e1c86d), SPH_C32(0x6baabd87), SPH_C32(0xcf120000), + SPH_C32(0xa7830000), SPH_C32(0x3cd90000), SPH_C32(0x4514f6a0), + SPH_C32(0x2e786c57), SPH_C32(0x61d28bda), SPH_C32(0x5d748c8c), + SPH_C32(0x612e5bd5) }, + { SPH_C32(0xdf920000), SPH_C32(0x075f0000), SPH_C32(0xb04d0000), + SPH_C32(0x715a6240), SPH_C32(0xa5db0a94), SPH_C32(0x0d235867), + SPH_C32(0x0f74ced9), SPH_C32(0xbcf0f510), SPH_C32(0x3fd70000), + SPH_C32(0xfea00000), SPH_C32(0x795b0000), SPH_C32(0xa499f660), + SPH_C32(0x15156a66), SPH_C32(0xa33fdd43), SPH_C32(0x96947290), + SPH_C32(0x3789ea4a) }, + { SPH_C32(0x7d4e0000), SPH_C32(0x65040000), SPH_C32(0xecc70000), + SPH_C32(0x3cd76480), SPH_C32(0x3e755d25), SPH_C32(0x867f7d79), + SPH_C32(0x3e57e2f8), SPH_C32(0x736278c6), SPH_C32(0x3af90000), + SPH_C32(0x0f2a0000), SPH_C32(0x561d0000), SPH_C32(0xc8bbf4e0), + SPH_C32(0xe3ce50c4), SPH_C32(0xb62d5ac8), SPH_C32(0xcdc4df22), + SPH_C32(0xbb05b7e4) }, + { SPH_C32(0x9b660000), SPH_C32(0x294f0000), SPH_C32(0x44920000), + SPH_C32(0xef076660), SPH_C32(0xe6146d9d), SPH_C32(0x1ed8cda3), + SPH_C32(0x16c2e44c), SPH_C32(0xa4383051), SPH_C32(0xca3c0000), + SPH_C32(0x56090000), SPH_C32(0x139f0000), SPH_C32(0x2936f420), + SPH_C32(0xd8a356f5), SPH_C32(0x74c00c51), SPH_C32(0x0624213e), + SPH_C32(0xeda2067b) }, + { SPH_C32(0x8d8b0000), SPH_C32(0x3c270000), SPH_C32(0xa9450000), + SPH_C32(0xdd5a6440), SPH_C32(0x05185b14), SPH_C32(0x44922be0), + SPH_C32(0xf5b71ce4), SPH_C32(0x25c5c959), SPH_C32(0x2c140000), + SPH_C32(0x1a420000), SPH_C32(0xbbca0000), SPH_C32(0xfae6f6c0), + SPH_C32(0x00c2664d), SPH_C32(0xec67bc8b), SPH_C32(0x2eb1278a), + SPH_C32(0x3af84eec) }, + { SPH_C32(0x6ba30000), SPH_C32(0x706c0000), SPH_C32(0x01100000), + SPH_C32(0x0e8a66a0), SPH_C32(0xdd796bac), SPH_C32(0xdc359b3a), + SPH_C32(0xdd221a50), SPH_C32(0xf29f81ce), SPH_C32(0xdcd10000), + SPH_C32(0x43610000), SPH_C32(0xfe480000), SPH_C32(0x1b6bf600), + SPH_C32(0x3baf607c), SPH_C32(0x2e8aea12), SPH_C32(0xe551d996), + SPH_C32(0x6c5fff73) }, + { SPH_C32(0x8c3a0000), SPH_C32(0xda980000), SPH_C32(0x607f0000), + SPH_C32(0x54078800), SPH_C32(0x85714513), SPH_C32(0x6006b243), + SPH_C32(0xdb50399c), SPH_C32(0x8a58e6a4), SPH_C32(0x1e6c0000), + SPH_C32(0xc4420000), SPH_C32(0x8a2e0000), SPH_C32(0xbcb6b800), + SPH_C32(0x2c4413b6), SPH_C32(0x8bfdd3da), SPH_C32(0x6a0c1bc8), + SPH_C32(0xb99dc2eb) }, + { SPH_C32(0x6a120000), SPH_C32(0x96d30000), SPH_C32(0xc82a0000), + SPH_C32(0x87d78ae0), SPH_C32(0x5d1075ab), SPH_C32(0xf8a10299), + SPH_C32(0xf3c53f28), SPH_C32(0x5d02ae33), SPH_C32(0xeea90000), + SPH_C32(0x9d610000), SPH_C32(0xcfac0000), SPH_C32(0x5d3bb8c0), + SPH_C32(0x17291587), SPH_C32(0x49108543), SPH_C32(0xa1ece5d4), + SPH_C32(0xef3a7374) }, + { SPH_C32(0x7cff0000), SPH_C32(0x83bb0000), SPH_C32(0x25fd0000), + SPH_C32(0xb58a88c0), SPH_C32(0xbe1c4322), SPH_C32(0xa2ebe4da), + SPH_C32(0x10b0c780), SPH_C32(0xdcff573b), SPH_C32(0x08810000), + SPH_C32(0xd12a0000), SPH_C32(0x67f90000), SPH_C32(0x8eebba20), + SPH_C32(0xcf48253f), SPH_C32(0xd1b73599), SPH_C32(0x8979e360), + SPH_C32(0x38603be3) }, + { SPH_C32(0x9ad70000), SPH_C32(0xcff00000), SPH_C32(0x8da80000), + SPH_C32(0x665a8a20), SPH_C32(0x667d739a), SPH_C32(0x3a4c5400), + SPH_C32(0x3825c134), SPH_C32(0x0ba51fac), SPH_C32(0xf8440000), + SPH_C32(0x88090000), SPH_C32(0x227b0000), SPH_C32(0x6f66bae0), + SPH_C32(0xf425230e), SPH_C32(0x135a6300), SPH_C32(0x42991d7c), + SPH_C32(0x6ec78a7c) }, + { SPH_C32(0x380b0000), SPH_C32(0xadab0000), SPH_C32(0xd1220000), + SPH_C32(0x2bd78ce0), SPH_C32(0xfdd3242b), SPH_C32(0xb110711e), + SPH_C32(0x0906ed15), SPH_C32(0xc437927a), SPH_C32(0xfd6a0000), + SPH_C32(0x79830000), SPH_C32(0x0d3d0000), SPH_C32(0x0344b860), + SPH_C32(0x02fe19ac), SPH_C32(0x0648e48b), SPH_C32(0x19c9b0ce), + SPH_C32(0xe24bd7d2) }, + { SPH_C32(0xde230000), SPH_C32(0xe1e00000), SPH_C32(0x79770000), + SPH_C32(0xf8078e00), SPH_C32(0x25b21493), SPH_C32(0x29b7c1c4), + SPH_C32(0x2193eba1), SPH_C32(0x136ddaed), SPH_C32(0x0daf0000), + SPH_C32(0x20a00000), SPH_C32(0x48bf0000), SPH_C32(0xe2c9b8a0), + SPH_C32(0x39931f9d), SPH_C32(0xc4a5b212), SPH_C32(0xd2294ed2), + SPH_C32(0xb4ec664d) }, + { SPH_C32(0xc8ce0000), SPH_C32(0xf4880000), SPH_C32(0x94a00000), + SPH_C32(0xca5a8c20), SPH_C32(0xc6be221a), SPH_C32(0x73fd2787), + SPH_C32(0xc2e61309), SPH_C32(0x929023e5), SPH_C32(0xeb870000), + SPH_C32(0x6ceb0000), SPH_C32(0xe0ea0000), SPH_C32(0x3119ba40), + SPH_C32(0xe1f22f25), SPH_C32(0x5c0202c8), SPH_C32(0xfabc4866), + SPH_C32(0x63b62eda) }, + { SPH_C32(0x2ee60000), SPH_C32(0xb8c30000), SPH_C32(0x3cf50000), + SPH_C32(0x198a8ec0), SPH_C32(0x1edf12a2), SPH_C32(0xeb5a975d), + SPH_C32(0xea7315bd), SPH_C32(0x45ca6b72), SPH_C32(0x1b420000), + SPH_C32(0x35c80000), SPH_C32(0xa5680000), SPH_C32(0xd094ba80), + SPH_C32(0xda9f2914), SPH_C32(0x9eef5451), SPH_C32(0x315cb67a), + SPH_C32(0x35119f45) }, + { SPH_C32(0x6f3c0000), SPH_C32(0x67590000), SPH_C32(0xe76c0000), + SPH_C32(0xebf58860), SPH_C32(0xabcb4f09), SPH_C32(0xedb38512), + SPH_C32(0xa895929a), SPH_C32(0xd18ef39d), SPH_C32(0x495b0000), + SPH_C32(0x0eb00000), SPH_C32(0xbc600000), SPH_C32(0x7c94bc80), + SPH_C32(0x7a5c7894), SPH_C32(0xd75e27d6), SPH_C32(0xcb9f6447), + SPH_C32(0xac24a30c) }, + { SPH_C32(0x89140000), SPH_C32(0x2b120000), SPH_C32(0x4f390000), + SPH_C32(0x38258a80), SPH_C32(0x73aa7fb1), SPH_C32(0x751435c8), + SPH_C32(0x8000942e), SPH_C32(0x06d4bb0a), SPH_C32(0xb99e0000), + SPH_C32(0x57930000), SPH_C32(0xf9e20000), SPH_C32(0x9d19bc40), + SPH_C32(0x41317ea5), SPH_C32(0x15b3714f), SPH_C32(0x007f9a5b), + SPH_C32(0xfa831293) }, + { SPH_C32(0x9ff90000), SPH_C32(0x3e7a0000), SPH_C32(0xa2ee0000), + SPH_C32(0x0a7888a0), SPH_C32(0x90a64938), SPH_C32(0x2f5ed38b), + SPH_C32(0x63756c86), SPH_C32(0x87294202), SPH_C32(0x5fb60000), + SPH_C32(0x1bd80000), SPH_C32(0x51b70000), SPH_C32(0x4ec9bea0), + SPH_C32(0x99504e1d), SPH_C32(0x8d14c195), SPH_C32(0x28ea9cef), + SPH_C32(0x2dd95a04) }, + { SPH_C32(0x79d10000), SPH_C32(0x72310000), SPH_C32(0x0abb0000), + SPH_C32(0xd9a88a40), SPH_C32(0x48c77980), SPH_C32(0xb7f96351), + SPH_C32(0x4be06a32), SPH_C32(0x50730a95), SPH_C32(0xaf730000), + SPH_C32(0x42fb0000), SPH_C32(0x14350000), SPH_C32(0xaf44be60), + SPH_C32(0xa23d482c), SPH_C32(0x4ff9970c), SPH_C32(0xe30a62f3), + SPH_C32(0x7b7eeb9b) }, + { SPH_C32(0xdb0d0000), SPH_C32(0x106a0000), SPH_C32(0x56310000), + SPH_C32(0x94258c80), SPH_C32(0xd3692e31), SPH_C32(0x3ca5464f), + SPH_C32(0x7ac34613), SPH_C32(0x9fe18743), SPH_C32(0xaa5d0000), + SPH_C32(0xb3710000), SPH_C32(0x3b730000), SPH_C32(0xc366bce0), + SPH_C32(0x54e6728e), SPH_C32(0x5aeb1087), SPH_C32(0xb85acf41), + SPH_C32(0xf7f2b635) }, + { SPH_C32(0x3d250000), SPH_C32(0x5c210000), SPH_C32(0xfe640000), + SPH_C32(0x47f58e60), SPH_C32(0x0b081e89), SPH_C32(0xa402f695), + SPH_C32(0x525640a7), SPH_C32(0x48bbcfd4), SPH_C32(0x5a980000), + SPH_C32(0xea520000), SPH_C32(0x7ef10000), SPH_C32(0x22ebbc20), + SPH_C32(0x6f8b74bf), SPH_C32(0x9806461e), SPH_C32(0x73ba315d), + SPH_C32(0xa15507aa) }, + { SPH_C32(0x2bc80000), SPH_C32(0x49490000), SPH_C32(0x13b30000), + SPH_C32(0x75a88c40), SPH_C32(0xe8042800), SPH_C32(0xfe4810d6), + SPH_C32(0xb123b80f), SPH_C32(0xc94636dc), SPH_C32(0xbcb00000), + SPH_C32(0xa6190000), SPH_C32(0xd6a40000), SPH_C32(0xf13bbec0), + SPH_C32(0xb7ea4407), SPH_C32(0x00a1f6c4), SPH_C32(0x5b2f37e9), + SPH_C32(0x760f4f3d) }, + { SPH_C32(0xcde00000), SPH_C32(0x05020000), SPH_C32(0xbbe60000), + SPH_C32(0xa6788ea0), SPH_C32(0x306518b8), SPH_C32(0x66efa00c), + SPH_C32(0x99b6bebb), SPH_C32(0x1e1c7e4b), SPH_C32(0x4c750000), + SPH_C32(0xff3a0000), SPH_C32(0x93260000), SPH_C32(0x10b6be00), + SPH_C32(0x8c874236), SPH_C32(0xc24ca05d), SPH_C32(0x90cfc9f5), + SPH_C32(0x20a8fea2) }, + { SPH_C32(0x8ec80000), SPH_C32(0x78190000), SPH_C32(0xe7400000), + SPH_C32(0xb76bf000), SPH_C32(0x9b6c31fc), SPH_C32(0x673b9995), + SPH_C32(0x1f920bab), SPH_C32(0xf56ac33a), SPH_C32(0xa4b10000), + SPH_C32(0xd7ef0000), SPH_C32(0x3dc90000), SPH_C32(0x4b9e9000), + SPH_C32(0xf30107fb), SPH_C32(0xbde710e0), SPH_C32(0x805696dc), + SPH_C32(0x93b1da1b) }, + { SPH_C32(0x68e00000), SPH_C32(0x34520000), SPH_C32(0x4f150000), + SPH_C32(0x64bbf2e0), SPH_C32(0x430d0144), SPH_C32(0xff9c294f), + SPH_C32(0x37070d1f), SPH_C32(0x22308bad), SPH_C32(0x54740000), + SPH_C32(0x8ecc0000), SPH_C32(0x784b0000), SPH_C32(0xaa1390c0), + SPH_C32(0xc86c01ca), SPH_C32(0x7f0a4679), SPH_C32(0x4bb668c0), + SPH_C32(0xc5166b84) }, + { SPH_C32(0x7e0d0000), SPH_C32(0x213a0000), SPH_C32(0xa2c20000), + SPH_C32(0x56e6f0c0), SPH_C32(0xa00137cd), SPH_C32(0xa5d6cf0c), + SPH_C32(0xd472f5b7), SPH_C32(0xa3cd72a5), SPH_C32(0xb25c0000), + SPH_C32(0xc2870000), SPH_C32(0xd01e0000), SPH_C32(0x79c39220), + SPH_C32(0x100d3172), SPH_C32(0xe7adf6a3), SPH_C32(0x63236e74), + SPH_C32(0x124c2313) }, + { SPH_C32(0x98250000), SPH_C32(0x6d710000), SPH_C32(0x0a970000), + SPH_C32(0x8536f220), SPH_C32(0x78600775), SPH_C32(0x3d717fd6), + SPH_C32(0xfce7f303), SPH_C32(0x74973a32), SPH_C32(0x42990000), + SPH_C32(0x9ba40000), SPH_C32(0x959c0000), SPH_C32(0x984e92e0), + SPH_C32(0x2b603743), SPH_C32(0x2540a03a), SPH_C32(0xa8c39068), + SPH_C32(0x44eb928c) }, + { SPH_C32(0x3af90000), SPH_C32(0x0f2a0000), SPH_C32(0x561d0000), + SPH_C32(0xc8bbf4e0), SPH_C32(0xe3ce50c4), SPH_C32(0xb62d5ac8), + SPH_C32(0xcdc4df22), SPH_C32(0xbb05b7e4), SPH_C32(0x47b70000), + SPH_C32(0x6a2e0000), SPH_C32(0xbada0000), SPH_C32(0xf46c9060), + SPH_C32(0xddbb0de1), SPH_C32(0x305227b1), SPH_C32(0xf3933dda), + SPH_C32(0xc867cf22) }, + { SPH_C32(0xdcd10000), SPH_C32(0x43610000), SPH_C32(0xfe480000), + SPH_C32(0x1b6bf600), SPH_C32(0x3baf607c), SPH_C32(0x2e8aea12), + SPH_C32(0xe551d996), SPH_C32(0x6c5fff73), SPH_C32(0xb7720000), + SPH_C32(0x330d0000), SPH_C32(0xff580000), SPH_C32(0x15e190a0), + SPH_C32(0xe6d60bd0), SPH_C32(0xf2bf7128), SPH_C32(0x3873c3c6), + SPH_C32(0x9ec07ebd) }, + { SPH_C32(0xca3c0000), SPH_C32(0x56090000), SPH_C32(0x139f0000), + SPH_C32(0x2936f420), SPH_C32(0xd8a356f5), SPH_C32(0x74c00c51), + SPH_C32(0x0624213e), SPH_C32(0xeda2067b), SPH_C32(0x515a0000), + SPH_C32(0x7f460000), SPH_C32(0x570d0000), SPH_C32(0xc6319240), + SPH_C32(0x3eb73b68), SPH_C32(0x6a18c1f2), SPH_C32(0x10e6c572), + SPH_C32(0x499a362a) }, + { SPH_C32(0x2c140000), SPH_C32(0x1a420000), SPH_C32(0xbbca0000), + SPH_C32(0xfae6f6c0), SPH_C32(0x00c2664d), SPH_C32(0xec67bc8b), + SPH_C32(0x2eb1278a), SPH_C32(0x3af84eec), SPH_C32(0xa19f0000), + SPH_C32(0x26650000), SPH_C32(0x128f0000), SPH_C32(0x27bc9280), + SPH_C32(0x05da3d59), SPH_C32(0xa8f5976b), SPH_C32(0xdb063b6e), + SPH_C32(0x1f3d87b5) }, + { SPH_C32(0x6dce0000), SPH_C32(0xc5d80000), SPH_C32(0x60530000), + SPH_C32(0x0899f060), SPH_C32(0xb5d63be6), SPH_C32(0xea8eaec4), + SPH_C32(0x6c57a0ad), SPH_C32(0xaebcd603), SPH_C32(0xf3860000), + SPH_C32(0x1d1d0000), SPH_C32(0x0b870000), SPH_C32(0x8bbc9480), + SPH_C32(0xa5196cd9), SPH_C32(0xe144e4ec), SPH_C32(0x21c5e953), + SPH_C32(0x8608bbfc) }, + { SPH_C32(0x8be60000), SPH_C32(0x89930000), SPH_C32(0xc8060000), + SPH_C32(0xdb49f280), SPH_C32(0x6db70b5e), SPH_C32(0x72291e1e), + SPH_C32(0x44c2a619), SPH_C32(0x79e69e94), SPH_C32(0x03430000), + SPH_C32(0x443e0000), SPH_C32(0x4e050000), SPH_C32(0x6a319440), + SPH_C32(0x9e746ae8), SPH_C32(0x23a9b275), SPH_C32(0xea25174f), + SPH_C32(0xd0af0a63) }, + { SPH_C32(0x9d0b0000), SPH_C32(0x9cfb0000), SPH_C32(0x25d10000), + SPH_C32(0xe914f0a0), SPH_C32(0x8ebb3dd7), SPH_C32(0x2863f85d), + SPH_C32(0xa7b75eb1), SPH_C32(0xf81b679c), SPH_C32(0xe56b0000), + SPH_C32(0x08750000), SPH_C32(0xe6500000), SPH_C32(0xb9e196a0), + SPH_C32(0x46155a50), SPH_C32(0xbb0e02af), SPH_C32(0xc2b011fb), + SPH_C32(0x07f542f4) }, + { SPH_C32(0x7b230000), SPH_C32(0xd0b00000), SPH_C32(0x8d840000), + SPH_C32(0x3ac4f240), SPH_C32(0x56da0d6f), SPH_C32(0xb0c44887), + SPH_C32(0x8f225805), SPH_C32(0x2f412f0b), SPH_C32(0x15ae0000), + SPH_C32(0x51560000), SPH_C32(0xa3d20000), SPH_C32(0x586c9660), + SPH_C32(0x7d785c61), SPH_C32(0x79e35436), SPH_C32(0x0950efe7), + SPH_C32(0x5152f36b) }, + { SPH_C32(0xd9ff0000), SPH_C32(0xb2eb0000), SPH_C32(0xd10e0000), + SPH_C32(0x7749f480), SPH_C32(0xcd745ade), SPH_C32(0x3b986d99), + SPH_C32(0xbe017424), SPH_C32(0xe0d3a2dd), SPH_C32(0x10800000), + SPH_C32(0xa0dc0000), SPH_C32(0x8c940000), SPH_C32(0x344e94e0), + SPH_C32(0x8ba366c3), SPH_C32(0x6cf1d3bd), SPH_C32(0x52004255), + SPH_C32(0xdddeaec5) }, + { SPH_C32(0x3fd70000), SPH_C32(0xfea00000), SPH_C32(0x795b0000), + SPH_C32(0xa499f660), SPH_C32(0x15156a66), SPH_C32(0xa33fdd43), + SPH_C32(0x96947290), SPH_C32(0x3789ea4a), SPH_C32(0xe0450000), + SPH_C32(0xf9ff0000), SPH_C32(0xc9160000), SPH_C32(0xd5c39420), + SPH_C32(0xb0ce60f2), SPH_C32(0xae1c8524), SPH_C32(0x99e0bc49), + SPH_C32(0x8b791f5a) }, + { SPH_C32(0x293a0000), SPH_C32(0xebc80000), SPH_C32(0x948c0000), + SPH_C32(0x96c4f440), SPH_C32(0xf6195cef), SPH_C32(0xf9753b00), + SPH_C32(0x75e18a38), SPH_C32(0xb6741342), SPH_C32(0x066d0000), + SPH_C32(0xb5b40000), SPH_C32(0x61430000), SPH_C32(0x061396c0), + SPH_C32(0x68af504a), SPH_C32(0x36bb35fe), SPH_C32(0xb175bafd), + SPH_C32(0x5c2357cd) }, + { SPH_C32(0xcf120000), SPH_C32(0xa7830000), SPH_C32(0x3cd90000), + SPH_C32(0x4514f6a0), SPH_C32(0x2e786c57), SPH_C32(0x61d28bda), + SPH_C32(0x5d748c8c), SPH_C32(0x612e5bd5), SPH_C32(0xf6a80000), + SPH_C32(0xec970000), SPH_C32(0x24c10000), SPH_C32(0xe79e9600), + SPH_C32(0x53c2567b), SPH_C32(0xf4566367), SPH_C32(0x7a9544e1), + SPH_C32(0x0a84e652) }, + { SPH_C32(0x36e70000), SPH_C32(0xc9350000), SPH_C32(0xd7980000), + SPH_C32(0xa32fa000), SPH_C32(0x5a34515e), SPH_C32(0x561c7179), + SPH_C32(0x310ab488), SPH_C32(0xa074fe54), SPH_C32(0xa6430000), + SPH_C32(0x756e0000), SPH_C32(0xbaf60000), SPH_C32(0xa8f2e800), + SPH_C32(0xed1c7314), SPH_C32(0xbada3b36), SPH_C32(0x4494a4eb), + SPH_C32(0xec83ff85) }, + { SPH_C32(0xd0cf0000), SPH_C32(0x857e0000), SPH_C32(0x7fcd0000), + SPH_C32(0x70ffa2e0), SPH_C32(0x825561e6), SPH_C32(0xcebbc1a3), + SPH_C32(0x199fb23c), SPH_C32(0x772eb6c3), SPH_C32(0x56860000), + SPH_C32(0x2c4d0000), SPH_C32(0xff740000), SPH_C32(0x497fe8c0), + SPH_C32(0xd6717525), SPH_C32(0x78376daf), SPH_C32(0x8f745af7), + SPH_C32(0xba244e1a) }, + { SPH_C32(0xc6220000), SPH_C32(0x90160000), SPH_C32(0x921a0000), + SPH_C32(0x42a2a0c0), SPH_C32(0x6159576f), SPH_C32(0x94f127e0), + SPH_C32(0xfaea4a94), SPH_C32(0xf6d34fcb), SPH_C32(0xb0ae0000), + SPH_C32(0x60060000), SPH_C32(0x57210000), SPH_C32(0x9aafea20), + SPH_C32(0x0e10459d), SPH_C32(0xe090dd75), SPH_C32(0xa7e15c43), + SPH_C32(0x6d7e068d) }, + { SPH_C32(0x200a0000), SPH_C32(0xdc5d0000), SPH_C32(0x3a4f0000), + SPH_C32(0x9172a220), SPH_C32(0xb93867d7), SPH_C32(0x0c56973a), + SPH_C32(0xd27f4c20), SPH_C32(0x2189075c), SPH_C32(0x406b0000), + SPH_C32(0x39250000), SPH_C32(0x12a30000), SPH_C32(0x7b22eae0), + SPH_C32(0x357d43ac), SPH_C32(0x227d8bec), SPH_C32(0x6c01a25f), + SPH_C32(0x3bd9b712) }, + { SPH_C32(0x82d60000), SPH_C32(0xbe060000), SPH_C32(0x66c50000), + SPH_C32(0xdcffa4e0), SPH_C32(0x22963066), SPH_C32(0x870ab224), + SPH_C32(0xe35c6001), SPH_C32(0xee1b8a8a), SPH_C32(0x45450000), + SPH_C32(0xc8af0000), SPH_C32(0x3de50000), SPH_C32(0x1700e860), + SPH_C32(0xc3a6790e), SPH_C32(0x376f0c67), SPH_C32(0x37510fed), + SPH_C32(0xb755eabc) }, + { SPH_C32(0x64fe0000), SPH_C32(0xf24d0000), SPH_C32(0xce900000), + SPH_C32(0x0f2fa600), SPH_C32(0xfaf700de), SPH_C32(0x1fad02fe), + SPH_C32(0xcbc966b5), SPH_C32(0x3941c21d), SPH_C32(0xb5800000), + SPH_C32(0x918c0000), SPH_C32(0x78670000), SPH_C32(0xf68de8a0), + SPH_C32(0xf8cb7f3f), SPH_C32(0xf5825afe), SPH_C32(0xfcb1f1f1), + SPH_C32(0xe1f25b23) }, + { SPH_C32(0x72130000), SPH_C32(0xe7250000), SPH_C32(0x23470000), + SPH_C32(0x3d72a420), SPH_C32(0x19fb3657), SPH_C32(0x45e7e4bd), + SPH_C32(0x28bc9e1d), SPH_C32(0xb8bc3b15), SPH_C32(0x53a80000), + SPH_C32(0xddc70000), SPH_C32(0xd0320000), SPH_C32(0x255dea40), + SPH_C32(0x20aa4f87), SPH_C32(0x6d25ea24), SPH_C32(0xd424f745), + SPH_C32(0x36a813b4) }, + { SPH_C32(0x943b0000), SPH_C32(0xab6e0000), SPH_C32(0x8b120000), + SPH_C32(0xeea2a6c0), SPH_C32(0xc19a06ef), SPH_C32(0xdd405467), + SPH_C32(0x002998a9), SPH_C32(0x6fe67382), SPH_C32(0xa36d0000), + SPH_C32(0x84e40000), SPH_C32(0x95b00000), SPH_C32(0xc4d0ea80), + SPH_C32(0x1bc749b6), SPH_C32(0xafc8bcbd), SPH_C32(0x1fc40959), + SPH_C32(0x600fa22b) }, + { SPH_C32(0xd5e10000), SPH_C32(0x74f40000), SPH_C32(0x508b0000), + SPH_C32(0x1cdda060), SPH_C32(0x748e5b44), SPH_C32(0xdba94628), + SPH_C32(0x42cf1f8e), SPH_C32(0xfba2eb6d), SPH_C32(0xf1740000), + SPH_C32(0xbf9c0000), SPH_C32(0x8cb80000), SPH_C32(0x68d0ec80), + SPH_C32(0xbb041836), SPH_C32(0xe679cf3a), SPH_C32(0xe507db64), + SPH_C32(0xf93a9e62) }, + { SPH_C32(0x33c90000), SPH_C32(0x38bf0000), SPH_C32(0xf8de0000), + SPH_C32(0xcf0da280), SPH_C32(0xacef6bfc), SPH_C32(0x430ef6f2), + SPH_C32(0x6a5a193a), SPH_C32(0x2cf8a3fa), SPH_C32(0x01b10000), + SPH_C32(0xe6bf0000), SPH_C32(0xc93a0000), SPH_C32(0x895dec40), + SPH_C32(0x80691e07), SPH_C32(0x249499a3), SPH_C32(0x2ee72578), + SPH_C32(0xaf9d2ffd) }, + { SPH_C32(0x25240000), SPH_C32(0x2dd70000), SPH_C32(0x15090000), + SPH_C32(0xfd50a0a0), SPH_C32(0x4fe35d75), SPH_C32(0x194410b1), + SPH_C32(0x892fe192), SPH_C32(0xad055af2), SPH_C32(0xe7990000), + SPH_C32(0xaaf40000), SPH_C32(0x616f0000), SPH_C32(0x5a8deea0), + SPH_C32(0x58082ebf), SPH_C32(0xbc332979), SPH_C32(0x067223cc), + SPH_C32(0x78c7676a) }, + { SPH_C32(0xc30c0000), SPH_C32(0x619c0000), SPH_C32(0xbd5c0000), + SPH_C32(0x2e80a240), SPH_C32(0x97826dcd), SPH_C32(0x81e3a06b), + SPH_C32(0xa1bae726), SPH_C32(0x7a5f1265), SPH_C32(0x175c0000), + SPH_C32(0xf3d70000), SPH_C32(0x24ed0000), SPH_C32(0xbb00ee60), + SPH_C32(0x6365288e), SPH_C32(0x7ede7fe0), SPH_C32(0xcd92ddd0), + SPH_C32(0x2e60d6f5) }, + { SPH_C32(0x61d00000), SPH_C32(0x03c70000), SPH_C32(0xe1d60000), + SPH_C32(0x630da480), SPH_C32(0x0c2c3a7c), SPH_C32(0x0abf8575), + SPH_C32(0x9099cb07), SPH_C32(0xb5cd9fb3), SPH_C32(0x12720000), + SPH_C32(0x025d0000), SPH_C32(0x0bab0000), SPH_C32(0xd722ece0), + SPH_C32(0x95be122c), SPH_C32(0x6bccf86b), SPH_C32(0x96c27062), + SPH_C32(0xa2ec8b5b) }, + { SPH_C32(0x87f80000), SPH_C32(0x4f8c0000), SPH_C32(0x49830000), + SPH_C32(0xb0dda660), SPH_C32(0xd44d0ac4), SPH_C32(0x921835af), + SPH_C32(0xb80ccdb3), SPH_C32(0x6297d724), SPH_C32(0xe2b70000), + SPH_C32(0x5b7e0000), SPH_C32(0x4e290000), SPH_C32(0x36afec20), + SPH_C32(0xaed3141d), SPH_C32(0xa921aef2), SPH_C32(0x5d228e7e), + SPH_C32(0xf44b3ac4) }, + { SPH_C32(0x91150000), SPH_C32(0x5ae40000), SPH_C32(0xa4540000), + SPH_C32(0x8280a440), SPH_C32(0x37413c4d), SPH_C32(0xc852d3ec), + SPH_C32(0x5b79351b), SPH_C32(0xe36a2e2c), SPH_C32(0x049f0000), + SPH_C32(0x17350000), SPH_C32(0xe67c0000), SPH_C32(0xe57feec0), + SPH_C32(0x76b224a5), SPH_C32(0x31861e28), SPH_C32(0x75b788ca), + SPH_C32(0x23117253) }, + { SPH_C32(0x773d0000), SPH_C32(0x16af0000), SPH_C32(0x0c010000), + SPH_C32(0x5150a6a0), SPH_C32(0xef200cf5), SPH_C32(0x50f56336), + SPH_C32(0x73ec33af), SPH_C32(0x343066bb), SPH_C32(0xf45a0000), + SPH_C32(0x4e160000), SPH_C32(0xa3fe0000), SPH_C32(0x04f2ee00), + SPH_C32(0x4ddf2294), SPH_C32(0xf36b48b1), SPH_C32(0xbe5776d6), + SPH_C32(0x75b6c3cc) }, + { SPH_C32(0x34150000), SPH_C32(0x6bb40000), SPH_C32(0x50a70000), + SPH_C32(0x4043d800), SPH_C32(0x442925b1), SPH_C32(0x51215aaf), + SPH_C32(0xf5c886bf), SPH_C32(0xdf46dbca), SPH_C32(0x1c9e0000), + SPH_C32(0x66c30000), SPH_C32(0x0d110000), SPH_C32(0x5fdac000), + SPH_C32(0x32596759), SPH_C32(0x8cc0f80c), SPH_C32(0xaece29ff), + SPH_C32(0xc6afe775) }, + { SPH_C32(0xd23d0000), SPH_C32(0x27ff0000), SPH_C32(0xf8f20000), + SPH_C32(0x9393dae0), SPH_C32(0x9c481509), SPH_C32(0xc986ea75), + SPH_C32(0xdd5d800b), SPH_C32(0x081c935d), SPH_C32(0xec5b0000), + SPH_C32(0x3fe00000), SPH_C32(0x48930000), SPH_C32(0xbe57c0c0), + SPH_C32(0x09346168), SPH_C32(0x4e2dae95), SPH_C32(0x652ed7e3), + SPH_C32(0x900856ea) }, + { SPH_C32(0xc4d00000), SPH_C32(0x32970000), SPH_C32(0x15250000), + SPH_C32(0xa1ced8c0), SPH_C32(0x7f442380), SPH_C32(0x93cc0c36), + SPH_C32(0x3e2878a3), SPH_C32(0x89e16a55), SPH_C32(0x0a730000), + SPH_C32(0x73ab0000), SPH_C32(0xe0c60000), SPH_C32(0x6d87c220), + SPH_C32(0xd15551d0), SPH_C32(0xd68a1e4f), SPH_C32(0x4dbbd157), + SPH_C32(0x47521e7d) }, + { SPH_C32(0x22f80000), SPH_C32(0x7edc0000), SPH_C32(0xbd700000), + SPH_C32(0x721eda20), SPH_C32(0xa7251338), SPH_C32(0x0b6bbcec), + SPH_C32(0x16bd7e17), SPH_C32(0x5ebb22c2), SPH_C32(0xfab60000), + SPH_C32(0x2a880000), SPH_C32(0xa5440000), SPH_C32(0x8c0ac2e0), + SPH_C32(0xea3857e1), SPH_C32(0x146748d6), SPH_C32(0x865b2f4b), + SPH_C32(0x11f5afe2) }, + { SPH_C32(0x80240000), SPH_C32(0x1c870000), SPH_C32(0xe1fa0000), + SPH_C32(0x3f93dce0), SPH_C32(0x3c8b4489), SPH_C32(0x803799f2), + SPH_C32(0x279e5236), SPH_C32(0x9129af14), SPH_C32(0xff980000), + SPH_C32(0xdb020000), SPH_C32(0x8a020000), SPH_C32(0xe028c060), + SPH_C32(0x1ce36d43), SPH_C32(0x0175cf5d), SPH_C32(0xdd0b82f9), + SPH_C32(0x9d79f24c) }, + { SPH_C32(0x660c0000), SPH_C32(0x50cc0000), SPH_C32(0x49af0000), + SPH_C32(0xec43de00), SPH_C32(0xe4ea7431), SPH_C32(0x18902928), + SPH_C32(0x0f0b5482), SPH_C32(0x4673e783), SPH_C32(0x0f5d0000), + SPH_C32(0x82210000), SPH_C32(0xcf800000), SPH_C32(0x01a5c0a0), + SPH_C32(0x278e6b72), SPH_C32(0xc39899c4), SPH_C32(0x16eb7ce5), + SPH_C32(0xcbde43d3) }, + { SPH_C32(0x70e10000), SPH_C32(0x45a40000), SPH_C32(0xa4780000), + SPH_C32(0xde1edc20), SPH_C32(0x07e642b8), SPH_C32(0x42dacf6b), + SPH_C32(0xec7eac2a), SPH_C32(0xc78e1e8b), SPH_C32(0xe9750000), + SPH_C32(0xce6a0000), SPH_C32(0x67d50000), SPH_C32(0xd275c240), + SPH_C32(0xffef5bca), SPH_C32(0x5b3f291e), SPH_C32(0x3e7e7a51), + SPH_C32(0x1c840b44) }, + { SPH_C32(0x96c90000), SPH_C32(0x09ef0000), SPH_C32(0x0c2d0000), + SPH_C32(0x0dcedec0), SPH_C32(0xdf877200), SPH_C32(0xda7d7fb1), + SPH_C32(0xc4ebaa9e), SPH_C32(0x10d4561c), SPH_C32(0x19b00000), + SPH_C32(0x97490000), SPH_C32(0x22570000), SPH_C32(0x33f8c280), + SPH_C32(0xc4825dfb), SPH_C32(0x99d27f87), SPH_C32(0xf59e844d), + SPH_C32(0x4a23badb) }, + { SPH_C32(0xd7130000), SPH_C32(0xd6750000), SPH_C32(0xd7b40000), + SPH_C32(0xffb1d860), SPH_C32(0x6a932fab), SPH_C32(0xdc946dfe), + SPH_C32(0x860d2db9), SPH_C32(0x8490cef3), SPH_C32(0x4ba90000), + SPH_C32(0xac310000), SPH_C32(0x3b5f0000), SPH_C32(0x9ff8c480), + SPH_C32(0x64410c7b), SPH_C32(0xd0630c00), SPH_C32(0x0f5d5670), + SPH_C32(0xd3168692) }, + { SPH_C32(0x313b0000), SPH_C32(0x9a3e0000), SPH_C32(0x7fe10000), + SPH_C32(0x2c61da80), SPH_C32(0xb2f21f13), SPH_C32(0x4433dd24), + SPH_C32(0xae982b0d), SPH_C32(0x53ca8664), SPH_C32(0xbb6c0000), + SPH_C32(0xf5120000), SPH_C32(0x7edd0000), SPH_C32(0x7e75c440), + SPH_C32(0x5f2c0a4a), SPH_C32(0x128e5a99), SPH_C32(0xc4bda86c), + SPH_C32(0x85b1370d) }, + { SPH_C32(0x27d60000), SPH_C32(0x8f560000), SPH_C32(0x92360000), + SPH_C32(0x1e3cd8a0), SPH_C32(0x51fe299a), SPH_C32(0x1e793b67), + SPH_C32(0x4dedd3a5), SPH_C32(0xd2377f6c), SPH_C32(0x5d440000), + SPH_C32(0xb9590000), SPH_C32(0xd6880000), SPH_C32(0xada5c6a0), + SPH_C32(0x874d3af2), SPH_C32(0x8a29ea43), SPH_C32(0xec28aed8), + SPH_C32(0x52eb7f9a) }, + { SPH_C32(0xc1fe0000), SPH_C32(0xc31d0000), SPH_C32(0x3a630000), + SPH_C32(0xcdecda40), SPH_C32(0x899f1922), SPH_C32(0x86de8bbd), + SPH_C32(0x6578d511), SPH_C32(0x056d37fb), SPH_C32(0xad810000), + SPH_C32(0xe07a0000), SPH_C32(0x930a0000), SPH_C32(0x4c28c660), + SPH_C32(0xbc203cc3), SPH_C32(0x48c4bcda), SPH_C32(0x27c850c4), + SPH_C32(0x044cce05) }, + { SPH_C32(0x63220000), SPH_C32(0xa1460000), SPH_C32(0x66e90000), + SPH_C32(0x8061dc80), SPH_C32(0x12314e93), SPH_C32(0x0d82aea3), + SPH_C32(0x545bf930), SPH_C32(0xcaffba2d), SPH_C32(0xa8af0000), + SPH_C32(0x11f00000), SPH_C32(0xbc4c0000), SPH_C32(0x200ac4e0), + SPH_C32(0x4afb0661), SPH_C32(0x5dd63b51), SPH_C32(0x7c98fd76), + SPH_C32(0x88c093ab) }, + { SPH_C32(0x850a0000), SPH_C32(0xed0d0000), SPH_C32(0xcebc0000), + SPH_C32(0x53b1de60), SPH_C32(0xca507e2b), SPH_C32(0x95251e79), + SPH_C32(0x7cceff84), SPH_C32(0x1da5f2ba), SPH_C32(0x586a0000), + SPH_C32(0x48d30000), SPH_C32(0xf9ce0000), SPH_C32(0xc187c420), + SPH_C32(0x71960050), SPH_C32(0x9f3b6dc8), SPH_C32(0xb778036a), + SPH_C32(0xde672234) }, + { SPH_C32(0x93e70000), SPH_C32(0xf8650000), SPH_C32(0x236b0000), + SPH_C32(0x61ecdc40), SPH_C32(0x295c48a2), SPH_C32(0xcf6ff83a), + SPH_C32(0x9fbb072c), SPH_C32(0x9c580bb2), SPH_C32(0xbe420000), + SPH_C32(0x04980000), SPH_C32(0x519b0000), SPH_C32(0x1257c6c0), + SPH_C32(0xa9f730e8), SPH_C32(0x079cdd12), SPH_C32(0x9fed05de), + SPH_C32(0x093d6aa3) }, + { SPH_C32(0x75cf0000), SPH_C32(0xb42e0000), SPH_C32(0x8b3e0000), + SPH_C32(0xb23cdea0), SPH_C32(0xf13d781a), SPH_C32(0x57c848e0), + SPH_C32(0xb72e0198), SPH_C32(0x4b024325), SPH_C32(0x4e870000), + SPH_C32(0x5dbb0000), SPH_C32(0x14190000), SPH_C32(0xf3dac600), + SPH_C32(0x929a36d9), SPH_C32(0xc5718b8b), SPH_C32(0x540dfbc2), + SPH_C32(0x5f9adb3c) } +}; + +static const sph_u32 T512_56[256][16] = { + { SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000), SPH_C32(0x00000000), SPH_C32(0x00000000), + SPH_C32(0x00000000) }, + { SPH_C32(0x033d0000), SPH_C32(0x08b30000), SPH_C32(0xf33a0000), + SPH_C32(0x3ac20007), SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), + SPH_C32(0x0ea5cfe3), SPH_C32(0xe6da7ffe), SPH_C32(0xa8da0000), + SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), SPH_C32(0x07da0002), + SPH_C32(0x7d669583), SPH_C32(0x1f98708a), SPH_C32(0xbb668808), + SPH_C32(0xda878000) }, + { SPH_C32(0xa8da0000), SPH_C32(0x96be0000), SPH_C32(0x5c1d0000), + SPH_C32(0x07da0002), SPH_C32(0x7d669583), SPH_C32(0x1f98708a), + SPH_C32(0xbb668808), SPH_C32(0xda878000), SPH_C32(0xabe70000), + SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), SPH_C32(0x3d180005), + SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), SPH_C32(0xb5c347eb), + SPH_C32(0x3c5dfffe) }, + { SPH_C32(0xabe70000), SPH_C32(0x9e0d0000), SPH_C32(0xaf270000), + SPH_C32(0x3d180005), SPH_C32(0x2c4f1fd3), SPH_C32(0x74f61695), + SPH_C32(0xb5c347eb), SPH_C32(0x3c5dfffe), SPH_C32(0x033d0000), + SPH_C32(0x08b30000), SPH_C32(0xf33a0000), SPH_C32(0x3ac20007), + SPH_C32(0x51298a50), SPH_C32(0x6b6e661f), SPH_C32(0x0ea5cfe3), + SPH_C32(0xe6da7ffe) }, + { SPH_C32(0x01930000), SPH_C32(0xe7820000), SPH_C32(0xedfb0000), + SPH_C32(0xcf0c000b), SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), + SPH_C32(0x063661e1), SPH_C32(0x536f9e7b), SPH_C32(0x92280000), + SPH_C32(0xdc850000), SPH_C32(0x57fa0000), SPH_C32(0x56dc0003), + SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), SPH_C32(0x90cef752), + SPH_C32(0x7b1675d7) }, + { SPH_C32(0x02ae0000), SPH_C32(0xef310000), SPH_C32(0x1ec10000), + SPH_C32(0xf5ce000c), SPH_C32(0xdcf90708), SPH_C32(0xd7cdd231), + SPH_C32(0x0893ae02), SPH_C32(0xb5b5e185), SPH_C32(0x3af20000), + SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), SPH_C32(0x51060001), + SPH_C32(0xc78fb695), SPH_C32(0x4577d386), SPH_C32(0x2ba87f5a), + SPH_C32(0xa191f5d7) }, + { SPH_C32(0xa9490000), SPH_C32(0x713c0000), SPH_C32(0xb1e60000), + SPH_C32(0xc8d60009), SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), + SPH_C32(0xbd50e9e9), SPH_C32(0x89e81e7b), SPH_C32(0x39cf0000), + SPH_C32(0x42880000), SPH_C32(0xf8dd0000), SPH_C32(0x6bc40006), + SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), SPH_C32(0x250db0b9), + SPH_C32(0x474b8a29) }, + { SPH_C32(0xaa740000), SPH_C32(0x798f0000), SPH_C32(0x42dc0000), + SPH_C32(0xf214000e), SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), + SPH_C32(0xb3f5260a), SPH_C32(0x6f326185), SPH_C32(0x91150000), + SPH_C32(0xd4360000), SPH_C32(0xa4c00000), SPH_C32(0x6c1e0004), + SPH_C32(0xebc0a946), SPH_C32(0x3181c513), SPH_C32(0x9e6b38b1), + SPH_C32(0x9dcc0a29) }, + { SPH_C32(0x92280000), SPH_C32(0xdc850000), SPH_C32(0x57fa0000), + SPH_C32(0x56dc0003), SPH_C32(0xbae92316), SPH_C32(0x5aefa30c), + SPH_C32(0x90cef752), SPH_C32(0x7b1675d7), SPH_C32(0x93bb0000), + SPH_C32(0x3b070000), SPH_C32(0xba010000), SPH_C32(0x99d00008), + SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), SPH_C32(0x96f896b3), + SPH_C32(0x2879ebac) }, + { SPH_C32(0x91150000), SPH_C32(0xd4360000), SPH_C32(0xa4c00000), + SPH_C32(0x6c1e0004), SPH_C32(0xebc0a946), SPH_C32(0x3181c513), + SPH_C32(0x9e6b38b1), SPH_C32(0x9dcc0a29), SPH_C32(0x3b610000), + SPH_C32(0xadb90000), SPH_C32(0xe61c0000), SPH_C32(0x9e0a000a), + SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), SPH_C32(0x2d9e1ebb), + SPH_C32(0xf2fe6bac) }, + { SPH_C32(0x3af20000), SPH_C32(0x4a3b0000), SPH_C32(0x0be70000), + SPH_C32(0x51060001), SPH_C32(0xc78fb695), SPH_C32(0x4577d386), + SPH_C32(0x2ba87f5a), SPH_C32(0xa191f5d7), SPH_C32(0x385c0000), + SPH_C32(0xa50a0000), SPH_C32(0x15260000), SPH_C32(0xa4c8000d), + SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), SPH_C32(0x233bd158), + SPH_C32(0x14241452) }, + { SPH_C32(0x39cf0000), SPH_C32(0x42880000), SPH_C32(0xf8dd0000), + SPH_C32(0x6bc40006), SPH_C32(0x96a63cc5), SPH_C32(0x2e19b599), + SPH_C32(0x250db0b9), SPH_C32(0x474b8a29), SPH_C32(0x90860000), + SPH_C32(0x33b40000), SPH_C32(0x493b0000), SPH_C32(0xa312000f), + SPH_C32(0x6610241e), SPH_C32(0x8d22713d), SPH_C32(0x985d5950), + SPH_C32(0xcea39452) }, + { SPH_C32(0x93bb0000), SPH_C32(0x3b070000), SPH_C32(0xba010000), + SPH_C32(0x99d00008), SPH_C32(0x3739ae4e), SPH_C32(0xe64c1722), + SPH_C32(0x96f896b3), SPH_C32(0x2879ebac), SPH_C32(0x01930000), + SPH_C32(0xe7820000), SPH_C32(0xedfb0000), SPH_C32(0xcf0c000b), + SPH_C32(0x8dd08d58), SPH_C32(0xbca3b42e), SPH_C32(0x063661e1), + SPH_C32(0x536f9e7b) }, + { SPH_C32(0x90860000), SPH_C32(0x33b40000), SPH_C32(0x493b0000), + SPH_C32(0xa312000f), SPH_C32(0x6610241e), SPH_C32(0x8d22713d), + SPH_C32(0x985d5950), SPH_C32(0xcea39452), SPH_C32(0xa9490000), + SPH_C32(0x713c0000), SPH_C32(0xb1e60000), SPH_C32(0xc8d60009), + SPH_C32(0xf0b618db), SPH_C32(0xa33bc4a4), SPH_C32(0xbd50e9e9), + SPH_C32(0x89e81e7b) }, + { SPH_C32(0x3b610000), SPH_C32(0xadb90000), SPH_C32(0xe61c0000), + SPH_C32(0x9e0a000a), SPH_C32(0x4a5f3bcd), SPH_C32(0xf9d467a8), + SPH_C32(0x2d9e1ebb), SPH_C32(0xf2fe6bac), SPH_C32(0xaa740000), + SPH_C32(0x798f0000), SPH_C32(0x42dc0000), SPH_C32(0xf214000e), + SPH_C32(0xa19f928b), SPH_C32(0xc855a2bb), SPH_C32(0xb3f5260a), + SPH_C32(0x6f326185) }, + { SPH_C32(0x385c0000), SPH_C32(0xa50a0000), SPH_C32(0x15260000), + SPH_C32(0xa4c8000d), SPH_C32(0x1b76b19d), SPH_C32(0x92ba01b7), + SPH_C32(0x233bd158), SPH_C32(0x14241452), SPH_C32(0x02ae0000), + SPH_C32(0xef310000), SPH_C32(0x1ec10000), SPH_C32(0xf5ce000c), + SPH_C32(0xdcf90708), SPH_C32(0xd7cdd231), SPH_C32(0x0893ae02), + SPH_C32(0xb5b5e185) }, + { SPH_C32(0x5fa80000), SPH_C32(0x56030000), SPH_C32(0x43ae0000), + SPH_C32(0x64f30013), SPH_C32(0x257e86bf), SPH_C32(0x1311944e), + SPH_C32(0x541e95bf), SPH_C32(0x8ea4db69), SPH_C32(0x00440000), + SPH_C32(0x7f480000), SPH_C32(0xda7c0000), SPH_C32(0x2a230001), + SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), SPH_C32(0x030a9e60), + SPH_C32(0xbe0a679e) }, + { SPH_C32(0x5c950000), SPH_C32(0x5eb00000), SPH_C32(0xb0940000), + SPH_C32(0x5e310014), SPH_C32(0x74570cef), SPH_C32(0x787ff251), + SPH_C32(0x5abb5a5c), SPH_C32(0x687ea497), SPH_C32(0xa89e0000), + SPH_C32(0xe9f60000), SPH_C32(0x86610000), SPH_C32(0x2df90003), + SPH_C32(0x46cb5c4f), SPH_C32(0xb62eec0d), SPH_C32(0xb86c1668), + SPH_C32(0x648de79e) }, + { SPH_C32(0xf7720000), SPH_C32(0xc0bd0000), SPH_C32(0x1fb30000), + SPH_C32(0x63290011), SPH_C32(0x5818133c), SPH_C32(0x0c89e4c4), + SPH_C32(0xef781db7), SPH_C32(0x54235b69), SPH_C32(0xaba30000), + SPH_C32(0xe1450000), SPH_C32(0x755b0000), SPH_C32(0x173b0004), + SPH_C32(0x17e2d61f), SPH_C32(0xdd408a12), SPH_C32(0xb6c9d98b), + SPH_C32(0x82579860) }, + { SPH_C32(0xf44f0000), SPH_C32(0xc80e0000), SPH_C32(0xec890000), + SPH_C32(0x59eb0016), SPH_C32(0x0931996c), SPH_C32(0x67e782db), + SPH_C32(0xe1ddd254), SPH_C32(0xb2f92497), SPH_C32(0x03790000), + SPH_C32(0x77fb0000), SPH_C32(0x29460000), SPH_C32(0x10e10006), + SPH_C32(0x6a84439c), SPH_C32(0xc2d8fa98), SPH_C32(0x0daf5183), + SPH_C32(0x58d01860) }, + { SPH_C32(0x5e3b0000), SPH_C32(0xb1810000), SPH_C32(0xae550000), + SPH_C32(0xabff0018), SPH_C32(0xa8ae0be7), SPH_C32(0xafb22060), + SPH_C32(0x5228f45e), SPH_C32(0xddcb4512), SPH_C32(0x926c0000), + SPH_C32(0xa3cd0000), SPH_C32(0x8d860000), SPH_C32(0x7cff0002), + SPH_C32(0x8144eada), SPH_C32(0xf3593f8b), SPH_C32(0x93c46932), + SPH_C32(0xc51c1249) }, + { SPH_C32(0x5d060000), SPH_C32(0xb9320000), SPH_C32(0x5d6f0000), + SPH_C32(0x913d001f), SPH_C32(0xf98781b7), SPH_C32(0xc4dc467f), + SPH_C32(0x5c8d3bbd), SPH_C32(0x3b113aec), SPH_C32(0x3ab60000), + SPH_C32(0x35730000), SPH_C32(0xd19b0000), SPH_C32(0x7b250000), + SPH_C32(0xfc227f59), SPH_C32(0xecc14f01), SPH_C32(0x28a2e13a), + SPH_C32(0x1f9b9249) }, + { SPH_C32(0xf6e10000), SPH_C32(0x273f0000), SPH_C32(0xf2480000), + SPH_C32(0xac25001a), SPH_C32(0xd5c89e64), SPH_C32(0xb02a50ea), + SPH_C32(0xe94e7c56), SPH_C32(0x074cc512), SPH_C32(0x398b0000), + SPH_C32(0x3dc00000), SPH_C32(0x22a10000), SPH_C32(0x41e70007), + SPH_C32(0xad0bf509), SPH_C32(0x87af291e), SPH_C32(0x26072ed9), + SPH_C32(0xf941edb7) }, + { SPH_C32(0xf5dc0000), SPH_C32(0x2f8c0000), SPH_C32(0x01720000), + SPH_C32(0x96e7001d), SPH_C32(0x84e11434), SPH_C32(0xdb4436f5), + SPH_C32(0xe7ebb3b5), SPH_C32(0xe196baec), SPH_C32(0x91510000), + SPH_C32(0xab7e0000), SPH_C32(0x7ebc0000), SPH_C32(0x463d0005), + SPH_C32(0xd06d608a), SPH_C32(0x98375994), SPH_C32(0x9d61a6d1), + SPH_C32(0x23c66db7) }, + { SPH_C32(0xcd800000), SPH_C32(0x8a860000), SPH_C32(0x14540000), + SPH_C32(0x322f0010), SPH_C32(0x9f97a5a9), SPH_C32(0x49fe3742), + SPH_C32(0xc4d062ed), SPH_C32(0xf5b2aebe), SPH_C32(0x93ff0000), + SPH_C32(0x444f0000), SPH_C32(0x607d0000), SPH_C32(0xb3f30009), + SPH_C32(0x0c946782), SPH_C32(0x4ffa8ba5), SPH_C32(0x95f208d3), + SPH_C32(0x96738c32) }, + { SPH_C32(0xcebd0000), SPH_C32(0x82350000), SPH_C32(0xe76e0000), + SPH_C32(0x08ed0017), SPH_C32(0xcebe2ff9), SPH_C32(0x2290515d), + SPH_C32(0xca75ad0e), SPH_C32(0x1368d140), SPH_C32(0x3b250000), + SPH_C32(0xd2f10000), SPH_C32(0x3c600000), SPH_C32(0xb429000b), + SPH_C32(0x71f2f201), SPH_C32(0x5062fb2f), SPH_C32(0x2e9480db), + SPH_C32(0x4cf40c32) }, + { SPH_C32(0x655a0000), SPH_C32(0x1c380000), SPH_C32(0x48490000), + SPH_C32(0x35f50012), SPH_C32(0xe2f1302a), SPH_C32(0x566647c8), + SPH_C32(0x7fb6eae5), SPH_C32(0x2f352ebe), SPH_C32(0x38180000), + SPH_C32(0xda420000), SPH_C32(0xcf5a0000), SPH_C32(0x8eeb000c), + SPH_C32(0x20db7851), SPH_C32(0x3b0c9d30), SPH_C32(0x20314f38), + SPH_C32(0xaa2e73cc) }, + { SPH_C32(0x66670000), SPH_C32(0x148b0000), SPH_C32(0xbb730000), + SPH_C32(0x0f370015), SPH_C32(0xb3d8ba7a), SPH_C32(0x3d0821d7), + SPH_C32(0x71132506), SPH_C32(0xc9ef5140), SPH_C32(0x90c20000), + SPH_C32(0x4cfc0000), SPH_C32(0x93470000), SPH_C32(0x8931000e), + SPH_C32(0x5dbdedd2), SPH_C32(0x2494edba), SPH_C32(0x9b57c730), + SPH_C32(0x70a9f3cc) }, + { SPH_C32(0xcc130000), SPH_C32(0x6d040000), SPH_C32(0xf9af0000), + SPH_C32(0xfd23001b), SPH_C32(0x124728f1), SPH_C32(0xf55d836c), + SPH_C32(0xc2e6030c), SPH_C32(0xa6dd30c5), SPH_C32(0x01d70000), + SPH_C32(0x98ca0000), SPH_C32(0x37870000), SPH_C32(0xe52f000a), + SPH_C32(0xb67d4494), SPH_C32(0x151528a9), SPH_C32(0x053cff81), + SPH_C32(0xed65f9e5) }, + { SPH_C32(0xcf2e0000), SPH_C32(0x65b70000), SPH_C32(0x0a950000), + SPH_C32(0xc7e1001c), SPH_C32(0x436ea2a1), SPH_C32(0x9e33e573), + SPH_C32(0xcc43ccef), SPH_C32(0x40074f3b), SPH_C32(0xa90d0000), + SPH_C32(0x0e740000), SPH_C32(0x6b9a0000), SPH_C32(0xe2f50008), + SPH_C32(0xcb1bd117), SPH_C32(0x0a8d5823), SPH_C32(0xbe5a7789), + SPH_C32(0x37e279e5) }, + { SPH_C32(0x64c90000), SPH_C32(0xfbba0000), SPH_C32(0xa5b20000), + SPH_C32(0xfaf90019), SPH_C32(0x6f21bd72), SPH_C32(0xeac5f3e6), + SPH_C32(0x79808b04), SPH_C32(0x7c5ab0c5), SPH_C32(0xaa300000), + SPH_C32(0x06c70000), SPH_C32(0x98a00000), SPH_C32(0xd837000f), + SPH_C32(0x9a325b47), SPH_C32(0x61e33e3c), SPH_C32(0xb0ffb86a), + SPH_C32(0xd138061b) }, + { SPH_C32(0x67f40000), SPH_C32(0xf3090000), SPH_C32(0x56880000), + SPH_C32(0xc03b001e), SPH_C32(0x3e083722), SPH_C32(0x81ab95f9), + SPH_C32(0x772544e7), SPH_C32(0x9a80cf3b), SPH_C32(0x02ea0000), + SPH_C32(0x90790000), SPH_C32(0xc4bd0000), SPH_C32(0xdfed000d), + SPH_C32(0xe754cec4), SPH_C32(0x7e7b4eb6), SPH_C32(0x0b993062), + SPH_C32(0x0bbf861b) }, + { SPH_C32(0x00440000), SPH_C32(0x7f480000), SPH_C32(0xda7c0000), + SPH_C32(0x2a230001), SPH_C32(0x3badc9cc), SPH_C32(0xa9b69c87), + SPH_C32(0x030a9e60), SPH_C32(0xbe0a679e), SPH_C32(0x5fec0000), + SPH_C32(0x294b0000), SPH_C32(0x99d20000), SPH_C32(0x4ed00012), + SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), SPH_C32(0x57140bdf), + SPH_C32(0x30aebcf7) }, + { SPH_C32(0x03790000), SPH_C32(0x77fb0000), SPH_C32(0x29460000), + SPH_C32(0x10e10006), SPH_C32(0x6a84439c), SPH_C32(0xc2d8fa98), + SPH_C32(0x0daf5183), SPH_C32(0x58d01860), SPH_C32(0xf7360000), + SPH_C32(0xbff50000), SPH_C32(0xc5cf0000), SPH_C32(0x490a0010), + SPH_C32(0x63b5daf0), SPH_C32(0xa53f7843), SPH_C32(0xec7283d7), + SPH_C32(0xea293cf7) }, + { SPH_C32(0xa89e0000), SPH_C32(0xe9f60000), SPH_C32(0x86610000), + SPH_C32(0x2df90003), SPH_C32(0x46cb5c4f), SPH_C32(0xb62eec0d), + SPH_C32(0xb86c1668), SPH_C32(0x648de79e), SPH_C32(0xf40b0000), + SPH_C32(0xb7460000), SPH_C32(0x36f50000), SPH_C32(0x73c80017), + SPH_C32(0x329c50a0), SPH_C32(0xce511e5c), SPH_C32(0xe2d74c34), + SPH_C32(0x0cf34309) }, + { SPH_C32(0xaba30000), SPH_C32(0xe1450000), SPH_C32(0x755b0000), + SPH_C32(0x173b0004), SPH_C32(0x17e2d61f), SPH_C32(0xdd408a12), + SPH_C32(0xb6c9d98b), SPH_C32(0x82579860), SPH_C32(0x5cd10000), + SPH_C32(0x21f80000), SPH_C32(0x6ae80000), SPH_C32(0x74120015), + SPH_C32(0x4ffac523), SPH_C32(0xd1c96ed6), SPH_C32(0x59b1c43c), + SPH_C32(0xd674c309) }, + { SPH_C32(0x01d70000), SPH_C32(0x98ca0000), SPH_C32(0x37870000), + SPH_C32(0xe52f000a), SPH_C32(0xb67d4494), SPH_C32(0x151528a9), + SPH_C32(0x053cff81), SPH_C32(0xed65f9e5), SPH_C32(0xcdc40000), + SPH_C32(0xf5ce0000), SPH_C32(0xce280000), SPH_C32(0x180c0011), + SPH_C32(0xa43a6c65), SPH_C32(0xe048abc5), SPH_C32(0xc7dafc8d), + SPH_C32(0x4bb8c920) }, + { SPH_C32(0x02ea0000), SPH_C32(0x90790000), SPH_C32(0xc4bd0000), + SPH_C32(0xdfed000d), SPH_C32(0xe754cec4), SPH_C32(0x7e7b4eb6), + SPH_C32(0x0b993062), SPH_C32(0x0bbf861b), SPH_C32(0x651e0000), + SPH_C32(0x63700000), SPH_C32(0x92350000), SPH_C32(0x1fd60013), + SPH_C32(0xd95cf9e6), SPH_C32(0xffd0db4f), SPH_C32(0x7cbc7485), + SPH_C32(0x913f4920) }, + { SPH_C32(0xa90d0000), SPH_C32(0x0e740000), SPH_C32(0x6b9a0000), + SPH_C32(0xe2f50008), SPH_C32(0xcb1bd117), SPH_C32(0x0a8d5823), + SPH_C32(0xbe5a7789), SPH_C32(0x37e279e5), SPH_C32(0x66230000), + SPH_C32(0x6bc30000), SPH_C32(0x610f0000), SPH_C32(0x25140014), + SPH_C32(0x887573b6), SPH_C32(0x94bebd50), SPH_C32(0x7219bb66), + SPH_C32(0x77e536de) }, + { SPH_C32(0xaa300000), SPH_C32(0x06c70000), SPH_C32(0x98a00000), + SPH_C32(0xd837000f), SPH_C32(0x9a325b47), SPH_C32(0x61e33e3c), + SPH_C32(0xb0ffb86a), SPH_C32(0xd138061b), SPH_C32(0xcef90000), + SPH_C32(0xfd7d0000), SPH_C32(0x3d120000), SPH_C32(0x22ce0016), + SPH_C32(0xf513e635), SPH_C32(0x8b26cdda), SPH_C32(0xc97f336e), + SPH_C32(0xad62b6de) }, + { SPH_C32(0x926c0000), SPH_C32(0xa3cd0000), SPH_C32(0x8d860000), + SPH_C32(0x7cff0002), SPH_C32(0x8144eada), SPH_C32(0xf3593f8b), + SPH_C32(0x93c46932), SPH_C32(0xc51c1249), SPH_C32(0xcc570000), + SPH_C32(0x124c0000), SPH_C32(0x23d30000), SPH_C32(0xd700001a), + SPH_C32(0x29eae13d), SPH_C32(0x5ceb1feb), SPH_C32(0xc1ec9d6c), + SPH_C32(0x18d7575b) }, + { SPH_C32(0x91510000), SPH_C32(0xab7e0000), SPH_C32(0x7ebc0000), + SPH_C32(0x463d0005), SPH_C32(0xd06d608a), SPH_C32(0x98375994), + SPH_C32(0x9d61a6d1), SPH_C32(0x23c66db7), SPH_C32(0x648d0000), + SPH_C32(0x84f20000), SPH_C32(0x7fce0000), SPH_C32(0xd0da0018), + SPH_C32(0x548c74be), SPH_C32(0x43736f61), SPH_C32(0x7a8a1564), + SPH_C32(0xc250d75b) }, + { SPH_C32(0x3ab60000), SPH_C32(0x35730000), SPH_C32(0xd19b0000), + SPH_C32(0x7b250000), SPH_C32(0xfc227f59), SPH_C32(0xecc14f01), + SPH_C32(0x28a2e13a), SPH_C32(0x1f9b9249), SPH_C32(0x67b00000), + SPH_C32(0x8c410000), SPH_C32(0x8cf40000), SPH_C32(0xea18001f), + SPH_C32(0x05a5feee), SPH_C32(0x281d097e), SPH_C32(0x742fda87), + SPH_C32(0x248aa8a5) }, + { SPH_C32(0x398b0000), SPH_C32(0x3dc00000), SPH_C32(0x22a10000), + SPH_C32(0x41e70007), SPH_C32(0xad0bf509), SPH_C32(0x87af291e), + SPH_C32(0x26072ed9), SPH_C32(0xf941edb7), SPH_C32(0xcf6a0000), + SPH_C32(0x1aff0000), SPH_C32(0xd0e90000), SPH_C32(0xedc2001d), + SPH_C32(0x78c36b6d), SPH_C32(0x378579f4), SPH_C32(0xcf49528f), + SPH_C32(0xfe0d28a5) }, + { SPH_C32(0x93ff0000), SPH_C32(0x444f0000), SPH_C32(0x607d0000), + SPH_C32(0xb3f30009), SPH_C32(0x0c946782), SPH_C32(0x4ffa8ba5), + SPH_C32(0x95f208d3), SPH_C32(0x96738c32), SPH_C32(0x5e7f0000), + SPH_C32(0xcec90000), SPH_C32(0x74290000), SPH_C32(0x81dc0019), + SPH_C32(0x9303c22b), SPH_C32(0x0604bce7), SPH_C32(0x51226a3e), + SPH_C32(0x63c1228c) }, + { SPH_C32(0x90c20000), SPH_C32(0x4cfc0000), SPH_C32(0x93470000), + SPH_C32(0x8931000e), SPH_C32(0x5dbdedd2), SPH_C32(0x2494edba), + SPH_C32(0x9b57c730), SPH_C32(0x70a9f3cc), SPH_C32(0xf6a50000), + SPH_C32(0x58770000), SPH_C32(0x28340000), SPH_C32(0x8606001b), + SPH_C32(0xee6557a8), SPH_C32(0x199ccc6d), SPH_C32(0xea44e236), + SPH_C32(0xb946a28c) }, + { SPH_C32(0x3b250000), SPH_C32(0xd2f10000), SPH_C32(0x3c600000), + SPH_C32(0xb429000b), SPH_C32(0x71f2f201), SPH_C32(0x5062fb2f), + SPH_C32(0x2e9480db), SPH_C32(0x4cf40c32), SPH_C32(0xf5980000), + SPH_C32(0x50c40000), SPH_C32(0xdb0e0000), SPH_C32(0xbcc4001c), + SPH_C32(0xbf4cddf8), SPH_C32(0x72f2aa72), SPH_C32(0xe4e12dd5), + SPH_C32(0x5f9cdd72) }, + { SPH_C32(0x38180000), SPH_C32(0xda420000), SPH_C32(0xcf5a0000), + SPH_C32(0x8eeb000c), SPH_C32(0x20db7851), SPH_C32(0x3b0c9d30), + SPH_C32(0x20314f38), SPH_C32(0xaa2e73cc), SPH_C32(0x5d420000), + SPH_C32(0xc67a0000), SPH_C32(0x87130000), SPH_C32(0xbb1e001e), + SPH_C32(0xc22a487b), SPH_C32(0x6d6adaf8), SPH_C32(0x5f87a5dd), + SPH_C32(0x851b5d72) }, + { SPH_C32(0x5fec0000), SPH_C32(0x294b0000), SPH_C32(0x99d20000), + SPH_C32(0x4ed00012), SPH_C32(0x1ed34f73), SPH_C32(0xbaa708c9), + SPH_C32(0x57140bdf), SPH_C32(0x30aebcf7), SPH_C32(0x5fa80000), + SPH_C32(0x56030000), SPH_C32(0x43ae0000), SPH_C32(0x64f30013), + SPH_C32(0x257e86bf), SPH_C32(0x1311944e), SPH_C32(0x541e95bf), + SPH_C32(0x8ea4db69) }, + { SPH_C32(0x5cd10000), SPH_C32(0x21f80000), SPH_C32(0x6ae80000), + SPH_C32(0x74120015), SPH_C32(0x4ffac523), SPH_C32(0xd1c96ed6), + SPH_C32(0x59b1c43c), SPH_C32(0xd674c309), SPH_C32(0xf7720000), + SPH_C32(0xc0bd0000), SPH_C32(0x1fb30000), SPH_C32(0x63290011), + SPH_C32(0x5818133c), SPH_C32(0x0c89e4c4), SPH_C32(0xef781db7), + SPH_C32(0x54235b69) }, + { SPH_C32(0xf7360000), SPH_C32(0xbff50000), SPH_C32(0xc5cf0000), + SPH_C32(0x490a0010), SPH_C32(0x63b5daf0), SPH_C32(0xa53f7843), + SPH_C32(0xec7283d7), SPH_C32(0xea293cf7), SPH_C32(0xf44f0000), + SPH_C32(0xc80e0000), SPH_C32(0xec890000), SPH_C32(0x59eb0016), + SPH_C32(0x0931996c), SPH_C32(0x67e782db), SPH_C32(0xe1ddd254), + SPH_C32(0xb2f92497) }, + { SPH_C32(0xf40b0000), SPH_C32(0xb7460000), SPH_C32(0x36f50000), + SPH_C32(0x73c80017), SPH_C32(0x329c50a0), SPH_C32(0xce511e5c), + SPH_C32(0xe2d74c34), SPH_C32(0x0cf34309), SPH_C32(0x5c950000), + SPH_C32(0x5eb00000), SPH_C32(0xb0940000), SPH_C32(0x5e310014), + SPH_C32(0x74570cef), SPH_C32(0x787ff251), SPH_C32(0x5abb5a5c), + SPH_C32(0x687ea497) }, + { SPH_C32(0x5e7f0000), SPH_C32(0xcec90000), SPH_C32(0x74290000), + SPH_C32(0x81dc0019), SPH_C32(0x9303c22b), SPH_C32(0x0604bce7), + SPH_C32(0x51226a3e), SPH_C32(0x63c1228c), SPH_C32(0xcd800000), + SPH_C32(0x8a860000), SPH_C32(0x14540000), SPH_C32(0x322f0010), + SPH_C32(0x9f97a5a9), SPH_C32(0x49fe3742), SPH_C32(0xc4d062ed), + SPH_C32(0xf5b2aebe) }, + { SPH_C32(0x5d420000), SPH_C32(0xc67a0000), SPH_C32(0x87130000), + SPH_C32(0xbb1e001e), SPH_C32(0xc22a487b), SPH_C32(0x6d6adaf8), + SPH_C32(0x5f87a5dd), SPH_C32(0x851b5d72), SPH_C32(0x655a0000), + SPH_C32(0x1c380000), SPH_C32(0x48490000), SPH_C32(0x35f50012), + SPH_C32(0xe2f1302a), SPH_C32(0x566647c8), SPH_C32(0x7fb6eae5), + SPH_C32(0x2f352ebe) }, + { SPH_C32(0xf6a50000), SPH_C32(0x58770000), SPH_C32(0x28340000), + SPH_C32(0x8606001b), SPH_C32(0xee6557a8), SPH_C32(0x199ccc6d), + SPH_C32(0xea44e236), SPH_C32(0xb946a28c), SPH_C32(0x66670000), + SPH_C32(0x148b0000), SPH_C32(0xbb730000), SPH_C32(0x0f370015), + SPH_C32(0xb3d8ba7a), SPH_C32(0x3d0821d7), SPH_C32(0x71132506), + SPH_C32(0xc9ef5140) }, + { SPH_C32(0xf5980000), SPH_C32(0x50c40000), SPH_C32(0xdb0e0000), + SPH_C32(0xbcc4001c), SPH_C32(0xbf4cddf8), SPH_C32(0x72f2aa72), + SPH_C32(0xe4e12dd5), SPH_C32(0x5f9cdd72), SPH_C32(0xcebd0000), + SPH_C32(0x82350000), SPH_C32(0xe76e0000), SPH_C32(0x08ed0017), + SPH_C32(0xcebe2ff9), SPH_C32(0x2290515d), SPH_C32(0xca75ad0e), + SPH_C32(0x1368d140) }, + { SPH_C32(0xcdc40000), SPH_C32(0xf5ce0000), SPH_C32(0xce280000), + SPH_C32(0x180c0011), SPH_C32(0xa43a6c65), SPH_C32(0xe048abc5), + SPH_C32(0xc7dafc8d), SPH_C32(0x4bb8c920), SPH_C32(0xcc130000), + SPH_C32(0x6d040000), SPH_C32(0xf9af0000), SPH_C32(0xfd23001b), + SPH_C32(0x124728f1), SPH_C32(0xf55d836c), SPH_C32(0xc2e6030c), + SPH_C32(0xa6dd30c5) }, + { SPH_C32(0xcef90000), SPH_C32(0xfd7d0000), SPH_C32(0x3d120000), + SPH_C32(0x22ce0016), SPH_C32(0xf513e635), SPH_C32(0x8b26cdda), + SPH_C32(0xc97f336e), SPH_C32(0xad62b6de), SPH_C32(0x64c90000), + SPH_C32(0xfbba0000), SPH_C32(0xa5b20000), SPH_C32(0xfaf90019), + SPH_C32(0x6f21bd72), SPH_C32(0xeac5f3e6), SPH_C32(0x79808b04), + SPH_C32(0x7c5ab0c5) }, + { SPH_C32(0x651e0000), SPH_C32(0x63700000), SPH_C32(0x92350000), + SPH_C32(0x1fd60013), SPH_C32(0xd95cf9e6), SPH_C32(0xffd0db4f), + SPH_C32(0x7cbc7485), SPH_C32(0x913f4920), SPH_C32(0x67f40000), + SPH_C32(0xf3090000), SPH_C32(0x56880000), SPH_C32(0xc03b001e), + SPH_C32(0x3e083722), SPH_C32(0x81ab95f9), SPH_C32(0x772544e7), + SPH_C32(0x9a80cf3b) }, + { SPH_C32(0x66230000), SPH_C32(0x6bc30000), SPH_C32(0x610f0000), + SPH_C32(0x25140014), SPH_C32(0x887573b6), SPH_C32(0x94bebd50), + SPH_C32(0x7219bb66), SPH_C32(0x77e536de), SPH_C32(0xcf2e0000), + SPH_C32(0x65b70000), SPH_C32(0x0a950000), SPH_C32(0xc7e1001c), + SPH_C32(0x436ea2a1), SPH_C32(0x9e33e573), SPH_C32(0xcc43ccef), + SPH_C32(0x40074f3b) }, + { SPH_C32(0xcc570000), SPH_C32(0x124c0000), SPH_C32(0x23d30000), + SPH_C32(0xd700001a), SPH_C32(0x29eae13d), SPH_C32(0x5ceb1feb), + SPH_C32(0xc1ec9d6c), SPH_C32(0x18d7575b), SPH_C32(0x5e3b0000), + SPH_C32(0xb1810000), SPH_C32(0xae550000), SPH_C32(0xabff0018), + SPH_C32(0xa8ae0be7), SPH_C32(0xafb22060), SPH_C32(0x5228f45e), + SPH_C32(0xddcb4512) }, + { SPH_C32(0xcf6a0000), SPH_C32(0x1aff0000), SPH_C32(0xd0e90000), + SPH_C32(0xedc2001d), SPH_C32(0x78c36b6d), SPH_C32(0x378579f4), + SPH_C32(0xcf49528f), SPH_C32(0xfe0d28a5), SPH_C32(0xf6e10000), + SPH_C32(0x273f0000), SPH_C32(0xf2480000), SPH_C32(0xac25001a), + SPH_C32(0xd5c89e64), SPH_C32(0xb02a50ea), SPH_C32(0xe94e7c56), + SPH_C32(0x074cc512) }, + { SPH_C32(0x648d0000), SPH_C32(0x84f20000), SPH_C32(0x7fce0000), + SPH_C32(0xd0da0018), SPH_C32(0x548c74be), SPH_C32(0x43736f61), + SPH_C32(0x7a8a1564), SPH_C32(0xc250d75b), SPH_C32(0xf5dc0000), + SPH_C32(0x2f8c0000), SPH_C32(0x01720000), SPH_C32(0x96e7001d), + SPH_C32(0x84e11434), SPH_C32(0xdb4436f5), SPH_C32(0xe7ebb3b5), + SPH_C32(0xe196baec) }, + { SPH_C32(0x67b00000), SPH_C32(0x8c410000), SPH_C32(0x8cf40000), + SPH_C32(0xea18001f), SPH_C32(0x05a5feee), SPH_C32(0x281d097e), + SPH_C32(0x742fda87), SPH_C32(0x248aa8a5), SPH_C32(0x5d060000), + SPH_C32(0xb9320000), SPH_C32(0x5d6f0000), SPH_C32(0x913d001f), + SPH_C32(0xf98781b7), SPH_C32(0xc4dc467f), SPH_C32(0x5c8d3bbd), + SPH_C32(0x3b113aec) }, + { SPH_C32(0xee930000), SPH_C32(0xd6070000), SPH_C32(0x92c10000), + SPH_C32(0x2b9801e0), SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), + SPH_C32(0x45312374), SPH_C32(0x201f6a64), SPH_C32(0x7b280000), + SPH_C32(0x57420000), SPH_C32(0xa9e50000), SPH_C32(0x634300a0), + SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), SPH_C32(0x27f83b03), + SPH_C32(0xc7ff60f0) }, + { SPH_C32(0xedae0000), SPH_C32(0xdeb40000), SPH_C32(0x61fb0000), + SPH_C32(0x115a01e7), SPH_C32(0xc578a22c), SPH_C32(0x50029d48), + SPH_C32(0x4b94ec97), SPH_C32(0xc6c5159a), SPH_C32(0xd3f20000), + SPH_C32(0xc1fc0000), SPH_C32(0xf5f80000), SPH_C32(0x649900a2), + SPH_C32(0xe3bdd1ac), SPH_C32(0x7201e531), SPH_C32(0x9c9eb30b), + SPH_C32(0x1d78e0f0) }, + { SPH_C32(0x46490000), SPH_C32(0x40b90000), SPH_C32(0xcedc0000), + SPH_C32(0x2c4201e2), SPH_C32(0xe937bdff), SPH_C32(0x24f48bdd), + SPH_C32(0xfe57ab7c), SPH_C32(0xfa98ea64), SPH_C32(0xd0cf0000), + SPH_C32(0xc94f0000), SPH_C32(0x06c20000), SPH_C32(0x5e5b00a5), + SPH_C32(0xb2945bfc), SPH_C32(0x196f832e), SPH_C32(0x923b7ce8), + SPH_C32(0xfba29f0e) }, + { SPH_C32(0x45740000), SPH_C32(0x480a0000), SPH_C32(0x3de60000), + SPH_C32(0x168001e5), SPH_C32(0xb81e37af), SPH_C32(0x4f9aedc2), + SPH_C32(0xf0f2649f), SPH_C32(0x1c42959a), SPH_C32(0x78150000), + SPH_C32(0x5ff10000), SPH_C32(0x5adf0000), SPH_C32(0x598100a7), + SPH_C32(0xcff2ce7f), SPH_C32(0x06f7f3a4), SPH_C32(0x295df4e0), + SPH_C32(0x21251f0e) }, + { SPH_C32(0xef000000), SPH_C32(0x31850000), SPH_C32(0x7f3a0000), + SPH_C32(0xe49401eb), SPH_C32(0x1981a524), SPH_C32(0x87cf4f79), + SPH_C32(0x43074295), SPH_C32(0x7370f41f), SPH_C32(0xe9000000), + SPH_C32(0x8bc70000), SPH_C32(0xfe1f0000), SPH_C32(0x359f00a3), + SPH_C32(0x24326739), SPH_C32(0x377636b7), SPH_C32(0xb736cc51), + SPH_C32(0xbce91527) }, + { SPH_C32(0xec3d0000), SPH_C32(0x39360000), SPH_C32(0x8c000000), + SPH_C32(0xde5601ec), SPH_C32(0x48a82f74), SPH_C32(0xeca12966), + SPH_C32(0x4da28d76), SPH_C32(0x95aa8be1), SPH_C32(0x41da0000), + SPH_C32(0x1d790000), SPH_C32(0xa2020000), SPH_C32(0x324500a1), + SPH_C32(0x5954f2ba), SPH_C32(0x28ee463d), SPH_C32(0x0c504459), + SPH_C32(0x666e9527) }, + { SPH_C32(0x47da0000), SPH_C32(0xa73b0000), SPH_C32(0x23270000), + SPH_C32(0xe34e01e9), SPH_C32(0x64e730a7), SPH_C32(0x98573ff3), + SPH_C32(0xf861ca9d), SPH_C32(0xa9f7741f), SPH_C32(0x42e70000), + SPH_C32(0x15ca0000), SPH_C32(0x51380000), SPH_C32(0x088700a6), + SPH_C32(0x087d78ea), SPH_C32(0x43802022), SPH_C32(0x02f58bba), + SPH_C32(0x80b4ead9) }, + { SPH_C32(0x44e70000), SPH_C32(0xaf880000), SPH_C32(0xd01d0000), + SPH_C32(0xd98c01ee), SPH_C32(0x35cebaf7), SPH_C32(0xf33959ec), + SPH_C32(0xf6c4057e), SPH_C32(0x4f2d0be1), SPH_C32(0xea3d0000), + SPH_C32(0x83740000), SPH_C32(0x0d250000), SPH_C32(0x0f5d00a4), + SPH_C32(0x751bed69), SPH_C32(0x5c1850a8), SPH_C32(0xb99303b2), + SPH_C32(0x5a336ad9) }, + { SPH_C32(0x7cbb0000), SPH_C32(0x0a820000), SPH_C32(0xc53b0000), + SPH_C32(0x7d4401e3), SPH_C32(0x2eb80b6a), SPH_C32(0x6183585b), + SPH_C32(0xd5ffd426), SPH_C32(0x5b091fb3), SPH_C32(0xe8930000), + SPH_C32(0x6c450000), SPH_C32(0x13e40000), SPH_C32(0xfa9300a8), + SPH_C32(0xa9e2ea61), SPH_C32(0x8bd58299), SPH_C32(0xb100adb0), + SPH_C32(0xef868b5c) }, + { SPH_C32(0x7f860000), SPH_C32(0x02310000), SPH_C32(0x36010000), + SPH_C32(0x478601e4), SPH_C32(0x7f91813a), SPH_C32(0x0aed3e44), + SPH_C32(0xdb5a1bc5), SPH_C32(0xbdd3604d), SPH_C32(0x40490000), + SPH_C32(0xfafb0000), SPH_C32(0x4ff90000), SPH_C32(0xfd4900aa), + SPH_C32(0xd4847fe2), SPH_C32(0x944df213), SPH_C32(0x0a6625b8), + SPH_C32(0x35010b5c) }, + { SPH_C32(0xd4610000), SPH_C32(0x9c3c0000), SPH_C32(0x99260000), + SPH_C32(0x7a9e01e1), SPH_C32(0x53de9ee9), SPH_C32(0x7e1b28d1), + SPH_C32(0x6e995c2e), SPH_C32(0x818e9fb3), SPH_C32(0x43740000), + SPH_C32(0xf2480000), SPH_C32(0xbcc30000), SPH_C32(0xc78b00ad), + SPH_C32(0x85adf5b2), SPH_C32(0xff23940c), SPH_C32(0x04c3ea5b), + SPH_C32(0xd3db74a2) }, + { SPH_C32(0xd75c0000), SPH_C32(0x948f0000), SPH_C32(0x6a1c0000), + SPH_C32(0x405c01e6), SPH_C32(0x02f714b9), SPH_C32(0x15754ece), + SPH_C32(0x603c93cd), SPH_C32(0x6754e04d), SPH_C32(0xebae0000), + SPH_C32(0x64f60000), SPH_C32(0xe0de0000), SPH_C32(0xc05100af), + SPH_C32(0xf8cb6031), SPH_C32(0xe0bbe486), SPH_C32(0xbfa56253), + SPH_C32(0x095cf4a2) }, + { SPH_C32(0x7d280000), SPH_C32(0xed000000), SPH_C32(0x28c00000), + SPH_C32(0xb24801e8), SPH_C32(0xa3688632), SPH_C32(0xdd20ec75), + SPH_C32(0xd3c9b5c7), SPH_C32(0x086681c8), SPH_C32(0x7abb0000), + SPH_C32(0xb0c00000), SPH_C32(0x441e0000), SPH_C32(0xac4f00ab), + SPH_C32(0x130bc977), SPH_C32(0xd13a2195), SPH_C32(0x21ce5ae2), + SPH_C32(0x9490fe8b) }, + { SPH_C32(0x7e150000), SPH_C32(0xe5b30000), SPH_C32(0xdbfa0000), + SPH_C32(0x888a01ef), SPH_C32(0xf2410c62), SPH_C32(0xb64e8a6a), + SPH_C32(0xdd6c7a24), SPH_C32(0xeebcfe36), SPH_C32(0xd2610000), + SPH_C32(0x267e0000), SPH_C32(0x18030000), SPH_C32(0xab9500a9), + SPH_C32(0x6e6d5cf4), SPH_C32(0xcea2511f), SPH_C32(0x9aa8d2ea), + SPH_C32(0x4e177e8b) }, + { SPH_C32(0xd5f20000), SPH_C32(0x7bbe0000), SPH_C32(0x74dd0000), + SPH_C32(0xb59201ea), SPH_C32(0xde0e13b1), SPH_C32(0xc2b89cff), + SPH_C32(0x68af3dcf), SPH_C32(0xd2e101c8), SPH_C32(0xd15c0000), + SPH_C32(0x2ecd0000), SPH_C32(0xeb390000), SPH_C32(0x915700ae), + SPH_C32(0x3f44d6a4), SPH_C32(0xa5cc3700), SPH_C32(0x940d1d09), + SPH_C32(0xa8cd0175) }, + { SPH_C32(0xd6cf0000), SPH_C32(0x730d0000), SPH_C32(0x87e70000), + SPH_C32(0x8f5001ed), SPH_C32(0x8f2799e1), SPH_C32(0xa9d6fae0), + SPH_C32(0x660af22c), SPH_C32(0x343b7e36), SPH_C32(0x79860000), + SPH_C32(0xb8730000), SPH_C32(0xb7240000), SPH_C32(0x968d00ac), + SPH_C32(0x42224327), SPH_C32(0xba54478a), SPH_C32(0x2f6b9501), + SPH_C32(0x724a8175) }, + { SPH_C32(0xb13b0000), SPH_C32(0x80040000), SPH_C32(0xd16f0000), + SPH_C32(0x4f6b01f3), SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), + SPH_C32(0x112fb6cb), SPH_C32(0xaebbb10d), SPH_C32(0x7b6c0000), + SPH_C32(0x280a0000), SPH_C32(0x73990000), SPH_C32(0x496000a1), + SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), SPH_C32(0x24f2a563), + SPH_C32(0x79f5076e) }, + { SPH_C32(0xb2060000), SPH_C32(0x88b70000), SPH_C32(0x22550000), + SPH_C32(0x75a901f4), SPH_C32(0xe0062493), SPH_C32(0x43130906), + SPH_C32(0x1f8a7928), SPH_C32(0x4861cef3), SPH_C32(0xd3b60000), + SPH_C32(0xbeb40000), SPH_C32(0x2f840000), SPH_C32(0x4eba00a3), + SPH_C32(0xd8101860), SPH_C32(0xdbb779b6), SPH_C32(0x9f942d6b), + SPH_C32(0xa372876e) }, + { SPH_C32(0x19e10000), SPH_C32(0x16ba0000), SPH_C32(0x8d720000), + SPH_C32(0x48b101f1), SPH_C32(0xcc493b40), SPH_C32(0x37e51f93), + SPH_C32(0xaa493ec3), SPH_C32(0x743c310d), SPH_C32(0xd08b0000), + SPH_C32(0xb6070000), SPH_C32(0xdcbe0000), SPH_C32(0x747800a4), + SPH_C32(0x89399230), SPH_C32(0xb0d91fa9), SPH_C32(0x9131e288), + SPH_C32(0x45a8f890) }, + { SPH_C32(0x1adc0000), SPH_C32(0x1e090000), SPH_C32(0x7e480000), + SPH_C32(0x727301f6), SPH_C32(0x9d60b110), SPH_C32(0x5c8b798c), + SPH_C32(0xa4ecf120), SPH_C32(0x92e64ef3), SPH_C32(0x78510000), + SPH_C32(0x20b90000), SPH_C32(0x80a30000), SPH_C32(0x73a200a6), + SPH_C32(0xf45f07b3), SPH_C32(0xaf416f23), SPH_C32(0x2a576a80), + SPH_C32(0x9f2f7890) }, + { SPH_C32(0xb0a80000), SPH_C32(0x67860000), SPH_C32(0x3c940000), + SPH_C32(0x806701f8), SPH_C32(0x3cff239b), SPH_C32(0x94dedb37), + SPH_C32(0x1719d72a), SPH_C32(0xfdd42f76), SPH_C32(0xe9440000), + SPH_C32(0xf48f0000), SPH_C32(0x24630000), SPH_C32(0x1fbc00a2), + SPH_C32(0x1f9faef5), SPH_C32(0x9ec0aa30), SPH_C32(0xb43c5231), + SPH_C32(0x02e372b9) }, + { SPH_C32(0xb3950000), SPH_C32(0x6f350000), SPH_C32(0xcfae0000), + SPH_C32(0xbaa501ff), SPH_C32(0x6dd6a9cb), SPH_C32(0xffb0bd28), + SPH_C32(0x19bc18c9), SPH_C32(0x1b0e5088), SPH_C32(0x419e0000), + SPH_C32(0x62310000), SPH_C32(0x787e0000), SPH_C32(0x186600a0), + SPH_C32(0x62f93b76), SPH_C32(0x8158daba), SPH_C32(0x0f5ada39), + SPH_C32(0xd864f2b9) }, + { SPH_C32(0x18720000), SPH_C32(0xf1380000), SPH_C32(0x60890000), + SPH_C32(0x87bd01fa), SPH_C32(0x4199b618), SPH_C32(0x8b46abbd), + SPH_C32(0xac7f5f22), SPH_C32(0x2753af76), SPH_C32(0x42a30000), + SPH_C32(0x6a820000), SPH_C32(0x8b440000), SPH_C32(0x22a400a7), + SPH_C32(0x33d0b126), SPH_C32(0xea36bca5), SPH_C32(0x01ff15da), + SPH_C32(0x3ebe8d47) }, + { SPH_C32(0x1b4f0000), SPH_C32(0xf98b0000), SPH_C32(0x93b30000), + SPH_C32(0xbd7f01fd), SPH_C32(0x10b03c48), SPH_C32(0xe028cda2), + SPH_C32(0xa2da90c1), SPH_C32(0xc189d088), SPH_C32(0xea790000), + SPH_C32(0xfc3c0000), SPH_C32(0xd7590000), SPH_C32(0x257e00a5), + SPH_C32(0x4eb624a5), SPH_C32(0xf5aecc2f), SPH_C32(0xba999dd2), + SPH_C32(0xe4390d47) }, + { SPH_C32(0x23130000), SPH_C32(0x5c810000), SPH_C32(0x86950000), + SPH_C32(0x19b701f0), SPH_C32(0x0bc68dd5), SPH_C32(0x7292cc15), + SPH_C32(0x81e14199), SPH_C32(0xd5adc4da), SPH_C32(0xe8d70000), + SPH_C32(0x130d0000), SPH_C32(0xc9980000), SPH_C32(0xd0b000a9), + SPH_C32(0x924f23ad), SPH_C32(0x22631e1e), SPH_C32(0xb20a33d0), + SPH_C32(0x518cecc2) }, + { SPH_C32(0x202e0000), SPH_C32(0x54320000), SPH_C32(0x75af0000), + SPH_C32(0x237501f7), SPH_C32(0x5aef0785), SPH_C32(0x19fcaa0a), + SPH_C32(0x8f448e7a), SPH_C32(0x3377bb24), SPH_C32(0x400d0000), + SPH_C32(0x85b30000), SPH_C32(0x95850000), SPH_C32(0xd76a00ab), + SPH_C32(0xef29b62e), SPH_C32(0x3dfb6e94), SPH_C32(0x096cbbd8), + SPH_C32(0x8b0b6cc2) }, + { SPH_C32(0x8bc90000), SPH_C32(0xca3f0000), SPH_C32(0xda880000), + SPH_C32(0x1e6d01f2), SPH_C32(0x76a01856), SPH_C32(0x6d0abc9f), + SPH_C32(0x3a87c991), SPH_C32(0x0f2a44da), SPH_C32(0x43300000), + SPH_C32(0x8d000000), SPH_C32(0x66bf0000), SPH_C32(0xeda800ac), + SPH_C32(0xbe003c7e), SPH_C32(0x5695088b), SPH_C32(0x07c9743b), + SPH_C32(0x6dd1133c) }, + { SPH_C32(0x88f40000), SPH_C32(0xc28c0000), SPH_C32(0x29b20000), + SPH_C32(0x24af01f5), SPH_C32(0x27899206), SPH_C32(0x0664da80), + SPH_C32(0x34220672), SPH_C32(0xe9f03b24), SPH_C32(0xebea0000), + SPH_C32(0x1bbe0000), SPH_C32(0x3aa20000), SPH_C32(0xea7200ae), + SPH_C32(0xc366a9fd), SPH_C32(0x490d7801), SPH_C32(0xbcaffc33), + SPH_C32(0xb756933c) }, + { SPH_C32(0x22800000), SPH_C32(0xbb030000), SPH_C32(0x6b6e0000), + SPH_C32(0xd6bb01fb), SPH_C32(0x8616008d), SPH_C32(0xce31783b), + SPH_C32(0x87d72078), SPH_C32(0x86c25aa1), SPH_C32(0x7aff0000), + SPH_C32(0xcf880000), SPH_C32(0x9e620000), SPH_C32(0x866c00aa), + SPH_C32(0x28a600bb), SPH_C32(0x788cbd12), SPH_C32(0x22c4c482), + SPH_C32(0x2a9a9915) }, + { SPH_C32(0x21bd0000), SPH_C32(0xb3b00000), SPH_C32(0x98540000), + SPH_C32(0xec7901fc), SPH_C32(0xd73f8add), SPH_C32(0xa55f1e24), + SPH_C32(0x8972ef9b), SPH_C32(0x6018255f), SPH_C32(0xd2250000), + SPH_C32(0x59360000), SPH_C32(0xc27f0000), SPH_C32(0x81b600a8), + SPH_C32(0x55c09538), SPH_C32(0x6714cd98), SPH_C32(0x99a24c8a), + SPH_C32(0xf01d1915) }, + { SPH_C32(0x8a5a0000), SPH_C32(0x2dbd0000), SPH_C32(0x37730000), + SPH_C32(0xd16101f9), SPH_C32(0xfb70950e), SPH_C32(0xd1a908b1), + SPH_C32(0x3cb1a870), SPH_C32(0x5c45daa1), SPH_C32(0xd1180000), + SPH_C32(0x51850000), SPH_C32(0x31450000), SPH_C32(0xbb7400af), + SPH_C32(0x04e91f68), SPH_C32(0x0c7aab87), SPH_C32(0x97078369), + SPH_C32(0x16c766eb) }, + { SPH_C32(0x89670000), SPH_C32(0x250e0000), SPH_C32(0xc4490000), + SPH_C32(0xeba301fe), SPH_C32(0xaa591f5e), SPH_C32(0xbac76eae), + SPH_C32(0x32146793), SPH_C32(0xba9fa55f), SPH_C32(0x79c20000), + SPH_C32(0xc73b0000), SPH_C32(0x6d580000), SPH_C32(0xbcae00ad), + SPH_C32(0x798f8aeb), SPH_C32(0x13e2db0d), SPH_C32(0x2c610b61), + SPH_C32(0xcc40e6eb) }, + { SPH_C32(0xeed70000), SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), + SPH_C32(0x01bb01e1), SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), + SPH_C32(0x463bbd14), SPH_C32(0x9e150dfa), SPH_C32(0x24c40000), + SPH_C32(0x7e090000), SPH_C32(0x30370000), SPH_C32(0x2d9300b2), + SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), SPH_C32(0x70ec30dc), + SPH_C32(0xf751dc07) }, + { SPH_C32(0xedea0000), SPH_C32(0xa1fc0000), SPH_C32(0xbb870000), + SPH_C32(0x3b7901e6), SPH_C32(0xfed56be0), SPH_C32(0xf9b401cf), + SPH_C32(0x489e72f7), SPH_C32(0x78cf7204), SPH_C32(0x8c1e0000), + SPH_C32(0xe8b70000), SPH_C32(0x6c2a0000), SPH_C32(0x2a4900b0), + SPH_C32(0xfd6e9edf), SPH_C32(0xc8a6edf8), SPH_C32(0xcb8ab8d4), + SPH_C32(0x2dd65c07) }, + { SPH_C32(0x460d0000), SPH_C32(0x3ff10000), SPH_C32(0x14a00000), + SPH_C32(0x066101e3), SPH_C32(0xd29a7433), SPH_C32(0x8d42175a), + SPH_C32(0xfd5d351c), SPH_C32(0x44928dfa), SPH_C32(0x8f230000), + SPH_C32(0xe0040000), SPH_C32(0x9f100000), SPH_C32(0x108b00b7), + SPH_C32(0xac47148f), SPH_C32(0xa3c88be7), SPH_C32(0xc52f7737), + SPH_C32(0xcb0c23f9) }, + { SPH_C32(0x45300000), SPH_C32(0x37420000), SPH_C32(0xe79a0000), + SPH_C32(0x3ca301e4), SPH_C32(0x83b3fe63), SPH_C32(0xe62c7145), + SPH_C32(0xf3f8faff), SPH_C32(0xa248f204), SPH_C32(0x27f90000), + SPH_C32(0x76ba0000), SPH_C32(0xc30d0000), SPH_C32(0x175100b5), + SPH_C32(0xd121810c), SPH_C32(0xbc50fb6d), SPH_C32(0x7e49ff3f), + SPH_C32(0x118ba3f9) }, + { SPH_C32(0xef440000), SPH_C32(0x4ecd0000), SPH_C32(0xa5460000), + SPH_C32(0xceb701ea), SPH_C32(0x222c6ce8), SPH_C32(0x2e79d3fe), + SPH_C32(0x400ddcf5), SPH_C32(0xcd7a9381), SPH_C32(0xb6ec0000), + SPH_C32(0xa28c0000), SPH_C32(0x67cd0000), SPH_C32(0x7b4f00b1), + SPH_C32(0x3ae1284a), SPH_C32(0x8dd13e7e), SPH_C32(0xe022c78e), + SPH_C32(0x8c47a9d0) }, + { SPH_C32(0xec790000), SPH_C32(0x467e0000), SPH_C32(0x567c0000), + SPH_C32(0xf47501ed), SPH_C32(0x7305e6b8), SPH_C32(0x4517b5e1), + SPH_C32(0x4ea81316), SPH_C32(0x2ba0ec7f), SPH_C32(0x1e360000), + SPH_C32(0x34320000), SPH_C32(0x3bd00000), SPH_C32(0x7c9500b3), + SPH_C32(0x4787bdc9), SPH_C32(0x92494ef4), SPH_C32(0x5b444f86), + SPH_C32(0x56c029d0) }, + { SPH_C32(0x479e0000), SPH_C32(0xd8730000), SPH_C32(0xf95b0000), + SPH_C32(0xc96d01e8), SPH_C32(0x5f4af96b), SPH_C32(0x31e1a374), + SPH_C32(0xfb6b54fd), SPH_C32(0x17fd1381), SPH_C32(0x1d0b0000), + SPH_C32(0x3c810000), SPH_C32(0xc8ea0000), SPH_C32(0x465700b4), + SPH_C32(0x16ae3799), SPH_C32(0xf92728eb), SPH_C32(0x55e18065), + SPH_C32(0xb01a562e) }, + { SPH_C32(0x44a30000), SPH_C32(0xd0c00000), SPH_C32(0x0a610000), + SPH_C32(0xf3af01ef), SPH_C32(0x0e63733b), SPH_C32(0x5a8fc56b), + SPH_C32(0xf5ce9b1e), SPH_C32(0xf1276c7f), SPH_C32(0xb5d10000), + SPH_C32(0xaa3f0000), SPH_C32(0x94f70000), SPH_C32(0x418d00b6), + SPH_C32(0x6bc8a21a), SPH_C32(0xe6bf5861), SPH_C32(0xee87086d), + SPH_C32(0x6a9dd62e) }, + { SPH_C32(0x7cff0000), SPH_C32(0x75ca0000), SPH_C32(0x1f470000), + SPH_C32(0x576701e2), SPH_C32(0x1515c2a6), SPH_C32(0xc835c4dc), + SPH_C32(0xd6f54a46), SPH_C32(0xe503782d), SPH_C32(0xb77f0000), + SPH_C32(0x450e0000), SPH_C32(0x8a360000), SPH_C32(0xb44300ba), + SPH_C32(0xb731a512), SPH_C32(0x31728a50), SPH_C32(0xe614a66f), + SPH_C32(0xdf2837ab) }, + { SPH_C32(0x7fc20000), SPH_C32(0x7d790000), SPH_C32(0xec7d0000), + SPH_C32(0x6da501e5), SPH_C32(0x443c48f6), SPH_C32(0xa35ba2c3), + SPH_C32(0xd85085a5), SPH_C32(0x03d907d3), SPH_C32(0x1fa50000), + SPH_C32(0xd3b00000), SPH_C32(0xd62b0000), SPH_C32(0xb39900b8), + SPH_C32(0xca573091), SPH_C32(0x2eeafada), SPH_C32(0x5d722e67), + SPH_C32(0x05afb7ab) }, + { SPH_C32(0xd4250000), SPH_C32(0xe3740000), SPH_C32(0x435a0000), + SPH_C32(0x50bd01e0), SPH_C32(0x68735725), SPH_C32(0xd7adb456), + SPH_C32(0x6d93c24e), SPH_C32(0x3f84f82d), SPH_C32(0x1c980000), + SPH_C32(0xdb030000), SPH_C32(0x25110000), SPH_C32(0x895b00bf), + SPH_C32(0x9b7ebac1), SPH_C32(0x45849cc5), SPH_C32(0x53d7e184), + SPH_C32(0xe375c855) }, + { SPH_C32(0xd7180000), SPH_C32(0xebc70000), SPH_C32(0xb0600000), + SPH_C32(0x6a7f01e7), SPH_C32(0x395add75), SPH_C32(0xbcc3d249), + SPH_C32(0x63360dad), SPH_C32(0xd95e87d3), SPH_C32(0xb4420000), + SPH_C32(0x4dbd0000), SPH_C32(0x790c0000), SPH_C32(0x8e8100bd), + SPH_C32(0xe6182f42), SPH_C32(0x5a1cec4f), SPH_C32(0xe8b1698c), + SPH_C32(0x39f24855) }, + { SPH_C32(0x7d6c0000), SPH_C32(0x92480000), SPH_C32(0xf2bc0000), + SPH_C32(0x986b01e9), SPH_C32(0x98c54ffe), SPH_C32(0x749670f2), + SPH_C32(0xd0c32ba7), SPH_C32(0xb66ce656), SPH_C32(0x25570000), + SPH_C32(0x998b0000), SPH_C32(0xddcc0000), SPH_C32(0xe29f00b9), + SPH_C32(0x0dd88604), SPH_C32(0x6b9d295c), SPH_C32(0x76da513d), + SPH_C32(0xa43e427c) }, + { SPH_C32(0x7e510000), SPH_C32(0x9afb0000), SPH_C32(0x01860000), + SPH_C32(0xa2a901ee), SPH_C32(0xc9ecc5ae), SPH_C32(0x1ff816ed), + SPH_C32(0xde66e444), SPH_C32(0x50b699a8), SPH_C32(0x8d8d0000), + SPH_C32(0x0f350000), SPH_C32(0x81d10000), SPH_C32(0xe54500bb), + SPH_C32(0x70be1387), SPH_C32(0x740559d6), SPH_C32(0xcdbcd935), + SPH_C32(0x7eb9c27c) }, + { SPH_C32(0xd5b60000), SPH_C32(0x04f60000), SPH_C32(0xaea10000), + SPH_C32(0x9fb101eb), SPH_C32(0xe5a3da7d), SPH_C32(0x6b0e0078), + SPH_C32(0x6ba5a3af), SPH_C32(0x6ceb6656), SPH_C32(0x8eb00000), + SPH_C32(0x07860000), SPH_C32(0x72eb0000), SPH_C32(0xdf8700bc), + SPH_C32(0x219799d7), SPH_C32(0x1f6b3fc9), SPH_C32(0xc31916d6), + SPH_C32(0x9863bd82) }, + { SPH_C32(0xd68b0000), SPH_C32(0x0c450000), SPH_C32(0x5d9b0000), + SPH_C32(0xa57301ec), SPH_C32(0xb48a502d), SPH_C32(0x00606667), + SPH_C32(0x65006c4c), SPH_C32(0x8a3119a8), SPH_C32(0x266a0000), + SPH_C32(0x91380000), SPH_C32(0x2ef60000), SPH_C32(0xd85d00be), + SPH_C32(0x5cf10c54), SPH_C32(0x00f34f43), SPH_C32(0x787f9ede), + SPH_C32(0x42e43d82) }, + { SPH_C32(0xb17f0000), SPH_C32(0xff4c0000), SPH_C32(0x0b130000), + SPH_C32(0x654801f2), SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), + SPH_C32(0x122528ab), SPH_C32(0x10b1d693), SPH_C32(0x24800000), + SPH_C32(0x01410000), SPH_C32(0xea4b0000), SPH_C32(0x07b000b3), + SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), SPH_C32(0x73e6aebc), + SPH_C32(0x495bbb99) }, + { SPH_C32(0xb2420000), SPH_C32(0xf7ff0000), SPH_C32(0xf8290000), + SPH_C32(0x5f8a01f5), SPH_C32(0xdbabed5f), SPH_C32(0xeaa59581), + SPH_C32(0x1c80e748), SPH_C32(0xf66ba96d), SPH_C32(0x8c5a0000), + SPH_C32(0x97ff0000), SPH_C32(0xb6560000), SPH_C32(0x006a00b1), + SPH_C32(0xc6c35713), SPH_C32(0x6110717f), SPH_C32(0xc88026b4), + SPH_C32(0x93dc3b99) }, + { SPH_C32(0x19a50000), SPH_C32(0x69f20000), SPH_C32(0x570e0000), + SPH_C32(0x629201f0), SPH_C32(0xf7e4f28c), SPH_C32(0x9e538314), + SPH_C32(0xa943a0a3), SPH_C32(0xca365693), SPH_C32(0x8f670000), + SPH_C32(0x9f4c0000), SPH_C32(0x456c0000), SPH_C32(0x3aa800b6), + SPH_C32(0x97eadd43), SPH_C32(0x0a7e1760), SPH_C32(0xc625e957), + SPH_C32(0x75064467) }, + { SPH_C32(0x1a980000), SPH_C32(0x61410000), SPH_C32(0xa4340000), + SPH_C32(0x585001f7), SPH_C32(0xa6cd78dc), SPH_C32(0xf53de50b), + SPH_C32(0xa7e66f40), SPH_C32(0x2cec296d), SPH_C32(0x27bd0000), + SPH_C32(0x09f20000), SPH_C32(0x19710000), SPH_C32(0x3d7200b4), + SPH_C32(0xea8c48c0), SPH_C32(0x15e667ea), SPH_C32(0x7d43615f), + SPH_C32(0xaf81c467) }, + { SPH_C32(0xb0ec0000), SPH_C32(0x18ce0000), SPH_C32(0xe6e80000), + SPH_C32(0xaa4401f9), SPH_C32(0x0752ea57), SPH_C32(0x3d6847b0), + SPH_C32(0x1413494a), SPH_C32(0x43de48e8), SPH_C32(0xb6a80000), + SPH_C32(0xddc40000), SPH_C32(0xbdb10000), SPH_C32(0x516c00b0), + SPH_C32(0x014ce186), SPH_C32(0x2467a2f9), SPH_C32(0xe32859ee), + SPH_C32(0x324dce4e) }, + { SPH_C32(0xb3d10000), SPH_C32(0x107d0000), SPH_C32(0x15d20000), + SPH_C32(0x908601fe), SPH_C32(0x567b6007), SPH_C32(0x560621af), + SPH_C32(0x1ab686a9), SPH_C32(0xa5043716), SPH_C32(0x1e720000), + SPH_C32(0x4b7a0000), SPH_C32(0xe1ac0000), SPH_C32(0x56b600b2), + SPH_C32(0x7c2a7405), SPH_C32(0x3bffd273), SPH_C32(0x584ed1e6), + SPH_C32(0xe8ca4e4e) }, + { SPH_C32(0x18360000), SPH_C32(0x8e700000), SPH_C32(0xbaf50000), + SPH_C32(0xad9e01fb), SPH_C32(0x7a347fd4), SPH_C32(0x22f0373a), + SPH_C32(0xaf75c142), SPH_C32(0x9959c8e8), SPH_C32(0x1d4f0000), + SPH_C32(0x43c90000), SPH_C32(0x12960000), SPH_C32(0x6c7400b5), + SPH_C32(0x2d03fe55), SPH_C32(0x5091b46c), SPH_C32(0x56eb1e05), + SPH_C32(0x0e1031b0) }, + { SPH_C32(0x1b0b0000), SPH_C32(0x86c30000), SPH_C32(0x49cf0000), + SPH_C32(0x975c01fc), SPH_C32(0x2b1df584), SPH_C32(0x499e5125), + SPH_C32(0xa1d00ea1), SPH_C32(0x7f83b716), SPH_C32(0xb5950000), + SPH_C32(0xd5770000), SPH_C32(0x4e8b0000), SPH_C32(0x6bae00b7), + SPH_C32(0x50656bd6), SPH_C32(0x4f09c4e6), SPH_C32(0xed8d960d), + SPH_C32(0xd497b1b0) }, + { SPH_C32(0x23570000), SPH_C32(0x23c90000), SPH_C32(0x5ce90000), + SPH_C32(0x339401f1), SPH_C32(0x306b4419), SPH_C32(0xdb245092), + SPH_C32(0x82ebdff9), SPH_C32(0x6ba7a344), SPH_C32(0xb73b0000), + SPH_C32(0x3a460000), SPH_C32(0x504a0000), SPH_C32(0x9e6000bb), + SPH_C32(0x8c9c6cde), SPH_C32(0x98c416d7), SPH_C32(0xe51e380f), + SPH_C32(0x61225035) }, + { SPH_C32(0x206a0000), SPH_C32(0x2b7a0000), SPH_C32(0xafd30000), + SPH_C32(0x095601f6), SPH_C32(0x6142ce49), SPH_C32(0xb04a368d), + SPH_C32(0x8c4e101a), SPH_C32(0x8d7ddcba), SPH_C32(0x1fe10000), + SPH_C32(0xacf80000), SPH_C32(0x0c570000), SPH_C32(0x99ba00b9), + SPH_C32(0xf1faf95d), SPH_C32(0x875c665d), SPH_C32(0x5e78b007), + SPH_C32(0xbba5d035) }, + { SPH_C32(0x8b8d0000), SPH_C32(0xb5770000), SPH_C32(0x00f40000), + SPH_C32(0x344e01f3), SPH_C32(0x4d0dd19a), SPH_C32(0xc4bc2018), + SPH_C32(0x398d57f1), SPH_C32(0xb1202344), SPH_C32(0x1cdc0000), + SPH_C32(0xa44b0000), SPH_C32(0xff6d0000), SPH_C32(0xa37800be), + SPH_C32(0xa0d3730d), SPH_C32(0xec320042), SPH_C32(0x50dd7fe4), + SPH_C32(0x5d7fafcb) }, + { SPH_C32(0x88b00000), SPH_C32(0xbdc40000), SPH_C32(0xf3ce0000), + SPH_C32(0x0e8c01f4), SPH_C32(0x1c245bca), SPH_C32(0xafd24607), + SPH_C32(0x37289812), SPH_C32(0x57fa5cba), SPH_C32(0xb4060000), + SPH_C32(0x32f50000), SPH_C32(0xa3700000), SPH_C32(0xa4a200bc), + SPH_C32(0xddb5e68e), SPH_C32(0xf3aa70c8), SPH_C32(0xebbbf7ec), + SPH_C32(0x87f82fcb) }, + { SPH_C32(0x22c40000), SPH_C32(0xc44b0000), SPH_C32(0xb1120000), + SPH_C32(0xfc9801fa), SPH_C32(0xbdbbc941), SPH_C32(0x6787e4bc), + SPH_C32(0x84ddbe18), SPH_C32(0x38c83d3f), SPH_C32(0x25130000), + SPH_C32(0xe6c30000), SPH_C32(0x07b00000), SPH_C32(0xc8bc00b8), + SPH_C32(0x36754fc8), SPH_C32(0xc22bb5db), SPH_C32(0x75d0cf5d), + SPH_C32(0x1a3425e2) }, + { SPH_C32(0x21f90000), SPH_C32(0xccf80000), SPH_C32(0x42280000), + SPH_C32(0xc65a01fd), SPH_C32(0xec924311), SPH_C32(0x0ce982a3), + SPH_C32(0x8a7871fb), SPH_C32(0xde1242c1), SPH_C32(0x8dc90000), + SPH_C32(0x707d0000), SPH_C32(0x5bad0000), SPH_C32(0xcf6600ba), + SPH_C32(0x4b13da4b), SPH_C32(0xddb3c551), SPH_C32(0xceb64755), + SPH_C32(0xc0b3a5e2) }, + { SPH_C32(0x8a1e0000), SPH_C32(0x52f50000), SPH_C32(0xed0f0000), + SPH_C32(0xfb4201f8), SPH_C32(0xc0dd5cc2), SPH_C32(0x781f9436), + SPH_C32(0x3fbb3610), SPH_C32(0xe24fbd3f), SPH_C32(0x8ef40000), + SPH_C32(0x78ce0000), SPH_C32(0xa8970000), SPH_C32(0xf5a400bd), + SPH_C32(0x1a3a501b), SPH_C32(0xb6dda34e), SPH_C32(0xc01388b6), + SPH_C32(0x2669da1c) }, + { SPH_C32(0x89230000), SPH_C32(0x5a460000), SPH_C32(0x1e350000), + SPH_C32(0xc18001ff), SPH_C32(0x91f4d692), SPH_C32(0x1371f229), + SPH_C32(0x311ef9f3), SPH_C32(0x0495c2c1), SPH_C32(0x262e0000), + SPH_C32(0xee700000), SPH_C32(0xf48a0000), SPH_C32(0xf27e00bf), + SPH_C32(0x675cc598), SPH_C32(0xa945d3c4), SPH_C32(0x7b7500be), + SPH_C32(0xfcee5a1c) }, + { SPH_C32(0x7b280000), SPH_C32(0x57420000), SPH_C32(0xa9e50000), + SPH_C32(0x634300a0), SPH_C32(0x9edb442f), SPH_C32(0x6d9995bb), + SPH_C32(0x27f83b03), SPH_C32(0xc7ff60f0), SPH_C32(0x95bb0000), + SPH_C32(0x81450000), SPH_C32(0x3b240000), SPH_C32(0x48db0140), + SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), SPH_C32(0x62c91877), + SPH_C32(0xe7e00a94) }, + { SPH_C32(0x78150000), SPH_C32(0x5ff10000), SPH_C32(0x5adf0000), + SPH_C32(0x598100a7), SPH_C32(0xcff2ce7f), SPH_C32(0x06f7f3a4), + SPH_C32(0x295df4e0), SPH_C32(0x21251f0e), SPH_C32(0x3d610000), + SPH_C32(0x17fb0000), SPH_C32(0x67390000), SPH_C32(0x4f010142), + SPH_C32(0x77ecf9d0), SPH_C32(0x496d1e66), SPH_C32(0xd9af907f), + SPH_C32(0x3d678a94) }, + { SPH_C32(0xd3f20000), SPH_C32(0xc1fc0000), SPH_C32(0xf5f80000), + SPH_C32(0x649900a2), SPH_C32(0xe3bdd1ac), SPH_C32(0x7201e531), + SPH_C32(0x9c9eb30b), SPH_C32(0x1d78e0f0), SPH_C32(0x3e5c0000), + SPH_C32(0x1f480000), SPH_C32(0x94030000), SPH_C32(0x75c30145), + SPH_C32(0x26c57380), SPH_C32(0x22037879), SPH_C32(0xd70a5f9c), + SPH_C32(0xdbbdf56a) }, + { SPH_C32(0xd0cf0000), SPH_C32(0xc94f0000), SPH_C32(0x06c20000), + SPH_C32(0x5e5b00a5), SPH_C32(0xb2945bfc), SPH_C32(0x196f832e), + SPH_C32(0x923b7ce8), SPH_C32(0xfba29f0e), SPH_C32(0x96860000), + SPH_C32(0x89f60000), SPH_C32(0xc81e0000), SPH_C32(0x72190147), + SPH_C32(0x5ba3e603), SPH_C32(0x3d9b08f3), SPH_C32(0x6c6cd794), + SPH_C32(0x013a756a) }, + { SPH_C32(0x7abb0000), SPH_C32(0xb0c00000), SPH_C32(0x441e0000), + SPH_C32(0xac4f00ab), SPH_C32(0x130bc977), SPH_C32(0xd13a2195), + SPH_C32(0x21ce5ae2), SPH_C32(0x9490fe8b), SPH_C32(0x07930000), + SPH_C32(0x5dc00000), SPH_C32(0x6cde0000), SPH_C32(0x1e070143), + SPH_C32(0xb0634f45), SPH_C32(0x0c1acde0), SPH_C32(0xf207ef25), + SPH_C32(0x9cf67f43) }, + { SPH_C32(0x79860000), SPH_C32(0xb8730000), SPH_C32(0xb7240000), + SPH_C32(0x968d00ac), SPH_C32(0x42224327), SPH_C32(0xba54478a), + SPH_C32(0x2f6b9501), SPH_C32(0x724a8175), SPH_C32(0xaf490000), + SPH_C32(0xcb7e0000), SPH_C32(0x30c30000), SPH_C32(0x19dd0141), + SPH_C32(0xcd05dac6), SPH_C32(0x1382bd6a), SPH_C32(0x4961672d), + SPH_C32(0x4671ff43) }, + { SPH_C32(0xd2610000), SPH_C32(0x267e0000), SPH_C32(0x18030000), + SPH_C32(0xab9500a9), SPH_C32(0x6e6d5cf4), SPH_C32(0xcea2511f), + SPH_C32(0x9aa8d2ea), SPH_C32(0x4e177e8b), SPH_C32(0xac740000), + SPH_C32(0xc3cd0000), SPH_C32(0xc3f90000), SPH_C32(0x231f0146), + SPH_C32(0x9c2c5096), SPH_C32(0x78ecdb75), SPH_C32(0x47c4a8ce), + SPH_C32(0xa0ab80bd) }, + { SPH_C32(0xd15c0000), SPH_C32(0x2ecd0000), SPH_C32(0xeb390000), + SPH_C32(0x915700ae), SPH_C32(0x3f44d6a4), SPH_C32(0xa5cc3700), + SPH_C32(0x940d1d09), SPH_C32(0xa8cd0175), SPH_C32(0x04ae0000), + SPH_C32(0x55730000), SPH_C32(0x9fe40000), SPH_C32(0x24c50144), + SPH_C32(0xe14ac515), SPH_C32(0x6774abff), SPH_C32(0xfca220c6), + SPH_C32(0x7a2c00bd) }, + { SPH_C32(0xe9000000), SPH_C32(0x8bc70000), SPH_C32(0xfe1f0000), + SPH_C32(0x359f00a3), SPH_C32(0x24326739), SPH_C32(0x377636b7), + SPH_C32(0xb736cc51), SPH_C32(0xbce91527), SPH_C32(0x06000000), + SPH_C32(0xba420000), SPH_C32(0x81250000), SPH_C32(0xd10b0148), + SPH_C32(0x3db3c21d), SPH_C32(0xb0b979ce), SPH_C32(0xf4318ec4), + SPH_C32(0xcf99e138) }, + { SPH_C32(0xea3d0000), SPH_C32(0x83740000), SPH_C32(0x0d250000), + SPH_C32(0x0f5d00a4), SPH_C32(0x751bed69), SPH_C32(0x5c1850a8), + SPH_C32(0xb99303b2), SPH_C32(0x5a336ad9), SPH_C32(0xaeda0000), + SPH_C32(0x2cfc0000), SPH_C32(0xdd380000), SPH_C32(0xd6d1014a), + SPH_C32(0x40d5579e), SPH_C32(0xaf210944), SPH_C32(0x4f5706cc), + SPH_C32(0x151e6138) }, + { SPH_C32(0x41da0000), SPH_C32(0x1d790000), SPH_C32(0xa2020000), + SPH_C32(0x324500a1), SPH_C32(0x5954f2ba), SPH_C32(0x28ee463d), + SPH_C32(0x0c504459), SPH_C32(0x666e9527), SPH_C32(0xade70000), + SPH_C32(0x244f0000), SPH_C32(0x2e020000), SPH_C32(0xec13014d), + SPH_C32(0x11fcddce), SPH_C32(0xc44f6f5b), SPH_C32(0x41f2c92f), + SPH_C32(0xf3c41ec6) }, + { SPH_C32(0x42e70000), SPH_C32(0x15ca0000), SPH_C32(0x51380000), + SPH_C32(0x088700a6), SPH_C32(0x087d78ea), SPH_C32(0x43802022), + SPH_C32(0x02f58bba), SPH_C32(0x80b4ead9), SPH_C32(0x053d0000), + SPH_C32(0xb2f10000), SPH_C32(0x721f0000), SPH_C32(0xebc9014f), + SPH_C32(0x6c9a484d), SPH_C32(0xdbd71fd1), SPH_C32(0xfa944127), + SPH_C32(0x29439ec6) }, + { SPH_C32(0xe8930000), SPH_C32(0x6c450000), SPH_C32(0x13e40000), + SPH_C32(0xfa9300a8), SPH_C32(0xa9e2ea61), SPH_C32(0x8bd58299), + SPH_C32(0xb100adb0), SPH_C32(0xef868b5c), SPH_C32(0x94280000), + SPH_C32(0x66c70000), SPH_C32(0xd6df0000), SPH_C32(0x87d7014b), + SPH_C32(0x875ae10b), SPH_C32(0xea56dac2), SPH_C32(0x64ff7996), + SPH_C32(0xb48f94ef) }, + { SPH_C32(0xebae0000), SPH_C32(0x64f60000), SPH_C32(0xe0de0000), + SPH_C32(0xc05100af), SPH_C32(0xf8cb6031), SPH_C32(0xe0bbe486), + SPH_C32(0xbfa56253), SPH_C32(0x095cf4a2), SPH_C32(0x3cf20000), + SPH_C32(0xf0790000), SPH_C32(0x8ac20000), SPH_C32(0x800d0149), + SPH_C32(0xfa3c7488), SPH_C32(0xf5ceaa48), SPH_C32(0xdf99f19e), + SPH_C32(0x6e0814ef) }, + { SPH_C32(0x40490000), SPH_C32(0xfafb0000), SPH_C32(0x4ff90000), + SPH_C32(0xfd4900aa), SPH_C32(0xd4847fe2), SPH_C32(0x944df213), + SPH_C32(0x0a6625b8), SPH_C32(0x35010b5c), SPH_C32(0x3fcf0000), + SPH_C32(0xf8ca0000), SPH_C32(0x79f80000), SPH_C32(0xbacf014e), + SPH_C32(0xab15fed8), SPH_C32(0x9ea0cc57), SPH_C32(0xd13c3e7d), + SPH_C32(0x88d26b11) }, + { SPH_C32(0x43740000), SPH_C32(0xf2480000), SPH_C32(0xbcc30000), + SPH_C32(0xc78b00ad), SPH_C32(0x85adf5b2), SPH_C32(0xff23940c), + SPH_C32(0x04c3ea5b), SPH_C32(0xd3db74a2), SPH_C32(0x97150000), + SPH_C32(0x6e740000), SPH_C32(0x25e50000), SPH_C32(0xbd15014c), + SPH_C32(0xd6736b5b), SPH_C32(0x8138bcdd), SPH_C32(0x6a5ab675), + SPH_C32(0x5255eb11) }, + { SPH_C32(0x24800000), SPH_C32(0x01410000), SPH_C32(0xea4b0000), + SPH_C32(0x07b000b3), SPH_C32(0xbba5c290), SPH_C32(0x7e8801f5), + SPH_C32(0x73e6aebc), SPH_C32(0x495bbb99), SPH_C32(0x95ff0000), + SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), SPH_C32(0x62f80141), + SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), SPH_C32(0x61c38617), + SPH_C32(0x59ea6d0a) }, + { SPH_C32(0x27bd0000), SPH_C32(0x09f20000), SPH_C32(0x19710000), + SPH_C32(0x3d7200b4), SPH_C32(0xea8c48c0), SPH_C32(0x15e667ea), + SPH_C32(0x7d43615f), SPH_C32(0xaf81c467), SPH_C32(0x3d250000), + SPH_C32(0x68b30000), SPH_C32(0xbd450000), SPH_C32(0x65220143), + SPH_C32(0x4c41301c), SPH_C32(0xe0db82e1), SPH_C32(0xdaa50e1f), + SPH_C32(0x836ded0a) }, + { SPH_C32(0x8c5a0000), SPH_C32(0x97ff0000), SPH_C32(0xb6560000), + SPH_C32(0x006a00b1), SPH_C32(0xc6c35713), SPH_C32(0x6110717f), + SPH_C32(0xc88026b4), SPH_C32(0x93dc3b99), SPH_C32(0x3e180000), + SPH_C32(0x60000000), SPH_C32(0x4e7f0000), SPH_C32(0x5fe00144), + SPH_C32(0x1d68ba4c), SPH_C32(0x8bb5e4fe), SPH_C32(0xd400c1fc), + SPH_C32(0x65b792f4) }, + { SPH_C32(0x8f670000), SPH_C32(0x9f4c0000), SPH_C32(0x456c0000), + SPH_C32(0x3aa800b6), SPH_C32(0x97eadd43), SPH_C32(0x0a7e1760), + SPH_C32(0xc625e957), SPH_C32(0x75064467), SPH_C32(0x96c20000), + SPH_C32(0xf6be0000), SPH_C32(0x12620000), SPH_C32(0x583a0146), + SPH_C32(0x600e2fcf), SPH_C32(0x942d9474), SPH_C32(0x6f6649f4), + SPH_C32(0xbf3012f4) }, + { SPH_C32(0x25130000), SPH_C32(0xe6c30000), SPH_C32(0x07b00000), + SPH_C32(0xc8bc00b8), SPH_C32(0x36754fc8), SPH_C32(0xc22bb5db), + SPH_C32(0x75d0cf5d), SPH_C32(0x1a3425e2), SPH_C32(0x07d70000), + SPH_C32(0x22880000), SPH_C32(0xb6a20000), SPH_C32(0x34240142), + SPH_C32(0x8bce8689), SPH_C32(0xa5ac5167), SPH_C32(0xf10d7145), + SPH_C32(0x22fc18dd) }, + { SPH_C32(0x262e0000), SPH_C32(0xee700000), SPH_C32(0xf48a0000), + SPH_C32(0xf27e00bf), SPH_C32(0x675cc598), SPH_C32(0xa945d3c4), + SPH_C32(0x7b7500be), SPH_C32(0xfcee5a1c), SPH_C32(0xaf0d0000), + SPH_C32(0xb4360000), SPH_C32(0xeabf0000), SPH_C32(0x33fe0140), + SPH_C32(0xf6a8130a), SPH_C32(0xba3421ed), SPH_C32(0x4a6bf94d), + SPH_C32(0xf87b98dd) }, + { SPH_C32(0x8dc90000), SPH_C32(0x707d0000), SPH_C32(0x5bad0000), + SPH_C32(0xcf6600ba), SPH_C32(0x4b13da4b), SPH_C32(0xddb3c551), + SPH_C32(0xceb64755), SPH_C32(0xc0b3a5e2), SPH_C32(0xac300000), + SPH_C32(0xbc850000), SPH_C32(0x19850000), SPH_C32(0x093c0147), + SPH_C32(0xa781995a), SPH_C32(0xd15a47f2), SPH_C32(0x44ce36ae), + SPH_C32(0x1ea1e723) }, + { SPH_C32(0x8ef40000), SPH_C32(0x78ce0000), SPH_C32(0xa8970000), + SPH_C32(0xf5a400bd), SPH_C32(0x1a3a501b), SPH_C32(0xb6dda34e), + SPH_C32(0xc01388b6), SPH_C32(0x2669da1c), SPH_C32(0x04ea0000), + SPH_C32(0x2a3b0000), SPH_C32(0x45980000), SPH_C32(0x0ee60145), + SPH_C32(0xdae70cd9), SPH_C32(0xcec23778), SPH_C32(0xffa8bea6), + SPH_C32(0xc4266723) }, + { SPH_C32(0xb6a80000), SPH_C32(0xddc40000), SPH_C32(0xbdb10000), + SPH_C32(0x516c00b0), SPH_C32(0x014ce186), SPH_C32(0x2467a2f9), + SPH_C32(0xe32859ee), SPH_C32(0x324dce4e), SPH_C32(0x06440000), + SPH_C32(0xc50a0000), SPH_C32(0x5b590000), SPH_C32(0xfb280149), + SPH_C32(0x061e0bd1), SPH_C32(0x190fe549), SPH_C32(0xf73b10a4), + SPH_C32(0x719386a6) }, + { SPH_C32(0xb5950000), SPH_C32(0xd5770000), SPH_C32(0x4e8b0000), + SPH_C32(0x6bae00b7), SPH_C32(0x50656bd6), SPH_C32(0x4f09c4e6), + SPH_C32(0xed8d960d), SPH_C32(0xd497b1b0), SPH_C32(0xae9e0000), + SPH_C32(0x53b40000), SPH_C32(0x07440000), SPH_C32(0xfcf2014b), + SPH_C32(0x7b789e52), SPH_C32(0x069795c3), SPH_C32(0x4c5d98ac), + SPH_C32(0xab1406a6) }, + { SPH_C32(0x1e720000), SPH_C32(0x4b7a0000), SPH_C32(0xe1ac0000), + SPH_C32(0x56b600b2), SPH_C32(0x7c2a7405), SPH_C32(0x3bffd273), + SPH_C32(0x584ed1e6), SPH_C32(0xe8ca4e4e), SPH_C32(0xada30000), + SPH_C32(0x5b070000), SPH_C32(0xf47e0000), SPH_C32(0xc630014c), + SPH_C32(0x2a511402), SPH_C32(0x6df9f3dc), SPH_C32(0x42f8574f), + SPH_C32(0x4dce7958) }, + { SPH_C32(0x1d4f0000), SPH_C32(0x43c90000), SPH_C32(0x12960000), + SPH_C32(0x6c7400b5), SPH_C32(0x2d03fe55), SPH_C32(0x5091b46c), + SPH_C32(0x56eb1e05), SPH_C32(0x0e1031b0), SPH_C32(0x05790000), + SPH_C32(0xcdb90000), SPH_C32(0xa8630000), SPH_C32(0xc1ea014e), + SPH_C32(0x57378181), SPH_C32(0x72618356), SPH_C32(0xf99edf47), + SPH_C32(0x9749f958) }, + { SPH_C32(0xb73b0000), SPH_C32(0x3a460000), SPH_C32(0x504a0000), + SPH_C32(0x9e6000bb), SPH_C32(0x8c9c6cde), SPH_C32(0x98c416d7), + SPH_C32(0xe51e380f), SPH_C32(0x61225035), SPH_C32(0x946c0000), + SPH_C32(0x198f0000), SPH_C32(0x0ca30000), SPH_C32(0xadf4014a), + SPH_C32(0xbcf728c7), SPH_C32(0x43e04645), SPH_C32(0x67f5e7f6), + SPH_C32(0x0a85f371) }, + { SPH_C32(0xb4060000), SPH_C32(0x32f50000), SPH_C32(0xa3700000), + SPH_C32(0xa4a200bc), SPH_C32(0xddb5e68e), SPH_C32(0xf3aa70c8), + SPH_C32(0xebbbf7ec), SPH_C32(0x87f82fcb), SPH_C32(0x3cb60000), + SPH_C32(0x8f310000), SPH_C32(0x50be0000), SPH_C32(0xaa2e0148), + SPH_C32(0xc191bd44), SPH_C32(0x5c7836cf), SPH_C32(0xdc936ffe), + SPH_C32(0xd0027371) }, + { SPH_C32(0x1fe10000), SPH_C32(0xacf80000), SPH_C32(0x0c570000), + SPH_C32(0x99ba00b9), SPH_C32(0xf1faf95d), SPH_C32(0x875c665d), + SPH_C32(0x5e78b007), SPH_C32(0xbba5d035), SPH_C32(0x3f8b0000), + SPH_C32(0x87820000), SPH_C32(0xa3840000), SPH_C32(0x90ec014f), + SPH_C32(0x90b83714), SPH_C32(0x371650d0), SPH_C32(0xd236a01d), + SPH_C32(0x36d80c8f) }, + { SPH_C32(0x1cdc0000), SPH_C32(0xa44b0000), SPH_C32(0xff6d0000), + SPH_C32(0xa37800be), SPH_C32(0xa0d3730d), SPH_C32(0xec320042), + SPH_C32(0x50dd7fe4), SPH_C32(0x5d7fafcb), SPH_C32(0x97510000), + SPH_C32(0x113c0000), SPH_C32(0xff990000), SPH_C32(0x9736014d), + SPH_C32(0xeddea297), SPH_C32(0x288e205a), SPH_C32(0x69502815), + SPH_C32(0xec5f8c8f) }, + { SPH_C32(0x7b6c0000), SPH_C32(0x280a0000), SPH_C32(0x73990000), + SPH_C32(0x496000a1), SPH_C32(0xa5768de3), SPH_C32(0xc42f093c), + SPH_C32(0x24f2a563), SPH_C32(0x79f5076e), SPH_C32(0xca570000), + SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), SPH_C32(0x060b0152), + SPH_C32(0x14592320), SPH_C32(0xec526625), SPH_C32(0x35dd13a8), + SPH_C32(0xd74eb663) }, + { SPH_C32(0x78510000), SPH_C32(0x20b90000), SPH_C32(0x80a30000), + SPH_C32(0x73a200a6), SPH_C32(0xf45f07b3), SPH_C32(0xaf416f23), + SPH_C32(0x2a576a80), SPH_C32(0x9f2f7890), SPH_C32(0x628d0000), + SPH_C32(0x3eb00000), SPH_C32(0xfeeb0000), SPH_C32(0x01d10150), + SPH_C32(0x693fb6a3), SPH_C32(0xf3ca16af), SPH_C32(0x8ebb9ba0), + SPH_C32(0x0dc93663) }, + { SPH_C32(0xd3b60000), SPH_C32(0xbeb40000), SPH_C32(0x2f840000), + SPH_C32(0x4eba00a3), SPH_C32(0xd8101860), SPH_C32(0xdbb779b6), + SPH_C32(0x9f942d6b), SPH_C32(0xa372876e), SPH_C32(0x61b00000), + SPH_C32(0x36030000), SPH_C32(0x0dd10000), SPH_C32(0x3b130157), + SPH_C32(0x38163cf3), SPH_C32(0x98a470b0), SPH_C32(0x801e5443), + SPH_C32(0xeb13499d) }, + { SPH_C32(0xd08b0000), SPH_C32(0xb6070000), SPH_C32(0xdcbe0000), + SPH_C32(0x747800a4), SPH_C32(0x89399230), SPH_C32(0xb0d91fa9), + SPH_C32(0x9131e288), SPH_C32(0x45a8f890), SPH_C32(0xc96a0000), + SPH_C32(0xa0bd0000), SPH_C32(0x51cc0000), SPH_C32(0x3cc90155), + SPH_C32(0x4570a970), SPH_C32(0x873c003a), SPH_C32(0x3b78dc4b), + SPH_C32(0x3194c99d) }, + { SPH_C32(0x7aff0000), SPH_C32(0xcf880000), SPH_C32(0x9e620000), + SPH_C32(0x866c00aa), SPH_C32(0x28a600bb), SPH_C32(0x788cbd12), + SPH_C32(0x22c4c482), SPH_C32(0x2a9a9915), SPH_C32(0x587f0000), + SPH_C32(0x748b0000), SPH_C32(0xf50c0000), SPH_C32(0x50d70151), + SPH_C32(0xaeb00036), SPH_C32(0xb6bdc529), SPH_C32(0xa513e4fa), + SPH_C32(0xac58c3b4) }, + { SPH_C32(0x79c20000), SPH_C32(0xc73b0000), SPH_C32(0x6d580000), + SPH_C32(0xbcae00ad), SPH_C32(0x798f8aeb), SPH_C32(0x13e2db0d), + SPH_C32(0x2c610b61), SPH_C32(0xcc40e6eb), SPH_C32(0xf0a50000), + SPH_C32(0xe2350000), SPH_C32(0xa9110000), SPH_C32(0x570d0153), + SPH_C32(0xd3d695b5), SPH_C32(0xa925b5a3), SPH_C32(0x1e756cf2), + SPH_C32(0x76df43b4) }, + { SPH_C32(0xd2250000), SPH_C32(0x59360000), SPH_C32(0xc27f0000), + SPH_C32(0x81b600a8), SPH_C32(0x55c09538), SPH_C32(0x6714cd98), + SPH_C32(0x99a24c8a), SPH_C32(0xf01d1915), SPH_C32(0xf3980000), + SPH_C32(0xea860000), SPH_C32(0x5a2b0000), SPH_C32(0x6dcf0154), + SPH_C32(0x82ff1fe5), SPH_C32(0xc24bd3bc), SPH_C32(0x10d0a311), + SPH_C32(0x90053c4a) }, + { SPH_C32(0xd1180000), SPH_C32(0x51850000), SPH_C32(0x31450000), + SPH_C32(0xbb7400af), SPH_C32(0x04e91f68), SPH_C32(0x0c7aab87), + SPH_C32(0x97078369), SPH_C32(0x16c766eb), SPH_C32(0x5b420000), + SPH_C32(0x7c380000), SPH_C32(0x06360000), SPH_C32(0x6a150156), + SPH_C32(0xff998a66), SPH_C32(0xddd3a336), SPH_C32(0xabb62b19), + SPH_C32(0x4a82bc4a) }, + { SPH_C32(0xe9440000), SPH_C32(0xf48f0000), SPH_C32(0x24630000), + SPH_C32(0x1fbc00a2), SPH_C32(0x1f9faef5), SPH_C32(0x9ec0aa30), + SPH_C32(0xb43c5231), SPH_C32(0x02e372b9), SPH_C32(0x59ec0000), + SPH_C32(0x93090000), SPH_C32(0x18f70000), SPH_C32(0x9fdb015a), + SPH_C32(0x23608d6e), SPH_C32(0x0a1e7107), SPH_C32(0xa325851b), + SPH_C32(0xff375dcf) }, + { SPH_C32(0xea790000), SPH_C32(0xfc3c0000), SPH_C32(0xd7590000), + SPH_C32(0x257e00a5), SPH_C32(0x4eb624a5), SPH_C32(0xf5aecc2f), + SPH_C32(0xba999dd2), SPH_C32(0xe4390d47), SPH_C32(0xf1360000), + SPH_C32(0x05b70000), SPH_C32(0x44ea0000), SPH_C32(0x98010158), + SPH_C32(0x5e0618ed), SPH_C32(0x1586018d), SPH_C32(0x18430d13), + SPH_C32(0x25b0ddcf) }, + { SPH_C32(0x419e0000), SPH_C32(0x62310000), SPH_C32(0x787e0000), + SPH_C32(0x186600a0), SPH_C32(0x62f93b76), SPH_C32(0x8158daba), + SPH_C32(0x0f5ada39), SPH_C32(0xd864f2b9), SPH_C32(0xf20b0000), + SPH_C32(0x0d040000), SPH_C32(0xb7d00000), SPH_C32(0xa2c3015f), + SPH_C32(0x0f2f92bd), SPH_C32(0x7ee86792), SPH_C32(0x16e6c2f0), + SPH_C32(0xc36aa231) }, + { SPH_C32(0x42a30000), SPH_C32(0x6a820000), SPH_C32(0x8b440000), + SPH_C32(0x22a400a7), SPH_C32(0x33d0b126), SPH_C32(0xea36bca5), + SPH_C32(0x01ff15da), SPH_C32(0x3ebe8d47), SPH_C32(0x5ad10000), + SPH_C32(0x9bba0000), SPH_C32(0xebcd0000), SPH_C32(0xa519015d), + SPH_C32(0x7249073e), SPH_C32(0x61701718), SPH_C32(0xad804af8), + SPH_C32(0x19ed2231) }, + { SPH_C32(0xe8d70000), SPH_C32(0x130d0000), SPH_C32(0xc9980000), + SPH_C32(0xd0b000a9), SPH_C32(0x924f23ad), SPH_C32(0x22631e1e), + SPH_C32(0xb20a33d0), SPH_C32(0x518cecc2), SPH_C32(0xcbc40000), + SPH_C32(0x4f8c0000), SPH_C32(0x4f0d0000), SPH_C32(0xc9070159), + SPH_C32(0x9989ae78), SPH_C32(0x50f1d20b), SPH_C32(0x33eb7249), + SPH_C32(0x84212818) }, + { SPH_C32(0xebea0000), SPH_C32(0x1bbe0000), SPH_C32(0x3aa20000), + SPH_C32(0xea7200ae), SPH_C32(0xc366a9fd), SPH_C32(0x490d7801), + SPH_C32(0xbcaffc33), SPH_C32(0xb756933c), SPH_C32(0x631e0000), + SPH_C32(0xd9320000), SPH_C32(0x13100000), SPH_C32(0xcedd015b), + SPH_C32(0xe4ef3bfb), SPH_C32(0x4f69a281), SPH_C32(0x888dfa41), + SPH_C32(0x5ea6a818) }, + { SPH_C32(0x400d0000), SPH_C32(0x85b30000), SPH_C32(0x95850000), + SPH_C32(0xd76a00ab), SPH_C32(0xef29b62e), SPH_C32(0x3dfb6e94), + SPH_C32(0x096cbbd8), SPH_C32(0x8b0b6cc2), SPH_C32(0x60230000), + SPH_C32(0xd1810000), SPH_C32(0xe02a0000), SPH_C32(0xf41f015c), + SPH_C32(0xb5c6b1ab), SPH_C32(0x2407c49e), SPH_C32(0x862835a2), + SPH_C32(0xb87cd7e6) }, + { SPH_C32(0x43300000), SPH_C32(0x8d000000), SPH_C32(0x66bf0000), + SPH_C32(0xeda800ac), SPH_C32(0xbe003c7e), SPH_C32(0x5695088b), + SPH_C32(0x07c9743b), SPH_C32(0x6dd1133c), SPH_C32(0xc8f90000), + SPH_C32(0x473f0000), SPH_C32(0xbc370000), SPH_C32(0xf3c5015e), + SPH_C32(0xc8a02428), SPH_C32(0x3b9fb414), SPH_C32(0x3d4ebdaa), + SPH_C32(0x62fb57e6) }, + { SPH_C32(0x24c40000), SPH_C32(0x7e090000), SPH_C32(0x30370000), + SPH_C32(0x2d9300b2), SPH_C32(0x80080b5c), SPH_C32(0xd73e9d72), + SPH_C32(0x70ec30dc), SPH_C32(0xf751dc07), SPH_C32(0xca130000), + SPH_C32(0xd7460000), SPH_C32(0x788a0000), SPH_C32(0x2c280153), + SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), SPH_C32(0x36d78dc8), + SPH_C32(0x6944d1fd) }, + { SPH_C32(0x27f90000), SPH_C32(0x76ba0000), SPH_C32(0xc30d0000), + SPH_C32(0x175100b5), SPH_C32(0xd121810c), SPH_C32(0xbc50fb6d), + SPH_C32(0x7e49ff3f), SPH_C32(0x118ba3f9), SPH_C32(0x62c90000), + SPH_C32(0x41f80000), SPH_C32(0x24970000), SPH_C32(0x2bf20151), + SPH_C32(0x52927f6f), SPH_C32(0x5a7c8a28), SPH_C32(0x8db105c0), + SPH_C32(0xb3c351fd) }, + { SPH_C32(0x8c1e0000), SPH_C32(0xe8b70000), SPH_C32(0x6c2a0000), + SPH_C32(0x2a4900b0), SPH_C32(0xfd6e9edf), SPH_C32(0xc8a6edf8), + SPH_C32(0xcb8ab8d4), SPH_C32(0x2dd65c07), SPH_C32(0x61f40000), + SPH_C32(0x494b0000), SPH_C32(0xd7ad0000), SPH_C32(0x11300156), + SPH_C32(0x03bbf53f), SPH_C32(0x3112ec37), SPH_C32(0x8314ca23), + SPH_C32(0x55192e03) }, + { SPH_C32(0x8f230000), SPH_C32(0xe0040000), SPH_C32(0x9f100000), + SPH_C32(0x108b00b7), SPH_C32(0xac47148f), SPH_C32(0xa3c88be7), + SPH_C32(0xc52f7737), SPH_C32(0xcb0c23f9), SPH_C32(0xc92e0000), + SPH_C32(0xdff50000), SPH_C32(0x8bb00000), SPH_C32(0x16ea0154), + SPH_C32(0x7edd60bc), SPH_C32(0x2e8a9cbd), SPH_C32(0x3872422b), + SPH_C32(0x8f9eae03) }, + { SPH_C32(0x25570000), SPH_C32(0x998b0000), SPH_C32(0xddcc0000), + SPH_C32(0xe29f00b9), SPH_C32(0x0dd88604), SPH_C32(0x6b9d295c), + SPH_C32(0x76da513d), SPH_C32(0xa43e427c), SPH_C32(0x583b0000), + SPH_C32(0x0bc30000), SPH_C32(0x2f700000), SPH_C32(0x7af40150), + SPH_C32(0x951dc9fa), SPH_C32(0x1f0b59ae), SPH_C32(0xa6197a9a), + SPH_C32(0x1252a42a) }, + { SPH_C32(0x266a0000), SPH_C32(0x91380000), SPH_C32(0x2ef60000), + SPH_C32(0xd85d00be), SPH_C32(0x5cf10c54), SPH_C32(0x00f34f43), + SPH_C32(0x787f9ede), SPH_C32(0x42e43d82), SPH_C32(0xf0e10000), + SPH_C32(0x9d7d0000), SPH_C32(0x736d0000), SPH_C32(0x7d2e0152), + SPH_C32(0xe87b5c79), SPH_C32(0x00932924), SPH_C32(0x1d7ff292), + SPH_C32(0xc8d5242a) }, + { SPH_C32(0x8d8d0000), SPH_C32(0x0f350000), SPH_C32(0x81d10000), + SPH_C32(0xe54500bb), SPH_C32(0x70be1387), SPH_C32(0x740559d6), + SPH_C32(0xcdbcd935), SPH_C32(0x7eb9c27c), SPH_C32(0xf3dc0000), + SPH_C32(0x95ce0000), SPH_C32(0x80570000), SPH_C32(0x47ec0155), + SPH_C32(0xb952d629), SPH_C32(0x6bfd4f3b), SPH_C32(0x13da3d71), + SPH_C32(0x2e0f5bd4) }, + { SPH_C32(0x8eb00000), SPH_C32(0x07860000), SPH_C32(0x72eb0000), + SPH_C32(0xdf8700bc), SPH_C32(0x219799d7), SPH_C32(0x1f6b3fc9), + SPH_C32(0xc31916d6), SPH_C32(0x9863bd82), SPH_C32(0x5b060000), + SPH_C32(0x03700000), SPH_C32(0xdc4a0000), SPH_C32(0x40360157), + SPH_C32(0xc43443aa), SPH_C32(0x74653fb1), SPH_C32(0xa8bcb579), + SPH_C32(0xf488dbd4) }, + { SPH_C32(0xb6ec0000), SPH_C32(0xa28c0000), SPH_C32(0x67cd0000), + SPH_C32(0x7b4f00b1), SPH_C32(0x3ae1284a), SPH_C32(0x8dd13e7e), + SPH_C32(0xe022c78e), SPH_C32(0x8c47a9d0), SPH_C32(0x59a80000), + SPH_C32(0xec410000), SPH_C32(0xc28b0000), SPH_C32(0xb5f8015b), + SPH_C32(0x18cd44a2), SPH_C32(0xa3a8ed80), SPH_C32(0xa02f1b7b), + SPH_C32(0x413d3a51) }, + { SPH_C32(0xb5d10000), SPH_C32(0xaa3f0000), SPH_C32(0x94f70000), + SPH_C32(0x418d00b6), SPH_C32(0x6bc8a21a), SPH_C32(0xe6bf5861), + SPH_C32(0xee87086d), SPH_C32(0x6a9dd62e), SPH_C32(0xf1720000), + SPH_C32(0x7aff0000), SPH_C32(0x9e960000), SPH_C32(0xb2220159), + SPH_C32(0x65abd121), SPH_C32(0xbc309d0a), SPH_C32(0x1b499373), + SPH_C32(0x9bbaba51) }, + { SPH_C32(0x1e360000), SPH_C32(0x34320000), SPH_C32(0x3bd00000), + SPH_C32(0x7c9500b3), SPH_C32(0x4787bdc9), SPH_C32(0x92494ef4), + SPH_C32(0x5b444f86), SPH_C32(0x56c029d0), SPH_C32(0xf24f0000), + SPH_C32(0x724c0000), SPH_C32(0x6dac0000), SPH_C32(0x88e0015e), + SPH_C32(0x34825b71), SPH_C32(0xd75efb15), SPH_C32(0x15ec5c90), + SPH_C32(0x7d60c5af) }, + { SPH_C32(0x1d0b0000), SPH_C32(0x3c810000), SPH_C32(0xc8ea0000), + SPH_C32(0x465700b4), SPH_C32(0x16ae3799), SPH_C32(0xf92728eb), + SPH_C32(0x55e18065), SPH_C32(0xb01a562e), SPH_C32(0x5a950000), + SPH_C32(0xe4f20000), SPH_C32(0x31b10000), SPH_C32(0x8f3a015c), + SPH_C32(0x49e4cef2), SPH_C32(0xc8c68b9f), SPH_C32(0xae8ad498), + SPH_C32(0xa7e745af) }, + { SPH_C32(0xb77f0000), SPH_C32(0x450e0000), SPH_C32(0x8a360000), + SPH_C32(0xb44300ba), SPH_C32(0xb731a512), SPH_C32(0x31728a50), + SPH_C32(0xe614a66f), SPH_C32(0xdf2837ab), SPH_C32(0xcb800000), + SPH_C32(0x30c40000), SPH_C32(0x95710000), SPH_C32(0xe3240158), + SPH_C32(0xa22467b4), SPH_C32(0xf9474e8c), SPH_C32(0x30e1ec29), + SPH_C32(0x3a2b4f86) }, + { SPH_C32(0xb4420000), SPH_C32(0x4dbd0000), SPH_C32(0x790c0000), + SPH_C32(0x8e8100bd), SPH_C32(0xe6182f42), SPH_C32(0x5a1cec4f), + SPH_C32(0xe8b1698c), SPH_C32(0x39f24855), SPH_C32(0x635a0000), + SPH_C32(0xa67a0000), SPH_C32(0xc96c0000), SPH_C32(0xe4fe015a), + SPH_C32(0xdf42f237), SPH_C32(0xe6df3e06), SPH_C32(0x8b876421), + SPH_C32(0xe0accf86) }, + { SPH_C32(0x1fa50000), SPH_C32(0xd3b00000), SPH_C32(0xd62b0000), + SPH_C32(0xb39900b8), SPH_C32(0xca573091), SPH_C32(0x2eeafada), + SPH_C32(0x5d722e67), SPH_C32(0x05afb7ab), SPH_C32(0x60670000), + SPH_C32(0xaec90000), SPH_C32(0x3a560000), SPH_C32(0xde3c015d), + SPH_C32(0x8e6b7867), SPH_C32(0x8db15819), SPH_C32(0x8522abc2), + SPH_C32(0x0676b078) }, + { SPH_C32(0x1c980000), SPH_C32(0xdb030000), SPH_C32(0x25110000), + SPH_C32(0x895b00bf), SPH_C32(0x9b7ebac1), SPH_C32(0x45849cc5), + SPH_C32(0x53d7e184), SPH_C32(0xe375c855), SPH_C32(0xc8bd0000), + SPH_C32(0x38770000), SPH_C32(0x664b0000), SPH_C32(0xd9e6015f), + SPH_C32(0xf30dede4), SPH_C32(0x92292893), SPH_C32(0x3e4423ca), + SPH_C32(0xdcf13078) }, + { SPH_C32(0x95bb0000), SPH_C32(0x81450000), SPH_C32(0x3b240000), + SPH_C32(0x48db0140), SPH_C32(0x0a8a6c53), SPH_C32(0x56f56eec), + SPH_C32(0x62c91877), SPH_C32(0xe7e00a94), SPH_C32(0xee930000), + SPH_C32(0xd6070000), SPH_C32(0x92c10000), SPH_C32(0x2b9801e0), + SPH_C32(0x9451287c), SPH_C32(0x3b6cfb57), SPH_C32(0x45312374), + SPH_C32(0x201f6a64) }, + { SPH_C32(0x96860000), SPH_C32(0x89f60000), SPH_C32(0xc81e0000), + SPH_C32(0x72190147), SPH_C32(0x5ba3e603), SPH_C32(0x3d9b08f3), + SPH_C32(0x6c6cd794), SPH_C32(0x013a756a), SPH_C32(0x46490000), + SPH_C32(0x40b90000), SPH_C32(0xcedc0000), SPH_C32(0x2c4201e2), + SPH_C32(0xe937bdff), SPH_C32(0x24f48bdd), SPH_C32(0xfe57ab7c), + SPH_C32(0xfa98ea64) }, + { SPH_C32(0x3d610000), SPH_C32(0x17fb0000), SPH_C32(0x67390000), + SPH_C32(0x4f010142), SPH_C32(0x77ecf9d0), SPH_C32(0x496d1e66), + SPH_C32(0xd9af907f), SPH_C32(0x3d678a94), SPH_C32(0x45740000), + SPH_C32(0x480a0000), SPH_C32(0x3de60000), SPH_C32(0x168001e5), + SPH_C32(0xb81e37af), SPH_C32(0x4f9aedc2), SPH_C32(0xf0f2649f), + SPH_C32(0x1c42959a) }, + { SPH_C32(0x3e5c0000), SPH_C32(0x1f480000), SPH_C32(0x94030000), + SPH_C32(0x75c30145), SPH_C32(0x26c57380), SPH_C32(0x22037879), + SPH_C32(0xd70a5f9c), SPH_C32(0xdbbdf56a), SPH_C32(0xedae0000), + SPH_C32(0xdeb40000), SPH_C32(0x61fb0000), SPH_C32(0x115a01e7), + SPH_C32(0xc578a22c), SPH_C32(0x50029d48), SPH_C32(0x4b94ec97), + SPH_C32(0xc6c5159a) }, + { SPH_C32(0x94280000), SPH_C32(0x66c70000), SPH_C32(0xd6df0000), + SPH_C32(0x87d7014b), SPH_C32(0x875ae10b), SPH_C32(0xea56dac2), + SPH_C32(0x64ff7996), SPH_C32(0xb48f94ef), SPH_C32(0x7cbb0000), + SPH_C32(0x0a820000), SPH_C32(0xc53b0000), SPH_C32(0x7d4401e3), + SPH_C32(0x2eb80b6a), SPH_C32(0x6183585b), SPH_C32(0xd5ffd426), + SPH_C32(0x5b091fb3) }, + { SPH_C32(0x97150000), SPH_C32(0x6e740000), SPH_C32(0x25e50000), + SPH_C32(0xbd15014c), SPH_C32(0xd6736b5b), SPH_C32(0x8138bcdd), + SPH_C32(0x6a5ab675), SPH_C32(0x5255eb11), SPH_C32(0xd4610000), + SPH_C32(0x9c3c0000), SPH_C32(0x99260000), SPH_C32(0x7a9e01e1), + SPH_C32(0x53de9ee9), SPH_C32(0x7e1b28d1), SPH_C32(0x6e995c2e), + SPH_C32(0x818e9fb3) }, + { SPH_C32(0x3cf20000), SPH_C32(0xf0790000), SPH_C32(0x8ac20000), + SPH_C32(0x800d0149), SPH_C32(0xfa3c7488), SPH_C32(0xf5ceaa48), + SPH_C32(0xdf99f19e), SPH_C32(0x6e0814ef), SPH_C32(0xd75c0000), + SPH_C32(0x948f0000), SPH_C32(0x6a1c0000), SPH_C32(0x405c01e6), + SPH_C32(0x02f714b9), SPH_C32(0x15754ece), SPH_C32(0x603c93cd), + SPH_C32(0x6754e04d) }, + { SPH_C32(0x3fcf0000), SPH_C32(0xf8ca0000), SPH_C32(0x79f80000), + SPH_C32(0xbacf014e), SPH_C32(0xab15fed8), SPH_C32(0x9ea0cc57), + SPH_C32(0xd13c3e7d), SPH_C32(0x88d26b11), SPH_C32(0x7f860000), + SPH_C32(0x02310000), SPH_C32(0x36010000), SPH_C32(0x478601e4), + SPH_C32(0x7f91813a), SPH_C32(0x0aed3e44), SPH_C32(0xdb5a1bc5), + SPH_C32(0xbdd3604d) }, + { SPH_C32(0x07930000), SPH_C32(0x5dc00000), SPH_C32(0x6cde0000), + SPH_C32(0x1e070143), SPH_C32(0xb0634f45), SPH_C32(0x0c1acde0), + SPH_C32(0xf207ef25), SPH_C32(0x9cf67f43), SPH_C32(0x7d280000), + SPH_C32(0xed000000), SPH_C32(0x28c00000), SPH_C32(0xb24801e8), + SPH_C32(0xa3688632), SPH_C32(0xdd20ec75), SPH_C32(0xd3c9b5c7), + SPH_C32(0x086681c8) }, + { SPH_C32(0x04ae0000), SPH_C32(0x55730000), SPH_C32(0x9fe40000), + SPH_C32(0x24c50144), SPH_C32(0xe14ac515), SPH_C32(0x6774abff), + SPH_C32(0xfca220c6), SPH_C32(0x7a2c00bd), SPH_C32(0xd5f20000), + SPH_C32(0x7bbe0000), SPH_C32(0x74dd0000), SPH_C32(0xb59201ea), + SPH_C32(0xde0e13b1), SPH_C32(0xc2b89cff), SPH_C32(0x68af3dcf), + SPH_C32(0xd2e101c8) }, + { SPH_C32(0xaf490000), SPH_C32(0xcb7e0000), SPH_C32(0x30c30000), + SPH_C32(0x19dd0141), SPH_C32(0xcd05dac6), SPH_C32(0x1382bd6a), + SPH_C32(0x4961672d), SPH_C32(0x4671ff43), SPH_C32(0xd6cf0000), + SPH_C32(0x730d0000), SPH_C32(0x87e70000), SPH_C32(0x8f5001ed), + SPH_C32(0x8f2799e1), SPH_C32(0xa9d6fae0), SPH_C32(0x660af22c), + SPH_C32(0x343b7e36) }, + { SPH_C32(0xac740000), SPH_C32(0xc3cd0000), SPH_C32(0xc3f90000), + SPH_C32(0x231f0146), SPH_C32(0x9c2c5096), SPH_C32(0x78ecdb75), + SPH_C32(0x47c4a8ce), SPH_C32(0xa0ab80bd), SPH_C32(0x7e150000), + SPH_C32(0xe5b30000), SPH_C32(0xdbfa0000), SPH_C32(0x888a01ef), + SPH_C32(0xf2410c62), SPH_C32(0xb64e8a6a), SPH_C32(0xdd6c7a24), + SPH_C32(0xeebcfe36) }, + { SPH_C32(0x06000000), SPH_C32(0xba420000), SPH_C32(0x81250000), + SPH_C32(0xd10b0148), SPH_C32(0x3db3c21d), SPH_C32(0xb0b979ce), + SPH_C32(0xf4318ec4), SPH_C32(0xcf99e138), SPH_C32(0xef000000), + SPH_C32(0x31850000), SPH_C32(0x7f3a0000), SPH_C32(0xe49401eb), + SPH_C32(0x1981a524), SPH_C32(0x87cf4f79), SPH_C32(0x43074295), + SPH_C32(0x7370f41f) }, + { SPH_C32(0x053d0000), SPH_C32(0xb2f10000), SPH_C32(0x721f0000), + SPH_C32(0xebc9014f), SPH_C32(0x6c9a484d), SPH_C32(0xdbd71fd1), + SPH_C32(0xfa944127), SPH_C32(0x29439ec6), SPH_C32(0x47da0000), + SPH_C32(0xa73b0000), SPH_C32(0x23270000), SPH_C32(0xe34e01e9), + SPH_C32(0x64e730a7), SPH_C32(0x98573ff3), SPH_C32(0xf861ca9d), + SPH_C32(0xa9f7741f) }, + { SPH_C32(0xaeda0000), SPH_C32(0x2cfc0000), SPH_C32(0xdd380000), + SPH_C32(0xd6d1014a), SPH_C32(0x40d5579e), SPH_C32(0xaf210944), + SPH_C32(0x4f5706cc), SPH_C32(0x151e6138), SPH_C32(0x44e70000), + SPH_C32(0xaf880000), SPH_C32(0xd01d0000), SPH_C32(0xd98c01ee), + SPH_C32(0x35cebaf7), SPH_C32(0xf33959ec), SPH_C32(0xf6c4057e), + SPH_C32(0x4f2d0be1) }, + { SPH_C32(0xade70000), SPH_C32(0x244f0000), SPH_C32(0x2e020000), + SPH_C32(0xec13014d), SPH_C32(0x11fcddce), SPH_C32(0xc44f6f5b), + SPH_C32(0x41f2c92f), SPH_C32(0xf3c41ec6), SPH_C32(0xec3d0000), + SPH_C32(0x39360000), SPH_C32(0x8c000000), SPH_C32(0xde5601ec), + SPH_C32(0x48a82f74), SPH_C32(0xeca12966), SPH_C32(0x4da28d76), + SPH_C32(0x95aa8be1) }, + { SPH_C32(0xca130000), SPH_C32(0xd7460000), SPH_C32(0x788a0000), + SPH_C32(0x2c280153), SPH_C32(0x2ff4eaec), SPH_C32(0x45e4faa2), + SPH_C32(0x36d78dc8), SPH_C32(0x6944d1fd), SPH_C32(0xeed70000), + SPH_C32(0xa94f0000), SPH_C32(0x48bd0000), SPH_C32(0x01bb01e1), + SPH_C32(0xaffce1b0), SPH_C32(0x92da67d0), SPH_C32(0x463bbd14), + SPH_C32(0x9e150dfa) }, + { SPH_C32(0xc92e0000), SPH_C32(0xdff50000), SPH_C32(0x8bb00000), + SPH_C32(0x16ea0154), SPH_C32(0x7edd60bc), SPH_C32(0x2e8a9cbd), + SPH_C32(0x3872422b), SPH_C32(0x8f9eae03), SPH_C32(0x460d0000), + SPH_C32(0x3ff10000), SPH_C32(0x14a00000), SPH_C32(0x066101e3), + SPH_C32(0xd29a7433), SPH_C32(0x8d42175a), SPH_C32(0xfd5d351c), + SPH_C32(0x44928dfa) }, + { SPH_C32(0x62c90000), SPH_C32(0x41f80000), SPH_C32(0x24970000), + SPH_C32(0x2bf20151), SPH_C32(0x52927f6f), SPH_C32(0x5a7c8a28), + SPH_C32(0x8db105c0), SPH_C32(0xb3c351fd), SPH_C32(0x45300000), + SPH_C32(0x37420000), SPH_C32(0xe79a0000), SPH_C32(0x3ca301e4), + SPH_C32(0x83b3fe63), SPH_C32(0xe62c7145), SPH_C32(0xf3f8faff), + SPH_C32(0xa248f204) }, + { SPH_C32(0x61f40000), SPH_C32(0x494b0000), SPH_C32(0xd7ad0000), + SPH_C32(0x11300156), SPH_C32(0x03bbf53f), SPH_C32(0x3112ec37), + SPH_C32(0x8314ca23), SPH_C32(0x55192e03), SPH_C32(0xedea0000), + SPH_C32(0xa1fc0000), SPH_C32(0xbb870000), SPH_C32(0x3b7901e6), + SPH_C32(0xfed56be0), SPH_C32(0xf9b401cf), SPH_C32(0x489e72f7), + SPH_C32(0x78cf7204) }, + { SPH_C32(0xcb800000), SPH_C32(0x30c40000), SPH_C32(0x95710000), + SPH_C32(0xe3240158), SPH_C32(0xa22467b4), SPH_C32(0xf9474e8c), + SPH_C32(0x30e1ec29), SPH_C32(0x3a2b4f86), SPH_C32(0x7cff0000), + SPH_C32(0x75ca0000), SPH_C32(0x1f470000), SPH_C32(0x576701e2), + SPH_C32(0x1515c2a6), SPH_C32(0xc835c4dc), SPH_C32(0xd6f54a46), + SPH_C32(0xe503782d) }, + { SPH_C32(0xc8bd0000), SPH_C32(0x38770000), SPH_C32(0x664b0000), + SPH_C32(0xd9e6015f), SPH_C32(0xf30dede4), SPH_C32(0x92292893), + SPH_C32(0x3e4423ca), SPH_C32(0xdcf13078), SPH_C32(0xd4250000), + SPH_C32(0xe3740000), SPH_C32(0x435a0000), SPH_C32(0x50bd01e0), + SPH_C32(0x68735725), SPH_C32(0xd7adb456), SPH_C32(0x6d93c24e), + SPH_C32(0x3f84f82d) }, + { SPH_C32(0x635a0000), SPH_C32(0xa67a0000), SPH_C32(0xc96c0000), + SPH_C32(0xe4fe015a), SPH_C32(0xdf42f237), SPH_C32(0xe6df3e06), + SPH_C32(0x8b876421), SPH_C32(0xe0accf86), SPH_C32(0xd7180000), + SPH_C32(0xebc70000), SPH_C32(0xb0600000), SPH_C32(0x6a7f01e7), + SPH_C32(0x395add75), SPH_C32(0xbcc3d249), SPH_C32(0x63360dad), + SPH_C32(0xd95e87d3) }, + { SPH_C32(0x60670000), SPH_C32(0xaec90000), SPH_C32(0x3a560000), + SPH_C32(0xde3c015d), SPH_C32(0x8e6b7867), SPH_C32(0x8db15819), + SPH_C32(0x8522abc2), SPH_C32(0x0676b078), SPH_C32(0x7fc20000), + SPH_C32(0x7d790000), SPH_C32(0xec7d0000), SPH_C32(0x6da501e5), + SPH_C32(0x443c48f6), SPH_C32(0xa35ba2c3), SPH_C32(0xd85085a5), + SPH_C32(0x03d907d3) }, + { SPH_C32(0x583b0000), SPH_C32(0x0bc30000), SPH_C32(0x2f700000), + SPH_C32(0x7af40150), SPH_C32(0x951dc9fa), SPH_C32(0x1f0b59ae), + SPH_C32(0xa6197a9a), SPH_C32(0x1252a42a), SPH_C32(0x7d6c0000), + SPH_C32(0x92480000), SPH_C32(0xf2bc0000), SPH_C32(0x986b01e9), + SPH_C32(0x98c54ffe), SPH_C32(0x749670f2), SPH_C32(0xd0c32ba7), + SPH_C32(0xb66ce656) }, + { SPH_C32(0x5b060000), SPH_C32(0x03700000), SPH_C32(0xdc4a0000), + SPH_C32(0x40360157), SPH_C32(0xc43443aa), SPH_C32(0x74653fb1), + SPH_C32(0xa8bcb579), SPH_C32(0xf488dbd4), SPH_C32(0xd5b60000), + SPH_C32(0x04f60000), SPH_C32(0xaea10000), SPH_C32(0x9fb101eb), + SPH_C32(0xe5a3da7d), SPH_C32(0x6b0e0078), SPH_C32(0x6ba5a3af), + SPH_C32(0x6ceb6656) }, + { SPH_C32(0xf0e10000), SPH_C32(0x9d7d0000), SPH_C32(0x736d0000), + SPH_C32(0x7d2e0152), SPH_C32(0xe87b5c79), SPH_C32(0x00932924), + SPH_C32(0x1d7ff292), SPH_C32(0xc8d5242a), SPH_C32(0xd68b0000), + SPH_C32(0x0c450000), SPH_C32(0x5d9b0000), SPH_C32(0xa57301ec), + SPH_C32(0xb48a502d), SPH_C32(0x00606667), SPH_C32(0x65006c4c), + SPH_C32(0x8a3119a8) }, + { SPH_C32(0xf3dc0000), SPH_C32(0x95ce0000), SPH_C32(0x80570000), + SPH_C32(0x47ec0155), SPH_C32(0xb952d629), SPH_C32(0x6bfd4f3b), + SPH_C32(0x13da3d71), SPH_C32(0x2e0f5bd4), SPH_C32(0x7e510000), + SPH_C32(0x9afb0000), SPH_C32(0x01860000), SPH_C32(0xa2a901ee), + SPH_C32(0xc9ecc5ae), SPH_C32(0x1ff816ed), SPH_C32(0xde66e444), + SPH_C32(0x50b699a8) }, + { SPH_C32(0x59a80000), SPH_C32(0xec410000), SPH_C32(0xc28b0000), + SPH_C32(0xb5f8015b), SPH_C32(0x18cd44a2), SPH_C32(0xa3a8ed80), + SPH_C32(0xa02f1b7b), SPH_C32(0x413d3a51), SPH_C32(0xef440000), + SPH_C32(0x4ecd0000), SPH_C32(0xa5460000), SPH_C32(0xceb701ea), + SPH_C32(0x222c6ce8), SPH_C32(0x2e79d3fe), SPH_C32(0x400ddcf5), + SPH_C32(0xcd7a9381) }, + { SPH_C32(0x5a950000), SPH_C32(0xe4f20000), SPH_C32(0x31b10000), + SPH_C32(0x8f3a015c), SPH_C32(0x49e4cef2), SPH_C32(0xc8c68b9f), + SPH_C32(0xae8ad498), SPH_C32(0xa7e745af), SPH_C32(0x479e0000), + SPH_C32(0xd8730000), SPH_C32(0xf95b0000), SPH_C32(0xc96d01e8), + SPH_C32(0x5f4af96b), SPH_C32(0x31e1a374), SPH_C32(0xfb6b54fd), + SPH_C32(0x17fd1381) }, + { SPH_C32(0xf1720000), SPH_C32(0x7aff0000), SPH_C32(0x9e960000), + SPH_C32(0xb2220159), SPH_C32(0x65abd121), SPH_C32(0xbc309d0a), + SPH_C32(0x1b499373), SPH_C32(0x9bbaba51), SPH_C32(0x44a30000), + SPH_C32(0xd0c00000), SPH_C32(0x0a610000), SPH_C32(0xf3af01ef), + SPH_C32(0x0e63733b), SPH_C32(0x5a8fc56b), SPH_C32(0xf5ce9b1e), + SPH_C32(0xf1276c7f) }, + { SPH_C32(0xf24f0000), SPH_C32(0x724c0000), SPH_C32(0x6dac0000), + SPH_C32(0x88e0015e), SPH_C32(0x34825b71), SPH_C32(0xd75efb15), + SPH_C32(0x15ec5c90), SPH_C32(0x7d60c5af), SPH_C32(0xec790000), + SPH_C32(0x467e0000), SPH_C32(0x567c0000), SPH_C32(0xf47501ed), + SPH_C32(0x7305e6b8), SPH_C32(0x4517b5e1), SPH_C32(0x4ea81316), + SPH_C32(0x2ba0ec7f) }, + { SPH_C32(0x95ff0000), SPH_C32(0xfe0d0000), SPH_C32(0xe1580000), + SPH_C32(0x62f80141), SPH_C32(0x3127a59f), SPH_C32(0xff43f26b), + SPH_C32(0x61c38617), SPH_C32(0x59ea6d0a), SPH_C32(0xb17f0000), + SPH_C32(0xff4c0000), SPH_C32(0x0b130000), SPH_C32(0x654801f2), + SPH_C32(0x8a82670f), SPH_C32(0x81cbf39e), SPH_C32(0x122528ab), + SPH_C32(0x10b1d693) }, + { SPH_C32(0x96c20000), SPH_C32(0xf6be0000), SPH_C32(0x12620000), + SPH_C32(0x583a0146), SPH_C32(0x600e2fcf), SPH_C32(0x942d9474), + SPH_C32(0x6f6649f4), SPH_C32(0xbf3012f4), SPH_C32(0x19a50000), + SPH_C32(0x69f20000), SPH_C32(0x570e0000), SPH_C32(0x629201f0), + SPH_C32(0xf7e4f28c), SPH_C32(0x9e538314), SPH_C32(0xa943a0a3), + SPH_C32(0xca365693) }, + { SPH_C32(0x3d250000), SPH_C32(0x68b30000), SPH_C32(0xbd450000), + SPH_C32(0x65220143), SPH_C32(0x4c41301c), SPH_C32(0xe0db82e1), + SPH_C32(0xdaa50e1f), SPH_C32(0x836ded0a), SPH_C32(0x1a980000), + SPH_C32(0x61410000), SPH_C32(0xa4340000), SPH_C32(0x585001f7), + SPH_C32(0xa6cd78dc), SPH_C32(0xf53de50b), SPH_C32(0xa7e66f40), + SPH_C32(0x2cec296d) }, + { SPH_C32(0x3e180000), SPH_C32(0x60000000), SPH_C32(0x4e7f0000), + SPH_C32(0x5fe00144), SPH_C32(0x1d68ba4c), SPH_C32(0x8bb5e4fe), + SPH_C32(0xd400c1fc), SPH_C32(0x65b792f4), SPH_C32(0xb2420000), + SPH_C32(0xf7ff0000), SPH_C32(0xf8290000), SPH_C32(0x5f8a01f5), + SPH_C32(0xdbabed5f), SPH_C32(0xeaa59581), SPH_C32(0x1c80e748), + SPH_C32(0xf66ba96d) }, + { SPH_C32(0x946c0000), SPH_C32(0x198f0000), SPH_C32(0x0ca30000), + SPH_C32(0xadf4014a), SPH_C32(0xbcf728c7), SPH_C32(0x43e04645), + SPH_C32(0x67f5e7f6), SPH_C32(0x0a85f371), SPH_C32(0x23570000), + SPH_C32(0x23c90000), SPH_C32(0x5ce90000), SPH_C32(0x339401f1), + SPH_C32(0x306b4419), SPH_C32(0xdb245092), SPH_C32(0x82ebdff9), + SPH_C32(0x6ba7a344) }, + { SPH_C32(0x97510000), SPH_C32(0x113c0000), SPH_C32(0xff990000), + SPH_C32(0x9736014d), SPH_C32(0xeddea297), SPH_C32(0x288e205a), + SPH_C32(0x69502815), SPH_C32(0xec5f8c8f), SPH_C32(0x8b8d0000), + SPH_C32(0xb5770000), SPH_C32(0x00f40000), SPH_C32(0x344e01f3), + SPH_C32(0x4d0dd19a), SPH_C32(0xc4bc2018), SPH_C32(0x398d57f1), + SPH_C32(0xb1202344) }, + { SPH_C32(0x3cb60000), SPH_C32(0x8f310000), SPH_C32(0x50be0000), + SPH_C32(0xaa2e0148), SPH_C32(0xc191bd44), SPH_C32(0x5c7836cf), + SPH_C32(0xdc936ffe), SPH_C32(0xd0027371), SPH_C32(0x88b00000), + SPH_C32(0xbdc40000), SPH_C32(0xf3ce0000), SPH_C32(0x0e8c01f4), + SPH_C32(0x1c245bca), SPH_C32(0xafd24607), SPH_C32(0x37289812), + SPH_C32(0x57fa5cba) }, + { SPH_C32(0x3f8b0000), SPH_C32(0x87820000), SPH_C32(0xa3840000), + SPH_C32(0x90ec014f), SPH_C32(0x90b83714), SPH_C32(0x371650d0), + SPH_C32(0xd236a01d), SPH_C32(0x36d80c8f), SPH_C32(0x206a0000), + SPH_C32(0x2b7a0000), SPH_C32(0xafd30000), SPH_C32(0x095601f6), + SPH_C32(0x6142ce49), SPH_C32(0xb04a368d), SPH_C32(0x8c4e101a), + SPH_C32(0x8d7ddcba) }, + { SPH_C32(0x07d70000), SPH_C32(0x22880000), SPH_C32(0xb6a20000), + SPH_C32(0x34240142), SPH_C32(0x8bce8689), SPH_C32(0xa5ac5167), + SPH_C32(0xf10d7145), SPH_C32(0x22fc18dd), SPH_C32(0x22c40000), + SPH_C32(0xc44b0000), SPH_C32(0xb1120000), SPH_C32(0xfc9801fa), + SPH_C32(0xbdbbc941), SPH_C32(0x6787e4bc), SPH_C32(0x84ddbe18), + SPH_C32(0x38c83d3f) }, + { SPH_C32(0x04ea0000), SPH_C32(0x2a3b0000), SPH_C32(0x45980000), + SPH_C32(0x0ee60145), SPH_C32(0xdae70cd9), SPH_C32(0xcec23778), + SPH_C32(0xffa8bea6), SPH_C32(0xc4266723), SPH_C32(0x8a1e0000), + SPH_C32(0x52f50000), SPH_C32(0xed0f0000), SPH_C32(0xfb4201f8), + SPH_C32(0xc0dd5cc2), SPH_C32(0x781f9436), SPH_C32(0x3fbb3610), + SPH_C32(0xe24fbd3f) }, + { SPH_C32(0xaf0d0000), SPH_C32(0xb4360000), SPH_C32(0xeabf0000), + SPH_C32(0x33fe0140), SPH_C32(0xf6a8130a), SPH_C32(0xba3421ed), + SPH_C32(0x4a6bf94d), SPH_C32(0xf87b98dd), SPH_C32(0x89230000), + SPH_C32(0x5a460000), SPH_C32(0x1e350000), SPH_C32(0xc18001ff), + SPH_C32(0x91f4d692), SPH_C32(0x1371f229), SPH_C32(0x311ef9f3), + SPH_C32(0x0495c2c1) }, + { SPH_C32(0xac300000), SPH_C32(0xbc850000), SPH_C32(0x19850000), + SPH_C32(0x093c0147), SPH_C32(0xa781995a), SPH_C32(0xd15a47f2), + SPH_C32(0x44ce36ae), SPH_C32(0x1ea1e723), SPH_C32(0x21f90000), + SPH_C32(0xccf80000), SPH_C32(0x42280000), SPH_C32(0xc65a01fd), + SPH_C32(0xec924311), SPH_C32(0x0ce982a3), SPH_C32(0x8a7871fb), + SPH_C32(0xde1242c1) }, + { SPH_C32(0x06440000), SPH_C32(0xc50a0000), SPH_C32(0x5b590000), + SPH_C32(0xfb280149), SPH_C32(0x061e0bd1), SPH_C32(0x190fe549), + SPH_C32(0xf73b10a4), SPH_C32(0x719386a6), SPH_C32(0xb0ec0000), + SPH_C32(0x18ce0000), SPH_C32(0xe6e80000), SPH_C32(0xaa4401f9), + SPH_C32(0x0752ea57), SPH_C32(0x3d6847b0), SPH_C32(0x1413494a), + SPH_C32(0x43de48e8) }, + { SPH_C32(0x05790000), SPH_C32(0xcdb90000), SPH_C32(0xa8630000), + SPH_C32(0xc1ea014e), SPH_C32(0x57378181), SPH_C32(0x72618356), + SPH_C32(0xf99edf47), SPH_C32(0x9749f958), SPH_C32(0x18360000), + SPH_C32(0x8e700000), SPH_C32(0xbaf50000), SPH_C32(0xad9e01fb), + SPH_C32(0x7a347fd4), SPH_C32(0x22f0373a), SPH_C32(0xaf75c142), + SPH_C32(0x9959c8e8) }, + { SPH_C32(0xae9e0000), SPH_C32(0x53b40000), SPH_C32(0x07440000), + SPH_C32(0xfcf2014b), SPH_C32(0x7b789e52), SPH_C32(0x069795c3), + SPH_C32(0x4c5d98ac), SPH_C32(0xab1406a6), SPH_C32(0x1b0b0000), + SPH_C32(0x86c30000), SPH_C32(0x49cf0000), SPH_C32(0x975c01fc), + SPH_C32(0x2b1df584), SPH_C32(0x499e5125), SPH_C32(0xa1d00ea1), + SPH_C32(0x7f83b716) }, + { SPH_C32(0xada30000), SPH_C32(0x5b070000), SPH_C32(0xf47e0000), + SPH_C32(0xc630014c), SPH_C32(0x2a511402), SPH_C32(0x6df9f3dc), + SPH_C32(0x42f8574f), SPH_C32(0x4dce7958), SPH_C32(0xb3d10000), + SPH_C32(0x107d0000), SPH_C32(0x15d20000), SPH_C32(0x908601fe), + SPH_C32(0x567b6007), SPH_C32(0x560621af), SPH_C32(0x1ab686a9), + SPH_C32(0xa5043716) }, + { SPH_C32(0xca570000), SPH_C32(0xa80e0000), SPH_C32(0xa2f60000), + SPH_C32(0x060b0152), SPH_C32(0x14592320), SPH_C32(0xec526625), + SPH_C32(0x35dd13a8), SPH_C32(0xd74eb663), SPH_C32(0xb13b0000), + SPH_C32(0x80040000), SPH_C32(0xd16f0000), SPH_C32(0x4f6b01f3), + SPH_C32(0xb12faec3), SPH_C32(0x287d6f19), SPH_C32(0x112fb6cb), + SPH_C32(0xaebbb10d) }, + { SPH_C32(0xc96a0000), SPH_C32(0xa0bd0000), SPH_C32(0x51cc0000), + SPH_C32(0x3cc90155), SPH_C32(0x4570a970), SPH_C32(0x873c003a), + SPH_C32(0x3b78dc4b), SPH_C32(0x3194c99d), SPH_C32(0x19e10000), + SPH_C32(0x16ba0000), SPH_C32(0x8d720000), SPH_C32(0x48b101f1), + SPH_C32(0xcc493b40), SPH_C32(0x37e51f93), SPH_C32(0xaa493ec3), + SPH_C32(0x743c310d) }, + { SPH_C32(0x628d0000), SPH_C32(0x3eb00000), SPH_C32(0xfeeb0000), + SPH_C32(0x01d10150), SPH_C32(0x693fb6a3), SPH_C32(0xf3ca16af), + SPH_C32(0x8ebb9ba0), SPH_C32(0x0dc93663), SPH_C32(0x1adc0000), + SPH_C32(0x1e090000), SPH_C32(0x7e480000), SPH_C32(0x727301f6), + SPH_C32(0x9d60b110), SPH_C32(0x5c8b798c), SPH_C32(0xa4ecf120), + SPH_C32(0x92e64ef3) }, + { SPH_C32(0x61b00000), SPH_C32(0x36030000), SPH_C32(0x0dd10000), + SPH_C32(0x3b130157), SPH_C32(0x38163cf3), SPH_C32(0x98a470b0), + SPH_C32(0x801e5443), SPH_C32(0xeb13499d), SPH_C32(0xb2060000), + SPH_C32(0x88b70000), SPH_C32(0x22550000), SPH_C32(0x75a901f4), + SPH_C32(0xe0062493), SPH_C32(0x43130906), SPH_C32(0x1f8a7928), + SPH_C32(0x4861cef3) }, + { SPH_C32(0xcbc40000), SPH_C32(0x4f8c0000), SPH_C32(0x4f0d0000), + SPH_C32(0xc9070159), SPH_C32(0x9989ae78), SPH_C32(0x50f1d20b), + SPH_C32(0x33eb7249), SPH_C32(0x84212818), SPH_C32(0x23130000), + SPH_C32(0x5c810000), SPH_C32(0x86950000), SPH_C32(0x19b701f0), + SPH_C32(0x0bc68dd5), SPH_C32(0x7292cc15), SPH_C32(0x81e14199), + SPH_C32(0xd5adc4da) }, + { SPH_C32(0xc8f90000), SPH_C32(0x473f0000), SPH_C32(0xbc370000), + SPH_C32(0xf3c5015e), SPH_C32(0xc8a02428), SPH_C32(0x3b9fb414), + SPH_C32(0x3d4ebdaa), SPH_C32(0x62fb57e6), SPH_C32(0x8bc90000), + SPH_C32(0xca3f0000), SPH_C32(0xda880000), SPH_C32(0x1e6d01f2), + SPH_C32(0x76a01856), SPH_C32(0x6d0abc9f), SPH_C32(0x3a87c991), + SPH_C32(0x0f2a44da) }, + { SPH_C32(0x631e0000), SPH_C32(0xd9320000), SPH_C32(0x13100000), + SPH_C32(0xcedd015b), SPH_C32(0xe4ef3bfb), SPH_C32(0x4f69a281), + SPH_C32(0x888dfa41), SPH_C32(0x5ea6a818), SPH_C32(0x88f40000), + SPH_C32(0xc28c0000), SPH_C32(0x29b20000), SPH_C32(0x24af01f5), + SPH_C32(0x27899206), SPH_C32(0x0664da80), SPH_C32(0x34220672), + SPH_C32(0xe9f03b24) }, + { SPH_C32(0x60230000), SPH_C32(0xd1810000), SPH_C32(0xe02a0000), + SPH_C32(0xf41f015c), SPH_C32(0xb5c6b1ab), SPH_C32(0x2407c49e), + SPH_C32(0x862835a2), SPH_C32(0xb87cd7e6), SPH_C32(0x202e0000), + SPH_C32(0x54320000), SPH_C32(0x75af0000), SPH_C32(0x237501f7), + SPH_C32(0x5aef0785), SPH_C32(0x19fcaa0a), SPH_C32(0x8f448e7a), + SPH_C32(0x3377bb24) }, + { SPH_C32(0x587f0000), SPH_C32(0x748b0000), SPH_C32(0xf50c0000), + SPH_C32(0x50d70151), SPH_C32(0xaeb00036), SPH_C32(0xb6bdc529), + SPH_C32(0xa513e4fa), SPH_C32(0xac58c3b4), SPH_C32(0x22800000), + SPH_C32(0xbb030000), SPH_C32(0x6b6e0000), SPH_C32(0xd6bb01fb), + SPH_C32(0x8616008d), SPH_C32(0xce31783b), SPH_C32(0x87d72078), + SPH_C32(0x86c25aa1) }, + { SPH_C32(0x5b420000), SPH_C32(0x7c380000), SPH_C32(0x06360000), + SPH_C32(0x6a150156), SPH_C32(0xff998a66), SPH_C32(0xddd3a336), + SPH_C32(0xabb62b19), SPH_C32(0x4a82bc4a), SPH_C32(0x8a5a0000), + SPH_C32(0x2dbd0000), SPH_C32(0x37730000), SPH_C32(0xd16101f9), + SPH_C32(0xfb70950e), SPH_C32(0xd1a908b1), SPH_C32(0x3cb1a870), + SPH_C32(0x5c45daa1) }, + { SPH_C32(0xf0a50000), SPH_C32(0xe2350000), SPH_C32(0xa9110000), + SPH_C32(0x570d0153), SPH_C32(0xd3d695b5), SPH_C32(0xa925b5a3), + SPH_C32(0x1e756cf2), SPH_C32(0x76df43b4), SPH_C32(0x89670000), + SPH_C32(0x250e0000), SPH_C32(0xc4490000), SPH_C32(0xeba301fe), + SPH_C32(0xaa591f5e), SPH_C32(0xbac76eae), SPH_C32(0x32146793), + SPH_C32(0xba9fa55f) }, + { SPH_C32(0xf3980000), SPH_C32(0xea860000), SPH_C32(0x5a2b0000), + SPH_C32(0x6dcf0154), SPH_C32(0x82ff1fe5), SPH_C32(0xc24bd3bc), + SPH_C32(0x10d0a311), SPH_C32(0x90053c4a), SPH_C32(0x21bd0000), + SPH_C32(0xb3b00000), SPH_C32(0x98540000), SPH_C32(0xec7901fc), + SPH_C32(0xd73f8add), SPH_C32(0xa55f1e24), SPH_C32(0x8972ef9b), + SPH_C32(0x6018255f) }, + { SPH_C32(0x59ec0000), SPH_C32(0x93090000), SPH_C32(0x18f70000), + SPH_C32(0x9fdb015a), SPH_C32(0x23608d6e), SPH_C32(0x0a1e7107), + SPH_C32(0xa325851b), SPH_C32(0xff375dcf), SPH_C32(0xb0a80000), + SPH_C32(0x67860000), SPH_C32(0x3c940000), SPH_C32(0x806701f8), + SPH_C32(0x3cff239b), SPH_C32(0x94dedb37), SPH_C32(0x1719d72a), + SPH_C32(0xfdd42f76) }, + { SPH_C32(0x5ad10000), SPH_C32(0x9bba0000), SPH_C32(0xebcd0000), + SPH_C32(0xa519015d), SPH_C32(0x7249073e), SPH_C32(0x61701718), + SPH_C32(0xad804af8), SPH_C32(0x19ed2231), SPH_C32(0x18720000), + SPH_C32(0xf1380000), SPH_C32(0x60890000), SPH_C32(0x87bd01fa), + SPH_C32(0x4199b618), SPH_C32(0x8b46abbd), SPH_C32(0xac7f5f22), + SPH_C32(0x2753af76) }, + { SPH_C32(0xf1360000), SPH_C32(0x05b70000), SPH_C32(0x44ea0000), + SPH_C32(0x98010158), SPH_C32(0x5e0618ed), SPH_C32(0x1586018d), + SPH_C32(0x18430d13), SPH_C32(0x25b0ddcf), SPH_C32(0x1b4f0000), + SPH_C32(0xf98b0000), SPH_C32(0x93b30000), SPH_C32(0xbd7f01fd), + SPH_C32(0x10b03c48), SPH_C32(0xe028cda2), SPH_C32(0xa2da90c1), + SPH_C32(0xc189d088) }, + { SPH_C32(0xf20b0000), SPH_C32(0x0d040000), SPH_C32(0xb7d00000), + SPH_C32(0xa2c3015f), SPH_C32(0x0f2f92bd), SPH_C32(0x7ee86792), + SPH_C32(0x16e6c2f0), SPH_C32(0xc36aa231), SPH_C32(0xb3950000), + SPH_C32(0x6f350000), SPH_C32(0xcfae0000), SPH_C32(0xbaa501ff), + SPH_C32(0x6dd6a9cb), SPH_C32(0xffb0bd28), SPH_C32(0x19bc18c9), + SPH_C32(0x1b0e5088) } +}; + +#define INPUT_BIG do { \ + unsigned acc = buf[0]; \ + const sph_u32 *rp; \ + rp = &T512_0[acc][0]; \ + m0 = rp[0]; \ + m1 = rp[1]; \ + m2 = rp[2]; \ + m3 = rp[3]; \ + m4 = rp[4]; \ + m5 = rp[5]; \ + m6 = rp[6]; \ + m7 = rp[7]; \ + m8 = rp[8]; \ + m9 = rp[9]; \ + mA = rp[10]; \ + mB = rp[11]; \ + mC = rp[12]; \ + mD = rp[13]; \ + mE = rp[14]; \ + mF = rp[15]; \ + acc = buf[1]; \ + rp = &T512_8[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[2]; \ + rp = &T512_16[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[3]; \ + rp = &T512_24[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[4]; \ + rp = &T512_32[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[5]; \ + rp = &T512_40[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[6]; \ + rp = &T512_48[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + acc = buf[7]; \ + rp = &T512_56[acc][0]; \ + m0 ^= rp[0]; \ + m1 ^= rp[1]; \ + m2 ^= rp[2]; \ + m3 ^= rp[3]; \ + m4 ^= rp[4]; \ + m5 ^= rp[5]; \ + m6 ^= rp[6]; \ + m7 ^= rp[7]; \ + m8 ^= rp[8]; \ + m9 ^= rp[9]; \ + mA ^= rp[10]; \ + mB ^= rp[11]; \ + mC ^= rp[12]; \ + mD ^= rp[13]; \ + mE ^= rp[14]; \ + mF ^= rp[15]; \ + } while (0) + +#endif + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/hashblock.h b/src/hashblock.h new file mode 100644 index 0000000..f5164f3 --- /dev/null +++ b/src/hashblock.h @@ -0,0 +1,160 @@ +#ifndef HASHBLOCK_H +#define HASHBLOCK_H + +#include "uint256.h" +#include "sph_blake.h" +#include "sph_bmw.h" +#include "sph_groestl.h" +#include "sph_jh.h" +#include "sph_keccak.h" +#include "sph_skein.h" +#include "sph_luffa.h" +#include "sph_cubehash.h" +#include "sph_shavite.h" +#include "sph_simd.h" +#include "sph_echo.h" +#include "sph_hamsi.h" +#include "sph_fugue.h" +#include "sph_shabal.h" + +#ifndef QT_NO_DEBUG +#include +#endif + +#ifdef GLOBALDEFINED +#define GLOBAL +#else +#define GLOBAL extern +#endif + +GLOBAL sph_blake512_context z_blake; +GLOBAL sph_bmw512_context z_bmw; +GLOBAL sph_groestl512_context z_groestl; +GLOBAL sph_jh512_context z_jh; +GLOBAL sph_keccak512_context z_keccak; +GLOBAL sph_skein512_context z_skein; +GLOBAL sph_luffa512_context z_luffa; +GLOBAL sph_cubehash512_context z_cubehash; +GLOBAL sph_shavite512_context z_shavite; +GLOBAL sph_simd512_context z_simd; +GLOBAL sph_echo512_context z_echo; +GLOBAL sph_hamsi512_context z_hamsi; +GLOBAL sph_fugue512_context z_fugue; +GLOBAL sph_shabal512_context z_shabal; + +#define fillz() do { \ + sph_blake512_init(&z_blake); \ + sph_bmw512_init(&z_bmw); \ + sph_groestl512_init(&z_groestl); \ + sph_jh512_init(&z_jh); \ + sph_keccak512_init(&z_keccak); \ + sph_skein512_init(&z_skein); \ + sph_luffa512_init(&z_luffa); \ + sph_cubehash512_init(&z_cubehash); \ + sph_shavite512_init(&z_shavite); \ + sph_simd512_init(&z_simd); \ + sph_echo512_init(&z_echo); \ + sph_hamsi512_init(&z_hamsi); \ + sph_fugue512_init(&z_fugue); \ + sph_shabal512_init(&z_shabal); \ +} while (0) + + +#define ZBLAKE (memcpy(&ctx_blake, &z_blake, sizeof(z_blake))) +#define ZBMW (memcpy(&ctx_bmw, &z_bmw, sizeof(z_bmw))) +#define ZGROESTL (memcpy(&ctx_groestl, &z_groestl, sizeof(z_groestl))) +#define ZJH (memcpy(&ctx_jh, &z_jh, sizeof(z_jh))) +#define ZKECCAK (memcpy(&ctx_keccak, &z_keccak, sizeof(z_keccak))) +#define ZSKEIN (memcpy(&ctx_skein, &z_skein, sizeof(z_skein))) +#define ZHAMSI (memcpy(&ctx_hamsi, &z_hamsi, sizeof(z_hamsi))) +#define ZFUGUE (memcpy(&ctx_fugue, &z_fugue, sizeof(z_fugue))) +#define ZSHABAL (memcpy(&ctx_shabal, &z_shabal, sizeof(z_shabal))) + +template +inline uint256 Hash9(const T1 pbegin, const T1 pend) + +{ + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_skein512_context ctx_skein; + sph_luffa512_context ctx_luffa; + sph_cubehash512_context ctx_cubehash; + sph_shavite512_context ctx_shavite; + sph_simd512_context ctx_simd; + sph_echo512_context ctx_echo; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; +static unsigned char pblank[1]; + +#ifndef QT_NO_DEBUG + //std::string strhash; + //strhash = ""; +#endif + + uint512 hash[17]; + + sph_blake512_init(&ctx_blake); + sph_blake512 (&ctx_blake, (pbegin == pend ? pblank : static_cast(&pbegin[0])), (pend - pbegin) * sizeof(pbegin[0])); + sph_blake512_close(&ctx_blake, static_cast(&hash[0])); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512 (&ctx_bmw, static_cast(&hash[0]), 64); + sph_bmw512_close(&ctx_bmw, static_cast(&hash[1])); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512 (&ctx_groestl, static_cast(&hash[1]), 64); + sph_groestl512_close(&ctx_groestl, static_cast(&hash[2])); + + sph_skein512_init(&ctx_skein); + sph_skein512 (&ctx_skein, static_cast(&hash[2]), 64); + sph_skein512_close(&ctx_skein, static_cast(&hash[3])); + + sph_jh512_init(&ctx_jh); + sph_jh512 (&ctx_jh, static_cast(&hash[3]), 64); + sph_jh512_close(&ctx_jh, static_cast(&hash[4])); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512 (&ctx_keccak, static_cast(&hash[4]), 64); + sph_keccak512_close(&ctx_keccak, static_cast(&hash[5])); + + sph_luffa512_init(&ctx_luffa); + sph_luffa512 (&ctx_luffa, static_cast(&hash[5]), 64); + sph_luffa512_close(&ctx_luffa, static_cast(&hash[6])); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512 (&ctx_cubehash, static_cast(&hash[6]), 64); + sph_cubehash512_close(&ctx_cubehash, static_cast(&hash[7])); + + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, static_cast(&hash[7]), 64); + sph_shavite512_close(&ctx_shavite, static_cast(&hash[8])); + + sph_simd512_init(&ctx_simd); + sph_simd512 (&ctx_simd, static_cast(&hash[8]), 64); + sph_simd512_close(&ctx_simd, static_cast(&hash[9])); + + sph_echo512_init(&ctx_echo); + sph_echo512 (&ctx_echo, static_cast(&hash[9]), 64); + sph_echo512_close(&ctx_echo, static_cast(&hash[10])); + + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512 (&ctx_hamsi, static_cast(&hash[10]), 64); + sph_hamsi512_close(&ctx_hamsi, static_cast(&hash[11])); + + sph_fugue512_init(&ctx_fugue); + sph_fugue512 (&ctx_fugue, static_cast(&hash[11]), 64); + sph_fugue512_close(&ctx_fugue, static_cast(&hash[12])); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512 (&ctx_shabal, static_cast(&hash[12]), 64); + sph_shabal512_close(&ctx_shabal, static_cast(&hash[13])); + + + return hash[13].trim256(); +} + +#endif // HASHBLOCK_H diff --git a/src/init.cpp b/src/init.cpp new file mode 100644 index 0000000..e18ac25 --- /dev/null +++ b/src/init.cpp @@ -0,0 +1,881 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "db.h" +#include "walletdb.h" +#include "bitcoinrpc.h" +#include "net.h" +#include "init.h" +#include "util.h" +#include "ui_interface.h" +#include "checkpoints.h" +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +using namespace std; +using namespace boost; + +CWallet* pwalletMain; +CClientUIInterface uiInterface; + +////////////////////////////////////////////////////////////////////////////// +// +// Shutdown +// + +void ExitTimeout(void* parg) +{ +#ifdef WIN32 + Sleep(5000); + ExitProcess(0); +#endif +} + +void StartShutdown() +{ +#ifdef QT_GUI + // ensure we leave the Qt main loop for a clean GUI exit (Shutdown() is called in bitcoin.cpp afterwards) + uiInterface.QueueShutdown(); +#else + // Without UI, Shutdown() can simply be started in a new thread + NewThread(Shutdown, NULL); +#endif +} + +void Shutdown(void* parg) +{ + static CCriticalSection cs_Shutdown; + static bool fTaken; + + // Make this thread recognisable as the shutdown thread + RenameThread("bitcoin-shutoff"); + + bool fFirstThread = false; + { + TRY_LOCK(cs_Shutdown, lockShutdown); + if (lockShutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + } + static bool fExit; + if (fFirstThread) + { + fShutdown = true; + nTransactionsUpdated++; + bitdb.Flush(false); + StopNode(); + bitdb.Flush(true); + boost::filesystem::remove(GetPidFile()); + UnregisterWallet(pwalletMain); + delete pwalletMain; + NewThread(ExitTimeout, NULL); + Sleep(50); + printf("BERN exited\n\n"); + fExit = true; +#ifndef QT_GUI + // ensure non-UI client gets exited here, but let Bitcoin-Qt reach 'return 0;' in bitcoin.cpp + exit(0); +#endif + } + else + { + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); + } +} + +void HandleSIGTERM(int) +{ + fRequestShutdown = true; +} + +void HandleSIGHUP(int) +{ + fReopenDebugLog = true; +} + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Start +// +#if !defined(QT_GUI) +bool AppInit(int argc, char* argv[]) +{ + bool fRet = false; + try + { + // + // Parameters + // + // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() + ParseParameters(argc, argv); + if (!boost::filesystem::is_directory(GetDataDir(false))) + { + fprintf(stderr, "Error: Specified directory does not exist\n"); + Shutdown(NULL); + } + ReadConfigFile(mapArgs, mapMultiArgs); + + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + // First part of help message is specific to bitcoind / RPC client + std::string strUsage = _("BERN version") + " " + FormatFullVersion() + "\n\n" + + _("Usage:") + "\n" + + " BERNd [options] " + "\n" + + " BERNd [options] [params] " + _("Send command to -server or BERNd") + "\n" + + " BERNd [options] help " + _("List commands") + "\n" + + " BERNd [options] help " + _("Get help for a command") + "\n"; + + strUsage += "\n" + HelpMessage(); + + fprintf(stdout, "%s", strUsage.c_str()); + return false; + } + + // Command-line RPC + for (int i = 1; i < argc; i++) + if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "BERN:")) + fCommandLine = true; + + if (fCommandLine) + { + int ret = CommandLineRPC(argc, argv); + exit(ret); + } + + fRet = AppInit2(); + } + catch (std::exception& e) { + PrintException(&e, "AppInit()"); + } catch (...) { + PrintException(NULL, "AppInit()"); + } + if (!fRet) + Shutdown(NULL); + return fRet; +} + +extern void noui_connect(); +int main(int argc, char* argv[]) +{ + bool fRet = false; + + // Connect bitcoind signal handlers + noui_connect(); + + fRet = AppInit(argc, argv); + + if (fRet && fDaemon) + return 0; + + return 1; +} +#endif + +bool static InitError(const std::string &str) +{ + uiInterface.ThreadSafeMessageBox(str, _("BERN"), CClientUIInterface::OK | CClientUIInterface::MODAL); + return false; +} + +bool static InitWarning(const std::string &str) +{ + uiInterface.ThreadSafeMessageBox(str, _("BERN"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + return true; +} + + +bool static Bind(const CService &addr, bool fError = true) { + if (IsLimited(addr)) + return false; + std::string strError; + if (!BindListenPort(addr, strError)) { + if (fError) + return InitError(strError); + return false; + } + return true; +} + +// Core-specific options shared between UI and daemon +std::string HelpMessage() +{ + string strUsage = _("Options:") + "\n" + + " -? " + _("This help message") + "\n" + + " -conf= " + _("Specify configuration file (default: BERN.conf)") + "\n" + + " -pid= " + _("Specify pid file (default: BERNd.pid)") + "\n" + + " -gen " + _("Generate coins") + "\n" + + " -gen=0 " + _("Don't generate coins") + "\n" + + " -datadir= " + _("Specify data directory") + "\n" + + " -dbcache= " + _("Set database cache size in megabytes (default: 25)") + "\n" + + " -dblogsize= " + _("Set database disk log size in megabytes (default: 100)") + "\n" + + " -timeout= " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n" + + " -proxy= " + _("Connect through socks proxy") + "\n" + + " -socks= " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" + + " -tor= " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n" + " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" + + " -port= " + _("Listen for connections on (default: 20631 or testnet: 20630)") + "\n" + + " -maxconnections= " + _("Maintain at most connections to peers (default: 125)") + "\n" + + " -addnode= " + _("Add a node to connect to and attempt to keep the connection open") + "\n" + + " -connect= " + _("Connect only to the specified node(s)") + "\n" + + " -seednode= " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" + + " -externalip= " + _("Specify your own public address") + "\n" + + " -onlynet= " + _("Only connect to nodes in network (IPv4, IPv6 or Tor)") + "\n" + + " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n" + + " -irc " + _("Find peers using internet relay chat (default: 1)") + "\n" + + " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n" + + " -bind= " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" + + " -dnsseed " + _("Find peers using DNS lookup (default: 1)") + "\n" + + " -nosynccheckpoints " + _("Disable sync checkpoints (default: 0)") + "\n" + + " -banscore= " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" + + " -bantime= " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" + + " -maxreceivebuffer= " + _("Maximum per-connection receive buffer, *1000 bytes (default: 5000)") + "\n" + + " -maxsendbuffer= " + _("Maximum per-connection send buffer, *1000 bytes (default: 1000)") + "\n" + +#ifdef USE_UPNP +#if USE_UPNP + " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n" + +#else + " -upnp " + _("Use UPnP to map the listening port (default: 0)") + "\n" + +#endif +#endif + " -detachdb " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" + + " -paytxfee= " + _("Fee per KB to add to transactions you send") + "\n" + +#ifdef QT_GUI + " -server " + _("Accept command line and JSON-RPC commands") + "\n" + +#endif +#if !defined(WIN32) && !defined(QT_GUI) + " -daemon " + _("Run in the background as a daemon and accept commands") + "\n" + +#endif + " -testnet " + _("Use the test network") + "\n" + + " -debug " + _("Output extra debugging information. Implies all other -debug* options") + "\n" + + " -debugnet " + _("Output extra network debugging information") + "\n" + + " -logtimestamps " + _("Prepend debug output with timestamp") + "\n" + + " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n" + + " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n" + +#ifdef WIN32 + " -printtodebugger " + _("Send trace/debug info to debugger") + "\n" + +#endif + " -rpcuser= " + _("Username for JSON-RPC connections") + "\n" + + " -rpcpassword= " + _("Password for JSON-RPC connections") + "\n" + + " -rpcport= " + _("Listen for JSON-RPC connections on (default: 20731 or testnet: 20730)") + "\n" + + " -rpcallowip= " + _("Allow JSON-RPC connections from specified IP address") + "\n" + + " -rpcconnect= " + _("Send commands to node running on (default: 127.0.0.1)") + "\n" + + " -blocknotify= " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" + + " -walletnotify= " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n" + + " -upgradewallet " + _("Upgrade wallet to latest format") + "\n" + + " -keypool= " + _("Set key pool size to (default: 100)") + "\n" + + " -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" + + " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + "\n" + + " -checkblocks= " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" + + " -checklevel= " + _("How thorough the block verification is (0-6, default: 1)") + "\n" + + " -loadblock= " + _("Imports blocks from external blk000?.dat file") + "\n" + + + "\n" + _("Block creation options:") + "\n" + + " -blockminsize= " + _("Set minimum block size in bytes (default: 0)") + "\n" + + " -blockmaxsize= " + _("Set maximum block size in bytes (default: 250000)") + "\n" + + " -blockprioritysize= " + _("Set maximum size of high-priority/low-fee transactions in bytes (default: 27000)") + "\n" + + + "\n" + _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" + + " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n" + + " -rpcsslcertificatechainfile= " + _("Server certificate file (default: server.cert)") + "\n" + + " -rpcsslprivatekeyfile= " + _("Server private key (default: server.pem)") + "\n" + + " -rpcsslciphers= " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n"; + + return strUsage; +} + +/** Initialize bitcoin. + * @pre Parameters should be parsed and config file should be read. + */ +bool AppInit2() +{ + // ********************************************************* Step 1: setup +#ifdef _MSC_VER + // Turn off Microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif +#if _MSC_VER >= 1400 + // Disable confusing "helpful" text message on abort, Ctrl-C + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +#endif +#ifdef WIN32 + // Enable Data Execution Prevention (DEP) + // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008 + // A failure is non-critical and needs no further attention! +#ifndef PROCESS_DEP_ENABLE +// We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7), +// which is not correct. Can be removed, when GCCs winbase.h is fixed! +#define PROCESS_DEP_ENABLE 0x00000001 +#endif + typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD); + PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); + if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); +#endif +#ifndef WIN32 + umask(077); + + // Clean shutdown on SIGTERM + struct sigaction sa; + sa.sa_handler = HandleSIGTERM; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + // Reopen debug.log on SIGHUP + struct sigaction sa_hup; + sa_hup.sa_handler = HandleSIGHUP; + sigemptyset(&sa_hup.sa_mask); + sa_hup.sa_flags = 0; + sigaction(SIGHUP, &sa_hup, NULL); +#endif + + // ********************************************************* Step 2: parameter interactions + + fTestNet = GetBoolArg("-testnet"); + if (fTestNet) { + SoftSetBoolArg("-irc", true); + } + + if (mapArgs.count("-bind")) { + // when specifying an explicit binding address, you want to listen on it + // even when -connect or -proxy is specified + SoftSetBoolArg("-listen", true); + } + + if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { + // when only connecting to trusted nodes, do not seed via DNS, or listen by default + SoftSetBoolArg("-dnsseed", false); + SoftSetBoolArg("-listen", false); + } + + if (mapArgs.count("-proxy")) { + // to protect privacy, do not listen by default if a proxy server is specified + SoftSetBoolArg("-listen", false); + } + + if (!GetBoolArg("-listen", true)) { + // do not map ports or try to retrieve public IP when not listening (pointless) + SoftSetBoolArg("-upnp", false); + SoftSetBoolArg("-discover", false); + } + + if (mapArgs.count("-externalip")) { + // if an explicit public IP is specified, do not try to find others + SoftSetBoolArg("-discover", false); + } + + if (GetBoolArg("-salvagewallet")) { + // Rewrite just private keys: rescan to find transactions + SoftSetBoolArg("-rescan", true); + } + + // ********************************************************* Step 3: parameter-to-internal-flags + + fDebug = GetBoolArg("-debug"); + + // -debug implies fDebug* + if (fDebug) + fDebugNet = true; + else + fDebugNet = GetBoolArg("-debugnet"); + + fStaking = GetBoolArg("-staking", true); + + bitdb.SetDetach(GetBoolArg("-detachdb", false)); + +#if !defined(WIN32) && !defined(QT_GUI) + fDaemon = GetBoolArg("-daemon"); +#else + fDaemon = false; +#endif + + if (fDaemon) + fServer = true; + else + fServer = GetBoolArg("-server"); + + /* force fServer when running without GUI */ +#if !defined(QT_GUI) + fServer = true; +#endif + fPrintToConsole = GetBoolArg("-printtoconsole"); + fPrintToDebugger = GetBoolArg("-printtodebugger"); + fLogTimestamps = GetBoolArg("-logtimestamps"); + + if (mapArgs.count("-timeout")) + { + int nNewTimeout = GetArg("-timeout", 5000); + if (nNewTimeout > 0 && nNewTimeout < 600000) + nConnectTimeout = nNewTimeout; + } + + // Continue to put "/P2SH/" in the coinbase to monitor + // BIP16 support. + // This can be removed eventually... + const char* pszP2SH = "/P2SH/"; + COINBASE_FLAGS << std::vector(pszP2SH, pszP2SH+strlen(pszP2SH)); + + + if (mapArgs.count("-paytxfee")) + { + if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee)) + return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s'"), mapArgs["-paytxfee"].c_str())); + if (nTransactionFee > 0.25 * COIN) + InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); + } + + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log + + std::string strDataDir = GetDataDir().string(); + + // Make sure only a single Bitcoin process is using the data directory. + boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; + FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. + if (file) fclose(file); + static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); + if (!lock.try_lock()) + return InitError(strprintf(_("Cannot obtain a lock on data directory %s. BERN is probably already running."), strDataDir.c_str())); + +#if !defined(WIN32) && !defined(QT_GUI) + if (fDaemon) + { + // Daemonize + pid_t pid = fork(); + if (pid < 0) + { + fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); + return false; + } + if (pid > 0) + { + CreatePidFile(GetPidFile(), pid); + return true; + } + + pid_t sid = setsid(); + if (sid < 0) + fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); + } +#endif + + if (GetBoolArg("-shrinkdebugfile", !fDebug)) + ShrinkDebugFile(); + printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + printf("BERN version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str()); + printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); + if (!fLogTimestamps) + printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("Default data directory %s\n", GetDefaultDataDir().string().c_str()); + printf("Used data directory %s\n", strDataDir.c_str()); + std::ostringstream strErrors; + + if (fDaemon) + fprintf(stdout, "BERN server starting\n"); + + int64 nStart; + + // ********************************************************* Step 5: verify database integrity + + uiInterface.InitMessage(_("Verifying database integrity...")); + + if (!bitdb.Open(GetDataDir())) + { + string msg = strprintf(_("Error initializing database environment %s!" + " To recover, BACKUP THAT DIRECTORY, then remove" + " everything from it except for wallet.dat."), strDataDir.c_str()); + return InitError(msg); + } + + if (GetBoolArg("-salvagewallet")) + { + // Recover readable keypairs: + if (!CWalletDB::Recover(bitdb, "wallet.dat", true)) + return false; + } + + if (filesystem::exists(GetDataDir() / "wallet.dat")) + { + CDBEnv::VerifyResult r = bitdb.Verify("wallet.dat", CWalletDB::Recover); + if (r == CDBEnv::RECOVER_OK) + { + string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!" + " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" + " your balance or transactions are incorrect you should" + " restore from a backup."), strDataDir.c_str()); + uiInterface.ThreadSafeMessageBox(msg, _("BERN"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + } + if (r == CDBEnv::RECOVER_FAIL) + return InitError(_("wallet.dat corrupt, salvage failed")); + } + + // ********************************************************* Step 6: network initialization + + int nSocksVersion = GetArg("-socks", 5); + + if (nSocksVersion != 4 && nSocksVersion != 5) + return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion)); + + if (mapArgs.count("-onlynet")) { + std::set nets; + BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) { + enum Network net = ParseNetwork(snet); + if (net == NET_UNROUTABLE) + return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str())); + nets.insert(net); + } + for (int n = 0; n < NET_MAX; n++) { + enum Network net = (enum Network)n; + if (!nets.count(net)) + SetLimited(net); + } + } +#if defined(USE_IPV6) +#if ! USE_IPV6 + else + SetLimited(NET_IPV6); +#endif +#endif + + CService addrProxy; + bool fProxy = false; + if (mapArgs.count("-proxy")) { + addrProxy = CService(mapArgs["-proxy"], 9050); + if (!addrProxy.IsValid()) + return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str())); + + if (!IsLimited(NET_IPV4)) + SetProxy(NET_IPV4, addrProxy, nSocksVersion); + if (nSocksVersion > 4) { +#ifdef USE_IPV6 + if (!IsLimited(NET_IPV6)) + SetProxy(NET_IPV6, addrProxy, nSocksVersion); +#endif + SetNameProxy(addrProxy, nSocksVersion); + } + fProxy = true; + } + + // -tor can override normal proxy, -notor disables tor entirely + if (!(mapArgs.count("-tor") && mapArgs["-tor"] == "0") && (fProxy || mapArgs.count("-tor"))) { + CService addrOnion; + if (!mapArgs.count("-tor")) + addrOnion = addrProxy; + else + addrOnion = CService(mapArgs["-tor"], 9050); + if (!addrOnion.IsValid()) + return InitError(strprintf(_("Invalid -tor address: '%s'"), mapArgs["-tor"].c_str())); + SetProxy(NET_TOR, addrOnion, 5); + SetReachable(NET_TOR); + } + + // see Step 2: parameter interactions for more information about these + fNoListen = !GetBoolArg("-listen", true); + fDiscover = GetBoolArg("-discover", true); + fNameLookup = GetBoolArg("-dns", true); +#ifdef USE_UPNP + fUseUPnP = GetBoolArg("-upnp", USE_UPNP); +#endif + + bool fBound = false; + if (!fNoListen) + { + std::string strError; + if (mapArgs.count("-bind")) { + BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) { + CService addrBind; + if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) + return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str())); + fBound |= Bind(addrBind); + } + } else { + struct in_addr inaddr_any; + inaddr_any.s_addr = INADDR_ANY; +#ifdef USE_IPV6 + if (!IsLimited(NET_IPV6)) + fBound |= Bind(CService(in6addr_any, GetListenPort()), false); +#endif + if (!IsLimited(NET_IPV4)) + fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound); + } + if (!fBound) + return InitError(_("Failed to listen on any port. Use -listen=0 if you want this.")); + } + + if (mapArgs.count("-externalip")) + { + BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) { + CService addrLocal(strAddr, GetListenPort(), fNameLookup); + if (!addrLocal.IsValid()) + return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str())); + AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); + } + } + + if (mapArgs.count("-reservebalance")) // ppcoin: reserve balance amount + { + int64 nReserveBalance = 0; + if (!ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) + { + InitError(_("Invalid amount for -reservebalance=")); + return false; + } + } + + if (mapArgs.count("-checkpointkey")) // ppcoin: checkpoint master priv key + { + if (!Checkpoints::SetCheckpointPrivKey(GetArg("-checkpointkey", ""))) + InitError(_("Unable to sign checkpoint, wrong checkpointkey?\n")); + } + + BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) + AddOneShot(strDest); + + // TODO: replace this by DNSseed + // AddOneShot(string("")); + + // ********************************************************* Step 7: load blockchain + + if (!bitdb.Open(GetDataDir())) + { + string msg = strprintf(_("Error initializing database environment %s!" + " To recover, BACKUP THAT DIRECTORY, then remove" + " everything from it except for wallet.dat."), strDataDir.c_str()); + return InitError(msg); + } + + if (GetBoolArg("-loadblockindextest")) + { + CTxDB txdb("r"); + txdb.LoadBlockIndex(); + PrintBlockTree(); + return false; + } + + uiInterface.InitMessage(_("Loading block index...")); + printf("Loading block index...\n"); + nStart = GetTimeMillis(); + if (!LoadBlockIndex()) + return InitError(_("Error loading blkindex.dat")); + + // as LoadBlockIndex can take several minutes, it's possible the user + // requested to kill bitcoin-qt during the last operation. If so, exit. + // As the program has not fully started yet, Shutdown() is possibly overkill. + if (fRequestShutdown) + { + printf("Shutdown requested. Exiting.\n"); + return false; + } + printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree")) + { + PrintBlockTree(); + return false; + } + + if (mapArgs.count("-printblock")) + { + string strMatch = mapArgs["-printblock"]; + int nFound = 0; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + uint256 hash = (*mi).first; + if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) + { + CBlockIndex* pindex = (*mi).second; + CBlock block; + block.ReadFromDisk(pindex); + block.BuildMerkleTree(); + block.print(); + printf("\n"); + nFound++; + } + } + if (nFound == 0) + printf("No blocks matching %s were found\n", strMatch.c_str()); + return false; + } + + // ********************************************************* Step 8: load wallet + + uiInterface.InitMessage(_("Loading wallet...")); + printf("Loading wallet...\n"); + nStart = GetTimeMillis(); + bool fFirstRun = true; + pwalletMain = new CWallet("wallet.dat"); + DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun); + if (nLoadWalletRet != DB_LOAD_OK) + { + if (nLoadWalletRet == DB_CORRUPT) + strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n"; + else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) + { + string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data" + " or address book entries might be missing or incorrect.")); + uiInterface.ThreadSafeMessageBox(msg, _("BERN"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + } + else if (nLoadWalletRet == DB_TOO_NEW) + strErrors << _("Error loading wallet.dat: Wallet requires newer version of BERN") << "\n"; + else if (nLoadWalletRet == DB_NEED_REWRITE) + { + strErrors << _("Wallet needed to be rewritten: restart BERN to complete") << "\n"; + printf("%s", strErrors.str().c_str()); + return InitError(strErrors.str()); + } + else + strErrors << _("Error loading wallet.dat") << "\n"; + } + + if (GetBoolArg("-upgradewallet", fFirstRun)) + { + int nMaxVersion = GetArg("-upgradewallet", 0); + if (nMaxVersion == 0) // the -upgradewallet without argument case + { + printf("Performing wallet upgrade to %i\n", FEATURE_LATEST); + nMaxVersion = CLIENT_VERSION; + pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately + } + else + printf("Allowing wallet upgrade up to %i\n", nMaxVersion); + if (nMaxVersion < pwalletMain->GetVersion()) + strErrors << _("Cannot downgrade wallet") << "\n"; + pwalletMain->SetMaxVersion(nMaxVersion); + } + + if (fFirstRun) + { + // Create new keyUser and set as default key + RandAddSeedPerfmon(); + + CPubKey newDefaultKey; + if (!pwalletMain->GetKeyFromPool(newDefaultKey, false)) + strErrors << _("Cannot initialize keypool") << "\n"; + pwalletMain->SetDefaultKey(newDefaultKey); + if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), "")) + strErrors << _("Cannot write default address") << "\n"; + } + + printf("%s", strErrors.str().c_str()); + printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + RegisterWallet(pwalletMain); + + CBlockIndex *pindexRescan = pindexBest; + if (GetBoolArg("-rescan")) + pindexRescan = pindexGenesisBlock; + else + { + CWalletDB walletdb("wallet.dat"); + CBlockLocator locator; + if (walletdb.ReadBestBlock(locator)) + pindexRescan = locator.GetBlockIndex(); + } + if (pindexBest != pindexRescan && pindexBest && pindexRescan && pindexBest->nHeight > pindexRescan->nHeight) + { + uiInterface.InitMessage(_("Rescanning...")); + printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight); + nStart = GetTimeMillis(); + pwalletMain->ScanForWalletTransactions(pindexRescan, true); + printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart); + } + + // ********************************************************* Step 9: import blocks + + if (mapArgs.count("-loadblock")) + { + uiInterface.InitMessage(_("Importing blockchain data file.")); + + BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"]) + { + FILE *file = fopen(strFile.c_str(), "rb"); + if (file) + LoadExternalBlockFile(file); + } + } + + filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat"; + if (filesystem::exists(pathBootstrap)) { + uiInterface.InitMessage(_("Importing bootstrap blockchain data file.")); + + FILE *file = fopen(pathBootstrap.string().c_str(), "rb"); + if (file) { + filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; + LoadExternalBlockFile(file); + RenameOver(pathBootstrap, pathBootstrapOld); + } + } + + // ********************************************************* Step 10: load peers + + uiInterface.InitMessage(_("Loading addresses...")); + printf("Loading addresses...\n"); + nStart = GetTimeMillis(); + + { + CAddrDB adb; + if (!adb.Read(addrman)) + printf("Invalid or missing peers.dat; recreating\n"); + } + + printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n", + addrman.size(), GetTimeMillis() - nStart); + + // ********************************************************* Step 11: start node + + if (!CheckDiskSpace()) + return false; + + RandAddSeedPerfmon(); + + //// debug print + printf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size()); + printf("nBestHeight = %d\n", nBestHeight); + printf("setKeyPool.size() = %"PRIszu"\n", pwalletMain->setKeyPool.size()); + printf("mapWallet.size() = %"PRIszu"\n", pwalletMain->mapWallet.size()); + printf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain->mapAddressBook.size()); + + if (!NewThread(StartNode, NULL)) + InitError(_("Error: could not start node")); + + if (fServer) + NewThread(ThreadRPCServer, NULL); + + // ********************************************************* Step 12: finished + + uiInterface.InitMessage(_("Done loading")); + printf("Done loading\n"); + + if (!strErrors.str().empty()) + return InitError(strErrors.str()); + + // Add wallet transactions that aren't already in a block to mapTransactions + pwalletMain->ReacceptWalletTransactions(); + +#if !defined(QT_GUI) + // Loop until process is exit()ed from shutdown() function, + // called from ThreadRPCServer thread when a "stop" command is received. + while (1) + Sleep(5000); +#endif + + return true; +} diff --git a/src/init.h b/src/init.h new file mode 100644 index 0000000..8308ee6 --- /dev/null +++ b/src/init.h @@ -0,0 +1,17 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_INIT_H +#define BITCOIN_INIT_H + +#include "wallet.h" + +extern CWallet* pwalletMain; + +void StartShutdown(); +void Shutdown(void* parg); +bool AppInit2(); +std::string HelpMessage(); + +#endif diff --git a/src/irc.cpp b/src/irc.cpp new file mode 100644 index 0000000..94d1554 --- /dev/null +++ b/src/irc.cpp @@ -0,0 +1,405 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "irc.h" +#include "net.h" +#include "strlcpy.h" +#include "base58.h" + +using namespace std; +using namespace boost; + +int nGotIRCAddresses = 0; + +void ThreadIRCSeed2(void* parg); + + + + +#pragma pack(push, 1) +struct ircaddr +{ + struct in_addr ip; + short port; +}; +#pragma pack(pop) + +string EncodeAddress(const CService& addr) +{ + struct ircaddr tmp; + if (addr.GetInAddr(&tmp.ip)) + { + tmp.port = htons(addr.GetPort()); + + vector vch(UBEGIN(tmp), UEND(tmp)); + return string("u") + EncodeBase58Check(vch); + } + return ""; +} + +bool DecodeAddress(string str, CService& addr) +{ + vector vch; + if (!DecodeBase58Check(str.substr(1), vch)) + return false; + + struct ircaddr tmp; + if (vch.size() != sizeof(tmp)) + return false; + memcpy(&tmp, &vch[0], sizeof(tmp)); + + addr = CService(tmp.ip, ntohs(tmp.port)); + return true; +} + + + + + + +static bool Send(SOCKET hSocket, const char* pszSend) +{ + if (strstr(pszSend, "PONG") != pszSend) + printf("IRC SENDING: %s\n", pszSend); + const char* psz = pszSend; + const char* pszEnd = psz + strlen(psz); + while (psz < pszEnd) + { + int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL); + if (ret < 0) + return false; + psz += ret; + } + return true; +} + +bool RecvLineIRC(SOCKET hSocket, string& strLine) +{ + while (true) + { + bool fRet = RecvLine(hSocket, strLine); + if (fRet) + { + if (fShutdown) + return false; + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() >= 1 && vWords[0] == "PING") + { + strLine[1] = 'O'; + strLine += '\r'; + Send(hSocket, strLine.c_str()); + continue; + } + } + return fRet; + } +} + +int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL, const char* psz4=NULL) +{ + while(true) + { + string strLine; + strLine.reserve(10000); + if (!RecvLineIRC(hSocket, strLine)) + return 0; + printf("IRC %s\n", strLine.c_str()); + if (psz1 && strLine.find(psz1) != string::npos) + return 1; + if (psz2 && strLine.find(psz2) != string::npos) + return 2; + if (psz3 && strLine.find(psz3) != string::npos) + return 3; + if (psz4 && strLine.find(psz4) != string::npos) + return 4; + } +} + +bool Wait(int nSeconds) +{ + if (fShutdown) + return false; + printf("IRC waiting %d seconds to reconnect\n", nSeconds); + for (int i = 0; i < nSeconds; i++) + { + if (fShutdown) + return false; + Sleep(1000); + } + return true; +} + +bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet) +{ + strRet.clear(); + while(true) + { + string strLine; + if (!RecvLineIRC(hSocket, strLine)) + return false; + + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() < 2) + continue; + + if (vWords[1] == psz1) + { + printf("IRC %s\n", strLine.c_str()); + strRet = strLine; + return true; + } + } +} + +bool GetIPFromIRC(SOCKET hSocket, string strMyName, CNetAddr& ipRet) +{ + Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str()); + + string strLine; + if (!RecvCodeLine(hSocket, "302", strLine)) + return false; + + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() < 4) + return false; + + string str = vWords[3]; + if (str.rfind("@") == string::npos) + return false; + string strHost = str.substr(str.rfind("@")+1); + + // Hybrid IRC used by lfnet always returns IP when you userhost yourself, + // but in case another IRC is ever used this should work. + printf("GetIPFromIRC() got userhost %s\n", strHost.c_str()); + CNetAddr addr(strHost, true); + if (!addr.IsValid()) + return false; + ipRet = addr; + + return true; +} + + + +void ThreadIRCSeed(void* parg) +{ + // Make this thread recognisable as the IRC seeding thread + RenameThread("bitcoin-ircseed"); + + try + { + ThreadIRCSeed2(parg); + } + catch (std::exception& e) { + PrintExceptionContinue(&e, "ThreadIRCSeed()"); + } catch (...) { + PrintExceptionContinue(NULL, "ThreadIRCSeed()"); + } + printf("ThreadIRCSeed exited\n"); +} + +void ThreadIRCSeed2(void* parg) +{ + // Don't connect to IRC if we won't use IPv4 connections. + if (IsLimited(NET_IPV4)) + return; + + // ... or if we won't make outbound connections and won't accept inbound ones. + if (mapArgs.count("-connect") && fNoListen) + return; + + // ... or if IRC is not enabled. + if (!GetBoolArg("-irc", true)) + return; + + printf("ThreadIRCSeed started\n"); + int nErrorWait = 10; + int nRetryWait = 10; + int nNameRetry = 0; + + while (!fShutdown) + { + CService addrConnect("92.243.23.21", 6667); // irc.lfnet.org + + CService addrIRC("irc.lfnet.org", 6667, true); + if (addrIRC.IsValid()) + addrConnect = addrIRC; + + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + { + printf("IRC connect failed\n"); + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname")) + { + closesocket(hSocket); + hSocket = INVALID_SOCKET; + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses + CService addrLocal; + string strMyName; + // Don't use our IP as our nick if we're not listening + // or if it keeps failing because the nick is already in use. + if (!fNoListen && GetLocal(addrLocal, &addrIPv4) && nNameRetry<3) + strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); + if (strMyName == "") + strMyName = strprintf("x%"PRI64u"", GetRand(1000000000)); + + Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); + Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); + + int nRet = RecvUntil(hSocket, " 004 ", " 433 "); + if (nRet != 1) + { + closesocket(hSocket); + hSocket = INVALID_SOCKET; + if (nRet == 2) + { + printf("IRC name already in use\n"); + nNameRetry++; + Wait(10); + continue; + } + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + nNameRetry = 0; + Sleep(500); + + // Get our external IP from the IRC server and re-nick before joining the channel + CNetAddr addrFromIRC; + if (GetIPFromIRC(hSocket, strMyName, addrFromIRC)) + { + printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str()); + // Don't use our IP as our nick if we're not listening + if (!fNoListen && addrFromIRC.IsRoutable()) + { + // IRC lets you to re-nick + AddLocal(addrFromIRC, LOCAL_IRC); + strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); + Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); + } + } + + if (fTestNet) { + Send(hSocket, "JOIN #BERNTEST\r"); + Send(hSocket, "WHO #BERNTEST\r"); + } else { + // randomly join #BERN00-#BERN05 + // int channel_number = GetRandInt(5); + + // Channel number is always 0 for initial release + int channel_number = 0; + Send(hSocket, strprintf("JOIN #BERN%02d\r", channel_number).c_str()); + Send(hSocket, strprintf("WHO #BERN%02d\r", channel_number).c_str()); + } + + int64 nStart = GetTime(); + string strLine; + strLine.reserve(10000); + while (!fShutdown && RecvLineIRC(hSocket, strLine)) + { + if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') + continue; + + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() < 2) + continue; + + char pszName[10000]; + pszName[0] = '\0'; + + if (vWords[1] == "352" && vWords.size() >= 8) + { + // index 7 is limited to 16 characters + // could get full length name at index 10, but would be different from join messages + strlcpy(pszName, vWords[7].c_str(), sizeof(pszName)); + printf("IRC got who\n"); + } + + if (vWords[1] == "JOIN" && vWords[0].size() > 1) + { + // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname + strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName)); + if (strchr(pszName, '!')) + *strchr(pszName, '!') = '\0'; + printf("IRC got join\n"); + } + + if (pszName[0] == 'u') + { + CAddress addr; + if (DecodeAddress(pszName, addr)) + { + addr.nTime = GetAdjustedTime(); + if (addrman.Add(addr, addrConnect, 51 * 60)) + printf("IRC got new address: %s\n", addr.ToString().c_str()); + nGotIRCAddresses++; + } + else + { + printf("IRC decode failed\n"); + } + } + } + closesocket(hSocket); + hSocket = INVALID_SOCKET; + + if (GetTime() - nStart > 20 * 60) + { + nErrorWait /= 3; + nRetryWait /= 3; + } + + nRetryWait = nRetryWait * 11 / 10; + if (!Wait(nRetryWait += 60)) + return; + } +} + + + + + + + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR) + { + printf("Error at WSAStartup()\n"); + return false; + } + + ThreadIRCSeed(NULL); + + WSACleanup(); + return 0; +} +#endif diff --git a/src/irc.h b/src/irc.h new file mode 100644 index 0000000..119aeb3 --- /dev/null +++ b/src/irc.h @@ -0,0 +1,12 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_IRC_H +#define BITCOIN_IRC_H + +void ThreadIRCSeed(void* parg); + +extern int nGotIRCAddresses; + +#endif diff --git a/src/jh.c b/src/jh.c new file mode 100644 index 0000000..41487a5 --- /dev/null +++ b/src/jh.c @@ -0,0 +1,1116 @@ +/* $Id: jh.c 255 2011-06-07 19:50:20Z tp $ */ +/* + * JH 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 + */ + +#include +#include + +#include "sph_jh.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_JH +#define SPH_SMALL_FOOTPRINT_JH 1 +#endif + +#if !defined SPH_JH_64 && SPH_64_TRUE +#define SPH_JH_64 1 +#endif + +#if !SPH_64 +#undef SPH_JH_64 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +/* + * The internal bitslice representation may use either big-endian or + * little-endian (true bitslice operations do not care about the bit + * ordering, and the bit-swapping linear operations in JH happen to + * be invariant through endianness-swapping). The constants must be + * defined according to the chosen endianness; we use some + * byte-swapping macros for that. + */ + +#if SPH_LITTLE_ENDIAN + +#define C32e(x) ((SPH_C32(x) >> 24) \ + | ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) \ + | ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) \ + | ((SPH_C32(x) << 24) & SPH_C32(0xFF000000))) +#define dec32e_aligned sph_dec32le_aligned +#define enc32e sph_enc32le + +#if SPH_64 +#define C64e(x) ((SPH_C64(x) >> 56) \ + | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \ + | ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) \ + | ((SPH_C64(x) >> 8) & SPH_C64(0x00000000FF000000)) \ + | ((SPH_C64(x) << 8) & SPH_C64(0x000000FF00000000)) \ + | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \ + | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \ + | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000))) +#define dec64e_aligned sph_dec64le_aligned +#define enc64e sph_enc64le +#endif + +#else + +#define C32e(x) SPH_C32(x) +#define dec32e_aligned sph_dec32be_aligned +#define enc32e sph_enc32be +#if SPH_64 +#define C64e(x) SPH_C64(x) +#define dec64e_aligned sph_dec64be_aligned +#define enc64e sph_enc64be +#endif + +#endif + +#define Sb(x0, x1, x2, x3, c) do { \ + x3 = ~x3; \ + x0 ^= (c) & ~x2; \ + tmp = (c) ^ (x0 & x1); \ + x0 ^= x2 & x3; \ + x3 ^= ~x1 & x2; \ + x1 ^= x0 & x2; \ + x2 ^= x0 & ~x3; \ + x0 ^= x1 | x3; \ + x3 ^= x1 & x2; \ + x1 ^= tmp & x0; \ + x2 ^= tmp; \ + } while (0) + +#define Lb(x0, x1, x2, x3, x4, x5, x6, x7) do { \ + x4 ^= x1; \ + x5 ^= x2; \ + x6 ^= x3 ^ x0; \ + x7 ^= x0; \ + x0 ^= x5; \ + x1 ^= x6; \ + x2 ^= x7 ^ x4; \ + x3 ^= x4; \ + } while (0) + +#if SPH_JH_64 + +static const sph_u64 C[] = { + C64e(0x72d5dea2df15f867), C64e(0x7b84150ab7231557), + C64e(0x81abd6904d5a87f6), C64e(0x4e9f4fc5c3d12b40), + C64e(0xea983ae05c45fa9c), C64e(0x03c5d29966b2999a), + C64e(0x660296b4f2bb538a), C64e(0xb556141a88dba231), + C64e(0x03a35a5c9a190edb), C64e(0x403fb20a87c14410), + C64e(0x1c051980849e951d), C64e(0x6f33ebad5ee7cddc), + C64e(0x10ba139202bf6b41), C64e(0xdc786515f7bb27d0), + C64e(0x0a2c813937aa7850), C64e(0x3f1abfd2410091d3), + C64e(0x422d5a0df6cc7e90), C64e(0xdd629f9c92c097ce), + C64e(0x185ca70bc72b44ac), C64e(0xd1df65d663c6fc23), + C64e(0x976e6c039ee0b81a), C64e(0x2105457e446ceca8), + C64e(0xeef103bb5d8e61fa), C64e(0xfd9697b294838197), + C64e(0x4a8e8537db03302f), C64e(0x2a678d2dfb9f6a95), + C64e(0x8afe7381f8b8696c), C64e(0x8ac77246c07f4214), + C64e(0xc5f4158fbdc75ec4), C64e(0x75446fa78f11bb80), + C64e(0x52de75b7aee488bc), C64e(0x82b8001e98a6a3f4), + C64e(0x8ef48f33a9a36315), C64e(0xaa5f5624d5b7f989), + C64e(0xb6f1ed207c5ae0fd), C64e(0x36cae95a06422c36), + C64e(0xce2935434efe983d), C64e(0x533af974739a4ba7), + C64e(0xd0f51f596f4e8186), C64e(0x0e9dad81afd85a9f), + C64e(0xa7050667ee34626a), C64e(0x8b0b28be6eb91727), + C64e(0x47740726c680103f), C64e(0xe0a07e6fc67e487b), + C64e(0x0d550aa54af8a4c0), C64e(0x91e3e79f978ef19e), + C64e(0x8676728150608dd4), C64e(0x7e9e5a41f3e5b062), + C64e(0xfc9f1fec4054207a), C64e(0xe3e41a00cef4c984), + C64e(0x4fd794f59dfa95d8), C64e(0x552e7e1124c354a5), + C64e(0x5bdf7228bdfe6e28), C64e(0x78f57fe20fa5c4b2), + C64e(0x05897cefee49d32e), C64e(0x447e9385eb28597f), + C64e(0x705f6937b324314a), C64e(0x5e8628f11dd6e465), + C64e(0xc71b770451b920e7), C64e(0x74fe43e823d4878a), + C64e(0x7d29e8a3927694f2), C64e(0xddcb7a099b30d9c1), + C64e(0x1d1b30fb5bdc1be0), C64e(0xda24494ff29c82bf), + C64e(0xa4e7ba31b470bfff), C64e(0x0d324405def8bc48), + C64e(0x3baefc3253bbd339), C64e(0x459fc3c1e0298ba0), + C64e(0xe5c905fdf7ae090f), C64e(0x947034124290f134), + C64e(0xa271b701e344ed95), C64e(0xe93b8e364f2f984a), + C64e(0x88401d63a06cf615), C64e(0x47c1444b8752afff), + C64e(0x7ebb4af1e20ac630), C64e(0x4670b6c5cc6e8ce6), + C64e(0xa4d5a456bd4fca00), C64e(0xda9d844bc83e18ae), + C64e(0x7357ce453064d1ad), C64e(0xe8a6ce68145c2567), + C64e(0xa3da8cf2cb0ee116), C64e(0x33e906589a94999a), + C64e(0x1f60b220c26f847b), C64e(0xd1ceac7fa0d18518), + C64e(0x32595ba18ddd19d3), C64e(0x509a1cc0aaa5b446), + C64e(0x9f3d6367e4046bba), C64e(0xf6ca19ab0b56ee7e), + C64e(0x1fb179eaa9282174), C64e(0xe9bdf7353b3651ee), + C64e(0x1d57ac5a7550d376), C64e(0x3a46c2fea37d7001), + C64e(0xf735c1af98a4d842), C64e(0x78edec209e6b6779), + C64e(0x41836315ea3adba8), C64e(0xfac33b4d32832c83), + C64e(0xa7403b1f1c2747f3), C64e(0x5940f034b72d769a), + C64e(0xe73e4e6cd2214ffd), C64e(0xb8fd8d39dc5759ef), + C64e(0x8d9b0c492b49ebda), C64e(0x5ba2d74968f3700d), + C64e(0x7d3baed07a8d5584), C64e(0xf5a5e9f0e4f88e65), + C64e(0xa0b8a2f436103b53), C64e(0x0ca8079e753eec5a), + C64e(0x9168949256e8884f), C64e(0x5bb05c55f8babc4c), + C64e(0xe3bb3b99f387947b), C64e(0x75daf4d6726b1c5d), + C64e(0x64aeac28dc34b36d), C64e(0x6c34a550b828db71), + C64e(0xf861e2f2108d512a), C64e(0xe3db643359dd75fc), + C64e(0x1cacbcf143ce3fa2), C64e(0x67bbd13c02e843b0), + C64e(0x330a5bca8829a175), C64e(0x7f34194db416535c), + C64e(0x923b94c30e794d1e), C64e(0x797475d7b6eeaf3f), + C64e(0xeaa8d4f7be1a3921), C64e(0x5cf47e094c232751), + C64e(0x26a32453ba323cd2), C64e(0x44a3174a6da6d5ad), + C64e(0xb51d3ea6aff2c908), C64e(0x83593d98916b3c56), + C64e(0x4cf87ca17286604d), C64e(0x46e23ecc086ec7f6), + C64e(0x2f9833b3b1bc765e), C64e(0x2bd666a5efc4e62a), + C64e(0x06f4b6e8bec1d436), C64e(0x74ee8215bcef2163), + C64e(0xfdc14e0df453c969), C64e(0xa77d5ac406585826), + C64e(0x7ec1141606e0fa16), C64e(0x7e90af3d28639d3f), + C64e(0xd2c9f2e3009bd20c), C64e(0x5faace30b7d40c30), + C64e(0x742a5116f2e03298), C64e(0x0deb30d8e3cef89a), + C64e(0x4bc59e7bb5f17992), C64e(0xff51e66e048668d3), + C64e(0x9b234d57e6966731), C64e(0xcce6a6f3170a7505), + C64e(0xb17681d913326cce), C64e(0x3c175284f805a262), + C64e(0xf42bcbb378471547), C64e(0xff46548223936a48), + C64e(0x38df58074e5e6565), C64e(0xf2fc7c89fc86508e), + C64e(0x31702e44d00bca86), C64e(0xf04009a23078474e), + C64e(0x65a0ee39d1f73883), C64e(0xf75ee937e42c3abd), + C64e(0x2197b2260113f86f), C64e(0xa344edd1ef9fdee7), + C64e(0x8ba0df15762592d9), C64e(0x3c85f7f612dc42be), + C64e(0xd8a7ec7cab27b07e), C64e(0x538d7ddaaa3ea8de), + C64e(0xaa25ce93bd0269d8), C64e(0x5af643fd1a7308f9), + C64e(0xc05fefda174a19a5), C64e(0x974d66334cfd216a), + C64e(0x35b49831db411570), C64e(0xea1e0fbbedcd549b), + C64e(0x9ad063a151974072), C64e(0xf6759dbf91476fe2) +}; + +#define Ceven_hi(r) (C[((r) << 2) + 0]) +#define Ceven_lo(r) (C[((r) << 2) + 1]) +#define Codd_hi(r) (C[((r) << 2) + 2]) +#define Codd_lo(r) (C[((r) << 2) + 3]) + +#define S(x0, x1, x2, x3, cb, r) do { \ + Sb(x0 ## h, x1 ## h, x2 ## h, x3 ## h, cb ## hi(r)); \ + Sb(x0 ## l, x1 ## l, x2 ## l, x3 ## l, cb ## lo(r)); \ + } while (0) + +#define L(x0, x1, x2, x3, x4, x5, x6, x7) do { \ + Lb(x0 ## h, x1 ## h, x2 ## h, x3 ## h, \ + x4 ## h, x5 ## h, x6 ## h, x7 ## h); \ + Lb(x0 ## l, x1 ## l, x2 ## l, x3 ## l, \ + x4 ## l, x5 ## l, x6 ## l, x7 ## l); \ + } while (0) + +#define Wz(x, c, n) do { \ + sph_u64 t = (x ## h & (c)) << (n); \ + x ## h = ((x ## h >> (n)) & (c)) | t; \ + t = (x ## l & (c)) << (n); \ + x ## l = ((x ## l >> (n)) & (c)) | t; \ + } while (0) + +#define W0(x) Wz(x, SPH_C64(0x5555555555555555), 1) +#define W1(x) Wz(x, SPH_C64(0x3333333333333333), 2) +#define W2(x) Wz(x, SPH_C64(0x0F0F0F0F0F0F0F0F), 4) +#define W3(x) Wz(x, SPH_C64(0x00FF00FF00FF00FF), 8) +#define W4(x) Wz(x, SPH_C64(0x0000FFFF0000FFFF), 16) +#define W5(x) Wz(x, SPH_C64(0x00000000FFFFFFFF), 32) +#define W6(x) do { \ + sph_u64 t = x ## h; \ + x ## h = x ## l; \ + x ## l = t; \ + } while (0) + +#define DECL_STATE \ + sph_u64 h0h, h1h, h2h, h3h, h4h, h5h, h6h, h7h; \ + sph_u64 h0l, h1l, h2l, h3l, h4l, h5l, h6l, h7l; \ + sph_u64 tmp; + +#define READ_STATE(state) do { \ + h0h = (state)->H.wide[ 0]; \ + h0l = (state)->H.wide[ 1]; \ + h1h = (state)->H.wide[ 2]; \ + h1l = (state)->H.wide[ 3]; \ + h2h = (state)->H.wide[ 4]; \ + h2l = (state)->H.wide[ 5]; \ + h3h = (state)->H.wide[ 6]; \ + h3l = (state)->H.wide[ 7]; \ + h4h = (state)->H.wide[ 8]; \ + h4l = (state)->H.wide[ 9]; \ + h5h = (state)->H.wide[10]; \ + h5l = (state)->H.wide[11]; \ + h6h = (state)->H.wide[12]; \ + h6l = (state)->H.wide[13]; \ + h7h = (state)->H.wide[14]; \ + h7l = (state)->H.wide[15]; \ + } while (0) + +#define WRITE_STATE(state) do { \ + (state)->H.wide[ 0] = h0h; \ + (state)->H.wide[ 1] = h0l; \ + (state)->H.wide[ 2] = h1h; \ + (state)->H.wide[ 3] = h1l; \ + (state)->H.wide[ 4] = h2h; \ + (state)->H.wide[ 5] = h2l; \ + (state)->H.wide[ 6] = h3h; \ + (state)->H.wide[ 7] = h3l; \ + (state)->H.wide[ 8] = h4h; \ + (state)->H.wide[ 9] = h4l; \ + (state)->H.wide[10] = h5h; \ + (state)->H.wide[11] = h5l; \ + (state)->H.wide[12] = h6h; \ + (state)->H.wide[13] = h6l; \ + (state)->H.wide[14] = h7h; \ + (state)->H.wide[15] = h7l; \ + } while (0) + +#define INPUT_BUF1 \ + sph_u64 m0h = dec64e_aligned(buf + 0); \ + sph_u64 m0l = dec64e_aligned(buf + 8); \ + sph_u64 m1h = dec64e_aligned(buf + 16); \ + sph_u64 m1l = dec64e_aligned(buf + 24); \ + sph_u64 m2h = dec64e_aligned(buf + 32); \ + sph_u64 m2l = dec64e_aligned(buf + 40); \ + sph_u64 m3h = dec64e_aligned(buf + 48); \ + sph_u64 m3l = dec64e_aligned(buf + 56); \ + h0h ^= m0h; \ + h0l ^= m0l; \ + h1h ^= m1h; \ + h1l ^= m1l; \ + h2h ^= m2h; \ + h2l ^= m2l; \ + h3h ^= m3h; \ + h3l ^= m3l; + +#define INPUT_BUF2 \ + h4h ^= m0h; \ + h4l ^= m0l; \ + h5h ^= m1h; \ + h5l ^= m1l; \ + h6h ^= m2h; \ + h6l ^= m2l; \ + h7h ^= m3h; \ + h7l ^= m3l; + +static const sph_u64 IV224[] = { + C64e(0x2dfedd62f99a98ac), C64e(0xae7cacd619d634e7), + C64e(0xa4831005bc301216), C64e(0xb86038c6c9661494), + C64e(0x66d9899f2580706f), C64e(0xce9ea31b1d9b1adc), + C64e(0x11e8325f7b366e10), C64e(0xf994857f02fa06c1), + C64e(0x1b4f1b5cd8c840b3), C64e(0x97f6a17f6e738099), + C64e(0xdcdf93a5adeaa3d3), C64e(0xa431e8dec9539a68), + C64e(0x22b4a98aec86a1e4), C64e(0xd574ac959ce56cf0), + C64e(0x15960deab5ab2bbf), C64e(0x9611dcf0dd64ea6e) +}; + +static const sph_u64 IV256[] = { + C64e(0xeb98a3412c20d3eb), C64e(0x92cdbe7b9cb245c1), + C64e(0x1c93519160d4c7fa), C64e(0x260082d67e508a03), + C64e(0xa4239e267726b945), C64e(0xe0fb1a48d41a9477), + C64e(0xcdb5ab26026b177a), C64e(0x56f024420fff2fa8), + C64e(0x71a396897f2e4d75), C64e(0x1d144908f77de262), + C64e(0x277695f776248f94), C64e(0x87d5b6574780296c), + C64e(0x5c5e272dac8e0d6c), C64e(0x518450c657057a0f), + C64e(0x7be4d367702412ea), C64e(0x89e3ab13d31cd769) +}; + +static const sph_u64 IV384[] = { + C64e(0x481e3bc6d813398a), C64e(0x6d3b5e894ade879b), + C64e(0x63faea68d480ad2e), C64e(0x332ccb21480f8267), + C64e(0x98aec84d9082b928), C64e(0xd455ea3041114249), + C64e(0x36f555b2924847ec), C64e(0xc7250a93baf43ce1), + C64e(0x569b7f8a27db454c), C64e(0x9efcbd496397af0e), + C64e(0x589fc27d26aa80cd), C64e(0x80c08b8c9deb2eda), + C64e(0x8a7981e8f8d5373a), C64e(0xf43967adddd17a71), + C64e(0xa9b4d3bda475d394), C64e(0x976c3fba9842737f) +}; + +static const sph_u64 IV512[] = { + C64e(0x6fd14b963e00aa17), C64e(0x636a2e057a15d543), + C64e(0x8a225e8d0c97ef0b), C64e(0xe9341259f2b3c361), + C64e(0x891da0c1536f801e), C64e(0x2aa9056bea2b6d80), + C64e(0x588eccdb2075baa6), C64e(0xa90f3a76baf83bf7), + C64e(0x0169e60541e34a69), C64e(0x46b58a8e2e6fe65a), + C64e(0x1047a7d0c1843c24), C64e(0x3b6e71b12d5ac199), + C64e(0xcf57f6ec9db1f856), C64e(0xa706887c5716b156), + C64e(0xe3c2fcdfe68517fb), C64e(0x545a4678cc8cdd4b) +}; + +#else + +static const sph_u32 C[] = { + C32e(0x72d5dea2), C32e(0xdf15f867), C32e(0x7b84150a), + C32e(0xb7231557), C32e(0x81abd690), C32e(0x4d5a87f6), + C32e(0x4e9f4fc5), C32e(0xc3d12b40), C32e(0xea983ae0), + C32e(0x5c45fa9c), C32e(0x03c5d299), C32e(0x66b2999a), + C32e(0x660296b4), C32e(0xf2bb538a), C32e(0xb556141a), + C32e(0x88dba231), C32e(0x03a35a5c), C32e(0x9a190edb), + C32e(0x403fb20a), C32e(0x87c14410), C32e(0x1c051980), + C32e(0x849e951d), C32e(0x6f33ebad), C32e(0x5ee7cddc), + C32e(0x10ba1392), C32e(0x02bf6b41), C32e(0xdc786515), + C32e(0xf7bb27d0), C32e(0x0a2c8139), C32e(0x37aa7850), + C32e(0x3f1abfd2), C32e(0x410091d3), C32e(0x422d5a0d), + C32e(0xf6cc7e90), C32e(0xdd629f9c), C32e(0x92c097ce), + C32e(0x185ca70b), C32e(0xc72b44ac), C32e(0xd1df65d6), + C32e(0x63c6fc23), C32e(0x976e6c03), C32e(0x9ee0b81a), + C32e(0x2105457e), C32e(0x446ceca8), C32e(0xeef103bb), + C32e(0x5d8e61fa), C32e(0xfd9697b2), C32e(0x94838197), + C32e(0x4a8e8537), C32e(0xdb03302f), C32e(0x2a678d2d), + C32e(0xfb9f6a95), C32e(0x8afe7381), C32e(0xf8b8696c), + C32e(0x8ac77246), C32e(0xc07f4214), C32e(0xc5f4158f), + C32e(0xbdc75ec4), C32e(0x75446fa7), C32e(0x8f11bb80), + C32e(0x52de75b7), C32e(0xaee488bc), C32e(0x82b8001e), + C32e(0x98a6a3f4), C32e(0x8ef48f33), C32e(0xa9a36315), + C32e(0xaa5f5624), C32e(0xd5b7f989), C32e(0xb6f1ed20), + C32e(0x7c5ae0fd), C32e(0x36cae95a), C32e(0x06422c36), + C32e(0xce293543), C32e(0x4efe983d), C32e(0x533af974), + C32e(0x739a4ba7), C32e(0xd0f51f59), C32e(0x6f4e8186), + C32e(0x0e9dad81), C32e(0xafd85a9f), C32e(0xa7050667), + C32e(0xee34626a), C32e(0x8b0b28be), C32e(0x6eb91727), + C32e(0x47740726), C32e(0xc680103f), C32e(0xe0a07e6f), + C32e(0xc67e487b), C32e(0x0d550aa5), C32e(0x4af8a4c0), + C32e(0x91e3e79f), C32e(0x978ef19e), C32e(0x86767281), + C32e(0x50608dd4), C32e(0x7e9e5a41), C32e(0xf3e5b062), + C32e(0xfc9f1fec), C32e(0x4054207a), C32e(0xe3e41a00), + C32e(0xcef4c984), C32e(0x4fd794f5), C32e(0x9dfa95d8), + C32e(0x552e7e11), C32e(0x24c354a5), C32e(0x5bdf7228), + C32e(0xbdfe6e28), C32e(0x78f57fe2), C32e(0x0fa5c4b2), + C32e(0x05897cef), C32e(0xee49d32e), C32e(0x447e9385), + C32e(0xeb28597f), C32e(0x705f6937), C32e(0xb324314a), + C32e(0x5e8628f1), C32e(0x1dd6e465), C32e(0xc71b7704), + C32e(0x51b920e7), C32e(0x74fe43e8), C32e(0x23d4878a), + C32e(0x7d29e8a3), C32e(0x927694f2), C32e(0xddcb7a09), + C32e(0x9b30d9c1), C32e(0x1d1b30fb), C32e(0x5bdc1be0), + C32e(0xda24494f), C32e(0xf29c82bf), C32e(0xa4e7ba31), + C32e(0xb470bfff), C32e(0x0d324405), C32e(0xdef8bc48), + C32e(0x3baefc32), C32e(0x53bbd339), C32e(0x459fc3c1), + C32e(0xe0298ba0), C32e(0xe5c905fd), C32e(0xf7ae090f), + C32e(0x94703412), C32e(0x4290f134), C32e(0xa271b701), + C32e(0xe344ed95), C32e(0xe93b8e36), C32e(0x4f2f984a), + C32e(0x88401d63), C32e(0xa06cf615), C32e(0x47c1444b), + C32e(0x8752afff), C32e(0x7ebb4af1), C32e(0xe20ac630), + C32e(0x4670b6c5), C32e(0xcc6e8ce6), C32e(0xa4d5a456), + C32e(0xbd4fca00), C32e(0xda9d844b), C32e(0xc83e18ae), + C32e(0x7357ce45), C32e(0x3064d1ad), C32e(0xe8a6ce68), + C32e(0x145c2567), C32e(0xa3da8cf2), C32e(0xcb0ee116), + C32e(0x33e90658), C32e(0x9a94999a), C32e(0x1f60b220), + C32e(0xc26f847b), C32e(0xd1ceac7f), C32e(0xa0d18518), + C32e(0x32595ba1), C32e(0x8ddd19d3), C32e(0x509a1cc0), + C32e(0xaaa5b446), C32e(0x9f3d6367), C32e(0xe4046bba), + C32e(0xf6ca19ab), C32e(0x0b56ee7e), C32e(0x1fb179ea), + C32e(0xa9282174), C32e(0xe9bdf735), C32e(0x3b3651ee), + C32e(0x1d57ac5a), C32e(0x7550d376), C32e(0x3a46c2fe), + C32e(0xa37d7001), C32e(0xf735c1af), C32e(0x98a4d842), + C32e(0x78edec20), C32e(0x9e6b6779), C32e(0x41836315), + C32e(0xea3adba8), C32e(0xfac33b4d), C32e(0x32832c83), + C32e(0xa7403b1f), C32e(0x1c2747f3), C32e(0x5940f034), + C32e(0xb72d769a), C32e(0xe73e4e6c), C32e(0xd2214ffd), + C32e(0xb8fd8d39), C32e(0xdc5759ef), C32e(0x8d9b0c49), + C32e(0x2b49ebda), C32e(0x5ba2d749), C32e(0x68f3700d), + C32e(0x7d3baed0), C32e(0x7a8d5584), C32e(0xf5a5e9f0), + C32e(0xe4f88e65), C32e(0xa0b8a2f4), C32e(0x36103b53), + C32e(0x0ca8079e), C32e(0x753eec5a), C32e(0x91689492), + C32e(0x56e8884f), C32e(0x5bb05c55), C32e(0xf8babc4c), + C32e(0xe3bb3b99), C32e(0xf387947b), C32e(0x75daf4d6), + C32e(0x726b1c5d), C32e(0x64aeac28), C32e(0xdc34b36d), + C32e(0x6c34a550), C32e(0xb828db71), C32e(0xf861e2f2), + C32e(0x108d512a), C32e(0xe3db6433), C32e(0x59dd75fc), + C32e(0x1cacbcf1), C32e(0x43ce3fa2), C32e(0x67bbd13c), + C32e(0x02e843b0), C32e(0x330a5bca), C32e(0x8829a175), + C32e(0x7f34194d), C32e(0xb416535c), C32e(0x923b94c3), + C32e(0x0e794d1e), C32e(0x797475d7), C32e(0xb6eeaf3f), + C32e(0xeaa8d4f7), C32e(0xbe1a3921), C32e(0x5cf47e09), + C32e(0x4c232751), C32e(0x26a32453), C32e(0xba323cd2), + C32e(0x44a3174a), C32e(0x6da6d5ad), C32e(0xb51d3ea6), + C32e(0xaff2c908), C32e(0x83593d98), C32e(0x916b3c56), + C32e(0x4cf87ca1), C32e(0x7286604d), C32e(0x46e23ecc), + C32e(0x086ec7f6), C32e(0x2f9833b3), C32e(0xb1bc765e), + C32e(0x2bd666a5), C32e(0xefc4e62a), C32e(0x06f4b6e8), + C32e(0xbec1d436), C32e(0x74ee8215), C32e(0xbcef2163), + C32e(0xfdc14e0d), C32e(0xf453c969), C32e(0xa77d5ac4), + C32e(0x06585826), C32e(0x7ec11416), C32e(0x06e0fa16), + C32e(0x7e90af3d), C32e(0x28639d3f), C32e(0xd2c9f2e3), + C32e(0x009bd20c), C32e(0x5faace30), C32e(0xb7d40c30), + C32e(0x742a5116), C32e(0xf2e03298), C32e(0x0deb30d8), + C32e(0xe3cef89a), C32e(0x4bc59e7b), C32e(0xb5f17992), + C32e(0xff51e66e), C32e(0x048668d3), C32e(0x9b234d57), + C32e(0xe6966731), C32e(0xcce6a6f3), C32e(0x170a7505), + C32e(0xb17681d9), C32e(0x13326cce), C32e(0x3c175284), + C32e(0xf805a262), C32e(0xf42bcbb3), C32e(0x78471547), + C32e(0xff465482), C32e(0x23936a48), C32e(0x38df5807), + C32e(0x4e5e6565), C32e(0xf2fc7c89), C32e(0xfc86508e), + C32e(0x31702e44), C32e(0xd00bca86), C32e(0xf04009a2), + C32e(0x3078474e), C32e(0x65a0ee39), C32e(0xd1f73883), + C32e(0xf75ee937), C32e(0xe42c3abd), C32e(0x2197b226), + C32e(0x0113f86f), C32e(0xa344edd1), C32e(0xef9fdee7), + C32e(0x8ba0df15), C32e(0x762592d9), C32e(0x3c85f7f6), + C32e(0x12dc42be), C32e(0xd8a7ec7c), C32e(0xab27b07e), + C32e(0x538d7dda), C32e(0xaa3ea8de), C32e(0xaa25ce93), + C32e(0xbd0269d8), C32e(0x5af643fd), C32e(0x1a7308f9), + C32e(0xc05fefda), C32e(0x174a19a5), C32e(0x974d6633), + C32e(0x4cfd216a), C32e(0x35b49831), C32e(0xdb411570), + C32e(0xea1e0fbb), C32e(0xedcd549b), C32e(0x9ad063a1), + C32e(0x51974072), C32e(0xf6759dbf), C32e(0x91476fe2) +}; + +#define Ceven_w3(r) (C[((r) << 3) + 0]) +#define Ceven_w2(r) (C[((r) << 3) + 1]) +#define Ceven_w1(r) (C[((r) << 3) + 2]) +#define Ceven_w0(r) (C[((r) << 3) + 3]) +#define Codd_w3(r) (C[((r) << 3) + 4]) +#define Codd_w2(r) (C[((r) << 3) + 5]) +#define Codd_w1(r) (C[((r) << 3) + 6]) +#define Codd_w0(r) (C[((r) << 3) + 7]) + +#define S(x0, x1, x2, x3, cb, r) do { \ + Sb(x0 ## 3, x1 ## 3, x2 ## 3, x3 ## 3, cb ## w3(r)); \ + Sb(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, cb ## w2(r)); \ + Sb(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, cb ## w1(r)); \ + Sb(x0 ## 0, x1 ## 0, x2 ## 0, x3 ## 0, cb ## w0(r)); \ + } while (0) + +#define L(x0, x1, x2, x3, x4, x5, x6, x7) do { \ + Lb(x0 ## 3, x1 ## 3, x2 ## 3, x3 ## 3, \ + x4 ## 3, x5 ## 3, x6 ## 3, x7 ## 3); \ + Lb(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, \ + x4 ## 2, x5 ## 2, x6 ## 2, x7 ## 2); \ + Lb(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, \ + x4 ## 1, x5 ## 1, x6 ## 1, x7 ## 1); \ + Lb(x0 ## 0, x1 ## 0, x2 ## 0, x3 ## 0, \ + x4 ## 0, x5 ## 0, x6 ## 0, x7 ## 0); \ + } while (0) + +#define Wz(x, c, n) do { \ + sph_u32 t = (x ## 3 & (c)) << (n); \ + x ## 3 = ((x ## 3 >> (n)) & (c)) | t; \ + t = (x ## 2 & (c)) << (n); \ + x ## 2 = ((x ## 2 >> (n)) & (c)) | t; \ + t = (x ## 1 & (c)) << (n); \ + x ## 1 = ((x ## 1 >> (n)) & (c)) | t; \ + t = (x ## 0 & (c)) << (n); \ + x ## 0 = ((x ## 0 >> (n)) & (c)) | t; \ + } while (0) + +#define W0(x) Wz(x, SPH_C32(0x55555555), 1) +#define W1(x) Wz(x, SPH_C32(0x33333333), 2) +#define W2(x) Wz(x, SPH_C32(0x0F0F0F0F), 4) +#define W3(x) Wz(x, SPH_C32(0x00FF00FF), 8) +#define W4(x) Wz(x, SPH_C32(0x0000FFFF), 16) +#define W5(x) do { \ + sph_u32 t = x ## 3; \ + x ## 3 = x ## 2; \ + x ## 2 = t; \ + t = x ## 1; \ + x ## 1 = x ## 0; \ + x ## 0 = t; \ + } while (0) +#define W6(x) do { \ + sph_u32 t = x ## 3; \ + x ## 3 = x ## 1; \ + x ## 1 = t; \ + t = x ## 2; \ + x ## 2 = x ## 0; \ + x ## 0 = t; \ + } while (0) + +#define DECL_STATE \ + sph_u32 h03, h02, h01, h00, h13, h12, h11, h10; \ + sph_u32 h23, h22, h21, h20, h33, h32, h31, h30; \ + sph_u32 h43, h42, h41, h40, h53, h52, h51, h50; \ + sph_u32 h63, h62, h61, h60, h73, h72, h71, h70; \ + sph_u32 tmp; + +#define READ_STATE(state) do { \ + h03 = (state)->H.narrow[ 0]; \ + h02 = (state)->H.narrow[ 1]; \ + h01 = (state)->H.narrow[ 2]; \ + h00 = (state)->H.narrow[ 3]; \ + h13 = (state)->H.narrow[ 4]; \ + h12 = (state)->H.narrow[ 5]; \ + h11 = (state)->H.narrow[ 6]; \ + h10 = (state)->H.narrow[ 7]; \ + h23 = (state)->H.narrow[ 8]; \ + h22 = (state)->H.narrow[ 9]; \ + h21 = (state)->H.narrow[10]; \ + h20 = (state)->H.narrow[11]; \ + h33 = (state)->H.narrow[12]; \ + h32 = (state)->H.narrow[13]; \ + h31 = (state)->H.narrow[14]; \ + h30 = (state)->H.narrow[15]; \ + h43 = (state)->H.narrow[16]; \ + h42 = (state)->H.narrow[17]; \ + h41 = (state)->H.narrow[18]; \ + h40 = (state)->H.narrow[19]; \ + h53 = (state)->H.narrow[20]; \ + h52 = (state)->H.narrow[21]; \ + h51 = (state)->H.narrow[22]; \ + h50 = (state)->H.narrow[23]; \ + h63 = (state)->H.narrow[24]; \ + h62 = (state)->H.narrow[25]; \ + h61 = (state)->H.narrow[26]; \ + h60 = (state)->H.narrow[27]; \ + h73 = (state)->H.narrow[28]; \ + h72 = (state)->H.narrow[29]; \ + h71 = (state)->H.narrow[30]; \ + h70 = (state)->H.narrow[31]; \ + } while (0) + +#define WRITE_STATE(state) do { \ + (state)->H.narrow[ 0] = h03; \ + (state)->H.narrow[ 1] = h02; \ + (state)->H.narrow[ 2] = h01; \ + (state)->H.narrow[ 3] = h00; \ + (state)->H.narrow[ 4] = h13; \ + (state)->H.narrow[ 5] = h12; \ + (state)->H.narrow[ 6] = h11; \ + (state)->H.narrow[ 7] = h10; \ + (state)->H.narrow[ 8] = h23; \ + (state)->H.narrow[ 9] = h22; \ + (state)->H.narrow[10] = h21; \ + (state)->H.narrow[11] = h20; \ + (state)->H.narrow[12] = h33; \ + (state)->H.narrow[13] = h32; \ + (state)->H.narrow[14] = h31; \ + (state)->H.narrow[15] = h30; \ + (state)->H.narrow[16] = h43; \ + (state)->H.narrow[17] = h42; \ + (state)->H.narrow[18] = h41; \ + (state)->H.narrow[19] = h40; \ + (state)->H.narrow[20] = h53; \ + (state)->H.narrow[21] = h52; \ + (state)->H.narrow[22] = h51; \ + (state)->H.narrow[23] = h50; \ + (state)->H.narrow[24] = h63; \ + (state)->H.narrow[25] = h62; \ + (state)->H.narrow[26] = h61; \ + (state)->H.narrow[27] = h60; \ + (state)->H.narrow[28] = h73; \ + (state)->H.narrow[29] = h72; \ + (state)->H.narrow[30] = h71; \ + (state)->H.narrow[31] = h70; \ + } while (0) + +#define INPUT_BUF1 \ + sph_u32 m03 = dec32e_aligned(buf + 0); \ + sph_u32 m02 = dec32e_aligned(buf + 4); \ + sph_u32 m01 = dec32e_aligned(buf + 8); \ + sph_u32 m00 = dec32e_aligned(buf + 12); \ + sph_u32 m13 = dec32e_aligned(buf + 16); \ + sph_u32 m12 = dec32e_aligned(buf + 20); \ + sph_u32 m11 = dec32e_aligned(buf + 24); \ + sph_u32 m10 = dec32e_aligned(buf + 28); \ + sph_u32 m23 = dec32e_aligned(buf + 32); \ + sph_u32 m22 = dec32e_aligned(buf + 36); \ + sph_u32 m21 = dec32e_aligned(buf + 40); \ + sph_u32 m20 = dec32e_aligned(buf + 44); \ + sph_u32 m33 = dec32e_aligned(buf + 48); \ + sph_u32 m32 = dec32e_aligned(buf + 52); \ + sph_u32 m31 = dec32e_aligned(buf + 56); \ + sph_u32 m30 = dec32e_aligned(buf + 60); \ + h03 ^= m03; \ + h02 ^= m02; \ + h01 ^= m01; \ + h00 ^= m00; \ + h13 ^= m13; \ + h12 ^= m12; \ + h11 ^= m11; \ + h10 ^= m10; \ + h23 ^= m23; \ + h22 ^= m22; \ + h21 ^= m21; \ + h20 ^= m20; \ + h33 ^= m33; \ + h32 ^= m32; \ + h31 ^= m31; \ + h30 ^= m30; + +#define INPUT_BUF2 \ + h43 ^= m03; \ + h42 ^= m02; \ + h41 ^= m01; \ + h40 ^= m00; \ + h53 ^= m13; \ + h52 ^= m12; \ + h51 ^= m11; \ + h50 ^= m10; \ + h63 ^= m23; \ + h62 ^= m22; \ + h61 ^= m21; \ + h60 ^= m20; \ + h73 ^= m33; \ + h72 ^= m32; \ + h71 ^= m31; \ + h70 ^= m30; + +static const sph_u32 IV224[] = { + C32e(0x2dfedd62), C32e(0xf99a98ac), C32e(0xae7cacd6), C32e(0x19d634e7), + C32e(0xa4831005), C32e(0xbc301216), C32e(0xb86038c6), C32e(0xc9661494), + C32e(0x66d9899f), C32e(0x2580706f), C32e(0xce9ea31b), C32e(0x1d9b1adc), + C32e(0x11e8325f), C32e(0x7b366e10), C32e(0xf994857f), C32e(0x02fa06c1), + C32e(0x1b4f1b5c), C32e(0xd8c840b3), C32e(0x97f6a17f), C32e(0x6e738099), + C32e(0xdcdf93a5), C32e(0xadeaa3d3), C32e(0xa431e8de), C32e(0xc9539a68), + C32e(0x22b4a98a), C32e(0xec86a1e4), C32e(0xd574ac95), C32e(0x9ce56cf0), + C32e(0x15960dea), C32e(0xb5ab2bbf), C32e(0x9611dcf0), C32e(0xdd64ea6e) +}; + +static const sph_u32 IV256[] = { + C32e(0xeb98a341), C32e(0x2c20d3eb), C32e(0x92cdbe7b), C32e(0x9cb245c1), + C32e(0x1c935191), C32e(0x60d4c7fa), C32e(0x260082d6), C32e(0x7e508a03), + C32e(0xa4239e26), C32e(0x7726b945), C32e(0xe0fb1a48), C32e(0xd41a9477), + C32e(0xcdb5ab26), C32e(0x026b177a), C32e(0x56f02442), C32e(0x0fff2fa8), + C32e(0x71a39689), C32e(0x7f2e4d75), C32e(0x1d144908), C32e(0xf77de262), + C32e(0x277695f7), C32e(0x76248f94), C32e(0x87d5b657), C32e(0x4780296c), + C32e(0x5c5e272d), C32e(0xac8e0d6c), C32e(0x518450c6), C32e(0x57057a0f), + C32e(0x7be4d367), C32e(0x702412ea), C32e(0x89e3ab13), C32e(0xd31cd769) +}; + +static const sph_u32 IV384[] = { + C32e(0x481e3bc6), C32e(0xd813398a), C32e(0x6d3b5e89), C32e(0x4ade879b), + C32e(0x63faea68), C32e(0xd480ad2e), C32e(0x332ccb21), C32e(0x480f8267), + C32e(0x98aec84d), C32e(0x9082b928), C32e(0xd455ea30), C32e(0x41114249), + C32e(0x36f555b2), C32e(0x924847ec), C32e(0xc7250a93), C32e(0xbaf43ce1), + C32e(0x569b7f8a), C32e(0x27db454c), C32e(0x9efcbd49), C32e(0x6397af0e), + C32e(0x589fc27d), C32e(0x26aa80cd), C32e(0x80c08b8c), C32e(0x9deb2eda), + C32e(0x8a7981e8), C32e(0xf8d5373a), C32e(0xf43967ad), C32e(0xddd17a71), + C32e(0xa9b4d3bd), C32e(0xa475d394), C32e(0x976c3fba), C32e(0x9842737f) +}; + +static const sph_u32 IV512[] = { + C32e(0x6fd14b96), C32e(0x3e00aa17), C32e(0x636a2e05), C32e(0x7a15d543), + C32e(0x8a225e8d), C32e(0x0c97ef0b), C32e(0xe9341259), C32e(0xf2b3c361), + C32e(0x891da0c1), C32e(0x536f801e), C32e(0x2aa9056b), C32e(0xea2b6d80), + C32e(0x588eccdb), C32e(0x2075baa6), C32e(0xa90f3a76), C32e(0xbaf83bf7), + C32e(0x0169e605), C32e(0x41e34a69), C32e(0x46b58a8e), C32e(0x2e6fe65a), + C32e(0x1047a7d0), C32e(0xc1843c24), C32e(0x3b6e71b1), C32e(0x2d5ac199), + C32e(0xcf57f6ec), C32e(0x9db1f856), C32e(0xa706887c), C32e(0x5716b156), + C32e(0xe3c2fcdf), C32e(0xe68517fb), C32e(0x545a4678), C32e(0xcc8cdd4b) +}; + +#endif + +#define SL(ro) SLu(r + ro, ro) + +#define SLu(r, ro) do { \ + S(h0, h2, h4, h6, Ceven_, r); \ + S(h1, h3, h5, h7, Codd_, r); \ + L(h0, h2, h4, h6, h1, h3, h5, h7); \ + W ## ro(h1); \ + W ## ro(h3); \ + W ## ro(h5); \ + W ## ro(h7); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_JH + +#if SPH_JH_64 + +/* + * The "small footprint" 64-bit version just uses a partially unrolled + * loop. + */ + +#define E8 do { \ + unsigned r; \ + for (r = 0; r < 42; r += 7) { \ + SL(0); \ + SL(1); \ + SL(2); \ + SL(3); \ + SL(4); \ + SL(5); \ + SL(6); \ + } \ + } while (0) + +#else + +#define E8 do { \ + unsigned r, g; \ + for (r = g = 0; r < 42; r ++) { \ + S(h0, h2, h4, h6, Ceven_, r); \ + S(h1, h3, h5, h7, Codd_, r); \ + L(h0, h2, h4, h6, h1, h3, h5, h7); \ + switch (g) { \ + case 0: \ + W0(h1); \ + W0(h3); \ + W0(h5); \ + W0(h7); \ + break; \ + case 1: \ + W1(h1); \ + W1(h3); \ + W1(h5); \ + W1(h7); \ + break; \ + case 2: \ + W2(h1); \ + W2(h3); \ + W2(h5); \ + W2(h7); \ + break; \ + case 3: \ + W3(h1); \ + W3(h3); \ + W3(h5); \ + W3(h7); \ + break; \ + case 4: \ + W4(h1); \ + W4(h3); \ + W4(h5); \ + W4(h7); \ + break; \ + case 5: \ + W5(h1); \ + W5(h3); \ + W5(h5); \ + W5(h7); \ + break; \ + case 6: \ + W6(h1); \ + W6(h3); \ + W6(h5); \ + W6(h7); \ + break; \ + } \ + if (++ g == 7) \ + g = 0; \ + } \ + } while (0) + +#endif + +#else + +#if SPH_JH_64 + +/* + * On a "true 64-bit" architecture, we can unroll at will. + */ + +#define E8 do { \ + SLu( 0, 0); \ + SLu( 1, 1); \ + SLu( 2, 2); \ + SLu( 3, 3); \ + SLu( 4, 4); \ + SLu( 5, 5); \ + SLu( 6, 6); \ + SLu( 7, 0); \ + SLu( 8, 1); \ + SLu( 9, 2); \ + SLu(10, 3); \ + SLu(11, 4); \ + SLu(12, 5); \ + SLu(13, 6); \ + SLu(14, 0); \ + SLu(15, 1); \ + SLu(16, 2); \ + SLu(17, 3); \ + SLu(18, 4); \ + SLu(19, 5); \ + SLu(20, 6); \ + SLu(21, 0); \ + SLu(22, 1); \ + SLu(23, 2); \ + SLu(24, 3); \ + SLu(25, 4); \ + SLu(26, 5); \ + SLu(27, 6); \ + SLu(28, 0); \ + SLu(29, 1); \ + SLu(30, 2); \ + SLu(31, 3); \ + SLu(32, 4); \ + SLu(33, 5); \ + SLu(34, 6); \ + SLu(35, 0); \ + SLu(36, 1); \ + SLu(37, 2); \ + SLu(38, 3); \ + SLu(39, 4); \ + SLu(40, 5); \ + SLu(41, 6); \ + } while (0) + +#else + +/* + * We are not aiming at a small footprint, but we are still using a + * 32-bit implementation. Full loop unrolling would smash the L1 + * cache on some "big" architectures (32 kB L1 cache). + */ + +#define E8 do { \ + unsigned r; \ + for (r = 0; r < 42; r += 7) { \ + SL(0); \ + SL(1); \ + SL(2); \ + SL(3); \ + SL(4); \ + SL(5); \ + SL(6); \ + } \ + } while (0) + +#endif + +#endif + +static void +jh_init(sph_jh_context *sc, const void *iv) +{ + sc->ptr = 0; +#if SPH_JH_64 + memcpy(sc->H.wide, iv, sizeof sc->H.wide); +#else + memcpy(sc->H.narrow, iv, sizeof sc->H.narrow); +#endif +#if SPH_64 + sc->block_count = 0; +#else + sc->block_count_high = 0; + sc->block_count_low = 0; +#endif +} + +static void +jh_core(sph_jh_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_BUF1; + E8; + INPUT_BUF2; +#if SPH_64 + sc->block_count ++; +#else + if ((sc->block_count_low = SPH_T32( + sc->block_count_low + 1)) == 0) + sc->block_count_high ++; +#endif + ptr = 0; + } + } + WRITE_STATE(sc); + sc->ptr = ptr; +} + +static void +jh_close(sph_jh_context *sc, unsigned ub, unsigned n, + void *dst, size_t out_size_w32, const void *iv) +{ + unsigned z; + unsigned char buf[128]; + size_t numz, u; +#if SPH_64 + sph_u64 l0, l1; +#else + sph_u32 l0, l1, l2, l3; +#endif + + z = 0x80 >> n; + buf[0] = ((ub & -z) | z) & 0xFF; + if (sc->ptr == 0 && n == 0) { + numz = 47; + } else { + numz = 111 - sc->ptr; + } + memset(buf + 1, 0, numz); +#if SPH_64 + l0 = SPH_T64(sc->block_count << 9) + (sc->ptr << 3) + n; + l1 = SPH_T64(sc->block_count >> 55); + sph_enc64be(buf + numz + 1, l1); + sph_enc64be(buf + numz + 9, l0); +#else + l0 = SPH_T32(sc->block_count_low << 9) + (sc->ptr << 3) + n; + l1 = SPH_T32(sc->block_count_low >> 23) + + SPH_T32(sc->block_count_high << 9); + l2 = SPH_T32(sc->block_count_high >> 23); + l3 = 0; + sph_enc32be(buf + numz + 1, l3); + sph_enc32be(buf + numz + 5, l2); + sph_enc32be(buf + numz + 9, l1); + sph_enc32be(buf + numz + 13, l0); +#endif + jh_core(sc, buf, numz + 17); +#if SPH_JH_64 + for (u = 0; u < 8; u ++) + enc64e(buf + (u << 3), sc->H.wide[u + 8]); +#else + for (u = 0; u < 16; u ++) + enc32e(buf + (u << 2), sc->H.narrow[u + 16]); +#endif + memcpy(dst, buf + ((16 - out_size_w32) << 2), out_size_w32 << 2); + jh_init(sc, iv); +} + +/* see sph_jh.h */ +void +sph_jh224_init(void *cc) +{ + jh_init(cc, IV224); +} + +/* see sph_jh.h */ +void +sph_jh224(void *cc, const void *data, size_t len) +{ + jh_core(cc, data, len); +} + +/* see sph_jh.h */ +void +sph_jh224_close(void *cc, void *dst) +{ + jh_close(cc, 0, 0, dst, 7, IV224); +} + +/* see sph_jh.h */ +void +sph_jh224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + jh_close(cc, ub, n, dst, 7, IV224); +} + +/* see sph_jh.h */ +void +sph_jh256_init(void *cc) +{ + jh_init(cc, IV256); +} + +/* see sph_jh.h */ +void +sph_jh256(void *cc, const void *data, size_t len) +{ + jh_core(cc, data, len); +} + +/* see sph_jh.h */ +void +sph_jh256_close(void *cc, void *dst) +{ + jh_close(cc, 0, 0, dst, 8, IV256); +} + +/* see sph_jh.h */ +void +sph_jh256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + jh_close(cc, ub, n, dst, 8, IV256); +} + +/* see sph_jh.h */ +void +sph_jh384_init(void *cc) +{ + jh_init(cc, IV384); +} + +/* see sph_jh.h */ +void +sph_jh384(void *cc, const void *data, size_t len) +{ + jh_core(cc, data, len); +} + +/* see sph_jh.h */ +void +sph_jh384_close(void *cc, void *dst) +{ + jh_close(cc, 0, 0, dst, 12, IV384); +} + +/* see sph_jh.h */ +void +sph_jh384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + jh_close(cc, ub, n, dst, 12, IV384); +} + +/* see sph_jh.h */ +void +sph_jh512_init(void *cc) +{ + jh_init(cc, IV512); +} + +/* see sph_jh.h */ +void +sph_jh512(void *cc, const void *data, size_t len) +{ + jh_core(cc, data, len); +} + +/* see sph_jh.h */ +void +sph_jh512_close(void *cc, void *dst) +{ + jh_close(cc, 0, 0, dst, 16, IV512); +} + +/* see sph_jh.h */ +void +sph_jh512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + jh_close(cc, ub, n, dst, 16, IV512); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/json/LICENSE.txt b/src/json/LICENSE.txt new file mode 100644 index 0000000..797d536 --- /dev/null +++ b/src/json/LICENSE.txt @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2007 - 2009 John W. Wilkinson + +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. diff --git a/src/json/json_spirit.h b/src/json/json_spirit.h new file mode 100644 index 0000000..ac1879d --- /dev/null +++ b/src/json/json_spirit.h @@ -0,0 +1,18 @@ +#ifndef JSON_SPIRIT +#define JSON_SPIRIT + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_reader.h" +#include "json_spirit_writer.h" +#include "json_spirit_utils.h" + +#endif diff --git a/src/json/json_spirit_error_position.h b/src/json/json_spirit_error_position.h new file mode 100644 index 0000000..1720850 --- /dev/null +++ b/src/json/json_spirit_error_position.h @@ -0,0 +1,54 @@ +#ifndef JSON_SPIRIT_ERROR_POSITION +#define JSON_SPIRIT_ERROR_POSITION + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +namespace json_spirit +{ + // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. + // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" + // functions that return a bool. + // + struct Error_position + { + Error_position(); + Error_position( unsigned int line, unsigned int column, const std::string& reason ); + bool operator==( const Error_position& lhs ) const; + unsigned int line_; + unsigned int column_; + std::string reason_; + }; + + inline Error_position::Error_position() + : line_( 0 ) + , column_( 0 ) + { + } + + inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) + : line_( line ) + , column_( column ) + , reason_( reason ) + { + } + + inline bool Error_position::operator==( const Error_position& lhs ) const + { + if( this == &lhs ) return true; + + return ( reason_ == lhs.reason_ ) && + ( line_ == lhs.line_ ) && + ( column_ == lhs.column_ ); +} +} + +#endif diff --git a/src/json/json_spirit_reader.cpp b/src/json/json_spirit_reader.cpp new file mode 100644 index 0000000..aa4f637 --- /dev/null +++ b/src/json/json_spirit_reader.cpp @@ -0,0 +1,137 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_reader.h" +#include "json_spirit_reader_template.h" + +using namespace json_spirit; + +bool json_spirit::read( const std::string& s, Value& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, Value& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, Value& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, Value& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif + +bool json_spirit::read( const std::string& s, mValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, mValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, mValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, mValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wmValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wmValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif diff --git a/src/json/json_spirit_reader.h b/src/json/json_spirit_reader.h new file mode 100644 index 0000000..96494a9 --- /dev/null +++ b/src/json/json_spirit_reader.h @@ -0,0 +1,62 @@ +#ifndef JSON_SPIRIT_READER +#define JSON_SPIRIT_READER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" +#include + +namespace json_spirit +{ + // functions to reads a JSON values + + bool read( const std::string& s, Value& value ); + bool read( std::istream& is, Value& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + + void read_or_throw( const std::string& s, Value& value ); + void read_or_throw( std::istream& is, Value& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wValue& value ); + bool read( std::wistream& is, wValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + + void read_or_throw( const std::wstring& s, wValue& value ); + void read_or_throw( std::wistream& is, wValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + +#endif + + bool read( const std::string& s, mValue& value ); + bool read( std::istream& is, mValue& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + + void read_or_throw( const std::string& s, mValue& value ); + void read_or_throw( std::istream& is, mValue& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wmValue& value ); + bool read( std::wistream& is, wmValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + + void read_or_throw( const std::wstring& s, wmValue& value ); + void read_or_throw( std::wistream& is, wmValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + +#endif +} + +#endif diff --git a/src/json/json_spirit_reader_template.h b/src/json/json_spirit_reader_template.h new file mode 100644 index 0000000..4dec00e --- /dev/null +++ b/src/json/json_spirit_reader_template.h @@ -0,0 +1,612 @@ +#ifndef JSON_SPIRIT_READER_TEMPLATE +#define JSON_SPIRIT_READER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" + +//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread + +#include +#include +#include + +#if BOOST_VERSION >= 103800 + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit::classic +#else + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit +#endif + +namespace json_spirit +{ + const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); + const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >(); + + template< class Iter_type > + bool is_eq( Iter_type first, Iter_type last, const char* c_str ) + { + for( Iter_type i = first; i != last; ++i, ++c_str ) + { + if( *c_str == 0 ) return false; + + if( *i != *c_str ) return false; + } + + return true; + } + + template< class Char_type > + Char_type hex_to_num( const Char_type c ) + { + if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; + if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; + if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; + return 0; + } + + template< class Char_type, class Iter_type > + Char_type hex_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); + } + + template< class Char_type, class Iter_type > + Char_type unicode_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + const Char_type c3( *( ++begin ) ); + const Char_type c4( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 12 ) + + ( hex_to_num( c2 ) << 8 ) + + ( hex_to_num( c3 ) << 4 ) + + hex_to_num( c4 ); + } + + template< class String_type > + void append_esc_char_and_incr_iter( String_type& s, + typename String_type::const_iterator& begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::value_type Char_type; + + const Char_type c2( *begin ); + + switch( c2 ) + { + case 't': s += '\t'; break; + case 'b': s += '\b'; break; + case 'f': s += '\f'; break; + case 'n': s += '\n'; break; + case 'r': s += '\r'; break; + case '\\': s += '\\'; break; + case '/': s += '/'; break; + case '"': s += '"'; break; + case 'x': + { + if( end - begin >= 3 ) // expecting "xHH..." + { + s += hex_str_to_char< Char_type >( begin ); + } + break; + } + case 'u': + { + if( end - begin >= 5 ) // expecting "uHHHH..." + { + s += unicode_str_to_char< Char_type >( begin ); + } + break; + } + } + } + + template< class String_type > + String_type substitute_esc_chars( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::const_iterator Iter_type; + + if( end - begin < 2 ) return String_type( begin, end ); + + String_type result; + + result.reserve( end - begin ); + + const Iter_type end_minus_1( end - 1 ); + + Iter_type substr_start = begin; + Iter_type i = begin; + + for( ; i < end_minus_1; ++i ) + { + if( *i == '\\' ) + { + result.append( substr_start, i ); + + ++i; // skip the '\' + + append_esc_char_and_incr_iter( result, i, end ); + + substr_start = i + 1; + } + } + + result.append( substr_start, end ); + + return result; + } + + template< class String_type > + String_type get_str_( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + assert( end - begin >= 2 ); + + typedef typename String_type::const_iterator Iter_type; + + Iter_type str_without_quotes( ++begin ); + Iter_type end_without_quotes( --end ); + + return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); + } + + inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) + { + return get_str_< std::string >( begin, end ); + } + + inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) + { + return get_str_< std::wstring >( begin, end ); + } + + template< class String_type, class Iter_type > + String_type get_str( Iter_type begin, Iter_type end ) + { + const String_type tmp( begin, end ); // convert multipass iterators to string iterators + + return get_str( tmp.begin(), tmp.end() ); + } + + // this class's methods get called by the spirit parse resulting + // in the creation of a JSON object or array + // + // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator + // + template< class Value_type, class Iter_type > + class Semantic_actions + { + public: + + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + + Semantic_actions( Value_type& value ) + : value_( value ) + , current_p_( 0 ) + { + } + + void begin_obj( Char_type c ) + { + assert( c == '{' ); + + begin_compound< Object_type >(); + } + + void end_obj( Char_type c ) + { + assert( c == '}' ); + + end_compound(); + } + + void begin_array( Char_type c ) + { + assert( c == '[' ); + + begin_compound< Array_type >(); + } + + void end_array( Char_type c ) + { + assert( c == ']' ); + + end_compound(); + } + + void new_name( Iter_type begin, Iter_type end ) + { + assert( current_p_->type() == obj_type ); + + name_ = get_str< String_type >( begin, end ); + } + + void new_str( Iter_type begin, Iter_type end ) + { + add_to_current( get_str< String_type >( begin, end ) ); + } + + void new_true( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "true" ) ); + + add_to_current( true ); + } + + void new_false( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "false" ) ); + + add_to_current( false ); + } + + void new_null( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "null" ) ); + + add_to_current( Value_type() ); + } + + void new_int( boost::int64_t i ) + { + add_to_current( i ); + } + + void new_uint64( boost::uint64_t ui ) + { + add_to_current( ui ); + } + + void new_real( double d ) + { + add_to_current( d ); + } + + private: + + Semantic_actions& operator=( const Semantic_actions& ); + // to prevent "assignment operator could not be generated" warning + + Value_type* add_first( const Value_type& value ) + { + assert( current_p_ == 0 ); + + value_ = value; + current_p_ = &value_; + return current_p_; + } + + template< class Array_or_obj > + void begin_compound() + { + if( current_p_ == 0 ) + { + add_first( Array_or_obj() ); + } + else + { + stack_.push_back( current_p_ ); + + Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place + + current_p_ = add_to_current( new_array_or_obj ); + } + } + + void end_compound() + { + if( current_p_ != &value_ ) + { + current_p_ = stack_.back(); + + stack_.pop_back(); + } + } + + Value_type* add_to_current( const Value_type& value ) + { + if( current_p_ == 0 ) + { + return add_first( value ); + } + else if( current_p_->type() == array_type ) + { + current_p_->get_array().push_back( value ); + + return ¤t_p_->get_array().back(); + } + + assert( current_p_->type() == obj_type ); + + return &Config_type::add( current_p_->get_obj(), name_, value ); + } + + Value_type& value_; // this is the object or array that is being created + Value_type* current_p_; // the child object or array that is currently being constructed + + std::vector< Value_type* > stack_; // previous child objects and arrays + + String_type name_; // of current name/value pair + }; + + template< typename Iter_type > + void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) + { + throw Error_position( i.get_position().line, i.get_position().column, reason ); + } + + template< typename Iter_type > + void throw_error( Iter_type i, const std::string& reason ) + { + throw reason; + } + + // the spirit grammer + // + template< class Value_type, class Iter_type > + class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > + { + public: + + typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; + + Json_grammer( Semantic_actions_t& semantic_actions ) + : actions_( semantic_actions ) + { + } + + static void throw_not_value( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a value" ); + } + + static void throw_not_array( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an array" ); + } + + static void throw_not_object( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an object" ); + } + + static void throw_not_pair( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a pair" ); + } + + static void throw_not_colon( Iter_type begin, Iter_type end ) + { + throw_error( begin, "no colon in pair" ); + } + + static void throw_not_string( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a string" ); + } + + template< typename ScannerT > + class definition + { + public: + + definition( const Json_grammer& self ) + { + using namespace spirit_namespace; + + typedef typename Value_type::String_type::value_type Char_type; + + // first we convert the semantic action class methods to functors with the + // parameter signature expected by spirit + + typedef boost::function< void( Char_type ) > Char_action; + typedef boost::function< void( Iter_type, Iter_type ) > Str_action; + typedef boost::function< void( double ) > Real_action; + typedef boost::function< void( boost::int64_t ) > Int_action; + typedef boost::function< void( boost::uint64_t ) > Uint64_action; + + Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); + Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); + Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); + Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); + Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); + Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); + Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); + Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); + Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); + Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); + Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); + Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); + + // actual grammer + + json_ + = value_ | eps_p[ &throw_not_value ] + ; + + value_ + = string_[ new_str ] + | number_ + | object_ + | array_ + | str_p( "true" ) [ new_true ] + | str_p( "false" )[ new_false ] + | str_p( "null" ) [ new_null ] + ; + + object_ + = ch_p('{')[ begin_obj ] + >> !members_ + >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) + ; + + members_ + = pair_ >> *( ',' >> pair_ ) + ; + + pair_ + = string_[ new_name ] + >> ( ':' | eps_p[ &throw_not_colon ] ) + >> ( value_ | eps_p[ &throw_not_value ] ) + ; + + array_ + = ch_p('[')[ begin_array ] + >> !elements_ + >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) + ; + + elements_ + = value_ >> *( ',' >> value_ ) + ; + + string_ + = lexeme_d // this causes white space inside a string to be retained + [ + confix_p + ( + '"', + *lex_escape_ch_p, + '"' + ) + ] + ; + + number_ + = strict_real_p[ new_real ] + | int64_p [ new_int ] + | uint64_p [ new_uint64 ] + ; + } + + spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; + + const spirit_namespace::rule< ScannerT >& start() const { return json_; } + }; + + private: + + Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning + + Semantic_actions_t& actions_; + }; + + template< class Iter_type, class Value_type > + Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + Semantic_actions< Value_type, Iter_type > semantic_actions( value ); + + const spirit_namespace::parse_info< Iter_type > info = + spirit_namespace::parse( begin, end, + Json_grammer< Value_type, Iter_type >( semantic_actions ), + spirit_namespace::space_p ); + + if( !info.hit ) + { + assert( false ); // in theory exception should already have been thrown + throw_error( info.stop, "error" ); + } + + return info.stop; + } + + template< class Iter_type, class Value_type > + void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; + + const Posn_iter_t posn_begin( begin, end ); + const Posn_iter_t posn_end( end, end ); + + read_range_or_throw( posn_begin, posn_end, value ); + } + + template< class Iter_type, class Value_type > + bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) + { + try + { + begin = read_range_or_throw( begin, end, value ); + + return true; + } + catch( ... ) + { + return false; + } + } + + template< class String_type, class Value_type > + void read_string_or_throw( const String_type& s, Value_type& value ) + { + add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); + } + + template< class String_type, class Value_type > + bool read_string( const String_type& s, Value_type& value ) + { + typename String_type::const_iterator begin = s.begin(); + + return read_range( begin, s.end(), value ); + } + + template< class Istream_type > + struct Multi_pass_iters + { + typedef typename Istream_type::char_type Char_type; + typedef std::istream_iterator< Char_type, Char_type > istream_iter; + typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; + + Multi_pass_iters( Istream_type& is ) + { + is.unsetf( std::ios::skipws ); + + begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); + end_ = spirit_namespace::make_multi_pass( istream_iter() ); + } + + Mp_iter begin_; + Mp_iter end_; + }; + + template< class Istream_type, class Value_type > + bool read_stream( Istream_type& is, Value_type& value ) + { + Multi_pass_iters< Istream_type > mp_iters( is ); + + return read_range( mp_iters.begin_, mp_iters.end_, value ); + } + + template< class Istream_type, class Value_type > + void read_stream_or_throw( Istream_type& is, Value_type& value ) + { + const Multi_pass_iters< Istream_type > mp_iters( is ); + + add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); + } +} + +#endif diff --git a/src/json/json_spirit_stream_reader.h b/src/json/json_spirit_stream_reader.h new file mode 100644 index 0000000..7e59c9a --- /dev/null +++ b/src/json/json_spirit_stream_reader.h @@ -0,0 +1,70 @@ +#ifndef JSON_SPIRIT_READ_STREAM +#define JSON_SPIRIT_READ_STREAM + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_reader_template.h" + +namespace json_spirit +{ + // these classes allows you to read multiple top level contiguous values from a stream, + // the normal stream read functions have a bug that prevent multiple top level values + // from being read unless they are separated by spaces + + template< class Istream_type, class Value_type > + class Stream_reader + { + public: + + Stream_reader( Istream_type& is ) + : iters_( is ) + { + } + + bool read_next( Value_type& value ) + { + return read_range( iters_.begin_, iters_.end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + + Mp_iters iters_; + }; + + template< class Istream_type, class Value_type > + class Stream_reader_thrower + { + public: + + Stream_reader_thrower( Istream_type& is ) + : iters_( is ) + , posn_begin_( iters_.begin_, iters_.end_ ) + , posn_end_( iters_.end_, iters_.end_ ) + { + } + + void read_next( Value_type& value ) + { + posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; + + Mp_iters iters_; + Posn_iter_t posn_begin_, posn_end_; + }; +} + +#endif diff --git a/src/json/json_spirit_utils.h b/src/json/json_spirit_utils.h new file mode 100644 index 0000000..553e3b9 --- /dev/null +++ b/src/json/json_spirit_utils.h @@ -0,0 +1,61 @@ +#ifndef JSON_SPIRIT_UTILS +#define JSON_SPIRIT_UTILS + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + template< class Obj_t, class Map_t > + void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) + { + mp_obj.clear(); + + for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + mp_obj[ i->name_ ] = i->value_; + } + } + + template< class Obj_t, class Map_t > + void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) + { + obj.clear(); + + for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) + { + obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); + } + } + + typedef std::map< std::string, Value > Mapped_obj; + +#ifndef BOOST_NO_STD_WSTRING + typedef std::map< std::wstring, wValue > wMapped_obj; +#endif + + template< class Object_type, class String_type > + const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) + { + for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + if( i->name_ == name ) + { + return i->value_; + } + } + + return Object_type::value_type::Value_type::null; + } +} + +#endif diff --git a/src/json/json_spirit_value.cpp b/src/json/json_spirit_value.cpp new file mode 100644 index 0000000..44d2f06 --- /dev/null +++ b/src/json/json_spirit_value.cpp @@ -0,0 +1,8 @@ +/* Copyright (c) 2007 John W Wilkinson + + This source code can be used for any purpose as long as + this comment is retained. */ + +// json spirit version 2.00 + +#include "json_spirit_value.h" diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h new file mode 100644 index 0000000..7e83a2a --- /dev/null +++ b/src/json/json_spirit_value.h @@ -0,0 +1,534 @@ +#ifndef JSON_SPIRIT_VALUE +#define JSON_SPIRIT_VALUE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace json_spirit +{ + enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; + static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"}; + + template< class Config > // Config determines whether the value uses std::string or std::wstring and + // whether JSON Objects are represented as vectors or maps + class Value_impl + { + public: + + typedef Config Config_type; + typedef typename Config::String_type String_type; + typedef typename Config::Object_type Object; + typedef typename Config::Array_type Array; + typedef typename String_type::const_pointer Const_str_ptr; // eg const char* + + Value_impl(); // creates null value + Value_impl( Const_str_ptr value ); + Value_impl( const String_type& value ); + Value_impl( const Object& value ); + Value_impl( const Array& value ); + Value_impl( bool value ); + Value_impl( int value ); + Value_impl( boost::int64_t value ); + Value_impl( boost::uint64_t value ); + Value_impl( double value ); + + Value_impl( const Value_impl& other ); + + bool operator==( const Value_impl& lhs ) const; + + Value_impl& operator=( const Value_impl& lhs ); + + Value_type type() const; + + bool is_uint64() const; + bool is_null() const; + + const String_type& get_str() const; + const Object& get_obj() const; + const Array& get_array() const; + bool get_bool() const; + int get_int() const; + boost::int64_t get_int64() const; + boost::uint64_t get_uint64() const; + double get_real() const; + + Object& get_obj(); + Array& get_array(); + + template< typename T > T get_value() const; // example usage: int i = value.get_value< int >(); + // or double d = value.get_value< double >(); + + static const Value_impl null; + + private: + + void check_type( const Value_type vtype ) const; + + typedef boost::variant< String_type, + boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, + bool, boost::int64_t, double > Variant; + + Value_type type_; + Variant v_; + bool is_uint64_; + }; + + // vector objects + + template< class Config > + struct Pair_impl + { + typedef typename Config::String_type String_type; + typedef typename Config::Value_type Value_type; + + Pair_impl( const String_type& name, const Value_type& value ); + + bool operator==( const Pair_impl& lhs ) const; + + String_type name_; + Value_type value_; + }; + + template< class String > + struct Config_vector + { + typedef String String_type; + typedef Value_impl< Config_vector > Value_type; + typedef Pair_impl < Config_vector > Pair_type; + typedef std::vector< Value_type > Array_type; + typedef std::vector< Pair_type > Object_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + obj.push_back( Pair_type( name , value ) ); + + return obj.back().value_; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.name_; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.value_; + } + }; + + // typedefs for ASCII + + typedef Config_vector< std::string > Config; + + typedef Config::Value_type Value; + typedef Config::Pair_type Pair; + typedef Config::Object_type Object; + typedef Config::Array_type Array; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_vector< std::wstring > wConfig; + + typedef wConfig::Value_type wValue; + typedef wConfig::Pair_type wPair; + typedef wConfig::Object_type wObject; + typedef wConfig::Array_type wArray; +#endif + + // map objects + + template< class String > + struct Config_map + { + typedef String String_type; + typedef Value_impl< Config_map > Value_type; + typedef std::vector< Value_type > Array_type; + typedef std::map< String_type, Value_type > Object_type; + typedef typename Object_type::value_type Pair_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + return obj[ name ] = value; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.first; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.second; + } + }; + + // typedefs for ASCII + + typedef Config_map< std::string > mConfig; + + typedef mConfig::Value_type mValue; + typedef mConfig::Object_type mObject; + typedef mConfig::Array_type mArray; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_map< std::wstring > wmConfig; + + typedef wmConfig::Value_type wmValue; + typedef wmConfig::Object_type wmObject; + typedef wmConfig::Array_type wmArray; + +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////// + // + // implementation + + template< class Config > + const Value_impl< Config > Value_impl< Config >::null; + + template< class Config > + Value_impl< Config >::Value_impl() + : type_( null_type ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Const_str_ptr value ) + : type_( str_type ) + , v_( String_type( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const String_type& value ) + : type_( str_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Object& value ) + : type_( obj_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Array& value ) + : type_( array_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( bool value ) + : type_( bool_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( int value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::int64_t value ) + : type_( int_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::uint64_t value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( true ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( double value ) + : type_( real_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) + : type_( other.type() ) + , v_( other.v_ ) + , is_uint64_( other.is_uint64_ ) + { + } + + template< class Config > + Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) + { + Value_impl tmp( lhs ); + + std::swap( type_, tmp.type_ ); + std::swap( v_, tmp.v_ ); + std::swap( is_uint64_, tmp.is_uint64_ ); + + return *this; + } + + template< class Config > + bool Value_impl< Config >::operator==( const Value_impl& lhs ) const + { + if( this == &lhs ) return true; + + if( type() != lhs.type() ) return false; + + return v_ == lhs.v_; + } + + template< class Config > + Value_type Value_impl< Config >::type() const + { + return type_; + } + + template< class Config > + bool Value_impl< Config >::is_uint64() const + { + return is_uint64_; + } + + template< class Config > + bool Value_impl< Config >::is_null() const + { + return type() == null_type; + } + + template< class Config > + void Value_impl< Config >::check_type( const Value_type vtype ) const + { + if( type() != vtype ) + { + std::ostringstream os; + + ///// Bitcoin: Tell the types by name instead of by number + os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype]; + + throw std::runtime_error( os.str() ); + } + } + + template< class Config > + const typename Config::String_type& Value_impl< Config >::get_str() const + { + check_type( str_type ); + + return *boost::get< String_type >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + bool Value_impl< Config >::get_bool() const + { + check_type( bool_type ); + + return boost::get< bool >( v_ ); + } + + template< class Config > + int Value_impl< Config >::get_int() const + { + check_type( int_type ); + + return static_cast< int >( get_int64() ); + } + + template< class Config > + boost::int64_t Value_impl< Config >::get_int64() const + { + check_type( int_type ); + + return boost::get< boost::int64_t >( v_ ); + } + + template< class Config > + boost::uint64_t Value_impl< Config >::get_uint64() const + { + check_type( int_type ); + + return static_cast< boost::uint64_t >( get_int64() ); + } + + template< class Config > + double Value_impl< Config >::get_real() const + { + if( type() == int_type ) + { + return is_uint64() ? static_cast< double >( get_uint64() ) + : static_cast< double >( get_int64() ); + } + + check_type( real_type ); + + return boost::get< double >( v_ ); + } + + template< class Config > + typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + typename Value_impl< Config >::Array& Value_impl< Config >::get_array() + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) + : name_( name ) + , value_( value ) + { + } + + template< class Config > + bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const + { + if( this == &lhs ) return true; + + return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); + } + + // converts a C string, ie. 8 bit char array, to a string object + // + template < class String_type > + String_type to_str( const char* c_str ) + { + String_type result; + + for( const char* p = c_str; *p != 0; ++p ) + { + result += *p; + } + + return result; + } + + // + + namespace internal_ + { + template< typename T > + struct Type_to_type + { + }; + + template< class Value > + int get_value( const Value& value, Type_to_type< int > ) + { + return value.get_int(); + } + + template< class Value > + boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > ) + { + return value.get_int64(); + } + + template< class Value > + boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > ) + { + return value.get_uint64(); + } + + template< class Value > + double get_value( const Value& value, Type_to_type< double > ) + { + return value.get_real(); + } + + template< class Value > + typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) + { + return value.get_str(); + } + + template< class Value > + typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) + { + return value.get_array(); + } + + template< class Value > + typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) + { + return value.get_obj(); + } + + template< class Value > + bool get_value( const Value& value, Type_to_type< bool > ) + { + return value.get_bool(); + } + } + + template< class Config > + template< typename T > + T Value_impl< Config >::get_value() const + { + return internal_::get_value( *this, internal_::Type_to_type< T >() ); + } +} + +#endif diff --git a/src/json/json_spirit_writer.cpp b/src/json/json_spirit_writer.cpp new file mode 100644 index 0000000..d24a632 --- /dev/null +++ b/src/json/json_spirit_writer.cpp @@ -0,0 +1,95 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_writer.h" +#include "json_spirit_writer_template.h" + +void json_spirit::write( const Value& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const Value& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const Value& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const Value& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wValue& value ) +{ + return write_string( value, true ); +} + +#endif + +void json_spirit::write( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const mValue& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const mValue& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wmValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wmValue& value ) +{ + return write_string( value, true ); +} + +#endif diff --git a/src/json/json_spirit_writer.h b/src/json/json_spirit_writer.h new file mode 100644 index 0000000..52e1406 --- /dev/null +++ b/src/json/json_spirit_writer.h @@ -0,0 +1,50 @@ +#ifndef JSON_SPIRIT_WRITER +#define JSON_SPIRIT_WRITER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + // functions to convert JSON Values to text, + // the "formatted" versions add whitespace to format the output nicely + + void write ( const Value& value, std::ostream& os ); + void write_formatted( const Value& value, std::ostream& os ); + std::string write ( const Value& value ); + std::string write_formatted( const Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wValue& value, std::wostream& os ); + void write_formatted( const wValue& value, std::wostream& os ); + std::wstring write ( const wValue& value ); + std::wstring write_formatted( const wValue& value ); + +#endif + + void write ( const mValue& value, std::ostream& os ); + void write_formatted( const mValue& value, std::ostream& os ); + std::string write ( const mValue& value ); + std::string write_formatted( const mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wmValue& value, std::wostream& os ); + void write_formatted( const wmValue& value, std::wostream& os ); + std::wstring write ( const wmValue& value ); + std::wstring write_formatted( const wmValue& value ); + +#endif +} + +#endif diff --git a/src/json/json_spirit_writer_template.h b/src/json/json_spirit_writer_template.h new file mode 100644 index 0000000..28c49dd --- /dev/null +++ b/src/json/json_spirit_writer_template.h @@ -0,0 +1,248 @@ +#ifndef JSON_SPIRIT_WRITER_TEMPLATE +#define JSON_SPIRIT_WRITER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" + +#include +#include +#include + +namespace json_spirit +{ + inline char to_hex_char( unsigned int c ) + { + assert( c <= 0xF ); + + const char ch = static_cast< char >( c ); + + if( ch < 10 ) return '0' + ch; + + return 'A' - 10 + ch; + } + + template< class String_type > + String_type non_printable_to_string( unsigned int c ) + { + typedef typename String_type::value_type Char_type; + + String_type result( 6, '\\' ); + + result[1] = 'u'; + + result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 2 ] = to_hex_char( c & 0x000F ); + + return result; + } + + template< typename Char_type, class String_type > + bool add_esc_char( Char_type c, String_type& s ) + { + switch( c ) + { + case '"': s += to_str< String_type >( "\\\"" ); return true; + case '\\': s += to_str< String_type >( "\\\\" ); return true; + case '\b': s += to_str< String_type >( "\\b" ); return true; + case '\f': s += to_str< String_type >( "\\f" ); return true; + case '\n': s += to_str< String_type >( "\\n" ); return true; + case '\r': s += to_str< String_type >( "\\r" ); return true; + case '\t': s += to_str< String_type >( "\\t" ); return true; + } + + return false; + } + + template< class String_type > + String_type add_esc_chars( const String_type& s ) + { + typedef typename String_type::const_iterator Iter_type; + typedef typename String_type::value_type Char_type; + + String_type result; + + const Iter_type end( s.end() ); + + for( Iter_type i = s.begin(); i != end; ++i ) + { + const Char_type c( *i ); + + if( add_esc_char( c, result ) ) continue; + + const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); + + if( iswprint( unsigned_c ) ) + { + result += c; + } + else + { + result += non_printable_to_string< String_type >( unsigned_c ); + } + } + + return result; + } + + // this class generates the JSON text, + // it keeps track of the indentation level etc. + // + template< class Value_type, class Ostream_type > + class Generator + { + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + typedef typename Object_type::value_type Obj_member_type; + + public: + + Generator( const Value_type& value, Ostream_type& os, bool pretty ) + : os_( os ) + , indentation_level_( 0 ) + , pretty_( pretty ) + { + output( value ); + } + + private: + + void output( const Value_type& value ) + { + switch( value.type() ) + { + case obj_type: output( value.get_obj() ); break; + case array_type: output( value.get_array() ); break; + case str_type: output( value.get_str() ); break; + case bool_type: output( value.get_bool() ); break; + case int_type: output_int( value ); break; + + /// Bitcoin: Added std::fixed and changed precision from 16 to 8 + case real_type: os_ << std::showpoint << std::fixed << std::setprecision(8) + << value.get_real(); break; + + case null_type: os_ << "null"; break; + default: assert( false ); + } + } + + void output( const Object_type& obj ) + { + output_array_or_obj( obj, '{', '}' ); + } + + void output( const Array_type& arr ) + { + output_array_or_obj( arr, '[', ']' ); + } + + void output( const Obj_member_type& member ) + { + output( Config_type::get_name( member ) ); space(); + os_ << ':'; space(); + output( Config_type::get_value( member ) ); + } + + void output_int( const Value_type& value ) + { + if( value.is_uint64() ) + { + os_ << value.get_uint64(); + } + else + { + os_ << value.get_int64(); + } + } + + void output( const String_type& s ) + { + os_ << '"' << add_esc_chars( s ) << '"'; + } + + void output( bool b ) + { + os_ << to_str< String_type >( b ? "true" : "false" ); + } + + template< class T > + void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) + { + os_ << start_char; new_line(); + + ++indentation_level_; + + for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) + { + indent(); output( *i ); + + typename T::const_iterator next = i; + + if( ++next != t.end()) + { + os_ << ','; + } + + new_line(); + } + + --indentation_level_; + + indent(); os_ << end_char; + } + + void indent() + { + if( !pretty_ ) return; + + for( int i = 0; i < indentation_level_; ++i ) + { + os_ << " "; + } + } + + void space() + { + if( pretty_ ) os_ << ' '; + } + + void new_line() + { + if( pretty_ ) os_ << '\n'; + } + + Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning + + Ostream_type& os_; + int indentation_level_; + bool pretty_; + }; + + template< class Value_type, class Ostream_type > + void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) + { + Generator< Value_type, Ostream_type >( value, os, pretty ); + } + + template< class Value_type > + typename Value_type::String_type write_string( const Value_type& value, bool pretty ) + { + typedef typename Value_type::String_type::value_type Char_type; + + std::basic_ostringstream< Char_type > os; + + write_stream( value, os, pretty ); + + return os.str(); + } +} + +#endif diff --git a/src/keccak.c b/src/keccak.c new file mode 100644 index 0000000..cff9f87 --- /dev/null +++ b/src/keccak.c @@ -0,0 +1,1824 @@ +/* $Id: keccak.c 259 2011-07-19 22:11:27Z tp $ */ +/* + * Keccak 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 + */ + +#include +#include + +#include "sph_keccak.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * Parameters: + * + * SPH_KECCAK_64 use a 64-bit type + * SPH_KECCAK_UNROLL number of loops to unroll (0/undef for full unroll) + * SPH_KECCAK_INTERLEAVE use bit-interleaving (32-bit type only) + * SPH_KECCAK_NOCOPY do not copy the state into local variables + * + * If there is no usable 64-bit type, the code automatically switches + * back to the 32-bit implementation. + * + * Some tests on an Intel Core2 Q6600 (both 64-bit and 32-bit, 32 kB L1 + * code cache), a PowerPC (G3, 32 kB L1 code cache), an ARM920T core + * (16 kB L1 code cache), and a small MIPS-compatible CPU (Broadcom BCM3302, + * 8 kB L1 code cache), seem to show that the following are optimal: + * + * -- x86, 64-bit: use the 64-bit implementation, unroll 8 rounds, + * do not copy the state; unrolling 2, 6 or all rounds also provides + * near-optimal performance. + * -- x86, 32-bit: use the 32-bit implementation, unroll 6 rounds, + * interleave, do not copy the state. Unrolling 1, 2, 4 or 8 rounds + * also provides near-optimal performance. + * -- PowerPC: use the 64-bit implementation, unroll 8 rounds, + * copy the state. Unrolling 4 or 6 rounds is near-optimal. + * -- ARM: use the 64-bit implementation, unroll 2 or 4 rounds, + * copy the state. + * -- MIPS: use the 64-bit implementation, unroll 2 rounds, copy + * the state. Unrolling only 1 round is also near-optimal. + * + * Also, interleaving does not always yield actual improvements when + * using a 32-bit implementation; in particular when the architecture + * does not offer a native rotation opcode (interleaving replaces one + * 64-bit rotation with two 32-bit rotations, which is a gain only if + * there is a native 32-bit rotation opcode and not a native 64-bit + * rotation opcode; also, interleaving implies a small overhead when + * processing input words). + * + * To sum up: + * -- when possible, use the 64-bit code + * -- exception: on 32-bit x86, use 32-bit code + * -- when using 32-bit code, use interleaving + * -- copy the state, except on x86 + * -- unroll 8 rounds on "big" machine, 2 rounds on "small" machines + */ + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_KECCAK +#define SPH_SMALL_FOOTPRINT_KECCAK 1 +#endif + +/* + * By default, we select the 64-bit implementation if a 64-bit type + * is available, unless a 32-bit x86 is detected. + */ +#if !defined SPH_KECCAK_64 && SPH_64 \ + && !(defined __i386__ || SPH_I386_GCC || SPH_I386_MSVC) +#define SPH_KECCAK_64 1 +#endif + +/* + * If using a 32-bit implementation, we prefer to interleave. + */ +#if !SPH_KECCAK_64 && !defined SPH_KECCAK_INTERLEAVE +#define SPH_KECCAK_INTERLEAVE 1 +#endif + +/* + * Unroll 8 rounds on big systems, 2 rounds on small systems. + */ +#ifndef SPH_KECCAK_UNROLL +#if SPH_SMALL_FOOTPRINT_KECCAK +#define SPH_KECCAK_UNROLL 2 +#else +#define SPH_KECCAK_UNROLL 8 +#endif +#endif + +/* + * We do not want to copy the state to local variables on x86 (32-bit + * and 64-bit alike). + */ +#ifndef SPH_KECCAK_NOCOPY +#if defined __i386__ || defined __x86_64 || SPH_I386_MSVC || SPH_I386_GCC +#define SPH_KECCAK_NOCOPY 1 +#else +#define SPH_KECCAK_NOCOPY 0 +#endif +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +#if SPH_KECCAK_64 + +static const sph_u64 RC[] = { + SPH_C64(0x0000000000000001), SPH_C64(0x0000000000008082), + SPH_C64(0x800000000000808A), SPH_C64(0x8000000080008000), + SPH_C64(0x000000000000808B), SPH_C64(0x0000000080000001), + SPH_C64(0x8000000080008081), SPH_C64(0x8000000000008009), + SPH_C64(0x000000000000008A), SPH_C64(0x0000000000000088), + SPH_C64(0x0000000080008009), SPH_C64(0x000000008000000A), + SPH_C64(0x000000008000808B), SPH_C64(0x800000000000008B), + SPH_C64(0x8000000000008089), SPH_C64(0x8000000000008003), + SPH_C64(0x8000000000008002), SPH_C64(0x8000000000000080), + SPH_C64(0x000000000000800A), SPH_C64(0x800000008000000A), + SPH_C64(0x8000000080008081), SPH_C64(0x8000000000008080), + SPH_C64(0x0000000080000001), SPH_C64(0x8000000080008008) +}; + +#if SPH_KECCAK_NOCOPY + +#define a00 (kc->u.wide[ 0]) +#define a10 (kc->u.wide[ 1]) +#define a20 (kc->u.wide[ 2]) +#define a30 (kc->u.wide[ 3]) +#define a40 (kc->u.wide[ 4]) +#define a01 (kc->u.wide[ 5]) +#define a11 (kc->u.wide[ 6]) +#define a21 (kc->u.wide[ 7]) +#define a31 (kc->u.wide[ 8]) +#define a41 (kc->u.wide[ 9]) +#define a02 (kc->u.wide[10]) +#define a12 (kc->u.wide[11]) +#define a22 (kc->u.wide[12]) +#define a32 (kc->u.wide[13]) +#define a42 (kc->u.wide[14]) +#define a03 (kc->u.wide[15]) +#define a13 (kc->u.wide[16]) +#define a23 (kc->u.wide[17]) +#define a33 (kc->u.wide[18]) +#define a43 (kc->u.wide[19]) +#define a04 (kc->u.wide[20]) +#define a14 (kc->u.wide[21]) +#define a24 (kc->u.wide[22]) +#define a34 (kc->u.wide[23]) +#define a44 (kc->u.wide[24]) + +#define DECL_STATE +#define READ_STATE(sc) +#define WRITE_STATE(sc) + +#define INPUT_BUF(size) do { \ + size_t j; \ + for (j = 0; j < (size); j += 8) { \ + kc->u.wide[j >> 3] ^= sph_dec64le_aligned(buf + j); \ + } \ + } while (0) + +#define INPUT_BUF144 INPUT_BUF(144) +#define INPUT_BUF136 INPUT_BUF(136) +#define INPUT_BUF104 INPUT_BUF(104) +#define INPUT_BUF72 INPUT_BUF(72) + +#else + +#define DECL_STATE \ + sph_u64 a00, a01, a02, a03, a04; \ + sph_u64 a10, a11, a12, a13, a14; \ + sph_u64 a20, a21, a22, a23, a24; \ + sph_u64 a30, a31, a32, a33, a34; \ + sph_u64 a40, a41, a42, a43, a44; + +#define READ_STATE(state) do { \ + a00 = (state)->u.wide[ 0]; \ + a10 = (state)->u.wide[ 1]; \ + a20 = (state)->u.wide[ 2]; \ + a30 = (state)->u.wide[ 3]; \ + a40 = (state)->u.wide[ 4]; \ + a01 = (state)->u.wide[ 5]; \ + a11 = (state)->u.wide[ 6]; \ + a21 = (state)->u.wide[ 7]; \ + a31 = (state)->u.wide[ 8]; \ + a41 = (state)->u.wide[ 9]; \ + a02 = (state)->u.wide[10]; \ + a12 = (state)->u.wide[11]; \ + a22 = (state)->u.wide[12]; \ + a32 = (state)->u.wide[13]; \ + a42 = (state)->u.wide[14]; \ + a03 = (state)->u.wide[15]; \ + a13 = (state)->u.wide[16]; \ + a23 = (state)->u.wide[17]; \ + a33 = (state)->u.wide[18]; \ + a43 = (state)->u.wide[19]; \ + a04 = (state)->u.wide[20]; \ + a14 = (state)->u.wide[21]; \ + a24 = (state)->u.wide[22]; \ + a34 = (state)->u.wide[23]; \ + a44 = (state)->u.wide[24]; \ + } while (0) + +#define WRITE_STATE(state) do { \ + (state)->u.wide[ 0] = a00; \ + (state)->u.wide[ 1] = a10; \ + (state)->u.wide[ 2] = a20; \ + (state)->u.wide[ 3] = a30; \ + (state)->u.wide[ 4] = a40; \ + (state)->u.wide[ 5] = a01; \ + (state)->u.wide[ 6] = a11; \ + (state)->u.wide[ 7] = a21; \ + (state)->u.wide[ 8] = a31; \ + (state)->u.wide[ 9] = a41; \ + (state)->u.wide[10] = a02; \ + (state)->u.wide[11] = a12; \ + (state)->u.wide[12] = a22; \ + (state)->u.wide[13] = a32; \ + (state)->u.wide[14] = a42; \ + (state)->u.wide[15] = a03; \ + (state)->u.wide[16] = a13; \ + (state)->u.wide[17] = a23; \ + (state)->u.wide[18] = a33; \ + (state)->u.wide[19] = a43; \ + (state)->u.wide[20] = a04; \ + (state)->u.wide[21] = a14; \ + (state)->u.wide[22] = a24; \ + (state)->u.wide[23] = a34; \ + (state)->u.wide[24] = a44; \ + } while (0) + +#define INPUT_BUF144 do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + a41 ^= sph_dec64le_aligned(buf + 72); \ + a02 ^= sph_dec64le_aligned(buf + 80); \ + a12 ^= sph_dec64le_aligned(buf + 88); \ + a22 ^= sph_dec64le_aligned(buf + 96); \ + a32 ^= sph_dec64le_aligned(buf + 104); \ + a42 ^= sph_dec64le_aligned(buf + 112); \ + a03 ^= sph_dec64le_aligned(buf + 120); \ + a13 ^= sph_dec64le_aligned(buf + 128); \ + a23 ^= sph_dec64le_aligned(buf + 136); \ + } while (0) + +#define INPUT_BUF136 do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + a41 ^= sph_dec64le_aligned(buf + 72); \ + a02 ^= sph_dec64le_aligned(buf + 80); \ + a12 ^= sph_dec64le_aligned(buf + 88); \ + a22 ^= sph_dec64le_aligned(buf + 96); \ + a32 ^= sph_dec64le_aligned(buf + 104); \ + a42 ^= sph_dec64le_aligned(buf + 112); \ + a03 ^= sph_dec64le_aligned(buf + 120); \ + a13 ^= sph_dec64le_aligned(buf + 128); \ + } while (0) + +#define INPUT_BUF104 do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + a41 ^= sph_dec64le_aligned(buf + 72); \ + a02 ^= sph_dec64le_aligned(buf + 80); \ + a12 ^= sph_dec64le_aligned(buf + 88); \ + a22 ^= sph_dec64le_aligned(buf + 96); \ + } while (0) + +#define INPUT_BUF72 do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + } while (0) + +#define INPUT_BUF(lim) do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + if ((lim) == 72) \ + break; \ + a41 ^= sph_dec64le_aligned(buf + 72); \ + a02 ^= sph_dec64le_aligned(buf + 80); \ + a12 ^= sph_dec64le_aligned(buf + 88); \ + a22 ^= sph_dec64le_aligned(buf + 96); \ + if ((lim) == 104) \ + break; \ + a32 ^= sph_dec64le_aligned(buf + 104); \ + a42 ^= sph_dec64le_aligned(buf + 112); \ + a03 ^= sph_dec64le_aligned(buf + 120); \ + a13 ^= sph_dec64le_aligned(buf + 128); \ + if ((lim) == 136) \ + break; \ + a23 ^= sph_dec64le_aligned(buf + 136); \ + } while (0) + +#endif + +#define DECL64(x) sph_u64 x +#define MOV64(d, s) (d = s) +#define XOR64(d, a, b) (d = a ^ b) +#define AND64(d, a, b) (d = a & b) +#define OR64(d, a, b) (d = a | b) +#define NOT64(d, s) (d = SPH_T64(~s)) +#define ROL64(d, v, n) (d = SPH_ROTL64(v, n)) +#define XOR64_IOTA XOR64 + +#else + +static const struct { + sph_u32 high, low; +} RC[] = { +#if SPH_KECCAK_INTERLEAVE + { SPH_C32(0x00000000), SPH_C32(0x00000001) }, + { SPH_C32(0x00000089), SPH_C32(0x00000000) }, + { SPH_C32(0x8000008B), SPH_C32(0x00000000) }, + { SPH_C32(0x80008080), SPH_C32(0x00000000) }, + { SPH_C32(0x0000008B), SPH_C32(0x00000001) }, + { SPH_C32(0x00008000), SPH_C32(0x00000001) }, + { SPH_C32(0x80008088), SPH_C32(0x00000001) }, + { SPH_C32(0x80000082), SPH_C32(0x00000001) }, + { SPH_C32(0x0000000B), SPH_C32(0x00000000) }, + { SPH_C32(0x0000000A), SPH_C32(0x00000000) }, + { SPH_C32(0x00008082), SPH_C32(0x00000001) }, + { SPH_C32(0x00008003), SPH_C32(0x00000000) }, + { SPH_C32(0x0000808B), SPH_C32(0x00000001) }, + { SPH_C32(0x8000000B), SPH_C32(0x00000001) }, + { SPH_C32(0x8000008A), SPH_C32(0x00000001) }, + { SPH_C32(0x80000081), SPH_C32(0x00000001) }, + { SPH_C32(0x80000081), SPH_C32(0x00000000) }, + { SPH_C32(0x80000008), SPH_C32(0x00000000) }, + { SPH_C32(0x00000083), SPH_C32(0x00000000) }, + { SPH_C32(0x80008003), SPH_C32(0x00000000) }, + { SPH_C32(0x80008088), SPH_C32(0x00000001) }, + { SPH_C32(0x80000088), SPH_C32(0x00000000) }, + { SPH_C32(0x00008000), SPH_C32(0x00000001) }, + { SPH_C32(0x80008082), SPH_C32(0x00000000) } +#else + { SPH_C32(0x00000000), SPH_C32(0x00000001) }, + { SPH_C32(0x00000000), SPH_C32(0x00008082) }, + { SPH_C32(0x80000000), SPH_C32(0x0000808A) }, + { SPH_C32(0x80000000), SPH_C32(0x80008000) }, + { SPH_C32(0x00000000), SPH_C32(0x0000808B) }, + { SPH_C32(0x00000000), SPH_C32(0x80000001) }, + { SPH_C32(0x80000000), SPH_C32(0x80008081) }, + { SPH_C32(0x80000000), SPH_C32(0x00008009) }, + { SPH_C32(0x00000000), SPH_C32(0x0000008A) }, + { SPH_C32(0x00000000), SPH_C32(0x00000088) }, + { SPH_C32(0x00000000), SPH_C32(0x80008009) }, + { SPH_C32(0x00000000), SPH_C32(0x8000000A) }, + { SPH_C32(0x00000000), SPH_C32(0x8000808B) }, + { SPH_C32(0x80000000), SPH_C32(0x0000008B) }, + { SPH_C32(0x80000000), SPH_C32(0x00008089) }, + { SPH_C32(0x80000000), SPH_C32(0x00008003) }, + { SPH_C32(0x80000000), SPH_C32(0x00008002) }, + { SPH_C32(0x80000000), SPH_C32(0x00000080) }, + { SPH_C32(0x00000000), SPH_C32(0x0000800A) }, + { SPH_C32(0x80000000), SPH_C32(0x8000000A) }, + { SPH_C32(0x80000000), SPH_C32(0x80008081) }, + { SPH_C32(0x80000000), SPH_C32(0x00008080) }, + { SPH_C32(0x00000000), SPH_C32(0x80000001) }, + { SPH_C32(0x80000000), SPH_C32(0x80008008) } +#endif +}; + +#if SPH_KECCAK_INTERLEAVE + +#define INTERLEAVE(xl, xh) do { \ + sph_u32 l, h, t; \ + l = (xl); h = (xh); \ + t = (l ^ (l >> 1)) & SPH_C32(0x22222222); l ^= t ^ (t << 1); \ + t = (h ^ (h >> 1)) & SPH_C32(0x22222222); h ^= t ^ (t << 1); \ + t = (l ^ (l >> 2)) & SPH_C32(0x0C0C0C0C); l ^= t ^ (t << 2); \ + t = (h ^ (h >> 2)) & SPH_C32(0x0C0C0C0C); h ^= t ^ (t << 2); \ + t = (l ^ (l >> 4)) & SPH_C32(0x00F000F0); l ^= t ^ (t << 4); \ + t = (h ^ (h >> 4)) & SPH_C32(0x00F000F0); h ^= t ^ (t << 4); \ + t = (l ^ (l >> 8)) & SPH_C32(0x0000FF00); l ^= t ^ (t << 8); \ + t = (h ^ (h >> 8)) & SPH_C32(0x0000FF00); h ^= t ^ (t << 8); \ + t = (l ^ SPH_T32(h << 16)) & SPH_C32(0xFFFF0000); \ + l ^= t; h ^= t >> 16; \ + (xl) = l; (xh) = h; \ + } while (0) + +#define UNINTERLEAVE(xl, xh) do { \ + sph_u32 l, h, t; \ + l = (xl); h = (xh); \ + t = (l ^ SPH_T32(h << 16)) & SPH_C32(0xFFFF0000); \ + l ^= t; h ^= t >> 16; \ + t = (l ^ (l >> 8)) & SPH_C32(0x0000FF00); l ^= t ^ (t << 8); \ + t = (h ^ (h >> 8)) & SPH_C32(0x0000FF00); h ^= t ^ (t << 8); \ + t = (l ^ (l >> 4)) & SPH_C32(0x00F000F0); l ^= t ^ (t << 4); \ + t = (h ^ (h >> 4)) & SPH_C32(0x00F000F0); h ^= t ^ (t << 4); \ + t = (l ^ (l >> 2)) & SPH_C32(0x0C0C0C0C); l ^= t ^ (t << 2); \ + t = (h ^ (h >> 2)) & SPH_C32(0x0C0C0C0C); h ^= t ^ (t << 2); \ + t = (l ^ (l >> 1)) & SPH_C32(0x22222222); l ^= t ^ (t << 1); \ + t = (h ^ (h >> 1)) & SPH_C32(0x22222222); h ^= t ^ (t << 1); \ + (xl) = l; (xh) = h; \ + } while (0) + +#else + +#define INTERLEAVE(l, h) +#define UNINTERLEAVE(l, h) + +#endif + +#if SPH_KECCAK_NOCOPY + +#define a00l (kc->u.narrow[2 * 0 + 0]) +#define a00h (kc->u.narrow[2 * 0 + 1]) +#define a10l (kc->u.narrow[2 * 1 + 0]) +#define a10h (kc->u.narrow[2 * 1 + 1]) +#define a20l (kc->u.narrow[2 * 2 + 0]) +#define a20h (kc->u.narrow[2 * 2 + 1]) +#define a30l (kc->u.narrow[2 * 3 + 0]) +#define a30h (kc->u.narrow[2 * 3 + 1]) +#define a40l (kc->u.narrow[2 * 4 + 0]) +#define a40h (kc->u.narrow[2 * 4 + 1]) +#define a01l (kc->u.narrow[2 * 5 + 0]) +#define a01h (kc->u.narrow[2 * 5 + 1]) +#define a11l (kc->u.narrow[2 * 6 + 0]) +#define a11h (kc->u.narrow[2 * 6 + 1]) +#define a21l (kc->u.narrow[2 * 7 + 0]) +#define a21h (kc->u.narrow[2 * 7 + 1]) +#define a31l (kc->u.narrow[2 * 8 + 0]) +#define a31h (kc->u.narrow[2 * 8 + 1]) +#define a41l (kc->u.narrow[2 * 9 + 0]) +#define a41h (kc->u.narrow[2 * 9 + 1]) +#define a02l (kc->u.narrow[2 * 10 + 0]) +#define a02h (kc->u.narrow[2 * 10 + 1]) +#define a12l (kc->u.narrow[2 * 11 + 0]) +#define a12h (kc->u.narrow[2 * 11 + 1]) +#define a22l (kc->u.narrow[2 * 12 + 0]) +#define a22h (kc->u.narrow[2 * 12 + 1]) +#define a32l (kc->u.narrow[2 * 13 + 0]) +#define a32h (kc->u.narrow[2 * 13 + 1]) +#define a42l (kc->u.narrow[2 * 14 + 0]) +#define a42h (kc->u.narrow[2 * 14 + 1]) +#define a03l (kc->u.narrow[2 * 15 + 0]) +#define a03h (kc->u.narrow[2 * 15 + 1]) +#define a13l (kc->u.narrow[2 * 16 + 0]) +#define a13h (kc->u.narrow[2 * 16 + 1]) +#define a23l (kc->u.narrow[2 * 17 + 0]) +#define a23h (kc->u.narrow[2 * 17 + 1]) +#define a33l (kc->u.narrow[2 * 18 + 0]) +#define a33h (kc->u.narrow[2 * 18 + 1]) +#define a43l (kc->u.narrow[2 * 19 + 0]) +#define a43h (kc->u.narrow[2 * 19 + 1]) +#define a04l (kc->u.narrow[2 * 20 + 0]) +#define a04h (kc->u.narrow[2 * 20 + 1]) +#define a14l (kc->u.narrow[2 * 21 + 0]) +#define a14h (kc->u.narrow[2 * 21 + 1]) +#define a24l (kc->u.narrow[2 * 22 + 0]) +#define a24h (kc->u.narrow[2 * 22 + 1]) +#define a34l (kc->u.narrow[2 * 23 + 0]) +#define a34h (kc->u.narrow[2 * 23 + 1]) +#define a44l (kc->u.narrow[2 * 24 + 0]) +#define a44h (kc->u.narrow[2 * 24 + 1]) + +#define DECL_STATE +#define READ_STATE(state) +#define WRITE_STATE(state) + +#define INPUT_BUF(size) do { \ + size_t j; \ + for (j = 0; j < (size); j += 8) { \ + sph_u32 tl, th; \ + tl = sph_dec32le_aligned(buf + j + 0); \ + th = sph_dec32le_aligned(buf + j + 4); \ + INTERLEAVE(tl, th); \ + kc->u.narrow[(j >> 2) + 0] ^= tl; \ + kc->u.narrow[(j >> 2) + 1] ^= th; \ + } \ + } while (0) + +#define INPUT_BUF144 INPUT_BUF(144) +#define INPUT_BUF136 INPUT_BUF(136) +#define INPUT_BUF104 INPUT_BUF(104) +#define INPUT_BUF72 INPUT_BUF(72) + +#else + +#define DECL_STATE \ + sph_u32 a00l, a00h, a01l, a01h, a02l, a02h, a03l, a03h, a04l, a04h; \ + sph_u32 a10l, a10h, a11l, a11h, a12l, a12h, a13l, a13h, a14l, a14h; \ + sph_u32 a20l, a20h, a21l, a21h, a22l, a22h, a23l, a23h, a24l, a24h; \ + sph_u32 a30l, a30h, a31l, a31h, a32l, a32h, a33l, a33h, a34l, a34h; \ + sph_u32 a40l, a40h, a41l, a41h, a42l, a42h, a43l, a43h, a44l, a44h; + +#define READ_STATE(state) do { \ + a00l = (state)->u.narrow[2 * 0 + 0]; \ + a00h = (state)->u.narrow[2 * 0 + 1]; \ + a10l = (state)->u.narrow[2 * 1 + 0]; \ + a10h = (state)->u.narrow[2 * 1 + 1]; \ + a20l = (state)->u.narrow[2 * 2 + 0]; \ + a20h = (state)->u.narrow[2 * 2 + 1]; \ + a30l = (state)->u.narrow[2 * 3 + 0]; \ + a30h = (state)->u.narrow[2 * 3 + 1]; \ + a40l = (state)->u.narrow[2 * 4 + 0]; \ + a40h = (state)->u.narrow[2 * 4 + 1]; \ + a01l = (state)->u.narrow[2 * 5 + 0]; \ + a01h = (state)->u.narrow[2 * 5 + 1]; \ + a11l = (state)->u.narrow[2 * 6 + 0]; \ + a11h = (state)->u.narrow[2 * 6 + 1]; \ + a21l = (state)->u.narrow[2 * 7 + 0]; \ + a21h = (state)->u.narrow[2 * 7 + 1]; \ + a31l = (state)->u.narrow[2 * 8 + 0]; \ + a31h = (state)->u.narrow[2 * 8 + 1]; \ + a41l = (state)->u.narrow[2 * 9 + 0]; \ + a41h = (state)->u.narrow[2 * 9 + 1]; \ + a02l = (state)->u.narrow[2 * 10 + 0]; \ + a02h = (state)->u.narrow[2 * 10 + 1]; \ + a12l = (state)->u.narrow[2 * 11 + 0]; \ + a12h = (state)->u.narrow[2 * 11 + 1]; \ + a22l = (state)->u.narrow[2 * 12 + 0]; \ + a22h = (state)->u.narrow[2 * 12 + 1]; \ + a32l = (state)->u.narrow[2 * 13 + 0]; \ + a32h = (state)->u.narrow[2 * 13 + 1]; \ + a42l = (state)->u.narrow[2 * 14 + 0]; \ + a42h = (state)->u.narrow[2 * 14 + 1]; \ + a03l = (state)->u.narrow[2 * 15 + 0]; \ + a03h = (state)->u.narrow[2 * 15 + 1]; \ + a13l = (state)->u.narrow[2 * 16 + 0]; \ + a13h = (state)->u.narrow[2 * 16 + 1]; \ + a23l = (state)->u.narrow[2 * 17 + 0]; \ + a23h = (state)->u.narrow[2 * 17 + 1]; \ + a33l = (state)->u.narrow[2 * 18 + 0]; \ + a33h = (state)->u.narrow[2 * 18 + 1]; \ + a43l = (state)->u.narrow[2 * 19 + 0]; \ + a43h = (state)->u.narrow[2 * 19 + 1]; \ + a04l = (state)->u.narrow[2 * 20 + 0]; \ + a04h = (state)->u.narrow[2 * 20 + 1]; \ + a14l = (state)->u.narrow[2 * 21 + 0]; \ + a14h = (state)->u.narrow[2 * 21 + 1]; \ + a24l = (state)->u.narrow[2 * 22 + 0]; \ + a24h = (state)->u.narrow[2 * 22 + 1]; \ + a34l = (state)->u.narrow[2 * 23 + 0]; \ + a34h = (state)->u.narrow[2 * 23 + 1]; \ + a44l = (state)->u.narrow[2 * 24 + 0]; \ + a44h = (state)->u.narrow[2 * 24 + 1]; \ + } while (0) + +#define WRITE_STATE(state) do { \ + (state)->u.narrow[2 * 0 + 0] = a00l; \ + (state)->u.narrow[2 * 0 + 1] = a00h; \ + (state)->u.narrow[2 * 1 + 0] = a10l; \ + (state)->u.narrow[2 * 1 + 1] = a10h; \ + (state)->u.narrow[2 * 2 + 0] = a20l; \ + (state)->u.narrow[2 * 2 + 1] = a20h; \ + (state)->u.narrow[2 * 3 + 0] = a30l; \ + (state)->u.narrow[2 * 3 + 1] = a30h; \ + (state)->u.narrow[2 * 4 + 0] = a40l; \ + (state)->u.narrow[2 * 4 + 1] = a40h; \ + (state)->u.narrow[2 * 5 + 0] = a01l; \ + (state)->u.narrow[2 * 5 + 1] = a01h; \ + (state)->u.narrow[2 * 6 + 0] = a11l; \ + (state)->u.narrow[2 * 6 + 1] = a11h; \ + (state)->u.narrow[2 * 7 + 0] = a21l; \ + (state)->u.narrow[2 * 7 + 1] = a21h; \ + (state)->u.narrow[2 * 8 + 0] = a31l; \ + (state)->u.narrow[2 * 8 + 1] = a31h; \ + (state)->u.narrow[2 * 9 + 0] = a41l; \ + (state)->u.narrow[2 * 9 + 1] = a41h; \ + (state)->u.narrow[2 * 10 + 0] = a02l; \ + (state)->u.narrow[2 * 10 + 1] = a02h; \ + (state)->u.narrow[2 * 11 + 0] = a12l; \ + (state)->u.narrow[2 * 11 + 1] = a12h; \ + (state)->u.narrow[2 * 12 + 0] = a22l; \ + (state)->u.narrow[2 * 12 + 1] = a22h; \ + (state)->u.narrow[2 * 13 + 0] = a32l; \ + (state)->u.narrow[2 * 13 + 1] = a32h; \ + (state)->u.narrow[2 * 14 + 0] = a42l; \ + (state)->u.narrow[2 * 14 + 1] = a42h; \ + (state)->u.narrow[2 * 15 + 0] = a03l; \ + (state)->u.narrow[2 * 15 + 1] = a03h; \ + (state)->u.narrow[2 * 16 + 0] = a13l; \ + (state)->u.narrow[2 * 16 + 1] = a13h; \ + (state)->u.narrow[2 * 17 + 0] = a23l; \ + (state)->u.narrow[2 * 17 + 1] = a23h; \ + (state)->u.narrow[2 * 18 + 0] = a33l; \ + (state)->u.narrow[2 * 18 + 1] = a33h; \ + (state)->u.narrow[2 * 19 + 0] = a43l; \ + (state)->u.narrow[2 * 19 + 1] = a43h; \ + (state)->u.narrow[2 * 20 + 0] = a04l; \ + (state)->u.narrow[2 * 20 + 1] = a04h; \ + (state)->u.narrow[2 * 21 + 0] = a14l; \ + (state)->u.narrow[2 * 21 + 1] = a14h; \ + (state)->u.narrow[2 * 22 + 0] = a24l; \ + (state)->u.narrow[2 * 22 + 1] = a24h; \ + (state)->u.narrow[2 * 23 + 0] = a34l; \ + (state)->u.narrow[2 * 23 + 1] = a34h; \ + (state)->u.narrow[2 * 24 + 0] = a44l; \ + (state)->u.narrow[2 * 24 + 1] = a44h; \ + } while (0) + +#define READ64(d, off) do { \ + sph_u32 tl, th; \ + tl = sph_dec32le_aligned(buf + (off)); \ + th = sph_dec32le_aligned(buf + (off) + 4); \ + INTERLEAVE(tl, th); \ + d ## l ^= tl; \ + d ## h ^= th; \ + } while (0) + +#define INPUT_BUF144 do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + READ64(a41, 72); \ + READ64(a02, 80); \ + READ64(a12, 88); \ + READ64(a22, 96); \ + READ64(a32, 104); \ + READ64(a42, 112); \ + READ64(a03, 120); \ + READ64(a13, 128); \ + READ64(a23, 136); \ + } while (0) + +#define INPUT_BUF136 do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + READ64(a41, 72); \ + READ64(a02, 80); \ + READ64(a12, 88); \ + READ64(a22, 96); \ + READ64(a32, 104); \ + READ64(a42, 112); \ + READ64(a03, 120); \ + READ64(a13, 128); \ + } while (0) + +#define INPUT_BUF104 do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + READ64(a41, 72); \ + READ64(a02, 80); \ + READ64(a12, 88); \ + READ64(a22, 96); \ + } while (0) + +#define INPUT_BUF72 do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + } while (0) + +#define INPUT_BUF(lim) do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + if ((lim) == 72) \ + break; \ + READ64(a41, 72); \ + READ64(a02, 80); \ + READ64(a12, 88); \ + READ64(a22, 96); \ + if ((lim) == 104) \ + break; \ + READ64(a32, 104); \ + READ64(a42, 112); \ + READ64(a03, 120); \ + READ64(a13, 128); \ + if ((lim) == 136) \ + break; \ + READ64(a23, 136); \ + } while (0) + +#endif + +#define DECL64(x) sph_u64 x ## l, x ## h +#define MOV64(d, s) (d ## l = s ## l, d ## h = s ## h) +#define XOR64(d, a, b) (d ## l = a ## l ^ b ## l, d ## h = a ## h ^ b ## h) +#define AND64(d, a, b) (d ## l = a ## l & b ## l, d ## h = a ## h & b ## h) +#define OR64(d, a, b) (d ## l = a ## l | b ## l, d ## h = a ## h | b ## h) +#define NOT64(d, s) (d ## l = SPH_T32(~s ## l), d ## h = SPH_T32(~s ## h)) +#define ROL64(d, v, n) ROL64_ ## n(d, v) + +#if SPH_KECCAK_INTERLEAVE + +#define ROL64_odd1(d, v) do { \ + sph_u32 tmp; \ + tmp = v ## l; \ + d ## l = SPH_T32(v ## h << 1) | (v ## h >> 31); \ + d ## h = tmp; \ + } while (0) + +#define ROL64_odd63(d, v) do { \ + sph_u32 tmp; \ + tmp = SPH_T32(v ## l << 31) | (v ## l >> 1); \ + d ## l = v ## h; \ + d ## h = tmp; \ + } while (0) + +#define ROL64_odd(d, v, n) do { \ + sph_u32 tmp; \ + tmp = SPH_T32(v ## l << (n - 1)) | (v ## l >> (33 - n)); \ + d ## l = SPH_T32(v ## h << n) | (v ## h >> (32 - n)); \ + d ## h = tmp; \ + } while (0) + +#define ROL64_even(d, v, n) do { \ + d ## l = SPH_T32(v ## l << n) | (v ## l >> (32 - n)); \ + d ## h = SPH_T32(v ## h << n) | (v ## h >> (32 - n)); \ + } while (0) + +#define ROL64_0(d, v) +#define ROL64_1(d, v) ROL64_odd1(d, v) +#define ROL64_2(d, v) ROL64_even(d, v, 1) +#define ROL64_3(d, v) ROL64_odd( d, v, 2) +#define ROL64_4(d, v) ROL64_even(d, v, 2) +#define ROL64_5(d, v) ROL64_odd( d, v, 3) +#define ROL64_6(d, v) ROL64_even(d, v, 3) +#define ROL64_7(d, v) ROL64_odd( d, v, 4) +#define ROL64_8(d, v) ROL64_even(d, v, 4) +#define ROL64_9(d, v) ROL64_odd( d, v, 5) +#define ROL64_10(d, v) ROL64_even(d, v, 5) +#define ROL64_11(d, v) ROL64_odd( d, v, 6) +#define ROL64_12(d, v) ROL64_even(d, v, 6) +#define ROL64_13(d, v) ROL64_odd( d, v, 7) +#define ROL64_14(d, v) ROL64_even(d, v, 7) +#define ROL64_15(d, v) ROL64_odd( d, v, 8) +#define ROL64_16(d, v) ROL64_even(d, v, 8) +#define ROL64_17(d, v) ROL64_odd( d, v, 9) +#define ROL64_18(d, v) ROL64_even(d, v, 9) +#define ROL64_19(d, v) ROL64_odd( d, v, 10) +#define ROL64_20(d, v) ROL64_even(d, v, 10) +#define ROL64_21(d, v) ROL64_odd( d, v, 11) +#define ROL64_22(d, v) ROL64_even(d, v, 11) +#define ROL64_23(d, v) ROL64_odd( d, v, 12) +#define ROL64_24(d, v) ROL64_even(d, v, 12) +#define ROL64_25(d, v) ROL64_odd( d, v, 13) +#define ROL64_26(d, v) ROL64_even(d, v, 13) +#define ROL64_27(d, v) ROL64_odd( d, v, 14) +#define ROL64_28(d, v) ROL64_even(d, v, 14) +#define ROL64_29(d, v) ROL64_odd( d, v, 15) +#define ROL64_30(d, v) ROL64_even(d, v, 15) +#define ROL64_31(d, v) ROL64_odd( d, v, 16) +#define ROL64_32(d, v) ROL64_even(d, v, 16) +#define ROL64_33(d, v) ROL64_odd( d, v, 17) +#define ROL64_34(d, v) ROL64_even(d, v, 17) +#define ROL64_35(d, v) ROL64_odd( d, v, 18) +#define ROL64_36(d, v) ROL64_even(d, v, 18) +#define ROL64_37(d, v) ROL64_odd( d, v, 19) +#define ROL64_38(d, v) ROL64_even(d, v, 19) +#define ROL64_39(d, v) ROL64_odd( d, v, 20) +#define ROL64_40(d, v) ROL64_even(d, v, 20) +#define ROL64_41(d, v) ROL64_odd( d, v, 21) +#define ROL64_42(d, v) ROL64_even(d, v, 21) +#define ROL64_43(d, v) ROL64_odd( d, v, 22) +#define ROL64_44(d, v) ROL64_even(d, v, 22) +#define ROL64_45(d, v) ROL64_odd( d, v, 23) +#define ROL64_46(d, v) ROL64_even(d, v, 23) +#define ROL64_47(d, v) ROL64_odd( d, v, 24) +#define ROL64_48(d, v) ROL64_even(d, v, 24) +#define ROL64_49(d, v) ROL64_odd( d, v, 25) +#define ROL64_50(d, v) ROL64_even(d, v, 25) +#define ROL64_51(d, v) ROL64_odd( d, v, 26) +#define ROL64_52(d, v) ROL64_even(d, v, 26) +#define ROL64_53(d, v) ROL64_odd( d, v, 27) +#define ROL64_54(d, v) ROL64_even(d, v, 27) +#define ROL64_55(d, v) ROL64_odd( d, v, 28) +#define ROL64_56(d, v) ROL64_even(d, v, 28) +#define ROL64_57(d, v) ROL64_odd( d, v, 29) +#define ROL64_58(d, v) ROL64_even(d, v, 29) +#define ROL64_59(d, v) ROL64_odd( d, v, 30) +#define ROL64_60(d, v) ROL64_even(d, v, 30) +#define ROL64_61(d, v) ROL64_odd( d, v, 31) +#define ROL64_62(d, v) ROL64_even(d, v, 31) +#define ROL64_63(d, v) ROL64_odd63(d, v) + +#else + +#define ROL64_small(d, v, n) do { \ + sph_u32 tmp; \ + tmp = SPH_T32(v ## l << n) | (v ## h >> (32 - n)); \ + d ## h = SPH_T32(v ## h << n) | (v ## l >> (32 - n)); \ + d ## l = tmp; \ + } while (0) + +#define ROL64_0(d, v) 0 +#define ROL64_1(d, v) ROL64_small(d, v, 1) +#define ROL64_2(d, v) ROL64_small(d, v, 2) +#define ROL64_3(d, v) ROL64_small(d, v, 3) +#define ROL64_4(d, v) ROL64_small(d, v, 4) +#define ROL64_5(d, v) ROL64_small(d, v, 5) +#define ROL64_6(d, v) ROL64_small(d, v, 6) +#define ROL64_7(d, v) ROL64_small(d, v, 7) +#define ROL64_8(d, v) ROL64_small(d, v, 8) +#define ROL64_9(d, v) ROL64_small(d, v, 9) +#define ROL64_10(d, v) ROL64_small(d, v, 10) +#define ROL64_11(d, v) ROL64_small(d, v, 11) +#define ROL64_12(d, v) ROL64_small(d, v, 12) +#define ROL64_13(d, v) ROL64_small(d, v, 13) +#define ROL64_14(d, v) ROL64_small(d, v, 14) +#define ROL64_15(d, v) ROL64_small(d, v, 15) +#define ROL64_16(d, v) ROL64_small(d, v, 16) +#define ROL64_17(d, v) ROL64_small(d, v, 17) +#define ROL64_18(d, v) ROL64_small(d, v, 18) +#define ROL64_19(d, v) ROL64_small(d, v, 19) +#define ROL64_20(d, v) ROL64_small(d, v, 20) +#define ROL64_21(d, v) ROL64_small(d, v, 21) +#define ROL64_22(d, v) ROL64_small(d, v, 22) +#define ROL64_23(d, v) ROL64_small(d, v, 23) +#define ROL64_24(d, v) ROL64_small(d, v, 24) +#define ROL64_25(d, v) ROL64_small(d, v, 25) +#define ROL64_26(d, v) ROL64_small(d, v, 26) +#define ROL64_27(d, v) ROL64_small(d, v, 27) +#define ROL64_28(d, v) ROL64_small(d, v, 28) +#define ROL64_29(d, v) ROL64_small(d, v, 29) +#define ROL64_30(d, v) ROL64_small(d, v, 30) +#define ROL64_31(d, v) ROL64_small(d, v, 31) + +#define ROL64_32(d, v) do { \ + sph_u32 tmp; \ + tmp = v ## l; \ + d ## l = v ## h; \ + d ## h = tmp; \ + } while (0) + +#define ROL64_big(d, v, n) do { \ + sph_u32 trl, trh; \ + ROL64_small(tr, v, n); \ + d ## h = trl; \ + d ## l = trh; \ + } while (0) + +#define ROL64_33(d, v) ROL64_big(d, v, 1) +#define ROL64_34(d, v) ROL64_big(d, v, 2) +#define ROL64_35(d, v) ROL64_big(d, v, 3) +#define ROL64_36(d, v) ROL64_big(d, v, 4) +#define ROL64_37(d, v) ROL64_big(d, v, 5) +#define ROL64_38(d, v) ROL64_big(d, v, 6) +#define ROL64_39(d, v) ROL64_big(d, v, 7) +#define ROL64_40(d, v) ROL64_big(d, v, 8) +#define ROL64_41(d, v) ROL64_big(d, v, 9) +#define ROL64_42(d, v) ROL64_big(d, v, 10) +#define ROL64_43(d, v) ROL64_big(d, v, 11) +#define ROL64_44(d, v) ROL64_big(d, v, 12) +#define ROL64_45(d, v) ROL64_big(d, v, 13) +#define ROL64_46(d, v) ROL64_big(d, v, 14) +#define ROL64_47(d, v) ROL64_big(d, v, 15) +#define ROL64_48(d, v) ROL64_big(d, v, 16) +#define ROL64_49(d, v) ROL64_big(d, v, 17) +#define ROL64_50(d, v) ROL64_big(d, v, 18) +#define ROL64_51(d, v) ROL64_big(d, v, 19) +#define ROL64_52(d, v) ROL64_big(d, v, 20) +#define ROL64_53(d, v) ROL64_big(d, v, 21) +#define ROL64_54(d, v) ROL64_big(d, v, 22) +#define ROL64_55(d, v) ROL64_big(d, v, 23) +#define ROL64_56(d, v) ROL64_big(d, v, 24) +#define ROL64_57(d, v) ROL64_big(d, v, 25) +#define ROL64_58(d, v) ROL64_big(d, v, 26) +#define ROL64_59(d, v) ROL64_big(d, v, 27) +#define ROL64_60(d, v) ROL64_big(d, v, 28) +#define ROL64_61(d, v) ROL64_big(d, v, 29) +#define ROL64_62(d, v) ROL64_big(d, v, 30) +#define ROL64_63(d, v) ROL64_big(d, v, 31) + +#endif + +#define XOR64_IOTA(d, s, k) \ + (d ## l = s ## l ^ k.low, d ## h = s ## h ^ k.high) + +#endif + +#define TH_ELT(t, c0, c1, c2, c3, c4, d0, d1, d2, d3, d4) do { \ + DECL64(tt0); \ + DECL64(tt1); \ + DECL64(tt2); \ + DECL64(tt3); \ + XOR64(tt0, d0, d1); \ + XOR64(tt1, d2, d3); \ + XOR64(tt0, tt0, d4); \ + XOR64(tt0, tt0, tt1); \ + ROL64(tt0, tt0, 1); \ + XOR64(tt2, c0, c1); \ + XOR64(tt3, c2, c3); \ + XOR64(tt0, tt0, c4); \ + XOR64(tt2, tt2, tt3); \ + XOR64(t, tt0, tt2); \ + } while (0) + +#define THETA(b00, b01, b02, b03, b04, b10, b11, b12, b13, b14, \ + b20, b21, b22, b23, b24, b30, b31, b32, b33, b34, \ + b40, b41, b42, b43, b44) \ + do { \ + DECL64(t0); \ + DECL64(t1); \ + DECL64(t2); \ + DECL64(t3); \ + DECL64(t4); \ + TH_ELT(t0, b40, b41, b42, b43, b44, b10, b11, b12, b13, b14); \ + TH_ELT(t1, b00, b01, b02, b03, b04, b20, b21, b22, b23, b24); \ + TH_ELT(t2, b10, b11, b12, b13, b14, b30, b31, b32, b33, b34); \ + TH_ELT(t3, b20, b21, b22, b23, b24, b40, b41, b42, b43, b44); \ + TH_ELT(t4, b30, b31, b32, b33, b34, b00, b01, b02, b03, b04); \ + XOR64(b00, b00, t0); \ + XOR64(b01, b01, t0); \ + XOR64(b02, b02, t0); \ + XOR64(b03, b03, t0); \ + XOR64(b04, b04, t0); \ + XOR64(b10, b10, t1); \ + XOR64(b11, b11, t1); \ + XOR64(b12, b12, t1); \ + XOR64(b13, b13, t1); \ + XOR64(b14, b14, t1); \ + XOR64(b20, b20, t2); \ + XOR64(b21, b21, t2); \ + XOR64(b22, b22, t2); \ + XOR64(b23, b23, t2); \ + XOR64(b24, b24, t2); \ + XOR64(b30, b30, t3); \ + XOR64(b31, b31, t3); \ + XOR64(b32, b32, t3); \ + XOR64(b33, b33, t3); \ + XOR64(b34, b34, t3); \ + XOR64(b40, b40, t4); \ + XOR64(b41, b41, t4); \ + XOR64(b42, b42, t4); \ + XOR64(b43, b43, t4); \ + XOR64(b44, b44, t4); \ + } while (0) + +#define RHO(b00, b01, b02, b03, b04, b10, b11, b12, b13, b14, \ + b20, b21, b22, b23, b24, b30, b31, b32, b33, b34, \ + b40, b41, b42, b43, b44) \ + do { \ + /* ROL64(b00, b00, 0); */ \ + ROL64(b01, b01, 36); \ + ROL64(b02, b02, 3); \ + ROL64(b03, b03, 41); \ + ROL64(b04, b04, 18); \ + ROL64(b10, b10, 1); \ + ROL64(b11, b11, 44); \ + ROL64(b12, b12, 10); \ + ROL64(b13, b13, 45); \ + ROL64(b14, b14, 2); \ + ROL64(b20, b20, 62); \ + ROL64(b21, b21, 6); \ + ROL64(b22, b22, 43); \ + ROL64(b23, b23, 15); \ + ROL64(b24, b24, 61); \ + ROL64(b30, b30, 28); \ + ROL64(b31, b31, 55); \ + ROL64(b32, b32, 25); \ + ROL64(b33, b33, 21); \ + ROL64(b34, b34, 56); \ + ROL64(b40, b40, 27); \ + ROL64(b41, b41, 20); \ + ROL64(b42, b42, 39); \ + ROL64(b43, b43, 8); \ + ROL64(b44, b44, 14); \ + } while (0) + +/* + * The KHI macro integrates the "lane complement" optimization. On input, + * some words are complemented: + * a00 a01 a02 a04 a13 a20 a21 a22 a30 a33 a34 a43 + * On output, the following words are complemented: + * a04 a10 a20 a22 a23 a31 + * + * The (implicit) permutation and the theta expansion will bring back + * the input mask for the next round. + */ + +#define KHI_XO(d, a, b, c) do { \ + DECL64(kt); \ + OR64(kt, b, c); \ + XOR64(d, a, kt); \ + } while (0) + +#define KHI_XA(d, a, b, c) do { \ + DECL64(kt); \ + AND64(kt, b, c); \ + XOR64(d, a, kt); \ + } while (0) + +#define KHI(b00, b01, b02, b03, b04, b10, b11, b12, b13, b14, \ + b20, b21, b22, b23, b24, b30, b31, b32, b33, b34, \ + b40, b41, b42, b43, b44) \ + do { \ + DECL64(c0); \ + DECL64(c1); \ + DECL64(c2); \ + DECL64(c3); \ + DECL64(c4); \ + DECL64(bnn); \ + NOT64(bnn, b20); \ + KHI_XO(c0, b00, b10, b20); \ + KHI_XO(c1, b10, bnn, b30); \ + KHI_XA(c2, b20, b30, b40); \ + KHI_XO(c3, b30, b40, b00); \ + KHI_XA(c4, b40, b00, b10); \ + MOV64(b00, c0); \ + MOV64(b10, c1); \ + MOV64(b20, c2); \ + MOV64(b30, c3); \ + MOV64(b40, c4); \ + NOT64(bnn, b41); \ + KHI_XO(c0, b01, b11, b21); \ + KHI_XA(c1, b11, b21, b31); \ + KHI_XO(c2, b21, b31, bnn); \ + KHI_XO(c3, b31, b41, b01); \ + KHI_XA(c4, b41, b01, b11); \ + MOV64(b01, c0); \ + MOV64(b11, c1); \ + MOV64(b21, c2); \ + MOV64(b31, c3); \ + MOV64(b41, c4); \ + NOT64(bnn, b32); \ + KHI_XO(c0, b02, b12, b22); \ + KHI_XA(c1, b12, b22, b32); \ + KHI_XA(c2, b22, bnn, b42); \ + KHI_XO(c3, bnn, b42, b02); \ + KHI_XA(c4, b42, b02, b12); \ + MOV64(b02, c0); \ + MOV64(b12, c1); \ + MOV64(b22, c2); \ + MOV64(b32, c3); \ + MOV64(b42, c4); \ + NOT64(bnn, b33); \ + KHI_XA(c0, b03, b13, b23); \ + KHI_XO(c1, b13, b23, b33); \ + KHI_XO(c2, b23, bnn, b43); \ + KHI_XA(c3, bnn, b43, b03); \ + KHI_XO(c4, b43, b03, b13); \ + MOV64(b03, c0); \ + MOV64(b13, c1); \ + MOV64(b23, c2); \ + MOV64(b33, c3); \ + MOV64(b43, c4); \ + NOT64(bnn, b14); \ + KHI_XA(c0, b04, bnn, b24); \ + KHI_XO(c1, bnn, b24, b34); \ + KHI_XA(c2, b24, b34, b44); \ + KHI_XO(c3, b34, b44, b04); \ + KHI_XA(c4, b44, b04, b14); \ + MOV64(b04, c0); \ + MOV64(b14, c1); \ + MOV64(b24, c2); \ + MOV64(b34, c3); \ + MOV64(b44, c4); \ + } while (0) + +#define IOTA(r) XOR64_IOTA(a00, a00, r) + +#define P0 a00, a01, a02, a03, a04, a10, a11, a12, a13, a14, a20, a21, \ + a22, a23, a24, a30, a31, a32, a33, a34, a40, a41, a42, a43, a44 +#define P1 a00, a30, a10, a40, a20, a11, a41, a21, a01, a31, a22, a02, \ + a32, a12, a42, a33, a13, a43, a23, a03, a44, a24, a04, a34, a14 +#define P2 a00, a33, a11, a44, a22, a41, a24, a02, a30, a13, a32, a10, \ + a43, a21, a04, a23, a01, a34, a12, a40, a14, a42, a20, a03, a31 +#define P3 a00, a23, a41, a14, a32, a24, a42, a10, a33, a01, a43, a11, \ + a34, a02, a20, a12, a30, a03, a21, a44, a31, a04, a22, a40, a13 +#define P4 a00, a12, a24, a31, a43, a42, a04, a11, a23, a30, a34, a41, \ + a03, a10, a22, a21, a33, a40, a02, a14, a13, a20, a32, a44, a01 +#define P5 a00, a21, a42, a13, a34, a04, a20, a41, a12, a33, a03, a24, \ + a40, a11, a32, a02, a23, a44, a10, a31, a01, a22, a43, a14, a30 +#define P6 a00, a02, a04, a01, a03, a20, a22, a24, a21, a23, a40, a42, \ + a44, a41, a43, a10, a12, a14, a11, a13, a30, a32, a34, a31, a33 +#define P7 a00, a10, a20, a30, a40, a22, a32, a42, a02, a12, a44, a04, \ + a14, a24, a34, a11, a21, a31, a41, a01, a33, a43, a03, a13, a23 +#define P8 a00, a11, a22, a33, a44, a32, a43, a04, a10, a21, a14, a20, \ + a31, a42, a03, a41, a02, a13, a24, a30, a23, a34, a40, a01, a12 +#define P9 a00, a41, a32, a23, a14, a43, a34, a20, a11, a02, a31, a22, \ + a13, a04, a40, a24, a10, a01, a42, a33, a12, a03, a44, a30, a21 +#define P10 a00, a24, a43, a12, a31, a34, a03, a22, a41, a10, a13, a32, \ + a01, a20, a44, a42, a11, a30, a04, a23, a21, a40, a14, a33, a02 +#define P11 a00, a42, a34, a21, a13, a03, a40, a32, a24, a11, a01, a43, \ + a30, a22, a14, a04, a41, a33, a20, a12, a02, a44, a31, a23, a10 +#define P12 a00, a04, a03, a02, a01, a40, a44, a43, a42, a41, a30, a34, \ + a33, a32, a31, a20, a24, a23, a22, a21, a10, a14, a13, a12, a11 +#define P13 a00, a20, a40, a10, a30, a44, a14, a34, a04, a24, a33, a03, \ + a23, a43, a13, a22, a42, a12, a32, a02, a11, a31, a01, a21, a41 +#define P14 a00, a22, a44, a11, a33, a14, a31, a03, a20, a42, a23, a40, \ + a12, a34, a01, a32, a04, a21, a43, a10, a41, a13, a30, a02, a24 +#define P15 a00, a32, a14, a41, a23, a31, a13, a40, a22, a04, a12, a44, \ + a21, a03, a30, a43, a20, a02, a34, a11, a24, a01, a33, a10, a42 +#define P16 a00, a43, a31, a24, a12, a13, a01, a44, a32, a20, a21, a14, \ + a02, a40, a33, a34, a22, a10, a03, a41, a42, a30, a23, a11, a04 +#define P17 a00, a34, a13, a42, a21, a01, a30, a14, a43, a22, a02, a31, \ + a10, a44, a23, a03, a32, a11, a40, a24, a04, a33, a12, a41, a20 +#define P18 a00, a03, a01, a04, a02, a30, a33, a31, a34, a32, a10, a13, \ + a11, a14, a12, a40, a43, a41, a44, a42, a20, a23, a21, a24, a22 +#define P19 a00, a40, a30, a20, a10, a33, a23, a13, a03, a43, a11, a01, \ + a41, a31, a21, a44, a34, a24, a14, a04, a22, a12, a02, a42, a32 +#define P20 a00, a44, a33, a22, a11, a23, a12, a01, a40, a34, a41, a30, \ + a24, a13, a02, a14, a03, a42, a31, a20, a32, a21, a10, a04, a43 +#define P21 a00, a14, a23, a32, a41, a12, a21, a30, a44, a03, a24, a33, \ + a42, a01, a10, a31, a40, a04, a13, a22, a43, a02, a11, a20, a34 +#define P22 a00, a31, a12, a43, a24, a21, a02, a33, a14, a40, a42, a23, \ + a04, a30, a11, a13, a44, a20, a01, a32, a34, a10, a41, a22, a03 +#define P23 a00, a13, a21, a34, a42, a02, a10, a23, a31, a44, a04, a12, \ + a20, a33, a41, a01, a14, a22, a30, a43, a03, a11, a24, a32, a40 + +#define P1_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a30); \ + MOV64(a30, a33); \ + MOV64(a33, a23); \ + MOV64(a23, a12); \ + MOV64(a12, a21); \ + MOV64(a21, a02); \ + MOV64(a02, a10); \ + MOV64(a10, a11); \ + MOV64(a11, a41); \ + MOV64(a41, a24); \ + MOV64(a24, a42); \ + MOV64(a42, a04); \ + MOV64(a04, a20); \ + MOV64(a20, a22); \ + MOV64(a22, a32); \ + MOV64(a32, a43); \ + MOV64(a43, a34); \ + MOV64(a34, a03); \ + MOV64(a03, a40); \ + MOV64(a40, a44); \ + MOV64(a44, a14); \ + MOV64(a14, a31); \ + MOV64(a31, a13); \ + MOV64(a13, t); \ + } while (0) + +#define P2_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a33); \ + MOV64(a33, a12); \ + MOV64(a12, a02); \ + MOV64(a02, a11); \ + MOV64(a11, a24); \ + MOV64(a24, a04); \ + MOV64(a04, a22); \ + MOV64(a22, a43); \ + MOV64(a43, a03); \ + MOV64(a03, a44); \ + MOV64(a44, a31); \ + MOV64(a31, t); \ + MOV64(t, a10); \ + MOV64(a10, a41); \ + MOV64(a41, a42); \ + MOV64(a42, a20); \ + MOV64(a20, a32); \ + MOV64(a32, a34); \ + MOV64(a34, a40); \ + MOV64(a40, a14); \ + MOV64(a14, a13); \ + MOV64(a13, a30); \ + MOV64(a30, a23); \ + MOV64(a23, a21); \ + MOV64(a21, t); \ + } while (0) + +#define P4_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a12); \ + MOV64(a12, a11); \ + MOV64(a11, a04); \ + MOV64(a04, a43); \ + MOV64(a43, a44); \ + MOV64(a44, t); \ + MOV64(t, a02); \ + MOV64(a02, a24); \ + MOV64(a24, a22); \ + MOV64(a22, a03); \ + MOV64(a03, a31); \ + MOV64(a31, a33); \ + MOV64(a33, t); \ + MOV64(t, a10); \ + MOV64(a10, a42); \ + MOV64(a42, a32); \ + MOV64(a32, a40); \ + MOV64(a40, a13); \ + MOV64(a13, a23); \ + MOV64(a23, t); \ + MOV64(t, a14); \ + MOV64(a14, a30); \ + MOV64(a30, a21); \ + MOV64(a21, a41); \ + MOV64(a41, a20); \ + MOV64(a20, a34); \ + MOV64(a34, t); \ + } while (0) + +#define P6_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a02); \ + MOV64(a02, a04); \ + MOV64(a04, a03); \ + MOV64(a03, t); \ + MOV64(t, a10); \ + MOV64(a10, a20); \ + MOV64(a20, a40); \ + MOV64(a40, a30); \ + MOV64(a30, t); \ + MOV64(t, a11); \ + MOV64(a11, a22); \ + MOV64(a22, a44); \ + MOV64(a44, a33); \ + MOV64(a33, t); \ + MOV64(t, a12); \ + MOV64(a12, a24); \ + MOV64(a24, a43); \ + MOV64(a43, a31); \ + MOV64(a31, t); \ + MOV64(t, a13); \ + MOV64(a13, a21); \ + MOV64(a21, a42); \ + MOV64(a42, a34); \ + MOV64(a34, t); \ + MOV64(t, a14); \ + MOV64(a14, a23); \ + MOV64(a23, a41); \ + MOV64(a41, a32); \ + MOV64(a32, t); \ + } while (0) + +#define P8_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a11); \ + MOV64(a11, a43); \ + MOV64(a43, t); \ + MOV64(t, a02); \ + MOV64(a02, a22); \ + MOV64(a22, a31); \ + MOV64(a31, t); \ + MOV64(t, a03); \ + MOV64(a03, a33); \ + MOV64(a33, a24); \ + MOV64(a24, t); \ + MOV64(t, a04); \ + MOV64(a04, a44); \ + MOV64(a44, a12); \ + MOV64(a12, t); \ + MOV64(t, a10); \ + MOV64(a10, a32); \ + MOV64(a32, a13); \ + MOV64(a13, t); \ + MOV64(t, a14); \ + MOV64(a14, a21); \ + MOV64(a21, a20); \ + MOV64(a20, t); \ + MOV64(t, a23); \ + MOV64(a23, a42); \ + MOV64(a42, a40); \ + MOV64(a40, t); \ + MOV64(t, a30); \ + MOV64(a30, a41); \ + MOV64(a41, a34); \ + MOV64(a34, t); \ + } while (0) + +#define P12_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a04); \ + MOV64(a04, t); \ + MOV64(t, a02); \ + MOV64(a02, a03); \ + MOV64(a03, t); \ + MOV64(t, a10); \ + MOV64(a10, a40); \ + MOV64(a40, t); \ + MOV64(t, a11); \ + MOV64(a11, a44); \ + MOV64(a44, t); \ + MOV64(t, a12); \ + MOV64(a12, a43); \ + MOV64(a43, t); \ + MOV64(t, a13); \ + MOV64(a13, a42); \ + MOV64(a42, t); \ + MOV64(t, a14); \ + MOV64(a14, a41); \ + MOV64(a41, t); \ + MOV64(t, a20); \ + MOV64(a20, a30); \ + MOV64(a30, t); \ + MOV64(t, a21); \ + MOV64(a21, a34); \ + MOV64(a34, t); \ + MOV64(t, a22); \ + MOV64(a22, a33); \ + MOV64(a33, t); \ + MOV64(t, a23); \ + MOV64(a23, a32); \ + MOV64(a32, t); \ + MOV64(t, a24); \ + MOV64(a24, a31); \ + MOV64(a31, t); \ + } while (0) + +#define LPAR ( +#define RPAR ) + +#define KF_ELT(r, s, k) do { \ + THETA LPAR P ## r RPAR; \ + RHO LPAR P ## r RPAR; \ + KHI LPAR P ## s RPAR; \ + IOTA(k); \ + } while (0) + +#define DO(x) x + +#define KECCAK_F_1600 DO(KECCAK_F_1600_) + +#if SPH_KECCAK_UNROLL == 1 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j ++) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + P1_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 2 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 2) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + P2_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 4 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 4) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + KF_ELT( 2, 3, RC[j + 2]); \ + KF_ELT( 3, 4, RC[j + 3]); \ + P4_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 6 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 6) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + KF_ELT( 2, 3, RC[j + 2]); \ + KF_ELT( 3, 4, RC[j + 3]); \ + KF_ELT( 4, 5, RC[j + 4]); \ + KF_ELT( 5, 6, RC[j + 5]); \ + P6_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 8 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 8) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + KF_ELT( 2, 3, RC[j + 2]); \ + KF_ELT( 3, 4, RC[j + 3]); \ + KF_ELT( 4, 5, RC[j + 4]); \ + KF_ELT( 5, 6, RC[j + 5]); \ + KF_ELT( 6, 7, RC[j + 6]); \ + KF_ELT( 7, 8, RC[j + 7]); \ + P8_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 12 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 12) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + KF_ELT( 2, 3, RC[j + 2]); \ + KF_ELT( 3, 4, RC[j + 3]); \ + KF_ELT( 4, 5, RC[j + 4]); \ + KF_ELT( 5, 6, RC[j + 5]); \ + KF_ELT( 6, 7, RC[j + 6]); \ + KF_ELT( 7, 8, RC[j + 7]); \ + KF_ELT( 8, 9, RC[j + 8]); \ + KF_ELT( 9, 10, RC[j + 9]); \ + KF_ELT(10, 11, RC[j + 10]); \ + KF_ELT(11, 12, RC[j + 11]); \ + P12_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 0 + +#define KECCAK_F_1600_ do { \ + KF_ELT( 0, 1, RC[ 0]); \ + KF_ELT( 1, 2, RC[ 1]); \ + KF_ELT( 2, 3, RC[ 2]); \ + KF_ELT( 3, 4, RC[ 3]); \ + KF_ELT( 4, 5, RC[ 4]); \ + KF_ELT( 5, 6, RC[ 5]); \ + KF_ELT( 6, 7, RC[ 6]); \ + KF_ELT( 7, 8, RC[ 7]); \ + KF_ELT( 8, 9, RC[ 8]); \ + KF_ELT( 9, 10, RC[ 9]); \ + KF_ELT(10, 11, RC[10]); \ + KF_ELT(11, 12, RC[11]); \ + KF_ELT(12, 13, RC[12]); \ + KF_ELT(13, 14, RC[13]); \ + KF_ELT(14, 15, RC[14]); \ + KF_ELT(15, 16, RC[15]); \ + KF_ELT(16, 17, RC[16]); \ + KF_ELT(17, 18, RC[17]); \ + KF_ELT(18, 19, RC[18]); \ + KF_ELT(19, 20, RC[19]); \ + KF_ELT(20, 21, RC[20]); \ + KF_ELT(21, 22, RC[21]); \ + KF_ELT(22, 23, RC[22]); \ + KF_ELT(23, 0, RC[23]); \ + } while (0) + +#else + +#error Unimplemented unroll count for Keccak. + +#endif + +static void +keccak_init(sph_keccak_context *kc, unsigned out_size) +{ + int i; + +#if SPH_KECCAK_64 + for (i = 0; i < 25; i ++) + kc->u.wide[i] = 0; + /* + * Initialization for the "lane complement". + */ + kc->u.wide[ 1] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[ 2] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[ 8] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[12] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[17] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[20] = SPH_C64(0xFFFFFFFFFFFFFFFF); +#else + + for (i = 0; i < 50; i ++) + kc->u.narrow[i] = 0; + /* + * Initialization for the "lane complement". + * Note: since we set to all-one full 64-bit words, + * interleaving (if applicable) is a no-op. + */ + kc->u.narrow[ 2] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[ 3] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[ 4] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[ 5] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[16] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[17] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[24] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[25] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[34] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[35] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[40] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[41] = SPH_C32(0xFFFFFFFF); +#endif + kc->ptr = 0; + kc->lim = 200 - (out_size >> 2); +} + +static void +keccak_core(sph_keccak_context *kc, const void *data, size_t len, size_t lim) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE + + buf = kc->buf; + ptr = kc->ptr; + + if (len < (lim - ptr)) { + memcpy(buf + ptr, data, len); + kc->ptr = ptr + len; + return; + } + + READ_STATE(kc); + while (len > 0) { + size_t clen; + + clen = (lim - ptr); + if (clen > len) + clen = len; + memcpy(buf + ptr, data, clen); + ptr += clen; + data = (const unsigned char *)data + clen; + len -= clen; + if (ptr == lim) { + INPUT_BUF(lim); + KECCAK_F_1600; + ptr = 0; + } + } + WRITE_STATE(kc); + kc->ptr = ptr; +} + +#if SPH_KECCAK_64 + +#define DEFCLOSE(d, lim) \ + static void keccak_close ## d( \ + sph_keccak_context *kc, unsigned ub, unsigned n, void *dst) \ + { \ + unsigned eb; \ + union { \ + unsigned char tmp[lim + 1]; \ + sph_u64 dummy; /* for alignment */ \ + } u; \ + size_t j; \ + \ + eb = (0x100 | (ub & 0xFF)) >> (8 - n); \ + if (kc->ptr == (lim - 1)) { \ + if (n == 7) { \ + u.tmp[0] = eb; \ + memset(u.tmp + 1, 0, lim - 1); \ + u.tmp[lim] = 0x80; \ + j = 1 + lim; \ + } else { \ + u.tmp[0] = eb | 0x80; \ + j = 1; \ + } \ + } else { \ + j = lim - kc->ptr; \ + u.tmp[0] = eb; \ + memset(u.tmp + 1, 0, j - 2); \ + u.tmp[j - 1] = 0x80; \ + } \ + keccak_core(kc, u.tmp, j, lim); \ + /* Finalize the "lane complement" */ \ + kc->u.wide[ 1] = ~kc->u.wide[ 1]; \ + kc->u.wide[ 2] = ~kc->u.wide[ 2]; \ + kc->u.wide[ 8] = ~kc->u.wide[ 8]; \ + kc->u.wide[12] = ~kc->u.wide[12]; \ + kc->u.wide[17] = ~kc->u.wide[17]; \ + kc->u.wide[20] = ~kc->u.wide[20]; \ + for (j = 0; j < d; j += 8) \ + sph_enc64le_aligned(u.tmp + j, kc->u.wide[j >> 3]); \ + memcpy(dst, u.tmp, d); \ + keccak_init(kc, (unsigned)d << 3); \ + } \ + +#else + +#define DEFCLOSE(d, lim) \ + static void keccak_close ## d( \ + sph_keccak_context *kc, unsigned ub, unsigned n, void *dst) \ + { \ + unsigned eb; \ + union { \ + unsigned char tmp[lim + 1]; \ + sph_u64 dummy; /* for alignment */ \ + } u; \ + size_t j; \ + \ + eb = (0x100 | (ub & 0xFF)) >> (8 - n); \ + if (kc->ptr == (lim - 1)) { \ + if (n == 7) { \ + u.tmp[0] = eb; \ + memset(u.tmp + 1, 0, lim - 1); \ + u.tmp[lim] = 0x80; \ + j = 1 + lim; \ + } else { \ + u.tmp[0] = eb | 0x80; \ + j = 1; \ + } \ + } else { \ + j = lim - kc->ptr; \ + u.tmp[0] = eb; \ + memset(u.tmp + 1, 0, j - 2); \ + u.tmp[j - 1] = 0x80; \ + } \ + keccak_core(kc, u.tmp, j, lim); \ + /* Finalize the "lane complement" */ \ + kc->u.narrow[ 2] = ~kc->u.narrow[ 2]; \ + kc->u.narrow[ 3] = ~kc->u.narrow[ 3]; \ + kc->u.narrow[ 4] = ~kc->u.narrow[ 4]; \ + kc->u.narrow[ 5] = ~kc->u.narrow[ 5]; \ + kc->u.narrow[16] = ~kc->u.narrow[16]; \ + kc->u.narrow[17] = ~kc->u.narrow[17]; \ + kc->u.narrow[24] = ~kc->u.narrow[24]; \ + kc->u.narrow[25] = ~kc->u.narrow[25]; \ + kc->u.narrow[34] = ~kc->u.narrow[34]; \ + kc->u.narrow[35] = ~kc->u.narrow[35]; \ + kc->u.narrow[40] = ~kc->u.narrow[40]; \ + kc->u.narrow[41] = ~kc->u.narrow[41]; \ + /* un-interleave */ \ + for (j = 0; j < 50; j += 2) \ + UNINTERLEAVE(kc->u.narrow[j], kc->u.narrow[j + 1]); \ + for (j = 0; j < d; j += 4) \ + sph_enc32le_aligned(u.tmp + j, kc->u.narrow[j >> 2]); \ + memcpy(dst, u.tmp, d); \ + keccak_init(kc, (unsigned)d << 3); \ + } \ + +#endif + +DEFCLOSE(28, 144) +DEFCLOSE(32, 136) +DEFCLOSE(48, 104) +DEFCLOSE(64, 72) + +/* see sph_keccak.h */ +void +sph_keccak224_init(void *cc) +{ + keccak_init(cc, 224); +} + +/* see sph_keccak.h */ +void +sph_keccak224(void *cc, const void *data, size_t len) +{ + keccak_core(cc, data, len, 144); +} + +/* see sph_keccak.h */ +void +sph_keccak224_close(void *cc, void *dst) +{ + sph_keccak224_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + keccak_close28(cc, ub, n, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak256_init(void *cc) +{ + keccak_init(cc, 256); +} + +/* see sph_keccak.h */ +void +sph_keccak256(void *cc, const void *data, size_t len) +{ + keccak_core(cc, data, len, 136); +} + +/* see sph_keccak.h */ +void +sph_keccak256_close(void *cc, void *dst) +{ + sph_keccak256_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + keccak_close32(cc, ub, n, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak384_init(void *cc) +{ + keccak_init(cc, 384); +} + +/* see sph_keccak.h */ +void +sph_keccak384(void *cc, const void *data, size_t len) +{ + keccak_core(cc, data, len, 104); +} + +/* see sph_keccak.h */ +void +sph_keccak384_close(void *cc, void *dst) +{ + sph_keccak384_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + keccak_close48(cc, ub, n, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak512_init(void *cc) +{ + keccak_init(cc, 512); +} + +/* see sph_keccak.h */ +void +sph_keccak512(void *cc, const void *data, size_t len) +{ + keccak_core(cc, data, len, 72); +} + +/* see sph_keccak.h */ +void +sph_keccak512_close(void *cc, void *dst) +{ + sph_keccak512_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + keccak_close64(cc, ub, n, dst); +} + + +#ifdef __cplusplus +} +#endif diff --git a/src/kernel.cpp b/src/kernel.cpp new file mode 100644 index 0000000..9fd5c4e --- /dev/null +++ b/src/kernel.cpp @@ -0,0 +1,432 @@ +// Copyright (c) 2012-2013 The PPCoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include "kernel.h" +#include "db.h" + +using namespace std; + +extern int nStakeMaxAge; +extern int nStakeTargetSpacing; + +// Modifier interval: time to elapse before new modifier is computed +// Set to 3-hour for production network and 20-minute for test network + +unsigned int nModifierInterval = MODIFIER_INTERVAL; + +// Hard checkpoints of stake modifiers to ensure they are deterministic +static std::map mapStakeModifierCheckpoints = + boost::assign::map_list_of + ( 0, 0x0e00670bu ) + + ; + +// Get time weight +int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd) +{ + // Kernel hash weight starts from 0 at the min age + // this change increases active coins participating the hash and helps + // to secure the network when proof-of-stake difficulty is low + + return min(nIntervalEnd - nIntervalBeginning - nStakeMinAge, (int64)nStakeMaxAge); +} + +// Get the last stake modifier and its generation time from a given block +static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64& nStakeModifier, int64& nModifierTime) +{ + if (!pindex) + return error("GetLastStakeModifier: null pindex"); + while (pindex && pindex->pprev && !pindex->GeneratedStakeModifier()) + pindex = pindex->pprev; + if (!pindex->GeneratedStakeModifier()) + return error("GetLastStakeModifier: no generation at genesis block"); + nStakeModifier = pindex->nStakeModifier; + nModifierTime = pindex->GetBlockTime(); + return true; +} + +// Get selection interval section (in seconds) +static int64 GetStakeModifierSelectionIntervalSection(int nSection) +{ + assert (nSection >= 0 && nSection < 64); + int64 a = nModifierInterval * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1))); + return a; +} + +// Get stake modifier selection interval (in seconds) +static int64 GetStakeModifierSelectionInterval() +{ + int64 nSelectionInterval = 0; + for (int nSection=0; nSection<64; nSection++) + { + nSelectionInterval += GetStakeModifierSelectionIntervalSection(nSection); + } + return nSelectionInterval; +} + +// select a block from the candidate blocks in vSortedByTimestamp, excluding +// already selected blocks in vSelectedBlocks, and with timestamp up to +// nSelectionIntervalStop. +static bool SelectBlockFromCandidates( + vector >& vSortedByTimestamp, + map& mapSelectedBlocks, + int64 nSelectionIntervalStop, uint64 nStakeModifierPrev, + const CBlockIndex** pindexSelected) +{ + bool fSelected = false; + uint256 hashBest = 0; + *pindexSelected = (const CBlockIndex*) 0; + BOOST_FOREACH(const PAIRTYPE(int64, uint256)& item, vSortedByTimestamp) + { + if (!mapBlockIndex.count(item.second)) + return error("SelectBlockFromCandidates: failed to find block index for candidate block %s", item.second.ToString().c_str()); + const CBlockIndex* pindex = mapBlockIndex[item.second]; + if (fSelected && pindex->GetBlockTime() > nSelectionIntervalStop) + break; + if (mapSelectedBlocks.count(pindex->GetBlockHash()) > 0) + continue; + // compute the selection hash by hashing its proof-hash and the + // previous proof-of-stake modifier + uint256 hashProof = pindex->IsProofOfStake()? pindex->hashProofOfStake : pindex->GetBlockHash(); + CDataStream ss(SER_GETHASH, 0); + ss << hashProof << nStakeModifierPrev; + uint256 hashSelection = Hash(ss.begin(), ss.end()); + // the selection hash is divided by 2**32 so that proof-of-stake block + // is always favored over proof-of-work block. this is to preserve + // the energy efficiency property + if (pindex->IsProofOfStake()) + hashSelection >>= 32; + if (fSelected && hashSelection < hashBest) + { + hashBest = hashSelection; + *pindexSelected = (const CBlockIndex*) pindex; + } + else if (!fSelected) + { + fSelected = true; + hashBest = hashSelection; + *pindexSelected = (const CBlockIndex*) pindex; + } + } + if (fDebug && GetBoolArg("-printstakemodifier")) + printf("SelectBlockFromCandidates: selection hash=%s\n", hashBest.ToString().c_str()); + return fSelected; +} + +// Stake Modifier (hash modifier of proof-of-stake): +// The purpose of stake modifier is to prevent a txout (coin) owner from +// computing future proof-of-stake generated by this txout at the time +// of transaction confirmation. To meet kernel protocol, the txout +// must hash with a future stake modifier to generate the proof. +// Stake modifier consists of bits each of which is contributed from a +// selected block of a given block group in the past. +// The selection of a block is based on a hash of the block's proof-hash and +// the previous stake modifier. +// Stake modifier is recomputed at a fixed time interval instead of every +// block. This is to make it difficult for an attacker to gain control of +// additional bits in the stake modifier, even after generating a chain of +// blocks. +bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64& nStakeModifier, bool& fGeneratedStakeModifier) +{ + nStakeModifier = 0; + fGeneratedStakeModifier = false; + if (!pindexPrev) + { + fGeneratedStakeModifier = true; + return true; // genesis block's modifier is 0 + } + // First find current stake modifier and its generation block time + // if it's not old enough, return the same stake modifier + int64 nModifierTime = 0; + if (!GetLastStakeModifier(pindexPrev, nStakeModifier, nModifierTime)) + return error("ComputeNextStakeModifier: unable to get last modifier"); + if (fDebug) + { + printf("ComputeNextStakeModifier: prev modifier=0x%016"PRI64x" time=%s\n", nStakeModifier, DateTimeStrFormat(nModifierTime).c_str()); + } + if (nModifierTime / nModifierInterval >= pindexPrev->GetBlockTime() / nModifierInterval) + return true; + + // Sort candidate blocks by timestamp + vector > vSortedByTimestamp; + vSortedByTimestamp.reserve(64 * nModifierInterval / nStakeTargetSpacing); + int64 nSelectionInterval = GetStakeModifierSelectionInterval(); + int64 nSelectionIntervalStart = (pindexPrev->GetBlockTime() / nModifierInterval) * nModifierInterval - nSelectionInterval; + const CBlockIndex* pindex = pindexPrev; + while (pindex && pindex->GetBlockTime() >= nSelectionIntervalStart) + { + vSortedByTimestamp.push_back(make_pair(pindex->GetBlockTime(), pindex->GetBlockHash())); + pindex = pindex->pprev; + } + int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0; + reverse(vSortedByTimestamp.begin(), vSortedByTimestamp.end()); + sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end()); + + // Select 64 blocks from candidate blocks to generate stake modifier + uint64 nStakeModifierNew = 0; + int64 nSelectionIntervalStop = nSelectionIntervalStart; + map mapSelectedBlocks; + for (int nRound=0; nRoundGetStakeEntropyBit()) << nRound); + // add the selected block from candidates to selected list + mapSelectedBlocks.insert(make_pair(pindex->GetBlockHash(), pindex)); + if (fDebug && GetBoolArg("-printstakemodifier")) + printf("ComputeNextStakeModifier: selected round %d stop=%s height=%d bit=%d\n", + nRound, DateTimeStrFormat(nSelectionIntervalStop).c_str(), pindex->nHeight, pindex->GetStakeEntropyBit()); + } + + // Print selection map for visualization of the selected blocks + if (fDebug && GetBoolArg("-printstakemodifier")) + { + string strSelectionMap = ""; + // '-' indicates proof-of-work blocks not selected + strSelectionMap.insert(0, pindexPrev->nHeight - nHeightFirstCandidate + 1, '-'); + pindex = pindexPrev; + while (pindex && pindex->nHeight >= nHeightFirstCandidate) + { + // '=' indicates proof-of-stake blocks not selected + if (pindex->IsProofOfStake()) + strSelectionMap.replace(pindex->nHeight - nHeightFirstCandidate, 1, "="); + pindex = pindex->pprev; + } + BOOST_FOREACH(const PAIRTYPE(uint256, const CBlockIndex*)& item, mapSelectedBlocks) + { + // 'S' indicates selected proof-of-stake blocks + // 'W' indicates selected proof-of-work blocks + strSelectionMap.replace(item.second->nHeight - nHeightFirstCandidate, 1, item.second->IsProofOfStake()? "S" : "W"); + } + printf("ComputeNextStakeModifier: selection height [%d, %d] map %s\n", nHeightFirstCandidate, pindexPrev->nHeight, strSelectionMap.c_str()); + } + if (fDebug) + { + printf("ComputeNextStakeModifier: new modifier=0x%016"PRI64x" time=%s\n", nStakeModifierNew, DateTimeStrFormat(pindexPrev->GetBlockTime()).c_str()); + } + + nStakeModifier = nStakeModifierNew; + fGeneratedStakeModifier = true; + return true; +} + +// The stake modifier used to hash for a stake kernel is chosen as the stake +// modifier about a selection interval later than the coin generating the kernel +static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier, int& nStakeModifierHeight, int64& nStakeModifierTime, bool fPrintProofOfStake) +{ + nStakeModifier = 0; + if (!mapBlockIndex.count(hashBlockFrom)) + return error("GetKernelStakeModifier() : block not indexed"); + const CBlockIndex* pindexFrom = mapBlockIndex[hashBlockFrom]; + nStakeModifierHeight = pindexFrom->nHeight; + nStakeModifierTime = pindexFrom->GetBlockTime(); + int64 nStakeModifierSelectionInterval = GetStakeModifierSelectionInterval(); + const CBlockIndex* pindex = pindexFrom; + + // loop to find the stake modifier later by a selection interval + while (nStakeModifierTime < pindexFrom->GetBlockTime() + nStakeModifierSelectionInterval) + { + if (!pindex->pnext) + { // reached best block; may happen if node is behind on block chain + if (fPrintProofOfStake || (pindex->GetBlockTime() + nStakeMinAge - nStakeModifierSelectionInterval > GetAdjustedTime())) + return error("GetKernelStakeModifier() : reached best block %s at height %d from block %s", + pindex->GetBlockHash().ToString().c_str(), pindex->nHeight, hashBlockFrom.ToString().c_str()); + else + { + if(fDebug) + printf(">> nStakeModifierTime = %"PRI64d", pindexFrom->GetBlockTime() = %"PRI64d", nStakeModifierSelectionInterval = %"PRI64d"\n", + nStakeModifierTime, pindexFrom->GetBlockTime(), nStakeModifierSelectionInterval); + + return false; + } + } + pindex = pindex->pnext; + if (pindex->GeneratedStakeModifier()) + { + nStakeModifierHeight = pindex->nHeight; + nStakeModifierTime = pindex->GetBlockTime(); + } + } + nStakeModifier = pindex->nStakeModifier; + return true; +} + +// ppcoin kernel protocol +// coinstake must meet hash target according to the protocol: +// kernel (input 0) must meet the formula +// hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget * nCoinDayWeight +// this ensures that the chance of getting a coinstake is proportional to the +// amount of coin age one owns. +// The reason this hash is chosen is the following: +// nStakeModifier: +// (v0.3) scrambles computation to make it very difficult to precompute +// future proof-of-stake at the time of the coin's confirmation +// (v0.2) nBits (deprecated): encodes all past block timestamps +// txPrev.block.nTime: prevent nodes from guessing a good timestamp to +// generate transaction for future advantage +// txPrev.offset: offset of txPrev inside block, to reduce the chance of +// nodes generating coinstake at the same time +// txPrev.nTime: reduce the chance of nodes generating coinstake at the same +// time +// txPrev.vout.n: output number of txPrev, to reduce the chance of nodes +// generating coinstake at the same time +// block/tx hash should not be used here as they can be generated in vast +// quantities so as to generate blocks faster, degrading the system back into +// a proof-of-work situation. +// +bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, bool fPrintProofOfStake) +{ + if (nTimeTx < txPrev.nTime) // Transaction timestamp violation + return error("CheckStakeKernelHash() : nTime violation"); + + unsigned int nTimeBlockFrom = blockFrom.GetBlockTime(); + if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement + return error("CheckStakeKernelHash() : min age violation"); + + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(nBits); + int64 nValueIn = txPrev.vout[prevout.n].nValue; + + // v0.3 protocol kernel hash weight starts from 0 at the min age + // this change increases active coins participating the hash and helps + // to secure the network when proof-of-stake difficulty is low + int64 nTimeWeight = min((int64)nTimeTx - txPrev.nTime, (int64)nStakeMaxAge) - nStakeMinAge; + CBigNum bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60); + + // printf(">>> CheckStakeKernelHash: nTimeWeight = %"PRI64d"\n", nTimeWeight); + // Calculate hash + CDataStream ss(SER_GETHASH, 0); + uint64 nStakeModifier = 0; + int nStakeModifierHeight = 0; + int64 nStakeModifierTime = 0; + + if (!GetKernelStakeModifier(blockFrom.GetHash(), nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake)) + { + if(fDebug) + printf(">>> CheckStakeKernelHash: GetKernelStakeModifier return false\n"); + + return false; + } + + if(fDebug && fPrintProofOfStake) + printf(">>> CheckStakeKernelHash: passed GetKernelStakeModifier\n"); + + ss << nStakeModifier; + + ss << nTimeBlockFrom << nTxPrevOffset << txPrev.nTime << prevout.n << nTimeTx; + hashProofOfStake = Hash(ss.begin(), ss.end()); + if (fPrintProofOfStake) + { + printf("CheckStakeKernelHash() : using modifier 0x%016"PRI64x" at height=%d timestamp=%s for block from height=%d timestamp=%s\n", + nStakeModifier, nStakeModifierHeight, + DateTimeStrFormat(nStakeModifierTime).c_str(), + mapBlockIndex[blockFrom.GetHash()]->nHeight, + DateTimeStrFormat(blockFrom.GetBlockTime()).c_str()); + printf("CheckStakeKernelHash() : check protocol=%s modifier=0x%016"PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", + "0.3", + nStakeModifier, + nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx, + hashProofOfStake.ToString().c_str()); + } + + // Now check if proof-of-stake hash meets target protocol + if (CBigNum(hashProofOfStake) > bnCoinDayWeight * bnTargetPerCoinDay) + { + if(fDebug) + { + printf(">>> bnCoinDayWeight = %s, bnTargetPerCoinDay=%s\n", + bnCoinDayWeight.ToString().c_str(), bnTargetPerCoinDay.ToString().c_str()); + printf(">>> CheckStakeKernelHash - hashProofOfStake too much\n"); + } + return false; + } + + + if (fDebug && !fPrintProofOfStake) + { + printf("CheckStakeKernelHash() : using modifier 0x%016"PRI64x" at height=%d timestamp=%s for block from height=%d timestamp=%s\n", + nStakeModifier, nStakeModifierHeight, + DateTimeStrFormat(nStakeModifierTime).c_str(), + mapBlockIndex[blockFrom.GetHash()]->nHeight, + DateTimeStrFormat(blockFrom.GetBlockTime()).c_str()); + printf("CheckStakeKernelHash() : pass protocol=%s modifier=0x%016"PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", + "0.3", + nStakeModifier, + nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx, + hashProofOfStake.ToString().c_str()); + } + return true; +} + +// Check kernel hash target and coinstake signature +bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake) +{ + if (!tx.IsCoinStake()) + return error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString().c_str()); + + // Kernel (input 0) must match the stake hash target per coin age (nBits) + const CTxIn& txin = tx.vin[0]; + + // First try finding the previous transaction in database + CTxDB txdb("r"); + CTransaction txPrev; + CTxIndex txindex; + if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) + return tx.DoS(1, error("CheckProofOfStake() : INFO: read txPrev failed")); // previous transaction not in main chain, may occur during initial download + txdb.Close(); + + // Verify signature + if (!VerifySignature(txPrev, tx, 0, true, 0)) + return tx.DoS(100, error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx.GetHash().ToString().c_str())); + + // Read block header + CBlock block; + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + return fDebug? error("CheckProofOfStake() : read block failed") : false; // unable to read block of previous transaction + + if (!CheckStakeKernelHash(nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, txPrev, txin.prevout, tx.nTime, hashProofOfStake, fDebug)) + return tx.DoS(1, error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s", tx.GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str())); // may occur during initial download or if behind on block chain sync + + return true; +} + +// Check whether the coinstake timestamp meets protocol +bool CheckCoinStakeTimestamp(int64 nTimeBlock, int64 nTimeTx) +{ + // v0.3 protocol + return (nTimeBlock == nTimeTx); +} + +// Get stake modifier checksum +unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex) +{ + assert (pindex->pprev || pindex->GetBlockHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)); + // Hash previous checksum with flags, hashProofOfStake and nStakeModifier + CDataStream ss(SER_GETHASH, 0); + if (pindex->pprev) + ss << pindex->pprev->nStakeModifierChecksum; + ss << pindex->nFlags << pindex->hashProofOfStake << pindex->nStakeModifier; + uint256 hashChecksum = Hash(ss.begin(), ss.end()); + hashChecksum >>= (256 - 32); + if(fDebug) + printf("stake checksum: 0x%016"PRI64x"", hashChecksum.Get64()); + return hashChecksum.Get64(); +} + +// Check stake modifier hard checkpoints +bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum) +{ + if (fTestNet) return true; // Testnet has no checkpoints + if (mapStakeModifierCheckpoints.count(nHeight)) + { + return nStakeModifierChecksum == mapStakeModifierCheckpoints[nHeight]; + } + return true; +} diff --git a/src/kernel.h b/src/kernel.h new file mode 100644 index 0000000..d757a20 --- /dev/null +++ b/src/kernel.h @@ -0,0 +1,40 @@ +// Copyright (c) 2012-2013 The PPCoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef PPCOIN_KERNEL_H +#define PPCOIN_KERNEL_H + +#include "main.h" + +// MODIFIER_INTERVAL: time to elapse before new modifier is computed +static const unsigned int MODIFIER_INTERVAL = 5 * 60;// * 60; // 20 minutes +extern unsigned int nModifierInterval; + +// MODIFIER_INTERVAL_RATIO: +// ratio of group interval length between the last group and the first group +static const int MODIFIER_INTERVAL_RATIO = 3; + +// Compute the hash modifier for proof-of-stake +bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64& nStakeModifier, bool& fGeneratedStakeModifier); + +// Check whether stake kernel meets hash target +// Sets hashProofOfStake on success return +bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, bool fPrintProofOfStake=false); + +// Check kernel hash target and coinstake signature +// Sets hashProofOfStake on success return +bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake); + +// Check whether the coinstake timestamp meets protocol +bool CheckCoinStakeTimestamp(int64 nTimeBlock, int64 nTimeTx); + +// Get stake modifier checksum +unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex); + +// Check stake modifier hard checkpoints +bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum); + +// Get time weight using supplied timestamps +int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd); + +#endif // PPCOIN_KERNEL_H diff --git a/src/key.cpp b/src/key.cpp new file mode 100644 index 0000000..23f3152 --- /dev/null +++ b/src/key.cpp @@ -0,0 +1,406 @@ +// Copyright (c) 2009-2012 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 + +#include +#include + +#include "key.h" + +// Generate a private key from just the secret parameter +int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) +{ + int ok = 0; + BN_CTX *ctx = NULL; + EC_POINT *pub_key = NULL; + + if (!eckey) return 0; + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + pub_key = EC_POINT_new(group); + + if (pub_key == NULL) + goto err; + + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) + goto err; + + EC_KEY_set_private_key(eckey,priv_key); + EC_KEY_set_public_key(eckey,pub_key); + + ok = 1; + +err: + + if (pub_key) + EC_POINT_free(pub_key); + if (ctx != NULL) + BN_CTX_free(ctx); + + return(ok); +} + +// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields +// recid selects which key is recovered +// if check is non-zero, additional checks are performed +int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) +{ + if (!eckey) return 0; + + int ret = 0; + BN_CTX *ctx = NULL; + + BIGNUM *x = NULL; + BIGNUM *e = NULL; + BIGNUM *order = NULL; + BIGNUM *sor = NULL; + BIGNUM *eor = NULL; + BIGNUM *field = NULL; + EC_POINT *R = NULL; + EC_POINT *O = NULL; + EC_POINT *Q = NULL; + BIGNUM *rr = NULL; + BIGNUM *zero = NULL; + int n = 0; + int i = recid / 2; + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; } + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; } + x = BN_CTX_get(ctx); + if (!BN_copy(x, order)) { ret=-1; goto err; } + if (!BN_mul_word(x, i)) { ret=-1; goto err; } + if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; } + field = BN_CTX_get(ctx); + if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } + if (BN_cmp(x, field) >= 0) { ret=0; goto err; } + if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; } + if (check) + { + if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; } + if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; } + } + if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + n = EC_GROUP_get_degree(group); + e = BN_CTX_get(ctx); + if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } + if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); + zero = BN_CTX_get(ctx); + if (!BN_zero(zero)) { ret=-1; goto err; } + if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } + rr = BN_CTX_get(ctx); + if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; } + sor = BN_CTX_get(ctx); + if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; } + eor = BN_CTX_get(ctx); + if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } + if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } + if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; } + + ret = 1; + +err: + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (R != NULL) EC_POINT_free(R); + if (O != NULL) EC_POINT_free(O); + if (Q != NULL) EC_POINT_free(Q); + return ret; +} + +void CKey::SetCompressedPubKey() +{ + EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED); + fCompressedPubKey = true; +} + +void CKey::Reset() +{ + fCompressedPubKey = false; + if (pkey != NULL) + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); + fSet = false; +} + +CKey::CKey() +{ + pkey = NULL; + Reset(); +} + +CKey::CKey(const CKey& b) +{ + pkey = EC_KEY_dup(b.pkey); + if (pkey == NULL) + throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); + fSet = b.fSet; +} + +CKey& CKey::operator=(const CKey& b) +{ + if (!EC_KEY_copy(pkey, b.pkey)) + throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); + fSet = b.fSet; + return (*this); +} + +CKey::~CKey() +{ + EC_KEY_free(pkey); +} + +bool CKey::IsNull() const +{ + return !fSet; +} + +bool CKey::IsCompressed() const +{ + return fCompressedPubKey; +} + +void CKey::MakeNewKey(bool fCompressed) +{ + if (!EC_KEY_generate_key(pkey)) + throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); + if (fCompressed) + SetCompressedPubKey(); + fSet = true; +} + +bool CKey::SetPrivKey(const CPrivKey& vchPrivKey) +{ + const unsigned char* pbegin = &vchPrivKey[0]; + if (d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) + { + // In testing, d2i_ECPrivateKey can return true + // but fill in pkey with a key that fails + // EC_KEY_check_key, so: + if (EC_KEY_check_key(pkey)) + { + fSet = true; + return true; + } + } + // If vchPrivKey data is bad d2i_ECPrivateKey() can + // leave pkey in a state where calling EC_KEY_free() + // crashes. To avoid that, set pkey to NULL and + // leak the memory (a leak is better than a crash) + pkey = NULL; + Reset(); + return false; +} + +bool CKey::SetSecret(const CSecret& vchSecret, bool fCompressed) +{ + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed"); + if (vchSecret.size() != 32) + throw key_error("CKey::SetSecret() : secret must be 32 bytes"); + BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new()); + if (bn == NULL) + throw key_error("CKey::SetSecret() : BN_bin2bn failed"); + if (!EC_KEY_regenerate_key(pkey,bn)) + { + BN_clear_free(bn); + throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed"); + } + BN_clear_free(bn); + fSet = true; + if (fCompressed || fCompressedPubKey) + SetCompressedPubKey(); + return true; +} + +CSecret CKey::GetSecret(bool &fCompressed) const +{ + CSecret vchRet; + vchRet.resize(32); + const BIGNUM *bn = EC_KEY_get0_private_key(pkey); + int nBytes = BN_num_bytes(bn); + if (bn == NULL) + throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed"); + int n=BN_bn2bin(bn,&vchRet[32 - nBytes]); + if (n != nBytes) + throw key_error("CKey::GetSecret(): BN_bn2bin failed"); + fCompressed = fCompressedPubKey; + return vchRet; +} + +CPrivKey CKey::GetPrivKey() const +{ + int nSize = i2d_ECPrivateKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed"); + CPrivKey vchPrivKey(nSize, 0); + unsigned char* pbegin = &vchPrivKey[0]; + if (i2d_ECPrivateKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size"); + return vchPrivKey; +} + +bool CKey::SetPubKey(const CPubKey& vchPubKey) +{ + const unsigned char* pbegin = &vchPubKey.vchPubKey[0]; + if (o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.vchPubKey.size())) + { + fSet = true; + if (vchPubKey.vchPubKey.size() == 33) + SetCompressedPubKey(); + return true; + } + pkey = NULL; + Reset(); + return false; +} + +CPubKey CKey::GetPubKey() const +{ + int nSize = i2o_ECPublicKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed"); + std::vector vchPubKey(nSize, 0); + unsigned char* pbegin = &vchPubKey[0]; + if (i2o_ECPublicKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); + return CPubKey(vchPubKey); +} + +bool CKey::Sign(uint256 hash, std::vector& vchSig) +{ + unsigned int nSize = ECDSA_size(pkey); + vchSig.resize(nSize); // Make sure it is big enough + if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey)) + { + vchSig.clear(); + return false; + } + vchSig.resize(nSize); // Shrink to fit actual size + return true; +} + +// create a compact signature (65 bytes), which allows reconstructing the used public key +// The format is one header byte, followed by two times 32 bytes for the serialized r and s values. +// The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, +// 0x1D = second key with even y, 0x1E = second key with odd y +bool CKey::SignCompact(uint256 hash, std::vector& vchSig) +{ + bool fOk = false; + ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); + if (sig==NULL) + return false; + vchSig.clear(); + vchSig.resize(65,0); + int nBitsR = BN_num_bits(sig->r); + int nBitsS = BN_num_bits(sig->s); + if (nBitsR <= 256 && nBitsS <= 256) + { + int nRecId = -1; + for (int i=0; i<4; i++) + { + CKey keyRec; + keyRec.fSet = true; + if (fCompressedPubKey) + keyRec.SetCompressedPubKey(); + if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1) + if (keyRec.GetPubKey() == this->GetPubKey()) + { + nRecId = i; + break; + } + } + + if (nRecId == -1) + throw key_error("CKey::SignCompact() : unable to construct recoverable key"); + + vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0); + BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]); + BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]); + fOk = true; + } + ECDSA_SIG_free(sig); + return fOk; +} + +// reconstruct public key from a compact signature +// This is only slightly more CPU intensive than just verifying it. +// If this function succeeds, the recovered public key is guaranteed to be valid +// (the signature is a valid signature of the given data for that key) +bool CKey::SetCompactSignature(uint256 hash, const std::vector& vchSig) +{ + if (vchSig.size() != 65) + return false; + int nV = vchSig[0]; + if (nV<27 || nV>=35) + return false; + ECDSA_SIG *sig = ECDSA_SIG_new(); + BN_bin2bn(&vchSig[1],32,sig->r); + BN_bin2bn(&vchSig[33],32,sig->s); + + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (nV >= 31) + { + SetCompressedPubKey(); + nV -= 4; + } + if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1) + { + fSet = true; + ECDSA_SIG_free(sig); + return true; + } + return false; +} + +bool CKey::Verify(uint256 hash, const std::vector& vchSig) +{ + // -1 = error, 0 = bad sig, 1 = good + if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) + return false; + + return true; +} + +bool CKey::VerifyCompact(uint256 hash, const std::vector& vchSig) +{ + CKey key; + if (!key.SetCompactSignature(hash, vchSig)) + return false; + if (GetPubKey() != key.GetPubKey()) + return false; + + return true; +} + +bool CKey::IsValid() +{ + if (!fSet) + return false; + + if (!EC_KEY_check_key(pkey)) + return false; + + bool fCompr; + CSecret secret = GetSecret(fCompr); + CKey key2; + key2.SetSecret(secret, fCompr); + return GetPubKey() == key2.GetPubKey(); +} diff --git a/src/key.h b/src/key.h new file mode 100644 index 0000000..c98f52e --- /dev/null +++ b/src/key.h @@ -0,0 +1,162 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_KEY_H +#define BITCOIN_KEY_H + +#include +#include + +#include "allocators.h" +#include "serialize.h" +#include "uint256.h" +#include "util.h" + +#include // for EC_KEY definition + +// secp160k1 +// const unsigned int PRIVATE_KEY_SIZE = 192; +// const unsigned int PUBLIC_KEY_SIZE = 41; +// const unsigned int SIGNATURE_SIZE = 48; +// +// secp192k1 +// const unsigned int PRIVATE_KEY_SIZE = 222; +// const unsigned int PUBLIC_KEY_SIZE = 49; +// const unsigned int SIGNATURE_SIZE = 57; +// +// secp224k1 +// const unsigned int PRIVATE_KEY_SIZE = 250; +// const unsigned int PUBLIC_KEY_SIZE = 57; +// const unsigned int SIGNATURE_SIZE = 66; +// +// secp256k1: +// const unsigned int PRIVATE_KEY_SIZE = 279; +// const unsigned int PUBLIC_KEY_SIZE = 65; +// const unsigned int SIGNATURE_SIZE = 72; +// +// see www.keylength.com +// script supports up to 75 for single byte push + +class key_error : public std::runtime_error +{ +public: + explicit key_error(const std::string& str) : std::runtime_error(str) {} +}; + +/** A reference to a CKey: the Hash160 of its serialized public key */ +class CKeyID : public uint160 +{ +public: + CKeyID() : uint160(0) { } + CKeyID(const uint160 &in) : uint160(in) { } +}; + +/** A reference to a CScript: the Hash160 of its serialization (see script.h) */ +class CScriptID : public uint160 +{ +public: + CScriptID() : uint160(0) { } + CScriptID(const uint160 &in) : uint160(in) { } +}; + +/** An encapsulated public key. */ +class CPubKey { +private: + std::vector vchPubKey; + friend class CKey; + +public: + CPubKey() { } + CPubKey(const std::vector &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { } + friend bool operator==(const CPubKey &a, const CPubKey &b) { return a.vchPubKey == b.vchPubKey; } + friend bool operator!=(const CPubKey &a, const CPubKey &b) { return a.vchPubKey != b.vchPubKey; } + friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; } + + IMPLEMENT_SERIALIZE( + READWRITE(vchPubKey); + ) + + CKeyID GetID() const { + return CKeyID(Hash160(vchPubKey)); + } + + uint256 GetHash() const { + return Hash(vchPubKey.begin(), vchPubKey.end()); + } + + bool IsValid() const { + return vchPubKey.size() == 33 || vchPubKey.size() == 65; + } + + bool IsCompressed() const { + return vchPubKey.size() == 33; + } + + std::vector Raw() const { + return vchPubKey; + } +}; + + +// secure_allocator is defined in allocators.h +// CPrivKey is a serialized private key, with all parameters included (279 bytes) +typedef std::vector > CPrivKey; +// CSecret is a serialization of just the secret parameter (32 bytes) +typedef std::vector > CSecret; + +/** An encapsulated OpenSSL Elliptic Curve key (public and/or private) */ +class CKey +{ +protected: + EC_KEY* pkey; + bool fSet; + bool fCompressedPubKey; + + void SetCompressedPubKey(); + +public: + + void Reset(); + + CKey(); + CKey(const CKey& b); + + CKey& operator=(const CKey& b); + + ~CKey(); + + bool IsNull() const; + bool IsCompressed() const; + + void MakeNewKey(bool fCompressed); + bool SetPrivKey(const CPrivKey& vchPrivKey); + bool SetSecret(const CSecret& vchSecret, bool fCompressed = false); + CSecret GetSecret(bool &fCompressed) const; + CPrivKey GetPrivKey() const; + bool SetPubKey(const CPubKey& vchPubKey); + CPubKey GetPubKey() const; + + bool Sign(uint256 hash, std::vector& vchSig); + + // create a compact signature (65 bytes), which allows reconstructing the used public key + // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. + // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, + // 0x1D = second key with even y, 0x1E = second key with odd y + bool SignCompact(uint256 hash, std::vector& vchSig); + + // reconstruct public key from a compact signature + // This is only slightly more CPU intensive than just verifying it. + // If this function succeeds, the recovered public key is guaranteed to be valid + // (the signature is a valid signature of the given data for that key) + bool SetCompactSignature(uint256 hash, const std::vector& vchSig); + + bool Verify(uint256 hash, const std::vector& vchSig); + + // Verify a compact signature + bool VerifyCompact(uint256 hash, const std::vector& vchSig); + + bool IsValid(); +}; + +#endif diff --git a/src/keystore.cpp b/src/keystore.cpp new file mode 100644 index 0000000..e0cf805 --- /dev/null +++ b/src/keystore.cpp @@ -0,0 +1,221 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "keystore.h" +#include "script.h" + +bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const +{ + CKey key; + if (!GetKey(address, key)) + return false; + vchPubKeyOut = key.GetPubKey(); + return true; +} + +bool CBasicKeyStore::AddKey(const CKey& key) +{ + bool fCompressed = false; + CSecret secret = key.GetSecret(fCompressed); + { + LOCK(cs_KeyStore); + mapKeys[key.GetPubKey().GetID()] = make_pair(secret, fCompressed); + } + return true; +} + +bool CBasicKeyStore::AddCScript(const CScript& redeemScript) +{ + { + LOCK(cs_KeyStore); + mapScripts[redeemScript.GetID()] = redeemScript; + } + return true; +} + +bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const +{ + bool result; + { + LOCK(cs_KeyStore); + result = (mapScripts.count(hash) > 0); + } + return result; +} + + +bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const +{ + { + LOCK(cs_KeyStore); + ScriptMap::const_iterator mi = mapScripts.find(hash); + if (mi != mapScripts.end()) + { + redeemScriptOut = (*mi).second; + return true; + } + } + return false; +} + +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(); + } + + NotifyStatusChanged(this); + return true; +} + +bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) +{ + { + LOCK(cs_KeyStore); + if (!SetCrypted()) + return false; + + CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); + for (; mi != mapCryptedKeys.end(); ++mi) + { + const CPubKey &vchPubKey = (*mi).second.first; + const std::vector &vchCryptedSecret = (*mi).second.second; + CSecret vchSecret; + if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) + return false; + if (vchSecret.size() != 32) + return false; + CKey key; + key.SetPubKey(vchPubKey); + key.SetSecret(vchSecret); + if (key.GetPubKey() == vchPubKey) + break; + return false; + } + vMasterKey = vMasterKeyIn; + } + NotifyStatusChanged(this); + return true; +} + +bool CCryptoKeyStore::AddKey(const CKey& key) +{ + { + LOCK(cs_KeyStore); + if (!IsCrypted()) + return CBasicKeyStore::AddKey(key); + + if (IsLocked()) + return false; + + std::vector vchCryptedSecret; + CPubKey vchPubKey = key.GetPubKey(); + bool fCompressed; + if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret)) + return false; + + if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) + return false; + } + return true; +} + + +bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector &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 &vchCryptedSecret = (*mi).second.second; + CSecret vchSecret; + if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) + return false; + if (vchSecret.size() != 32) + return false; + keyOut.SetPubKey(vchPubKey); + keyOut.SetSecret(vchSecret); + 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; + BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys) + { + CKey key; + if (!key.SetSecret(mKey.second.first, mKey.second.second)) + return false; + const CPubKey vchPubKey = key.GetPubKey(); + std::vector vchCryptedSecret; + bool fCompressed; + if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret)) + return false; + if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) + return false; + } + mapKeys.clear(); + } + return true; +} diff --git a/src/keystore.h b/src/keystore.h new file mode 100644 index 0000000..ab369bb --- /dev/null +++ b/src/keystore.h @@ -0,0 +1,184 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_KEYSTORE_H +#define BITCOIN_KEYSTORE_H + +#include "crypter.h" +#include "sync.h" +#include + +class CScript; + +/** A virtual base class for key stores */ +class CKeyStore +{ +protected: + mutable CCriticalSection cs_KeyStore; + +public: + virtual ~CKeyStore() {} + + // Add a key to the store. + virtual bool AddKey(const CKey& key) =0; + + // Check whether a key corresponding to a given address is present in the store. + virtual bool HaveKey(const CKeyID &address) const =0; + virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0; + virtual void GetKeys(std::set &setAddress) const =0; + virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + + // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013 + virtual bool AddCScript(const CScript& redeemScript) =0; + virtual bool HaveCScript(const CScriptID &hash) const =0; + virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0; + + virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const + { + CKey key; + if (!GetKey(address, key)) + return false; + vchSecret = key.GetSecret(fCompressed); + return true; + } +}; + +typedef std::map > KeyMap; +typedef std::map ScriptMap; + +/** Basic key store, that keeps keys in an address->secret map */ +class CBasicKeyStore : public CKeyStore +{ +protected: + KeyMap mapKeys; + ScriptMap mapScripts; + +public: + bool AddKey(const CKey& key); + bool HaveKey(const CKeyID &address) const + { + bool result; + { + LOCK(cs_KeyStore); + result = (mapKeys.count(address) > 0); + } + return result; + } + void GetKeys(std::set &setAddress) const + { + setAddress.clear(); + { + LOCK(cs_KeyStore); + KeyMap::const_iterator mi = mapKeys.begin(); + while (mi != mapKeys.end()) + { + setAddress.insert((*mi).first); + mi++; + } + } + } + bool GetKey(const CKeyID &address, CKey &keyOut) const + { + { + LOCK(cs_KeyStore); + KeyMap::const_iterator mi = mapKeys.find(address); + if (mi != mapKeys.end()) + { + keyOut.Reset(); + keyOut.SetSecret((*mi).second.first, (*mi).second.second); + return true; + } + } + return false; + } + virtual bool AddCScript(const CScript& redeemScript); + virtual bool HaveCScript(const CScriptID &hash) const; + virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const; +}; + +typedef std::map > > CryptedKeyMap; + +/** 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; + +protected: + bool SetCrypted(); + + // will encrypt previously unencrypted keys + bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); + + bool Unlock(const CKeyingMaterial& vMasterKeyIn); + +public: + CCryptoKeyStore() : fUseCrypto(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 &vchCryptedSecret); + bool AddKey(const CKey& key); + 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 &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++; + } + } + + /* Wallet status (encrypted, locked) changed. + * Note: Called without locks held. + */ + boost::signals2::signal NotifyStatusChanged; +}; + +#endif diff --git a/src/luffa.c b/src/luffa.c new file mode 100644 index 0000000..a761bea --- /dev/null +++ b/src/luffa.c @@ -0,0 +1,1426 @@ +/* $Id: luffa.c 219 2010-06-08 17:24:41Z tp $ */ +/* + * Luffa 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 + */ + +#include +#include +#include + +#include "sph_luffa.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_64_TRUE && !defined SPH_LUFFA_PARALLEL +#define SPH_LUFFA_PARALLEL 1 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +static const sph_u32 V_INIT[5][8] = { + { + SPH_C32(0x6d251e69), SPH_C32(0x44b051e0), + SPH_C32(0x4eaa6fb4), SPH_C32(0xdbf78465), + SPH_C32(0x6e292011), SPH_C32(0x90152df4), + SPH_C32(0xee058139), SPH_C32(0xdef610bb) + }, { + SPH_C32(0xc3b44b95), SPH_C32(0xd9d2f256), + SPH_C32(0x70eee9a0), SPH_C32(0xde099fa3), + SPH_C32(0x5d9b0557), SPH_C32(0x8fc944b3), + SPH_C32(0xcf1ccf0e), SPH_C32(0x746cd581) + }, { + SPH_C32(0xf7efc89d), SPH_C32(0x5dba5781), + SPH_C32(0x04016ce5), SPH_C32(0xad659c05), + SPH_C32(0x0306194f), SPH_C32(0x666d1836), + SPH_C32(0x24aa230a), SPH_C32(0x8b264ae7) + }, { + SPH_C32(0x858075d5), SPH_C32(0x36d79cce), + SPH_C32(0xe571f7d7), SPH_C32(0x204b1f67), + SPH_C32(0x35870c6a), SPH_C32(0x57e9e923), + SPH_C32(0x14bcb808), SPH_C32(0x7cde72ce) + }, { + SPH_C32(0x6c68e9be), SPH_C32(0x5ec41e22), + SPH_C32(0xc825b7c7), SPH_C32(0xaffb4363), + SPH_C32(0xf5df3999), SPH_C32(0x0fc688f1), + SPH_C32(0xb07224cc), SPH_C32(0x03e86cea) + } +}; + +static const sph_u32 RC00[8] = { + SPH_C32(0x303994a6), SPH_C32(0xc0e65299), + SPH_C32(0x6cc33a12), SPH_C32(0xdc56983e), + SPH_C32(0x1e00108f), SPH_C32(0x7800423d), + SPH_C32(0x8f5b7882), SPH_C32(0x96e1db12) +}; + +static const sph_u32 RC04[8] = { + SPH_C32(0xe0337818), SPH_C32(0x441ba90d), + SPH_C32(0x7f34d442), SPH_C32(0x9389217f), + SPH_C32(0xe5a8bce6), SPH_C32(0x5274baf4), + SPH_C32(0x26889ba7), SPH_C32(0x9a226e9d) +}; + +static const sph_u32 RC10[8] = { + SPH_C32(0xb6de10ed), SPH_C32(0x70f47aae), + SPH_C32(0x0707a3d4), SPH_C32(0x1c1e8f51), + SPH_C32(0x707a3d45), SPH_C32(0xaeb28562), + SPH_C32(0xbaca1589), SPH_C32(0x40a46f3e) +}; + +static const sph_u32 RC14[8] = { + SPH_C32(0x01685f3d), SPH_C32(0x05a17cf4), + SPH_C32(0xbd09caca), SPH_C32(0xf4272b28), + SPH_C32(0x144ae5cc), SPH_C32(0xfaa7ae2b), + SPH_C32(0x2e48f1c1), SPH_C32(0xb923c704) +}; + +#if SPH_LUFFA_PARALLEL + +static const sph_u64 RCW010[8] = { + SPH_C64(0xb6de10ed303994a6), SPH_C64(0x70f47aaec0e65299), + SPH_C64(0x0707a3d46cc33a12), SPH_C64(0x1c1e8f51dc56983e), + SPH_C64(0x707a3d451e00108f), SPH_C64(0xaeb285627800423d), + SPH_C64(0xbaca15898f5b7882), SPH_C64(0x40a46f3e96e1db12) +}; + +static const sph_u64 RCW014[8] = { + SPH_C64(0x01685f3de0337818), SPH_C64(0x05a17cf4441ba90d), + SPH_C64(0xbd09caca7f34d442), SPH_C64(0xf4272b289389217f), + SPH_C64(0x144ae5cce5a8bce6), SPH_C64(0xfaa7ae2b5274baf4), + SPH_C64(0x2e48f1c126889ba7), SPH_C64(0xb923c7049a226e9d) +}; + +#endif + +static const sph_u32 RC20[8] = { + SPH_C32(0xfc20d9d2), SPH_C32(0x34552e25), + SPH_C32(0x7ad8818f), SPH_C32(0x8438764a), + SPH_C32(0xbb6de032), SPH_C32(0xedb780c8), + SPH_C32(0xd9847356), SPH_C32(0xa2c78434) +}; + +static const sph_u32 RC24[8] = { + SPH_C32(0xe25e72c1), SPH_C32(0xe623bb72), + SPH_C32(0x5c58a4a4), SPH_C32(0x1e38e2e7), + SPH_C32(0x78e38b9d), SPH_C32(0x27586719), + SPH_C32(0x36eda57f), SPH_C32(0x703aace7) +}; + +static const sph_u32 RC30[8] = { + SPH_C32(0xb213afa5), SPH_C32(0xc84ebe95), + SPH_C32(0x4e608a22), SPH_C32(0x56d858fe), + SPH_C32(0x343b138f), SPH_C32(0xd0ec4e3d), + SPH_C32(0x2ceb4882), SPH_C32(0xb3ad2208) +}; + +static const sph_u32 RC34[8] = { + SPH_C32(0xe028c9bf), SPH_C32(0x44756f91), + SPH_C32(0x7e8fce32), SPH_C32(0x956548be), + SPH_C32(0xfe191be2), SPH_C32(0x3cb226e5), + SPH_C32(0x5944a28e), SPH_C32(0xa1c4c355) +}; + +#if SPH_LUFFA_PARALLEL + +static const sph_u64 RCW230[8] = { + SPH_C64(0xb213afa5fc20d9d2), SPH_C64(0xc84ebe9534552e25), + SPH_C64(0x4e608a227ad8818f), SPH_C64(0x56d858fe8438764a), + SPH_C64(0x343b138fbb6de032), SPH_C64(0xd0ec4e3dedb780c8), + SPH_C64(0x2ceb4882d9847356), SPH_C64(0xb3ad2208a2c78434) +}; + + +static const sph_u64 RCW234[8] = { + SPH_C64(0xe028c9bfe25e72c1), SPH_C64(0x44756f91e623bb72), + SPH_C64(0x7e8fce325c58a4a4), SPH_C64(0x956548be1e38e2e7), + SPH_C64(0xfe191be278e38b9d), SPH_C64(0x3cb226e527586719), + SPH_C64(0x5944a28e36eda57f), SPH_C64(0xa1c4c355703aace7) +}; + +#endif + +static const sph_u32 RC40[8] = { + SPH_C32(0xf0d2e9e3), SPH_C32(0xac11d7fa), + SPH_C32(0x1bcb66f2), SPH_C32(0x6f2d9bc9), + SPH_C32(0x78602649), SPH_C32(0x8edae952), + SPH_C32(0x3b6ba548), SPH_C32(0xedae9520) +}; + +static const sph_u32 RC44[8] = { + SPH_C32(0x5090d577), SPH_C32(0x2d1925ab), + SPH_C32(0xb46496ac), SPH_C32(0xd1925ab0), + SPH_C32(0x29131ab6), SPH_C32(0x0fc053c3), + SPH_C32(0x3f014f0c), SPH_C32(0xfc053c31) +}; + +#define DECL_TMP8(w) \ + sph_u32 w ## 0, w ## 1, w ## 2, w ## 3, w ## 4, w ## 5, w ## 6, w ## 7; + +#define M2(d, s) do { \ + sph_u32 tmp = s ## 7; \ + d ## 7 = s ## 6; \ + d ## 6 = s ## 5; \ + d ## 5 = s ## 4; \ + d ## 4 = s ## 3 ^ tmp; \ + d ## 3 = s ## 2 ^ tmp; \ + d ## 2 = s ## 1; \ + d ## 1 = s ## 0 ^ tmp; \ + d ## 0 = tmp; \ + } while (0) + +#define XOR(d, s1, s2) do { \ + d ## 0 = s1 ## 0 ^ s2 ## 0; \ + d ## 1 = s1 ## 1 ^ s2 ## 1; \ + d ## 2 = s1 ## 2 ^ s2 ## 2; \ + d ## 3 = s1 ## 3 ^ s2 ## 3; \ + d ## 4 = s1 ## 4 ^ s2 ## 4; \ + d ## 5 = s1 ## 5 ^ s2 ## 5; \ + d ## 6 = s1 ## 6 ^ s2 ## 6; \ + d ## 7 = s1 ## 7 ^ s2 ## 7; \ + } while (0) + +#if SPH_LUFFA_PARALLEL + +#define SUB_CRUMB_GEN(a0, a1, a2, a3, width) do { \ + sph_u ## width tmp; \ + tmp = (a0); \ + (a0) |= (a1); \ + (a2) ^= (a3); \ + (a1) = SPH_T ## width(~(a1)); \ + (a0) ^= (a3); \ + (a3) &= tmp; \ + (a1) ^= (a3); \ + (a3) ^= (a2); \ + (a2) &= (a0); \ + (a0) = SPH_T ## width(~(a0)); \ + (a2) ^= (a1); \ + (a1) |= (a3); \ + tmp ^= (a1); \ + (a3) ^= (a2); \ + (a2) &= (a1); \ + (a1) ^= (a0); \ + (a0) = tmp; \ + } while (0) + +#define SUB_CRUMB(a0, a1, a2, a3) SUB_CRUMB_GEN(a0, a1, a2, a3, 32) +#define SUB_CRUMBW(a0, a1, a2, a3) SUB_CRUMB_GEN(a0, a1, a2, a3, 64) + + +#if 0 + +#define ROL32W(x, n) SPH_T64( \ + (((x) << (n)) \ + & ~((SPH_C64(0xFFFFFFFF) >> (32 - (n))) << 32)) \ + | (((x) >> (32 - (n))) \ + & ~((SPH_C64(0xFFFFFFFF) >> (n)) << (n)))) + +#define MIX_WORDW(u, v) do { \ + (v) ^= (u); \ + (u) = ROL32W((u), 2) ^ (v); \ + (v) = ROL32W((v), 14) ^ (u); \ + (u) = ROL32W((u), 10) ^ (v); \ + (v) = ROL32W((v), 1); \ + } while (0) + +#endif + +#define MIX_WORDW(u, v) do { \ + sph_u32 ul, uh, vl, vh; \ + (v) ^= (u); \ + ul = SPH_T32((sph_u32)(u)); \ + uh = SPH_T32((sph_u32)((u) >> 32)); \ + vl = SPH_T32((sph_u32)(v)); \ + vh = SPH_T32((sph_u32)((v) >> 32)); \ + ul = SPH_ROTL32(ul, 2) ^ vl; \ + vl = SPH_ROTL32(vl, 14) ^ ul; \ + ul = SPH_ROTL32(ul, 10) ^ vl; \ + vl = SPH_ROTL32(vl, 1); \ + uh = SPH_ROTL32(uh, 2) ^ vh; \ + vh = SPH_ROTL32(vh, 14) ^ uh; \ + uh = SPH_ROTL32(uh, 10) ^ vh; \ + vh = SPH_ROTL32(vh, 1); \ + (u) = (sph_u64)ul | ((sph_u64)uh << 32); \ + (v) = (sph_u64)vl | ((sph_u64)vh << 32); \ + } while (0) + +#else + +#define SUB_CRUMB(a0, a1, a2, a3) do { \ + sph_u32 tmp; \ + tmp = (a0); \ + (a0) |= (a1); \ + (a2) ^= (a3); \ + (a1) = SPH_T32(~(a1)); \ + (a0) ^= (a3); \ + (a3) &= tmp; \ + (a1) ^= (a3); \ + (a3) ^= (a2); \ + (a2) &= (a0); \ + (a0) = SPH_T32(~(a0)); \ + (a2) ^= (a1); \ + (a1) |= (a3); \ + tmp ^= (a1); \ + (a3) ^= (a2); \ + (a2) &= (a1); \ + (a1) ^= (a0); \ + (a0) = tmp; \ + } while (0) + +#endif + +#define MIX_WORD(u, v) do { \ + (v) ^= (u); \ + (u) = SPH_ROTL32((u), 2) ^ (v); \ + (v) = SPH_ROTL32((v), 14) ^ (u); \ + (u) = SPH_ROTL32((u), 10) ^ (v); \ + (v) = SPH_ROTL32((v), 1); \ + } while (0) + +#define DECL_STATE3 \ + sph_u32 V00, V01, V02, V03, V04, V05, V06, V07; \ + sph_u32 V10, V11, V12, V13, V14, V15, V16, V17; \ + sph_u32 V20, V21, V22, V23, V24, V25, V26, V27; + +#define READ_STATE3(state) do { \ + V00 = (state)->V[0][0]; \ + V01 = (state)->V[0][1]; \ + V02 = (state)->V[0][2]; \ + V03 = (state)->V[0][3]; \ + V04 = (state)->V[0][4]; \ + V05 = (state)->V[0][5]; \ + V06 = (state)->V[0][6]; \ + V07 = (state)->V[0][7]; \ + V10 = (state)->V[1][0]; \ + V11 = (state)->V[1][1]; \ + V12 = (state)->V[1][2]; \ + V13 = (state)->V[1][3]; \ + V14 = (state)->V[1][4]; \ + V15 = (state)->V[1][5]; \ + V16 = (state)->V[1][6]; \ + V17 = (state)->V[1][7]; \ + V20 = (state)->V[2][0]; \ + V21 = (state)->V[2][1]; \ + V22 = (state)->V[2][2]; \ + V23 = (state)->V[2][3]; \ + V24 = (state)->V[2][4]; \ + V25 = (state)->V[2][5]; \ + V26 = (state)->V[2][6]; \ + V27 = (state)->V[2][7]; \ + } while (0) + +#define WRITE_STATE3(state) do { \ + (state)->V[0][0] = V00; \ + (state)->V[0][1] = V01; \ + (state)->V[0][2] = V02; \ + (state)->V[0][3] = V03; \ + (state)->V[0][4] = V04; \ + (state)->V[0][5] = V05; \ + (state)->V[0][6] = V06; \ + (state)->V[0][7] = V07; \ + (state)->V[1][0] = V10; \ + (state)->V[1][1] = V11; \ + (state)->V[1][2] = V12; \ + (state)->V[1][3] = V13; \ + (state)->V[1][4] = V14; \ + (state)->V[1][5] = V15; \ + (state)->V[1][6] = V16; \ + (state)->V[1][7] = V17; \ + (state)->V[2][0] = V20; \ + (state)->V[2][1] = V21; \ + (state)->V[2][2] = V22; \ + (state)->V[2][3] = V23; \ + (state)->V[2][4] = V24; \ + (state)->V[2][5] = V25; \ + (state)->V[2][6] = V26; \ + (state)->V[2][7] = V27; \ + } while (0) + +#define MI3 do { \ + DECL_TMP8(M) \ + DECL_TMP8(a) \ + M0 = sph_dec32be_aligned(buf + 0); \ + M1 = sph_dec32be_aligned(buf + 4); \ + M2 = sph_dec32be_aligned(buf + 8); \ + M3 = sph_dec32be_aligned(buf + 12); \ + M4 = sph_dec32be_aligned(buf + 16); \ + M5 = sph_dec32be_aligned(buf + 20); \ + M6 = sph_dec32be_aligned(buf + 24); \ + M7 = sph_dec32be_aligned(buf + 28); \ + XOR(a, V0, V1); \ + XOR(a, a, V2); \ + M2(a, a); \ + XOR(V0, a, V0); \ + XOR(V0, M, V0); \ + M2(M, M); \ + XOR(V1, a, V1); \ + XOR(V1, M, V1); \ + M2(M, M); \ + XOR(V2, a, V2); \ + XOR(V2, M, V2); \ + } while (0) + +#define TWEAK3 do { \ + V14 = SPH_ROTL32(V14, 1); \ + V15 = SPH_ROTL32(V15, 1); \ + V16 = SPH_ROTL32(V16, 1); \ + V17 = SPH_ROTL32(V17, 1); \ + V24 = SPH_ROTL32(V24, 2); \ + V25 = SPH_ROTL32(V25, 2); \ + V26 = SPH_ROTL32(V26, 2); \ + V27 = SPH_ROTL32(V27, 2); \ + } while (0) + +#if SPH_LUFFA_PARALLEL + +#define P3 do { \ + int r; \ + sph_u64 W0, W1, W2, W3, W4, W5, W6, W7; \ + TWEAK3; \ + W0 = (sph_u64)V00 | ((sph_u64)V10 << 32); \ + W1 = (sph_u64)V01 | ((sph_u64)V11 << 32); \ + W2 = (sph_u64)V02 | ((sph_u64)V12 << 32); \ + W3 = (sph_u64)V03 | ((sph_u64)V13 << 32); \ + W4 = (sph_u64)V04 | ((sph_u64)V14 << 32); \ + W5 = (sph_u64)V05 | ((sph_u64)V15 << 32); \ + W6 = (sph_u64)V06 | ((sph_u64)V16 << 32); \ + W7 = (sph_u64)V07 | ((sph_u64)V17 << 32); \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMBW(W0, W1, W2, W3); \ + SUB_CRUMBW(W5, W6, W7, W4); \ + MIX_WORDW(W0, W4); \ + MIX_WORDW(W1, W5); \ + MIX_WORDW(W2, W6); \ + MIX_WORDW(W3, W7); \ + W0 ^= RCW010[r]; \ + W4 ^= RCW014[r]; \ + } \ + V00 = SPH_T32((sph_u32)W0); \ + V10 = SPH_T32((sph_u32)(W0 >> 32)); \ + V01 = SPH_T32((sph_u32)W1); \ + V11 = SPH_T32((sph_u32)(W1 >> 32)); \ + V02 = SPH_T32((sph_u32)W2); \ + V12 = SPH_T32((sph_u32)(W2 >> 32)); \ + V03 = SPH_T32((sph_u32)W3); \ + V13 = SPH_T32((sph_u32)(W3 >> 32)); \ + V04 = SPH_T32((sph_u32)W4); \ + V14 = SPH_T32((sph_u32)(W4 >> 32)); \ + V05 = SPH_T32((sph_u32)W5); \ + V15 = SPH_T32((sph_u32)(W5 >> 32)); \ + V06 = SPH_T32((sph_u32)W6); \ + V16 = SPH_T32((sph_u32)(W6 >> 32)); \ + V07 = SPH_T32((sph_u32)W7); \ + V17 = SPH_T32((sph_u32)(W7 >> 32)); \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V20, V21, V22, V23); \ + SUB_CRUMB(V25, V26, V27, V24); \ + MIX_WORD(V20, V24); \ + MIX_WORD(V21, V25); \ + MIX_WORD(V22, V26); \ + MIX_WORD(V23, V27); \ + V20 ^= RC20[r]; \ + V24 ^= RC24[r]; \ + } \ + } while (0) + +#else + +#define P3 do { \ + int r; \ + TWEAK3; \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V00, V01, V02, V03); \ + SUB_CRUMB(V05, V06, V07, V04); \ + MIX_WORD(V00, V04); \ + MIX_WORD(V01, V05); \ + MIX_WORD(V02, V06); \ + MIX_WORD(V03, V07); \ + V00 ^= RC00[r]; \ + V04 ^= RC04[r]; \ + } \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V10, V11, V12, V13); \ + SUB_CRUMB(V15, V16, V17, V14); \ + MIX_WORD(V10, V14); \ + MIX_WORD(V11, V15); \ + MIX_WORD(V12, V16); \ + MIX_WORD(V13, V17); \ + V10 ^= RC10[r]; \ + V14 ^= RC14[r]; \ + } \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V20, V21, V22, V23); \ + SUB_CRUMB(V25, V26, V27, V24); \ + MIX_WORD(V20, V24); \ + MIX_WORD(V21, V25); \ + MIX_WORD(V22, V26); \ + MIX_WORD(V23, V27); \ + V20 ^= RC20[r]; \ + V24 ^= RC24[r]; \ + } \ + } while (0) + +#endif + +#define DECL_STATE4 \ + sph_u32 V00, V01, V02, V03, V04, V05, V06, V07; \ + sph_u32 V10, V11, V12, V13, V14, V15, V16, V17; \ + sph_u32 V20, V21, V22, V23, V24, V25, V26, V27; \ + sph_u32 V30, V31, V32, V33, V34, V35, V36, V37; + +#define READ_STATE4(state) do { \ + V00 = (state)->V[0][0]; \ + V01 = (state)->V[0][1]; \ + V02 = (state)->V[0][2]; \ + V03 = (state)->V[0][3]; \ + V04 = (state)->V[0][4]; \ + V05 = (state)->V[0][5]; \ + V06 = (state)->V[0][6]; \ + V07 = (state)->V[0][7]; \ + V10 = (state)->V[1][0]; \ + V11 = (state)->V[1][1]; \ + V12 = (state)->V[1][2]; \ + V13 = (state)->V[1][3]; \ + V14 = (state)->V[1][4]; \ + V15 = (state)->V[1][5]; \ + V16 = (state)->V[1][6]; \ + V17 = (state)->V[1][7]; \ + V20 = (state)->V[2][0]; \ + V21 = (state)->V[2][1]; \ + V22 = (state)->V[2][2]; \ + V23 = (state)->V[2][3]; \ + V24 = (state)->V[2][4]; \ + V25 = (state)->V[2][5]; \ + V26 = (state)->V[2][6]; \ + V27 = (state)->V[2][7]; \ + V30 = (state)->V[3][0]; \ + V31 = (state)->V[3][1]; \ + V32 = (state)->V[3][2]; \ + V33 = (state)->V[3][3]; \ + V34 = (state)->V[3][4]; \ + V35 = (state)->V[3][5]; \ + V36 = (state)->V[3][6]; \ + V37 = (state)->V[3][7]; \ + } while (0) + +#define WRITE_STATE4(state) do { \ + (state)->V[0][0] = V00; \ + (state)->V[0][1] = V01; \ + (state)->V[0][2] = V02; \ + (state)->V[0][3] = V03; \ + (state)->V[0][4] = V04; \ + (state)->V[0][5] = V05; \ + (state)->V[0][6] = V06; \ + (state)->V[0][7] = V07; \ + (state)->V[1][0] = V10; \ + (state)->V[1][1] = V11; \ + (state)->V[1][2] = V12; \ + (state)->V[1][3] = V13; \ + (state)->V[1][4] = V14; \ + (state)->V[1][5] = V15; \ + (state)->V[1][6] = V16; \ + (state)->V[1][7] = V17; \ + (state)->V[2][0] = V20; \ + (state)->V[2][1] = V21; \ + (state)->V[2][2] = V22; \ + (state)->V[2][3] = V23; \ + (state)->V[2][4] = V24; \ + (state)->V[2][5] = V25; \ + (state)->V[2][6] = V26; \ + (state)->V[2][7] = V27; \ + (state)->V[3][0] = V30; \ + (state)->V[3][1] = V31; \ + (state)->V[3][2] = V32; \ + (state)->V[3][3] = V33; \ + (state)->V[3][4] = V34; \ + (state)->V[3][5] = V35; \ + (state)->V[3][6] = V36; \ + (state)->V[3][7] = V37; \ + } while (0) + +#define MI4 do { \ + DECL_TMP8(M) \ + DECL_TMP8(a) \ + DECL_TMP8(b) \ + M0 = sph_dec32be_aligned(buf + 0); \ + M1 = sph_dec32be_aligned(buf + 4); \ + M2 = sph_dec32be_aligned(buf + 8); \ + M3 = sph_dec32be_aligned(buf + 12); \ + M4 = sph_dec32be_aligned(buf + 16); \ + M5 = sph_dec32be_aligned(buf + 20); \ + M6 = sph_dec32be_aligned(buf + 24); \ + M7 = sph_dec32be_aligned(buf + 28); \ + XOR(a, V0, V1); \ + XOR(b, V2, V3); \ + XOR(a, a, b); \ + M2(a, a); \ + XOR(V0, a, V0); \ + XOR(V1, a, V1); \ + XOR(V2, a, V2); \ + XOR(V3, a, V3); \ + M2(b, V0); \ + XOR(b, b, V3); \ + M2(V3, V3); \ + XOR(V3, V3, V2); \ + M2(V2, V2); \ + XOR(V2, V2, V1); \ + M2(V1, V1); \ + XOR(V1, V1, V0); \ + XOR(V0, b, M); \ + M2(M, M); \ + XOR(V1, V1, M); \ + M2(M, M); \ + XOR(V2, V2, M); \ + M2(M, M); \ + XOR(V3, V3, M); \ + } while (0) + +#define TWEAK4 do { \ + V14 = SPH_ROTL32(V14, 1); \ + V15 = SPH_ROTL32(V15, 1); \ + V16 = SPH_ROTL32(V16, 1); \ + V17 = SPH_ROTL32(V17, 1); \ + V24 = SPH_ROTL32(V24, 2); \ + V25 = SPH_ROTL32(V25, 2); \ + V26 = SPH_ROTL32(V26, 2); \ + V27 = SPH_ROTL32(V27, 2); \ + V34 = SPH_ROTL32(V34, 3); \ + V35 = SPH_ROTL32(V35, 3); \ + V36 = SPH_ROTL32(V36, 3); \ + V37 = SPH_ROTL32(V37, 3); \ + } while (0) + +#if SPH_LUFFA_PARALLEL + +#define P4 do { \ + int r; \ + sph_u64 W0, W1, W2, W3, W4, W5, W6, W7; \ + TWEAK4; \ + W0 = (sph_u64)V00 | ((sph_u64)V10 << 32); \ + W1 = (sph_u64)V01 | ((sph_u64)V11 << 32); \ + W2 = (sph_u64)V02 | ((sph_u64)V12 << 32); \ + W3 = (sph_u64)V03 | ((sph_u64)V13 << 32); \ + W4 = (sph_u64)V04 | ((sph_u64)V14 << 32); \ + W5 = (sph_u64)V05 | ((sph_u64)V15 << 32); \ + W6 = (sph_u64)V06 | ((sph_u64)V16 << 32); \ + W7 = (sph_u64)V07 | ((sph_u64)V17 << 32); \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMBW(W0, W1, W2, W3); \ + SUB_CRUMBW(W5, W6, W7, W4); \ + MIX_WORDW(W0, W4); \ + MIX_WORDW(W1, W5); \ + MIX_WORDW(W2, W6); \ + MIX_WORDW(W3, W7); \ + W0 ^= RCW010[r]; \ + W4 ^= RCW014[r]; \ + } \ + V00 = SPH_T32((sph_u32)W0); \ + V10 = SPH_T32((sph_u32)(W0 >> 32)); \ + V01 = SPH_T32((sph_u32)W1); \ + V11 = SPH_T32((sph_u32)(W1 >> 32)); \ + V02 = SPH_T32((sph_u32)W2); \ + V12 = SPH_T32((sph_u32)(W2 >> 32)); \ + V03 = SPH_T32((sph_u32)W3); \ + V13 = SPH_T32((sph_u32)(W3 >> 32)); \ + V04 = SPH_T32((sph_u32)W4); \ + V14 = SPH_T32((sph_u32)(W4 >> 32)); \ + V05 = SPH_T32((sph_u32)W5); \ + V15 = SPH_T32((sph_u32)(W5 >> 32)); \ + V06 = SPH_T32((sph_u32)W6); \ + V16 = SPH_T32((sph_u32)(W6 >> 32)); \ + V07 = SPH_T32((sph_u32)W7); \ + V17 = SPH_T32((sph_u32)(W7 >> 32)); \ + W0 = (sph_u64)V20 | ((sph_u64)V30 << 32); \ + W1 = (sph_u64)V21 | ((sph_u64)V31 << 32); \ + W2 = (sph_u64)V22 | ((sph_u64)V32 << 32); \ + W3 = (sph_u64)V23 | ((sph_u64)V33 << 32); \ + W4 = (sph_u64)V24 | ((sph_u64)V34 << 32); \ + W5 = (sph_u64)V25 | ((sph_u64)V35 << 32); \ + W6 = (sph_u64)V26 | ((sph_u64)V36 << 32); \ + W7 = (sph_u64)V27 | ((sph_u64)V37 << 32); \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMBW(W0, W1, W2, W3); \ + SUB_CRUMBW(W5, W6, W7, W4); \ + MIX_WORDW(W0, W4); \ + MIX_WORDW(W1, W5); \ + MIX_WORDW(W2, W6); \ + MIX_WORDW(W3, W7); \ + W0 ^= RCW230[r]; \ + W4 ^= RCW234[r]; \ + } \ + V20 = SPH_T32((sph_u32)W0); \ + V30 = SPH_T32((sph_u32)(W0 >> 32)); \ + V21 = SPH_T32((sph_u32)W1); \ + V31 = SPH_T32((sph_u32)(W1 >> 32)); \ + V22 = SPH_T32((sph_u32)W2); \ + V32 = SPH_T32((sph_u32)(W2 >> 32)); \ + V23 = SPH_T32((sph_u32)W3); \ + V33 = SPH_T32((sph_u32)(W3 >> 32)); \ + V24 = SPH_T32((sph_u32)W4); \ + V34 = SPH_T32((sph_u32)(W4 >> 32)); \ + V25 = SPH_T32((sph_u32)W5); \ + V35 = SPH_T32((sph_u32)(W5 >> 32)); \ + V26 = SPH_T32((sph_u32)W6); \ + V36 = SPH_T32((sph_u32)(W6 >> 32)); \ + V27 = SPH_T32((sph_u32)W7); \ + V37 = SPH_T32((sph_u32)(W7 >> 32)); \ + } while (0) + +#else + +#define P4 do { \ + int r; \ + TWEAK4; \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V00, V01, V02, V03); \ + SUB_CRUMB(V05, V06, V07, V04); \ + MIX_WORD(V00, V04); \ + MIX_WORD(V01, V05); \ + MIX_WORD(V02, V06); \ + MIX_WORD(V03, V07); \ + V00 ^= RC00[r]; \ + V04 ^= RC04[r]; \ + } \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V10, V11, V12, V13); \ + SUB_CRUMB(V15, V16, V17, V14); \ + MIX_WORD(V10, V14); \ + MIX_WORD(V11, V15); \ + MIX_WORD(V12, V16); \ + MIX_WORD(V13, V17); \ + V10 ^= RC10[r]; \ + V14 ^= RC14[r]; \ + } \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V20, V21, V22, V23); \ + SUB_CRUMB(V25, V26, V27, V24); \ + MIX_WORD(V20, V24); \ + MIX_WORD(V21, V25); \ + MIX_WORD(V22, V26); \ + MIX_WORD(V23, V27); \ + V20 ^= RC20[r]; \ + V24 ^= RC24[r]; \ + } \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V30, V31, V32, V33); \ + SUB_CRUMB(V35, V36, V37, V34); \ + MIX_WORD(V30, V34); \ + MIX_WORD(V31, V35); \ + MIX_WORD(V32, V36); \ + MIX_WORD(V33, V37); \ + V30 ^= RC30[r]; \ + V34 ^= RC34[r]; \ + } \ + } while (0) + +#endif + +#define DECL_STATE5 \ + sph_u32 V00, V01, V02, V03, V04, V05, V06, V07; \ + sph_u32 V10, V11, V12, V13, V14, V15, V16, V17; \ + sph_u32 V20, V21, V22, V23, V24, V25, V26, V27; \ + sph_u32 V30, V31, V32, V33, V34, V35, V36, V37; \ + sph_u32 V40, V41, V42, V43, V44, V45, V46, V47; + +#define READ_STATE5(state) do { \ + V00 = (state)->V[0][0]; \ + V01 = (state)->V[0][1]; \ + V02 = (state)->V[0][2]; \ + V03 = (state)->V[0][3]; \ + V04 = (state)->V[0][4]; \ + V05 = (state)->V[0][5]; \ + V06 = (state)->V[0][6]; \ + V07 = (state)->V[0][7]; \ + V10 = (state)->V[1][0]; \ + V11 = (state)->V[1][1]; \ + V12 = (state)->V[1][2]; \ + V13 = (state)->V[1][3]; \ + V14 = (state)->V[1][4]; \ + V15 = (state)->V[1][5]; \ + V16 = (state)->V[1][6]; \ + V17 = (state)->V[1][7]; \ + V20 = (state)->V[2][0]; \ + V21 = (state)->V[2][1]; \ + V22 = (state)->V[2][2]; \ + V23 = (state)->V[2][3]; \ + V24 = (state)->V[2][4]; \ + V25 = (state)->V[2][5]; \ + V26 = (state)->V[2][6]; \ + V27 = (state)->V[2][7]; \ + V30 = (state)->V[3][0]; \ + V31 = (state)->V[3][1]; \ + V32 = (state)->V[3][2]; \ + V33 = (state)->V[3][3]; \ + V34 = (state)->V[3][4]; \ + V35 = (state)->V[3][5]; \ + V36 = (state)->V[3][6]; \ + V37 = (state)->V[3][7]; \ + V40 = (state)->V[4][0]; \ + V41 = (state)->V[4][1]; \ + V42 = (state)->V[4][2]; \ + V43 = (state)->V[4][3]; \ + V44 = (state)->V[4][4]; \ + V45 = (state)->V[4][5]; \ + V46 = (state)->V[4][6]; \ + V47 = (state)->V[4][7]; \ + } while (0) + +#define WRITE_STATE5(state) do { \ + (state)->V[0][0] = V00; \ + (state)->V[0][1] = V01; \ + (state)->V[0][2] = V02; \ + (state)->V[0][3] = V03; \ + (state)->V[0][4] = V04; \ + (state)->V[0][5] = V05; \ + (state)->V[0][6] = V06; \ + (state)->V[0][7] = V07; \ + (state)->V[1][0] = V10; \ + (state)->V[1][1] = V11; \ + (state)->V[1][2] = V12; \ + (state)->V[1][3] = V13; \ + (state)->V[1][4] = V14; \ + (state)->V[1][5] = V15; \ + (state)->V[1][6] = V16; \ + (state)->V[1][7] = V17; \ + (state)->V[2][0] = V20; \ + (state)->V[2][1] = V21; \ + (state)->V[2][2] = V22; \ + (state)->V[2][3] = V23; \ + (state)->V[2][4] = V24; \ + (state)->V[2][5] = V25; \ + (state)->V[2][6] = V26; \ + (state)->V[2][7] = V27; \ + (state)->V[3][0] = V30; \ + (state)->V[3][1] = V31; \ + (state)->V[3][2] = V32; \ + (state)->V[3][3] = V33; \ + (state)->V[3][4] = V34; \ + (state)->V[3][5] = V35; \ + (state)->V[3][6] = V36; \ + (state)->V[3][7] = V37; \ + (state)->V[4][0] = V40; \ + (state)->V[4][1] = V41; \ + (state)->V[4][2] = V42; \ + (state)->V[4][3] = V43; \ + (state)->V[4][4] = V44; \ + (state)->V[4][5] = V45; \ + (state)->V[4][6] = V46; \ + (state)->V[4][7] = V47; \ + } while (0) + +#define MI5 do { \ + DECL_TMP8(M) \ + DECL_TMP8(a) \ + DECL_TMP8(b) \ + M0 = sph_dec32be_aligned(buf + 0); \ + M1 = sph_dec32be_aligned(buf + 4); \ + M2 = sph_dec32be_aligned(buf + 8); \ + M3 = sph_dec32be_aligned(buf + 12); \ + M4 = sph_dec32be_aligned(buf + 16); \ + M5 = sph_dec32be_aligned(buf + 20); \ + M6 = sph_dec32be_aligned(buf + 24); \ + M7 = sph_dec32be_aligned(buf + 28); \ + XOR(a, V0, V1); \ + XOR(b, V2, V3); \ + XOR(a, a, b); \ + XOR(a, a, V4); \ + M2(a, a); \ + XOR(V0, a, V0); \ + XOR(V1, a, V1); \ + XOR(V2, a, V2); \ + XOR(V3, a, V3); \ + XOR(V4, a, V4); \ + M2(b, V0); \ + XOR(b, b, V1); \ + M2(V1, V1); \ + XOR(V1, V1, V2); \ + M2(V2, V2); \ + XOR(V2, V2, V3); \ + M2(V3, V3); \ + XOR(V3, V3, V4); \ + M2(V4, V4); \ + XOR(V4, V4, V0); \ + M2(V0, b); \ + XOR(V0, V0, V4); \ + M2(V4, V4); \ + XOR(V4, V4, V3); \ + M2(V3, V3); \ + XOR(V3, V3, V2); \ + M2(V2, V2); \ + XOR(V2, V2, V1); \ + M2(V1, V1); \ + XOR(V1, V1, b); \ + XOR(V0, V0, M); \ + M2(M, M); \ + XOR(V1, V1, M); \ + M2(M, M); \ + XOR(V2, V2, M); \ + M2(M, M); \ + XOR(V3, V3, M); \ + M2(M, M); \ + XOR(V4, V4, M); \ + } while (0) + +#define TWEAK5 do { \ + V14 = SPH_ROTL32(V14, 1); \ + V15 = SPH_ROTL32(V15, 1); \ + V16 = SPH_ROTL32(V16, 1); \ + V17 = SPH_ROTL32(V17, 1); \ + V24 = SPH_ROTL32(V24, 2); \ + V25 = SPH_ROTL32(V25, 2); \ + V26 = SPH_ROTL32(V26, 2); \ + V27 = SPH_ROTL32(V27, 2); \ + V34 = SPH_ROTL32(V34, 3); \ + V35 = SPH_ROTL32(V35, 3); \ + V36 = SPH_ROTL32(V36, 3); \ + V37 = SPH_ROTL32(V37, 3); \ + V44 = SPH_ROTL32(V44, 4); \ + V45 = SPH_ROTL32(V45, 4); \ + V46 = SPH_ROTL32(V46, 4); \ + V47 = SPH_ROTL32(V47, 4); \ + } while (0) + +#if SPH_LUFFA_PARALLEL + +#define P5 do { \ + int r; \ + sph_u64 W0, W1, W2, W3, W4, W5, W6, W7; \ + TWEAK5; \ + W0 = (sph_u64)V00 | ((sph_u64)V10 << 32); \ + W1 = (sph_u64)V01 | ((sph_u64)V11 << 32); \ + W2 = (sph_u64)V02 | ((sph_u64)V12 << 32); \ + W3 = (sph_u64)V03 | ((sph_u64)V13 << 32); \ + W4 = (sph_u64)V04 | ((sph_u64)V14 << 32); \ + W5 = (sph_u64)V05 | ((sph_u64)V15 << 32); \ + W6 = (sph_u64)V06 | ((sph_u64)V16 << 32); \ + W7 = (sph_u64)V07 | ((sph_u64)V17 << 32); \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMBW(W0, W1, W2, W3); \ + SUB_CRUMBW(W5, W6, W7, W4); \ + MIX_WORDW(W0, W4); \ + MIX_WORDW(W1, W5); \ + MIX_WORDW(W2, W6); \ + MIX_WORDW(W3, W7); \ + W0 ^= RCW010[r]; \ + W4 ^= RCW014[r]; \ + } \ + V00 = SPH_T32((sph_u32)W0); \ + V10 = SPH_T32((sph_u32)(W0 >> 32)); \ + V01 = SPH_T32((sph_u32)W1); \ + V11 = SPH_T32((sph_u32)(W1 >> 32)); \ + V02 = SPH_T32((sph_u32)W2); \ + V12 = SPH_T32((sph_u32)(W2 >> 32)); \ + V03 = SPH_T32((sph_u32)W3); \ + V13 = SPH_T32((sph_u32)(W3 >> 32)); \ + V04 = SPH_T32((sph_u32)W4); \ + V14 = SPH_T32((sph_u32)(W4 >> 32)); \ + V05 = SPH_T32((sph_u32)W5); \ + V15 = SPH_T32((sph_u32)(W5 >> 32)); \ + V06 = SPH_T32((sph_u32)W6); \ + V16 = SPH_T32((sph_u32)(W6 >> 32)); \ + V07 = SPH_T32((sph_u32)W7); \ + V17 = SPH_T32((sph_u32)(W7 >> 32)); \ + W0 = (sph_u64)V20 | ((sph_u64)V30 << 32); \ + W1 = (sph_u64)V21 | ((sph_u64)V31 << 32); \ + W2 = (sph_u64)V22 | ((sph_u64)V32 << 32); \ + W3 = (sph_u64)V23 | ((sph_u64)V33 << 32); \ + W4 = (sph_u64)V24 | ((sph_u64)V34 << 32); \ + W5 = (sph_u64)V25 | ((sph_u64)V35 << 32); \ + W6 = (sph_u64)V26 | ((sph_u64)V36 << 32); \ + W7 = (sph_u64)V27 | ((sph_u64)V37 << 32); \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMBW(W0, W1, W2, W3); \ + SUB_CRUMBW(W5, W6, W7, W4); \ + MIX_WORDW(W0, W4); \ + MIX_WORDW(W1, W5); \ + MIX_WORDW(W2, W6); \ + MIX_WORDW(W3, W7); \ + W0 ^= RCW230[r]; \ + W4 ^= RCW234[r]; \ + } \ + V20 = SPH_T32((sph_u32)W0); \ + V30 = SPH_T32((sph_u32)(W0 >> 32)); \ + V21 = SPH_T32((sph_u32)W1); \ + V31 = SPH_T32((sph_u32)(W1 >> 32)); \ + V22 = SPH_T32((sph_u32)W2); \ + V32 = SPH_T32((sph_u32)(W2 >> 32)); \ + V23 = SPH_T32((sph_u32)W3); \ + V33 = SPH_T32((sph_u32)(W3 >> 32)); \ + V24 = SPH_T32((sph_u32)W4); \ + V34 = SPH_T32((sph_u32)(W4 >> 32)); \ + V25 = SPH_T32((sph_u32)W5); \ + V35 = SPH_T32((sph_u32)(W5 >> 32)); \ + V26 = SPH_T32((sph_u32)W6); \ + V36 = SPH_T32((sph_u32)(W6 >> 32)); \ + V27 = SPH_T32((sph_u32)W7); \ + V37 = SPH_T32((sph_u32)(W7 >> 32)); \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V40, V41, V42, V43); \ + SUB_CRUMB(V45, V46, V47, V44); \ + MIX_WORD(V40, V44); \ + MIX_WORD(V41, V45); \ + MIX_WORD(V42, V46); \ + MIX_WORD(V43, V47); \ + V40 ^= RC40[r]; \ + V44 ^= RC44[r]; \ + } \ + } while (0) + +#else + +#define P5 do { \ + int r; \ + TWEAK5; \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V00, V01, V02, V03); \ + SUB_CRUMB(V05, V06, V07, V04); \ + MIX_WORD(V00, V04); \ + MIX_WORD(V01, V05); \ + MIX_WORD(V02, V06); \ + MIX_WORD(V03, V07); \ + V00 ^= RC00[r]; \ + V04 ^= RC04[r]; \ + } \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V10, V11, V12, V13); \ + SUB_CRUMB(V15, V16, V17, V14); \ + MIX_WORD(V10, V14); \ + MIX_WORD(V11, V15); \ + MIX_WORD(V12, V16); \ + MIX_WORD(V13, V17); \ + V10 ^= RC10[r]; \ + V14 ^= RC14[r]; \ + } \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V20, V21, V22, V23); \ + SUB_CRUMB(V25, V26, V27, V24); \ + MIX_WORD(V20, V24); \ + MIX_WORD(V21, V25); \ + MIX_WORD(V22, V26); \ + MIX_WORD(V23, V27); \ + V20 ^= RC20[r]; \ + V24 ^= RC24[r]; \ + } \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V30, V31, V32, V33); \ + SUB_CRUMB(V35, V36, V37, V34); \ + MIX_WORD(V30, V34); \ + MIX_WORD(V31, V35); \ + MIX_WORD(V32, V36); \ + MIX_WORD(V33, V37); \ + V30 ^= RC30[r]; \ + V34 ^= RC34[r]; \ + } \ + for (r = 0; r < 8; r ++) { \ + SUB_CRUMB(V40, V41, V42, V43); \ + SUB_CRUMB(V45, V46, V47, V44); \ + MIX_WORD(V40, V44); \ + MIX_WORD(V41, V45); \ + MIX_WORD(V42, V46); \ + MIX_WORD(V43, V47); \ + V40 ^= RC40[r]; \ + V44 ^= RC44[r]; \ + } \ + } while (0) + +#endif + +static void +luffa3(sph_luffa224_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE3 + + buf = sc->buf; + ptr = sc->ptr; + if (len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + READ_STATE3(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) { + MI3; + P3; + ptr = 0; + } + } + WRITE_STATE3(sc); + sc->ptr = ptr; +} + +static void +luffa3_close(sph_luffa224_context *sc, unsigned ub, unsigned n, + void *dst, unsigned out_size_w32) +{ + unsigned char *buf, *out; + size_t ptr; + unsigned z; + int i; + DECL_STATE3 + + buf = sc->buf; + ptr = sc->ptr; + z = 0x80 >> n; + buf[ptr ++] = ((ub & -z) | z) & 0xFF; + memset(buf + ptr, 0, (sizeof sc->buf) - ptr); + READ_STATE3(sc); + for (i = 0; i < 2; i ++) { + MI3; + P3; + memset(buf, 0, sizeof sc->buf); + } + out = dst; + sph_enc32be(out + 0, V00 ^ V10 ^ V20); + sph_enc32be(out + 4, V01 ^ V11 ^ V21); + sph_enc32be(out + 8, V02 ^ V12 ^ V22); + sph_enc32be(out + 12, V03 ^ V13 ^ V23); + sph_enc32be(out + 16, V04 ^ V14 ^ V24); + sph_enc32be(out + 20, V05 ^ V15 ^ V25); + sph_enc32be(out + 24, V06 ^ V16 ^ V26); + if (out_size_w32 > 7) + sph_enc32be(out + 28, V07 ^ V17 ^ V27); +} + +static void +luffa4(sph_luffa384_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE4 + + buf = sc->buf; + ptr = sc->ptr; + if (len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + READ_STATE4(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) { + MI4; + P4; + ptr = 0; + } + } + WRITE_STATE4(sc); + sc->ptr = ptr; +} + +static void +luffa4_close(sph_luffa384_context *sc, unsigned ub, unsigned n, void *dst) +{ + unsigned char *buf, *out; + size_t ptr; + unsigned z; + int i; + DECL_STATE4 + + buf = sc->buf; + ptr = sc->ptr; + out = dst; + z = 0x80 >> n; + buf[ptr ++] = ((ub & -z) | z) & 0xFF; + memset(buf + ptr, 0, (sizeof sc->buf) - ptr); + READ_STATE4(sc); + for (i = 0; i < 3; i ++) { + MI4; + P4; + switch (i) { + case 0: + memset(buf, 0, sizeof sc->buf); + break; + case 1: + sph_enc32be(out + 0, V00 ^ V10 ^ V20 ^ V30); + sph_enc32be(out + 4, V01 ^ V11 ^ V21 ^ V31); + sph_enc32be(out + 8, V02 ^ V12 ^ V22 ^ V32); + sph_enc32be(out + 12, V03 ^ V13 ^ V23 ^ V33); + sph_enc32be(out + 16, V04 ^ V14 ^ V24 ^ V34); + sph_enc32be(out + 20, V05 ^ V15 ^ V25 ^ V35); + sph_enc32be(out + 24, V06 ^ V16 ^ V26 ^ V36); + sph_enc32be(out + 28, V07 ^ V17 ^ V27 ^ V37); + break; + case 2: + sph_enc32be(out + 32, V00 ^ V10 ^ V20 ^ V30); + sph_enc32be(out + 36, V01 ^ V11 ^ V21 ^ V31); + sph_enc32be(out + 40, V02 ^ V12 ^ V22 ^ V32); + sph_enc32be(out + 44, V03 ^ V13 ^ V23 ^ V33); + break; + } + } +} + +static void +luffa5(sph_luffa512_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE5 + + buf = sc->buf; + ptr = sc->ptr; + if (len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + READ_STATE5(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) { + MI5; + P5; + ptr = 0; + } + } + WRITE_STATE5(sc); + sc->ptr = ptr; +} + +static void +luffa5_close(sph_luffa512_context *sc, unsigned ub, unsigned n, void *dst) +{ + unsigned char *buf, *out; + size_t ptr; + unsigned z; + int i; + DECL_STATE5 + + buf = sc->buf; + ptr = sc->ptr; + out = dst; + z = 0x80 >> n; + buf[ptr ++] = ((ub & -z) | z) & 0xFF; + memset(buf + ptr, 0, (sizeof sc->buf) - ptr); + READ_STATE5(sc); + for (i = 0; i < 3; i ++) { + MI5; + P5; + switch (i) { + case 0: + memset(buf, 0, sizeof sc->buf); + break; + case 1: + sph_enc32be(out + 0, V00 ^ V10 ^ V20 ^ V30 ^ V40); + sph_enc32be(out + 4, V01 ^ V11 ^ V21 ^ V31 ^ V41); + sph_enc32be(out + 8, V02 ^ V12 ^ V22 ^ V32 ^ V42); + sph_enc32be(out + 12, V03 ^ V13 ^ V23 ^ V33 ^ V43); + sph_enc32be(out + 16, V04 ^ V14 ^ V24 ^ V34 ^ V44); + sph_enc32be(out + 20, V05 ^ V15 ^ V25 ^ V35 ^ V45); + sph_enc32be(out + 24, V06 ^ V16 ^ V26 ^ V36 ^ V46); + sph_enc32be(out + 28, V07 ^ V17 ^ V27 ^ V37 ^ V47); + break; + case 2: + sph_enc32be(out + 32, V00 ^ V10 ^ V20 ^ V30 ^ V40); + sph_enc32be(out + 36, V01 ^ V11 ^ V21 ^ V31 ^ V41); + sph_enc32be(out + 40, V02 ^ V12 ^ V22 ^ V32 ^ V42); + sph_enc32be(out + 44, V03 ^ V13 ^ V23 ^ V33 ^ V43); + sph_enc32be(out + 48, V04 ^ V14 ^ V24 ^ V34 ^ V44); + sph_enc32be(out + 52, V05 ^ V15 ^ V25 ^ V35 ^ V45); + sph_enc32be(out + 56, V06 ^ V16 ^ V26 ^ V36 ^ V46); + sph_enc32be(out + 60, V07 ^ V17 ^ V27 ^ V37 ^ V47); + break; + } + } +} + +/* see sph_luffa.h */ +void +sph_luffa224_init(void *cc) +{ + sph_luffa224_context *sc; + + sc = cc; + memcpy(sc->V, V_INIT, sizeof(sc->V)); + sc->ptr = 0; +} + +/* see sph_luffa.h */ +void +sph_luffa224(void *cc, const void *data, size_t len) +{ + luffa3(cc, data, len); +} + +/* see sph_luffa.h */ +void +sph_luffa224_close(void *cc, void *dst) +{ + sph_luffa224_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_luffa.h */ +void +sph_luffa224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + luffa3_close(cc, ub, n, dst, 7); + sph_luffa224_init(cc); +} + +/* see sph_luffa.h */ +void +sph_luffa256_init(void *cc) +{ + sph_luffa256_context *sc; + + sc = cc; + memcpy(sc->V, V_INIT, sizeof(sc->V)); + sc->ptr = 0; +} + +/* see sph_luffa.h */ +void +sph_luffa256(void *cc, const void *data, size_t len) +{ + luffa3(cc, data, len); +} + +/* see sph_luffa.h */ +void +sph_luffa256_close(void *cc, void *dst) +{ + sph_luffa256_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_luffa.h */ +void +sph_luffa256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + luffa3_close(cc, ub, n, dst, 8); + sph_luffa256_init(cc); +} + +/* see sph_luffa.h */ +void +sph_luffa384_init(void *cc) +{ + sph_luffa384_context *sc; + + sc = cc; + memcpy(sc->V, V_INIT, sizeof(sc->V)); + sc->ptr = 0; +} + +/* see sph_luffa.h */ +void +sph_luffa384(void *cc, const void *data, size_t len) +{ + luffa4(cc, data, len); +} + +/* see sph_luffa.h */ +void +sph_luffa384_close(void *cc, void *dst) +{ + sph_luffa384_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_luffa.h */ +void +sph_luffa384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + luffa4_close(cc, ub, n, dst); + sph_luffa384_init(cc); +} + +/* see sph_luffa.h */ +void +sph_luffa512_init(void *cc) +{ + sph_luffa512_context *sc; + + sc = cc; + memcpy(sc->V, V_INIT, sizeof(sc->V)); + sc->ptr = 0; +} + +/* see sph_luffa.h */ +void +sph_luffa512(void *cc, const void *data, size_t len) +{ + luffa5(cc, data, len); +} + +/* see sph_luffa.h */ +void +sph_luffa512_close(void *cc, void *dst) +{ + sph_luffa512_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_luffa.h */ +void +sph_luffa512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + luffa5_close(cc, ub, n, dst); + sph_luffa512_init(cc); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..61bac7b --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,4496 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "alert.h" +#include "checkpoints.h" +#include "db.h" +#include "net.h" +#include "init.h" +#include "ui_interface.h" +#include "kernel.h" +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +// +// Global state +// + +CCriticalSection cs_setpwalletRegistered; +set setpwalletRegistered; + +CCriticalSection cs_main; + +CTxMemPool mempool; +unsigned int nTransactionsUpdated = 0; + +map mapBlockIndex; +set > setStakeSeen; +uint256 hashGenesisBlock = hashGenesisBlockOfficial; +static CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); +static CBigNum bnProofOfStakeLimit(~uint256(0) >> 20); + +static CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 16); +static CBigNum bnProofOfStakeLimitTestNet(~uint256(0) >> 30); + +unsigned int nStakeMinAge = 60 * 60 * 24; // 24 hour +unsigned int nStakeMaxAge = 60 * 60 * 35040; // 4 years +unsigned int nStakeTargetSpacing = 60; // 1 minute block spacing + +int64 nChainStartTime = 1455848035; // launch 1456203600 +int nCoinbaseMaturity = 20; // +CBlockIndex* pindexGenesisBlock = NULL; +int nBestHeight = -1; +CBigNum bnBestChainTrust = 0; +CBigNum bnBestInvalidTrust = 0; +uint256 hashBestChain = 0; +CBlockIndex* pindexBest = NULL; +int64 nTimeBestReceived = 0; + +CMedianFilter cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have + +map mapOrphanBlocks; +multimap mapOrphanBlocksByPrev; +set > setStakeSeenOrphan; +map mapProofOfStake; + +map mapOrphanTransactions; +map > mapOrphanTransactionsByPrev; + +// Constant stuff for coinbase transactions we create: +CScript COINBASE_FLAGS; + +const string strMessageMagic = "BERN Signed Message:\n"; + +double dHashesPerSec; +int64 nHPSTimerStart; + +// Settings +int64 nTransactionFee = MIN_TX_FEE; + + +////////////////////////////////////////////////////////////////////////////// +// +// dispatching functions +// + +// These functions dispatch to one or all registered wallets + + +void RegisterWallet(CWallet* pwalletIn) +{ + { + LOCK(cs_setpwalletRegistered); + setpwalletRegistered.insert(pwalletIn); + } +} + +void UnregisterWallet(CWallet* pwalletIn) +{ + { + LOCK(cs_setpwalletRegistered); + setpwalletRegistered.erase(pwalletIn); + } +} + +// check whether the passed transaction is from us +bool static IsFromMe(CTransaction& tx) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + if (pwallet->IsFromMe(tx)) + return true; + return false; +} + +// get the wallet transaction with the given hash (if it exists) +bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + if (pwallet->GetTransaction(hashTx,wtx)) + return true; + return false; +} + +// erases transaction with the given hash from all wallets +void static EraseFromWallets(uint256 hash) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->EraseFromWallet(hash); +} + +// make sure all wallets know about the given transaction, in the given block +void SyncWithWallets(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fConnect) +{ + if (!fConnect) + { + // ppcoin: wallets need to refund inputs when disconnecting coinstake + if (tx.IsCoinStake()) + { + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + if (pwallet->IsFromMe(tx)) + pwallet->DisableTransaction(tx); + } + return; + } + + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate); +} + +// notify wallets about a new best chain +void static SetBestChain(const CBlockLocator& loc) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->SetBestChain(loc); +} + +// notify wallets about an updated transaction +void static UpdatedTransaction(const uint256& hashTx) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->UpdatedTransaction(hashTx); +} + +// dump all wallets +void static PrintWallets(const CBlock& block) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->PrintWallet(block); +} + +// notify wallets about an incoming inventory (for request counts) +void static Inventory(const uint256& hash) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->Inventory(hash); +} + +// ask wallets to resend their transactions +void ResendWalletTransactions() +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->ResendWalletTransactions(); +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapOrphanTransactions +// + +bool AddOrphanTx(const CDataStream& vMsg) +{ + CTransaction tx; + CDataStream(vMsg) >> tx; + uint256 hash = tx.GetHash(); + if (mapOrphanTransactions.count(hash)) + return false; + + CDataStream* pvMsg = new CDataStream(vMsg); + + // Ignore big transactions, to avoid a + // send-big-orphans memory exhaustion attack. If a peer has a legitimate + // large transaction with a missing parent then we assume + // it will rebroadcast it later, after the parent transaction(s) + // have been mined or received. + // 10,000 orphans, each of which is at most 5,000 bytes big is + // at most 500 megabytes of orphans: + if (pvMsg->size() > 5000) + { + printf("ignoring large orphan tx (size: %"PRIszu", hash: %s)\n", pvMsg->size(), hash.ToString().substr(0,10).c_str()); + delete pvMsg; + return false; + } + + mapOrphanTransactions[hash] = pvMsg; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + mapOrphanTransactionsByPrev[txin.prevout.hash].insert(make_pair(hash, pvMsg)); + + printf("stored orphan tx %s (mapsz %"PRIszu")\n", hash.ToString().substr(0,10).c_str(), + mapOrphanTransactions.size()); + return true; +} + +void static EraseOrphanTx(uint256 hash) +{ + if (!mapOrphanTransactions.count(hash)) + return; + const CDataStream* pvMsg = mapOrphanTransactions[hash]; + CTransaction tx; + CDataStream(*pvMsg) >> tx; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash); + if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty()) + mapOrphanTransactionsByPrev.erase(txin.prevout.hash); + } + delete pvMsg; + mapOrphanTransactions.erase(hash); +} + +unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) +{ + unsigned int nEvicted = 0; + while (mapOrphanTransactions.size() > nMaxOrphans) + { + // Evict a random orphan: + uint256 randomhash = GetRandHash(); + map::iterator it = mapOrphanTransactions.lower_bound(randomhash); + if (it == mapOrphanTransactions.end()) + it = mapOrphanTransactions.begin(); + EraseOrphanTx(it->first); + ++nEvicted; + } + return nEvicted; +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// CTransaction and CTxIndex +// + +bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet) +{ + SetNull(); + if (!txdb.ReadTxIndex(prevout.hash, txindexRet)) + return false; + if (!ReadFromDisk(txindexRet.pos)) + return false; + if (prevout.n >= vout.size()) + { + SetNull(); + return false; + } + return true; +} + +bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout) +{ + CTxIndex txindex; + return ReadFromDisk(txdb, prevout, txindex); +} + +bool CTransaction::ReadFromDisk(COutPoint prevout) +{ + CTxDB txdb("r"); + CTxIndex txindex; + return ReadFromDisk(txdb, prevout, txindex); +} + +bool CTransaction::IsStandard() const +{ + if (nVersion > CTransaction::CURRENT_VERSION) + return false; + + BOOST_FOREACH(const CTxIn& txin, vin) + { + // Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG + // pay-to-script-hash, which is 3 ~80-byte signatures, 3 + // ~65-byte public keys, plus a few script ops. + if (txin.scriptSig.size() > 500) + return false; + if (!txin.scriptSig.IsPushOnly()) + return false; + } + BOOST_FOREACH(const CTxOut& txout, vout) { + if (!::IsStandard(txout.scriptPubKey)) + return false; + if (txout.nValue == 0) + return false; + } + return true; +} + +// +// Check transaction inputs, and make sure any +// pay-to-script-hash transactions are evaluating IsStandard scripts +// +// Why bother? To avoid denial-of-service attacks; an attacker +// can submit a standard HASH... OP_EQUAL transaction, +// which will get accepted into blocks. The redemption +// script can be anything; an attacker could use a very +// expensive-to-check-upon-redemption script like: +// DUP CHECKSIG DROP ... repeated 100 times... OP_1 +// +bool CTransaction::AreInputsStandard(const MapPrevTx& mapInputs) const +{ + if (IsCoinBase()) + return true; // Coinbases don't use vin normally + + for (unsigned int i = 0; i < vin.size(); i++) + { + const CTxOut& prev = GetOutputFor(vin[i], mapInputs); + + vector > vSolutions; + txnouttype whichType; + // get the scriptPubKey corresponding to this input: + const CScript& prevScript = prev.scriptPubKey; + if (!Solver(prevScript, whichType, vSolutions)) + return false; + int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions); + if (nArgsExpected < 0) + return false; + + // Transactions with extra stuff in their scriptSigs are + // non-standard. Note that this EvalScript() call will + // be quick, because if there are any operations + // beside "push data" in the scriptSig the + // IsStandard() call returns false + vector > stack; + if (!EvalScript(stack, vin[i].scriptSig, *this, i, 0)) + return false; + + if (whichType == TX_SCRIPTHASH) + { + if (stack.empty()) + return false; + CScript subscript(stack.back().begin(), stack.back().end()); + vector > vSolutions2; + txnouttype whichType2; + if (!Solver(subscript, whichType2, vSolutions2)) + return false; + if (whichType2 == TX_SCRIPTHASH) + return false; + + int tmpExpected; + tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); + if (tmpExpected < 0) + return false; + nArgsExpected += tmpExpected; + } + + if (stack.size() != (unsigned int)nArgsExpected) + return false; + } + + return true; +} + +unsigned int +CTransaction::GetLegacySigOpCount() const +{ + unsigned int nSigOps = 0; + BOOST_FOREACH(const CTxIn& txin, vin) + { + nSigOps += txin.scriptSig.GetSigOpCount(false); + } + BOOST_FOREACH(const CTxOut& txout, vout) + { + nSigOps += txout.scriptPubKey.GetSigOpCount(false); + } + return nSigOps; +} + + +int CMerkleTx::SetMerkleBranch(const CBlock* pblock) +{ + if (fClient) + { + if (hashBlock == 0) + return 0; + } + else + { + CBlock blockTmp; + if (pblock == NULL) + { + // Load the block this tx is in + CTxIndex txindex; + if (!CTxDB("r").ReadTxIndex(GetHash(), txindex)) + return 0; + if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos)) + return 0; + pblock = &blockTmp; + } + + // Update the tx's hashBlock + hashBlock = pblock->GetHash(); + + // Locate the transaction + for (nIndex = 0; nIndex < (int)pblock->vtx.size(); nIndex++) + if (pblock->vtx[nIndex] == *(CTransaction*)this) + break; + if (nIndex == (int)pblock->vtx.size()) + { + vMerkleBranch.clear(); + nIndex = -1; + printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); + return 0; + } + + // Fill in merkle branch + vMerkleBranch = pblock->GetMerkleBranch(nIndex); + } + + // Is the tx in a block that's in the main chain + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + return pindexBest->nHeight - pindex->nHeight + 1; +} + + + + +bool CTransaction::CheckTransaction() const +{ + // Basic checks that don't depend on any context + if (vin.empty()) + return DoS(10, error("CTransaction::CheckTransaction() : vin empty")); + if (vout.empty()) + return DoS(10, error("CTransaction::CheckTransaction() : vout empty")); + // Size limits + if (::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) + return DoS(100, error("CTransaction::CheckTransaction() : size limits failed")); + + // Check for negative or overflow output values + int64 nValueOut = 0; + for (unsigned int i = 0; i < vout.size(); i++) + { + const CTxOut& txout = vout[i]; + if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake()) + return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction")); + + // ppcoin: enforce minimum output amount + if ((!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT) + return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue below minimum")); + + if (txout.nValue > MAX_MONEY) + return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high")); + nValueOut += txout.nValue; + if (!MoneyRange(nValueOut)) + return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range")); + } + + // Check for duplicate inputs + set vInOutPoints; + BOOST_FOREACH(const CTxIn& txin, vin) + { + if (vInOutPoints.count(txin.prevout)) + return false; + vInOutPoints.insert(txin.prevout); + } + + if (IsCoinBase()) + { + if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) + return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size")); + } + else + { + BOOST_FOREACH(const CTxIn& txin, vin) + if (txin.prevout.IsNull()) + return DoS(10, error("CTransaction::CheckTransaction() : prevout is null")); + } + + return true; +} + + +int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, + enum GetMinFee_mode mode, unsigned int nBytes) const +{ + // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE + int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; + + unsigned int nNewBlockSize = nBlockSize + nBytes; + int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; + + // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01 + if (nMinFee < nBaseFee) + { + BOOST_FOREACH(const CTxOut& txout, vout) + if (txout.nValue < CENT) + nMinFee = nBaseFee; + } + + // Raise the price as the block approaches full + if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2) + { + if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN) + return MAX_MONEY; + nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize); + } + + if (!MoneyRange(nMinFee)) + nMinFee = MAX_MONEY; + return nMinFee; +} + + +bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, + bool* pfMissingInputs) +{ + if (pfMissingInputs) + *pfMissingInputs = false; + + if (!tx.CheckTransaction()) + return error("CTxMemPool::accept() : CheckTransaction failed"); + + // Coinbase is only valid in a block, not as a loose transaction + if (tx.IsCoinBase()) + return tx.DoS(100, error("CTxMemPool::accept() : coinbase as individual tx")); + + // ppcoin: coinstake is also only valid in a block, not as a loose transaction + if (tx.IsCoinStake()) + return tx.DoS(100, error("CTxMemPool::accept() : coinstake as individual tx")); + + // To help v0.1.5 clients who would see it as a negative number + if ((int64)tx.nLockTime > std::numeric_limits::max()) + return error("CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet"); + + // Rather not work on nonstandard transactions (unless -testnet) + if (!fTestNet && !tx.IsStandard()) + return error("CTxMemPool::accept() : nonstandard transaction type"); + + // Do we already have it? + uint256 hash = tx.GetHash(); + { + LOCK(cs); + if (mapTx.count(hash)) + return false; + } + if (fCheckInputs) + if (txdb.ContainsTx(hash)) + return false; + + // Check for conflicts with in-memory transactions + CTransaction* ptxOld = NULL; + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + COutPoint outpoint = tx.vin[i].prevout; + if (mapNextTx.count(outpoint)) + { + // Disable replacement feature for now + return false; + + // Allow replacing with a newer version of the same transaction + if (i != 0) + return false; + ptxOld = mapNextTx[outpoint].ptx; + if (ptxOld->IsFinal()) + return false; + if (!tx.IsNewerThan(*ptxOld)) + return false; + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + COutPoint outpoint = tx.vin[i].prevout; + if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld) + return false; + } + break; + } + } + + if (fCheckInputs) + { + MapPrevTx mapInputs; + map mapUnused; + bool fInvalid = false; + if (!tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) + { + if (fInvalid) + return error("CTxMemPool::accept() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str()); + if (pfMissingInputs) + *pfMissingInputs = true; + return false; + } + + // Check for non-standard pay-to-script-hash in inputs + if (!tx.AreInputsStandard(mapInputs) && !fTestNet) + return error("CTxMemPool::accept() : nonstandard transaction input"); + + // Note: if you modify this code to accept non-standard transactions, then + // you should add code here to check that the transaction does a + // reasonable number of ECDSA signature verifications. + + int64 nFees = tx.GetValueIn(mapInputs)-tx.GetValueOut(); + unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + + // Don't accept it if it can't get into a block + int64 txMinFee = tx.GetMinFee(1000, false, GMF_RELAY, nSize); + if (nFees < txMinFee) + return error("CTxMemPool::accept() : not enough fees %s, %"PRI64d" < %"PRI64d, + hash.ToString().c_str(), + nFees, txMinFee); + + // Continuously rate-limit free transactions + // This mitigates 'penny-flooding' -- sending thousands of free transactions just to + // be annoying or make others' transactions take longer to confirm. + if (nFees < MIN_RELAY_TX_FEE) + { + static CCriticalSection cs; + static double dFreeCount; + static int64 nLastTime; + int64 nNow = GetTime(); + + { + LOCK(cs); + // Use an exponentially decaying ~10-minute window: + dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime)); + nLastTime = nNow; + // -limitfreerelay unit is thousand-bytes-per-minute + // At default rate it would take over a month to fill 1GB + if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(tx)) + return error("CTxMemPool::accept() : free transaction rejected by rate limiter"); + if (fDebug) + printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); + dFreeCount += nSize; + } + } + + // Check against previous transactions + // This is done last to help prevent CPU exhaustion denial-of-service attacks. + if (!tx.ConnectInputs(txdb, mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false)) + { + return error("CTxMemPool::accept() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str()); + } + } + + // Store transaction in memory + { + LOCK(cs); + if (ptxOld) + { + printf("CTxMemPool::accept() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str()); + remove(*ptxOld); + } + addUnchecked(hash, tx); + } + + ///// are we sure this is ok when loading transactions or restoring block txes + // If updated, erase old tx from wallet + if (ptxOld) + EraseFromWallets(ptxOld->GetHash()); + + printf("CTxMemPool::accept() : accepted %s (poolsz %"PRIszu")\n", + hash.ToString().substr(0,10).c_str(), + mapTx.size()); + return true; +} + +bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs) +{ + return mempool.accept(txdb, *this, fCheckInputs, pfMissingInputs); +} + +bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx) +{ + // Add to memory pool without checking anything. Don't call this directly, + // call CTxMemPool::accept to properly check the transaction first. + { + mapTx[hash] = tx; + for (unsigned int i = 0; i < tx.vin.size(); i++) + mapNextTx[tx.vin[i].prevout] = CInPoint(&mapTx[hash], i); + nTransactionsUpdated++; + } + return true; +} + + +bool CTxMemPool::remove(CTransaction &tx) +{ + // Remove transaction from memory pool + { + LOCK(cs); + uint256 hash = tx.GetHash(); + if (mapTx.count(hash)) + { + BOOST_FOREACH(const CTxIn& txin, tx.vin) + mapNextTx.erase(txin.prevout); + mapTx.erase(hash); + nTransactionsUpdated++; + } + } + return true; +} + +void CTxMemPool::clear() +{ + LOCK(cs); + mapTx.clear(); + mapNextTx.clear(); + ++nTransactionsUpdated; +} + +void CTxMemPool::queryHashes(std::vector& vtxid) +{ + vtxid.clear(); + + LOCK(cs); + vtxid.reserve(mapTx.size()); + for (map::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) + vtxid.push_back((*mi).first); +} + + + + +int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const +{ + if (hashBlock == 0 || nIndex == -1) + return 0; + + // Find the block it claims to be in + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + // Make sure the merkle branch connects to this block + if (!fMerkleVerified) + { + if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) + return 0; + fMerkleVerified = true; + } + + pindexRet = pindex; + return pindexBest->nHeight - pindex->nHeight + 1; +} + + +int CMerkleTx::GetBlocksToMaturity() const +{ + if (!(IsCoinBase() || IsCoinStake())) + return 0; + return max(0, (nCoinbaseMaturity+10) - GetDepthInMainChain()); +} + + +bool CMerkleTx::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs) +{ + if (fClient) + { + if (!IsInMainChain() && !ClientConnectInputs()) + return false; + return CTransaction::AcceptToMemoryPool(txdb, false); + } + else + { + return CTransaction::AcceptToMemoryPool(txdb, fCheckInputs); + } +} + +bool CMerkleTx::AcceptToMemoryPool() +{ + CTxDB txdb("r"); + return AcceptToMemoryPool(txdb); +} + + + +bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) +{ + + { + LOCK(mempool.cs); + // Add previous supporting transactions first + BOOST_FOREACH(CMerkleTx& tx, vtxPrev) + { + if (!(tx.IsCoinBase() || tx.IsCoinStake())) + { + uint256 hash = tx.GetHash(); + if (!mempool.exists(hash) && !txdb.ContainsTx(hash)) + tx.AcceptToMemoryPool(txdb, fCheckInputs); + } + } + return AcceptToMemoryPool(txdb, fCheckInputs); + } + return false; +} + + +bool CWalletTx::AcceptWalletTransaction() +{ + CTxDB txdb("r"); + return AcceptWalletTransaction(txdb); +} + + +int CTxIndex::GetDepthInMainChain() const +{ + // Read block header + CBlock block; + if (!block.ReadFromDisk(pos.nFile, pos.nBlockPos, false)) + return 0; + // Find the block in the index + map::iterator mi = mapBlockIndex.find(block.GetHash()); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + return 1 + nBestHeight - pindex->nHeight; +} + +// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock +bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock) +{ + { + LOCK(cs_main); + { + LOCK(mempool.cs); + if (mempool.exists(hash)) + { + tx = mempool.lookup(hash); + return true; + } + } + CTxDB txdb("r"); + CTxIndex txindex; + if (tx.ReadFromDisk(txdb, COutPoint(hash, 0), txindex)) + { + CBlock block; + if (block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + hashBlock = block.GetHash(); + return true; + } + } + return false; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// CBlock and CBlockIndex +// + +static CBlockIndex* pblockindexFBBHLast; +CBlockIndex* FindBlockByHeight(int nHeight) +{ + CBlockIndex *pblockindex; + if (nHeight < nBestHeight / 2) + pblockindex = pindexGenesisBlock; + else + pblockindex = pindexBest; + if (pblockindexFBBHLast && abs(nHeight - pblockindex->nHeight) > abs(nHeight - pblockindexFBBHLast->nHeight)) + pblockindex = pblockindexFBBHLast; + while (pblockindex->nHeight > nHeight) + pblockindex = pblockindex->pprev; + while (pblockindex->nHeight < nHeight) + pblockindex = pblockindex->pnext; + pblockindexFBBHLast = pblockindex; + return pblockindex; +} + + +bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions) +{ + if (!fReadTransactions) + { + *this = pindex->GetBlockHeader(); + return true; + } + if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions)) + return false; + if (GetHash() != pindex->GetBlockHash()) + return error("CBlock::ReadFromDisk() : GetHash() doesn't match index"); + return true; +} + + +uint256 static GetOrphanRoot(const CBlock* pblock) +{ + // Work back to the first block in the orphan chain + while (mapOrphanBlocks.count(pblock->hashPrevBlock)) + pblock = mapOrphanBlocks[pblock->hashPrevBlock]; + return pblock->GetHash(); +} + + +// ppcoin: find block wanted by given orphan block +uint256 WantedByOrphan(const CBlock* pblockOrphan) +{ + // Work back to the first block in the orphan chain + while (mapOrphanBlocks.count(pblockOrphan->hashPrevBlock)) + pblockOrphan = mapOrphanBlocks[pblockOrphan->hashPrevBlock]; + return pblockOrphan->hashPrevBlock; +} + + +int generateMTRandom(unsigned int s, int range) +{ + random::mt19937 gen(s); + random::uniform_int_distribution<> dist(0, range); + return dist(gen); +} + +static const int64 nMinSubsidy = 1 * COIN; +// miner's coin base reward based on nBits +int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) +{ + int64_t nSubsidy = 0 * COIN; + + if(nHeight == 1) { + nSubsidy = 10000000 * COIN; // BERN instamine. 5% of 200 mil = 10 mil + } else if(nHeight >= 2 && nHeight <= 720000) { // BERN target 250 days for first phase. Roughly ending a week prior to election from launch. + nSubsidy = 250 * COIN; // 90 mil plus 10 mil insta = half the coins in circulation. + } else if(nHeight >= 720001 && nHeight <= 3875760) { // 3 additional years + nSubsidy = 25 * COIN; // 25 = 39,447,000. 60,553,000 remain + } else if(nHeight >= 3875761 && nHeight <= 4927680) { // 1 additional year + nSubsidy = 100 * COIN; // 52,596,000. 7,957,000 remain + } else if(nHeight >= 4927681 && nHeight <= 6519080) { // we want this 795,700 times. 1,591,400 blocks + nSubsidy = 10 * COIN; + } + return nSubsidy + nFees; +} + + + +// miner's coin stake reward based on nBits and coin age spent (coin-days) +// simple algorithm, not depend on the diff +int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight) +{ + int64 nRewardCoinYear; + nRewardCoinYear = MAX_BERN_PROOF_OF_STAKE; + int64 nSubsidy = nCoinAge * nRewardCoinYear / 365; // BERN no / COIN so PoS is correct + + if (fDebug && GetBoolArg("-printcreation")) + printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits); + + return nSubsidy; +} + +static const int64 nTargetTimespan = 60 * 30; // 30 blocks +static const int64 nTargetSpacingWorkMax = 3 * nStakeTargetSpacing; + +// +// maximum nBits value could possible be required nTime after +// minimum proof-of-work required was nBase +// +unsigned int ComputeMaxBits(CBigNum bnTargetLimit, unsigned int nBase, int64 nTime) +{ + CBigNum bnResult; + bnResult.SetCompact(nBase); + bnResult *= 2; + while (nTime > 0 && bnResult < bnTargetLimit) + { + // Maximum 200% adjustment per day... + bnResult *= 2; + nTime -= 24 * 60 * 60; + } + if (bnResult > bnTargetLimit) + bnResult = bnTargetLimit; + return bnResult.GetCompact(); +} + +// +// minimum amount of work that could possibly be required nTime after +// minimum proof-of-work required was nBase +// +unsigned int ComputeMinWork(unsigned int nBase, int64 nTime) +{ + return ComputeMaxBits(bnProofOfWorkLimit, nBase, nTime); +} + +// +// minimum amount of stake that could possibly be required nTime after +// minimum proof-of-stake required was nBase +// +unsigned int ComputeMinStake(unsigned int nBase, int64 nTime, unsigned int nBlockTime) +{ + return ComputeMaxBits(bnProofOfStakeLimit, nBase, nTime); +} + + +// ppcoin: find last block index up to pindex +const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfStake) +{ + while (pindex && pindex->pprev && (pindex->IsProofOfStake() != fProofOfStake)) + pindex = pindex->pprev; + return pindex; +} + +unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) +{ + CBigNum bnTargetLimit = bnProofOfWorkLimit; + + if(fProofOfStake) + { + // Proof-of-Stake blocks has own target limit since nVersion=3 supermajority on mainNet and always on testNet + bnTargetLimit = bnProofOfStakeLimit; + } + + if (pindexLast == NULL) + return bnTargetLimit.GetCompact(); // genesis block + + const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); + if (pindexPrev->pprev == NULL) + return bnTargetLimit.GetCompact(); // first block + const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake); + if (pindexPrevPrev->pprev == NULL) + return bnTargetLimit.GetCompact(); // second block + + int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); + if(nActualSpacing < 0) + { + // printf(">> nActualSpacing = %"PRI64d" corrected to 1.\n", nActualSpacing); + nActualSpacing = 1; + } + else if(nActualSpacing > nTargetTimespan) + { + // printf(">> nActualSpacing = %"PRI64d" corrected to nTargetTimespan (900).\n", nActualSpacing); + nActualSpacing = nTargetTimespan; + } + + // ppcoin: target change every block + // ppcoin: retarget with exponential moving toward target spacing + CBigNum bnNew; + bnNew.SetCompact(pindexPrev->nBits); + + int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(nTargetSpacingWorkMax, (int64) nStakeTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight)); + int64 nInterval = nTargetTimespan / nTargetSpacing; + bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); + bnNew /= ((nInterval + 1) * nTargetSpacing); + + /* + printf(">> Height = %d, fProofOfStake = %d, nInterval = %"PRI64d", nTargetSpacing = %"PRI64d", nActualSpacing = %"PRI64d"\n", + pindexPrev->nHeight, fProofOfStake, nInterval, nTargetSpacing, nActualSpacing); + printf(">> pindexPrev->GetBlockTime() = %"PRI64d", pindexPrev->nHeight = %d, pindexPrevPrev->GetBlockTime() = %"PRI64d", pindexPrevPrev->nHeight = %d\n", + pindexPrev->GetBlockTime(), pindexPrev->nHeight, pindexPrevPrev->GetBlockTime(), pindexPrevPrev->nHeight); + */ + + if (bnNew > bnTargetLimit) + bnNew = bnTargetLimit; + + return bnNew.GetCompact(); +} + +bool CheckProofOfWork(uint256 hash, unsigned int nBits) +{ + CBigNum bnTarget; + bnTarget.SetCompact(nBits); + + // Check range + if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit) + return error("CheckProofOfWork() : nBits below minimum work"); + + // Check proof of work matches claimed amount + if (hash > bnTarget.getuint256()) + return error("CheckProofOfWork() : hash doesn't match nBits"); + + return true; +} + +// Return maximum amount of blocks that other nodes claim to have +int GetNumBlocksOfPeers() +{ + return std::max(cPeerBlockCounts.median(), Checkpoints::GetTotalBlocksEstimate()); +} + +bool IsInitialBlockDownload() +{ + if (pindexBest == NULL || nBestHeight < Checkpoints::GetTotalBlocksEstimate()) + return true; + static int64 nLastUpdate; + static CBlockIndex* pindexLastBest; + if (pindexBest != pindexLastBest) + { + pindexLastBest = pindexBest; + nLastUpdate = GetTime(); + } + return (GetTime() - nLastUpdate < 10 && + pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60); +} + +void static InvalidChainFound(CBlockIndex* pindexNew) +{ + if (pindexNew->bnChainTrust > bnBestInvalidTrust) + { + bnBestInvalidTrust = pindexNew->bnChainTrust; + CTxDB().WriteBestInvalidTrust(bnBestInvalidTrust); + uiInterface.NotifyBlocksChanged(); + } + + printf("InvalidChainFound: invalid block=%s height=%d trust=%s date=%s\n", + pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, + pindexNew->bnChainTrust.ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S", + pindexNew->GetBlockTime()).c_str()); + printf("InvalidChainFound: current best=%s height=%d trust=%s date=%s\n", + hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(), + DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); +} + +void CBlock::UpdateTime(const CBlockIndex* pindexPrev) +{ + nTime = max(GetBlockTime(), GetAdjustedTime()); +} + + +bool CTransaction::DisconnectInputs(CTxDB& txdb) +{ + // Relinquish previous transactions' spent pointers + if (!IsCoinBase()) + { + BOOST_FOREACH(const CTxIn& txin, vin) + { + COutPoint prevout = txin.prevout; + + // Get prev txindex from disk + CTxIndex txindex; + if (!txdb.ReadTxIndex(prevout.hash, txindex)) + return error("DisconnectInputs() : ReadTxIndex failed"); + + if (prevout.n >= txindex.vSpent.size()) + return error("DisconnectInputs() : prevout.n out of range"); + + // Mark outpoint as not spent + txindex.vSpent[prevout.n].SetNull(); + + // Write back + if (!txdb.UpdateTxIndex(prevout.hash, txindex)) + return error("DisconnectInputs() : UpdateTxIndex failed"); + } + } + + // Remove transaction from index + // This can fail if a duplicate of this transaction was in a chain that got + // reorganized away. This is only possible if this transaction was completely + // spent, so erasing it would be a no-op anyway. + txdb.EraseTxIndex(*this); + + return true; +} + + +bool CTransaction::FetchInputs(CTxDB& txdb, const map& mapTestPool, + bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid) +{ + // FetchInputs can return false either because we just haven't seen some inputs + // (in which case the transaction should be stored as an orphan) + // or because the transaction is malformed (in which case the transaction should + // be dropped). If tx is definitely invalid, fInvalid will be set to true. + fInvalid = false; + + if (IsCoinBase()) + return true; // Coinbase transactions have no inputs to fetch. + + for (unsigned int i = 0; i < vin.size(); i++) + { + COutPoint prevout = vin[i].prevout; + if (inputsRet.count(prevout.hash)) + continue; // Got it already + + // Read txindex + CTxIndex& txindex = inputsRet[prevout.hash].first; + bool fFound = true; + if ((fBlock || fMiner) && mapTestPool.count(prevout.hash)) + { + // Get txindex from current proposed changes + txindex = mapTestPool.find(prevout.hash)->second; + } + else + { + // Read txindex from txdb + fFound = txdb.ReadTxIndex(prevout.hash, txindex); + } + if (!fFound && (fBlock || fMiner)) + return fMiner ? false : error("FetchInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str()); + + // Read txPrev + CTransaction& txPrev = inputsRet[prevout.hash].second; + if (!fFound || txindex.pos == CDiskTxPos(1,1,1)) + { + // Get prev tx from single transactions in memory + { + LOCK(mempool.cs); + if (!mempool.exists(prevout.hash)) + return error("FetchInputs() : %s mempool Tx prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str()); + txPrev = mempool.lookup(prevout.hash); + } + if (!fFound) + txindex.vSpent.resize(txPrev.vout.size()); + } + else + { + // Get prev tx from disk + if (!txPrev.ReadFromDisk(txindex.pos)) + return error("FetchInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str()); + } + } + + // Make sure all prevout.n indexes are valid: + for (unsigned int i = 0; i < vin.size(); i++) + { + const COutPoint prevout = vin[i].prevout; + assert(inputsRet.count(prevout.hash) != 0); + const CTxIndex& txindex = inputsRet[prevout.hash].first; + const CTransaction& txPrev = inputsRet[prevout.hash].second; + if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) + { + // Revisit this if/when transaction replacement is implemented and allows + // adding inputs: + fInvalid = true; + return DoS(100, error("FetchInputs() : %s prevout.n out of range %d %"PRIszu" %"PRIszu" prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str())); + } + } + + return true; +} + + +const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const +{ + MapPrevTx::const_iterator mi = inputs.find(input.prevout.hash); + if (mi == inputs.end()) + throw std::runtime_error("CTransaction::GetOutputFor() : prevout.hash not found"); + + const CTransaction& txPrev = (mi->second).second; + if (input.prevout.n >= txPrev.vout.size()) + throw std::runtime_error("CTransaction::GetOutputFor() : prevout.n out of range"); + + return txPrev.vout[input.prevout.n]; +} + + +int64 CTransaction::GetValueIn(const MapPrevTx& inputs) const +{ + if (IsCoinBase()) + return 0; + + int64 nResult = 0; + for (unsigned int i = 0; i < vin.size(); i++) + { + nResult += GetOutputFor(vin[i], inputs).nValue; + } + return nResult; + +} + + +unsigned int CTransaction::GetP2SHSigOpCount(const MapPrevTx& inputs) const +{ + if (IsCoinBase()) + return 0; + + unsigned int nSigOps = 0; + for (unsigned int i = 0; i < vin.size(); i++) + { + const CTxOut& prevout = GetOutputFor(vin[i], inputs); + if (prevout.scriptPubKey.IsPayToScriptHash()) + nSigOps += prevout.scriptPubKey.GetSigOpCount(vin[i].scriptSig); + } + return nSigOps; +} + + +bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, + map& mapTestPool, const CDiskTxPos& posThisTx, + const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash) +{ + // Take over previous transactions' spent pointers + // fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain + // fMiner is true when called from the internal bitcoin miner + // ... both are false when called from CTransaction::AcceptToMemoryPool + if (!IsCoinBase()) + { + int64 nValueIn = 0; + int64 nFees = 0; + for (unsigned int i = 0; i < vin.size(); i++) + { + COutPoint prevout = vin[i].prevout; + assert(inputs.count(prevout.hash) > 0); + CTxIndex& txindex = inputs[prevout.hash].first; + CTransaction& txPrev = inputs[prevout.hash].second; + + if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) + return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %"PRIszu" %"PRIszu" prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str())); + + // If prev is coinbase or coinstake, check that it's matured + if (txPrev.IsCoinBase() || txPrev.IsCoinStake()) + for (const CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < nCoinbaseMaturity; pindex = pindex->pprev) + if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile) + return error("ConnectInputs() : tried to spend %s at depth %d", txPrev.IsCoinBase() ? "coinbase" : "coinstake", pindexBlock->nHeight - pindex->nHeight); + + // ppcoin: check transaction timestamp + if (txPrev.nTime > nTime) + return DoS(100, error("ConnectInputs() : transaction timestamp earlier than input transaction")); + + // Check for negative or overflow input values + nValueIn += txPrev.vout[prevout.n].nValue; + if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) + return DoS(100, error("ConnectInputs() : txin values out of range")); + + } + // The first loop above does all the inexpensive checks. + // Only if ALL inputs pass do we perform expensive ECDSA signature checks. + // Helps prevent CPU exhaustion attacks. + for (unsigned int i = 0; i < vin.size(); i++) + { + COutPoint prevout = vin[i].prevout; + assert(inputs.count(prevout.hash) > 0); + CTxIndex& txindex = inputs[prevout.hash].first; + CTransaction& txPrev = inputs[prevout.hash].second; + + // Check for conflicts (double-spend) + // This doesn't trigger the DoS code on purpose; if it did, it would make it easier + // for an attacker to attempt to split the network. + if (!txindex.vSpent[prevout.n].IsNull()) + return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str()); + + // Skip ECDSA signature verification when connecting blocks (fBlock=true) + // before the last blockchain checkpoint. This is safe because block merkle hashes are + // still computed and checked, and any change will be caught at the next checkpoint. + if (!(fBlock && (nBestHeight < Checkpoints::GetTotalBlocksEstimate()))) + { + // Verify signature + if (!VerifySignature(txPrev, *this, i, fStrictPayToScriptHash, 0)) + { + // only during transition phase for P2SH: do not invoke anti-DoS code for + // potentially old clients relaying bad P2SH transactions + if (fStrictPayToScriptHash && VerifySignature(txPrev, *this, i, false, 0)) + return error("ConnectInputs() : %s P2SH VerifySignature failed", GetHash().ToString().substr(0,10).c_str()); + + return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str())); + } + } + + // Mark outpoints as spent + txindex.vSpent[prevout.n] = posThisTx; + + // Write back + if (fBlock || fMiner) + { + mapTestPool[prevout.hash] = txindex; + } + } + + if (IsCoinStake()) + { + // ppcoin: coin stake tx earns reward instead of paying fee + uint64 nCoinAge; + if (!GetCoinAge(txdb, nCoinAge)) + return error("ConnectInputs() : %s unable to get coin age for coinstake", GetHash().ToString().substr(0,10).c_str()); + int64 nStakeReward = GetValueOut() - nValueIn; + if (nStakeReward > GetProofOfStakeReward(nCoinAge, pindexBlock->nBits, nTime, pindexBlock->nHeight) - GetMinFee() + MIN_TX_FEE) + return DoS(100, error("ConnectInputs() : %s stake reward exceeded", GetHash().ToString().substr(0,10).c_str())); + } + else + { + if (nValueIn < GetValueOut()) + return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str())); + + // Tally transaction fees + int64 nTxFee = nValueIn - GetValueOut(); + if (nTxFee < 0) + return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str())); + // ppcoin: enforce transaction fees for every block + if (nTxFee < GetMinFee()) + return fBlock? DoS(100, error("ConnectInputs() : %s not paying required fee=%s, paid=%s", GetHash().ToString().substr(0,10).c_str(), FormatMoney(GetMinFee()).c_str(), FormatMoney(nTxFee).c_str())) : false; + + nFees += nTxFee; + if (!MoneyRange(nFees)) + return DoS(100, error("ConnectInputs() : nFees out of range")); + } + } + + return true; +} + + +bool CTransaction::ClientConnectInputs() +{ + if (IsCoinBase()) + return false; + + // Take over previous transactions' spent pointers + { + LOCK(mempool.cs); + int64 nValueIn = 0; + for (unsigned int i = 0; i < vin.size(); i++) + { + // Get prev tx from single transactions in memory + COutPoint prevout = vin[i].prevout; + if (!mempool.exists(prevout.hash)) + return false; + CTransaction& txPrev = mempool.lookup(prevout.hash); + + if (prevout.n >= txPrev.vout.size()) + return false; + + // Verify signature + if (!VerifySignature(txPrev, *this, i, true, 0)) + return error("ConnectInputs() : VerifySignature failed"); + + ///// this is redundant with the mempool.mapNextTx stuff, + ///// not sure which I want to get rid of + ///// this has to go away now that posNext is gone + // // Check for conflicts + // if (!txPrev.vout[prevout.n].posNext.IsNull()) + // return error("ConnectInputs() : prev tx already used"); + // + // // Flag outpoints as used + // txPrev.vout[prevout.n].posNext = posThisTx; + + nValueIn += txPrev.vout[prevout.n].nValue; + + if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) + return error("ClientConnectInputs() : txin values out of range"); + } + if (GetValueOut() > nValueIn) + return false; + } + + return true; +} + + +bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) +{ + // Disconnect in reverse order + for (int i = vtx.size()-1; i >= 0; i--) + if (!vtx[i].DisconnectInputs(txdb)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = 0; + if (!txdb.WriteBlockIndex(blockindexPrev)) + return error("DisconnectBlock() : WriteBlockIndex failed"); + } + + // ppcoin: clean up wallet after disconnecting coinstake + BOOST_FOREACH(CTransaction& tx, vtx) + SyncWithWallets(tx, this, false, false); + + return true; +} + +bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) +{ + // Check it again in case a previous version let a bad block in + if (!CheckBlock(!fJustCheck, !fJustCheck)) + return false; + + // Do not allow blocks that contain transactions which 'overwrite' older transactions, + // unless those are already completely spent. + // If such overwrites are allowed, coinbases and transactions depending upon those + // can be duplicated to remove the ability to spend the first instance -- even after + // being sent to another address. + // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information. + // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool + // already refuses previously-known transaction ids entirely. + // This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC. + // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the + // two in the chain that violate it. This prevents exploiting the issue against nodes in their + // initial block download. + bool fEnforceBIP30 = true; // Always active in BERN + bool fStrictPayToScriptHash = true; // Always active in BERN + + //// issue here: it doesn't know the version + unsigned int nTxPos; + if (fJustCheck) + // FetchInputs treats CDiskTxPos(1,1,1) as a special "refer to memorypool" indicator + // Since we're just checking the block and not actually connecting it, it might not (and probably shouldn't) be on the disk to get the transaction from + nTxPos = 1; + else + nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - (2 * GetSizeOfCompactSize(0)) + GetSizeOfCompactSize(vtx.size()); + + map mapQueuedChanges; + int64 nFees = 0; + int64 nValueIn = 0; + int64 nValueOut = 0; + unsigned int nSigOps = 0; + BOOST_FOREACH(CTransaction& tx, vtx) + { + uint256 hashTx = tx.GetHash(); + + if (fEnforceBIP30) { + CTxIndex txindexOld; + if (txdb.ReadTxIndex(hashTx, txindexOld)) { + BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent) + if (pos.IsNull()) + return false; + } + } + + nSigOps += tx.GetLegacySigOpCount(); + if (nSigOps > MAX_BLOCK_SIGOPS) + return DoS(100, error("ConnectBlock() : too many sigops")); + + CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); + if (!fJustCheck) + nTxPos += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); + + MapPrevTx mapInputs; + if (tx.IsCoinBase()) + nValueOut += tx.GetValueOut(); + else + { + bool fInvalid; + if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid)) + return false; + + if (fStrictPayToScriptHash) + { + // Add in sigops done by pay-to-script-hash inputs; + // this is to prevent a "rogue miner" from creating + // an incredibly-expensive-to-validate block. + nSigOps += tx.GetP2SHSigOpCount(mapInputs); + if (nSigOps > MAX_BLOCK_SIGOPS) + return DoS(100, error("ConnectBlock() : too many sigops")); + } + + int64 nTxValueIn = tx.GetValueIn(mapInputs); + int64 nTxValueOut = tx.GetValueOut(); + nValueIn += nTxValueIn; + nValueOut += nTxValueOut; + if (!tx.IsCoinStake()) + nFees += nTxValueIn - nTxValueOut; + + if (!tx.ConnectInputs(txdb, mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fStrictPayToScriptHash)) + return false; + } + + mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size()); + } + + // ppcoin: track money supply and mint amount info + pindex->nMint = nValueOut - nValueIn + nFees; + pindex->nMoneySupply = (pindex->pprev? pindex->pprev->nMoneySupply : 0) + nValueOut - nValueIn; + if (!txdb.WriteBlockIndex(CDiskBlockIndex(pindex))) + return error("Connect() : WriteBlockIndex for pindex failed"); + + // ppcoin: fees are not collected by miners as in bitcoin + // ppcoin: fees are destroyed to compensate the entire network + if (fDebug && GetBoolArg("-printcreation")) + printf("ConnectBlock() : destroy=%s nFees=%"PRI64d"\n", FormatMoney(nFees).c_str(), nFees); + + if (fJustCheck) + return true; + + // Write queued txindex changes + for (map::iterator mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi) + { + if (!txdb.UpdateTxIndex((*mi).first, (*mi).second)) + return error("ConnectBlock() : UpdateTxIndex failed"); + } + + uint256 prevHash = 0; + if(pindex->pprev) + { + prevHash = pindex->pprev->GetBlockHash(); + // printf("==> Got prevHash = %s\n", prevHash.ToString().c_str()); + } + + if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = pindex->GetBlockHash(); + if (!txdb.WriteBlockIndex(blockindexPrev)) + return error("ConnectBlock() : WriteBlockIndex failed"); + } + + // Watch for transactions paying to me + BOOST_FOREACH(CTransaction& tx, vtx) + SyncWithWallets(tx, this, true); + + return true; +} + +bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) +{ + printf("REORGANIZE\n"); + + // Find the fork + CBlockIndex* pfork = pindexBest; + CBlockIndex* plonger = pindexNew; + while (pfork != plonger) + { + while (plonger->nHeight > pfork->nHeight) + if (!(plonger = plonger->pprev)) + return error("Reorganize() : plonger->pprev is null"); + if (pfork == plonger) + break; + if (!(pfork = pfork->pprev)) + return error("Reorganize() : pfork->pprev is null"); + } + + // List of what to disconnect + vector vDisconnect; + for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev) + vDisconnect.push_back(pindex); + + // List of what to connect + vector vConnect; + for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev) + vConnect.push_back(pindex); + reverse(vConnect.begin(), vConnect.end()); + + printf("REORGANIZE: Disconnect %"PRIszu" blocks; %s..%s\n", vDisconnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexBest->GetBlockHash().ToString().substr(0,20).c_str()); + printf("REORGANIZE: Connect %"PRIszu" blocks; %s..%s\n", vConnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->GetBlockHash().ToString().substr(0,20).c_str()); + + // Disconnect shorter branch + vector vResurrect; + BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) + { + CBlock block; + if (!block.ReadFromDisk(pindex)) + return error("Reorganize() : ReadFromDisk for disconnect failed"); + if (!block.DisconnectBlock(txdb, pindex)) + return error("Reorganize() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str()); + + // Queue memory transactions to resurrect + BOOST_FOREACH(const CTransaction& tx, block.vtx) + if (!(tx.IsCoinBase() || tx.IsCoinStake())) + vResurrect.push_back(tx); + } + + // Connect longer branch + vector vDelete; + for (unsigned int i = 0; i < vConnect.size(); i++) + { + CBlockIndex* pindex = vConnect[i]; + CBlock block; + if (!block.ReadFromDisk(pindex)) + return error("Reorganize() : ReadFromDisk for connect failed"); + if (!block.ConnectBlock(txdb, pindex)) + { + // Invalid block + return error("Reorganize() : ConnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str()); + } + + // Queue memory transactions to delete + BOOST_FOREACH(const CTransaction& tx, block.vtx) + vDelete.push_back(tx); + } + if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) + return error("Reorganize() : WriteHashBestChain failed"); + + // Make sure it's successfully written to disk before changing memory structure + if (!txdb.TxnCommit()) + return error("Reorganize() : TxnCommit failed"); + + // Disconnect shorter branch + BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) + if (pindex->pprev) + pindex->pprev->pnext = NULL; + + // Connect longer branch + BOOST_FOREACH(CBlockIndex* pindex, vConnect) + if (pindex->pprev) + pindex->pprev->pnext = pindex; + + // Resurrect memory transactions that were in the disconnected branch + BOOST_FOREACH(CTransaction& tx, vResurrect) + tx.AcceptToMemoryPool(txdb, false); + + // Delete redundant memory transactions that are in the connected branch + BOOST_FOREACH(CTransaction& tx, vDelete) + mempool.remove(tx); + + printf("REORGANIZE: done\n"); + + return true; +} + + +// Called from inside SetBestChain: attaches a block to the new best chain being built +bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew) +{ + uint256 hash = GetHash(); + + // Adding to current best branch + if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash)) + { + txdb.TxnAbort(); + InvalidChainFound(pindexNew); + return false; + } + if (!txdb.TxnCommit()) + return error("SetBestChain() : TxnCommit failed"); + + // Add to current best branch + pindexNew->pprev->pnext = pindexNew; + + // Delete redundant memory transactions + BOOST_FOREACH(CTransaction& tx, vtx) + mempool.remove(tx); + + return true; +} + + +bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) +{ + uint256 hash = GetHash(); + + if (!txdb.TxnBegin()) + return error("SetBestChain() : TxnBegin failed"); + + if (pindexGenesisBlock == NULL && hash == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) + { + txdb.WriteHashBestChain(hash); + if (!txdb.TxnCommit()) + return error("SetBestChain() : TxnCommit failed"); + pindexGenesisBlock = pindexNew; + } + else if (hashPrevBlock == hashBestChain) + { + if (!SetBestChainInner(txdb, pindexNew)) + return error("SetBestChain() : SetBestChainInner failed"); + } + else + { + // the first block in the new chain that will cause it to become the new best chain + CBlockIndex *pindexIntermediate = pindexNew; + + // list of blocks that need to be connected afterwards + std::vector vpindexSecondary; + + // Reorganize is costly in terms of db load, as it works in a single db transaction. + // Try to limit how much needs to be done inside + while (pindexIntermediate->pprev && pindexIntermediate->pprev->bnChainTrust > pindexBest->bnChainTrust) + { + vpindexSecondary.push_back(pindexIntermediate); + pindexIntermediate = pindexIntermediate->pprev; + } + + if (!vpindexSecondary.empty()) + printf("Postponing %"PRIszu" reconnects\n", vpindexSecondary.size()); + + // Switch to new best branch + if (!Reorganize(txdb, pindexIntermediate)) + { + txdb.TxnAbort(); + InvalidChainFound(pindexNew); + return error("SetBestChain() : Reorganize failed"); + } + + // Connect further blocks + BOOST_REVERSE_FOREACH(CBlockIndex *pindex, vpindexSecondary) + { + CBlock block; + if (!block.ReadFromDisk(pindex)) + { + printf("SetBestChain() : ReadFromDisk failed\n"); + break; + } + if (!txdb.TxnBegin()) { + printf("SetBestChain() : TxnBegin 2 failed\n"); + break; + } + // errors now are not fatal, we still did a reorganisation to a new chain in a valid way + if (!block.SetBestChainInner(txdb, pindex)) + break; + } + } + + // Update best block in wallet (so we can detect restored wallets) + bool fIsInitialDownload = IsInitialBlockDownload(); + if (!fIsInitialDownload) + { + const CBlockLocator locator(pindexNew); + ::SetBestChain(locator); + } + + // New best block + hashBestChain = hash; + pindexBest = pindexNew; + pblockindexFBBHLast = NULL; + nBestHeight = pindexBest->nHeight; + bnBestChainTrust = pindexNew->bnChainTrust; + nTimeBestReceived = GetTime(); + nTransactionsUpdated++; + printf("SetBestChain: new best=%s height=%d trust=%s date=%s\n", + hashBestChain.ToString().c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(), + DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); + + printf("Stake checkpoint: %x\n", pindexBest->nStakeModifierChecksum); + + // Check the version of the last 100 blocks to see if we need to upgrade: + if (!fIsInitialDownload) + { + int nUpgraded = 0; + const CBlockIndex* pindex = pindexBest; + for (int i = 0; i < 100 && pindex != NULL; i++) + { + if (pindex->nVersion > CBlock::CURRENT_VERSION) + ++nUpgraded; + pindex = pindex->pprev; + } + if (nUpgraded > 0) + printf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, CBlock::CURRENT_VERSION); + if (nUpgraded > 100/2) + // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: + strMiscWarning = _("Warning: This version is obsolete, upgrade required!"); + } + + std::string strCmd = GetArg("-blocknotify", ""); + + if (!fIsInitialDownload && !strCmd.empty()) + { + boost::replace_all(strCmd, "%s", hashBestChain.GetHex()); + boost::thread t(runCommand, strCmd); // thread runs free + } + + return true; +} + +// ppcoin: total coin age spent in transaction, in the unit of coin-days. +// Only those coins meeting minimum age requirement counts. As those +// transactions not in main chain are not currently indexed so we +// might not find out about their coin age. Older transactions are +// guaranteed to be in main chain by sync-checkpoint. This rule is +// introduced to help nodes establish a consistent view of the coin +// age (trust score) of competing branches. +bool CTransaction::GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const +{ + CBigNum bnCentSecond = 0; // coin age in the unit of cent-seconds + nCoinAge = 0; + + if (IsCoinBase()) + return true; + + BOOST_FOREACH(const CTxIn& txin, vin) + { + // First try finding the previous transaction in database + CTransaction txPrev; + CTxIndex txindex; + if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) + continue; // previous transaction not in main chain + if (nTime < txPrev.nTime) + return false; // Transaction timestamp violation + + // Read block header + CBlock block; + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + return false; // unable to read block of previous transaction + if (block.GetBlockTime() + nStakeMinAge > nTime) + continue; // only count coins meeting min age requirement + + int64 nValueIn = txPrev.vout[txin.prevout.n].nValue; + bnCentSecond += CBigNum(nValueIn) * (nTime-txPrev.nTime) / CENT; + + if (fDebug && GetBoolArg("-printcoinage")) + printf("coin age nValueIn=%"PRI64d" nTimeDiff=%d bnCentSecond=%s\n", nValueIn, nTime - txPrev.nTime, bnCentSecond.ToString().c_str()); + } + + CBigNum bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60); + if (fDebug && GetBoolArg("-printcoinage")) + printf("coin age bnCoinDay=%s\n", bnCoinDay.ToString().c_str()); + nCoinAge = bnCoinDay.getuint64(); + return true; +} + +// ppcoin: total coin age spent in block, in the unit of coin-days. +bool CBlock::GetCoinAge(uint64& nCoinAge) const +{ + nCoinAge = 0; + + CTxDB txdb("r"); + BOOST_FOREACH(const CTransaction& tx, vtx) + { + uint64 nTxCoinAge; + if (tx.GetCoinAge(txdb, nTxCoinAge)) + nCoinAge += nTxCoinAge; + else + return false; + } + + if (nCoinAge == 0) // block coin age minimum 1 coin-day + nCoinAge = 1; + if (fDebug && GetBoolArg("-printcoinage")) + printf("block coin age total nCoinDays=%"PRI64d"\n", nCoinAge); + return true; +} + +bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str()); + + // Construct new block index object + CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this); + if (!pindexNew) + return error("AddToBlockIndex() : new CBlockIndex failed"); + pindexNew->phashBlock = &hash; + map::iterator miPrev = mapBlockIndex.find(hashPrevBlock); + if (miPrev != mapBlockIndex.end()) + { + pindexNew->pprev = (*miPrev).second; + pindexNew->nHeight = pindexNew->pprev->nHeight + 1; + } + + // ppcoin: compute chain trust score + pindexNew->bnChainTrust = (pindexNew->pprev ? pindexNew->pprev->bnChainTrust : 0) + pindexNew->GetBlockTrust(); + + // ppcoin: compute stake entropy bit for stake modifier + if (!pindexNew->SetStakeEntropyBit(GetStakeEntropyBit(pindexNew->nHeight))) + return error("AddToBlockIndex() : SetStakeEntropyBit() failed"); + + // ppcoin: record proof-of-stake hash value + if (pindexNew->IsProofOfStake()) + { + if (!mapProofOfStake.count(hash)) + return error("AddToBlockIndex() : hashProofOfStake not found in map"); + pindexNew->hashProofOfStake = mapProofOfStake[hash]; + } + + // ppcoin: compute stake modifier + uint64 nStakeModifier = 0; + bool fGeneratedStakeModifier = false; + if (!ComputeNextStakeModifier(pindexNew->pprev, nStakeModifier, fGeneratedStakeModifier)) + return error("AddToBlockIndex() : ComputeNextStakeModifier() failed"); + pindexNew->SetStakeModifier(nStakeModifier, fGeneratedStakeModifier); + pindexNew->nStakeModifierChecksum = GetStakeModifierChecksum(pindexNew); + if (!CheckStakeModifierCheckpoints(pindexNew->nHeight, pindexNew->nStakeModifierChecksum)) + return error("AddToBlockIndex() : Rejected by stake modifier checkpoint height=%d, modifier=0x%016"PRI64x, pindexNew->nHeight, nStakeModifier); + + // Add to mapBlockIndex + map::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + if (pindexNew->IsProofOfStake()) + setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); + pindexNew->phashBlock = &((*mi).first); + + // Write to disk block index + CTxDB txdb; + if (!txdb.TxnBegin()) + return false; + txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); + if (!txdb.TxnCommit()) + return false; + + // New best + if (pindexNew->bnChainTrust > bnBestChainTrust) + if (!SetBestChain(txdb, pindexNew)) + return false; + + txdb.Close(); + + if (pindexNew == pindexBest) + { + // Notify UI to display prev block's coinbase if it was ours + static uint256 hashPrevBestCoinBase; + UpdatedTransaction(hashPrevBestCoinBase); + hashPrevBestCoinBase = vtx[0].GetHash(); + } + + uiInterface.NotifyBlocksChanged(); + return true; +} + + +bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot) const +{ + // These are checks that are independent of context + // that can be verified before saving an orphan block. + + // Size limits + if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) + return DoS(100, error("CheckBlock() : size limits failed")); + + // Check proof of work matches claimed amount + if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits)) + return DoS(50, error("CheckBlock() : proof of work failed")); + + // First transaction must be coinbase, the rest must not be + if (vtx.empty() || !vtx[0].IsCoinBase()) + return DoS(100, error("CheckBlock() : first tx is not coinbase")); + for (unsigned int i = 1; i < vtx.size(); i++) + if (vtx[i].IsCoinBase()) + return DoS(100, error("CheckBlock() : more than one coinbase")); + + // ppcoin: only the second transaction can be the optional coinstake + for (unsigned int i = 2; i < vtx.size(); i++) + if (vtx[i].IsCoinStake()) + return DoS(100, error("CheckBlock() : coinstake in wrong position")); + + // ppcoin: coinbase output should be empty if proof-of-stake block + if (IsProofOfStake() && (vtx[0].vout.size() != 1 || !vtx[0].vout[0].IsEmpty())) + return error("CheckBlock() : coinbase output not empty for proof-of-stake block"); + + // Check transactions + BOOST_FOREACH(const CTransaction& tx, vtx) + { + if (!tx.CheckTransaction()) + return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed")); + + // ppcoin: check transaction timestamp + if (GetBlockTime() < (int64)tx.nTime) + return DoS(50, error("CheckBlock() : block timestamp earlier than transaction timestamp")); + } + + // Check for duplicate txids. This is caught by ConnectInputs(), + // but catching it earlier avoids a potential DoS attack: + set uniqueTx; + BOOST_FOREACH(const CTransaction& tx, vtx) + { + uniqueTx.insert(tx.GetHash()); + } + if (uniqueTx.size() != vtx.size()) + return DoS(100, error("CheckBlock() : duplicate transaction")); + + unsigned int nSigOps = 0; + BOOST_FOREACH(const CTransaction& tx, vtx) + { + nSigOps += tx.GetLegacySigOpCount(); + } + if (nSigOps > MAX_BLOCK_SIGOPS) + return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount")); + + // Check merkle root + if (fCheckMerkleRoot && hashMerkleRoot != BuildMerkleTree()) + return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch")); + + // ppcoin: check block signature + if (!CheckBlockSignature()) + return DoS(100, error("CheckBlock() : bad block signature")); + + return true; +} + + +bool CBlock::AcceptBlock() +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AcceptBlock() : block already in mapBlockIndex"); + + // Get prev block index + map::iterator mi = mapBlockIndex.find(hashPrevBlock); + if (mi == mapBlockIndex.end()) + return DoS(10, error("AcceptBlock() : prev block not found")); + CBlockIndex* pindexPrev = (*mi).second; + int nHeight = pindexPrev->nHeight+1; + + if (IsProofOfWork() && nHeight > CUTOFF_POW_BLOCK) + return DoS(100, error("AcceptBlock() : No proof-of-work allowed anymore (height = %d)", nHeight)); + + // Check proof-of-work or proof-of-stake + if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake())) + return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake")); + + // Check timestamp + if (GetBlockTime() > GetAdjustedTime() + GetMaxClockDrift(nHeight)) + return error("AcceptBlock() : block timestamp too far in the future"); + + // Check coinbase timestamp + if (GetBlockTime() > (int64)vtx[0].nTime + GetMaxClockDrift(nHeight)) + return DoS(50, error("AcceptBlock() : coinbase timestamp is too early")); + + // Check that all transactions are finalized + BOOST_FOREACH(const CTransaction& tx, vtx) + if (!tx.IsFinal(nHeight, GetBlockTime())) + return DoS(10, error("AcceptBlock() : contains a non-final transaction")); + + // Check that the block chain matches the known block chain up to a checkpoint + if (!Checkpoints::CheckHardened(nHeight, hash)) + return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight)); + + // ppcoin: check that the block satisfies synchronized checkpoint + if (!Checkpoints::CheckSync(hash, pindexPrev)) + { + if(!GetBoolArg("-nosynccheckpoints", false)) + { + return error("AcceptBlock() : rejected by synchronized checkpoint"); + } + else + { + strMiscWarning = _("WARNING: syncronized checkpoint violation detected, but skipped!"); + } + } + + // Reject block.nVersion < 3 blocks since 95% threshold on mainNet and always on testNet: + if (nVersion < 3 && ((!fTestNet && nHeight > 14060) || (fTestNet && nHeight > 0))) + return error("CheckBlock() : rejected nVersion < 3 block"); + + // Enforce rule that the coinbase starts with serialized block height + CScript expect = CScript() << nHeight; + if (!std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) + return DoS(100, error("AcceptBlock() : block height mismatch in coinbase")); + + // Write block to history file + if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION))) + return error("AcceptBlock() : out of disk space"); + unsigned int nFile = -1; + unsigned int nBlockPos = 0; + if (!WriteToDisk(nFile, nBlockPos)) + return error("AcceptBlock() : WriteToDisk failed"); + if (!AddToBlockIndex(nFile, nBlockPos)) + return error("AcceptBlock() : AddToBlockIndex failed"); + + // Relay inventory, but don't relay old inventory during initial block download + int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(); + if (hashBestChain == hash) + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) + pnode->PushInventory(CInv(MSG_BLOCK, hash)); + } + + // ppcoin: check pending sync-checkpoint + Checkpoints::AcceptPendingSyncCheckpoint(); + + return true; +} + + +CBigNum CBlockIndex::GetBlockTrust() const +{ + CBigNum bnTarget; + bnTarget.SetCompact(nBits); + if (bnTarget <= 0) + return 0; + + if (IsProofOfStake()) + { + // Return trust score as usual + return (CBigNum(1)<<256) / (bnTarget+1); + } + else + { + // Calculate work amount for block + CBigNum bnPoWTrust = (bnProofOfWorkLimit / (bnTarget+1)); + return bnPoWTrust > 1 ? bnPoWTrust : 1; + } +} + +bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck) +{ + unsigned int nFound = 0; + for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++) + { + if (pstart->nVersion >= minVersion) + ++nFound; + pstart = pstart->pprev; + } + return (nFound >= nRequired); +} + + +bool ProcessBlock(CNode* pfrom, CBlock* pblock) +{ + // Check for duplicate + uint256 hash = pblock->GetHash(); + if (mapBlockIndex.count(hash)) + return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str()); + if (mapOrphanBlocks.count(hash)) + return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str()); + + // ppcoin: check proof-of-stake + // Limited duplicity on stake: prevents block flood attack + // Duplicate stake allowed only when there is orphan child block + if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash) && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) + return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str()); + + // Preliminary checks + if (!pblock->CheckBlock()) + return error("ProcessBlock() : CheckBlock FAILED"); + + // ppcoin: verify hash target and signature of coinstake tx + if (pblock->IsProofOfStake()) + { + uint256 hashProofOfStake = 0; + if (!CheckProofOfStake(pblock->vtx[1], pblock->nBits, hashProofOfStake)) + { + printf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str()); + return false; // do not error here as we expect this during initial block download + } + if (!mapProofOfStake.count(hash)) // add to mapProofOfStake + mapProofOfStake.insert(make_pair(hash, hashProofOfStake)); + } + + CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint(); + + if(pcheckpoint && fDebug) + { + const CBlockIndex* pindexLastPos = GetLastBlockIndex(pcheckpoint, true); + if(pindexLastPos) + { + printf("ProcessBlock(): Last POS Block Height: %d \n", pindexLastPos->nHeight); + } + else + { + printf("ProcessBlock(): Previous POS block not found.\n"); + } + } + + if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) + { + // Extra checks to prevent "fill up memory by spamming with bogus blocks" + int64 deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime; + CBigNum bnNewBlock; + bnNewBlock.SetCompact(pblock->nBits); + CBigNum bnRequired; + + if (pblock->IsProofOfStake()) + bnRequired.SetCompact(ComputeMinStake(GetLastBlockIndex(pcheckpoint, true)->nBits, deltaTime, pblock->nTime)); + else + bnRequired.SetCompact(ComputeMinWork(GetLastBlockIndex(pcheckpoint, false)->nBits, deltaTime)); + + if (bnNewBlock > bnRequired) + { + if (pfrom) + pfrom->Misbehaving(100); + return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); + } + } + + // ppcoin: ask for pending sync-checkpoint if any + if (!IsInitialBlockDownload()) + Checkpoints::AskForPendingSyncCheckpoint(pfrom); + + // If don't already have its previous block, shunt it off to holding area until we get it + if (!mapBlockIndex.count(pblock->hashPrevBlock)) + { + printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str()); + CBlock* pblock2 = new CBlock(*pblock); + // ppcoin: check proof-of-stake + if (pblock2->IsProofOfStake()) + { + // Limited duplicity on stake: prevents block flood attack + // Duplicate stake allowed only when there is orphan child block + if (setStakeSeenOrphan.count(pblock2->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash) && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) + return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for orphan block %s", pblock2->GetProofOfStake().first.ToString().c_str(), pblock2->GetProofOfStake().second, hash.ToString().c_str()); + else + setStakeSeenOrphan.insert(pblock2->GetProofOfStake()); + } + mapOrphanBlocks.insert(make_pair(hash, pblock2)); + mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2)); + + // Ask this guy to fill in what we're missing + if (pfrom) + { + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2)); + // ppcoin: getblocks may not obtain the ancestor block rejected + // earlier by duplicate-stake check so we ask for it again directly + if (!IsInitialBlockDownload()) + pfrom->AskFor(CInv(MSG_BLOCK, WantedByOrphan(pblock2))); + } + return true; + } + + // Store to disk + if (!pblock->AcceptBlock()) + return error("ProcessBlock() : AcceptBlock FAILED"); + + // Recursively process any orphan blocks that depended on this one + vector vWorkQueue; + vWorkQueue.push_back(hash); + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (multimap::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev); + mi != mapOrphanBlocksByPrev.upper_bound(hashPrev); + ++mi) + { + CBlock* pblockOrphan = (*mi).second; + if (pblockOrphan->AcceptBlock()) + vWorkQueue.push_back(pblockOrphan->GetHash()); + mapOrphanBlocks.erase(pblockOrphan->GetHash()); + setStakeSeenOrphan.erase(pblockOrphan->GetProofOfStake()); + delete pblockOrphan; + } + mapOrphanBlocksByPrev.erase(hashPrev); + } + + printf("ProcessBlock: ACCEPTED\n"); + + // ppcoin: if responsible for sync-checkpoint send it + if (pfrom && !CSyncCheckpoint::strMasterPrivKey.empty()) + Checkpoints::SendSyncCheckpoint(Checkpoints::AutoSelectSyncCheckpoint()); + + return true; +} + +// ppcoin: sign block +bool CBlock::SignBlock(const CKeyStore& keystore) +{ + vector vSolutions; + txnouttype whichType; + + if(!IsProofOfStake()) + { + for(unsigned int i = 0; i < vtx[0].vout.size(); i++) + { + const CTxOut& txout = vtx[0].vout[i]; + + if (!Solver(txout.scriptPubKey, whichType, vSolutions)) + continue; + + if (whichType == TX_PUBKEY) + { + // Sign + valtype& vchPubKey = vSolutions[0]; + CKey key; + + if (!keystore.GetKey(Hash160(vchPubKey), key)) + continue; + if (key.GetPubKey() != vchPubKey) + continue; + if(!key.Sign(GetHash(), vchBlockSig)) + continue; + + return true; + } + } + } + else + { + const CTxOut& txout = vtx[1].vout[1]; + + if (!Solver(txout.scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_PUBKEY) + { + // Sign + valtype& vchPubKey = vSolutions[0]; + CKey key; + + if (!keystore.GetKey(Hash160(vchPubKey), key)) + return false; + if (key.GetPubKey() != vchPubKey) + return false; + + return key.Sign(GetHash(), vchBlockSig); + } + } + + printf("Sign failed\n"); + return false; +} + +// ppcoin: check block signature +bool CBlock::CheckBlockSignature() const +{ + if (GetHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) + return vchBlockSig.empty(); + + vector vSolutions; + txnouttype whichType; + + if(IsProofOfStake()) + { + const CTxOut& txout = vtx[1].vout[1]; + + if (!Solver(txout.scriptPubKey, whichType, vSolutions)) + return false; + if (whichType == TX_PUBKEY) + { + valtype& vchPubKey = vSolutions[0]; + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + if (vchBlockSig.empty()) + return false; + return key.Verify(GetHash(), vchBlockSig); + } + } + else + { + for(unsigned int i = 0; i < vtx[0].vout.size(); i++) + { + const CTxOut& txout = vtx[0].vout[i]; + + if (!Solver(txout.scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_PUBKEY) + { + // Verify + valtype& vchPubKey = vSolutions[0]; + CKey key; + if (!key.SetPubKey(vchPubKey)) + continue; + if (vchBlockSig.empty()) + continue; + if(!key.Verify(GetHash(), vchBlockSig)) + continue; + + return true; + } + } + } + return false; +} + + +bool CheckDiskSpace(uint64 nAdditionalBytes) +{ + uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; + + // Check for nMinDiskSpace bytes (currently 50MB) + if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) + { + fShutdown = true; + string strMessage = _("Warning: Disk space is low!"); + strMiscWarning = strMessage; + printf("*** %s\n", strMessage.c_str()); + uiInterface.ThreadSafeMessageBox(strMessage, "BERN", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + StartShutdown(); + return false; + } + return true; +} + + +static filesystem::path BlockFilePath(unsigned int nFile) +{ + string strBlockFn = strprintf("blk%04u.dat", nFile); + return GetDataDir() / strBlockFn; +} + + +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode) +{ + if ((nFile < 1) || (nFile == (unsigned int) -1)) + return NULL; + FILE* file = fopen(BlockFilePath(nFile).string().c_str(), pszMode); + if (!file) + return NULL; + if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) + { + if (fseek(file, nBlockPos, SEEK_SET) != 0) + { + fclose(file); + return NULL; + } + } + return file; +} + + +static unsigned int nCurrentBlockFile = 1; + +FILE* AppendBlockFile(unsigned int& nFileRet) +{ + nFileRet = 0; + while (true) + { + FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab"); + if (!file) + return NULL; + if (fseek(file, 0, SEEK_END) != 0) + return NULL; + // FAT32 file size max 4GB, fseek and ftell max 2GB, so we must stay under 2GB + if (ftell(file) < (long)(0x7F000000 - MAX_SIZE)) + { + nFileRet = nCurrentBlockFile; + return file; + } + fclose(file); + nCurrentBlockFile++; + } +} + + +bool LoadBlockIndex(bool fAllowNew) +{ + if (fTestNet) + { + pchMessageStart[0] = 0x70; + pchMessageStart[1] = 0x35; + pchMessageStart[2] = 0x22; + pchMessageStart[3] = 0x05; + + bnProofOfStakeLimit = bnProofOfStakeLimitTestNet; // 0x00000fff PoS base target is fixed in testnet + bnProofOfWorkLimit = bnProofOfWorkLimitTestNet; // 0x0000ffff PoW base target is fixed in testnet + nStakeMinAge = 15 * 60; // test net min age is 20 min + nStakeMaxAge = 60 * 60; // test net max age is 60 min + nModifierInterval = 60; // test modifier interval is 2 minutes + nCoinbaseMaturity = 10; // test maturity is 10 blocks + nStakeTargetSpacing = 3 * 60; // test block spacing is 3 minutes + } + + // + // Load block index + // + CTxDB txdb("cr"); + if (!txdb.LoadBlockIndex()) + return false; + txdb.Close(); + + // + // Init with genesis block + // + if (mapBlockIndex.empty()) + { + if (!fAllowNew) + return false; + + // Genesis block + const char* pszTimestamp = "BERNcash - the peoples coin! 23/2/2016"; + CTransaction txNew; + txNew.nTime = nChainStartTime; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].SetEmpty(); + + CBlock block; + block.vtx.push_back(txNew); + block.hashPrevBlock = 0; + block.hashMerkleRoot = block.BuildMerkleTree(); + block.nVersion = 1; + block.nTime = nChainStartTime + 10; + block.nBits = bnProofOfWorkLimit.GetCompact(); + block.nNonce = 1559966; + + if (false && (block.GetHash() != hashGenesisBlock)) { + + // This will figure out a valid hash and Nonce if you're + // creating a different genesis block: + uint256 hashTarget = CBigNum().SetCompact(block.nBits).getuint256(); + while (block.GetHash() > hashTarget) + { + ++block.nNonce; + if (block.nNonce == 0) + { + printf("NONCE WRAPPED, incrementing time"); + ++block.nTime; + } + if ((block.nNonce & 0xFFF) == 0) + { + printf("nonce %08X: hash = %s (target = %s)\n", block.nNonce, block.GetHash().ToString().c_str(), hashTarget.ToString().c_str()); + } + + } + } + + //// debug print + block.print(); + printf("block.GetHash() == %s\n", block.GetHash().ToString().c_str()); + printf("block.hashMerkleRoot == %s\n", block.hashMerkleRoot.ToString().c_str()); + printf("block.nTime = %u \n", block.nTime); + printf("block.nNonce = %u \n", block.nNonce); + + assert(block.hashMerkleRoot == uint256("0x37df7239291d8195fb2701235c2a6d76f62f8412c38e070a7f962c887da0d711")); + assert(block.GetHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)); + + // Start new block file + unsigned int nFile; + unsigned int nBlockPos; + if (!block.WriteToDisk(nFile, nBlockPos)) + return error("LoadBlockIndex() : writing genesis block to disk failed"); + if (!block.AddToBlockIndex(nFile, nBlockPos)) + return error("LoadBlockIndex() : genesis block not accepted"); + + // ppcoin: initialize synchronized checkpoint + if (!Checkpoints::WriteSyncCheckpoint((!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet))) + return error("LoadBlockIndex() : failed to init sync checkpoint"); + } + + // ppcoin: if checkpoint master key changed must reset sync-checkpoint + { + CTxDB txdb; + string strPubKey = ""; + if (!txdb.ReadCheckpointPubKey(strPubKey) || strPubKey != CSyncCheckpoint::strMasterPubKey) + { + // write checkpoint master key to db + txdb.TxnBegin(); + if (!txdb.WriteCheckpointPubKey(CSyncCheckpoint::strMasterPubKey)) + return error("LoadBlockIndex() : failed to write new checkpoint master key to db"); + if (!txdb.TxnCommit()) + return error("LoadBlockIndex() : failed to commit new checkpoint master key to db"); + if ((!fTestNet) && !Checkpoints::ResetSyncCheckpoint()) + return error("LoadBlockIndex() : failed to reset sync-checkpoint"); + } + txdb.Close(); + } + + return true; +} + + + +void PrintBlockTree() +{ + // pre-compute tree structure + map > mapNext; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + CBlockIndex* pindex = (*mi).second; + mapNext[pindex->pprev].push_back(pindex); + // test + //while (rand() % 3 == 0) + // mapNext[pindex->pprev].push_back(pindex); + } + + vector > vStack; + vStack.push_back(make_pair(0, pindexGenesisBlock)); + + int nPrevCol = 0; + while (!vStack.empty()) + { + int nCol = vStack.back().first; + CBlockIndex* pindex = vStack.back().second; + vStack.pop_back(); + + // print split or gap + if (nCol > nPrevCol) + { + for (int i = 0; i < nCol-1; i++) + printf("| "); + printf("|\\\n"); + } + else if (nCol < nPrevCol) + { + for (int i = 0; i < nCol; i++) + printf("| "); + printf("|\n"); + } + nPrevCol = nCol; + + // print columns + for (int i = 0; i < nCol; i++) + printf("| "); + + // print item + CBlock block; + block.ReadFromDisk(pindex); + printf("%d (%u,%u) %s %08x %s mint %7s tx %"PRIszu"", + pindex->nHeight, + pindex->nFile, + pindex->nBlockPos, + block.GetHash().ToString().c_str(), + block.nBits, + DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(), + FormatMoney(pindex->nMint).c_str(), + block.vtx.size()); + + PrintWallets(block); + + // put the main time-chain first + vector& vNext = mapNext[pindex]; + for (unsigned int i = 0; i < vNext.size(); i++) + { + if (vNext[i]->pnext) + { + swap(vNext[0], vNext[i]); + break; + } + } + + // iterate children + for (unsigned int i = 0; i < vNext.size(); i++) + vStack.push_back(make_pair(nCol+i, vNext[i])); + } +} + +bool LoadExternalBlockFile(FILE* fileIn) +{ + int64 nStart = GetTimeMillis(); + + int nLoaded = 0; + { + LOCK(cs_main); + try { + CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION); + unsigned int nPos = 0; + while (nPos != (unsigned int)-1 && blkdat.good() && !fRequestShutdown) + { + unsigned char pchData[65536]; + do { + fseek(blkdat, nPos, SEEK_SET); + int nRead = fread(pchData, 1, sizeof(pchData), blkdat); + if (nRead <= 8) + { + nPos = (unsigned int)-1; + break; + } + void* nFind = memchr(pchData, pchMessageStart[0], nRead+1-sizeof(pchMessageStart)); + if (nFind) + { + if (memcmp(nFind, pchMessageStart, sizeof(pchMessageStart))==0) + { + nPos += ((unsigned char*)nFind - pchData) + sizeof(pchMessageStart); + break; + } + nPos += ((unsigned char*)nFind - pchData) + 1; + } + else + nPos += sizeof(pchData) - sizeof(pchMessageStart) + 1; + } while(!fRequestShutdown); + if (nPos == (unsigned int)-1) + break; + fseek(blkdat, nPos, SEEK_SET); + unsigned int nSize; + blkdat >> nSize; + if (nSize > 0 && nSize <= MAX_BLOCK_SIZE) + { + CBlock block; + blkdat >> block; + if (ProcessBlock(NULL,&block)) + { + nLoaded++; + nPos += 4 + nSize; + } + } + } + } + catch (std::exception &e) { + printf("%s() : Deserialize or I/O error caught during load\n", + __PRETTY_FUNCTION__); + } + } + printf("Loaded %i blocks from external file in %"PRI64d"ms\n", nLoaded, GetTimeMillis() - nStart); + return nLoaded > 0; +} + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CAlert +// + +extern map mapAlerts; +extern CCriticalSection cs_mapAlerts; + +string GetWarnings(string strFor) +{ + int nPriority = 0; + string strStatusBar; + string strRPC; + + if (GetBoolArg("-testsafemode")) + strRPC = "test"; + + // Misc warnings like out of disk space and clock is wrong + if (strMiscWarning != "") + { + nPriority = 1000; + strStatusBar = strMiscWarning; + } + + // ppcoin: should not enter safe mode for longer invalid chain + // ppcoin: if sync-checkpoint is too old do not enter safe mode + if (Checkpoints::IsSyncCheckpointTooOld(60 * 60 * 24 * 365) && !fTestNet && !IsInitialBlockDownload()) + { + nPriority = 100; + strStatusBar = "WARNING: Checkpoint is too old. Wait for block chain to download, or notify developers."; + } + + // ppcoin: if detected invalid checkpoint enter safe mode + if (Checkpoints::hashInvalidCheckpoint != 0) + { + nPriority = 3000; + strStatusBar = strRPC = "WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers."; + } + + // Alerts + { + LOCK(cs_mapAlerts); + BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + { + const CAlert& alert = item.second; + if (alert.AppliesToMe() && alert.nPriority > nPriority) + { + nPriority = alert.nPriority; + strStatusBar = alert.strStatusBar; + if (nPriority > 1000) + strRPC = strStatusBar; // ppcoin: safe mode for high alert + } + } + } + + if (strFor == "statusbar") + return strStatusBar; + else if (strFor == "rpc") + return strRPC; + assert(!"GetWarnings() : invalid parameter"); + return "error"; +} + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Messages +// + + +bool static AlreadyHave(CTxDB& txdb, const CInv& inv) +{ + switch (inv.type) + { + case MSG_TX: + { + bool txInMap = false; + { + LOCK(mempool.cs); + txInMap = (mempool.exists(inv.hash)); + } + return txInMap || + mapOrphanTransactions.count(inv.hash) || + txdb.ContainsTx(inv.hash); + } + + case MSG_BLOCK: + return mapBlockIndex.count(inv.hash) || + mapOrphanBlocks.count(inv.hash); + } + // Don't know what it is, just say we already got one + return true; +} + + + + +// 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. +unsigned char pchMessageStart[4] = { 0x09, 0x11, 0x16, 0x20 }; + +bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) +{ + static map mapReuseKey; + RandAddSeedPerfmon(); + if (fDebug) + printf("received: %s (%"PRIszu" bytes)\n", strCommand.c_str(), vRecv.size()); + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) + { + printf("dropmessagestest DROPPING RECV MESSAGE\n"); + return true; + } + + + + + + if (strCommand == "version") + { + // Each connection can only send one version message + if (pfrom->nVersion != 0) + { + pfrom->Misbehaving(1); + return false; + } + + int64 nTime; + CAddress addrMe; + CAddress addrFrom; + uint64 nNonce = 1; + vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + if (pfrom->nVersion < MIN_PROTO_VERSION) + { + // Since February 20, 2012, the protocol is initiated at version 209, + // and earlier versions are no longer supported + printf("partner %s using obsolete version %i; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); + pfrom->fDisconnect = true; + return false; + } + + if (pfrom->nVersion == 10300) + pfrom->nVersion = 300; + if (!vRecv.empty()) + vRecv >> addrFrom >> nNonce; + if (!vRecv.empty()) + vRecv >> pfrom->strSubVer; + if (!vRecv.empty()) + vRecv >> pfrom->nStartingHeight; + + if (pfrom->fInbound && addrMe.IsRoutable()) + { + pfrom->addrLocal = addrMe; + SeenLocal(addrMe); + } + + // Disconnect if we connected to ourself + if (nNonce == nLocalHostNonce && nNonce > 1) + { + printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str()); + pfrom->fDisconnect = true; + return true; + } + + // ppcoin: record my external IP reported by peer + if (addrFrom.IsRoutable() && addrMe.IsRoutable()) + addrSeenByPeer = addrMe; + + // Be shy and don't send version until we hear + if (pfrom->fInbound) + pfrom->PushVersion(); + + pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); + + AddTimeData(pfrom->addr, nTime); + + // Change version + pfrom->PushMessage("verack"); + pfrom->vSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); + + if (!pfrom->fInbound) + { + // Advertise our address + if (!fNoListen && !IsInitialBlockDownload()) + { + CAddress addr = GetLocalAddress(&pfrom->addr); + if (addr.IsRoutable()) + pfrom->PushAddress(addr); + } + + // Get recent addresses + if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) + { + pfrom->PushMessage("getaddr"); + pfrom->fGetAddr = true; + } + addrman.Good(pfrom->addr); + } else { + if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom) + { + addrman.Add(addrFrom, addrFrom); + addrman.Good(addrFrom); + } + } + + // Ask the first connected node for block updates + static int nAskedForBlocks = 0; + if (!pfrom->fClient && !pfrom->fOneShot && + (pfrom->nStartingHeight > (nBestHeight - 144)) && + (pfrom->nVersion < NOBLKS_VERSION_START || + pfrom->nVersion >= NOBLKS_VERSION_END) && + (nAskedForBlocks < 1 || vNodes.size() <= 1)) + { + nAskedForBlocks++; + pfrom->PushGetBlocks(pindexBest, uint256(0)); + } + + // Relay alerts + { + LOCK(cs_mapAlerts); + BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + item.second.RelayTo(pfrom); + } + + // ppcoin: relay sync-checkpoint + { + LOCK(Checkpoints::cs_hashSyncCheckpoint); + if (!Checkpoints::checkpointMessage.IsNull()) + Checkpoints::checkpointMessage.RelayTo(pfrom); + } + + pfrom->fSuccessfullyConnected = true; + + printf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str()); + + cPeerBlockCounts.input(pfrom->nStartingHeight); + + // ppcoin: ask for pending sync-checkpoint if any + if (!IsInitialBlockDownload()) + Checkpoints::AskForPendingSyncCheckpoint(pfrom); + } + + + else if (pfrom->nVersion == 0) + { + // Must have a version message before anything else + pfrom->Misbehaving(1); + return false; + } + + + else if (strCommand == "verack") + { + pfrom->vRecv.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); + } + + + else if (strCommand == "addr") + { + vector vAddr; + vRecv >> vAddr; + + // Don't want addr from older versions unless seeding + if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000) + return true; + if (vAddr.size() > 1000) + { + pfrom->Misbehaving(20); + return error("message addr size() = %"PRIszu"", vAddr.size()); + } + + // Store the new addresses + vector vAddrOk; + int64 nNow = GetAdjustedTime(); + int64 nSince = nNow - 10 * 60; + BOOST_FOREACH(CAddress& addr, vAddr) + { + if (fShutdown) + return true; + if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) + addr.nTime = nNow - 5 * 24 * 60 * 60; + pfrom->AddAddressKnown(addr); + bool fReachable = IsReachable(addr); + if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) + { + // Relay to a limited number of other nodes + { + LOCK(cs_vNodes); + // Use deterministic randomness to send to the same nodes for 24 hours + // at a time so the setAddrKnowns of the chosen nodes prevent repeats + static uint256 hashSalt; + if (hashSalt == 0) + hashSalt = GetRandHash(); + uint64 hashAddr = addr.GetHash(); + uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)); + hashRand = Hash(BEGIN(hashRand), END(hashRand)); + multimap mapMix; + BOOST_FOREACH(CNode* pnode, vNodes) + { + if (pnode->nVersion < CADDR_TIME_VERSION) + continue; + unsigned int nPointer; + memcpy(&nPointer, &pnode, sizeof(nPointer)); + uint256 hashKey = hashRand ^ nPointer; + hashKey = Hash(BEGIN(hashKey), END(hashKey)); + mapMix.insert(make_pair(hashKey, pnode)); + } + int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s) + for (multimap::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) + ((*mi).second)->PushAddress(addr); + } + } + // Do not store addresses outside our network + if (fReachable) + vAddrOk.push_back(addr); + } + addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60); + if (vAddr.size() < 1000) + pfrom->fGetAddr = false; + if (pfrom->fOneShot) + pfrom->fDisconnect = true; + } + + + else if (strCommand == "inv") + { + vector vInv; + vRecv >> vInv; + if (vInv.size() > MAX_INV_SZ) + { + pfrom->Misbehaving(20); + return error("message inv size() = %"PRIszu"", vInv.size()); + } + + // find last block in inv vector + unsigned int nLastBlock = (unsigned int)(-1); + for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { + if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) { + nLastBlock = vInv.size() - 1 - nInv; + break; + } + } + CTxDB txdb("r"); + for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) + { + const CInv &inv = vInv[nInv]; + + if (fShutdown) + return true; + pfrom->AddInventoryKnown(inv); + + bool fAlreadyHave = AlreadyHave(txdb, inv); + if (fDebug) + printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); + + if (!fAlreadyHave) + pfrom->AskFor(inv); + else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) { + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); + } else if (nInv == nLastBlock) { + // In case we are on a very long side-chain, it is possible that we already have + // the last block in an inv bundle sent in response to getblocks. Try to detect + // this situation and push another getblocks to continue. + pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0)); + if (fDebug) + printf("force request: %s\n", inv.ToString().c_str()); + } + + // Track requests for our stuff + Inventory(inv.hash); + } + } + + + else if (strCommand == "getdata") + { + vector vInv; + vRecv >> vInv; + if (vInv.size() > MAX_INV_SZ) + { + pfrom->Misbehaving(20); + return error("message getdata size() = %"PRIszu"", vInv.size()); + } + + if (fDebugNet || (vInv.size() != 1)) + printf("received getdata (%"PRIszu" invsz)\n", vInv.size()); + + BOOST_FOREACH(const CInv& inv, vInv) + { + if (fShutdown) + return true; + if (fDebugNet || (vInv.size() == 1)) + printf("received getdata for: %s\n", inv.ToString().c_str()); + + if (inv.type == MSG_BLOCK) + { + // Send block from disk + map::iterator mi = mapBlockIndex.find(inv.hash); + if (mi != mapBlockIndex.end()) + { + CBlock block; + block.ReadFromDisk((*mi).second); + pfrom->PushMessage("block", block); + + // Trigger them to send a getblocks request for the next batch of inventory + if (inv.hash == pfrom->hashContinue) + { + // ppcoin: send latest proof-of-work block to allow the + // download node to accept as orphan (proof-of-stake + // block might be rejected by stake connection check) + vector vInv; + vInv.push_back(CInv(MSG_BLOCK, GetLastBlockIndex(pindexBest, false)->GetBlockHash())); + pfrom->PushMessage("inv", vInv); + pfrom->hashContinue = 0; + } + } + } + else if (inv.IsKnownType()) + { + // Send stream from relay memory + bool pushed = false; + { + LOCK(cs_mapRelay); + map::iterator mi = mapRelay.find(inv); + if (mi != mapRelay.end()) { + pfrom->PushMessage(inv.GetCommand(), (*mi).second); + pushed = true; + } + } + if (!pushed && inv.type == MSG_TX) { + LOCK(mempool.cs); + if (mempool.exists(inv.hash)) { + CTransaction tx = mempool.lookup(inv.hash); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss.reserve(1000); + ss << tx; + pfrom->PushMessage("tx", ss); + } + } + } + + // Track requests for our stuff + Inventory(inv.hash); + } + } + + + else if (strCommand == "getblocks") + { + CBlockLocator locator; + uint256 hashStop; + vRecv >> locator >> hashStop; + + // Find the last block the caller has in the main chain + CBlockIndex* pindex = locator.GetBlockIndex(); + + // Send the rest of the chain + if (pindex) + pindex = pindex->pnext; + int nLimit = 500; + printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit); + for (; pindex; pindex = pindex->pnext) + { + if (pindex->GetBlockHash() == hashStop) + { + printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str()); + // ppcoin: tell downloading node about the latest block if it's + // without risk being rejected due to stake connection check + if (hashStop != hashBestChain && pindex->GetBlockTime() + nStakeMinAge > pindexBest->GetBlockTime()) + pfrom->PushInventory(CInv(MSG_BLOCK, hashBestChain)); + break; + } + pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); + if (--nLimit <= 0) + { + // When this block is requested, we'll send an inv that'll make them + // getblocks the next batch of inventory. + printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str()); + pfrom->hashContinue = pindex->GetBlockHash(); + break; + } + } + } + else if (strCommand == "checkpoint") + { + CSyncCheckpoint checkpoint; + vRecv >> checkpoint; + + if (checkpoint.ProcessSyncCheckpoint(pfrom)) + { + // Relay + pfrom->hashCheckpointKnown = checkpoint.hashCheckpoint; + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + checkpoint.RelayTo(pnode); + } + } + + else if (strCommand == "getheaders") + { + CBlockLocator locator; + uint256 hashStop; + vRecv >> locator >> hashStop; + + CBlockIndex* pindex = NULL; + if (locator.IsNull()) + { + // If locator is null, return the hashStop block + map::iterator mi = mapBlockIndex.find(hashStop); + if (mi == mapBlockIndex.end()) + return true; + pindex = (*mi).second; + } + else + { + // Find the last block the caller has in the main chain + pindex = locator.GetBlockIndex(); + if (pindex) + pindex = pindex->pnext; + } + + vector vHeaders; + int nLimit = 2000; + printf("getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str()); + for (; pindex; pindex = pindex->pnext) + { + vHeaders.push_back(pindex->GetBlockHeader()); + if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) + break; + } + pfrom->PushMessage("headers", vHeaders); + } + + + else if (strCommand == "tx") + { + vector vWorkQueue; + vector vEraseQueue; + CDataStream vMsg(vRecv); + CTxDB txdb("r"); + CTransaction tx; + vRecv >> tx; + + CInv inv(MSG_TX, tx.GetHash()); + pfrom->AddInventoryKnown(inv); + + bool fMissingInputs = false; + if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs)) + { + SyncWithWallets(tx, NULL, true); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + vEraseQueue.push_back(inv.hash); + + // Recursively process any orphan transactions that depended on this one + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (map::iterator mi = mapOrphanTransactionsByPrev[hashPrev].begin(); + mi != mapOrphanTransactionsByPrev[hashPrev].end(); + ++mi) + { + const CDataStream& vMsg = *((*mi).second); + CTransaction tx; + CDataStream(vMsg) >> tx; + CInv inv(MSG_TX, tx.GetHash()); + bool fMissingInputs2 = false; + + if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs2)) + { + printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); + SyncWithWallets(tx, NULL, true); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + vEraseQueue.push_back(inv.hash); + } + else if (!fMissingInputs2) + { + // invalid orphan + vEraseQueue.push_back(inv.hash); + printf(" removed invalid orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); + } + } + } + + BOOST_FOREACH(uint256 hash, vEraseQueue) + EraseOrphanTx(hash); + } + else if (fMissingInputs) + { + AddOrphanTx(vMsg); + + // DoS prevention: do not allow mapOrphanTransactions to grow unbounded + unsigned int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS); + if (nEvicted > 0) + printf("mapOrphan overflow, removed %u tx\n", nEvicted); + } + if (tx.nDoS) pfrom->Misbehaving(tx.nDoS); + } + + + else if (strCommand == "block") + { + CBlock block; + vRecv >> block; + + printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str()); + // block.print(); + + CInv inv(MSG_BLOCK, block.GetHash()); + pfrom->AddInventoryKnown(inv); + + if (ProcessBlock(pfrom, &block)) + mapAlreadyAskedFor.erase(inv); + if (block.nDoS) pfrom->Misbehaving(block.nDoS); + } + + + else if (strCommand == "getaddr") + { + pfrom->vAddrToSend.clear(); + vector vAddr = addrman.GetAddr(); + BOOST_FOREACH(const CAddress &addr, vAddr) + pfrom->PushAddress(addr); + } + + + else if (strCommand == "mempool") + { + std::vector vtxid; + mempool.queryHashes(vtxid); + vector vInv; + for (unsigned int i = 0; i < vtxid.size(); i++) { + CInv inv(MSG_TX, vtxid[i]); + vInv.push_back(inv); + if (i == (MAX_INV_SZ - 1)) + break; + } + if (vInv.size() > 0) + pfrom->PushMessage("inv", vInv); + } + + + else if (strCommand == "checkorder") + { + uint256 hashReply; + vRecv >> hashReply; + + if (!GetBoolArg("-allowreceivebyip")) + { + pfrom->PushMessage("reply", hashReply, (int)2, string("")); + return true; + } + + CWalletTx order; + vRecv >> order; + + /// we have a chance to check the order here + + // Keep giving the same key to the same ip until they use it + if (!mapReuseKey.count(pfrom->addr)) + pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr], true); + + // Send back approval of order and pubkey to use + CScript scriptPubKey; + scriptPubKey << mapReuseKey[pfrom->addr] << OP_CHECKSIG; + pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey); + } + + + else if (strCommand == "reply") + { + uint256 hashReply; + vRecv >> hashReply; + + CRequestTracker tracker; + { + LOCK(pfrom->cs_mapRequests); + map::iterator mi = pfrom->mapRequests.find(hashReply); + if (mi != pfrom->mapRequests.end()) + { + tracker = (*mi).second; + pfrom->mapRequests.erase(mi); + } + } + if (!tracker.IsNull()) + tracker.fn(tracker.param1, vRecv); + } + + + else if (strCommand == "ping") + { + if (pfrom->nVersion > BIP0031_VERSION) + { + uint64 nonce = 0; + vRecv >> nonce; + // Echo the message back with the nonce. This allows for two useful features: + // + // 1) A remote node can quickly check if the connection is operational + // 2) Remote nodes can measure the latency of the network thread. If this node + // is overloaded it won't respond to pings quickly and the remote node can + // avoid sending us more work, like chain download requests. + // + // The nonce stops the remote getting confused between different pings: without + // it, if the remote node sends a ping once per second and this node takes 5 + // seconds to respond to each, the 5th ping the remote sends would appear to + // return very quickly. + pfrom->PushMessage("pong", nonce); + } + } + + + else if (strCommand == "alert") + { + CAlert alert; + vRecv >> alert; + + uint256 alertHash = alert.GetHash(); + if (pfrom->setKnown.count(alertHash) == 0) + { + if (alert.ProcessAlert()) + { + // Relay + pfrom->setKnown.insert(alertHash); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + alert.RelayTo(pnode); + } + } + else { + // Small DoS penalty so peers that send us lots of + // duplicate/expired/invalid-signature/whatever alerts + // eventually get banned. + // This isn't a Misbehaving(100) (immediate ban) because the + // peer might be an older or different implementation with + // a different signature key, etc. + pfrom->Misbehaving(10); + } + } + } + + + else + { + // Ignore unknown commands for extensibility + } + + + // Update the last seen time for this node's address + if (pfrom->fNetworkNode) + if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping") + AddressCurrentlyConnected(pfrom->addr); + + + return true; +} + +bool ProcessMessages(CNode* pfrom) +{ + CDataStream& vRecv = pfrom->vRecv; + if (vRecv.empty()) + return true; + //if (fDebug) + // printf("ProcessMessages(%u bytes)\n", vRecv.size()); + + // + // Message format + // (4) message start + // (12) command + // (4) size + // (4) checksum + // (x) data + // + + while (true) + { + // Don't bother if send buffer is too full to respond anyway + if (pfrom->vSend.size() >= SendBufferSize()) + break; + + // Scan for message start + CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart)); + int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader()); + if (vRecv.end() - pstart < nHeaderSize) + { + if ((int)vRecv.size() > nHeaderSize) + { + printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n"); + vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize); + } + break; + } + if (pstart - vRecv.begin() > 0) + printf("\n\nPROCESSMESSAGE SKIPPED %"PRIpdd" BYTES\n\n", pstart - vRecv.begin()); + vRecv.erase(vRecv.begin(), pstart); + + // Read header + vector vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize); + CMessageHeader hdr; + vRecv >> hdr; + if (!hdr.IsValid()) + { + printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); + continue; + } + string strCommand = hdr.GetCommand(); + + // Message size + unsigned int nMessageSize = hdr.nMessageSize; + if (nMessageSize > MAX_SIZE) + { + printf("ProcessMessages(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize); + continue; + } + if (nMessageSize > vRecv.size()) + { + // Rewind and wait for rest of message + vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end()); + break; + } + + // Checksum + uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + if (nChecksum != hdr.nChecksum) + { + printf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", + strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum); + continue; + } + + // Copy message to its own buffer + CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); + vRecv.ignore(nMessageSize); + + // Process message + bool fRet = false; + try + { + { + LOCK(cs_main); + fRet = ProcessMessage(pfrom, strCommand, vMsg); + } + if (fShutdown) + return true; + } + catch (std::ios_base::failure& e) + { + if (strstr(e.what(), "end of data")) + { + // Allow exceptions from under-length message on vRecv + printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); + } + else if (strstr(e.what(), "size too large")) + { + // Allow exceptions from over-long size + printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what()); + } + else + { + PrintExceptionContinue(&e, "ProcessMessages()"); + } + } + catch (std::exception& e) { + PrintExceptionContinue(&e, "ProcessMessages()"); + } catch (...) { + PrintExceptionContinue(NULL, "ProcessMessages()"); + } + + if (!fRet) + printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize); + } + + vRecv.Compact(); + return true; +} + + +bool SendMessages(CNode* pto, bool fSendTrickle) +{ + TRY_LOCK(cs_main, lockMain); + if (lockMain) { + // Don't send anything until we get their version message + if (pto->nVersion == 0) + return true; + + // Keep-alive ping. We send a nonce of zero because we don't use it anywhere + // right now. + if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) { + uint64 nonce = 0; + if (pto->nVersion > BIP0031_VERSION) + pto->PushMessage("ping", nonce); + else + pto->PushMessage("ping"); + } + + // Resend wallet transactions that haven't gotten in a block yet + ResendWalletTransactions(); + + // Address refresh broadcast + static int64 nLastRebroadcast; + if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) + { + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + // Periodically clear setAddrKnown to allow refresh broadcasts + if (nLastRebroadcast) + pnode->setAddrKnown.clear(); + + // Rebroadcast our address + if (!fNoListen) + { + CAddress addr = GetLocalAddress(&pnode->addr); + if (addr.IsRoutable()) + pnode->PushAddress(addr); + } + } + } + nLastRebroadcast = GetTime(); + } + + // + // Message: addr + // + if (fSendTrickle) + { + vector vAddr; + vAddr.reserve(pto->vAddrToSend.size()); + BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) + { + // returns true if wasn't already contained in the set + if (pto->setAddrKnown.insert(addr).second) + { + vAddr.push_back(addr); + // receiver rejects addr messages larger than 1000 + if (vAddr.size() >= 1000) + { + pto->PushMessage("addr", vAddr); + vAddr.clear(); + } + } + } + pto->vAddrToSend.clear(); + if (!vAddr.empty()) + pto->PushMessage("addr", vAddr); + } + + + // + // Message: inventory + // + vector vInv; + vector vInvWait; + { + LOCK(pto->cs_inventory); + vInv.reserve(pto->vInventoryToSend.size()); + vInvWait.reserve(pto->vInventoryToSend.size()); + BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) + { + if (pto->setInventoryKnown.count(inv)) + continue; + + // trickle out tx inv to protect privacy + if (inv.type == MSG_TX && !fSendTrickle) + { + // 1/4 of tx invs blast to all immediately + static uint256 hashSalt; + if (hashSalt == 0) + hashSalt = GetRandHash(); + uint256 hashRand = inv.hash ^ hashSalt; + hashRand = Hash(BEGIN(hashRand), END(hashRand)); + bool fTrickleWait = ((hashRand & 3) != 0); + + // always trickle our own transactions + if (!fTrickleWait) + { + CWalletTx wtx; + if (GetTransaction(inv.hash, wtx)) + if (wtx.fFromMe) + fTrickleWait = true; + } + + if (fTrickleWait) + { + vInvWait.push_back(inv); + continue; + } + } + + // returns true if wasn't already contained in the set + if (pto->setInventoryKnown.insert(inv).second) + { + vInv.push_back(inv); + if (vInv.size() >= 1000) + { + pto->PushMessage("inv", vInv); + vInv.clear(); + } + } + } + pto->vInventoryToSend = vInvWait; + } + if (!vInv.empty()) + pto->PushMessage("inv", vInv); + + + // + // Message: getdata + // + vector vGetData; + int64 nNow = GetTime() * 1000000; + CTxDB txdb("r"); + while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) + { + const CInv& inv = (*pto->mapAskFor.begin()).second; + if (!AlreadyHave(txdb, inv)) + { + if (fDebugNet) + printf("sending getdata: %s\n", inv.ToString().c_str()); + vGetData.push_back(inv); + if (vGetData.size() >= 1000) + { + pto->PushMessage("getdata", vGetData); + vGetData.clear(); + } + mapAlreadyAskedFor[inv] = nNow; + } + pto->mapAskFor.erase(pto->mapAskFor.begin()); + } + if (!vGetData.empty()) + pto->PushMessage("getdata", vGetData); + + } + return true; +} + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// BitcoinMiner +// + +int static FormatHashBlocks(void* pbuffer, unsigned int len) +{ + unsigned char* pdata = (unsigned char*)pbuffer; + unsigned int blocks = 1 + ((len + 8) / 64); + unsigned char* pend = pdata + 64 * blocks; + memset(pdata + len, 0, 64 * blocks - len); + pdata[len] = 0x80; + unsigned int bits = len * 8; + pend[-1] = (bits >> 0) & 0xff; + pend[-2] = (bits >> 8) & 0xff; + pend[-3] = (bits >> 16) & 0xff; + pend[-4] = (bits >> 24) & 0xff; + return blocks; +} + +static const unsigned int pSHA256InitState[8] = +{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + +void SHA256Transform(void* pstate, void* pinput, const void* pinit) +{ + SHA256_CTX ctx; + unsigned char data[64]; + + SHA256_Init(&ctx); + + for (int i = 0; i < 16; i++) + ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]); + + for (int i = 0; i < 8; i++) + ctx.h[i] = ((uint32_t*)pinit)[i]; + + SHA256_Update(&ctx, data, sizeof(data)); + for (int i = 0; i < 8; i++) + ((uint32_t*)pstate)[i] = ctx.h[i]; +} + +// Some explaining would be appreciated +class COrphan +{ +public: + CTransaction* ptx; + set setDependsOn; + double dPriority; + double dFeePerKb; + + COrphan(CTransaction* ptxIn) + { + ptx = ptxIn; + dPriority = dFeePerKb = 0; + } + + void print() const + { + printf("COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f)\n", + ptx->GetHash().ToString().substr(0,10).c_str(), dPriority, dFeePerKb); + BOOST_FOREACH(uint256 hash, setDependsOn) + printf(" setDependsOn %s\n", hash.ToString().substr(0,10).c_str()); + } +}; + + +uint64 nLastBlockTx = 0; +uint64 nLastBlockSize = 0; +int64 nLastCoinStakeSearchInterval = 0; + +// We want to sort transactions by priority and fee, so: +typedef boost::tuple TxPriority; +class TxPriorityCompare +{ + bool byFee; +public: + TxPriorityCompare(bool _byFee) : byFee(_byFee) { } + bool operator()(const TxPriority& a, const TxPriority& b) + { + if (byFee) + { + if (a.get<1>() == b.get<1>()) + return a.get<0>() < b.get<0>(); + return a.get<1>() < b.get<1>(); + } + else + { + if (a.get<0>() == b.get<0>()) + return a.get<1>() < b.get<1>(); + return a.get<0>() < b.get<0>(); + } + } +}; + +// CreateNewBlock: +// fProofOfStake: try (best effort) to make a proof-of-stake block +CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) +{ + CReserveKey reservekey(pwallet); + + // Create new block + auto_ptr pblock(new CBlock()); + if (!pblock.get()) + return NULL; + + // Create coinbase tx + CTransaction txNew; + txNew.vin.resize(1); + txNew.vin[0].prevout.SetNull(); + txNew.vout.resize(1); + txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; + + // Add our coinbase tx as first transaction + pblock->vtx.push_back(txNew); + + // Largest block you're willing to create: + unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE_GEN/2); + // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: + nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); + + // How much of the block should be dedicated to high-priority transactions, + // included regardless of the fees they pay + unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", 27000); + nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); + + // Minimum block size you want to create; block will be filled with free transactions + // until there are no more or the block reaches this size: + unsigned int nBlockMinSize = GetArg("-blockminsize", 0); + nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); + + // Fee-per-kilobyte amount considered the same as "free" + // Be careful setting this: if you set it to zero then + // a transaction spammer can cheaply fill blocks using + // 1-satoshi-fee transactions. It should be set above the real + // cost to you of processing a transaction. + int64 nMinTxFee = MIN_TX_FEE; + if (mapArgs.count("-mintxfee")) + ParseMoney(mapArgs["-mintxfee"], nMinTxFee); + + // ppcoin: if coinstake available add coinstake tx + static int64 nLastCoinStakeSearchTime = GetAdjustedTime(); // only initialized at startup + CBlockIndex* pindexPrev = pindexBest; + + if (fProofOfStake) // attempt to find a coinstake + { + pblock->nBits = GetNextTargetRequired(pindexPrev, true); + CTransaction txCoinStake; + int64 nSearchTime = txCoinStake.nTime; // search to current time + if (nSearchTime > nLastCoinStakeSearchTime) + { + // printf(">>> OK1\n"); + if (pwallet->CreateCoinStake(*pwallet, pblock->nBits, nSearchTime-nLastCoinStakeSearchTime, txCoinStake)) + { + if (txCoinStake.nTime >= max(pindexPrev->GetMedianTimePast()+1, pindexPrev->GetBlockTime() - nMaxClockDrift)) + { // make sure coinstake would meet timestamp protocol + // as it would be the same as the block timestamp + pblock->vtx[0].vout[0].SetEmpty(); + pblock->vtx[0].nTime = txCoinStake.nTime; + pblock->vtx.push_back(txCoinStake); + } + } + nLastCoinStakeSearchInterval = nSearchTime - nLastCoinStakeSearchTime; + nLastCoinStakeSearchTime = nSearchTime; + } + } + + pblock->nBits = GetNextTargetRequired(pindexPrev, pblock->IsProofOfStake()); + + // Collect memory pool transactions into the block + int64 nFees = 0; + { + LOCK2(cs_main, mempool.cs); + CBlockIndex* pindexPrev = pindexBest; + CTxDB txdb("r"); + + // Priority order to process transactions + list vOrphan; // list memory doesn't move + map > mapDependers; + + // This vector will be sorted into a priority queue: + vector vecPriority; + vecPriority.reserve(mempool.mapTx.size()); + for (map::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) + { + CTransaction& tx = (*mi).second; + if (tx.IsCoinBase() || tx.IsCoinStake() || !tx.IsFinal()) + continue; + + COrphan* porphan = NULL; + double dPriority = 0; + int64 nTotalIn = 0; + bool fMissingInputs = false; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + // Read prev transaction + CTransaction txPrev; + CTxIndex txindex; + if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) + { + // This should never happen; all transactions in the memory + // pool should connect to either transactions in the chain + // or other transactions in the memory pool. + if (!mempool.mapTx.count(txin.prevout.hash)) + { + printf("ERROR: mempool transaction missing input\n"); + if (fDebug) assert("mempool transaction missing input" == 0); + fMissingInputs = true; + if (porphan) + vOrphan.pop_back(); + break; + } + + // Has to wait for dependencies + if (!porphan) + { + // Use list for automatic deletion + vOrphan.push_back(COrphan(&tx)); + porphan = &vOrphan.back(); + } + mapDependers[txin.prevout.hash].push_back(porphan); + porphan->setDependsOn.insert(txin.prevout.hash); + nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue; + continue; + } + int64 nValueIn = txPrev.vout[txin.prevout.n].nValue; + nTotalIn += nValueIn; + + int nConf = txindex.GetDepthInMainChain(); + dPriority += (double)nValueIn * nConf; + } + if (fMissingInputs) continue; + + // Priority is sum(valuein * age) / txsize + unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + dPriority /= nTxSize; + + // This is a more accurate fee-per-kilobyte than is used by the client code, because the + // client code rounds up the size to the nearest 1K. That's good, because it gives an + // incentive to create smaller transactions. + double dFeePerKb = double(nTotalIn-tx.GetValueOut()) / (double(nTxSize)/1000.0); + + if (porphan) + { + porphan->dPriority = dPriority; + porphan->dFeePerKb = dFeePerKb; + } + else + vecPriority.push_back(TxPriority(dPriority, dFeePerKb, &(*mi).second)); + } + + // Collect transactions into block + map mapTestPool; + uint64 nBlockSize = 1000; + uint64 nBlockTx = 0; + int nBlockSigOps = 100; + bool fSortedByFee = (nBlockPrioritySize <= 0); + + TxPriorityCompare comparer(fSortedByFee); + std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); + + while (!vecPriority.empty()) + { + // Take highest priority transaction off the priority queue: + double dPriority = vecPriority.front().get<0>(); + double dFeePerKb = vecPriority.front().get<1>(); + CTransaction& tx = *(vecPriority.front().get<2>()); + + std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); + vecPriority.pop_back(); + + // Size limits + unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + if (nBlockSize + nTxSize >= nBlockMaxSize) + continue; + + // Legacy limits on sigOps: + unsigned int nTxSigOps = tx.GetLegacySigOpCount(); + if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) + continue; + + // Timestamp limit + if (tx.nTime > GetAdjustedTime() || (pblock->IsProofOfStake() && tx.nTime > pblock->vtx[1].nTime)) + continue; + + // ppcoin: simplify transaction fee - allow free = false + int64 nMinFee = tx.GetMinFee(nBlockSize, false, GMF_BLOCK); + + // Skip free transactions if we're past the minimum block size: + if (fSortedByFee && (dFeePerKb < nMinTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) + continue; + + // Prioritize by fee once past the priority size or we run out of high-priority + // transactions: + if (!fSortedByFee && + ((nBlockSize + nTxSize >= nBlockPrioritySize) || (dPriority < COIN * 144 / 250))) + { + fSortedByFee = true; + comparer = TxPriorityCompare(fSortedByFee); + std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); + } + + // Connecting shouldn't fail due to dependency on other memory pool transactions + // because we're already processing them in order of dependency + map mapTestPoolTmp(mapTestPool); + MapPrevTx mapInputs; + bool fInvalid; + if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid)) + continue; + + int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut(); + if (nTxFees < nMinFee) + continue; + + nTxSigOps += tx.GetP2SHSigOpCount(mapInputs); + if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) + continue; + + if (!tx.ConnectInputs(txdb, mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true)) + continue; + mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size()); + swap(mapTestPool, mapTestPoolTmp); + + // Added + pblock->vtx.push_back(tx); + nBlockSize += nTxSize; + ++nBlockTx; + nBlockSigOps += nTxSigOps; + nFees += nTxFees; + + if (fDebug && GetBoolArg("-printpriority")) + { + printf("priority %.1f feeperkb %.1f txid %s\n", + dPriority, dFeePerKb, tx.GetHash().ToString().c_str()); + } + + // Add transactions that depend on this one to the priority queue + uint256 hash = tx.GetHash(); + if (mapDependers.count(hash)) + { + BOOST_FOREACH(COrphan* porphan, mapDependers[hash]) + { + if (!porphan->setDependsOn.empty()) + { + porphan->setDependsOn.erase(hash); + if (porphan->setDependsOn.empty()) + { + vecPriority.push_back(TxPriority(porphan->dPriority, porphan->dFeePerKb, porphan->ptx)); + std::push_heap(vecPriority.begin(), vecPriority.end(), comparer); + } + } + } + } + } + + nLastBlockTx = nBlockTx; + nLastBlockSize = nBlockSize; + + if (fDebug && GetBoolArg("-printpriority")) + printf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize); + + if (pblock->IsProofOfWork()) + pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pindexPrev->nHeight+1, nFees, pindexPrev->GetBlockHash()); + + // Fill in header + pblock->hashPrevBlock = pindexPrev->GetBlockHash(); + if (pblock->IsProofOfStake()) + pblock->nTime = pblock->vtx[1].nTime; //same as coinstake timestamp + pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, pblock->GetMaxTransactionTime()); + pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift); + if (pblock->IsProofOfWork()) + pblock->UpdateTime(pindexPrev); + pblock->nNonce = 0; + } + + return pblock.release(); +} + + +void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) +{ + // Update nExtraNonce + static uint256 hashPrevBlock; + if (hashPrevBlock != pblock->hashPrevBlock) + { + nExtraNonce = 0; + hashPrevBlock = pblock->hashPrevBlock; + } + ++nExtraNonce; + unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2 + pblock->vtx[0].vin[0].scriptSig = (CScript() << nHeight << CBigNum(nExtraNonce)) + COINBASE_FLAGS; + assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100); + + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); +} + + +void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1) +{ + // + // Pre-build hash buffers + // + struct + { + struct unnamed2 + { + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + } + block; + unsigned char pchPadding0[64]; + uint256 hash1; + unsigned char pchPadding1[64]; + } + tmp; + memset(&tmp, 0, sizeof(tmp)); + + tmp.block.nVersion = pblock->nVersion; + tmp.block.hashPrevBlock = pblock->hashPrevBlock; + tmp.block.hashMerkleRoot = pblock->hashMerkleRoot; + tmp.block.nTime = pblock->nTime; + tmp.block.nBits = pblock->nBits; + tmp.block.nNonce = pblock->nNonce; + + FormatHashBlocks(&tmp.block, sizeof(tmp.block)); + FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); + + // Byte swap all the input buffer + for (unsigned int i = 0; i < sizeof(tmp)/4; i++) + ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]); + + // Precalc the first half of the first hash, which stays constant + SHA256Transform(pmidstate, &tmp.block, pSHA256InitState); + + memcpy(pdata, &tmp.block, 128); + memcpy(phash1, &tmp.hash1, 64); +} + + +bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) +{ + uint256 hash = pblock->GetHash(); + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + if (hash > hashTarget && pblock->IsProofOfWork()) + return error("BitcoinMiner : proof-of-work not meeting target"); + + //// debug print + printf("BitcoinMiner:\n"); + printf("new block found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + pblock->print(); + printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); + + // Found a solution + { + LOCK(cs_main); + if (pblock->hashPrevBlock != hashBestChain) + return error("BitcoinMiner : generated block is stale"); + + // Remove key from key pool + reservekey.KeepKey(); + + // Track how many getdata requests this block gets + { + LOCK(wallet.cs_wallet); + wallet.mapRequestCount[pblock->GetHash()] = 0; + } + + // Process this block the same as if we had received it from another node + if (!ProcessBlock(NULL, pblock)) + return error("BitcoinMiner : ProcessBlock, block not accepted"); + } + + return true; +} + +void static ThreadBitcoinMiner(void* parg); + +static bool fGenerateBitcoins = false; +static bool fLimitProcessors = false; +static int nLimitProcessors = -1; + +void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) +{ + printf("CPUMiner started for proof-of-%s\n", fProofOfStake? "stake" : "work"); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + + // Make this thread recognisable as the mining thread + RenameThread("bitcoin-miner"); + + // Each thread has its own key and counter + CReserveKey reservekey(pwallet); + unsigned int nExtraNonce = 0; + + while (fGenerateBitcoins || fProofOfStake) + { + if (fShutdown) + return; + + while (vNodes.empty() || IsInitialBlockDownload() || pwallet->IsLocked()) + { + nLastCoinStakeSearchInterval = 0; + Sleep(1000); + if (fShutdown) + return; + if (!fGenerateBitcoins && !fProofOfStake) + return; + } + + // + // Create new block + // + unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrev = pindexBest; + + auto_ptr pblock(CreateNewBlock(pwallet, fProofOfStake)); + if (!pblock.get()) + return; + IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce); + + if (fProofOfStake) + { + // ppcoin: if proof-of-stake block found then process block + if (pblock->IsProofOfStake()) + { + if (!pblock->SignBlock(*pwalletMain)) + continue; + printf("CPUMiner : proof-of-stake block found %s\n", pblock->GetHash().ToString().c_str()); + SetThreadPriority(THREAD_PRIORITY_NORMAL); + CheckWork(pblock.get(), *pwalletMain, reservekey); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + } + Sleep(250); + continue; + } + + printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(), + ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); + + // + // Pre-build hash buffers + // + //char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf); + //char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf); + //char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf); + + //FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1); + + //unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4); + //unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12); + + + // + // Search + // + int64 nStart = GetTime(); + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + uint256 hash; + + while (true) + { + hash = pblock->GetHash(); + if (hash <= hashTarget){ + // nHashesDone += pblock->nNonce; + if (!pblock->SignBlock(*pwalletMain)) + break; + + SetThreadPriority(THREAD_PRIORITY_NORMAL); + + printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + pblock->print(); + + CheckWork(pblock.get(), *pwalletMain, reservekey); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + break; + } + ++pblock->nNonce; + + + // Meter hashes/sec + static int64 nHashCounter; + if (nHPSTimerStart == 0) + { + nHPSTimerStart = GetTimeMillis(); + nHashCounter = 0; + } + else + nHashCounter += 1; + + if (GetTimeMillis() - nHPSTimerStart > 4000) + { + static CCriticalSection cs; + { + LOCK(cs); + if (GetTimeMillis() - nHPSTimerStart > 4000) + { + dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart); + nHPSTimerStart = GetTimeMillis(); + nHashCounter = 0; + + printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[THREAD_MINER], dHashesPerSec/1000.0); + + } + } + } + + // Check for stop or if block needs to be rebuilt + if (fShutdown) + return; + if (!fGenerateBitcoins) + return; + if (fLimitProcessors && vnThreadsRunning[THREAD_MINER] > nLimitProcessors) + return; + if (vNodes.empty()) + break; + if (++pblock->nNonce >= 0xffff0000) + break; + if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) + break; + if (pindexPrev != pindexBest) + break; + + // Update nTime every few seconds + pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, pblock->GetMaxTransactionTime()); + pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift); + pblock->UpdateTime(pindexPrev); + + if (pblock->GetBlockTime() >= (int64)pblock->vtx[0].nTime + nMaxClockDrift) + break; // need to update coinbase timestamp + } + } +} + +void static ThreadBitcoinMiner(void* parg) +{ + CWallet* pwallet = (CWallet*)parg; + try + { + vnThreadsRunning[THREAD_MINER]++; + BitcoinMiner(pwallet, false); + vnThreadsRunning[THREAD_MINER]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_MINER]--; + PrintException(&e, "ThreadBitcoinMiner()"); + } catch (...) { + vnThreadsRunning[THREAD_MINER]--; + PrintException(NULL, "ThreadBitcoinMiner()"); + } + nHPSTimerStart = 0; + if (vnThreadsRunning[THREAD_MINER] == 0) + dHashesPerSec = 0; + printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[THREAD_MINER]); +} + + +void GenerateBitcoins(bool fGenerate, CWallet* pwallet) +{ + fGenerateBitcoins = fGenerate; + nLimitProcessors = GetArg("-genproclimit", -1); + if (nLimitProcessors == 0) + fGenerateBitcoins = false; + fLimitProcessors = (nLimitProcessors != -1); + + if (fGenerate) + { + int nProcessors = boost::thread::hardware_concurrency(); + printf("%d processors\n", nProcessors); + if (nProcessors < 1) + nProcessors = 1; + if (fLimitProcessors && nProcessors > nLimitProcessors) + nProcessors = nLimitProcessors; + int nAddThreads = nProcessors - vnThreadsRunning[THREAD_MINER]; + printf("Starting %d BitcoinMiner threads\n", nAddThreads); + for (int i = 0; i < nAddThreads; i++) + { + if (!NewThread(ThreadBitcoinMiner, pwallet)) + printf("Error: NewThread(ThreadBitcoinMiner) failed\n"); + Sleep(10); + } + } +} diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..8bb6224 --- /dev/null +++ b/src/main.h @@ -0,0 +1,1608 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_MAIN_H +#define BITCOIN_MAIN_H + +#include "bignum.h" +#include "sync.h" +#include "net.h" +#include "script.h" +#include "scrypt.h" +#include "hashblock.h" + +#include + +class CWallet; +class CBlock; +class CBlockIndex; +class CKeyItem; +class CReserveKey; +class COutPoint; + +class CAddress; +class CInv; +class CRequestTracker; +class CNode; + +static const unsigned int MAX_BLOCK_SIZE = 10000000; +static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2; +static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; +static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100; +static const unsigned int MAX_INV_SZ = 50000; +static const int64 MIN_TX_FEE = 0.001 * CENT; +static const int64 MIN_RELAY_TX_FEE = 0 * CENT; +static const int64 MAX_MONEY = 100000000 * COIN; +static const int64 CIRCULATION_MONEY = MAX_MONEY; +static const double TAX_PERCENTAGE = 0.00; // no tax +static const int64 MAX_BERN_PROOF_OF_STAKE = 0.1 * COIN; // annual interest +static const int CUTOFF_POW_BLOCK = 6519080; + +static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; + +inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } +// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. +static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC + +#ifdef USE_UPNP +static const int fHaveUPnP = true; +#else +static const int fHaveUPnP = false; +#endif + +static const uint256 hashGenesisBlockOfficial("0x3a787ca8cd2114c31b9094d729e4d8485b23ce04e57b5528c18e98e31d17dead"); +static const uint256 hashGenesisBlockTestNet ("0x787cd5c72fe58e6eb86845ca45eee05c932310ed684a6a712382a4a1de031f89"); + +static const int64 nClockDriftSwitchHeight = 3000; +static const int64 nMaxClockDriftOrig = 2 * 60 * 60; +static const int64 nMaxClockDrift = 8 * 60; // 8 minutes + +inline int64 GetMaxClockDrift(int nHeight) { return nHeight > nClockDriftSwitchHeight ? nMaxClockDrift : nMaxClockDriftOrig; } + +extern CScript COINBASE_FLAGS; + + +extern CCriticalSection cs_main; +extern std::map mapBlockIndex; +extern std::set > setStakeSeen; +extern uint256 hashGenesisBlock; +extern CBlockIndex* pindexGenesisBlock; +extern unsigned int nStakeMinAge; +extern int nCoinbaseMaturity; +extern int nBestHeight; +extern CBigNum bnBestChainTrust; +extern CBigNum bnBestInvalidTrust; +extern uint256 hashBestChain; +extern CBlockIndex* pindexBest; +extern unsigned int nTransactionsUpdated; +extern uint64 nLastBlockTx; +extern uint64 nLastBlockSize; +extern int64 nLastCoinStakeSearchInterval; +extern const std::string strMessageMagic; +extern double dHashesPerSec; +extern int64 nHPSTimerStart; +extern int64 nTimeBestReceived; +extern CCriticalSection cs_setpwalletRegistered; +extern std::set setpwalletRegistered; +extern unsigned char pchMessageStart[4]; +extern std::map mapOrphanBlocks; + +// Settings +extern int64 nTransactionFee; + +// Minimum disk space required - used in CheckDiskSpace() +static const uint64 nMinDiskSpace = 52428800; + + +class CReserveKey; +class CTxDB; +class CTxIndex; + +void RegisterWallet(CWallet* pwalletIn); +void UnregisterWallet(CWallet* pwalletIn); +void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false, bool fConnect = true); +bool ProcessBlock(CNode* pfrom, CBlock* pblock); +bool CheckDiskSpace(uint64 nAdditionalBytes=0); +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); +FILE* AppendBlockFile(unsigned int& nFileRet); +bool LoadBlockIndex(bool fAllowNew=true); +void PrintBlockTree(); +CBlockIndex* FindBlockByHeight(int nHeight); +bool ProcessMessages(CNode* pfrom); +bool SendMessages(CNode* pto, bool fSendTrickle); +bool LoadExternalBlockFile(FILE* fileIn); +void GenerateBitcoins(bool fGenerate, CWallet* pwallet); +CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake=false); +void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); +void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); +bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); +bool CheckProofOfWork(uint256 hash, unsigned int nBits); +int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash); +int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight); +unsigned int ComputeMinWork(unsigned int nBase, int64 nTime); +unsigned int ComputeMinStake(unsigned int nBase, int64 nTime, unsigned int nBlockTime); +int GetNumBlocksOfPeers(); +bool IsInitialBlockDownload(); +std::string GetWarnings(std::string strFor); +bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock); +uint256 WantedByOrphan(const CBlock* pblockOrphan); +const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfStake); +void BitcoinMiner(CWallet *pwallet, bool fProofOfStake); +void ResendWalletTransactions(); + + + + + + + + + + +bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); + +/** Position on disk for a particular transaction. */ +class CDiskTxPos +{ +public: + unsigned int nFile; + unsigned int nBlockPos; + unsigned int nTxPos; + + CDiskTxPos() + { + SetNull(); + } + + CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn) + { + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nTxPos = nTxPosIn; + } + + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { nFile = (unsigned int) -1; nBlockPos = 0; nTxPos = 0; } + bool IsNull() const { return (nFile == (unsigned int) -1); } + + friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b) + { + return (a.nFile == b.nFile && + a.nBlockPos == b.nBlockPos && + a.nTxPos == b.nTxPos); + } + + friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b) + { + return !(a == b); + } + + + std::string ToString() const + { + if (IsNull()) + return "null"; + else + return strprintf("(nFile=%u, nBlockPos=%u, nTxPos=%u)", nFile, nBlockPos, nTxPos); + } + + void print() const + { + printf("%s", ToString().c_str()); + } +}; + + + +/** An inpoint - a combination of a transaction and an index n into its vin */ +class CInPoint +{ +public: + CTransaction* ptx; + unsigned int n; + + CInPoint() { SetNull(); } + CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; } + void SetNull() { ptx = NULL; n = (unsigned int) -1; } + bool IsNull() const { return (ptx == NULL && n == (unsigned int) -1); } +}; + + + +/** An outpoint - a combination of a transaction hash and an index n into its vout */ +class COutPoint +{ +public: + uint256 hash; + unsigned int n; + + COutPoint() { SetNull(); } + COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; } + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { hash = 0; n = (unsigned int) -1; } + bool IsNull() const { return (hash == 0 && n == (unsigned int) -1); } + + friend bool operator<(const COutPoint& a, const COutPoint& b) + { + return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); + } + + friend bool operator==(const COutPoint& a, const COutPoint& b) + { + return (a.hash == b.hash && a.n == b.n); + } + + friend bool operator!=(const COutPoint& a, const COutPoint& b) + { + return !(a == b); + } + + std::string ToString() const + { + return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10).c_str(), n); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +/** An input of a transaction. It contains the location of the previous + * transaction's output that it claims and a signature that matches the + * output's public key. + */ +class CTxIn +{ +public: + COutPoint prevout; + CScript scriptSig; + unsigned int nSequence; + + CTxIn() + { + nSequence = std::numeric_limits::max(); + } + + explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits::max()) + { + prevout = prevoutIn; + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits::max()) + { + prevout = COutPoint(hashPrevTx, nOut); + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(prevout); + READWRITE(scriptSig); + READWRITE(nSequence); + ) + + bool IsFinal() const + { + return (nSequence == std::numeric_limits::max()); + } + + friend bool operator==(const CTxIn& a, const CTxIn& b) + { + return (a.prevout == b.prevout && + a.scriptSig == b.scriptSig && + a.nSequence == b.nSequence); + } + + friend bool operator!=(const CTxIn& a, const CTxIn& b) + { + return !(a == b); + } + + std::string ToStringShort() const + { + return strprintf(" %s %d", prevout.hash.ToString().c_str(), prevout.n); + } + + std::string ToString() const + { + std::string str; + str += "CTxIn("; + str += prevout.ToString(); + if (prevout.IsNull()) + str += strprintf(", coinbase %s", HexStr(scriptSig).c_str()); + else + str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str()); + if (nSequence != std::numeric_limits::max()) + str += strprintf(", nSequence=%u", nSequence); + str += ")"; + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +/** An output of a transaction. It contains the public key that the next input + * must be able to sign with to claim it. + */ +class CTxOut +{ +public: + int64 nValue; + CScript scriptPubKey; + + CTxOut() + { + SetNull(); + } + + CTxOut(int64 nValueIn, CScript scriptPubKeyIn) + { + nValue = nValueIn; + scriptPubKey = scriptPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(nValue); + READWRITE(scriptPubKey); + ) + + void SetNull() + { + nValue = -1; + scriptPubKey.clear(); + } + + bool IsNull() + { + return (nValue == -1); + } + + void SetEmpty() + { + nValue = 0; + scriptPubKey.clear(); + } + + bool IsEmpty() const + { + return (nValue == 0 && scriptPubKey.empty()); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + friend bool operator==(const CTxOut& a, const CTxOut& b) + { + return (a.nValue == b.nValue && + a.scriptPubKey == b.scriptPubKey); + } + + friend bool operator!=(const CTxOut& a, const CTxOut& b) + { + return !(a == b); + } + + std::string ToStringShort() const + { + return strprintf(" out %s %s", FormatMoney(nValue).c_str(), scriptPubKey.ToString(true).c_str()); + } + + std::string ToString() const + { + if (IsEmpty()) return "CTxOut(empty)"; + if (scriptPubKey.size() < 6) + return "CTxOut(error)"; + return strprintf("CTxOut(nValue=%s, scriptPubKey=%s)", FormatMoney(nValue).c_str(), scriptPubKey.ToString().c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +enum GetMinFee_mode +{ + GMF_BLOCK, + GMF_RELAY, + GMF_SEND, +}; + +typedef std::map > MapPrevTx; + +/** The basic transaction that is broadcasted on the network and contained in + * blocks. A transaction can contain multiple inputs and outputs. + */ +class CTransaction +{ +public: + static const int CURRENT_VERSION=1; + + int nVersion; + unsigned int nTime; + std::vector vin; + std::vector vout; + unsigned int nLockTime; + + // Denial-of-service detection: + mutable int nDoS; + bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } + + CTransaction() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(nTime); + READWRITE(vin); + READWRITE(vout); + READWRITE(nLockTime); + ) + + void SetNull() + { + nVersion = CTransaction::CURRENT_VERSION; + nTime = GetAdjustedTime(); + vin.clear(); + vout.clear(); + nLockTime = 0; + nDoS = 0; // Denial-of-service prevention + } + + bool IsNull() const + { + return (vin.empty() && vout.empty()); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const + { + // Time based nLockTime implemented in 0.1.6 + if (nLockTime == 0) + return true; + if (nBlockHeight == 0) + nBlockHeight = nBestHeight; + if (nBlockTime == 0) + nBlockTime = GetAdjustedTime(); + if ((int64)nLockTime < ((int64)nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime)) + return true; + BOOST_FOREACH(const CTxIn& txin, vin) + if (!txin.IsFinal()) + return false; + return true; + } + + bool IsNewerThan(const CTransaction& old) const + { + if (vin.size() != old.vin.size()) + return false; + for (unsigned int i = 0; i < vin.size(); i++) + if (vin[i].prevout != old.vin[i].prevout) + return false; + + bool fNewer = false; + unsigned int nLowest = std::numeric_limits::max(); + for (unsigned int i = 0; i < vin.size(); i++) + { + if (vin[i].nSequence != old.vin[i].nSequence) + { + if (vin[i].nSequence <= nLowest) + { + fNewer = false; + nLowest = vin[i].nSequence; + } + if (old.vin[i].nSequence < nLowest) + { + fNewer = true; + nLowest = old.vin[i].nSequence; + } + } + } + return fNewer; + } + + bool IsCoinBase() const + { + return (vin.size() == 1 && vin[0].prevout.IsNull() && vout.size() >= 1); + } + + bool IsCoinStake() const + { + // ppcoin: the coin stake transaction is marked with the first output empty + return (vin.size() > 0 && (!vin[0].prevout.IsNull()) && vout.size() >= 2 && vout[0].IsEmpty()); + } + + bool IsCoinBaseOrStake() const + { + return (IsCoinBase() || IsCoinStake()); + } + + + /** Check for standard transaction types + @return True if all outputs (scriptPubKeys) use only standard transaction forms + */ + bool IsStandard() const; + + /** Check for standard transaction types + @param[in] mapInputs Map of previous transactions that have outputs we're spending + @return True if all inputs (scriptSigs) use only standard transaction forms + @see CTransaction::FetchInputs + */ + bool AreInputsStandard(const MapPrevTx& mapInputs) const; + + /** Count ECDSA signature operations the old-fashioned (pre-0.6) way + @return number of sigops this transaction's outputs will produce when spent + @see CTransaction::FetchInputs + */ + unsigned int GetLegacySigOpCount() const; + + /** Count ECDSA signature operations in pay-to-script-hash inputs. + + @param[in] mapInputs Map of previous transactions that have outputs we're spending + @return maximum number of sigops required to validate this transaction's inputs + @see CTransaction::FetchInputs + */ + unsigned int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const; + + /** Amount of bitcoins spent by this transaction. + @return sum of all outputs (note: does not include fees) + */ + int64 GetValueOut() const + { + int64 nValueOut = 0; + BOOST_FOREACH(const CTxOut& txout, vout) + { + nValueOut += txout.nValue; + if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut)) + throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); + } + return nValueOut; + } + + /** Amount of bitcoins coming in to this 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] mapInputs Map of previous transactions that have outputs we're spending + @return Sum of value of all inputs (scriptSigs) + @see CTransaction::FetchInputs + */ + int64 GetValueIn(const MapPrevTx& mapInputs) const; + + static bool AllowFree(double dPriority) + { + // Large (in bytes) low-priority (new, small-coin) transactions + // need a fee. + return dPriority > COIN * 2880 / 250; + } + + int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=false, enum GetMinFee_mode mode=GMF_BLOCK, unsigned int nBytes = 0) const; + + bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) + { + CAutoFile filein = CAutoFile(OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"), SER_DISK, CLIENT_VERSION); + if (!filein) + return error("CTransaction::ReadFromDisk() : OpenBlockFile failed"); + + // Read transaction + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : fseek failed"); + + try { + filein >> *this; + } + catch (std::exception &e) { + return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); + } + + // Return file pointer + if (pfileRet) + { + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : second fseek failed"); + *pfileRet = filein.release(); + } + return true; + } + + friend bool operator==(const CTransaction& a, const CTransaction& b) + { + return (a.nVersion == b.nVersion && + a.nTime == b.nTime && + a.vin == b.vin && + a.vout == b.vout && + a.nLockTime == b.nLockTime); + } + + friend bool operator!=(const CTransaction& a, const CTransaction& b) + { + return !(a == b); + } + + std::string ToStringShort() const + { + std::string str; + str += strprintf("%s %s", GetHash().ToString().c_str(), IsCoinBase()? "base" : (IsCoinStake()? "stake" : "user")); + return str; + } + + std::string ToString() const + { + std::string str; + str += IsCoinBase()? "Coinbase" : (IsCoinStake()? "Coinstake" : "CTransaction"); + str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%"PRIszu", vout.size=%"PRIszu", nLockTime=%d)\n", + GetHash().ToString().substr(0,10).c_str(), + nTime, + nVersion, + vin.size(), + vout.size(), + nLockTime + ); + + for (unsigned int i = 0; i < vin.size(); i++) + str += " " + vin[i].ToString() + "\n"; + for (unsigned int i = 0; i < vout.size(); i++) + str += " " + vout[i].ToString() + "\n"; + return str; + } + + void print() const + { + printf("%s", ToString().c_str()); + } + + + bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet); + bool ReadFromDisk(CTxDB& txdb, COutPoint prevout); + bool ReadFromDisk(COutPoint prevout); + bool DisconnectInputs(CTxDB& txdb); + + /** Fetch from memory and/or disk. inputsRet keys are transaction hashes. + + @param[in] txdb Transaction database + @param[in] mapTestPool List of pending changes to the transaction index database + @param[in] fBlock True if being called to add a new best-block to the chain + @param[in] fMiner True if being called by CreateNewBlock + @param[out] inputsRet Pointers to this transaction's inputs + @param[out] fInvalid returns true if transaction is invalid + @return Returns true if all inputs are in txdb or mapTestPool + */ + bool FetchInputs(CTxDB& txdb, const std::map& mapTestPool, + bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid); + + /** Sanity check previous transactions, then, if all checks succeed, + mark them as spent by this transaction. + + @param[in] inputs Previous transactions (from FetchInputs) + @param[out] mapTestPool Keeps track of inputs that need to be updated on disk + @param[in] posThisTx Position of this transaction on disk + @param[in] pindexBlock + @param[in] fBlock true if called from ConnectBlock + @param[in] fMiner true if called from CreateNewBlock + @param[in] fStrictPayToScriptHash true if fully validating p2sh transactions + @return Returns true if all checks succeed + */ + bool ConnectInputs(CTxDB& txdb, MapPrevTx inputs, + std::map& mapTestPool, const CDiskTxPos& posThisTx, + const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true); + bool ClientConnectInputs(); + bool CheckTransaction() const; + bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); + bool GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const; // ppcoin: get transaction coin age + +protected: + const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const; +}; + + + + + +/** A transaction with a merkle branch linking it to the block chain. */ +class CMerkleTx : public CTransaction +{ +public: + uint256 hashBlock; + std::vector vMerkleBranch; + int nIndex; + + // memory only + mutable bool fMerkleVerified; + + + CMerkleTx() + { + Init(); + } + + CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) + { + Init(); + } + + void Init() + { + hashBlock = 0; + nIndex = -1; + fMerkleVerified = false; + } + + + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(hashBlock); + READWRITE(vMerkleBranch); + READWRITE(nIndex); + ) + + + int SetMerkleBranch(const CBlock* pblock=NULL); + int GetDepthInMainChain(CBlockIndex* &pindexRet) const; + int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } + bool IsInMainChain() const { return GetDepthInMainChain() > 0; } + int GetBlocksToMaturity() const; + bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptToMemoryPool(); +}; + + + + +/** A txdb record that contains the disk location of a transaction and the + * locations of transactions that spend its outputs. vSpent is really only + * used as a flag, but having the location is very helpful for debugging. + */ +class CTxIndex +{ +public: + CDiskTxPos pos; + std::vector vSpent; + + CTxIndex() + { + SetNull(); + } + + CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs) + { + pos = posIn; + vSpent.resize(nOutputs); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(pos); + READWRITE(vSpent); + ) + + void SetNull() + { + pos.SetNull(); + vSpent.clear(); + } + + bool IsNull() + { + return pos.IsNull(); + } + + friend bool operator==(const CTxIndex& a, const CTxIndex& b) + { + return (a.pos == b.pos && + a.vSpent == b.vSpent); + } + + friend bool operator!=(const CTxIndex& a, const CTxIndex& b) + { + return !(a == b); + } + int GetDepthInMainChain() const; + +}; + + + + + +/** Nodes collect new transactions into a block, hash them into a hash tree, + * and scan through nonce values to make the block's hash satisfy proof-of-work + * requirements. When they solve the proof-of-work, they broadcast the block + * to everyone and the block is added to the block chain. The first transaction + * in the block is a special one that creates a new coin owned by the creator + * of the block. + * + * Blocks are appended to blk0001.dat files on disk. Their location on disk + * is indexed by CBlockIndex objects in memory. + */ +class CBlock +{ +public: + // header + static const int CURRENT_VERSION=4; + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + // network and disk + std::vector vtx; + + // ppcoin: block signature - signed by one of the coin base txout[N]'s owner + std::vector vchBlockSig; + + // memory only + mutable std::vector vMerkleTree; + + // Denial-of-service detection: + mutable int nDoS; + bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } + + CBlock() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(hashPrevBlock); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + + // ConnectBlock depends on vtx following header to generate CDiskTxPos + if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) + { + READWRITE(vtx); + READWRITE(vchBlockSig); + } + else if (fRead) + { + const_cast(this)->vtx.clear(); + const_cast(this)->vchBlockSig.clear(); + } + ) + + void SetNull() + { + nVersion = CBlock::CURRENT_VERSION; + hashPrevBlock = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + vtx.clear(); + vchBlockSig.clear(); + vMerkleTree.clear(); + nDoS = 0; + } + + bool IsNull() const + { + return (nBits == 0); + } + + uint256 GetHash() const + { + return Hash9(BEGIN(nVersion), END(nNonce)); + } + + int64 GetBlockTime() const + { + return (int64)nTime; + } + + void UpdateTime(const CBlockIndex* pindexPrev); + + // ppcoin: entropy bit for stake modifier if chosen by modifier + unsigned int GetStakeEntropyBit(unsigned int nHeight) const + { + // Take last bit of block hash as entropy bit + unsigned int nEntropyBit = ((GetHash().Get64()) & 1llu); + if (fDebug && GetBoolArg("-printstakemodifier")) + printf("GetStakeEntropyBit: nHeight=%u hashBlock=%s nEntropyBit=%u\n", nHeight, GetHash().ToString().c_str(), nEntropyBit); + return nEntropyBit; + } + + // ppcoin: two types of block: proof-of-work or proof-of-stake + bool IsProofOfStake() const + { + return (vtx.size() > 1 && vtx[1].IsCoinStake()); + } + + bool IsProofOfWork() const + { + return !IsProofOfStake(); + } + + std::pair GetProofOfStake() const + { + return IsProofOfStake()? std::make_pair(vtx[1].vin[0].prevout, vtx[1].nTime) : std::make_pair(COutPoint(), (unsigned int)0); + } + + // ppcoin: get max transaction timestamp + int64 GetMaxTransactionTime() const + { + int64 maxTransactionTime = 0; + BOOST_FOREACH(const CTransaction& tx, vtx) + maxTransactionTime = std::max(maxTransactionTime, (int64)tx.nTime); + return maxTransactionTime; + } + + uint256 BuildMerkleTree() const + { + vMerkleTree.clear(); + BOOST_FOREACH(const CTransaction& tx, vtx) + vMerkleTree.push_back(tx.GetHash()); + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + for (int i = 0; i < nSize; i += 2) + { + int i2 = std::min(i+1, nSize-1); + vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), + BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); + } + j += nSize; + } + return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); + } + + std::vector GetMerkleBranch(int nIndex) const + { + if (vMerkleTree.empty()) + BuildMerkleTree(); + std::vector vMerkleBranch; + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + int i = std::min(nIndex^1, nSize-1); + vMerkleBranch.push_back(vMerkleTree[j+i]); + nIndex >>= 1; + j += nSize; + } + return vMerkleBranch; + } + + static uint256 CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, int nIndex) + { + if (nIndex == -1) + return 0; + BOOST_FOREACH(const uint256& otherside, vMerkleBranch) + { + if (nIndex & 1) + hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); + else + hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); + nIndex >>= 1; + } + return hash; + } + + + bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet) + { + // Open history file to append + CAutoFile fileout = CAutoFile(AppendBlockFile(nFileRet), SER_DISK, CLIENT_VERSION); + if (!fileout) + return error("CBlock::WriteToDisk() : AppendBlockFile failed"); + + // Write index header + unsigned int nSize = fileout.GetSerializeSize(*this); + fileout << FLATDATA(pchMessageStart) << nSize; + + // Write block + long fileOutPos = ftell(fileout); + if (fileOutPos < 0) + return error("CBlock::WriteToDisk() : ftell failed"); + nBlockPosRet = fileOutPos; + fileout << *this; + + // Flush stdio buffers and commit to disk before returning + fflush(fileout); + if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0) + FileCommit(fileout); + + return true; + } + + bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true) + { + SetNull(); + + // Open history file to read + CAutoFile filein = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb"), SER_DISK, CLIENT_VERSION); + if (!filein) + return error("CBlock::ReadFromDisk() : OpenBlockFile failed"); + if (!fReadTransactions) + filein.nType |= SER_BLOCKHEADERONLY; + + // Read block + try { + filein >> *this; + } + catch (std::exception &e) { + return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); + } + + // Check the header + if (fReadTransactions && IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits)) + return error("CBlock::ReadFromDisk() : errors in block header"); + + return true; + } + + + + void print() const + { + printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%"PRIszu", vchBlockSig=%s)\n", + GetHash().ToString().c_str(), + nVersion, + hashPrevBlock.ToString().c_str(), + hashMerkleRoot.ToString().c_str(), + nTime, nBits, nNonce, + vtx.size(), + HexStr(vchBlockSig.begin(), vchBlockSig.end()).c_str()); + for (unsigned int i = 0; i < vtx.size(); i++) + { + printf(" "); + vtx[i].print(); + } + printf(" vMerkleTree: "); + for (unsigned int i = 0; i < vMerkleTree.size(); i++) + printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str()); + printf("\n"); + } + + + bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); + bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck=false); + bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true); + bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew); + bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); + bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true) const; + bool AcceptBlock(); + bool GetCoinAge(uint64& nCoinAge) const; // ppcoin: calculate total coin age spent in block + bool SignBlock(const CKeyStore& keystore); + bool CheckBlockSignature() const; + +private: + bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew); +}; + + + + + + +/** 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. pprev and pnext link a path through the + * main/longest chain. A blockindex may have multiple pprev pointing back + * to it, but pnext will only point forward to the longest branch, or will + * be null if the block is not part of the longest chain. + */ +class CBlockIndex +{ +public: + const uint256* phashBlock; + CBlockIndex* pprev; + CBlockIndex* pnext; + unsigned int nFile; + unsigned int nBlockPos; + CBigNum bnChainTrust; // ppcoin: trust score of block chain + int nHeight; + + int64 nMint; + int64 nMoneySupply; + + 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 + }; + + uint64 nStakeModifier; // hash modifier for proof-of-stake + unsigned int nStakeModifierChecksum; // checksum of index; in-memeory only + + // proof-of-stake specific fields + COutPoint prevoutStake; + unsigned int nStakeTime; + uint256 hashProofOfStake; + + // block header + int nVersion; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + CBlockIndex() + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = 0; + nBlockPos = 0; + nHeight = 0; + bnChainTrust = 0; + nMint = 0; + nMoneySupply = 0; + nFlags = 0; + nStakeModifier = 0; + nStakeModifierChecksum = 0; + hashProofOfStake = 0; + prevoutStake.SetNull(); + nStakeTime = 0; + + nVersion = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + } + + CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nHeight = 0; + bnChainTrust = 0; + nMint = 0; + nMoneySupply = 0; + nFlags = 0; + nStakeModifier = 0; + nStakeModifierChecksum = 0; + hashProofOfStake = 0; + if (block.IsProofOfStake()) + { + SetProofOfStake(); + prevoutStake = block.vtx[1].vin[0].prevout; + nStakeTime = block.vtx[1].nTime; + } + else + { + prevoutStake.SetNull(); + nStakeTime = 0; + } + + nVersion = block.nVersion; + hashMerkleRoot = block.hashMerkleRoot; + nTime = block.nTime; + nBits = block.nBits; + nNonce = block.nNonce; + } + + CBlock GetBlockHeader() const + { + CBlock block; + block.nVersion = nVersion; + if (pprev) + block.hashPrevBlock = pprev->GetBlockHash(); + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block; + } + + uint256 GetBlockHash() const + { + return *phashBlock; + } + + int64 GetBlockTime() const + { + return (int64)nTime; + } + + CBigNum GetBlockTrust() const; + + bool IsInMainChain() const + { + return (pnext || this == pindexBest); + } + + bool CheckIndex() const + { + return true; + } + + enum { nMedianTimeSpan=11 }; + + int64 GetMedianTimePast() const + { + int64 pmedian[nMedianTimeSpan]; + int64* pbegin = &pmedian[nMedianTimeSpan]; + int64* 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]; + } + + int64 GetMedianTime() const + { + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan/2; i++) + { + if (!pindex->pnext) + return GetBlockTime(); + pindex = pindex->pnext; + } + return pindex->GetMedianTimePast(); + } + + /** + * Returns true if there are nRequired or more blocks of minVersion or above + * in the last nToCheck blocks, starting at pstart and going backwards. + */ + static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, + unsigned int nRequired, unsigned int nToCheck); + + + 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 + { + return ((nFlags & BLOCK_STAKE_ENTROPY) >> 1); + } + + 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 nModifier, bool fGeneratedStakeModifier) + { + nStakeModifier = nModifier; + if (fGeneratedStakeModifier) + nFlags |= BLOCK_STAKE_MODIFIER; + } + + std::string ToString() const + { + return strprintf("CBlockIndex(nprev=%p, pnext=%p, nFile=%u, nBlockPos=%-6d nHeight=%d, nMint=%s, nMoneySupply=%s, nFlags=(%s)(%d)(%s), nStakeModifier=%016"PRI64x", nStakeModifierChecksum=%08x, hashProofOfStake=%s, prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)", + pprev, pnext, nFile, nBlockPos, nHeight, + FormatMoney(nMint).c_str(), FormatMoney(nMoneySupply).c_str(), + GeneratedStakeModifier() ? "MOD" : "-", GetStakeEntropyBit(), IsProofOfStake()? "PoS" : "PoW", + nStakeModifier, nStakeModifierChecksum, + hashProofOfStake.ToString().c_str(), + prevoutStake.ToString().c_str(), nStakeTime, + hashMerkleRoot.ToString().c_str(), + GetBlockHash().ToString().c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + +/** Used to marshal pointers into hashes for db storage. */ +class CDiskBlockIndex : public CBlockIndex +{ +public: + uint256 hashPrev; + uint256 hashNext; + + CDiskBlockIndex() + { + hashPrev = 0; + hashNext = 0; + } + + explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) + { + hashPrev = (pprev ? pprev->GetBlockHash() : 0); + hashNext = (pnext ? pnext->GetBlockHash() : 0); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + + READWRITE(hashNext); + READWRITE(nFile); + READWRITE(nBlockPos); + READWRITE(nHeight); + READWRITE(nMint); + READWRITE(nMoneySupply); + READWRITE(nFlags); + READWRITE(nStakeModifier); + if (IsProofOfStake()) + { + READWRITE(prevoutStake); + READWRITE(nStakeTime); + READWRITE(hashProofOfStake); + } + else if (fRead) + { + const_cast(this)->prevoutStake.SetNull(); + const_cast(this)->nStakeTime = 0; + const_cast(this)->hashProofOfStake = 0; + } + + // block header + READWRITE(this->nVersion); + READWRITE(hashPrev); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + ) + + uint256 GetBlockHash() const + { + CBlock block; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrev; + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block.GetHash(); + } + + + std::string ToString() const + { + std::string str = "CDiskBlockIndex("; + str += CBlockIndex::ToString(); + str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", + GetBlockHash().ToString().c_str(), + hashPrev.ToString().c_str(), + hashNext.ToString().c_str()); + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + + + + + +/** Describes a place in the block chain to another node such that if the + * other node doesn't have the same branch, it can find a recent common trunk. + * The further back it is, the further before the fork it may be. + */ +class CBlockLocator +{ +protected: + std::vector vHave; +public: + + CBlockLocator() + { + } + + explicit CBlockLocator(const CBlockIndex* pindex) + { + Set(pindex); + } + + explicit CBlockLocator(uint256 hashBlock) + { + std::map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end()) + Set((*mi).second); + } + + CBlockLocator(const std::vector& vHaveIn) + { + vHave = vHaveIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vHave); + ) + + void SetNull() + { + vHave.clear(); + } + + bool IsNull() + { + return vHave.empty(); + } + + void Set(const CBlockIndex* pindex) + { + vHave.clear(); + int nStep = 1; + while (pindex) + { + vHave.push_back(pindex->GetBlockHash()); + + // Exponentially larger steps back + for (int i = 0; pindex && i < nStep; i++) + pindex = pindex->pprev; + if (vHave.size() > 10) + nStep *= 2; + } + vHave.push_back((!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)); + } + + int GetDistanceBack() + { + // Retrace how far back it was in the sender's branch + int nDistance = 0; + int nStep = 1; + BOOST_FOREACH(const uint256& hash, vHave) + { + std::map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return nDistance; + } + nDistance += nStep; + if (nDistance > 10) + nStep *= 2; + } + return nDistance; + } + + CBlockIndex* GetBlockIndex() + { + // Find the first block the caller has in the main chain + BOOST_FOREACH(const uint256& hash, vHave) + { + std::map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return pindex; + } + } + return pindexGenesisBlock; + } + + uint256 GetBlockHash() + { + // Find the first block the caller has in the main chain + BOOST_FOREACH(const uint256& hash, vHave) + { + std::map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return hash; + } + } + return (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet); + } + + int GetHeight() + { + CBlockIndex* pindex = GetBlockIndex(); + if (!pindex) + return 0; + return pindex->nHeight; + } +}; + + + + + + + + +class CTxMemPool +{ +public: + mutable CCriticalSection cs; + std::map mapTx; + std::map mapNextTx; + + bool accept(CTxDB& txdb, CTransaction &tx, + bool fCheckInputs, bool* pfMissingInputs); + bool addUnchecked(const uint256& hash, CTransaction &tx); + bool remove(CTransaction &tx); + void clear(); + void queryHashes(std::vector& vtxid); + + unsigned long size() + { + LOCK(cs); + return mapTx.size(); + } + + bool exists(uint256 hash) + { + return (mapTx.count(hash) != 0); + } + + CTransaction& lookup(uint256 hash) + { + return mapTx[hash]; + } +}; + +extern CTxMemPool mempool; + +#endif diff --git a/src/makefile.bsd b/src/makefile.bsd new file mode 100644 index 0000000..0b4c03d --- /dev/null +++ b/src/makefile.bsd @@ -0,0 +1,189 @@ +# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +USE_UPNP:=0 +USE_IPV6:=1 + +LINK:=$(CXX) + +DEFS=-DBOOST_SPIRIT_THREADSAFE + +DEFS += $(addprefix -I,$(CURDIR) $(CURDIR)/obj $(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH)) +LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH)) + +TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) + +LMODE = dynamic +LMODE2 = dynamic +ifdef STATIC + LMODE = static + ifeq (${STATIC}, all) + LMODE2 = static + endif +else + TESTDEFS += -DBOOST_TEST_DYN_LINK +endif + +# for boost 1.37, add -mt to the boost libraries +LIBS += \ + -Wl,-B$(LMODE) \ + -l boost_system$(BOOST_LIB_SUFFIX) \ + -l boost_filesystem$(BOOST_LIB_SUFFIX) \ + -l boost_program_options$(BOOST_LIB_SUFFIX) \ + -l boost_thread$(BOOST_LIB_SUFFIX) \ + -l db_cxx$(BDB_LIB_SUFFIX) \ + -l ssl \ + -l crypto \ + -l execinfo + +ifndef USE_UPNP + override USE_UPNP = - +endif +ifneq (${USE_UPNP}, -) + LIBS += -l miniupnpc + DEFS += -DUSE_UPNP=$(USE_UPNP) +endif + +ifneq (${USE_IPV6}, -) + DEFS += -DUSE_IPV6=$(USE_IPV6) +endif + +LIBS+= \ + -Wl,-B$(LMODE2) \ + -l z \ + -l dl \ + -l pthread + + +# Hardening +# Make some classes of vulnerabilities unexploitable in case one is discovered. +# + # This is a workaround for Ubuntu bug #691722, the default -fstack-protector causes + # -fstack-protector-all to be ignored unless -fno-stack-protector is used first. + # see: https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/691722 + HARDENING=-fno-stack-protector + + # Stack Canaries + # Put numbers at the beginning of each stack frame and check that they are the same. + # If a stack buffer if overflowed, it writes over the canary number and then on return + # when that number is checked, it won't be the same and the program will exit with + # a "Stack smashing detected" error instead of being exploited. + HARDENING+=-fstack-protector-all -Wstack-protector + + # Make some important things such as the global offset table read only as soon as + # the dynamic linker is finished building it. This will prevent overwriting of addresses + # which would later be jumped to. + LDHARDENING+=-Wl,-z,relro -Wl,-z,now + + # Build position independent code to take advantage of Address Space Layout Randomization + # offered by some kernels. + # see doc/build-unix.txt for more information. + ifdef PIE + HARDENING+=-fPIE + LDHARDENING+=-pie + endif + + # -D_FORTIFY_SOURCE=2 does some checking for potentially exploitable code patterns in + # the source such overflowing a statically defined buffer. + HARDENING+=-D_FORTIFY_SOURCE=2 +# + + +DEBUGFLAGS=-g + +# CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only +# adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work. +xCXXFLAGS=-O0 -msse2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ + $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS) + +# LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only +# adds some defaults in front. Unfortunately, LDFLAGS=... $(LDFLAGS) does not work. +xLDFLAGS=$(LDHARDENING) $(LDFLAGS) + +OBJS= \ + obj/alert.o \ + obj/version.o \ + obj/checkpoints.o \ + obj/netbase.o \ + obj/addrman.o \ + obj/crypter.o \ + obj/key.o \ + obj/db.o \ + obj/init.o \ + obj/irc.o \ + obj/keystore.o \ + obj/main.o \ + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/rpcdump.o \ + obj/rpcnet.o \ + obj/rpcmining.o \ + obj/rpcwallet.o \ + obj/rpcblockchain.o \ + obj/rpcrawtransaction.o \ + obj/script.o \ + obj/sync.o \ + obj/util.o \ + obj/wallet.o \ + obj/walletdb.o \ + obj/noui.o \ + obj/kernel.o \ + obj/pbkdf2.o \ + obj/scrypt_mine.o \ + obj/scrypt-x86.o \ + obj/scrypt-x86_64.o + + +all: BERNd + +test check: test_BERN FORCE + ./test_BottleCaps + +# auto-generated dependencies: +-include obj/*.P +-include obj-test/*.P + +obj/build.h: FORCE + /bin/sh ../share/genbuild.sh obj/build.h +version.cpp: obj/build.h +DEFS += -DHAVE_BUILD_INFO + +obj/scrypt-x86.o: scrypt-x86.S + $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< + +obj/scrypt-x86_64.o: scrypt-x86_64.S + $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< + +obj/%.o: %.cpp + $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +BERNd: $(OBJS:obj/%=obj/%) + $(LINK) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS) + +TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) + +obj-test/%.o: test/%.cpp + $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +test_BERN: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) + $(LINK) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-B$(LMODE) -lboost_unit_test_framework $(xLDFLAGS) $(LIBS) + +clean: + -rm -f BERNd test_BERN + -rm -f obj/*.o + -rm -f obj-test/*.o + -rm -f obj/*.P + -rm -f obj-test/*.P + -rm -f obj/build.h + +FORCE: diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw new file mode 100644 index 0000000..e6b5543 --- /dev/null +++ b/src/makefile.linux-mingw @@ -0,0 +1,144 @@ +# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +DEPSDIR:=/usr/i586-mingw32msvc + +USE_UPNP:=0 +USE_IPV6:=1 + +INCLUDEPATHS= \ + -I"$(CURDIR)" \ + -I"$(CURDIR)"/obj \ + -I"$(DEPSDIR)/boost_1_50_0" \ + -I"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ + -I"$(DEPSDIR)/openssl-1.0.1g/include" \ + -I"$(DEPSDIR)" + +LIBPATHS= \ + -L"$(DEPSDIR)/boost_1_50_0/stage/lib" \ + -L"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ + -L"$(DEPSDIR)/openssl-1.0.1g" + +LIBS= \ + -l boost_system-mt-s \ + -l boost_filesystem-mt-s \ + -l boost_program_options-mt-s \ + -l boost_thread_win32-mt-s \ + -l boost_chrono-mt-s \ + -l db_cxx \ + -l ssl \ + -l crypto + +DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE +DEBUGFLAGS=-g +CFLAGS=-O2 -msse2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) +LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat + +TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) + +ifndef USE_UPNP + override USE_UPNP = - +endif +ifneq (${USE_UPNP}, -) + LIBPATHS += -L"$(DEPSDIR)/miniupnpc" + LIBS += -l miniupnpc -l iphlpapi + DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) +endif + +ifneq (${USE_IPV6}, -) + DEFS += -DUSE_IPV6=$(USE_IPV6) +endif + +LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l mswsock -l shlwapi + +# TODO: make the mingw builds smarter about dependencies, like the linux/osx builds are +HEADERS = $(wildcard *.h) + +OBJS= \ + obj/aes_helper.o \ + obj/fugue.o \ + obj/hamsi.o \ + obj/groestl.o \ + obj/blake.o \ + obj/bmw.o \ + obj/skein.o \ + obj/keccak.o \ + obj/shavite.o \ + obj/jh.o \ + obj/luffa.o \ + obj/cubehash.o \ + obj/echo.o \ + obj/simd.o \ + obj/alert.o \ + obj/version.o \ + obj/checkpoints.o \ + obj/netbase.o \ + obj/addrman.o \ + obj/crypter.o \ + obj/key.o \ + obj/db.o \ + obj/init.o \ + obj/irc.o \ + obj/keystore.o \ + obj/main.o \ + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/rpcdump.o \ + obj/rpcnet.o \ + obj/rpcmining.o \ + obj/rpcwallet.o \ + obj/rpcblockchain.o \ + obj/rpcrawtransaction.o \ + obj/script.o \ + obj/sync.o \ + obj/util.o \ + obj/wallet.o \ + obj/walletdb.o \ + obj/noui.o \ + obj/kernel.o \ + obj/pbkdf2.o \ + obj/scrypt.o \ + obj/scrypt_mine.o \ + obj/scrypt-x86.o \ + obj/scrypt-x86_64.o + +all: BERNd.exe + +obj/build.h: FORCE + /bin/sh ../share/genbuild.sh obj/build.h +version.cpp: obj/build.h +DEFS += -DHAVE_BUILD_INFO + +obj/%.o: %.cpp $(HEADERS) + i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $< + +obj/%.o: %.c $(HEADERS) + i586-mingw32msvc-g++ -c $(CFLAGS) -fpermissive -o $@ $< + +BERNd.exe: $(OBJS:obj/%=obj/%) + i586-mingw32msvc-g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) + +TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) + +obj-test/%.o: test/%.cpp $(HEADERS) + i586-mingw32msvc-g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $< + +test_BERN.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) + i586-mingw32msvc-g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework-mt-s $(LIBS) + +obj/scrypt-x86.o: scrypt-x86.S + i586-mingw32msvc-g++ -c $(CFLAGS) -MMD -o $@ $< + +obj/scrypt-x86_64.o: scrypt-x86_64.S + i586-mingw32msvc-g++ -c $(CFLAGS) -MMD -o $@ $< + +clean: + -rm -f obj/*.o + -rm -f BERNd.exe + -rm -f obj-test/*.o + -rm -f test_BERN.exe + -rm -f obj/build.h + +FORCE: diff --git a/src/makefile.mingw b/src/makefile.mingw new file mode 100644 index 0000000..7649257 --- /dev/null +++ b/src/makefile.mingw @@ -0,0 +1,118 @@ +# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +USE_UPNP:=0 +USE_IPV6:=0 + +INCLUDEPATHS?= \ + -I"C:/deps/boost_1_53_0" \ + -I"C:/deps/db-4.8.30.NC/build_unix" \ + -I"C:/deps/openssl-1.0.1g/include" + +LIBPATHS?= \ + -L"C:/deps/boost_1_53_0/stage/lib" \ + -L"C:/deps/db-4.8.30.NC/build_unix" \ + -L"C:/deps/openssl-1.0.1g" + + +LIBS= \ + -l boost_system-mgw48-mt-s-1_53 \ + -l boost_filesystem-mgw48-mt-s-1_53 \ + -l boost_program_options-mgw48-mt-s-1_53 \ + -l boost_thread-mgw48-mt-s-1_53 \ + -l db_cxx \ + -l ssl \ + -l crypto + +DEFS=-D_MT -DWIN32 -DWIN32_LEAN_AND_MEAN -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -D__NO_SYSTEM_INCLUDES +DEBUGFLAGS=-g +CFLAGS=${ADDITIONALCCFLAGS} -mthreads -O2 -msse2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) +LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat + +TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) + +ifndef USE_UPNP + override USE_UPNP = - +endif +ifneq (${USE_UPNP}, -) + INCLUDEPATHS += -I"C:/deps/" + LIBPATHS += -L"C:/deps/miniupnpc" + LIBS += -l miniupnpc -l iphlpapi + DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) +endif + +ifneq (${USE_IPV6}, -) + DEFS += -DUSE_IPV6=$(USE_IPV6) +endif + +LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l mswsock -l shlwapi + +# TODO: make the mingw builds smarter about dependencies, like the linux/osx builds are +HEADERS = $(wildcard *.h) + +OBJS= \ + obj/alert.o \ + obj/version.o \ + obj/checkpoints.o \ + obj/netbase.o \ + obj/addrman.o \ + obj/crypter.o \ + obj/key.o \ + obj/db.o \ + obj/init.o \ + obj/irc.o \ + obj/keystore.o \ + obj/main.o \ + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/rpcdump.o \ + obj/rpcnet.o \ + obj/rpcmining.o \ + obj/rpcwallet.o \ + obj/rpcblockchain.o \ + obj/rpcrawtransaction.o \ + obj/script.o \ + obj/sync.o \ + obj/util.o \ + obj/wallet.o \ + obj/walletdb.o \ + obj/noui.o \ + obj/kernel.o \ + obj/pbkdf2.o \ + obj/scrypt_mine.o \ + obj/scrypt-x86.o \ + obj/scrypt-x86_64.o + +all: BERNd.exe + +test check: test_BERN.exe FORCE + test_BERN.exe + +obj/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/scrypt-x86.o: scrypt-x86.S + $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< + +obj/scrypt-x86_64.o: scrypt-x86_64.S + $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< + +BERNd.exe: $(OBJS:obj/%=obj/%) + g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) + +TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) + +obj-test/%.o: test/%.cpp $(HEADERS) + g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $< + +test_BERN.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) + g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS) + +clean: + -del /Q BERN test_BERN + -del /Q obj\* + -del /Q obj-test\* + +FORCE: diff --git a/src/makefile.osx b/src/makefile.osx new file mode 100644 index 0000000..9105670 --- /dev/null +++ b/src/makefile.osx @@ -0,0 +1,172 @@ +# -*- mode: Makefile; -*- +# Copyright (c) 2011 Bitcoin Developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Mac OS X makefile for bitcoin +# Originally by Laszlo Hanyecz (solar@heliacal.net) + +CXX=llvm-g++ +DEPSDIR=/opt/local + +INCLUDEPATHS= \ + -I"$(CURDIR)" \ + -I"$(CURDIR)"/obj \ + -I"$(DEPSDIR)/include" \ + -I"$(DEPSDIR)/include/db48" + +LIBPATHS= \ + -L"$(DEPSDIR)/lib" \ + -L"$(DEPSDIR)/lib/db48" + +USE_UPNP:=1 +USE_IPV6:=1 + +LIBS= -dead_strip + +TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) + +ifdef STATIC +# Build STATIC if you are redistributing the bitcoind binary +TESTLIBS += \ + $(DEPSDIR)/lib/libboost_unit_test_framework-mt.a +LIBS += \ + $(DEPSDIR)/lib/db48/libdb_cxx-4.8.a \ + $(DEPSDIR)/lib/libboost_system-mt.a \ + $(DEPSDIR)/lib/libboost_filesystem-mt.a \ + $(DEPSDIR)/lib/libboost_program_options-mt.a \ + $(DEPSDIR)/lib/libboost_thread-mt.a \ + $(DEPSDIR)/lib/libssl.a \ + $(DEPSDIR)/lib/libcrypto.a \ + -lz +else +TESTLIBS += \ + -lboost_unit_test_framework-mt +LIBS += \ + -ldb_cxx-4.8 \ + -lboost_system-mt \ + -lboost_filesystem-mt \ + -lboost_program_options-mt \ + -lboost_thread-mt \ + -lssl \ + -lcrypto \ + -lz +TESTDEFS += -DBOOST_TEST_DYN_LINK +endif + +DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DBOOST_SPIRIT_THREADSAFE + +ifdef RELEASE +# Compile for maximum compatibility and smallest size. +# This requires that dependencies are compiled +# the same way. +CFLAGS = -mmacosx-version-min=10.5 -arch x86_64 -O3 -msse2 +else +CFLAGS = -g -msse2 +endif + +# ppc doesn't work because we don't support big-endian +CFLAGS += -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ + $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) + +OBJS= \ + obj/alert.o \ + obj/version.o \ + obj/checkpoints.o \ + obj/netbase.o \ + obj/addrman.o \ + obj/crypter.o \ + obj/key.o \ + obj/db.o \ + obj/init.o \ + obj/irc.o \ + obj/keystore.o \ + obj/main.o \ + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/rpcdump.o \ + obj/rpcnet.o \ + obj/rpcmining.o \ + obj/rpcwallet.o \ + obj/rpcblockchain.o \ + obj/rpcrawtransaction.o \ + obj/script.o \ + obj/sync.o \ + obj/util.o \ + obj/wallet.o \ + obj/walletdb.o \ + obj/noui.o \ + obj/pbkdf2.o \ + obj/kernel.o \ + obj/scrypt_mine.o \ + obj/scrypt-x86.o \ + obj/scrypt-x86_64.o + +ifndef USE_UPNP + override USE_UPNP = - +endif +ifneq (${USE_UPNP}, -) + DEFS += -DUSE_UPNP=$(USE_UPNP) +ifdef STATIC + LIBS += $(DEPSDIR)/lib/libminiupnpc.a +else + LIBS += -lminiupnpc +endif +endif + +ifneq (${USE_IPV6}, -) + DEFS += -DUSE_IPV6=$(USE_IPV6) +endif + +all: BERNd + +test check: test_BERN FORCE + ./test_BERN + +# auto-generated dependencies: +-include obj/*.P +-include obj-test/*.P + +obj/build.h: FORCE + /bin/sh ../share/genbuild.sh obj/build.h +version.cpp: obj/build.h +DEFS += -DHAVE_BUILD_INFO + +obj/%.o: %.cpp + $(CXX) -c $(CFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +obj/scrypt-x86.o: scrypt-x86.S + $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< + +obj/scrypt-x86_64.o: scrypt-x86_64.S + $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< + +BERNd: $(OBJS:obj/%=obj/%) + $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) + +TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) + +obj-test/%.o: test/%.cpp + $(CXX) -c $(TESTDEFS) $(CFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +test_BERN: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) + $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS) + +clean: + -rm -f BERNd test_BERN + -rm -f obj/*.o + -rm -f obj-test/*.o + -rm -f obj/*.P + -rm -f obj-test/*.P + -rm -f obj/build.h + +FORCE: diff --git a/src/makefile.unix b/src/makefile.unix new file mode 100644 index 0000000..6bfee40 --- /dev/null +++ b/src/makefile.unix @@ -0,0 +1,211 @@ +# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +USE_UPNP:=0 +USE_IPV6:=1 + +LINK:=$(CXX) + +DEFS=-DBOOST_SPIRIT_THREADSAFE + +DEFS += $(addprefix -I,$(CURDIR) $(CURDIR)/obj $(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH)) +LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH)) + +TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) + +LMODE = dynamic +LMODE2 = dynamic +ifdef STATIC + LMODE = static + ifeq (${STATIC}, all) + LMODE2 = static + endif +else + TESTDEFS += -DBOOST_TEST_DYN_LINK +endif + +# for boost 1.37, add -mt to the boost libraries +LIBS += \ + -Wl,-B$(LMODE) \ + -l boost_system$(BOOST_LIB_SUFFIX) \ + -l boost_filesystem$(BOOST_LIB_SUFFIX) \ + -l boost_program_options$(BOOST_LIB_SUFFIX) \ + -l boost_thread$(BOOST_LIB_SUFFIX) \ + -l db_cxx$(BDB_LIB_SUFFIX) \ + -l ssl \ + -l crypto + +ifndef USE_UPNP + override USE_UPNP = - +endif +ifneq (${USE_UPNP}, -) + LIBS += -l miniupnpc + DEFS += -DUSE_UPNP=$(USE_UPNP) +endif + +ifneq (${USE_IPV6}, -) + DEFS += -DUSE_IPV6=$(USE_IPV6) +endif + +LIBS+= \ + -Wl,-B$(LMODE2) \ + -l z \ + -l dl \ + -l pthread + + +# Hardening +# Make some classes of vulnerabilities unexploitable in case one is discovered. +# + # This is a workaround for Ubuntu bug #691722, the default -fstack-protector causes + # -fstack-protector-all to be ignored unless -fno-stack-protector is used first. + # see: https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/691722 + HARDENING=-fno-stack-protector + + # Stack Canaries + # Put numbers at the beginning of each stack frame and check that they are the same. + # If a stack buffer if overflowed, it writes over the canary number and then on return + # when that number is checked, it won't be the same and the program will exit with + # a "Stack smashing detected" error instead of being exploited. + HARDENING+=-fstack-protector-all -Wstack-protector + + # Make some important things such as the global offset table read only as soon as + # the dynamic linker is finished building it. This will prevent overwriting of addresses + # which would later be jumped to. + LDHARDENING+=-Wl,-z,relro -Wl,-z,now + + # Build position independent code to take advantage of Address Space Layout Randomization + # offered by some kernels. + # see doc/build-unix.txt for more information. + ifdef PIE + HARDENING+=-fPIE + LDHARDENING+=-pie + endif + + # -D_FORTIFY_SOURCE=2 does some checking for potentially exploitable code patterns in + # the source such overflowing a statically defined buffer. + HARDENING+=-D_FORTIFY_SOURCE=2 +# + + +DEBUGFLAGS=-g + +# CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only +# adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work. +xCXXFLAGS=-O2 -msse2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ + $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS) + +# LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only +# adds some defaults in front. Unfortunately, LDFLAGS=... $(LDFLAGS) does not work. +xLDFLAGS=$(LDHARDENING) $(LDFLAGS) + +OBJS= \ + obj/fugue.o \ + obj/hamsi.o \ + obj/shabal.o\ + obj/groestl.o \ + obj/blake.o \ + obj/bmw.o \ + obj/skein.o \ + obj/keccak.o \ + obj/shavite.o \ + obj/jh.o \ + obj/luffa.o \ + obj/cubehash.o \ + obj/echo.o \ + obj/simd.o \ + obj/alert.o \ + obj/version.o \ + obj/checkpoints.o \ + obj/netbase.o \ + obj/addrman.o \ + obj/crypter.o \ + obj/key.o \ + obj/db.o \ + obj/init.o \ + obj/irc.o \ + obj/keystore.o \ + obj/main.o \ + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/rpcdump.o \ + obj/rpcnet.o \ + obj/rpcmining.o \ + obj/rpcwallet.o \ + obj/rpcblockchain.o \ + obj/rpcrawtransaction.o \ + obj/script.o \ + obj/sync.o \ + obj/util.o \ + obj/wallet.o \ + obj/walletdb.o \ + obj/noui.o \ + obj/kernel.o \ + obj/pbkdf2.o \ + obj/scrypt.o \ + obj/scrypt_mine.o \ + obj/scrypt-x86.o \ + obj/scrypt-x86_64.o + + +all: BERNd + +test check: test_BERN FORCE + ./test_BERN + +# auto-generated dependencies: +-include obj/*.P +-include obj-test/*.P + +obj/build.h: FORCE + /bin/sh ../share/genbuild.sh obj/build.h +version.cpp: obj/build.h +DEFS += -DHAVE_BUILD_INFO + +obj/scrypt-x86.o: scrypt-x86.S + $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< + +obj/scrypt-x86_64.o: scrypt-x86_64.S + $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< + +obj/%.o: %.cpp + $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +obj/%.o: %.c + $(CXX) -c $(xCXXFLAGS) -fpermissive -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + + +BERNd: $(OBJS:obj/%=obj/%) + $(LINK) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS) + +TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) + +obj-test/%.o: test/%.cpp + $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +test_BERN: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) + $(LINK) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-B$(LMODE) -lboost_unit_test_framework $(xLDFLAGS) $(LIBS) + +clean: + -rm -f BERNd test_BERN + -rm -f obj/*.o + -rm -f obj-test/*.o + -rm -f obj/*.P + -rm -f obj-test/*.P + -rm -f obj/build.h + +FORCE: diff --git a/src/mruset.h b/src/mruset.h new file mode 100644 index 0000000..a527351 --- /dev/null +++ b/src/mruset.h @@ -0,0 +1,64 @@ +// Copyright (c) 2012 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_MRUSET_H +#define BITCOIN_MRUSET_H + +#include +#include + +/** STL-like set container that only keeps the most recent N elements. */ +template class mruset +{ +public: + typedef T key_type; + typedef T value_type; + typedef typename std::set::iterator iterator; + typedef typename std::set::const_iterator const_iterator; + typedef typename std::set::size_type size_type; + +protected: + std::set set; + std::deque queue; + size_type nMaxSize; + +public: + mruset(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; } + iterator begin() const { return set.begin(); } + iterator end() const { return set.end(); } + size_type size() const { return set.size(); } + bool empty() const { return set.empty(); } + iterator find(const key_type& k) const { return set.find(k); } + size_type count(const key_type& k) const { return set.count(k); } + bool inline friend operator==(const mruset& a, const mruset& b) { return a.set == b.set; } + bool inline friend operator==(const mruset& a, const std::set& b) { return a.set == b; } + bool inline friend operator<(const mruset& a, const mruset& b) { return a.set < b.set; } + std::pair insert(const key_type& x) + { + std::pair ret = set.insert(x); + if (ret.second) + { + if (nMaxSize && queue.size() == nMaxSize) + { + set.erase(queue.front()); + queue.pop_front(); + } + queue.push_back(x); + } + return ret; + } + size_type max_size() const { return nMaxSize; } + size_type max_size(size_type s) + { + if (s) + while (queue.size() > s) + { + set.erase(queue.front()); + queue.pop_front(); + } + nMaxSize = s; + return nMaxSize; + } +}; + +#endif diff --git a/src/net.cpp b/src/net.cpp new file mode 100644 index 0000000..4c4b4b7 --- /dev/null +++ b/src/net.cpp @@ -0,0 +1,1974 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "irc.h" +#include "db.h" +#include "net.h" +#include "init.h" +#include "strlcpy.h" +#include "addrman.h" +#include "ui_interface.h" + +#ifdef WIN32 +#include +#endif + +#ifdef USE_UPNP +#include +#include +#include +#include +#endif + +using namespace std; +using namespace boost; + +static const int MAX_OUTBOUND_CONNECTIONS = 12; + +void ThreadMessageHandler2(void* parg); +void ThreadSocketHandler2(void* parg); +void ThreadOpenConnections2(void* parg); +void ThreadOpenAddedConnections2(void* parg); +#ifdef USE_UPNP +void ThreadMapPort2(void* parg); +#endif +void ThreadDNSAddressSeed2(void* parg); +bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); + + +struct LocalServiceInfo { + int nScore; + int nPort; +}; + +// +// Global state variables +// +bool fClient = false; +bool fDiscover = true; +bool fUseUPnP = false; +uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); +static CCriticalSection cs_mapLocalHost; +static map mapLocalHost; +static bool vfReachable[NET_MAX] = {}; +static bool vfLimited[NET_MAX] = {}; +static CNode* pnodeLocalHost = NULL; +CAddress addrSeenByPeer(CService("0.0.0.0", 0), nLocalServices); +uint64 nLocalHostNonce = 0; +array vnThreadsRunning; +static std::vector vhListenSocket; +CAddrMan addrman; + +vector vNodes; +CCriticalSection cs_vNodes; +map mapRelay; +deque > vRelayExpiration; +CCriticalSection cs_mapRelay; +map mapAlreadyAskedFor; + +static deque vOneShots; +CCriticalSection cs_vOneShots; + +set setservAddNodeAddresses; +CCriticalSection cs_setservAddNodeAddresses; + +static CSemaphore *semOutbound = NULL; + +void AddOneShot(string strDest) +{ + LOCK(cs_vOneShots); + vOneShots.push_back(strDest); +} + +unsigned short GetListenPort() +{ + return (unsigned short)(GetArg("-port", GetDefaultPort())); +} + +void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd) +{ + // Filter out duplicate requests + if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd) + return; + pindexLastGetBlocksBegin = pindexBegin; + hashLastGetBlocksEnd = hashEnd; + + PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd); +} + +// find 'best' local address for a particular peer +bool GetLocal(CService& addr, const CNetAddr *paddrPeer) +{ + if (fNoListen) + return false; + + int nBestScore = -1; + int nBestReachability = -1; + { + LOCK(cs_mapLocalHost); + for (map::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) + { + int nScore = (*it).second.nScore; + int nReachability = (*it).first.GetReachabilityFrom(paddrPeer); + if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) + { + addr = CService((*it).first, (*it).second.nPort); + nBestReachability = nReachability; + nBestScore = nScore; + } + } + } + return nBestScore >= 0; +} + +// get best local address for a particular peer as a CAddress +CAddress GetLocalAddress(const CNetAddr *paddrPeer) +{ + CAddress ret(CService("0.0.0.0",0),0); + CService addr; + if (GetLocal(addr, paddrPeer)) + { + ret = CAddress(addr); + ret.nServices = nLocalServices; + ret.nTime = GetAdjustedTime(); + } + return ret; +} + +bool RecvLine(SOCKET hSocket, string& strLine) +{ + strLine = ""; + while (true) + { + char c; + int nBytes = recv(hSocket, &c, 1, 0); + if (nBytes > 0) + { + if (c == '\n') + continue; + if (c == '\r') + return true; + strLine += c; + if (strLine.size() >= 9000) + return true; + } + else if (nBytes <= 0) + { + if (fShutdown) + return false; + if (nBytes < 0) + { + int nErr = WSAGetLastError(); + if (nErr == WSAEMSGSIZE) + continue; + if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS) + { + Sleep(10); + continue; + } + } + if (!strLine.empty()) + return true; + if (nBytes == 0) + { + // socket closed + printf("socket closed\n"); + return false; + } + else + { + // socket error + int nErr = WSAGetLastError(); + printf("recv failed: %d\n", nErr); + return false; + } + } + } +} + +// used when scores of local addresses may have changed +// pushes better local address to peers +void static AdvertizeLocal() +{ + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + if (pnode->fSuccessfullyConnected) + { + CAddress addrLocal = GetLocalAddress(&pnode->addr); + if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal) + { + pnode->PushAddress(addrLocal); + pnode->addrLocal = addrLocal; + } + } + } +} + +void SetReachable(enum Network net, bool fFlag) +{ + LOCK(cs_mapLocalHost); + vfReachable[net] = fFlag; + if (net == NET_IPV6 && fFlag) + vfReachable[NET_IPV4] = true; +} + +// learn a new local address +bool AddLocal(const CService& addr, int nScore) +{ + if (!addr.IsRoutable()) + return false; + + if (!fDiscover && nScore < LOCAL_MANUAL) + return false; + + if (IsLimited(addr)) + return false; + + printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore); + + { + LOCK(cs_mapLocalHost); + bool fAlready = mapLocalHost.count(addr) > 0; + LocalServiceInfo &info = mapLocalHost[addr]; + if (!fAlready || nScore >= info.nScore) { + info.nScore = nScore + (fAlready ? 1 : 0); + info.nPort = addr.GetPort(); + } + SetReachable(addr.GetNetwork()); + } + + AdvertizeLocal(); + + return true; +} + +bool AddLocal(const CNetAddr &addr, int nScore) +{ + return AddLocal(CService(addr, GetListenPort()), nScore); +} + +/** Make a particular network entirely off-limits (no automatic connects to it) */ +void SetLimited(enum Network net, bool fLimited) +{ + if (net == NET_UNROUTABLE) + return; + LOCK(cs_mapLocalHost); + vfLimited[net] = fLimited; +} + +bool IsLimited(enum Network net) +{ + LOCK(cs_mapLocalHost); + return vfLimited[net]; +} + +bool IsLimited(const CNetAddr &addr) +{ + return IsLimited(addr.GetNetwork()); +} + +/** vote for a local address */ +bool SeenLocal(const CService& addr) +{ + { + LOCK(cs_mapLocalHost); + if (mapLocalHost.count(addr) == 0) + return false; + mapLocalHost[addr].nScore++; + } + + AdvertizeLocal(); + + return true; +} + +/** check whether a given address is potentially local */ +bool IsLocal(const CService& addr) +{ + LOCK(cs_mapLocalHost); + return mapLocalHost.count(addr) > 0; +} + +/** check whether a given address is in a network we can probably connect to */ +bool IsReachable(const CNetAddr& addr) +{ + LOCK(cs_mapLocalHost); + enum Network net = addr.GetNetwork(); + return vfReachable[net] && !vfLimited[net]; +} + +bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet) +{ + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str()); + + send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL); + + string strLine; + while (RecvLine(hSocket, strLine)) + { + if (strLine.empty()) // HTTP response is separated from headers by blank line + { + while (true) + { + if (!RecvLine(hSocket, strLine)) + { + closesocket(hSocket); + return false; + } + if (pszKeyword == NULL) + break; + if (strLine.find(pszKeyword) != string::npos) + { + strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword)); + break; + } + } + closesocket(hSocket); + if (strLine.find("<") != string::npos) + strLine = strLine.substr(0, strLine.find("<")); + strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); + while (strLine.size() > 0 && isspace(strLine[strLine.size()-1])) + strLine.resize(strLine.size()-1); + CService addr(strLine,0,true); + printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); + if (!addr.IsValid() || !addr.IsRoutable()) + return false; + ipRet.SetIP(addr); + return true; + } + } + closesocket(hSocket); + return error("GetMyExternalIP() : connection closed"); +} + +// We now get our external IP from the IRC server first and only use this as a backup +bool GetMyExternalIP(CNetAddr& ipRet) +{ + CService addrConnect; + const char* pszGet; + const char* pszKeyword; + + for (int nLookup = 0; nLookup <= 1; nLookup++) + for (int nHost = 1; nHost <= 2; nHost++) + { + // We should be phasing out our use of sites like these. If we need + // replacements, we should ask for volunteers to put this simple + // php file on their web server that prints the client IP: + // + if (nHost == 1) + { + addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org + + if (nLookup == 1) + { + CService addrIP("checkip.dyndns.org", 80, true); + if (addrIP.IsValid()) + addrConnect = addrIP; + } + + pszGet = "GET / HTTP/1.1\r\n" + "Host: checkip.dyndns.org\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = "Address:"; + } + else if (nHost == 2) + { + addrConnect = CService("74.208.43.192", 80); // www.showmyip.com + + if (nLookup == 1) + { + CService addrIP("www.showmyip.com", 80, true); + if (addrIP.IsValid()) + addrConnect = addrIP; + } + + pszGet = "GET /simple/ HTTP/1.1\r\n" + "Host: www.showmyip.com\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = NULL; // Returns just IP address + } + + if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet)) + return true; + } + + return false; +} + +void ThreadGetMyExternalIP(void* parg) +{ + // Make this thread recognisable as the external IP detection thread + RenameThread("bitcoin-ext-ip"); + + CNetAddr addrLocalHost; + if (GetMyExternalIP(addrLocalHost)) + { + printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str()); + AddLocal(addrLocalHost, LOCAL_HTTP); + } +} + + + + + +void AddressCurrentlyConnected(const CService& addr) +{ + addrman.Connected(addr); +} + + + + + + + +CNode* FindNode(const CNetAddr& ip) +{ + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if ((CNetAddr)pnode->addr == ip) + return (pnode); + } + return NULL; +} + +CNode* FindNode(std::string addrName) +{ + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->addrName == addrName) + return (pnode); + return NULL; +} + +CNode* FindNode(const CService& addr) +{ + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if ((CService)pnode->addr == addr) + return (pnode); + } + return NULL; +} + +CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout) +{ + if (pszDest == NULL) { + if (IsLocal(addrConnect)) + return NULL; + + // Look for an existing connection + CNode* pnode = FindNode((CService)addrConnect); + if (pnode) + { + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + return pnode; + } + } + + + /// debug print + printf("trying connection %s lastseen=%.1fhrs\n", + pszDest ? pszDest : addrConnect.ToString().c_str(), + pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0); + + // Connect + SOCKET hSocket; + if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, GetDefaultPort()) : ConnectSocket(addrConnect, hSocket)) + { + addrman.Attempt(addrConnect); + + /// debug print + printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str()); + + // Set to non-blocking +#ifdef WIN32 + u_long nOne = 1; + if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) + printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError()); +#else + if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) + printf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno); +#endif + + // Add node + CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false); + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + + { + LOCK(cs_vNodes); + vNodes.push_back(pnode); + } + + pnode->nTimeConnected = GetTime(); + return pnode; + } + else + { + return NULL; + } +} + +void CNode::CloseSocketDisconnect() +{ + fDisconnect = true; + if (hSocket != INVALID_SOCKET) + { + printf("disconnecting node %s\n", addrName.c_str()); + closesocket(hSocket); + hSocket = INVALID_SOCKET; + vRecv.clear(); + } +} + +void CNode::Cleanup() +{ +} + + +void CNode::PushVersion() +{ + /// when NTP implemented, change to just nTime = GetAdjustedTime() + int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); + CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0))); + CAddress addrMe = GetLocalAddress(&addr); + RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); + printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str()); + PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, + nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()), nBestHeight); +} + + + + + +std::map CNode::setBanned; +CCriticalSection CNode::cs_setBanned; + +void CNode::ClearBanned() +{ + setBanned.clear(); +} + +bool CNode::IsBanned(CNetAddr ip) +{ + bool fResult = false; + { + LOCK(cs_setBanned); + std::map::iterator i = setBanned.find(ip); + if (i != setBanned.end()) + { + int64 t = (*i).second; + if (GetTime() < t) + fResult = true; + } + } + return fResult; +} + +extern CMedianFilter cPeerBlockCounts; + +bool CNode::Misbehaving(int howmuch) +{ + if (addr.IsLocal()) + { + printf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch); + return false; + } + + nMisbehavior += howmuch; + if (nMisbehavior >= GetArg("-banscore", 100)) + { + int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban + printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior); + { + LOCK(cs_setBanned); + if (setBanned[addr] < banTime) + setBanned[addr] = banTime; + } + CloseSocketDisconnect(); + + cPeerBlockCounts.removeLast(nStartingHeight); // remove this node's reported number of blocks + + return true; + } else + printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior); + return false; +} + +#undef X +#define X(name) stats.name = name +void CNode::copyStats(CNodeStats &stats) +{ + X(nServices); + X(nLastSend); + X(nLastRecv); + X(nTimeConnected); + X(addrName); + X(nVersion); + X(strSubVer); + X(fInbound); + X(nReleaseTime); + X(nStartingHeight); + X(nMisbehavior); +} +#undef X + + + + + + + + + + +void ThreadSocketHandler(void* parg) +{ + // Make this thread recognisable as the networking thread + RenameThread("bitcoin-net"); + + try + { + vnThreadsRunning[THREAD_SOCKETHANDLER]++; + ThreadSocketHandler2(parg); + vnThreadsRunning[THREAD_SOCKETHANDLER]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_SOCKETHANDLER]--; + PrintException(&e, "ThreadSocketHandler()"); + } catch (...) { + vnThreadsRunning[THREAD_SOCKETHANDLER]--; + throw; // support pthread_cancel() + } + printf("ThreadSocketHandler exited\n"); +} + +void ThreadSocketHandler2(void* parg) +{ + printf("ThreadSocketHandler started\n"); + list vNodesDisconnected; + unsigned int nPrevNodeCount = 0; + + while (true) + { + // + // Disconnect nodes + // + { + LOCK(cs_vNodes); + // Disconnect unused nodes + vector vNodesCopy = vNodes; + BOOST_FOREACH(CNode* pnode, vNodesCopy) + { + if (pnode->fDisconnect || + (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty())) + { + // remove from vNodes + vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); + + // release outbound grant (if any) + pnode->grantOutbound.Release(); + + // close socket and cleanup + pnode->CloseSocketDisconnect(); + pnode->Cleanup(); + + // hold in disconnected pool until all refs are released + pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60); + if (pnode->fNetworkNode || pnode->fInbound) + pnode->Release(); + vNodesDisconnected.push_back(pnode); + } + } + + // Delete disconnected nodes + list vNodesDisconnectedCopy = vNodesDisconnected; + BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy) + { + // wait until threads are done using it + if (pnode->GetRefCount() <= 0) + { + bool fDelete = false; + { + TRY_LOCK(pnode->cs_vSend, lockSend); + if (lockSend) + { + TRY_LOCK(pnode->cs_vRecv, lockRecv); + if (lockRecv) + { + TRY_LOCK(pnode->cs_mapRequests, lockReq); + if (lockReq) + { + TRY_LOCK(pnode->cs_inventory, lockInv); + if (lockInv) + fDelete = true; + } + } + } + } + if (fDelete) + { + vNodesDisconnected.remove(pnode); + delete pnode; + } + } + } + } + if (vNodes.size() != nPrevNodeCount) + { + nPrevNodeCount = vNodes.size(); + uiInterface.NotifyNumConnectionsChanged(vNodes.size()); + } + + + // + // Find which sockets have data to receive + // + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 50000; // frequency to poll pnode->vSend + + fd_set fdsetRecv; + fd_set fdsetSend; + fd_set fdsetError; + FD_ZERO(&fdsetRecv); + FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); + SOCKET hSocketMax = 0; + bool have_fds = false; + + BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) { + FD_SET(hListenSocket, &fdsetRecv); + hSocketMax = max(hSocketMax, hListenSocket); + have_fds = true; + } + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + if (pnode->hSocket == INVALID_SOCKET) + continue; + FD_SET(pnode->hSocket, &fdsetRecv); + FD_SET(pnode->hSocket, &fdsetError); + hSocketMax = max(hSocketMax, pnode->hSocket); + have_fds = true; + { + TRY_LOCK(pnode->cs_vSend, lockSend); + if (lockSend && !pnode->vSend.empty()) + FD_SET(pnode->hSocket, &fdsetSend); + } + } + } + + vnThreadsRunning[THREAD_SOCKETHANDLER]--; + int nSelect = select(have_fds ? hSocketMax + 1 : 0, + &fdsetRecv, &fdsetSend, &fdsetError, &timeout); + vnThreadsRunning[THREAD_SOCKETHANDLER]++; + if (fShutdown) + return; + if (nSelect == SOCKET_ERROR) + { + if (have_fds) + { + int nErr = WSAGetLastError(); + printf("socket select error %d\n", nErr); + for (unsigned int i = 0; i <= hSocketMax; i++) + FD_SET(i, &fdsetRecv); + } + FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); + Sleep(timeout.tv_usec/1000); + } + + + // + // Accept new connections + // + BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) + if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv)) + { +#ifdef USE_IPV6 + struct sockaddr_storage sockaddr; +#else + struct sockaddr sockaddr; +#endif + socklen_t len = sizeof(sockaddr); + SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); + CAddress addr; + int nInbound = 0; + + if (hSocket != INVALID_SOCKET) + if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) + printf("Warning: Unknown socket family\n"); + + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->fInbound) + nInbound++; + } + + if (hSocket == INVALID_SOCKET) + { + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK) + printf("socket error accept failed: %d\n", nErr); + } + else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS) + { + { + LOCK(cs_setservAddNodeAddresses); + if (!setservAddNodeAddresses.count(addr)) + closesocket(hSocket); + } + } + else if (CNode::IsBanned(addr)) + { + printf("connection from %s dropped (banned)\n", addr.ToString().c_str()); + closesocket(hSocket); + } + else + { + printf("accepted connection %s\n", addr.ToString().c_str()); + CNode* pnode = new CNode(hSocket, addr, "", true); + pnode->AddRef(); + { + LOCK(cs_vNodes); + vNodes.push_back(pnode); + } + } + } + + + // + // Service each socket + // + vector vNodesCopy; + { + LOCK(cs_vNodes); + vNodesCopy = vNodes; + BOOST_FOREACH(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } + BOOST_FOREACH(CNode* pnode, vNodesCopy) + { + if (fShutdown) + return; + + // + // Receive + // + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError)) + { + TRY_LOCK(pnode->cs_vRecv, lockRecv); + if (lockRecv) + { + CDataStream& vRecv = pnode->vRecv; + unsigned int nPos = vRecv.size(); + + if (nPos > ReceiveBufferSize()) { + if (!pnode->fDisconnect) + printf("socket recv flood control disconnect (%"PRIszu" bytes)\n", vRecv.size()); + pnode->CloseSocketDisconnect(); + } + else { + // typical socket buffer is 8K-64K + char pchBuf[0x10000]; + int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + if (nBytes > 0) + { + vRecv.resize(nPos + nBytes); + memcpy(&vRecv[nPos], pchBuf, nBytes); + pnode->nLastRecv = GetTime(); + } + else if (nBytes == 0) + { + // socket closed gracefully + if (!pnode->fDisconnect) + printf("socket closed\n"); + pnode->CloseSocketDisconnect(); + } + else if (nBytes < 0) + { + // error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + if (!pnode->fDisconnect) + printf("socket recv error %d\n", nErr); + pnode->CloseSocketDisconnect(); + } + } + } + } + } + + // + // Send + // + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetSend)) + { + TRY_LOCK(pnode->cs_vSend, lockSend); + if (lockSend) + { + CDataStream& vSend = pnode->vSend; + if (!vSend.empty()) + { + int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT); + if (nBytes > 0) + { + vSend.erase(vSend.begin(), vSend.begin() + nBytes); + pnode->nLastSend = GetTime(); + } + else if (nBytes < 0) + { + // error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + printf("socket send error %d\n", nErr); + pnode->CloseSocketDisconnect(); + } + } + } + } + } + + // + // Inactivity checking + // + if (pnode->vSend.empty()) + pnode->nLastSendEmpty = GetTime(); + if (GetTime() - pnode->nTimeConnected > 60) + { + if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) + { + printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60) + { + printf("socket not sending\n"); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastRecv > 90*60) + { + printf("socket inactivity timeout\n"); + pnode->fDisconnect = true; + } + } + } + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodesCopy) + pnode->Release(); + } + + Sleep(10); + } +} + + + + + + + + + +#ifdef USE_UPNP +void ThreadMapPort(void* parg) +{ + // Make this thread recognisable as the UPnP thread + RenameThread("BERN-UPnP"); + + try + { + vnThreadsRunning[THREAD_UPNP]++; + ThreadMapPort2(parg); + vnThreadsRunning[THREAD_UPNP]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_UPNP]--; + PrintException(&e, "ThreadMapPort()"); + } catch (...) { + vnThreadsRunning[THREAD_UPNP]--; + PrintException(NULL, "ThreadMapPort()"); + } + printf("ThreadMapPort exited\n"); +} + +void ThreadMapPort2(void* parg) +{ + printf("ThreadMapPort started\n"); + + std::string port = strprintf("%u", GetListenPort()); + const char * multicastif = 0; + const char * minissdpdpath = 0; + struct UPNPDev * devlist = 0; + char lanaddr[64]; + +#ifndef UPNPDISCOVER_SUCCESS + /* miniupnpc 1.5 */ + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); +#else + /* miniupnpc 1.6 */ + int error = 0; + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); +#endif + + struct UPNPUrls urls; + struct IGDdatas data; + int r; + + r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); + if (r == 1) + { + if (fDiscover) { + char externalIPAddress[40]; + r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); + if(r != UPNPCOMMAND_SUCCESS) + printf("UPnP: GetExternalIPAddress() returned %d\n", r); + else + { + if(externalIPAddress[0]) + { + printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress); + AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP); + } + else + printf("UPnP: GetExternalIPAddress failed.\n"); + } + } + + string strDesc = "BERN " + FormatFullVersion(); +#ifndef UPNPDISCOVER_SUCCESS + /* miniupnpc 1.5 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); +#else + /* miniupnpc 1.6 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); +#endif + + if(r!=UPNPCOMMAND_SUCCESS) + printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", + port.c_str(), port.c_str(), lanaddr, r, strupnperror(r)); + else + printf("UPnP Port Mapping successful.\n"); + int i = 1; + while (true) { + if (fShutdown || !fUseUPnP) + { + r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); + printf("UPNP_DeletePortMapping() returned : %d\n", r); + freeUPNPDevlist(devlist); devlist = 0; + FreeUPNPUrls(&urls); + return; + } + if (i % 600 == 0) // Refresh every 20 minutes + { +#ifndef UPNPDISCOVER_SUCCESS + /* miniupnpc 1.5 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); +#else + /* miniupnpc 1.6 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); +#endif + + if(r!=UPNPCOMMAND_SUCCESS) + printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", + port.c_str(), port.c_str(), lanaddr, r, strupnperror(r)); + else + printf("UPnP Port Mapping successful.\n");; + } + Sleep(2000); + i++; + } + } else { + printf("No valid UPnP IGDs found\n"); + freeUPNPDevlist(devlist); devlist = 0; + if (r != 0) + FreeUPNPUrls(&urls); + while (true) { + if (fShutdown || !fUseUPnP) + return; + Sleep(2000); + } + } +} + +void MapPort() +{ + if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1) + { + if (!NewThread(ThreadMapPort, NULL)) + printf("Error: ThreadMapPort(ThreadMapPort) failed\n"); + } +} +#else +void MapPort() +{ + // Intentionally left blank. +} +#endif + + + + + + + + + +// DNS seeds +// Each pair gives a source name and a seed name. +// The first name is used as information source for addrman. +// The second name should resolve to a list of seed addresses. +static const char *strDNSSeed[][2] = { +{"WestSeed.BERNcoin.org", "WestSeed.BERNcoin.org"}, +{"EastSeed.BERNcoin.org", "EastSeed.BERNcoin.org"}, +{"bern-seed1.granitecoin.com", "bern-seed1.granitecoin.com"}, +{"bern-seed2.granitecoin.com", "bern-seed2.granitecoin.com"}, +{"bern-seed3.granitecoin.com", "bern-seed3.granitecoin.com"}, +{"bern-seed4.granitecoin.com", "bern-seed4.granitecoin.com"}, +{"bern-seed5.granitecoin.com", "bern-seed5.granitecoin.com"}, + +}; + +void ThreadDNSAddressSeed(void* parg) +{ + // Make this thread recognisable as the DNS seeding thread + RenameThread("BERN-dnsseed"); + + try + { + vnThreadsRunning[THREAD_DNSSEED]++; + ThreadDNSAddressSeed2(parg); + vnThreadsRunning[THREAD_DNSSEED]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_DNSSEED]--; + PrintException(&e, "ThreadDNSAddressSeed()"); + } catch (...) { + vnThreadsRunning[THREAD_DNSSEED]--; + throw; // support pthread_cancel() + } + printf("ThreadDNSAddressSeed exited\n"); +} + +void ThreadDNSAddressSeed2(void* parg) +{ + printf("ThreadDNSAddressSeed started\n"); + int found = 0; + + if (!fTestNet) + { + printf("Loading addresses from DNS seeds (could take a while)\n"); + + for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) { + if (HaveNameProxy()) { + AddOneShot(strDNSSeed[seed_idx][1]); + } else { + vector vaddr; + vector vAdd; + if (LookupHost(strDNSSeed[seed_idx][1], vaddr)) + { + BOOST_FOREACH(CNetAddr& ip, vaddr) + { + int nOneDay = 24*3600; + CAddress addr = CAddress(CService(ip, GetDefaultPort())); + addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old + vAdd.push_back(addr); + found++; + } + } + addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true)); + } + } + } + + printf("%d addresses found from DNS seeds\n", found); +} + + + + + + + + + + + + +unsigned int pnSeed[] = +{ +}; + +void DumpAddresses() +{ + int64 nStart = GetTimeMillis(); + + CAddrDB adb; + adb.Write(addrman); + + printf("Flushed %d addresses to peers.dat %"PRI64d"ms\n", + addrman.size(), GetTimeMillis() - nStart); +} + +void ThreadDumpAddress2(void* parg) +{ + vnThreadsRunning[THREAD_DUMPADDRESS]++; + while (!fShutdown) + { + DumpAddresses(); + vnThreadsRunning[THREAD_DUMPADDRESS]--; + Sleep(100000); + vnThreadsRunning[THREAD_DUMPADDRESS]++; + } + vnThreadsRunning[THREAD_DUMPADDRESS]--; +} + +void ThreadDumpAddress(void* parg) +{ + // Make this thread recognisable as the address dumping thread + RenameThread("bitcoin-adrdump"); + + try + { + ThreadDumpAddress2(parg); + } + catch (std::exception& e) { + PrintException(&e, "ThreadDumpAddress()"); + } + printf("ThreadDumpAddress exited\n"); +} + +void ThreadOpenConnections(void* parg) +{ + // Make this thread recognisable as the connection opening thread + RenameThread("bitcoin-opencon"); + + try + { + vnThreadsRunning[THREAD_OPENCONNECTIONS]++; + ThreadOpenConnections2(parg); + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + PrintException(&e, "ThreadOpenConnections()"); + } catch (...) { + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + PrintException(NULL, "ThreadOpenConnections()"); + } + printf("ThreadOpenConnections exited\n"); +} + +void static ProcessOneShot() +{ + string strDest; + { + LOCK(cs_vOneShots); + if (vOneShots.empty()) + return; + strDest = vOneShots.front(); + vOneShots.pop_front(); + } + CAddress addr; + CSemaphoreGrant grant(*semOutbound, true); + if (grant) { + if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true)) + AddOneShot(strDest); + } +} + +// ppcoin: stake minter thread +void static ThreadStakeMinter(void* parg) +{ + printf("ThreadStakeMinter started\n"); + CWallet* pwallet = (CWallet*)parg; + try + { + vnThreadsRunning[THREAD_CLOAKER]++; + BitcoinMiner(pwallet, true); + vnThreadsRunning[THREAD_CLOAKER]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_CLOAKER]--; + PrintException(&e, "ThreadStakeMinter()"); + } catch (...) { + vnThreadsRunning[THREAD_CLOAKER]--; + PrintException(NULL, "ThreadStakeMinter()"); + } + printf("ThreadStakeMinter exiting, %d threads remaining\n", vnThreadsRunning[THREAD_CLOAKER]); +} + +void ThreadOpenConnections2(void* parg) +{ + printf("ThreadOpenConnections started\n"); + + // Connect to specific addresses + if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) + { + for (int64 nLoop = 0;; nLoop++) + { + ProcessOneShot(); + BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"]) + { + CAddress addr; + OpenNetworkConnection(addr, NULL, strAddr.c_str()); + for (int i = 0; i < 10 && i < nLoop; i++) + { + Sleep(500); + if (fShutdown) + return; + } + } + Sleep(500); + } + } + + // Initiate network connections + int64 nStart = GetTime(); + while (true) + { + ProcessOneShot(); + + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + Sleep(500); + vnThreadsRunning[THREAD_OPENCONNECTIONS]++; + if (fShutdown) + return; + + + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + CSemaphoreGrant grant(*semOutbound); + vnThreadsRunning[THREAD_OPENCONNECTIONS]++; + if (fShutdown) + return; + + // Add seed nodes if IRC isn't working + if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet) + { + std::vector vAdd; + for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) + { + // 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 nOneWeek = 7*24*60*60; + struct in_addr ip; + memcpy(&ip, &pnSeed[i], sizeof(ip)); + CAddress addr(CService(ip, GetDefaultPort())); + addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek; + vAdd.push_back(addr); + } + addrman.Add(vAdd, CNetAddr("127.0.0.1")); + } + + // + // Choose an address to connect to based on most recently seen + // + CAddress addrConnect; + + // Only connect out to one peer per network group (/16 for IPv4). + // Do this here so we don't have to critsect vNodes inside mapAddresses critsect. + int nOutbound = 0; + set > setConnected; + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) { + if (!pnode->fInbound) { + setConnected.insert(pnode->addr.GetGroup()); + nOutbound++; + } + } + } + + int64 nANow = GetAdjustedTime(); + + int nTries = 0; + while (true) + { + // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections) + CAddress addr = addrman.Select(10 + min(nOutbound,8)*10); + + // if we selected an invalid address, restart + if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) + break; + + // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman, + // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates + // already-connected network ranges, ...) before trying new addrman addresses. + nTries++; + if (nTries > 100) + break; + + if (IsLimited(addr)) + continue; + + // only consider very recently tried nodes after 30 failed attempts + if (nANow - addr.nLastTry < 600 && nTries < 30) + continue; + + // do not allow non-default ports, unless after 50 invalid addresses selected already + if (addr.GetPort() != GetDefaultPort() && nTries < 50) + continue; + + addrConnect = addr; + break; + } + + if (addrConnect.IsValid()) + OpenNetworkConnection(addrConnect, &grant); + } +} + +void ThreadOpenAddedConnections(void* parg) +{ + // Make this thread recognisable as the connection opening thread + RenameThread("bitcoin-opencon"); + + try + { + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; + ThreadOpenAddedConnections2(parg); + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + PrintException(&e, "ThreadOpenAddedConnections()"); + } catch (...) { + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + PrintException(NULL, "ThreadOpenAddedConnections()"); + } + printf("ThreadOpenAddedConnections exited\n"); +} + +void ThreadOpenAddedConnections2(void* parg) +{ + printf("ThreadOpenAddedConnections started\n"); + + if (mapArgs.count("-addnode") == 0) + return; + + if (HaveNameProxy()) { + while(!fShutdown) { + BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) { + CAddress addr; + CSemaphoreGrant grant(*semOutbound); + OpenNetworkConnection(addr, &grant, strAddNode.c_str()); + Sleep(500); + } + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + Sleep(120000); // Retry every 2 minutes + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; + } + return; + } + + vector > vservAddressesToAdd(0); + BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) + { + vector vservNode(0); + if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0)) + { + vservAddressesToAdd.push_back(vservNode); + { + LOCK(cs_setservAddNodeAddresses); + BOOST_FOREACH(CService& serv, vservNode) + setservAddNodeAddresses.insert(serv); + } + } + } + while (true) + { + vector > vservConnectAddresses = vservAddressesToAdd; + // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry + // (keeping in mind that addnode entries can have many IPs if fNameLookup) + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + for (vector >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++) + BOOST_FOREACH(CService& addrNode, *(it)) + if (pnode->addr == addrNode) + { + it = vservConnectAddresses.erase(it); + it--; + break; + } + } + BOOST_FOREACH(vector& vserv, vservConnectAddresses) + { + CSemaphoreGrant grant(*semOutbound); + OpenNetworkConnection(CAddress(*(vserv.begin())), &grant); + Sleep(500); + if (fShutdown) + return; + } + if (fShutdown) + return; + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + Sleep(120000); // Retry every 2 minutes + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; + if (fShutdown) + return; + } +} + +// if successful, this moves the passed grant to the constructed node +bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot) +{ + // + // Initiate outbound network connection + // + if (fShutdown) + return false; + if (!strDest) + if (IsLocal(addrConnect) || + FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) || + FindNode(addrConnect.ToStringIPPort().c_str())) + return false; + if (strDest && FindNode(strDest)) + return false; + + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + CNode* pnode = ConnectNode(addrConnect, strDest); + vnThreadsRunning[THREAD_OPENCONNECTIONS]++; + if (fShutdown) + return false; + if (!pnode) + return false; + if (grantOutbound) + grantOutbound->MoveTo(pnode->grantOutbound); + pnode->fNetworkNode = true; + if (fOneShot) + pnode->fOneShot = true; + + return true; +} + + + + + + + + +void ThreadMessageHandler(void* parg) +{ + // Make this thread recognisable as the message handling thread + RenameThread("bitcoin-msghand"); + + try + { + vnThreadsRunning[THREAD_MESSAGEHANDLER]++; + ThreadMessageHandler2(parg); + vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + PrintException(&e, "ThreadMessageHandler()"); + } catch (...) { + vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + PrintException(NULL, "ThreadMessageHandler()"); + } + printf("ThreadMessageHandler exited\n"); +} + +void ThreadMessageHandler2(void* parg) +{ + printf("ThreadMessageHandler started\n"); + SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); + while (!fShutdown) + { + vector vNodesCopy; + { + LOCK(cs_vNodes); + vNodesCopy = vNodes; + BOOST_FOREACH(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } + + // Poll the connected nodes for messages + CNode* pnodeTrickle = NULL; + if (!vNodesCopy.empty()) + pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())]; + BOOST_FOREACH(CNode* pnode, vNodesCopy) + { + // Receive messages + { + TRY_LOCK(pnode->cs_vRecv, lockRecv); + if (lockRecv) + ProcessMessages(pnode); + } + if (fShutdown) + return; + + // Send messages + { + TRY_LOCK(pnode->cs_vSend, lockSend); + if (lockSend) + SendMessages(pnode, pnode == pnodeTrickle); + } + if (fShutdown) + return; + } + + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodesCopy) + pnode->Release(); + } + + // Wait and allow messages to bunch up. + // Reduce vnThreadsRunning so StopNode has permission to exit while + // we're sleeping, but we must always check fShutdown after doing this. + vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + Sleep(100); + if (fRequestShutdown) + StartShutdown(); + vnThreadsRunning[THREAD_MESSAGEHANDLER]++; + if (fShutdown) + return; + } +} + + + + + + +bool BindListenPort(const CService &addrBind, string& strError) +{ + strError = ""; + int nOne = 1; + +#ifdef WIN32 + // Initialize Windows Sockets + WSADATA wsadata; + int ret = WSAStartup(MAKEWORD(2,2), &wsadata); + if (ret != NO_ERROR) + { + strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret); + printf("%s\n", strError.c_str()); + return false; + } +#endif + + // Create socket for listening for incoming connections +#ifdef USE_IPV6 + struct sockaddr_storage sockaddr; +#else + struct sockaddr sockaddr; +#endif + socklen_t len = sizeof(sockaddr); + if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len)) + { + strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str()); + printf("%s\n", strError.c_str()); + return false; + } + + SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (hListenSocket == INVALID_SOCKET) + { + strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + +#ifdef SO_NOSIGPIPE + // Different way of disabling SIGPIPE on BSD + setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); +#endif + +#ifndef WIN32 + // Allow binding if the port is still in TIME_WAIT state after + // the program was closed and restarted. Not an issue on windows. + setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); +#endif + + +#ifdef WIN32 + // Set to non-blocking, incoming connections will also inherit this + if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR) +#else + if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) +#endif + { + strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + +#ifdef USE_IPV6 + // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option + // and enable it by default or not. Try to enable it, if possible. + if (addrBind.IsIPv6()) { +#ifdef IPV6_V6ONLY +#ifdef WIN32 + setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int)); +#else + setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int)); +#endif +#endif +#ifdef WIN32 + int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */; + int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */; + // this call is allowed to fail + setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int)); +#endif + } +#endif + + if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) + { + int nErr = WSAGetLastError(); + if (nErr == WSAEADDRINUSE) + strError = strprintf(_("Unable to bind to %s on this computer. BERN is probably already running."), addrBind.ToString().c_str()); + else + strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr)); + printf("%s\n", strError.c_str()); + return false; + } + printf("Bound to %s\n", addrBind.ToString().c_str()); + + // Listen for incoming connections + if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) + { + strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + vhListenSocket.push_back(hListenSocket); + + if (addrBind.IsRoutable() && fDiscover) + AddLocal(addrBind, LOCAL_BIND); + + return true; +} + +void static Discover() +{ + if (!fDiscover) + return; + +#ifdef WIN32 + // Get local host IP + char pszHostName[1000] = ""; + if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) + { + vector vaddr; + if (LookupHost(pszHostName, vaddr)) + { + BOOST_FOREACH (const CNetAddr &addr, vaddr) + { + AddLocal(addr, LOCAL_IF); + } + } + } +#else + // Get local host ip + struct ifaddrs* myaddrs; + if (getifaddrs(&myaddrs) == 0) + { + for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == NULL) continue; + if ((ifa->ifa_flags & IFF_UP) == 0) continue; + if (strcmp(ifa->ifa_name, "lo") == 0) continue; + if (strcmp(ifa->ifa_name, "lo0") == 0) continue; + if (ifa->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr); + CNetAddr addr(s4->sin_addr); + if (AddLocal(addr, LOCAL_IF)) + printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str()); + } +#ifdef USE_IPV6 + else if (ifa->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr); + CNetAddr addr(s6->sin6_addr); + if (AddLocal(addr, LOCAL_IF)) + printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str()); + } +#endif + } + freeifaddrs(myaddrs); + } +#endif + + // Don't use external IPv4 discovery, when -onlynet="IPv6" + if (!IsLimited(NET_IPV4)) + NewThread(ThreadGetMyExternalIP, NULL); +} + +void StartNode(void* parg) +{ + // Make this thread recognisable as the startup thread + RenameThread("bitcoin-start"); + + if (semOutbound == NULL) { + // initialize semaphore + int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125)); + semOutbound = new CSemaphore(nMaxOutbound); + } + + if (pnodeLocalHost == NULL) + pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices)); + + Discover(); + + // + // Start threads + // + + if (!GetBoolArg("-dnsseed", true)) + printf("DNS seeding disabled\n"); + else + if (!NewThread(ThreadDNSAddressSeed, NULL)) + printf("Error: NewThread(ThreadDNSAddressSeed) failed\n"); + + // Map ports with UPnP + if (fUseUPnP) + MapPort(); + + // Get addresses from IRC and advertise ours + if (!NewThread(ThreadIRCSeed, NULL)) + printf("Error: NewThread(ThreadIRCSeed) failed\n"); + + // Send and receive from sockets, accept connections + if (!NewThread(ThreadSocketHandler, NULL)) + printf("Error: NewThread(ThreadSocketHandler) failed\n"); + + // Initiate outbound connections from -addnode + if (!NewThread(ThreadOpenAddedConnections, NULL)) + printf("Error: NewThread(ThreadOpenAddedConnections) failed\n"); + + // Initiate outbound connections + if (!NewThread(ThreadOpenConnections, NULL)) + printf("Error: NewThread(ThreadOpenConnections) failed\n"); + + // Process messages + if (!NewThread(ThreadMessageHandler, NULL)) + printf("Error: NewThread(ThreadMessageHandler) failed\n"); + + // Dump network addresses + if (!NewThread(ThreadDumpAddress, NULL)) + printf("Error; NewThread(ThreadDumpAddress) failed\n"); + + if(fStaking) + { + // ppcoin: mint proof-of-stake blocks in the background + if (!NewThread(ThreadStakeMinter, pwalletMain)) + printf("Error: NewThread(ThreadStakeMinter) failed\n"); + } + else + { + printf("\n====================\n"); + printf("Staking is DISABLED.\n"); + printf("====================\n"); + } + + // Generate coins in the background + GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain); +} + +bool StopNode() +{ + printf("StopNode()\n"); + fShutdown = true; + nTransactionsUpdated++; + int64 nStart = GetTime(); + if (semOutbound) + for (int i=0; ipost(); + do + { + int nThreadsRunning = 0; + for (int n = 0; n < THREAD_MAX; n++) + nThreadsRunning += vnThreadsRunning[n]; + if (nThreadsRunning == 0) + break; + if (GetTime() - nStart > 20) + break; + Sleep(20); + } while(true); + if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n"); + if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n"); + if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n"); + if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n"); + if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n"); + if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n"); +#ifdef USE_UPNP + if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n"); +#endif + if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n"); + if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n"); + if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n"); + if (vnThreadsRunning[THREAD_CLOAKER] > 0) printf("ThreadStakeMinter still running\n"); + while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0) + Sleep(20); + Sleep(50); + DumpAddresses(); + return true; +} + +class CNetCleanup +{ +public: + CNetCleanup() + { + } + ~CNetCleanup() + { + // Close sockets + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->hSocket != INVALID_SOCKET) + closesocket(pnode->hSocket); + BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) + if (hListenSocket != INVALID_SOCKET) + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + +#ifdef WIN32 + // Shutdown Windows Sockets + WSACleanup(); +#endif + } +} +instance_of_cnetcleanup; diff --git a/src/net.h b/src/net.h new file mode 100644 index 0000000..9faa668 --- /dev/null +++ b/src/net.h @@ -0,0 +1,694 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_NET_H +#define BITCOIN_NET_H + +#include +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#include "mruset.h" +#include "netbase.h" +#include "protocol.h" +#include "addrman.h" + +class CRequestTracker; +class CNode; +class CBlockIndex; +extern int nBestHeight; + + + +inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); } +inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } + +void AddOneShot(std::string strDest); +bool RecvLine(SOCKET hSocket, std::string& strLine); +bool GetMyExternalIP(CNetAddr& ipRet); +void AddressCurrentlyConnected(const CService& addr); +CNode* FindNode(const CNetAddr& ip); +CNode* FindNode(const CService& ip); +CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0); +void MapPort(); +unsigned short GetListenPort(); +bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string())); +void StartNode(void* parg); +bool StopNode(); + +enum +{ + LOCAL_NONE, // unknown + LOCAL_IF, // address a local interface listens on + LOCAL_BIND, // address explicit bound to + LOCAL_UPNP, // address reported by UPnP + LOCAL_IRC, // address reported by IRC (deprecated) + LOCAL_HTTP, // address reported by whatismyip.com and similar + LOCAL_MANUAL, // address explicitly specified (-externalip=) + + LOCAL_MAX +}; + +void SetLimited(enum Network net, bool fLimited = true); +bool IsLimited(enum Network net); +bool IsLimited(const CNetAddr& addr); +bool AddLocal(const CService& addr, int nScore = LOCAL_NONE); +bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); +bool SeenLocal(const CService& addr); +bool IsLocal(const CService& addr); +bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); +bool IsReachable(const CNetAddr &addr); +void SetReachable(enum Network net, bool fFlag = true); +CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); + + +enum +{ + MSG_TX = 1, + MSG_BLOCK, +}; + +class CRequestTracker +{ +public: + void (*fn)(void*, CDataStream&); + void* param1; + + explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL) + { + fn = fnIn; + param1 = param1In; + } + + bool IsNull() + { + return fn == NULL; + } +}; + + +/** Thread types */ +enum threadId +{ + THREAD_SOCKETHANDLER, + THREAD_OPENCONNECTIONS, + THREAD_MESSAGEHANDLER, + THREAD_MINER, + THREAD_RPCLISTENER, + THREAD_UPNP, + THREAD_DNSSEED, + THREAD_ADDEDCONNECTIONS, + THREAD_DUMPADDRESS, + THREAD_RPCHANDLER, + THREAD_CLOAKER, + + THREAD_MAX +}; + +extern bool fClient; +extern bool fDiscover; +extern bool fUseUPnP; +extern uint64 nLocalServices; +extern uint64 nLocalHostNonce; +extern CAddress addrSeenByPeer; +extern boost::array vnThreadsRunning; +extern CAddrMan addrman; + +extern std::vector vNodes; +extern CCriticalSection cs_vNodes; +extern std::map mapRelay; +extern std::deque > vRelayExpiration; +extern CCriticalSection cs_mapRelay; +extern std::map mapAlreadyAskedFor; + + + + +class CNodeStats +{ +public: + uint64 nServices; + int64 nLastSend; + int64 nLastRecv; + int64 nTimeConnected; + std::string addrName; + int nVersion; + std::string strSubVer; + bool fInbound; + int64 nReleaseTime; + int nStartingHeight; + int nMisbehavior; +}; + + + + + +/** Information about a peer */ +class CNode +{ +public: + // socket + uint64 nServices; + SOCKET hSocket; + CDataStream vSend; + CDataStream vRecv; + CCriticalSection cs_vSend; + CCriticalSection cs_vRecv; + int64 nLastSend; + int64 nLastRecv; + int64 nLastSendEmpty; + int64 nTimeConnected; + int nHeaderStart; + unsigned int nMessageStart; + CAddress addr; + std::string addrName; + CService addrLocal; + int nVersion; + std::string strSubVer; + bool fOneShot; + bool fClient; + bool fInbound; + bool fNetworkNode; + bool fSuccessfullyConnected; + bool fDisconnect; + CSemaphoreGrant grantOutbound; +protected: + int nRefCount; + + // Denial-of-service detection/prevention + // Key is IP address, value is banned-until-time + static std::map setBanned; + static CCriticalSection cs_setBanned; + int nMisbehavior; + +public: + int64 nReleaseTime; + std::map mapRequests; + CCriticalSection cs_mapRequests; + uint256 hashContinue; + CBlockIndex* pindexLastGetBlocksBegin; + uint256 hashLastGetBlocksEnd; + int nStartingHeight; + + // flood relay + std::vector vAddrToSend; + std::set setAddrKnown; + bool fGetAddr; + std::set setKnown; + uint256 hashCheckpointKnown; // ppcoin: known sent sync-checkpoint + + // inventory based relay + mruset setInventoryKnown; + std::vector vInventoryToSend; + CCriticalSection cs_inventory; + std::multimap mapAskFor; + + CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION) + { + nServices = 0; + hSocket = hSocketIn; + nLastSend = 0; + nLastRecv = 0; + nLastSendEmpty = GetTime(); + nTimeConnected = GetTime(); + nHeaderStart = -1; + nMessageStart = -1; + addr = addrIn; + addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; + nVersion = 0; + strSubVer = ""; + fOneShot = false; + fClient = false; // set by version message + fInbound = fInboundIn; + fNetworkNode = false; + fSuccessfullyConnected = false; + fDisconnect = false; + nRefCount = 0; + nReleaseTime = 0; + hashContinue = 0; + pindexLastGetBlocksBegin = 0; + hashLastGetBlocksEnd = 0; + nStartingHeight = -1; + fGetAddr = false; + nMisbehavior = 0; + hashCheckpointKnown = 0; + setInventoryKnown.max_size(SendBufferSize() / 1000); + + // Be shy and don't send version until we hear + if (!fInbound) + PushVersion(); + } + + ~CNode() + { + if (hSocket != INVALID_SOCKET) + { + closesocket(hSocket); + hSocket = INVALID_SOCKET; + } + } + +private: + CNode(const CNode&); + void operator=(const CNode&); +public: + + + int GetRefCount() + { + return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); + } + + CNode* AddRef(int64 nTimeout=0) + { + if (nTimeout != 0) + nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout); + else + nRefCount++; + return this; + } + + void Release() + { + nRefCount--; + } + + + + void AddAddressKnown(const CAddress& addr) + { + setAddrKnown.insert(addr); + } + + void PushAddress(const CAddress& addr) + { + // Known checking here is only to save space from duplicates. + // SendMessages will filter it again for knowns that were added + // after addresses were pushed. + if (addr.IsValid() && !setAddrKnown.count(addr)) + vAddrToSend.push_back(addr); + } + + + void AddInventoryKnown(const CInv& inv) + { + { + LOCK(cs_inventory); + setInventoryKnown.insert(inv); + } + } + + void PushInventory(const CInv& inv) + { + { + LOCK(cs_inventory); + if (!setInventoryKnown.count(inv)) + vInventoryToSend.push_back(inv); + } + } + + void AskFor(const CInv& inv) + { + // We're using mapAskFor as a priority queue, + // the key is the earliest time the request can be sent + int64& nRequestTime = mapAlreadyAskedFor[inv]; + if (fDebugNet) + printf("askfor %s %"PRI64d" (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str()); + + // Make sure not to reuse time indexes to keep things in the same order + int64 nNow = (GetTime() - 1) * 1000000; + static int64 nLastTime; + ++nLastTime; + nNow = std::max(nNow, nLastTime); + nLastTime = nNow; + + // Each retry is 2 minutes after the last + nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow); + mapAskFor.insert(std::make_pair(nRequestTime, inv)); + } + + + + void BeginMessage(const char* pszCommand) + { + ENTER_CRITICAL_SECTION(cs_vSend); + if (nHeaderStart != -1) + AbortMessage(); + nHeaderStart = vSend.size(); + vSend << CMessageHeader(pszCommand, 0); + nMessageStart = vSend.size(); + if (fDebug) + printf("sending: %s ", pszCommand); + } + + void AbortMessage() + { + if (nHeaderStart < 0) + return; + vSend.resize(nHeaderStart); + nHeaderStart = -1; + nMessageStart = -1; + LEAVE_CRITICAL_SECTION(cs_vSend); + + if (fDebug) + printf("(aborted)\n"); + } + + void EndMessage() + { + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) + { + printf("dropmessages DROPPING SEND MESSAGE\n"); + AbortMessage(); + return; + } + + if (nHeaderStart < 0) + return; + + // Set the size + unsigned int nSize = vSend.size() - nMessageStart; + memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize)); + + // Set the checksum + uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end()); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum)); + memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum)); + + if (fDebug) { + printf("(%d bytes)\n", nSize); + } + + nHeaderStart = -1; + nMessageStart = -1; + LEAVE_CRITICAL_SECTION(cs_vSend); + } + + void EndMessageAbortIfEmpty() + { + if (nHeaderStart < 0) + return; + int nSize = vSend.size() - nMessageStart; + if (nSize > 0) + EndMessage(); + else + AbortMessage(); + } + + + + void PushVersion(); + + + void PushMessage(const char* pszCommand) + { + try + { + BeginMessage(pszCommand); + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1) + { + try + { + BeginMessage(pszCommand); + vSend << a1; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + + void PushRequest(const char* pszCommand, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + { + LOCK(cs_mapRequests); + mapRequests[hashReply] = CRequestTracker(fn, param1); + } + + PushMessage(pszCommand, hashReply); + } + + template + void PushRequest(const char* pszCommand, const T1& a1, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + { + LOCK(cs_mapRequests); + mapRequests[hashReply] = CRequestTracker(fn, param1); + } + + PushMessage(pszCommand, hashReply, a1); + } + + template + void PushRequest(const char* pszCommand, const T1& a1, const T2& a2, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + { + LOCK(cs_mapRequests); + mapRequests[hashReply] = CRequestTracker(fn, param1); + } + + PushMessage(pszCommand, hashReply, a1, a2); + } + + + + void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd); + bool IsSubscribed(unsigned int nChannel); + void Subscribe(unsigned int nChannel, unsigned int nHops=0); + void CancelSubscribe(unsigned int nChannel); + void CloseSocketDisconnect(); + void Cleanup(); + + + // Denial-of-service detection/prevention + // The idea is to detect peers that are behaving + // badly and disconnect/ban them, but do it in a + // one-coding-mistake-won't-shatter-the-entire-network + // way. + // IMPORTANT: There should be nothing I can give a + // node that it will forward on that will make that + // node's peers drop it. If there is, an attacker + // can isolate a node and/or try to split the network. + // Dropping a node for sending stuff that is invalid + // now but might be valid in a later version is also + // dangerous, because it can cause a network split + // between nodes running old code and nodes running + // new code. + static void ClearBanned(); // needed for unit testing + static bool IsBanned(CNetAddr ip); + bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot + void copyStats(CNodeStats &stats); +}; + + + + + + + + + + +inline void RelayInventory(const CInv& inv) +{ + // Put on lists to offer to the other nodes + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + pnode->PushInventory(inv); + } +} + +template +void RelayMessage(const CInv& inv, const T& a) +{ + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss.reserve(10000); + ss << a; + RelayMessage(inv, ss); +} + +template<> +inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) +{ + { + LOCK(cs_mapRelay); + // Expire old relay messages + while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) + { + mapRelay.erase(vRelayExpiration.front().second); + vRelayExpiration.pop_front(); + } + + // Save original serialized message so newer versions are preserved + mapRelay.insert(std::make_pair(inv, ss)); + vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv)); + } + + RelayInventory(inv); +} + + +#endif diff --git a/src/netbase.cpp b/src/netbase.cpp new file mode 100644 index 0000000..95d6493 --- /dev/null +++ b/src/netbase.cpp @@ -0,0 +1,1180 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "netbase.h" +#include "util.h" +#include "sync.h" + +#ifndef WIN32 +#include +#endif + +#include "strlcpy.h" +#include // for to_lower() + +using namespace std; + +// Settings +static proxyType proxyInfo[NET_MAX]; +static proxyType nameproxyInfo; +static CCriticalSection cs_proxyInfos; +int nConnectTimeout = 5000; +bool fNameLookup = false; + +static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; + +enum Network ParseNetwork(std::string net) { + boost::to_lower(net); + if (net == "ipv4") return NET_IPV4; + if (net == "ipv6") return NET_IPV6; + if (net == "tor") return NET_TOR; + if (net == "i2p") return NET_I2P; + return NET_UNROUTABLE; +} + +void SplitHostPort(std::string in, int &portOut, std::string &hostOut) { + size_t colon = in.find_last_of(':'); + // if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator + bool fHaveColon = colon != in.npos; + bool fBracketed = fHaveColon && (in[0]=='[' && in[colon-1]==']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe + bool fMultiColon = fHaveColon && (in.find_last_of(':',colon-1) != in.npos); + if (fHaveColon && (colon==0 || fBracketed || !fMultiColon)) { + char *endp = NULL; + int n = strtol(in.c_str() + colon + 1, &endp, 10); + if (endp && *endp == 0 && n >= 0) { + in = in.substr(0, colon); + if (n > 0 && n < 0x10000) + portOut = n; + } + } + if (in.size()>0 && in[0] == '[' && in[in.size()-1] == ']') + hostOut = in.substr(1, in.size()-2); + else + hostOut = in; +} + +bool static LookupIntern(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup) +{ + vIP.clear(); + + { + CNetAddr addr; + if (addr.SetSpecial(std::string(pszName))) { + vIP.push_back(addr); + return true; + } + } + + struct addrinfo aiHint; + memset(&aiHint, 0, sizeof(struct addrinfo)); + + aiHint.ai_socktype = SOCK_STREAM; + aiHint.ai_protocol = IPPROTO_TCP; +#ifdef WIN32 +# ifdef USE_IPV6 + aiHint.ai_family = AF_UNSPEC; +# else + aiHint.ai_family = AF_INET; +# endif + aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST; +#else +# ifdef USE_IPV6 + aiHint.ai_family = AF_UNSPEC; +# else + aiHint.ai_family = AF_INET; +# endif + aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; +#endif + struct addrinfo *aiRes = NULL; + int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); + if (nErr) + return false; + + struct addrinfo *aiTrav = aiRes; + while (aiTrav != NULL && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions)) + { + if (aiTrav->ai_family == AF_INET) + { + assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in)); + vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr)); + } + +#ifdef USE_IPV6 + if (aiTrav->ai_family == AF_INET6) + { + assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6)); + vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr)); + } +#endif + + aiTrav = aiTrav->ai_next; + } + + freeaddrinfo(aiRes); + + return (vIP.size() > 0); +} + +bool LookupHost(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup) +{ + if (pszName[0] == 0) + return false; + char psz[256]; + char *pszHost = psz; + strlcpy(psz, pszName, sizeof(psz)); + if (psz[0] == '[' && psz[strlen(psz)-1] == ']') + { + pszHost = psz+1; + psz[strlen(psz)-1] = 0; + } + + return LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup); +} + +bool LookupHostNumeric(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions) +{ + return LookupHost(pszName, vIP, nMaxSolutions, false); +} + +bool Lookup(const char *pszName, std::vector& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions) +{ + if (pszName[0] == 0) + return false; + int port = portDefault; + std::string hostname = ""; + SplitHostPort(std::string(pszName), port, hostname); + + std::vector vIP; + bool fRet = LookupIntern(hostname.c_str(), vIP, nMaxSolutions, fAllowLookup); + if (!fRet) + return false; + vAddr.resize(vIP.size()); + for (unsigned int i = 0; i < vIP.size(); i++) + vAddr[i] = CService(vIP[i], port); + return true; +} + +bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup) +{ + std::vector vService; + bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1); + if (!fRet) + return false; + addr = vService[0]; + return true; +} + +bool LookupNumeric(const char *pszName, CService& addr, int portDefault) +{ + return Lookup(pszName, addr, portDefault, false); +} + +bool static Socks4(const CService &addrDest, SOCKET& hSocket) +{ + printf("SOCKS4 connecting %s\n", addrDest.ToString().c_str()); + if (!addrDest.IsIPv4()) + { + closesocket(hSocket); + return error("Proxy destination is not IPv4"); + } + char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; + struct sockaddr_in addr; + socklen_t len = sizeof(addr); + if (!addrDest.GetSockAddr((struct sockaddr*)&addr, &len) || addr.sin_family != AF_INET) + { + closesocket(hSocket); + return error("Cannot get proxy destination address"); + } + memcpy(pszSocks4IP + 2, &addr.sin_port, 2); + memcpy(pszSocks4IP + 4, &addr.sin_addr, 4); + char* pszSocks4 = pszSocks4IP; + int nSize = sizeof(pszSocks4IP); + + int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL); + if (ret != nSize) + { + closesocket(hSocket); + return error("Error sending to proxy"); + } + char pchRet[8]; + if (recv(hSocket, pchRet, 8, 0) != 8) + { + closesocket(hSocket); + return error("Error reading proxy response"); + } + if (pchRet[1] != 0x5a) + { + closesocket(hSocket); + if (pchRet[1] != 0x5b) + printf("ERROR: Proxy returned error %d\n", pchRet[1]); + return false; + } + printf("SOCKS4 connected %s\n", addrDest.ToString().c_str()); + return true; +} + +bool static Socks5(string strDest, int port, SOCKET& hSocket) +{ + printf("SOCKS5 connecting %s\n", strDest.c_str()); + if (strDest.size() > 255) + { + closesocket(hSocket); + return error("Hostname too long"); + } + char pszSocks5Init[] = "\5\1\0"; + char *pszSocks5 = pszSocks5Init; + ssize_t nSize = sizeof(pszSocks5Init) - 1; + + ssize_t ret = send(hSocket, pszSocks5, nSize, MSG_NOSIGNAL); + if (ret != nSize) + { + closesocket(hSocket); + return error("Error sending to proxy"); + } + char pchRet1[2]; + if (recv(hSocket, pchRet1, 2, 0) != 2) + { + closesocket(hSocket); + return error("Error reading proxy response"); + } + if (pchRet1[0] != 0x05 || pchRet1[1] != 0x00) + { + closesocket(hSocket); + return error("Proxy failed to initialize"); + } + string strSocks5("\5\1"); + strSocks5 += '\000'; strSocks5 += '\003'; + strSocks5 += static_cast(std::min((int)strDest.size(), 255)); + strSocks5 += strDest; + strSocks5 += static_cast((port >> 8) & 0xFF); + strSocks5 += static_cast((port >> 0) & 0xFF); + ret = send(hSocket, strSocks5.c_str(), strSocks5.size(), MSG_NOSIGNAL); + if (ret != (ssize_t)strSocks5.size()) + { + closesocket(hSocket); + return error("Error sending to proxy"); + } + char pchRet2[4]; + if (recv(hSocket, pchRet2, 4, 0) != 4) + { + closesocket(hSocket); + return error("Error reading proxy response"); + } + if (pchRet2[0] != 0x05) + { + closesocket(hSocket); + return error("Proxy failed to accept request"); + } + if (pchRet2[1] != 0x00) + { + closesocket(hSocket); + switch (pchRet2[1]) + { + case 0x01: return error("Proxy error: general failure"); + case 0x02: return error("Proxy error: connection not allowed"); + case 0x03: return error("Proxy error: network unreachable"); + case 0x04: return error("Proxy error: host unreachable"); + case 0x05: return error("Proxy error: connection refused"); + case 0x06: return error("Proxy error: TTL expired"); + case 0x07: return error("Proxy error: protocol error"); + case 0x08: return error("Proxy error: address type not supported"); + default: return error("Proxy error: unknown"); + } + } + if (pchRet2[2] != 0x00) + { + closesocket(hSocket); + return error("Error: malformed proxy response"); + } + char pchRet3[256]; + switch (pchRet2[3]) + { + case 0x01: ret = recv(hSocket, pchRet3, 4, 0) != 4; break; + case 0x04: ret = recv(hSocket, pchRet3, 16, 0) != 16; break; + case 0x03: + { + ret = recv(hSocket, pchRet3, 1, 0) != 1; + if (ret) + return error("Error reading from proxy"); + int nRecv = pchRet3[0]; + ret = recv(hSocket, pchRet3, nRecv, 0) != nRecv; + break; + } + default: closesocket(hSocket); return error("Error: malformed proxy response"); + } + if (ret) + { + closesocket(hSocket); + return error("Error reading from proxy"); + } + if (recv(hSocket, pchRet3, 2, 0) != 2) + { + closesocket(hSocket); + return error("Error reading from proxy"); + } + printf("SOCKS5 connected %s\n", strDest.c_str()); + return true; +} + +bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout) +{ + hSocketRet = INVALID_SOCKET; + +#ifdef USE_IPV6 + struct sockaddr_storage sockaddr; +#else + struct sockaddr sockaddr; +#endif + socklen_t len = sizeof(sockaddr); + if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) { + printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str()); + return false; + } + + SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (hSocket == INVALID_SOCKET) + return false; +#ifdef SO_NOSIGPIPE + int set = 1; + setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); +#endif + +#ifdef WIN32 + u_long fNonblock = 1; + if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) +#else + int fFlags = fcntl(hSocket, F_GETFL, 0); + if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1) +#endif + { + closesocket(hSocket); + return false; + } + + if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) + { + // WSAEINVAL is here because some legacy version of winsock uses it + if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL) + { + struct timeval timeout; + timeout.tv_sec = nTimeout / 1000; + timeout.tv_usec = (nTimeout % 1000) * 1000; + + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(hSocket, &fdset); + int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); + if (nRet == 0) + { + printf("connection timeout\n"); + closesocket(hSocket); + return false; + } + if (nRet == SOCKET_ERROR) + { + printf("select() for connection failed: %i\n",WSAGetLastError()); + closesocket(hSocket); + return false; + } + socklen_t nRetSize = sizeof(nRet); +#ifdef WIN32 + if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) +#else + if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) +#endif + { + printf("getsockopt() for connection failed: %i\n",WSAGetLastError()); + closesocket(hSocket); + return false; + } + if (nRet != 0) + { + printf("connect() failed after select(): %s\n",strerror(nRet)); + closesocket(hSocket); + return false; + } + } +#ifdef WIN32 + else if (WSAGetLastError() != WSAEISCONN) +#else + else +#endif + { + printf("connect() failed: %i\n",WSAGetLastError()); + closesocket(hSocket); + return false; + } + } + + // this isn't even strictly necessary + // CNode::ConnectNode immediately turns the socket back to non-blocking + // but we'll turn it back to blocking just in case +#ifdef WIN32 + fNonblock = 0; + if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) +#else + fFlags = fcntl(hSocket, F_GETFL, 0); + if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR) +#endif + { + closesocket(hSocket); + return false; + } + + hSocketRet = hSocket; + return true; +} + +bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) { + assert(net >= 0 && net < NET_MAX); + if (nSocksVersion != 0 && nSocksVersion != 4 && nSocksVersion != 5) + return false; + if (nSocksVersion != 0 && !addrProxy.IsValid()) + return false; + LOCK(cs_proxyInfos); + proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion); + return true; +} + +bool GetProxy(enum Network net, proxyType &proxyInfoOut) { + assert(net >= 0 && net < NET_MAX); + LOCK(cs_proxyInfos); + if (!proxyInfo[net].second) + return false; + proxyInfoOut = proxyInfo[net]; + return true; +} + +bool SetNameProxy(CService addrProxy, int nSocksVersion) { + if (nSocksVersion != 0 && nSocksVersion != 5) + return false; + if (nSocksVersion != 0 && !addrProxy.IsValid()) + return false; + LOCK(cs_proxyInfos); + nameproxyInfo = std::make_pair(addrProxy, nSocksVersion); + return true; +} + +bool GetNameProxy(proxyType &nameproxyInfoOut) { + LOCK(cs_proxyInfos); + if (!nameproxyInfo.second) + return false; + nameproxyInfoOut = nameproxyInfo; + return true; +} + +bool HaveNameProxy() { + LOCK(cs_proxyInfos); + return nameproxyInfo.second != 0; +} + +bool IsProxy(const CNetAddr &addr) { + LOCK(cs_proxyInfos); + for (int i = 0; i < NET_MAX; i++) { + if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first)) + return true; + } + return false; +} + +bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout) +{ + proxyType proxy; + + // no proxy needed + if (!GetProxy(addrDest.GetNetwork(), proxy)) + return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout); + + SOCKET hSocket = INVALID_SOCKET; + + // first connect to proxy server + if (!ConnectSocketDirectly(proxy.first, hSocket, nTimeout)) + return false; + + // do socks negotiation + switch (proxy.second) { + case 4: + if (!Socks4(addrDest, hSocket)) + return false; + break; + case 5: + if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket)) + return false; + break; + default: + return false; + } + + hSocketRet = hSocket; + return true; +} + +bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout) +{ + string strDest; + int port = portDefault; + SplitHostPort(string(pszDest), port, strDest); + + SOCKET hSocket = INVALID_SOCKET; + + proxyType nameproxy; + GetNameProxy(nameproxy); + + CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxy.second), port); + if (addrResolved.IsValid()) { + addr = addrResolved; + return ConnectSocket(addr, hSocketRet, nTimeout); + } + addr = CService("0.0.0.0:0"); + if (!nameproxy.second) + return false; + if (!ConnectSocketDirectly(nameproxy.first, hSocket, nTimeout)) + return false; + + switch(nameproxy.second) { + default: + case 4: return false; + case 5: + if (!Socks5(strDest, port, hSocket)) + return false; + break; + } + + hSocketRet = hSocket; + return true; +} + +void CNetAddr::Init() +{ + memset(ip, 0, 16); +} + +void CNetAddr::SetIP(const CNetAddr& ipIn) +{ + memcpy(ip, ipIn.ip, sizeof(ip)); +} + +static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43}; +static const unsigned char pchGarliCat[] = {0xFD,0x60,0xDB,0x4D,0xDD,0xB5}; + +bool CNetAddr::SetSpecial(const std::string &strName) +{ + if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") { + std::vector vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str()); + if (vchAddr.size() != 16-sizeof(pchOnionCat)) + return false; + memcpy(ip, pchOnionCat, sizeof(pchOnionCat)); + for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++) + ip[i + sizeof(pchOnionCat)] = vchAddr[i]; + return true; + } + if (strName.size()>11 && strName.substr(strName.size() - 11, 11) == ".oc.b32.i2p") { + std::vector vchAddr = DecodeBase32(strName.substr(0, strName.size() - 11).c_str()); + if (vchAddr.size() != 16-sizeof(pchGarliCat)) + return false; + memcpy(ip, pchOnionCat, sizeof(pchGarliCat)); + for (unsigned int i=0; i<16-sizeof(pchGarliCat); i++) + ip[i + sizeof(pchGarliCat)] = vchAddr[i]; + return true; + } + return false; +} + +CNetAddr::CNetAddr() +{ + Init(); +} + +CNetAddr::CNetAddr(const struct in_addr& ipv4Addr) +{ + memcpy(ip, pchIPv4, 12); + memcpy(ip+12, &ipv4Addr, 4); +} + +#ifdef USE_IPV6 +CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr) +{ + memcpy(ip, &ipv6Addr, 16); +} +#endif + +CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup) +{ + Init(); + std::vector vIP; + if (LookupHost(pszIp, vIP, 1, fAllowLookup)) + *this = vIP[0]; +} + +CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup) +{ + Init(); + std::vector vIP; + if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup)) + *this = vIP[0]; +} + +unsigned int CNetAddr::GetByte(int n) const +{ + return ip[15-n]; +} + +bool CNetAddr::IsIPv4() const +{ + return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0); +} + +bool CNetAddr::IsIPv6() const +{ + return (!IsIPv4() && !IsTor() && !IsI2P()); +} + +bool CNetAddr::IsRFC1918() const +{ + return IsIPv4() && ( + GetByte(3) == 10 || + (GetByte(3) == 192 && GetByte(2) == 168) || + (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31))); +} + +bool CNetAddr::IsRFC3927() const +{ + return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254); +} + +bool CNetAddr::IsRFC3849() const +{ + return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8; +} + +bool CNetAddr::IsRFC3964() const +{ + return (GetByte(15) == 0x20 && GetByte(14) == 0x02); +} + +bool CNetAddr::IsRFC6052() const +{ + static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0}; + return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0); +} + +bool CNetAddr::IsRFC4380() const +{ + return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0); +} + +bool CNetAddr::IsRFC4862() const +{ + static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0}; + return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0); +} + +bool CNetAddr::IsRFC4193() const +{ + return ((GetByte(15) & 0xFE) == 0xFC); +} + +bool CNetAddr::IsRFC6145() const +{ + static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0}; + return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0); +} + +bool CNetAddr::IsRFC4843() const +{ + return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10); +} + +bool CNetAddr::IsTor() const +{ + return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0); +} + +bool CNetAddr::IsI2P() const +{ + return (memcmp(ip, pchGarliCat, sizeof(pchGarliCat)) == 0); +} + +bool CNetAddr::IsLocal() const +{ + // IPv4 loopback + if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0)) + return true; + + // IPv6 loopback (::1/128) + static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + if (memcmp(ip, pchLocal, 16) == 0) + return true; + + return false; +} + +bool CNetAddr::IsMulticast() const +{ + return (IsIPv4() && (GetByte(3) & 0xF0) == 0xE0) + || (GetByte(15) == 0xFF); +} + +bool CNetAddr::IsValid() const +{ + // Cleanup 3-byte shifted addresses caused by garbage in size field + // of addr messages from versions before 0.2.9 checksum. + // Two consecutive addr messages look like this: + // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... + // so if the first length field is garbled, it reads the second batch + // of addr misaligned by 3 bytes. + if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0) + return false; + + // unspecified IPv6 address (::/128) + unsigned char ipNone[16] = {}; + if (memcmp(ip, ipNone, 16) == 0) + return false; + + // documentation IPv6 address + if (IsRFC3849()) + return false; + + if (IsIPv4()) + { + // INADDR_NONE + uint32_t ipNone = INADDR_NONE; + if (memcmp(ip+12, &ipNone, 4) == 0) + return false; + + // 0 + ipNone = 0; + if (memcmp(ip+12, &ipNone, 4) == 0) + return false; + } + + return true; +} + +bool CNetAddr::IsRoutable() const +{ + return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || (IsRFC4193() && !IsTor() && !IsI2P()) || IsRFC4843() || IsLocal()); +} + +enum Network CNetAddr::GetNetwork() const +{ + if (!IsRoutable()) + return NET_UNROUTABLE; + + if (IsIPv4()) + return NET_IPV4; + + if (IsTor()) + return NET_TOR; + + if (IsI2P()) + return NET_I2P; + + return NET_IPV6; +} + +std::string CNetAddr::ToStringIP() const +{ + if (IsTor()) + return EncodeBase32(&ip[6], 10) + ".onion"; + if (IsI2P()) + return EncodeBase32(&ip[6], 10) + ".oc.b32.i2p"; + CService serv(*this, 0); +#ifdef USE_IPV6 + struct sockaddr_storage sockaddr; +#else + struct sockaddr sockaddr; +#endif + socklen_t socklen = sizeof(sockaddr); + if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) { + char name[1025] = ""; + if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST)) + return std::string(name); + } + if (IsIPv4()) + return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); + else + return strprintf("%x:%x:%x:%x:%x:%x:%x:%x", + GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12), + GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8), + GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4), + GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0)); +} + +std::string CNetAddr::ToString() const +{ + return ToStringIP(); +} + +bool operator==(const CNetAddr& a, const CNetAddr& b) +{ + return (memcmp(a.ip, b.ip, 16) == 0); +} + +bool operator!=(const CNetAddr& a, const CNetAddr& b) +{ + return (memcmp(a.ip, b.ip, 16) != 0); +} + +bool operator<(const CNetAddr& a, const CNetAddr& b) +{ + return (memcmp(a.ip, b.ip, 16) < 0); +} + +bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const +{ + if (!IsIPv4()) + return false; + memcpy(pipv4Addr, ip+12, 4); + return true; +} + +#ifdef USE_IPV6 +bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const +{ + memcpy(pipv6Addr, ip, 16); + return true; +} +#endif + +// get canonical identifier of an address' group +// no two connections will be attempted to addresses with the same group +std::vector CNetAddr::GetGroup() const +{ + std::vector vchRet; + int nClass = NET_IPV6; + int nStartByte = 0; + int nBits = 16; + + // all local addresses belong to the same group + if (IsLocal()) + { + nClass = 255; + nBits = 0; + } + + // all unroutable addresses belong to the same group + if (!IsRoutable()) + { + nClass = NET_UNROUTABLE; + nBits = 0; + } + // for IPv4 addresses, '1' + the 16 higher-order bits of the IP + // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix + else if (IsIPv4() || IsRFC6145() || IsRFC6052()) + { + nClass = NET_IPV4; + nStartByte = 12; + } + // for 6to4 tunnelled addresses, use the encapsulated IPv4 address + else if (IsRFC3964()) + { + nClass = NET_IPV4; + nStartByte = 2; + } + // for Teredo-tunnelled IPv6 addresses, use the encapsulated IPv4 address + else if (IsRFC4380()) + { + vchRet.push_back(NET_IPV4); + vchRet.push_back(GetByte(3) ^ 0xFF); + vchRet.push_back(GetByte(2) ^ 0xFF); + return vchRet; + } + else if (IsTor()) + { + nClass = NET_TOR; + nStartByte = 6; + nBits = 4; + } + else if (IsI2P()) + { + nClass = NET_I2P; + nStartByte = 6; + nBits = 4; + } + // for he.net, use /36 groups + else if (GetByte(15) == 0x20 && GetByte(14) == 0x11 && GetByte(13) == 0x04 && GetByte(12) == 0x70) + nBits = 36; + // for the rest of the IPv6 network, use /32 groups + else + nBits = 32; + + vchRet.push_back(nClass); + while (nBits >= 8) + { + vchRet.push_back(GetByte(15 - nStartByte)); + nStartByte++; + nBits -= 8; + } + if (nBits > 0) + vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1)); + + return vchRet; +} + +uint64 CNetAddr::GetHash() const +{ + uint256 hash = Hash(&ip[0], &ip[16]); + uint64 nRet; + memcpy(&nRet, &hash, sizeof(nRet)); + return nRet; +} + +void CNetAddr::print() const +{ + printf("CNetAddr(%s)\n", ToString().c_str()); +} + +// private extensions to enum Network, only returned by GetExtNetwork, +// and only used in GetReachabilityFrom +static const int NET_UNKNOWN = NET_MAX + 0; +static const int NET_TEREDO = NET_MAX + 1; +int static GetExtNetwork(const CNetAddr *addr) +{ + if (addr == NULL) + return NET_UNKNOWN; + if (addr->IsRFC4380()) + return NET_TEREDO; + return addr->GetNetwork(); +} + +/** Calculates a metric for how reachable (*this) is from a given partner */ +int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const +{ + enum Reachability { + REACH_UNREACHABLE, + REACH_DEFAULT, + REACH_TEREDO, + REACH_IPV6_WEAK, + REACH_IPV4, + REACH_IPV6_STRONG, + REACH_PRIVATE + }; + + if (!IsRoutable()) + return REACH_UNREACHABLE; + + int ourNet = GetExtNetwork(this); + int theirNet = GetExtNetwork(paddrPartner); + bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145(); + + switch(theirNet) { + case NET_IPV4: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_IPV4: return REACH_IPV4; + } + case NET_IPV6: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_TEREDO: return REACH_TEREDO; + case NET_IPV4: return REACH_IPV4; + case NET_IPV6: return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunnelled + } + case NET_TOR: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well + case NET_TOR: return REACH_PRIVATE; + } + case NET_I2P: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_I2P: return REACH_PRIVATE; + } + case NET_TEREDO: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_TEREDO: return REACH_TEREDO; + case NET_IPV6: return REACH_IPV6_WEAK; + case NET_IPV4: return REACH_IPV4; + } + case NET_UNKNOWN: + case NET_UNROUTABLE: + default: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_TEREDO: return REACH_TEREDO; + case NET_IPV6: return REACH_IPV6_WEAK; + case NET_IPV4: return REACH_IPV4; + case NET_I2P: return REACH_PRIVATE; // assume connections from unroutable addresses are + case NET_TOR: return REACH_PRIVATE; // either from Tor/I2P, or don't care about our address + } + } +} + +void CService::Init() +{ + port = 0; +} + +CService::CService() +{ + Init(); +} + +CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn) +{ +} + +CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn) +{ +} + +#ifdef USE_IPV6 +CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn) +{ +} +#endif + +CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port)) +{ + assert(addr.sin_family == AF_INET); +} + +#ifdef USE_IPV6 +CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port)) +{ + assert(addr.sin6_family == AF_INET6); +} +#endif + +bool CService::SetSockAddr(const struct sockaddr *paddr) +{ + switch (paddr->sa_family) { + case AF_INET: + *this = CService(*(const struct sockaddr_in*)paddr); + return true; +#ifdef USE_IPV6 + case AF_INET6: + *this = CService(*(const struct sockaddr_in6*)paddr); + return true; +#endif + default: + return false; + } +} + +CService::CService(const char *pszIpPort, bool fAllowLookup) +{ + Init(); + CService ip; + if (Lookup(pszIpPort, ip, 0, fAllowLookup)) + *this = ip; +} + +CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup) +{ + Init(); + CService ip; + if (Lookup(pszIpPort, ip, portDefault, fAllowLookup)) + *this = ip; +} + +CService::CService(const std::string &strIpPort, bool fAllowLookup) +{ + Init(); + CService ip; + if (Lookup(strIpPort.c_str(), ip, 0, fAllowLookup)) + *this = ip; +} + +CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup) +{ + Init(); + CService ip; + if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup)) + *this = ip; +} + +unsigned short CService::GetPort() const +{ + return port; +} + +bool operator==(const CService& a, const CService& b) +{ + return (CNetAddr)a == (CNetAddr)b && a.port == b.port; +} + +bool operator!=(const CService& a, const CService& b) +{ + return (CNetAddr)a != (CNetAddr)b || a.port != b.port; +} + +bool operator<(const CService& a, const CService& b) +{ + return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port); +} + +bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const +{ + if (IsIPv4()) { + if (*addrlen < (socklen_t)sizeof(struct sockaddr_in)) + return false; + *addrlen = sizeof(struct sockaddr_in); + struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr; + memset(paddrin, 0, *addrlen); + if (!GetInAddr(&paddrin->sin_addr)) + return false; + paddrin->sin_family = AF_INET; + paddrin->sin_port = htons(port); + return true; + } +#ifdef USE_IPV6 + if (IsIPv6()) { + if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6)) + return false; + *addrlen = sizeof(struct sockaddr_in6); + struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr; + memset(paddrin6, 0, *addrlen); + if (!GetIn6Addr(&paddrin6->sin6_addr)) + return false; + paddrin6->sin6_family = AF_INET6; + paddrin6->sin6_port = htons(port); + return true; + } +#endif + return false; +} + +std::vector CService::GetKey() const +{ + std::vector vKey; + vKey.resize(18); + memcpy(&vKey[0], ip, 16); + vKey[16] = port / 0x100; + vKey[17] = port & 0x0FF; + return vKey; +} + +std::string CService::ToStringPort() const +{ + return strprintf("%u", port); +} + +std::string CService::ToStringIPPort() const +{ + if (IsIPv4() || IsTor() || IsI2P()) { + return ToStringIP() + ":" + ToStringPort(); + } else { + return "[" + ToStringIP() + "]:" + ToStringPort(); + } +} + +std::string CService::ToString() const +{ + return ToStringIPPort(); +} + +void CService::print() const +{ + printf("CService(%s)\n", ToString().c_str()); +} + +void CService::SetPort(unsigned short portIn) +{ + port = portIn; +} diff --git a/src/netbase.h b/src/netbase.h new file mode 100644 index 0000000..0a29d4f --- /dev/null +++ b/src/netbase.h @@ -0,0 +1,153 @@ +// Copyright (c) 2009-2012 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_NETBASE_H +#define BITCOIN_NETBASE_H + +#include +#include + +#include "serialize.h" +#include "compat.h" + +extern int nConnectTimeout; + +#ifdef WIN32 +// In MSVC, this is defined as a macro, undefine it to prevent a compile and link error +#undef SetPort +#endif + +enum Network +{ + NET_UNROUTABLE, + NET_IPV4, + NET_IPV6, + NET_TOR, + NET_I2P, + + NET_MAX, +}; + +extern int nConnectTimeout; +extern bool fNameLookup; + +/** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */ +class CNetAddr +{ + protected: + unsigned char ip[16]; // in network byte order + + public: + CNetAddr(); + CNetAddr(const struct in_addr& ipv4Addr); + explicit CNetAddr(const char *pszIp, bool fAllowLookup = false); + explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false); + void Init(); + void SetIP(const CNetAddr& ip); + bool SetSpecial(const std::string &strName); // for Tor and I2P addresses + bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) + bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor/I2P) + bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) + bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32) + bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16) + bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16) + bool IsRFC4193() const; // IPv6 unique local (FC00::/15) + bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32) + bool IsRFC4843() const; // IPv6 ORCHID (2001:10::/28) + bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64) + bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96) + bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) + bool IsTor() const; + bool IsI2P() const; + bool IsLocal() const; + bool IsRoutable() const; + bool IsValid() const; + bool IsMulticast() const; + enum Network GetNetwork() const; + std::string ToString() const; + std::string ToStringIP() const; + unsigned int GetByte(int n) const; + uint64 GetHash() const; + bool GetInAddr(struct in_addr* pipv4Addr) const; + std::vector GetGroup() const; + int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const; + void print() const; + +#ifdef USE_IPV6 + CNetAddr(const struct in6_addr& pipv6Addr); + bool GetIn6Addr(struct in6_addr* pipv6Addr) const; +#endif + + friend bool operator==(const CNetAddr& a, const CNetAddr& b); + friend bool operator!=(const CNetAddr& a, const CNetAddr& b); + friend bool operator<(const CNetAddr& a, const CNetAddr& b); + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(ip)); + ) +}; + +/** A combination of a network address (CNetAddr) and a (TCP) port */ +class CService : public CNetAddr +{ + protected: + unsigned short port; // host order + + public: + CService(); + CService(const CNetAddr& ip, unsigned short port); + CService(const struct in_addr& ipv4Addr, unsigned short port); + CService(const struct sockaddr_in& addr); + explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false); + explicit CService(const char *pszIpPort, bool fAllowLookup = false); + explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false); + explicit CService(const std::string& strIpPort, bool fAllowLookup = false); + void Init(); + void SetPort(unsigned short portIn); + unsigned short GetPort() const; + bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const; + bool SetSockAddr(const struct sockaddr* paddr); + friend bool operator==(const CService& a, const CService& b); + friend bool operator!=(const CService& a, const CService& b); + friend bool operator<(const CService& a, const CService& b); + std::vector GetKey() const; + std::string ToString() const; + std::string ToStringPort() const; + std::string ToStringIPPort() const; + void print() const; + +#ifdef USE_IPV6 + CService(const struct in6_addr& ipv6Addr, unsigned short port); + CService(const struct sockaddr_in6& addr); +#endif + + IMPLEMENT_SERIALIZE + ( + CService* pthis = const_cast(this); + READWRITE(FLATDATA(ip)); + unsigned short portN = htons(port); + READWRITE(portN); + if (fRead) + pthis->port = ntohs(portN); + ) +}; + +typedef std::pair proxyType; + +enum Network ParseNetwork(std::string net); +void SplitHostPort(std::string in, int &portOut, std::string &hostOut); +bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion = 5); +bool GetProxy(enum Network net, proxyType &proxyInfoOut); +bool IsProxy(const CNetAddr &addr); +bool SetNameProxy(CService addrProxy, int nSocksVersion = 5); +bool HaveNameProxy(); +bool LookupHost(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true); +bool LookupHostNumeric(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions = 0); +bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true); +bool Lookup(const char *pszName, std::vector& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0); +bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0); +bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout); +bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout); + +#endif diff --git a/src/noui.cpp b/src/noui.cpp new file mode 100644 index 0000000..db25f2d --- /dev/null +++ b/src/noui.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "ui_interface.h" +#include "init.h" +#include "bitcoinrpc.h" + +#include + +static int noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) +{ + printf("%s: %s\n", caption.c_str(), message.c_str()); + fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); + return 4; +} + +static bool noui_ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption) +{ + return true; +} + +void noui_connect() +{ + // Connect bitcoind signal handlers + uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox); + uiInterface.ThreadSafeAskFee.connect(noui_ThreadSafeAskFee); +} diff --git a/src/obj-test/.gitignore b/src/obj-test/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/src/obj-test/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/src/obj/.gitignore b/src/obj/.gitignore new file mode 100644 index 0000000..84aca57 --- /dev/null +++ b/src/obj/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# backup files +*.bak diff --git a/src/pbkdf2.cpp b/src/pbkdf2.cpp new file mode 100644 index 0000000..b98e4e8 --- /dev/null +++ b/src/pbkdf2.cpp @@ -0,0 +1,148 @@ + + +#include +#include "pbkdf2.h" + +static inline uint32_t +be32dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); +} + +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; +} + + + +/* Initialize an HMAC-SHA256 operation with the given key. */ +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. */ +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. */ +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)); +} + diff --git a/src/pbkdf2.h b/src/pbkdf2.h new file mode 100644 index 0000000..88a6a25 --- /dev/null +++ b/src/pbkdf2.h @@ -0,0 +1,27 @@ + + +#ifndef PBKDF2_H +#define PBKDF2_H + +#include +#include + +typedef struct HMAC_SHA256Context { + SHA256_CTX ictx; + SHA256_CTX octx; +} HMAC_SHA256_CTX; + +void +HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen); + +void +HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len); + +void +HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx); + +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); + +#endif // PBKDF2_H diff --git a/src/protocol.cpp b/src/protocol.cpp new file mode 100644 index 0000000..d6e340e --- /dev/null +++ b/src/protocol.cpp @@ -0,0 +1,150 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "protocol.h" +#include "util.h" +#include "netbase.h" + +#ifndef WIN32 +# include +#endif + +static const char* ppszTypeName[] = +{ + "ERROR", + "tx", + "block", +}; + +CMessageHeader::CMessageHeader() +{ + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + memset(pchCommand, 0, sizeof(pchCommand)); + pchCommand[1] = 1; + nMessageSize = -1; + nChecksum = 0; +} + +CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) +{ + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + strncpy(pchCommand, pszCommand, COMMAND_SIZE); + nMessageSize = nMessageSizeIn; + nChecksum = 0; +} + +std::string CMessageHeader::GetCommand() const +{ + if (pchCommand[COMMAND_SIZE-1] == 0) + return std::string(pchCommand, pchCommand + strlen(pchCommand)); + else + return std::string(pchCommand, pchCommand + COMMAND_SIZE); +} + +bool CMessageHeader::IsValid() const +{ + // Check start string + if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) + return false; + + // Check the command string for errors + for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) + { + if (*p1 == 0) + { + // Must be all zeros after the first zero + for (; p1 < pchCommand + COMMAND_SIZE; p1++) + if (*p1 != 0) + return false; + } + else if (*p1 < ' ' || *p1 > 0x7E) + return false; + } + + // Message size + if (nMessageSize > MAX_SIZE) + { + printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize); + return false; + } + + return true; +} + + + +CAddress::CAddress() : CService() +{ + Init(); +} + +CAddress::CAddress(CService ipIn, uint64 nServicesIn) : CService(ipIn) +{ + Init(); + nServices = nServicesIn; +} + +void CAddress::Init() +{ + nServices = NODE_NETWORK; + nTime = 100000000; + nLastTry = 0; +} + +CInv::CInv() +{ + type = 0; + hash = 0; +} + +CInv::CInv(int typeIn, const uint256& hashIn) +{ + type = typeIn; + hash = hashIn; +} + +CInv::CInv(const std::string& strType, const uint256& hashIn) +{ + unsigned int i; + for (i = 1; i < ARRAYLEN(ppszTypeName); i++) + { + if (strType == ppszTypeName[i]) + { + type = i; + break; + } + } + if (i == ARRAYLEN(ppszTypeName)) + throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); + hash = hashIn; +} + +bool operator<(const CInv& a, const CInv& b) +{ + return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); +} + +bool CInv::IsKnownType() const +{ + return (type >= 1 && type < (int)ARRAYLEN(ppszTypeName)); +} + +const char* CInv::GetCommand() const +{ + if (!IsKnownType()) + throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type)); + return ppszTypeName[type]; +} + +std::string CInv::ToString() const +{ + return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str()); +} + +void CInv::print() const +{ + printf("CInv(%s)\n", ToString().c_str()); +} + diff --git a/src/protocol.h b/src/protocol.h new file mode 100644 index 0000000..69c058e --- /dev/null +++ b/src/protocol.h @@ -0,0 +1,137 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 __cplusplus +# error This header can only be compiled as C++. +#endif + +#ifndef __INCLUDED_PROTOCOL_H__ +#define __INCLUDED_PROTOCOL_H__ + +#include "serialize.h" +#include "netbase.h" +#include +#include "uint256.h" + +extern bool fTestNet; +static inline unsigned short GetDefaultPort(const bool testnet = fTestNet) +{ + return testnet ? 42020 : 32020; +} + + +extern unsigned char pchMessageStart[4]; + +/** Message header. + * (4) message start. + * (12) command. + * (4) size. + * (4) checksum. + */ +class CMessageHeader +{ + public: + CMessageHeader(); + CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn); + + std::string GetCommand() const; + bool IsValid() const; + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + READWRITE(nChecksum); + ) + + // TODO: make private (improves encapsulation) + public: + enum { + MESSAGE_START_SIZE=sizeof(::pchMessageStart), + COMMAND_SIZE=12, + MESSAGE_SIZE_SIZE=sizeof(int), + CHECKSUM_SIZE=sizeof(int), + + MESSAGE_SIZE_OFFSET=MESSAGE_START_SIZE+COMMAND_SIZE, + CHECKSUM_OFFSET=MESSAGE_SIZE_OFFSET+MESSAGE_SIZE_SIZE + }; + char pchMessageStart[MESSAGE_START_SIZE]; + char pchCommand[COMMAND_SIZE]; + unsigned int nMessageSize; + unsigned int nChecksum; +}; + +/** nServices flags */ +enum +{ + NODE_NETWORK = (1 << 0), +}; + +/** A CService with information about it as peer */ +class CAddress : public CService +{ + public: + CAddress(); + explicit CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK); + + void Init(); + + IMPLEMENT_SERIALIZE + ( + CAddress* pthis = const_cast(this); + CService* pip = (CService*)pthis; + if (fRead) + pthis->Init(); + if (nType & SER_DISK) + READWRITE(nVersion); + if ((nType & SER_DISK) || + (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) + READWRITE(nTime); + READWRITE(nServices); + READWRITE(*pip); + ) + + void print() const; + + // TODO: make private (improves encapsulation) + public: + uint64 nServices; + + // disk and network only + unsigned int nTime; + + // memory only + int64 nLastTry; +}; + +/** inv message data */ +class CInv +{ + public: + CInv(); + CInv(int typeIn, const uint256& hashIn); + CInv(const std::string& strType, const uint256& hashIn); + + IMPLEMENT_SERIALIZE + ( + READWRITE(type); + READWRITE(hash); + ) + + friend bool operator<(const CInv& a, const CInv& b); + + bool IsKnownType() const; + const char* GetCommand() const; + std::string ToString() const; + void print() const; + + // TODO: make private (improves encapsulation) + public: + int type; + uint256 hash; +}; + +#endif // __INCLUDED_PROTOCOL_H__ diff --git a/src/qt/aboutdialog.cpp b/src/qt/aboutdialog.cpp new file mode 100644 index 0000000..14ff9e9 --- /dev/null +++ b/src/qt/aboutdialog.cpp @@ -0,0 +1,31 @@ +#include "aboutdialog.h" +#include "ui_aboutdialog.h" +#include "clientmodel.h" + +#include "version.h" + +AboutDialog::AboutDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutDialog) +{ + ui->setupUi(this); + // this->setStyleSheet("background-color: #effbef;"); +} + +void AboutDialog::setModel(ClientModel *model) +{ + if(model) + { + ui->versionLabel->setText(model->formatFullVersion()); + } +} + +AboutDialog::~AboutDialog() +{ + delete ui; +} + +void AboutDialog::on_buttonBox_accepted() +{ + close(); +} diff --git a/src/qt/aboutdialog.h b/src/qt/aboutdialog.h new file mode 100644 index 0000000..2ed9e9e --- /dev/null +++ b/src/qt/aboutdialog.h @@ -0,0 +1,28 @@ +#ifndef ABOUTDIALOG_H +#define ABOUTDIALOG_H + +#include + +namespace Ui { + class AboutDialog; +} +class ClientModel; + +/** "About" dialog box */ +class AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent = 0); + ~AboutDialog(); + + void setModel(ClientModel *model); +private: + Ui::AboutDialog *ui; + +private slots: + void on_buttonBox_accepted(); +}; + +#endif // ABOUTDIALOG_H diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp new file mode 100644 index 0000000..6d18d4f --- /dev/null +++ b/src/qt/addressbookpage.cpp @@ -0,0 +1,376 @@ +#include "addressbookpage.h" +#include "ui_addressbookpage.h" + +#include "addresstablemodel.h" +#include "optionsmodel.h" +#include "bitcoingui.h" +#include "editaddressdialog.h" +#include "csvmodelwriter.h" +#include "guiutil.h" + +#include +#include +#include +#include + +#ifdef USE_QRCODE +#include "qrcodedialog.h" +#endif + +AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : + QDialog(parent), + ui(new Ui::AddressBookPage), + model(0), + optionsModel(0), + mode(mode), + tab(tab) +{ + ui->setupUi(this); + +#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac + ui->newAddressButton->setIcon(QIcon()); + ui->copyToClipboard->setIcon(QIcon()); + ui->deleteButton->setIcon(QIcon()); +#endif + +#ifndef USE_QRCODE + ui->showQRCode->setVisible(false); +#endif + + switch(mode) + { + case ForSending: + connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept())); + ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->tableView->setFocus(); + break; + case ForEditing: + ui->buttonBox->setVisible(false); + break; + } + switch(tab) + { + case SendingTab: + ui->labelExplanation->setVisible(false); + ui->deleteButton->setVisible(true); + ui->signMessage->setVisible(false); + break; + case ReceivingTab: + ui->deleteButton->setVisible(false); + ui->signMessage->setVisible(true); + break; + } + + // Context menu actions + QAction *copyLabelAction = new QAction(tr("Copy &Label"), this); + QAction *copyAddressAction = new QAction(ui->copyToClipboard->text(), this); + QAction *editAction = new QAction(tr("&Edit"), this); + QAction *showQRCodeAction = new QAction(ui->showQRCode->text(), this); + QAction *signMessageAction = new QAction(ui->signMessage->text(), this); + QAction *verifyMessageAction = new QAction(ui->verifyMessage->text(), this); + deleteAction = new QAction(ui->deleteButton->text(), this); + + // Build context menu + contextMenu = new QMenu(); + contextMenu->addAction(copyAddressAction); + contextMenu->addAction(copyLabelAction); + contextMenu->addAction(editAction); + if(tab == SendingTab) + contextMenu->addAction(deleteAction); + contextMenu->addSeparator(); + contextMenu->addAction(showQRCodeAction); + if(tab == ReceivingTab) + contextMenu->addAction(signMessageAction); + else if(tab == SendingTab) + contextMenu->addAction(verifyMessageAction); + + // Connect signals for context menu actions + connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyToClipboard_clicked())); + connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction())); + connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction())); + connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteButton_clicked())); + connect(showQRCodeAction, SIGNAL(triggered()), this, SLOT(on_showQRCode_clicked())); + connect(signMessageAction, SIGNAL(triggered()), this, SLOT(on_signMessage_clicked())); + connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(on_verifyMessage_clicked())); + + connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); + + // Pass through accept action from button box + connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); +} + +AddressBookPage::~AddressBookPage() +{ + delete ui; +} + +void AddressBookPage::setModel(AddressTableModel *model) +{ + this->model = model; + if(!model) + return; + + proxyModel = new QSortFilterProxyModel(this); + proxyModel->setSourceModel(model); + proxyModel->setDynamicSortFilter(true); + proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + switch(tab) + { + case ReceivingTab: + // Receive filter + proxyModel->setFilterRole(AddressTableModel::TypeRole); + proxyModel->setFilterFixedString(AddressTableModel::Receive); + break; + case SendingTab: + // Send filter + proxyModel->setFilterRole(AddressTableModel::TypeRole); + proxyModel->setFilterFixedString(AddressTableModel::Send); + break; + } + ui->tableView->setModel(proxyModel); + ui->tableView->sortByColumn(0, Qt::AscendingOrder); + + // Set column widths + #if QT_VERSION < 0x050000 + ui->tableView->horizontalHeader()->resizeSection(AddressTableModel::Address, 320); + ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Label, QHeaderView::Stretch); + #else + ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch); + ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents); + #endif + connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + this, SLOT(selectionChanged())); + + // Select row for newly created address + connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(selectNewAddress(QModelIndex,int,int))); + + selectionChanged(); +} + +void AddressBookPage::setOptionsModel(OptionsModel *optionsModel) +{ + this->optionsModel = optionsModel; +} + +void AddressBookPage::on_copyToClipboard_clicked() +{ + GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address); +} + +void AddressBookPage::onCopyLabelAction() +{ + GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Label); +} + +void AddressBookPage::onEditAction() +{ + if(!ui->tableView->selectionModel()) + return; + QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows(); + if(indexes.isEmpty()) + return; + + EditAddressDialog dlg( + tab == SendingTab ? + EditAddressDialog::EditSendingAddress : + EditAddressDialog::EditReceivingAddress); + dlg.setModel(model); + QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0)); + dlg.loadRow(origIndex.row()); + dlg.exec(); +} + +void AddressBookPage::on_signMessage_clicked() +{ + QTableView *table = ui->tableView; + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + QString addr; + + foreach (QModelIndex index, indexes) + { + QVariant address = index.data(); + addr = address.toString(); + } + + emit signMessage(addr); +} + +void AddressBookPage::on_verifyMessage_clicked() +{ + QTableView *table = ui->tableView; + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + QString addr; + + foreach (QModelIndex index, indexes) + { + QVariant address = index.data(); + addr = address.toString(); + } + + emit verifyMessage(addr); +} + +void AddressBookPage::on_newAddressButton_clicked() +{ + if(!model) + return; + EditAddressDialog dlg( + tab == SendingTab ? + EditAddressDialog::NewSendingAddress : + EditAddressDialog::NewReceivingAddress, this); + dlg.setModel(model); + if(dlg.exec()) + { + newAddressToSelect = dlg.getAddress(); + } +} + +void AddressBookPage::on_deleteButton_clicked() +{ + QTableView *table = ui->tableView; + if(!table->selectionModel()) + return; + QModelIndexList indexes = table->selectionModel()->selectedRows(); + if(!indexes.isEmpty()) + { + table->model()->removeRow(indexes.at(0).row()); + } +} + +void AddressBookPage::selectionChanged() +{ + // Set button states based on selected tab and selection + QTableView *table = ui->tableView; + if(!table->selectionModel()) + return; + + if(table->selectionModel()->hasSelection()) + { + switch(tab) + { + case SendingTab: + // In sending tab, allow deletion of selection + ui->deleteButton->setEnabled(true); + ui->deleteButton->setVisible(true); + deleteAction->setEnabled(true); + ui->signMessage->setEnabled(false); + ui->signMessage->setVisible(false); + ui->verifyMessage->setEnabled(true); + ui->verifyMessage->setVisible(true); + break; + case ReceivingTab: + // Deleting receiving addresses, however, is not allowed + ui->deleteButton->setEnabled(false); + ui->deleteButton->setVisible(false); + deleteAction->setEnabled(false); + ui->signMessage->setEnabled(true); + ui->signMessage->setVisible(true); + ui->verifyMessage->setEnabled(false); + ui->verifyMessage->setVisible(false); + break; + } + ui->copyToClipboard->setEnabled(true); + ui->showQRCode->setEnabled(true); + } + else + { + ui->deleteButton->setEnabled(false); + ui->showQRCode->setEnabled(false); + ui->copyToClipboard->setEnabled(false); + ui->signMessage->setEnabled(false); + ui->verifyMessage->setEnabled(false); + } +} + +void AddressBookPage::done(int retval) +{ + QTableView *table = ui->tableView; + if(!table->selectionModel() || !table->model()) + return; + // When this is a tab/widget and not a model dialog, ignore "done" + if(mode == ForEditing) + return; + + // Figure out which address was selected, and return it + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + + foreach (QModelIndex index, indexes) + { + QVariant address = table->model()->data(index); + returnValue = address.toString(); + } + + if(returnValue.isEmpty()) + { + // If no address entry selected, return rejected + retval = Rejected; + } + + QDialog::done(retval); +} + +void AddressBookPage::exportClicked() +{ + // CSV is currently the only supported format + QString filename = GUIUtil::getSaveFileName( + this, + tr("Export Address Book Data"), QString(), + tr("Comma separated file (*.csv)")); + + if (filename.isNull()) return; + + CSVModelWriter writer(filename); + + // name, column, role + writer.setModel(proxyModel); + writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole); + writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole); + + if(!writer.write()) + { + QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename), + QMessageBox::Abort, QMessageBox::Abort); + } +} + +void AddressBookPage::on_showQRCode_clicked() +{ +#ifdef USE_QRCODE + QTableView *table = ui->tableView; + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + + foreach (QModelIndex index, indexes) + { + QString address = index.data().toString(), label = index.sibling(index.row(), 0).data(Qt::EditRole).toString(); + + QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this); + if(optionsModel) + dialog->setModel(optionsModel); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + } +#endif +} + +void AddressBookPage::contextualMenu(const QPoint &point) +{ + QModelIndex index = ui->tableView->indexAt(point); + if(index.isValid()) + { + contextMenu->exec(QCursor::pos()); + } +} + +void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int end) +{ + QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent)); + if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect)) + { + // Select row of newly created address, once + ui->tableView->setFocus(); + ui->tableView->selectRow(idx.row()); + newAddressToSelect.clear(); + } +} diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h new file mode 100644 index 0000000..df87486 --- /dev/null +++ b/src/qt/addressbookpage.h @@ -0,0 +1,85 @@ +#ifndef ADDRESSBOOKPAGE_H +#define ADDRESSBOOKPAGE_H + +#include + +namespace Ui { + class AddressBookPage; +} +class AddressTableModel; +class OptionsModel; + +QT_BEGIN_NAMESPACE +class QTableView; +class QItemSelection; +class QSortFilterProxyModel; +class QMenu; +class QModelIndex; +QT_END_NAMESPACE + +/** Widget that shows a list of sending or receiving addresses. + */ +class AddressBookPage : public QDialog +{ + Q_OBJECT + +public: + enum Tabs { + SendingTab = 0, + ReceivingTab = 1 + }; + + enum Mode { + ForSending, /**< Open address book to pick address for sending */ + ForEditing /**< Open address book for editing */ + }; + + explicit AddressBookPage(Mode mode, Tabs tab, QWidget *parent = 0); + ~AddressBookPage(); + + void setModel(AddressTableModel *model); + void setOptionsModel(OptionsModel *optionsModel); + const QString &getReturnValue() const { return returnValue; } + +public slots: + void done(int retval); + void exportClicked(); + +private: + Ui::AddressBookPage *ui; + AddressTableModel *model; + OptionsModel *optionsModel; + Mode mode; + Tabs tab; + QString returnValue; + QSortFilterProxyModel *proxyModel; + QMenu *contextMenu; + QAction *deleteAction; + QString newAddressToSelect; + +private slots: + void on_deleteButton_clicked(); + void on_newAddressButton_clicked(); + /** Copy address of currently selected address entry to clipboard */ + void on_copyToClipboard_clicked(); + void on_signMessage_clicked(); + void on_verifyMessage_clicked(); + void selectionChanged(); + void on_showQRCode_clicked(); + /** Spawn contextual menu (right mouse menu) for address book entry */ + void contextualMenu(const QPoint &point); + + /** Copy label of currently selected address entry to clipboard */ + void onCopyLabelAction(); + /** Edit currently selected address entry */ + void onEditAction(); + + /** New entry/entries were added to address table */ + void selectNewAddress(const QModelIndex &parent, int begin, int end); + +signals: + void signMessage(QString addr); + void verifyMessage(QString addr); +}; + +#endif // ADDRESSBOOKDIALOG_H diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp new file mode 100644 index 0000000..e3e7ee6 --- /dev/null +++ b/src/qt/addresstablemodel.cpp @@ -0,0 +1,411 @@ +#include "addresstablemodel.h" +#include "guiutil.h" +#include "walletmodel.h" + +#include "wallet.h" +#include "base58.h" + +#include +#include + +const QString AddressTableModel::Send = "S"; +const QString AddressTableModel::Receive = "R"; +extern QString glbAddress; + +struct AddressTableEntry +{ + enum Type { + Sending, + Receiving + }; + + Type type; + QString label; + QString address; + + AddressTableEntry() {} + AddressTableEntry(Type type, const QString &label, const QString &address): + type(type), label(label), address(address) {} +}; + +struct AddressTableEntryLessThan +{ + bool operator()(const AddressTableEntry &a, const AddressTableEntry &b) const + { + return a.address < b.address; + } + bool operator()(const AddressTableEntry &a, const QString &b) const + { + return a.address < b; + } + bool operator()(const QString &a, const AddressTableEntry &b) const + { + return a < b.address; + } +}; + +// Private implementation +class AddressTablePriv +{ +public: + CWallet *wallet; + QList cachedAddressTable; + AddressTableModel *parent; + + AddressTablePriv(CWallet *wallet, AddressTableModel *parent): + wallet(wallet), parent(parent) {} + + void refreshAddressTable() + { + cachedAddressTable.clear(); + { + LOCK(wallet->cs_wallet); + BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& item, wallet->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + const std::string& strName = item.second; + bool fMine = IsMine(*wallet, address.Get()); + cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending, + QString::fromStdString(strName), + QString::fromStdString(address.ToString()))); + if (glbAddress.isEmpty()) + { + glbAddress = QString::fromStdString(address.ToString()); + } + } + } + } + + void updateEntry(const QString &address, const QString &label, bool isMine, int status) + { + // Find address / label in model + QList::iterator lower = qLowerBound( + cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan()); + QList::iterator upper = qUpperBound( + cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan()); + int lowerIndex = (lower - cachedAddressTable.begin()); + int upperIndex = (upper - cachedAddressTable.begin()); + bool inModel = (lower != upper); + AddressTableEntry::Type newEntryType = isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending; + + switch(status) + { + case CT_NEW: + if(inModel) + { + OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_NOW, but entry is already in model\n"); + break; + } + parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex); + cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address)); + parent->endInsertRows(); + break; + case CT_UPDATED: + if(!inModel) + { + OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_UPDATED, but entry is not in model\n"); + break; + } + lower->type = newEntryType; + lower->label = label; + parent->emitDataChanged(lowerIndex); + break; + case CT_DELETED: + if(!inModel) + { + OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_DELETED, but entry is not in model\n"); + break; + } + parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); + cachedAddressTable.erase(lower, upper); + parent->endRemoveRows(); + break; + } + } + + int size() + { + return cachedAddressTable.size(); + } + + AddressTableEntry *index(int idx) + { + if(idx >= 0 && idx < cachedAddressTable.size()) + { + return &cachedAddressTable[idx]; + } + else + { + return 0; + } + } +}; + +AddressTableModel::AddressTableModel(CWallet *wallet, WalletModel *parent) : + QAbstractTableModel(parent),walletModel(parent),wallet(wallet),priv(0) +{ + columns << tr("Label") << tr("Address"); + priv = new AddressTablePriv(wallet, this); + priv->refreshAddressTable(); +} + +AddressTableModel::~AddressTableModel() +{ + delete priv; +} + +int AddressTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int AddressTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns.length(); +} + +QVariant AddressTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + AddressTableEntry *rec = static_cast(index.internalPointer()); + + if(role == Qt::DisplayRole || role == Qt::EditRole) + { + switch(index.column()) + { + case Label: + if(rec->label.isEmpty() && role == Qt::DisplayRole) + { + return tr("(no label)"); + } + else + { + return rec->label; + } + case Address: + return rec->address; + } + } + else if (role == Qt::FontRole) + { + QFont font; + if(index.column() == Address) + { + font = GUIUtil::bitcoinAddressFont(); + } + return font; + } + else if (role == TypeRole) + { + switch(rec->type) + { + case AddressTableEntry::Sending: + return Send; + case AddressTableEntry::Receiving: + return Receive; + default: break; + } + } + return QVariant(); +} + +bool AddressTableModel::setData(const QModelIndex & index, const QVariant & value, int role) +{ + if(!index.isValid()) + return false; + AddressTableEntry *rec = static_cast(index.internalPointer()); + + editStatus = OK; + + if(role == Qt::EditRole) + { + switch(index.column()) + { + case Label: + wallet->SetAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get(), value.toString().toStdString()); + rec->label = value.toString(); + break; + case Address: + // Refuse to set invalid address, set error status and return false + if(!walletModel->validateAddress(value.toString())) + { + editStatus = INVALID_ADDRESS; + return false; + } + // Double-check that we're not overwriting a receiving address + if(rec->type == AddressTableEntry::Sending) + { + { + LOCK(wallet->cs_wallet); + // Remove old entry + wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get()); + // Add new entry with new address + wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()).Get(), rec->label.toStdString()); + } + } + break; + } + + return true; + } + return false; +} + +QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole) + { + return columns[section]; + } + } + return QVariant(); +} + +Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const +{ + if(!index.isValid()) + return 0; + AddressTableEntry *rec = static_cast(index.internalPointer()); + + Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + // Can edit address and label for sending addresses, + // and only label for receiving addresses. + if(rec->type == AddressTableEntry::Sending || + (rec->type == AddressTableEntry::Receiving && index.column()==Label)) + { + retval |= Qt::ItemIsEditable; + } + return retval; +} + +QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & parent) const +{ + Q_UNUSED(parent); + AddressTableEntry *data = priv->index(row); + if(data) + { + return createIndex(row, column, priv->index(row)); + } + else + { + return QModelIndex(); + } +} + +void AddressTableModel::updateEntry(const QString &address, const QString &label, bool isMine, int status) +{ + // Update address book model from Bitcoin core + priv->updateEntry(address, label, isMine, status); +} + +QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address) +{ + std::string strLabel = label.toStdString(); + std::string strAddress = address.toStdString(); + + editStatus = OK; + + if(type == Send) + { + if(!walletModel->validateAddress(address)) + { + editStatus = INVALID_ADDRESS; + return QString(); + } + // Check for duplicate addresses + { + LOCK(wallet->cs_wallet); + if(wallet->mapAddressBook.count(CBitcoinAddress(strAddress).Get())) + { + editStatus = DUPLICATE_ADDRESS; + return QString(); + } + } + } + else if(type == Receive) + { + // Generate a new address to associate with given label + WalletModel::UnlockContext ctx(walletModel->requestUnlock()); + if(!ctx.isValid()) + { + // Unlock wallet failed or was cancelled + editStatus = WALLET_UNLOCK_FAILURE; + return QString(); + } + CPubKey newKey; + if(!wallet->GetKeyFromPool(newKey, true)) + { + editStatus = KEY_GENERATION_FAILURE; + return QString(); + } + strAddress = CBitcoinAddress(newKey.GetID()).ToString(); + } + else + { + return QString(); + } + // Add entry + { + LOCK(wallet->cs_wallet); + wallet->SetAddressBookName(CBitcoinAddress(strAddress).Get(), strLabel); + } + return QString::fromStdString(strAddress); +} + +bool AddressTableModel::removeRows(int row, int count, const QModelIndex & parent) +{ + Q_UNUSED(parent); + AddressTableEntry *rec = priv->index(row); + if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving) + { + // Can only remove one row at a time, and cannot remove rows not in model. + // Also refuse to remove receiving addresses. + return false; + } + { + LOCK(wallet->cs_wallet); + wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get()); + } + return true; +} + +/* Look up label for address in address book, if not found return empty string. + */ +QString AddressTableModel::labelForAddress(const QString &address) const +{ + { + LOCK(wallet->cs_wallet); + CBitcoinAddress address_parsed(address.toStdString()); + std::map::iterator mi = wallet->mapAddressBook.find(address_parsed.Get()); + if (mi != wallet->mapAddressBook.end()) + { + return QString::fromStdString(mi->second); + } + } + return QString(); +} + +int AddressTableModel::lookupAddress(const QString &address) const +{ + QModelIndexList lst = match(index(0, Address, QModelIndex()), + Qt::EditRole, address, 1, Qt::MatchExactly); + if(lst.isEmpty()) + { + return -1; + } + else + { + return lst.at(0).row(); + } +} + +void AddressTableModel::emitDataChanged(int idx) +{ + emit dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex())); +} diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h new file mode 100644 index 0000000..42974e3 --- /dev/null +++ b/src/qt/addresstablemodel.h @@ -0,0 +1,91 @@ +#ifndef ADDRESSTABLEMODEL_H +#define ADDRESSTABLEMODEL_H + +#include +#include + +class AddressTablePriv; +class CWallet; +class WalletModel; + +/** + Qt model of the address book in the core. This allows views to access and modify the address book. + */ +class AddressTableModel : public QAbstractTableModel +{ + Q_OBJECT +public: + explicit AddressTableModel(CWallet *wallet, WalletModel *parent = 0); + ~AddressTableModel(); + + enum ColumnIndex { + Label = 0, /**< User specified label */ + Address = 1 /**< Bitcoin address */ + }; + + enum RoleIndex { + TypeRole = Qt::UserRole /**< Type of address (#Send or #Receive) */ + }; + + /** Return status of edit/insert operation */ + enum EditStatus { + OK, + INVALID_ADDRESS, /**< Unparseable address */ + DUPLICATE_ADDRESS, /**< Address already in address book */ + WALLET_UNLOCK_FAILURE, /**< Wallet could not be unlocked to create new receiving address */ + KEY_GENERATION_FAILURE /**< Generating a new public key for a receiving address failed */ + }; + + static const QString Send; /**< Specifies send address */ + static const QString Receive; /**< Specifies receive address */ + + /** @name Methods overridden from QAbstractTableModel + @{*/ + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex & index, const QVariant & value, int role); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex & parent) const; + bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()); + Qt::ItemFlags flags(const QModelIndex & index) const; + /*@}*/ + + /* Add an address to the model. + Returns the added address on success, and an empty string otherwise. + */ + QString addRow(const QString &type, const QString &label, const QString &address); + + /* Look up label for address in address book, if not found return empty string. + */ + QString labelForAddress(const QString &address) const; + + /* Look up row index of an address in the model. + Return -1 if not found. + */ + int lookupAddress(const QString &address) const; + + EditStatus getEditStatus() const { return editStatus; } + +private: + WalletModel *walletModel; + CWallet *wallet; + AddressTablePriv *priv; + QStringList columns; + EditStatus editStatus; + + /** Notify listeners that data changed. */ + void emitDataChanged(int index); + +signals: + void defaultAddressChanged(const QString &address); + +public slots: + /* Update address list from core. + */ + void updateEntry(const QString &address, const QString &label, bool isMine, int status); + + friend class AddressTablePriv; +}; + +#endif // ADDRESSTABLEMODEL_H diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp new file mode 100644 index 0000000..ccd0c93 --- /dev/null +++ b/src/qt/askpassphrasedialog.cpp @@ -0,0 +1,257 @@ +#include "askpassphrasedialog.h" +#include "ui_askpassphrasedialog.h" + +#include "guiconstants.h" +#include "walletmodel.h" + +#include +#include +#include + +extern bool fWalletUnlockMintOnly; + +AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : + QDialog(parent), + ui(new Ui::AskPassphraseDialog), + mode(mode), + model(0), + fCapsLock(false) +{ + ui->setupUi(this); + ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE); + ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE); + ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE); + + // Setup Caps Lock detection. + ui->passEdit1->installEventFilter(this); + ui->passEdit2->installEventFilter(this); + ui->passEdit3->installEventFilter(this); + + switch(mode) + { + case Encrypt: // Ask passphrase x2 + ui->passLabel1->hide(); + ui->passEdit1->hide(); + ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of 10 or more random characters, or eight or more words.")); + setWindowTitle(tr("Encrypt wallet")); + break; + case UnlockMinting: + ui->mintingCheckBox->setChecked(true); + ui->mintingCheckBox->show(); + // fallthru + case Unlock: // Ask passphrase + ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet.")); + ui->passLabel2->hide(); + ui->passEdit2->hide(); + ui->passLabel3->hide(); + ui->passEdit3->hide(); + setWindowTitle(tr("Unlock wallet")); + break; + case Decrypt: // Ask passphrase + ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet.")); + ui->passLabel2->hide(); + ui->passEdit2->hide(); + ui->passLabel3->hide(); + ui->passEdit3->hide(); + setWindowTitle(tr("Decrypt wallet")); + break; + case ChangePass: // Ask old passphrase + new passphrase x2 + setWindowTitle(tr("Change passphrase")); + ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet.")); + break; + } + + textChanged(); + connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); +} + +AskPassphraseDialog::~AskPassphraseDialog() +{ + // Attempt to overwrite text so that they do not linger around in memory + ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size())); + ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size())); + ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size())); + delete ui; +} + +void AskPassphraseDialog::setModel(WalletModel *model) +{ + this->model = model; +} + +void AskPassphraseDialog::accept() +{ + SecureString oldpass, newpass1, newpass2; + if(!model) + return; + oldpass.reserve(MAX_PASSPHRASE_SIZE); + newpass1.reserve(MAX_PASSPHRASE_SIZE); + newpass2.reserve(MAX_PASSPHRASE_SIZE); + // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) + // Alternately, find a way to make this input mlock()'d to begin with. + oldpass.assign(ui->passEdit1->text().toStdString().c_str()); + newpass1.assign(ui->passEdit2->text().toStdString().c_str()); + newpass2.assign(ui->passEdit3->text().toStdString().c_str()); + + switch(mode) + { + case Encrypt: { + if(newpass1.empty() || newpass2.empty()) + { + // Cannot encrypt with empty passphrase + break; + } + QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"), + tr("Warning: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR COINS!") + "

" + tr("Are you sure you wish to encrypt your wallet?"), + QMessageBox::Yes|QMessageBox::Cancel, + QMessageBox::Cancel); + if(retval == QMessageBox::Yes) + { + if(newpass1 == newpass2) + { + if(model->setWalletEncrypted(true, newpass1)) + { + QMessageBox::warning(this, tr("Wallet encrypted"), + "" + + tr("BERN will close now to finish the encryption process. " + "Remember that encrypting your wallet cannot fully protect " + "your coins from being stolen by malware infecting your computer.") + + "

" + + tr("IMPORTANT: Any previous backups you have made of your wallet file " + "should be replaced with the newly generated, encrypted wallet file. " + "For security reasons, previous backups of the unencrypted wallet file " + "will become useless as soon as you start using the new, encrypted wallet.") + + "
"); + QApplication::quit(); + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted.")); + } + QDialog::accept(); // Success + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("The supplied passphrases do not match.")); + } + } + else + { + QDialog::reject(); // Cancelled + } + } break; + case UnlockMinting: + case Unlock: + if(!model->setWalletLocked(false, oldpass)) + { + QMessageBox::critical(this, tr("Wallet unlock failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + else + { + fWalletUnlockMintOnly = ui->mintingCheckBox->isChecked(); + QDialog::accept(); // Success + } + break; + case Decrypt: + if(!model->setWalletEncrypted(false, oldpass)) + { + QMessageBox::critical(this, tr("Wallet decryption failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + else + { + QDialog::accept(); // Success + } + break; + case ChangePass: + if(newpass1 == newpass2) + { + if(model->changePassphrase(oldpass, newpass1)) + { + QMessageBox::information(this, tr("Wallet encrypted"), + tr("Wallet passphrase was successfully changed.")); + QDialog::accept(); // Success + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("The supplied passphrases do not match.")); + } + break; + } +} + +void AskPassphraseDialog::textChanged() +{ + // Validate input, set Ok button to enabled when acceptable + bool acceptable = false; + switch(mode) + { + case Encrypt: // New passphrase x2 + acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); + break; + case UnlockMinting: + case Unlock: // Old passphrase x1 + case Decrypt: + acceptable = !ui->passEdit1->text().isEmpty(); + break; + case ChangePass: // Old passphrase x1, new passphrase x2 + acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); + break; + } + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable); +} + +bool AskPassphraseDialog::event(QEvent *event) +{ + // Detect Caps Lock key press. + if (event->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(event); + if (ke->key() == Qt::Key_CapsLock) { + fCapsLock = !fCapsLock; + } + if (fCapsLock) { + ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!")); + } else { + ui->capsLabel->clear(); + } + } + return QWidget::event(event); +} + +bool AskPassphraseDialog::eventFilter(QObject *object, QEvent *event) +{ + /* Detect Caps Lock. + * There is no good OS-independent way to check a key state in Qt, but we + * can detect Caps Lock by checking for the following condition: + * Shift key is down and the result is a lower case character, or + * Shift key is not down and the result is an upper case character. + */ + if (event->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(event); + QString str = ke->text(); + if (str.length() != 0) { + const QChar *psz = str.unicode(); + bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0; + if ((fShift && psz->isLower()) || (!fShift && psz->isUpper())) { + fCapsLock = true; + ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!")); + } else if (psz->isLetter()) { + fCapsLock = false; + ui->capsLabel->clear(); + } + } + } + return QDialog::eventFilter(object, event); +} diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h new file mode 100644 index 0000000..ca01274 --- /dev/null +++ b/src/qt/askpassphrasedialog.h @@ -0,0 +1,46 @@ +#ifndef ASKPASSPHRASEDIALOG_H +#define ASKPASSPHRASEDIALOG_H + +#include + +namespace Ui { + class AskPassphraseDialog; +} + +class WalletModel; + +/** Multifunctional dialog to ask for passphrases. Used for encryption, unlocking, and changing the passphrase. + */ +class AskPassphraseDialog : public QDialog +{ + Q_OBJECT + +public: + enum Mode { + Encrypt, /**< Ask passphrase twice and encrypt */ + UnlockMinting, /**< Ask passphrase and unlock for minting only */ + Unlock, /**< Ask passphrase and unlock */ + ChangePass, /**< Ask old passphrase + new passphrase twice */ + Decrypt /**< Ask passphrase and decrypt wallet */ + }; + + explicit AskPassphraseDialog(Mode mode, QWidget *parent = 0); + ~AskPassphraseDialog(); + + void accept(); + + void setModel(WalletModel *model); + +private: + Ui::AskPassphraseDialog *ui; + Mode mode; + WalletModel *model; + bool fCapsLock; + +private slots: + void textChanged(); + bool event(QEvent *event); + bool eventFilter(QObject *, QEvent *event); +}; + +#endif // ASKPASSPHRASEDIALOG_H diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp new file mode 100644 index 0000000..bd0699f --- /dev/null +++ b/src/qt/bitcoin.cpp @@ -0,0 +1,274 @@ +/* + * W.J. van der Laan 2011-2012 + */ +#include "bitcoingui.h" +#include "clientmodel.h" +#include "walletmodel.h" +#include "optionsmodel.h" +#include "guiutil.h" +#include "guiconstants.h" + +#include "init.h" +#include "ui_interface.h" +#include "qtipcserver.h" + +#include +#include +#if QT_VERSION < 0x050000 +#include +#endif +#include +#include +#include +#include + +#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED) +#define _BITCOIN_QT_PLUGINS_INCLUDED +#define __INSURE__ +#include +Q_IMPORT_PLUGIN(qcncodecs) +Q_IMPORT_PLUGIN(qjpcodecs) +Q_IMPORT_PLUGIN(qtwcodecs) +Q_IMPORT_PLUGIN(qkrcodecs) +Q_IMPORT_PLUGIN(qtaccessiblewidgets) +#endif + +// Need a global reference for the notifications to find the GUI +static BitcoinGUI *guiref; +static QSplashScreen *splashref; + +static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) +{ + // Message from network thread + if(guiref) + { + bool modal = (style & CClientUIInterface::MODAL); + // in case of modal message, use blocking connection to wait for user to click OK + QMetaObject::invokeMethod(guiref, "error", + modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(caption)), + Q_ARG(QString, QString::fromStdString(message)), + Q_ARG(bool, modal)); + } + else + { + printf("%s: %s\n", caption.c_str(), message.c_str()); + fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); + } +} + +static bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption) +{ + if(!guiref) + return false; + if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon) + return true; + bool payFee = false; + + QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(), + Q_ARG(qint64, nFeeRequired), + Q_ARG(bool*, &payFee)); + + return payFee; +} + +static void ThreadSafeHandleURI(const std::string& strURI) +{ + if(!guiref) + return; + + QMetaObject::invokeMethod(guiref, "handleURI", GUIUtil::blockingGUIThreadConnection(), + Q_ARG(QString, QString::fromStdString(strURI))); +} + +static void InitMessage(const std::string &message) +{ + if(splashref) + { + splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(70,71,71)); + QApplication::instance()->processEvents(); + } +} + +static void QueueShutdown() +{ + QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection); +} + +/* + Translate string to current locale using Qt. + */ +static std::string Translate(const char* psz) +{ + return QCoreApplication::translate("bitcoin-core", psz).toStdString(); +} + +/* Handle runaway exceptions. Shows a message box with the problem and quits the program. + */ +static void handleRunawayException(std::exception *e) +{ + PrintExceptionContinue(e, "Runaway exception"); + QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. BERN can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning)); + exit(1); +} + +#ifndef BITCOIN_QT_TEST +int main(int argc, char *argv[]) +{ + // Do this early as we don't want to bother initializing if we are just calling IPC + ipcScanRelay(argc, argv); + + #if QT_VERSION < 0x050000 + // Internal string conversion is all UTF-8 + QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); + QTextCodec::setCodecForCStrings(QTextCodec::codecForTr()); + #endif + + Q_INIT_RESOURCE(bitcoin); + QApplication app(argc, argv); + + // Install global event filter that makes sure that long tooltips can be word-wrapped + app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app)); + + // Command-line options take precedence: + ParseParameters(argc, argv); + + // ... then bitcoin.conf: + if (!boost::filesystem::is_directory(GetDataDir(false))) + { + // This message can not be translated, as translation is not initialized yet + // (which not yet possible because lang=XX can be overridden in bitcoin.conf in the data directory) + QMessageBox::critical(0, "BERN", + QString("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); + return 1; + } + ReadConfigFile(mapArgs, mapMultiArgs); + + // Application identification (must be set before OptionsModel is initialized, + // as it is used to locate QSettings) + app.setOrganizationName("BERN"); + app.setOrganizationDomain("BERN.su"); + if(GetBoolArg("-testnet")) // Separate UI settings for testnet + app.setApplicationName("BERN-Qt-testnet"); + else + app.setApplicationName("BERN-Qt"); + + // ... then GUI settings: + OptionsModel optionsModel; + + // Get desired locale (e.g. "de_DE") from command line or use system locale + QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString())); + QString lang = lang_territory; + // Convert to "de" only by truncating "_DE" + lang.truncate(lang_territory.lastIndexOf('_')); + + QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; + // Load language files for configured locale: + // - First load the translator for the base language, without territory + // - Then load the more specific locale translator + + // Load e.g. qt_de.qm + if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + app.installTranslator(&qtTranslatorBase); + + // Load e.g. qt_de_DE.qm + if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + app.installTranslator(&qtTranslator); + + // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc) + if (translatorBase.load(lang, ":/translations/")) + app.installTranslator(&translatorBase); + + // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc) + if (translator.load(lang_territory, ":/translations/")) + app.installTranslator(&translator); + + // Subscribe to global signals from core + uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox); + uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee); + uiInterface.ThreadSafeHandleURI.connect(ThreadSafeHandleURI); + uiInterface.InitMessage.connect(InitMessage); + uiInterface.QueueShutdown.connect(QueueShutdown); + uiInterface.Translate.connect(Translate); + + // Show help message immediately after parsing command-line options (for "-lang") and setting locale, + // but before showing splash screen. + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + GUIUtil::HelpMessageBox help; + help.showOrPrint(); + return 1; + } + + QSplashScreen splash(QPixmap(":/images/splash"), 0); + if (GetBoolArg("-splash", true) && !GetBoolArg("-min")) + { + splash.show(); + splash.setAutoFillBackground(true); + splashref = &splash; + } + + app.processEvents(); + + app.setQuitOnLastWindowClosed(false); + + try + { + // Regenerate startup link, to fix links to old versions + if (GUIUtil::GetStartOnSystemStartup()) + GUIUtil::SetStartOnSystemStartup(true); + + BitcoinGUI window; + guiref = &window; + if(AppInit2()) + { + { + // Put this in a block, so that the Model objects are cleaned up before + // calling Shutdown(). + + optionsModel.Upgrade(); // Must be done after AppInit2 + + if (splashref) + splash.finish(&window); + + ClientModel clientModel(&optionsModel); + WalletModel walletModel(pwalletMain, &optionsModel); + + window.setClientModel(&clientModel); + window.setWalletModel(&walletModel); + + // If -min option passed, start window minimized. + if(GetBoolArg("-min")) + { + window.showMinimized(); + } + else + { + window.show(); + } + + // Place this here as guiref has to be defined if we don't want to lose URIs + ipcInit(argc, argv); + + app.exec(); + + window.hide(); + window.setClientModel(0); + window.setWalletModel(0); + guiref = 0; + } + // Shutdown the core and its threads, but don't exit Bitcoin-Qt here + Shutdown(NULL); + } + else + { + return 1; + } + } catch (std::exception& e) { + handleRunawayException(&e); + } catch (...) { + handleRunawayException(NULL); + } + return 0; +} +#endif // BITCOIN_QT_TEST diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc new file mode 100644 index 0000000..026b178 --- /dev/null +++ b/src/qt/bitcoin.qrc @@ -0,0 +1,60 @@ + + + res/icons/BERN-128.png + res/icons/address-book.png + res/icons/quit.png + res/icons/send.png + res/icons/BERN-16.png + res/icons/connect0_16.png + res/icons/connect1_16.png + res/icons/connect2_16.png + res/icons/connect3_16.png + res/icons/connect4_16.png + res/icons/transaction0.png + res/icons/transaction2.png + res/icons/clock1.png + res/icons/clock2.png + res/icons/clock3.png + res/icons/clock4.png + res/icons/clock5.png + res/icons/configure.png + res/icons/receive.png + res/icons/editpaste.png + res/icons/editcopy.png + res/icons/add.png + res/icons/edit.png + res/icons/history.png + res/icons/overview.png + res/icons/export.png + res/icons/synced.png + res/icons/remove.png + res/icons/tx_mined.png + res/icons/tx_input.png + res/icons/tx_output.png + res/icons/tx_inout.png + res/icons/lock_closed.png + res/icons/lock_open.png + res/icons/staking_on.png + res/icons/key.png + res/icons/filesave.png + res/icons/qrcode.png + res/icons/debugwindow.png + res/icons/statistics.png + res/icons/block.png + res/icons/powmining_inactive.png + res/icons/powmining_active.png + res/icons/mining.png + + + res/images/about.png + res/images/splash.png + res/images/wallet.png + res/images/shadow9202.png + + + res/movies/update_spinner.mng + + + locale/bitcoin_en.qm + + diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp new file mode 100644 index 0000000..5136ea0 --- /dev/null +++ b/src/qt/bitcoinaddressvalidator.cpp @@ -0,0 +1,77 @@ +#include "bitcoinaddressvalidator.h" + +/* Base58 characters are: + "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + + This is: + - All numbers except for '0' + - All upper-case letters except for 'I' and 'O' + - All lower-case letters except for 'l' + + User friendly Base58 input can map + - 'l' and 'I' to '1' + - '0' and 'O' to 'o' +*/ + +BitcoinAddressValidator::BitcoinAddressValidator(QObject *parent) : + QValidator(parent) +{ +} + +QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) const +{ + // Correction + for(int idx=0; idx= '0' && ch<='9') || + (ch >= 'a' && ch<='z') || + (ch >= 'A' && ch<='Z')) && + ch != 'l' && ch != 'I' && ch != '0' && ch != 'O') + { + // Alphanumeric and not a 'forbidden' character + } + else + { + state = QValidator::Invalid; + } + } + + // Empty address is "intermediate" input + if(input.isEmpty()) + { + state = QValidator::Intermediate; + } + + return state; +} diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h new file mode 100644 index 0000000..9710d12 --- /dev/null +++ b/src/qt/bitcoinaddressvalidator.h @@ -0,0 +1,24 @@ +#ifndef BITCOINADDRESSVALIDATOR_H +#define BITCOINADDRESSVALIDATOR_H + +#include + +/** Base48 entry widget validator. + Corrects near-miss characters and refuses characters that are no part of base48. + */ +class BitcoinAddressValidator : public QValidator +{ + Q_OBJECT +public: + explicit BitcoinAddressValidator(QObject *parent = 0); + + State validate(QString &input, int &pos) const; + + static const int MaxAddressLength = 35; +signals: + +public slots: + +}; + +#endif // BITCOINADDRESSVALIDATOR_H diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp new file mode 100644 index 0000000..9514ec8 --- /dev/null +++ b/src/qt/bitcoinamountfield.cpp @@ -0,0 +1,168 @@ +#include "bitcoinamountfield.h" +#include "qvaluecombobox.h" +#include "bitcoinunits.h" + +#include "guiconstants.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BitcoinAmountField::BitcoinAmountField(QWidget *parent): + QWidget(parent), amount(0), currentUnit(-1) +{ + amount = new QDoubleSpinBox(this); + amount->setLocale(QLocale::c()); + amount->setDecimals(8); + amount->installEventFilter(this); + amount->setMaximumWidth(170); + amount->setSingleStep(0.001); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(amount); + unit = new QValueComboBox(this); + unit->setModel(new BitcoinUnits(this)); + layout->addWidget(unit); + layout->addStretch(1); + layout->setContentsMargins(0,0,0,0); + + setLayout(layout); + + setFocusPolicy(Qt::TabFocus); + setFocusProxy(amount); + + // If one if the widgets changes, the combined content changes as well + connect(amount, SIGNAL(valueChanged(QString)), this, SIGNAL(textChanged())); + connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int))); + + // Set default based on configuration + unitChanged(unit->currentIndex()); +} + +void BitcoinAmountField::setText(const QString &text) +{ + if (text.isEmpty()) + amount->clear(); + else + amount->setValue(text.toDouble()); +} + +void BitcoinAmountField::clear() +{ + amount->clear(); + unit->setCurrentIndex(0); +} + +bool BitcoinAmountField::validate() +{ + bool valid = true; + if (amount->value() == 0.0) + valid = false; + if (valid && !BitcoinUnits::parse(currentUnit, text(), 0)) + valid = false; + + setValid(valid); + + return valid; +} + +void BitcoinAmountField::setValid(bool valid) +{ + if (valid) + amount->setStyleSheet(""); + else + amount->setStyleSheet(STYLE_INVALID); +} + +QString BitcoinAmountField::text() const +{ + if (amount->text().isEmpty()) + return QString(); + else + return amount->text(); +} + +bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::FocusIn) + { + // Clear invalid flag on focus + setValid(true); + } + else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) + { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Comma) + { + // Translate a comma into a period + QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count()); + qApp->sendEvent(object, &periodKeyEvent); + return true; + } + } + return QWidget::eventFilter(object, event); +} + +QWidget *BitcoinAmountField::setupTabChain(QWidget *prev) +{ + QWidget::setTabOrder(prev, amount); + return amount; +} + +qint64 BitcoinAmountField::value(bool *valid_out) const +{ + qint64 val_out = 0; + bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out); + if(valid_out) + { + *valid_out = valid; + } + return val_out; +} + +void BitcoinAmountField::setValue(qint64 value) +{ + setText(BitcoinUnits::format(currentUnit, value)); +} + +void BitcoinAmountField::unitChanged(int idx) +{ + // Use description tooltip for current unit for the combobox + unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString()); + + // Determine new unit ID + int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt(); + + // Parse current value and convert to new unit + bool valid = false; + qint64 currentValue = value(&valid); + + currentUnit = newUnit; + + // Set max length after retrieving the value, to prevent truncation + amount->setDecimals(BitcoinUnits::decimals(currentUnit)); + amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals())); + + if(valid) + { + // If value was valid, re-place it in the widget with the new unit + setValue(currentValue); + } + else + { + // If current value is invalid, just clear field + setText(""); + } + setValid(true); +} + +void BitcoinAmountField::setDisplayUnit(int newUnit) +{ + unit->setValue(newUnit); +} diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h new file mode 100644 index 0000000..269ab0f --- /dev/null +++ b/src/qt/bitcoinamountfield.h @@ -0,0 +1,61 @@ +#ifndef BITCOINFIELD_H +#define BITCOINFIELD_H + +#include + +QT_BEGIN_NAMESPACE +class QDoubleSpinBox; +class QValueComboBox; +QT_END_NAMESPACE + +/** Widget for entering bitcoin amounts. + */ +class BitcoinAmountField: public QWidget +{ + Q_OBJECT + Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY textChanged USER true) +public: + explicit BitcoinAmountField(QWidget *parent = 0); + + qint64 value(bool *valid=0) const; + void setValue(qint64 value); + + /** Mark current value as invalid in UI. */ + void setValid(bool valid); + /** Perform input validation, mark field as invalid if entered value is not valid. */ + bool validate(); + + /** Change unit used to display amount. */ + void setDisplayUnit(int unit); + + /** Make field empty and ready for new input. */ + void clear(); + + /** Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907), + in these cases we have to set it up manually. + */ + QWidget *setupTabChain(QWidget *prev); + + QString text() const; + +signals: + void textChanged(); + +protected: + /** Intercept focus-in event and ',' key presses */ + bool eventFilter(QObject *object, QEvent *event); + +private: + QDoubleSpinBox *amount; + QValueComboBox *unit; + int currentUnit; + + void setText(const QString &text); + +private slots: + void unitChanged(int idx); + +}; + + +#endif // BITCOINFIELD_H diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp new file mode 100644 index 0000000..f777928 --- /dev/null +++ b/src/qt/bitcoingui.cpp @@ -0,0 +1,1147 @@ +/* + * Qt4 bitcoin GUI. + * + * W.J. van der Laan 2011-2012 + * The Bitcoin Developers 2011-2012 + */ +#include "bitcoingui.h" +#include "transactiontablemodel.h" +#include "addressbookpage.h" +#include "sendcoinsdialog.h" +#include "signverifymessagedialog.h" +#include "optionsdialog.h" +#include "aboutdialog.h" +#include "clientmodel.h" +#include "walletmodel.h" +#include "editaddressdialog.h" +#include "optionsmodel.h" +#include "transactiondescdialog.h" +#include "addresstablemodel.h" +#include "transactionview.h" +#include "overviewpage.h" +#include "bitcoinunits.h" +#include "guiconstants.h" +#include "askpassphrasedialog.h" +#include "notificator.h" +#include "guiutil.h" +#include "rpcconsole.h" +#include "wallet.h" +#include "bitcoinrpc.h" +#include "miningpage.h" +#include "statisticspage.h" +#include "blockbrowser.h" + +#ifdef Q_OS_MAC +#include "macdockiconhandler.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if QT_VERSION < 0x050000 +#include +#else +#include +#endif +#include +#include +#if QT_VERSION < 0x050000 +#include +#else +#include +#include +#endif +#include + +#include + +extern CWallet *pwalletMain; +extern int64 nLastCoinStakeSearchInterval; +extern unsigned int nStakeTargetSpacing; +QString glbAddress; + +BitcoinGUI::BitcoinGUI(QWidget *parent): + QMainWindow(parent), + clientModel(0), + walletModel(0), + encryptWalletAction(0), + changePassphraseAction(0), + lockWalletToggleAction(0), + unlockWalletAction(0), + lockWalletAction(0), + aboutQtAction(0), + trayIcon(0), + notificator(0), + rpcConsole(0) +{ + resize(930, 550); + setWindowTitle(tr("BERN") + " - " + tr("Wallet")); +#ifndef Q_OS_MAC + qApp->setWindowIcon(QIcon(":icons/bitcoin")); + setWindowIcon(QIcon(":icons/bitcoin")); +#else + setUnifiedTitleAndToolBarOnMac(true); + QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); +#endif + // Accept D&D of URIs + setAcceptDrops(true); + + setStyleSheet("QToolTip { color: #cecece; background-color: #333333; border:0px;} "); + + // Create actions for the toolbar, menu bar and tray/dock icon + createActions(); + + // Create application menu bar + createMenuBar(); + + // Create the toolbars + createToolBars(); + + // Create the tray icon (or setup the dock icon) + createTrayIcon(); + + // Create tabs + overviewPage = new OverviewPage(); + + transactionsPage = new QWidget(this); + QVBoxLayout *vbox = new QVBoxLayout(); + transactionView = new TransactionView(this); + vbox->addWidget(transactionView); + transactionsPage->setLayout(vbox); + + addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab); + + receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab); + + sendCoinsPage = new SendCoinsDialog(this); + + signVerifyMessageDialog = new SignVerifyMessageDialog(this); + + miningPage = new MiningPage(this); + statisticsPage = new StatisticsPage(this); + blockBrowser = new BlockBrowser(this); + + centralWidget = new QStackedWidget(this); + centralWidget->addWidget(overviewPage); + centralWidget->addWidget(transactionsPage); + centralWidget->addWidget(addressBookPage); + centralWidget->addWidget(receiveCoinsPage); + centralWidget->addWidget(sendCoinsPage); + centralWidget->addWidget(miningPage); + centralWidget->addWidget(statisticsPage); + centralWidget->addWidget(blockBrowser); + setCentralWidget(centralWidget); + + // Create status bar + statusBar(); + + // Status bar notification icons + QFrame *frameBlocks = new QFrame(); + frameBlocks->setContentsMargins(0,0,0,0); + frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks); + frameBlocksLayout->setContentsMargins(3,0,3,0); + frameBlocksLayout->setSpacing(4); + labelEncryptionIcon = new QLabel(); + labelMiningIcon = new QLabel(); + labelMintingIcon = new QLabel(); + labelConnectionsIcon = new QLabel(); + labelBlocksIcon = new QLabel(); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelEncryptionIcon); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelMiningIcon); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelMintingIcon); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelConnectionsIcon); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelBlocksIcon); + frameBlocksLayout->addStretch(); + + labelEncryptionIcon->setObjectName("labelEncryptionIcon"); + labelConnectionsIcon->setObjectName("labelConnectionsIcon"); + labelBlocksIcon->setObjectName("labelBlocksIcon"); + labelMiningIcon->setObjectName("labelMiningIcon"); + labelMintingIcon->setObjectName("labelMintingIcon"); + labelEncryptionIcon->setStyleSheet("#labelEncryptionIcon QToolTip {color:#cecece;background-color:#333333;border:0px;}"); + labelConnectionsIcon->setStyleSheet("#labelConnectionsIcon QToolTip {color:#cecece;background-color:#333333;border:0px;}"); + labelBlocksIcon->setStyleSheet("#labelBlocksIcon QToolTip {color:#cecece;background-color:#333333;border:0px;}"); + labelMintingIcon->setStyleSheet("#labelMintingIcon QToolTip {color:#cecece;background-color:#333333;border:0px;}"); + labelMiningIcon->setStyleSheet("#labelMiningIcon QToolTip {color:#cecece;background-color:#333333;border:0px;}"); + + + // Set minting pixmap + labelMintingIcon->setPixmap(QIcon(":/icons/minting").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelMintingIcon->setEnabled(false); + // Add timer to update minting icon + QTimer *timerMintingIcon = new QTimer(labelMintingIcon); + timerMintingIcon->start(MODEL_UPDATE_DELAY); + connect(timerMintingIcon, SIGNAL(timeout()), this, SLOT(updateMintingIcon())); + // Add timer to update minting weights + QTimer *timerMintingWeights = new QTimer(labelMintingIcon); + timerMintingWeights->start(30 * 100); // was 1000 + connect(timerMintingWeights, SIGNAL(timeout()), this, SLOT(updateMintingWeights())); + // Set initial values for user and network weights + nWeight = 0; + nNetworkWeight = 0; + // Set mining pixmap + labelMiningIcon->setPixmap(QIcon(":/icons/powmining_inactive").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelMiningIcon->setEnabled(true); + + // Progress bar and label for blocks download + progressBarLabel = new QLabel(); + progressBarLabel->setVisible(false); + progressBar = new QProgressBar(); + progressBar->setAlignment(Qt::AlignCenter); + progressBar->setVisible(false); + + // Override style sheet for progress bar for styles that have a segmented progress bar, + // as they make the text unreadable (workaround for issue #1071) + // See https://qt-project.org/doc/qt-4.8/gallery.html + QString curStyle = qApp->style()->metaObject()->className(); + if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle") + { + progressBar->setStyleSheet("QProgressBar { background-color: #e8e8e8; border: 1px solid grey; border-radius: 7px; padding: 1px; text-align: center; } QProgressBar::chunk { background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #FF8000, stop: 1 orange); border-radius: 7px; margin: 0px; }"); + } + + statusBar()->addWidget(progressBarLabel); + statusBar()->addWidget(progressBar); + statusBar()->addPermanentWidget(frameBlocks); + statusBar()->setObjectName("BERNstatusBar"); + statusBar()->setStyleSheet("#BERNstatusBar { border-top-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #4B4F52, stop:0.5 #8B8F92, stop:1.0 #8B8F92); border-top-width: 2px; border-top-style: inset; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #666666, stop:0.5 #323232, stop:1.0 #111111); color: #ffffff; } QToolTip { color: #ffffff; background-color: #9D0000; border-width: 1px;border-color:#CA0D0D;}"); + syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this); + + // Clicking on a transaction on the overview page simply sends you to transaction history page + connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage())); + connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex))); + + // Double-clicking on a transaction on the transaction history page shows details + connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails())); + + rpcConsole = new RPCConsole(this); + connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show())); + + // Clicking on "Verify Message" in the address book sends you to the verify message tab + connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString))); + // Clicking on "Sign Message" in the receive coins page sends you to the sign message tab + connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString))); + + gotoOverviewPage(); +} + +BitcoinGUI::~BitcoinGUI() +{ + if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu) + trayIcon->hide(); +#ifdef Q_OS_MAC + delete appMenuBar; +#endif +} + +void BitcoinGUI::createActions() +{ + QActionGroup *tabGroup = new QActionGroup(this); + + overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this); + overviewAction->setToolTip(tr("Show general overview of BERN wallet")); + overviewAction->setCheckable(true); + overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1)); + tabGroup->addAction(overviewAction); + + sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send"), this); + sendCoinsAction->setToolTip(tr("Send to a BERN address")); + sendCoinsAction->setCheckable(true); + sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); + tabGroup->addAction(sendCoinsAction); + + receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive"), this); + receiveCoinsAction->setToolTip(tr("Show the list of your BERN addresses for receiving payments")); + receiveCoinsAction->setCheckable(true); + receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); + tabGroup->addAction(receiveCoinsAction); + + historyAction = new QAction(QIcon(":/icons/history"), tr("&Ledger"), this); + historyAction->setToolTip(tr("Browse your BERN transaction history")); + historyAction->setCheckable(true); + historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4)); + tabGroup->addAction(historyAction); + + addressBookAction = new QAction(QIcon(":/icons/address-book"), tr("&Addresses"), this); + addressBookAction->setToolTip(tr("Edit the list of your stored BERN addresses and labels")); + addressBookAction->setCheckable(true); + addressBookAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5)); + tabGroup->addAction(addressBookAction); + + miningAction = new QAction(QIcon(":/icons/mining"), tr("&Mine"), this); + miningAction->setToolTip(tr("BERN PoW mining")); + miningAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_6)); + miningAction->setCheckable(true); + tabGroup->addAction(miningAction); + + statisticsAction = new QAction(QIcon(":/icons/statistics"), tr("&Stats"), this); + statisticsAction->setToolTip(tr("BERN statistics")); + statisticsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_7)); + statisticsAction->setCheckable(true); + tabGroup->addAction(statisticsAction); + + blockAction = new QAction(QIcon(":/icons/block"), tr("&Explore"), this); + blockAction->setToolTip(tr("Explore the BERN blockchain")); + blockAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_8)); + blockAction->setCheckable(true); + tabGroup->addAction(blockAction); + + connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage())); + connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); + connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); + connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); + connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage())); + connect(miningAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(miningAction, SIGNAL(triggered()), this, SLOT(gotoMiningPage())); + connect(statisticsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(statisticsAction, SIGNAL(triggered()), this, SLOT(gotoStatisticsPage())); + connect(blockAction, SIGNAL(triggered()), this, SLOT(gotoBlockBrowser())); + connect(blockAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + + quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this); + quitAction->setToolTip(tr("Quit application")); + quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); + quitAction->setMenuRole(QAction::QuitRole); + aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About BERN"), this); + aboutAction->setToolTip(tr("Show information about BERN")); + aboutAction->setMenuRole(QAction::AboutRole); + aboutQtAction = new QAction(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this); + aboutQtAction->setToolTip(tr("Show information about Qt")); + aboutQtAction->setMenuRole(QAction::AboutQtRole); + optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); + optionsAction->setToolTip(tr("Modify configuration options for BERN")); + optionsAction->setMenuRole(QAction::PreferencesRole); + toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Show / Hide"), this); + encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); + encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet")); + encryptWalletAction->setCheckable(true); + backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); + backupWalletAction->setToolTip(tr("Backup wallet to another location")); + changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this); + changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption")); + lockWalletToggleAction = new QAction(this); + unlockWalletAction = new QAction(QIcon(":/icons/lock_open"), tr("&Unlock Wallet..."), this); + unlockWalletAction->setToolTip(tr("Unlock wallet")); + lockWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Lock Wallet"), this); + lockWalletAction->setToolTip(tr("Lock wallet")); + signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this); + verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this); + + exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this); + exportAction->setToolTip(tr("Export the data in the current tab to a file")); + openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug Window"), this); + openRPCConsoleAction->setToolTip(tr("Open debugging and diagnostic console")); + + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); + connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked())); + connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden())); + connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool))); + connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet())); + connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase())); + connect(lockWalletToggleAction, SIGNAL(triggered()), this, SLOT(lockWalletToggle())); + connect(unlockWalletAction, SIGNAL(triggered()), this, SLOT(unlockWallet())); + connect(lockWalletAction, SIGNAL(triggered()), this, SLOT(lockWallet())); + connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); + connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); +} + +void BitcoinGUI::createMenuBar() +{ +#ifdef Q_OS_MAC + // Create a decoupled menu bar on Mac which stays even if the window is closed + appMenuBar = new QMenuBar(); +#else + // Get the main window's menu bar on other platforms + appMenuBar = menuBar(); +#endif + + // Configure the menus + QMenu *file = appMenuBar->addMenu(tr("&File")); + file->addAction(backupWalletAction); + file->addAction(exportAction); + file->addAction(signMessageAction); + file->addAction(verifyMessageAction); + file->addSeparator(); + file->addAction(quitAction); + + QMenu *settings = appMenuBar->addMenu(tr("&Settings")); + settings->addAction(encryptWalletAction); + settings->addAction(changePassphraseAction); + settings->addAction(lockWalletToggleAction); + settings->addSeparator(); + settings->addAction(optionsAction); + + QMenu *help = appMenuBar->addMenu(tr("&Help")); + help->addAction(openRPCConsoleAction); + help->addSeparator(); + help->addAction(aboutAction); + help->addAction(aboutQtAction); + + // QString ss("QMenuBar::item { background-color: #effbef; color: black }"); + // appMenuBar->setStyleSheet(ss); +} + +void BitcoinGUI::createToolBars() +{ + QToolBar *toolbar = addToolBar(tr("Tabs toolbar")); + toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + toolbar->addAction(overviewAction); + toolbar->addAction(sendCoinsAction); + toolbar->addAction(receiveCoinsAction); + toolbar->addAction(historyAction); + toolbar->addAction(addressBookAction); + toolbar->addAction(miningAction); + toolbar->addAction(statisticsAction); + toolbar->addAction(blockAction); + + QToolBar *toolbar2 = addToolBar(tr("Actions toolbar")); + toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + toolbar2->addAction(lockWalletToggleAction); + toolbar2->addAction(exportAction); + + toolbar->setObjectName("tabsToolbar"); + toolbar2->setObjectName("actionsToolbar"); + toolbar->setStyleSheet("QToolButton { min-height:48px;color:#ffffff;border:none;margin:0px;padding:0px;} QToolButton:hover { color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #8E8F8F, stop:1.0 #7E7F81); margin:0px; padding:0px; border:none; } QToolButton:checked { color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #474748, stop:1.0 #353536); margin:0px; padding:0px; border-right-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #3b3b3b, stop:0.5 #6c6c6f, stop:1.0 #6c6c6f);border-right-width:2px;border-right-style:inset; border-left-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #6c6c6f, stop:0.5 #6c6c6f, stop:1.0 #3b3b3b);border-left-width:2px;border-left-style:inset; } QToolButton:pressed { color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #474748, stop:1.0 #353536); margin:0px; padding:0px; border:none;} QToolButton:selected { color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #474748, stop:1.0 #353536); margin:0px;padding:0px;border:none; } #tabsToolbar { min-height:48px; color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #6e6e71, stop:1.0 #4e4e4f); margin:0px; padding:0px; border-top-color: rgba(160, 160, 160, 191); border-top-width: 1px; border-top-style: inset; } QToolBar::handle { background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #6e6e71, stop:1.0 #4e4e4f); }"); + toolbar2->setStyleSheet("QToolButton { min-height:48px;color:#ffffff;border:none;margin:0px;padding:0px;} QToolButton::disabled { color: #808080; } QToolButton:hover { color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #7D7E7F, stop:1.0 #6D6F70); margin:0px; padding:0px; border:none; } QToolButton:checked { color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #363637, stop:1.0 #242425); margin:0px; padding:0px; border-right-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #2a2a2a, stop:0.5 #5b5b5e, stop:1.0 #5b5b5e);border-right-width:2px;border-right-style:inset; border-left-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #5b5b5e, stop:0.5 #5b5b5e, stop:1.0 #2a2a2a);border-left-width:2px;border-left-style:inset; } QToolButton:pressed { color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #363637, stop:1.0 #242425); margin:0px; padding:0px; border:none; border-left-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #5b5b5e, stop:0.5 #5b5b5e, stop:1.0 #2a2a2a);border-left-width:2px;border-left-style:inset;} QToolButton:selected { color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #363637, stop:1.0 #242425); margin:0px;padding:0px;border:none; } #actionsToolbar { color: #ffffff; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #5D5D60, stop:1.0 #3D3D3F); margin:0px; padding:0px; border-top-color: rgba(160, 160, 160, 191); border-top-width: 1px; border-top-style: inset; } QToolBar::handle { background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #5D5D60, stop:1.0 #3D3D3F); }"); +} + +void BitcoinGUI::setClientModel(ClientModel *clientModel) +{ + this->clientModel = clientModel; + if(clientModel) + { + // Replace some strings and icons, when using the testnet + if(clientModel->isTestNet()) + { + setWindowTitle(windowTitle() + QString(" ") + tr("[testnet]")); +#ifndef Q_OS_MAC + qApp->setWindowIcon(QIcon(":icons/bitcoin_testnet")); + setWindowIcon(QIcon(":icons/bitcoin_testnet")); +#else + MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet")); +#endif + if(trayIcon) + { + trayIcon->setToolTip(tr("BERN Wallet") + QString(" ") + tr("[testnet]")); + trayIcon->setIcon(QIcon(":/icons/toolbar_testnet")); + toggleHideAction->setIcon(QIcon(":/icons/toolbar_testnet")); + } + + aboutAction->setIcon(QIcon(":/icons/toolbar_testnet")); + } + + // Keep up to date with client + setNumConnections(clientModel->getNumConnections()); + connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); + + setNumBlocks(clientModel->getNumBlocks(), clientModel->getNumBlocksOfPeers()); + connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int))); + + setMining(false, 0); + connect(clientModel, SIGNAL(miningChanged(bool,int)), this, SLOT(setMining(bool,int))); + + // Report errors from network/worker thread + connect(clientModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); + + rpcConsole->setClientModel(clientModel); + addressBookPage->setOptionsModel(clientModel->getOptionsModel()); + receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel()); + } +} + +void BitcoinGUI::setWalletModel(WalletModel *walletModel) +{ + this->walletModel = walletModel; + if(walletModel) + { + // Report errors from wallet thread + connect(walletModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); + + // Put transaction list in tabs + transactionView->setModel(walletModel); + + overviewPage->setModel(walletModel); + addressBookPage->setModel(walletModel->getAddressTableModel()); + receiveCoinsPage->setModel(walletModel->getAddressTableModel()); + sendCoinsPage->setModel(walletModel); + signVerifyMessageDialog->setModel(walletModel); + miningPage->setModel(clientModel); + statisticsPage->setModel(clientModel); + blockBrowser->setModel(clientModel); + + setEncryptionStatus(walletModel->getEncryptionStatus()); + connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int))); + + // Balloon pop-up for new transaction + connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(incomingTransaction(QModelIndex,int,int))); + + // Ask for passphrase if needed + connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); + } +} + +void BitcoinGUI::createTrayIcon() +{ + QMenu *trayIconMenu; +#ifndef Q_OS_MAC + trayIcon = new QSystemTrayIcon(this); + trayIconMenu = new QMenu(this); + trayIcon->setContextMenu(trayIconMenu); + trayIcon->setToolTip(tr("BERN Wallet")); + trayIcon->setIcon(QIcon(":/icons/toolbar")); + connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + trayIcon->show(); +#else + // Note: On Mac, the dock icon is used to provide the tray's functionality. + MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); + trayIconMenu = dockIconHandler->dockMenu(); + dockIconHandler->setMainWindow((QMainWindow*)this); +#endif + + // Configuration of the tray icon (or dock icon) icon menu + trayIconMenu->addAction(toggleHideAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(sendCoinsAction); + trayIconMenu->addAction(receiveCoinsAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(signMessageAction); + trayIconMenu->addAction(verifyMessageAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(optionsAction); + trayIconMenu->addAction(openRPCConsoleAction); +#ifndef Q_OS_MAC // This is built-in on Mac + trayIconMenu->addSeparator(); + trayIconMenu->addAction(quitAction); +#endif + + notificator = new Notificator(qApp->applicationName(), trayIcon); +} + +#ifndef Q_OS_MAC +void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) +{ + if(reason == QSystemTrayIcon::Trigger) + { + // Click on system tray icon triggers show/hide of the main window + toggleHideAction->trigger(); + } +} +#endif + +void BitcoinGUI::optionsClicked() +{ + if(!clientModel || !clientModel->getOptionsModel()) + return; + OptionsDialog dlg; + dlg.setModel(clientModel->getOptionsModel()); + dlg.exec(); +} + +void BitcoinGUI::aboutClicked() +{ + AboutDialog dlg; + dlg.setModel(clientModel); + dlg.exec(); +} + +void BitcoinGUI::setNumConnections(int count) +{ + QString icon; + switch(count) + { + case 0: icon = ":/icons/connect_0"; break; + case 1: case 2: case 3: icon = ":/icons/connect_1"; break; + case 4: case 5: case 6: icon = ":/icons/connect_2"; break; + case 7: case 8: case 9: icon = ":/icons/connect_3"; break; + default: icon = ":/icons/connect_4"; break; + } + labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelConnectionsIcon->setToolTip(tr("%n active connection(s) to the BERN network.", "", count)); +} + +void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) +{ + // don't show / hide progress bar and its label if we have no connection to the network + if (!clientModel || clientModel->getNumConnections() == 0) + { + progressBarLabel->setVisible(false); + progressBar->setVisible(false); + + return; + } + + QString strStatusBarWarnings = clientModel->getStatusBarWarnings(); + QString tooltip; + + if(count < nTotalBlocks) + { + int nRemainingBlocks = nTotalBlocks - count; + float nPercentageDone = count / (nTotalBlocks * 0.01f); + + if (strStatusBarWarnings.isEmpty()) + { + progressBarLabel->setText(tr("Synchronizing with network...")); + progressBarLabel->setVisible(true); + progressBar->setFormat(tr("~%n block(s) remaining", "", nRemainingBlocks)); + progressBar->setMaximum(nTotalBlocks); + progressBar->setValue(count); + progressBar->setVisible(true); + } + + tooltip = tr("Downloaded %1 of %2 blocks of transaction history (%3% done).").arg(count).arg(nTotalBlocks).arg(nPercentageDone, 0, 'f', 2); + } + else + { + if (strStatusBarWarnings.isEmpty()) + progressBarLabel->setVisible(false); + + progressBar->setVisible(false); + tooltip = tr("Downloaded %1 blocks of transaction history.").arg(count); + } + + // Override progressBarLabel text and hide progress bar, when we have warnings to display + if (!strStatusBarWarnings.isEmpty()) + { + progressBarLabel->setText(strStatusBarWarnings); + progressBarLabel->setVisible(true); + progressBar->setVisible(false); + } + //tooltip = tr("Current PoW difficulty is %1.").arg(clientModel->GetDifficulty(GetLastBlockIndex(pindexBest, true)) + QString("
") + tooltip; + //tooltip = tr("Current PoS difficulty is %1.").arg(clientModel->GetDifficulty()) + QString("
") + tooltip; + + QDateTime lastBlockDate = clientModel->getLastBlockDate(); + int secs = lastBlockDate.secsTo(QDateTime::currentDateTime()); + QString text; + + // Represent time from last generated block in human readable text + if(secs <= 0) + { + // Fully up to date. Leave text empty. + } + else if(secs < 60) + { + text = tr("%n second(s) ago","",secs); + } + else if(secs < 60*60) + { + text = tr("%n minute(s) ago","",secs/60); + } + else if(secs < 24*60*60) + { + text = tr("%n hour(s) ago","",secs/(60*60)); + } + else + { + text = tr("%n day(s) ago","",secs/(60*60*24)); + } + + // Set icon state: spinning if catching up, tick otherwise + if(secs < 90*60 && count >= nTotalBlocks) + { + tooltip = tr("Up to date") + QString(".
") + tooltip; + labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + + overviewPage->showOutOfSyncWarning(false); + } + else + { + tooltip = tr("Catching up...") + QString("
") + tooltip; + labelBlocksIcon->setMovie(syncIconMovie); + syncIconMovie->start(); + + overviewPage->showOutOfSyncWarning(true); + } + + if(!text.isEmpty()) + { + tooltip += QString("
"); + tooltip += tr("Last received block was generated %1.").arg(text); + } + + // Don't word-wrap this (fixed-width) tooltip + tooltip = QString("") + tooltip + QString(""); + + labelBlocksIcon->setToolTip(tooltip); + progressBarLabel->setToolTip(tooltip); + progressBar->setToolTip(tooltip); +} + +void BitcoinGUI::error(const QString &title, const QString &message, bool modal) +{ + // Report errors from network/worker thread + if(modal) + { + QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok); + } else { + notificator->notify(Notificator::Critical, title, message); + } +} + +void BitcoinGUI::changeEvent(QEvent *e) +{ + QMainWindow::changeEvent(e); +#ifndef Q_OS_MAC // Ignored on Mac + if(e->type() == QEvent::WindowStateChange) + { + if(clientModel && clientModel->getOptionsModel()->getMinimizeToTray()) + { + QWindowStateChangeEvent *wsevt = static_cast(e); + if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized()) + { + QTimer::singleShot(0, this, SLOT(hide())); + e->ignore(); + } + } + } +#endif +} + +void BitcoinGUI::closeEvent(QCloseEvent *event) +{ + if(clientModel) + { +#ifndef Q_OS_MAC // Ignored on Mac + if(!clientModel->getOptionsModel()->getMinimizeToTray() && + !clientModel->getOptionsModel()->getMinimizeOnClose()) + { + qApp->quit(); + } +#endif + } + QMainWindow::closeEvent(event); +} + +void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee) +{ + QString strMessage = + tr("This transaction is over the size limit. You can still send it for a fee of %1, " + "which goes to the nodes that process your transaction and helps to support the network. " + "Do you want to pay the fee?").arg( + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired)); + QMessageBox::StandardButton retval = QMessageBox::question( + this, tr("Confirm transaction fee"), strMessage, + QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes); + *payFee = (retval == QMessageBox::Yes); +} + +void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int end) +{ + if(!walletModel || !clientModel) + return; + TransactionTableModel *ttm = walletModel->getTransactionTableModel(); + qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent) + .data(Qt::EditRole).toULongLong(); + if(!clientModel->inInitialBlockDownload()) + { + // On new transaction, make an info balloon + // Unless the initial block download is in progress, to prevent balloon-spam + QString date = ttm->index(start, TransactionTableModel::Date, parent) + .data().toString(); + QString type = ttm->index(start, TransactionTableModel::Type, parent) + .data().toString(); + QString address = ttm->index(start, TransactionTableModel::ToAddress, parent) + .data().toString(); + QIcon icon = qvariant_cast(ttm->index(start, + TransactionTableModel::ToAddress, parent) + .data(Qt::DecorationRole)); + + notificator->notify(Notificator::Information, + (amount)<0 ? tr("Sent transaction") : + tr("Incoming transaction"), + tr("Date: %1\n" + "Amount: %2\n" + "Type: %3\n" + "Address: %4\n") + .arg(date) + .arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true)) + .arg(type) + .arg(address), icon); + } +} + +void BitcoinGUI::gotoOverviewPage() +{ + overviewAction->setChecked(true); + centralWidget->setCurrentWidget(overviewPage); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +} + +void BitcoinGUI::gotoHistoryPage() +{ + historyAction->setChecked(true); + centralWidget->setCurrentWidget(transactionsPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked())); +} + +void BitcoinGUI::gotoAddressBookPage() +{ + addressBookAction->setChecked(true); + centralWidget->setCurrentWidget(addressBookPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked())); +} + +void BitcoinGUI::gotoReceiveCoinsPage() +{ + receiveCoinsAction->setChecked(true); + centralWidget->setCurrentWidget(receiveCoinsPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked())); +} + +void BitcoinGUI::gotoSendCoinsPage() +{ + sendCoinsAction->setChecked(true); + centralWidget->setCurrentWidget(sendCoinsPage); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +} + +void BitcoinGUI::gotoSignMessageTab(QString addr) +{ + // call show() in showTab_SM() + signVerifyMessageDialog->showTab_SM(true); + + if(!addr.isEmpty()) + signVerifyMessageDialog->setAddress_SM(addr); +} + +void BitcoinGUI::gotoVerifyMessageTab(QString addr) +{ + // call show() in showTab_VM() + signVerifyMessageDialog->showTab_VM(true); + + if(!addr.isEmpty()) + signVerifyMessageDialog->setAddress_VM(addr); +} + +void BitcoinGUI::gotoMiningPage() +{ + miningAction->setChecked(true); + centralWidget->setCurrentWidget(miningPage); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +} + +void BitcoinGUI::gotoStatisticsPage() +{ + statisticsAction->setChecked(true); + centralWidget->setCurrentWidget(statisticsPage); + + //exportAction->setVisible(false); + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +} + +void BitcoinGUI::gotoBlockBrowser() +{ + blockAction->setChecked(true); + centralWidget->setCurrentWidget(blockBrowser); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +} + + +void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event) +{ + // Accept only URIs + if(event->mimeData()->hasUrls()) + event->acceptProposedAction(); +} + +void BitcoinGUI::dropEvent(QDropEvent *event) +{ + if(event->mimeData()->hasUrls()) + { + int nValidUrisFound = 0; + QList uris = event->mimeData()->urls(); + foreach(const QUrl &uri, uris) + { + if (sendCoinsPage->handleURI(uri.toString())) + nValidUrisFound++; + } + + // if valid URIs were found + if (nValidUrisFound) + gotoSendCoinsPage(); + else + notificator->notify(Notificator::Warning, tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid BERN address or malformed URI parameters.")); + } + + event->acceptProposedAction(); +} + +void BitcoinGUI::handleURI(QString strURI) +{ + // URI has to be valid + if (sendCoinsPage->handleURI(strURI)) + { + showNormalIfMinimized(); + gotoSendCoinsPage(); + } + else + notificator->notify(Notificator::Warning, tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid BERN address or malformed URI parameters.")); +} + +void BitcoinGUI::setEncryptionStatus(int status) +{ + switch(status) + { + case WalletModel::Unencrypted: + labelEncryptionIcon->hide(); + encryptWalletAction->setChecked(false); + encryptWalletAction->setEnabled(true); + changePassphraseAction->setEnabled(false); + lockWalletToggleAction->setVisible(false); + break; + case WalletModel::Unlocked: + labelEncryptionIcon->show(); + labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently unlocked.")); + encryptWalletAction->setChecked(true); + encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported + changePassphraseAction->setEnabled(true); + lockWalletToggleAction->setVisible(true); + lockWalletToggleAction->setIcon(QIcon(":/icons/lock_closed")); + lockWalletToggleAction->setText(tr("&Lock Wallet")); + lockWalletToggleAction->setToolTip(tr("Lock wallet")); + break; + case WalletModel::Locked: + labelEncryptionIcon->show(); + labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently locked.")); + encryptWalletAction->setChecked(true); + encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported + changePassphraseAction->setEnabled(true); + lockWalletToggleAction->setVisible(true); + lockWalletToggleAction->setIcon(QIcon(":/icons/lock_open")); + lockWalletToggleAction->setText(tr("&Unlock Wallet...")); + lockWalletToggleAction->setToolTip(tr("Unlock wallet")); + break; + } +} + +void BitcoinGUI::encryptWallet(bool status) +{ + if(!walletModel) + return; + AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt: + AskPassphraseDialog::Decrypt, this); + dlg.setModel(walletModel); + dlg.exec(); + + setEncryptionStatus(walletModel->getEncryptionStatus()); +} + +void BitcoinGUI::backupWallet() +{ +#if QT_VERSION < 0x050000 + QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); +#else + QString saveDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); +#endif + QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)")); + if(!filename.isEmpty()) { + if(!walletModel->backupWallet(filename)) { + QMessageBox::warning(this, tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location.")); + } + } +} + +void BitcoinGUI::unlockWallet() +{ + if(!walletModel) + return; + // Unlock wallet when requested by wallet model + if(walletModel->getEncryptionStatus() == WalletModel::Locked) + { + AskPassphraseDialog::Mode mode = sender() == unlockWalletAction ? + AskPassphraseDialog::UnlockMinting : AskPassphraseDialog::Unlock; + AskPassphraseDialog dlg(mode, this); + dlg.setModel(walletModel); + dlg.exec(); + } +} + +void BitcoinGUI::lockWallet() +{ + if(!walletModel) + return; + + walletModel->setWalletLocked(true); +} + +void BitcoinGUI::changePassphrase() +{ + AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this); + dlg.setModel(walletModel); + dlg.exec(); +} + +void BitcoinGUI::lockWalletToggle() +{ + if(!walletModel) + return; + + // Unlock wallet when requested by wallet model + if(walletModel->getEncryptionStatus() == WalletModel::Locked) + { + AskPassphraseDialog::Mode mode = AskPassphraseDialog::UnlockMinting; + AskPassphraseDialog dlg(mode, this); + dlg.setModel(walletModel); + dlg.exec(); + } + else + walletModel->setWalletLocked(true); +} + +void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden) +{ + // activateWindow() (sometimes) helps with keyboard focus on Windows + if (isHidden()) + { + show(); + activateWindow(); + } + else if (isMinimized()) + { + showNormal(); + activateWindow(); + } + else if (GUIUtil::isObscured(this)) + { + raise(); + activateWindow(); + } + else if(fToggleHidden) + hide(); +} + +void BitcoinGUI::toggleHidden() +{ + showNormalIfMinimized(true); +} + +void BitcoinGUI::updateMintingIcon() +{ + if (pwalletMain && pwalletMain->IsLocked()) + { + labelMintingIcon->setToolTip(tr("Not staking because wallet is locked.")); + labelMintingIcon->setEnabled(false); + } + else if (vNodes.empty()) + { + labelMintingIcon->setToolTip(tr("Not staking because wallet is offline.")); + labelMintingIcon->setEnabled(false); + } + else if (IsInitialBlockDownload()) + { + labelMintingIcon->setToolTip(tr("Not staking because wallet is syncing.")); + labelMintingIcon->setEnabled(false); + } + else if (!nWeight) + { + labelMintingIcon->setToolTip(tr("Not staking because you don't have mature coins.")); + labelMintingIcon->setEnabled(false); + } + else if (nLastCoinStakeSearchInterval) + { + uint64 nEstimateTime = nStakeTargetSpacing * nNetworkWeight / nWeight; + + QString text; + if (nEstimateTime < 60) + { + text = tr("%n second(s)", "", nEstimateTime); + } + else if (nEstimateTime < 60*60) + { + text = tr("%n minute(s)", "", nEstimateTime/60); + } + else if (nEstimateTime < 24*60*60) + { + text = tr("%n hour(s)", "", nEstimateTime/(60*60)); + } + else + { + text = tr("%n day(s)", "", nEstimateTime/(60*60*24)); + } + + labelMintingIcon->setEnabled(true); + labelMintingIcon->setToolTip(tr("Staking.
Your weight is %1.
Network weight is %2.
Expected time to earn reward is %3.").arg(nWeight).arg(nNetworkWeight).arg(text)); + } + else + { + labelMintingIcon->setToolTip(tr("Not staking.")); + labelMintingIcon->setEnabled(false); + } +} + +void BitcoinGUI::updateMintingWeights() +{ + // Only update if we have the network's current number of blocks, or weight(s) are zero (fixes lagging GUI) + if ((clientModel && clientModel->getNumBlocks() == clientModel->getNumBlocksOfPeers()) || !nWeight || !nNetworkWeight) + { + nWeight = 0; + + if (pwalletMain) + pwalletMain->GetStakeWeight(*pwalletMain, nMinMax, nMinMax, nWeight); + + nNetworkWeight = GetPoSKernelPS(); + } +} + +void BitcoinGUI::setMining(bool mining, int hashrate) +{ + if (mining) + { + labelMiningIcon->setPixmap(QIcon(":/icons/powmining_active").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelMiningIcon->setToolTip(tr("Mining BERN at %1 hashes per second").arg(hashrate)); + } + else + { + labelMiningIcon->setPixmap(QIcon(":/icons/powmining_inactive").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelMiningIcon->setToolTip(tr("Not mining BERN")); + } +} diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h new file mode 100644 index 0000000..f16b200 --- /dev/null +++ b/src/qt/bitcoingui.h @@ -0,0 +1,214 @@ +#ifndef BITCOINGUI_H +#define BITCOINGUI_H + +#include +#include + +#include "util.h" // for uint64 + +class TransactionTableModel; +class ClientModel; +class WalletModel; +class TransactionView; +class OverviewPage; +class AddressBookPage; +class SendCoinsDialog; +class SignVerifyMessageDialog; +class Notificator; +class RPCConsole; +class MiningPage; +class StatisticsPage; +class BlockBrowser; + +QT_BEGIN_NAMESPACE +class QLabel; +class QLineEdit; +class QTableView; +class QAbstractItemModel; +class QModelIndex; +class QProgressBar; +class QStackedWidget; +class QUrl; +QT_END_NAMESPACE + +/** + Bitcoin GUI main class. This class represents the main window of the Bitcoin UI. It communicates with both the client and + wallet models to give the user an up-to-date view of the current core state. +*/ +class BitcoinGUI : public QMainWindow +{ + Q_OBJECT +public: + explicit BitcoinGUI(QWidget *parent = 0); + ~BitcoinGUI(); + + /** Set the client model. + The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic. + */ + void setClientModel(ClientModel *clientModel); + /** Set the wallet model. + The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending + functionality. + */ + void setWalletModel(WalletModel *walletModel); + +protected: + void changeEvent(QEvent *e); + void closeEvent(QCloseEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private: + ClientModel *clientModel; + WalletModel *walletModel; + + QStackedWidget *centralWidget; + + OverviewPage *overviewPage; + QWidget *transactionsPage; + AddressBookPage *addressBookPage; + AddressBookPage *receiveCoinsPage; + SendCoinsDialog *sendCoinsPage; + SignVerifyMessageDialog *signVerifyMessageDialog; + MiningPage *miningPage; + StatisticsPage *statisticsPage; + BlockBrowser *blockBrowser; + + QLabel *labelEncryptionIcon; + QLabel *labelMintingIcon; + QLabel *labelMiningIcon; + QLabel *labelConnectionsIcon; + QLabel *labelBlocksIcon; + QLabel *progressBarLabel; + QProgressBar *progressBar; + + QMenuBar *appMenuBar; + QAction *overviewAction; + QAction *historyAction; + QAction *quitAction; + QAction *sendCoinsAction; + QAction *addressBookAction; + QAction *signMessageAction; + QAction *verifyMessageAction; + QAction *aboutAction; + QAction *receiveCoinsAction; + QAction *optionsAction; + QAction *toggleHideAction; + QAction *exportAction; + QAction *encryptWalletAction; + QAction *backupWalletAction; + QAction *changePassphraseAction; + QAction *lockWalletToggleAction; + QAction *unlockWalletAction; + QAction *lockWalletAction; + QAction *aboutQtAction; + QAction *openRPCConsoleAction; + QAction *miningAction; + QAction *statisticsAction; + QAction *blockAction; + + QSystemTrayIcon *trayIcon; + Notificator *notificator; + TransactionView *transactionView; + RPCConsole *rpcConsole; + + QMovie *syncIconMovie; + + uint64 nMinMax; + uint64 nWeight; + uint64 nNetworkWeight; + + /** Create the main UI actions. */ + void createActions(); + /** Create the menu bar and sub-menus. */ + void createMenuBar(); + /** Create the toolbars */ + void createToolBars(); + /** Create system tray (notification) icon */ + void createTrayIcon(); + +public slots: + /** Set number of connections shown in the UI */ + void setNumConnections(int count); + /** Set number of blocks shown in the UI */ + void setNumBlocks(int count, int nTotalBlocks); + /** Set mining status in UI */ + void setMining(bool mining, int hashrate); + /** Set the encryption status as shown in the UI. + @param[in] status current encryption status + @see WalletModel::EncryptionStatus + */ + void setEncryptionStatus(int status); + + /** Notify the user of an error in the network or transaction handling code. */ + void error(const QString &title, const QString &message, bool modal); + /** Asks the user whether to pay the transaction fee or to cancel the transaction. + It is currently not possible to pass a return value to another thread through + BlockingQueuedConnection, so an indirected pointer is used. + https://bugreports.qt-project.org/browse/QTBUG-10440 + + @param[in] nFeeRequired the required fee + @param[out] payFee true to pay the fee, false to not pay the fee + */ + void askFee(qint64 nFeeRequired, bool *payFee); + void handleURI(QString strURI); + +private slots: + /** Switch to overview (home) page */ + void gotoOverviewPage(); + /** Switch to history (transactions) page */ + void gotoHistoryPage(); + /** Switch to address book page */ + void gotoAddressBookPage(); + /** Switch to receive coins page */ + void gotoReceiveCoinsPage(); + /** Switch to send coins page */ + void gotoSendCoinsPage(); + /** Switch to mining page*/ + void gotoMiningPage(); + /** Switch to statistics page*/ + void gotoStatisticsPage(); + /** Switch to block explorer*/ + void gotoBlockBrowser(); + + /** Show Sign/Verify Message dialog and switch to sign message tab */ + void gotoSignMessageTab(QString addr = ""); + /** Show Sign/Verify Message dialog and switch to verify message tab */ + void gotoVerifyMessageTab(QString addr = ""); + + /** Show configuration dialog */ + void optionsClicked(); + /** Show about dialog */ + void aboutClicked(); +#ifndef Q_OS_MAC + /** Handle tray icon clicked */ + void trayIconActivated(QSystemTrayIcon::ActivationReason reason); +#endif + /** Show incoming transaction notification for new transactions. + + The new items are those between start and end inclusive, under the given parent item. + */ + void incomingTransaction(const QModelIndex & parent, int start, int end); + /** Encrypt the wallet */ + void encryptWallet(bool status); + /** Backup the wallet */ + void backupWallet(); + /** Change encrypted wallet passphrase */ + void changePassphrase(); + /** Toggle unlocking wallet temporarily */ + void lockWalletToggle(); + void unlockWallet(); + void lockWallet(); + + /** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */ + void showNormalIfMinimized(bool fToggleHidden = false); + /** simply calls showNormalIfMinimized(true) for use in SLOT() macro */ + void toggleHidden(); + + /** Update info about minting */ + void updateMintingIcon(); + /** Update minting weight info */ + void updateMintingWeights(); +}; + +#endif diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp new file mode 100644 index 0000000..a05acb6 --- /dev/null +++ b/src/qt/bitcoinstrings.cpp @@ -0,0 +1,177 @@ +#include +// Automatically generated by extract_strings.py +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif +static const char UNUSED *bitcoin_strings[] = { +QT_TRANSLATE_NOOP("bitcoin-core", "" +"%s, you must set a rpcpassword in the configuration file:\n" +" %s\n" +"It is recommended you use the following random password:\n" +"rpcuser=bitcoinrpc\n" +"rpcpassword=%s\n" +"(you do not need to remember this password)\n" +"If the file does not exist, create it with owner-readable-only file " +"permissions.\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:" +"@STRENGTH)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"An error occurred while setting up the RPC port %u for listening on IPv4: %s"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"An error occurred while setting up the RPC port %u for listening on IPv6, " +"falling back to IPv4: %s"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Cannot obtain a lock on data directory %s. BERN is probably already " +"running."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Detach block and address databases. Increases shutdown time (default: 0)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Error initializing database environment %s! To recover, BACKUP THAT " +"DIRECTORY, then remove everything from it except for wallet.dat."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Error: The transaction was rejected. This might happen if some of the coins " +"in your wallet were already spent, such as if you used a copy of wallet.dat " +"and coins were spent in the copy but not marked as spent here."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Error: This transaction requires a transaction fee of at least %s because of " +"its amount, complexity, or use of recently received funds "), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Error: Wallet unlocked for block staking only, unable to create transaction."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Execute command when the best block changes (%s in cmd is replaced by block " +"hash)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Listen for JSON-RPC connections on (default: 8344 or testnet: 18344)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Number of seconds to keep misbehaving peers from reconnecting (default: " +"86400)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Set maximum size of high-priority/low-fee transactions in bytes (default: " +"27000)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Unable to bind to %s on this computer. BERN is probably already running."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Warning: -paytxfee is set very high! This is the transaction fee you will " +"pay if you send a transaction."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Warning: Please check that your computer's date and time are correct! If " +"your clock is wrong BERN will not work properly."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Warning: error reading wallet.dat! All keys read correctly, but transaction " +"data or address book entries might be missing or incorrect."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as " +"wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect " +"you should restore from a backup."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"You must set rpcpassword= in the configuration file:\n" +"%s\n" +"If the file does not exist, create it with owner-readable-only file " +"permissions."), +QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"), +QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"), +QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"), +QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address"), +QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"), +QT_TRANSLATE_NOOP("bitcoin-core", "Bind to given address. Use [host]:port notation for IPv6"), +QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"), +QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"), +QT_TRANSLATE_NOOP("bitcoin-core", "Cannot initialize keypool"), +QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"), +QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks proxy"), +QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"), +QT_TRANSLATE_NOOP("bitcoin-core", "Discover own IP address (default: 1 when listening and no -externalip)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins"), +QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading blkindex.dat"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of BERN"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: Transaction creation failed "), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction "), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: could not start node"), +QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."), +QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send"), +QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using DNS lookup (default: 0)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using internet relay chat (default: 1)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins"), +QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command"), +QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 2500, 0 = all)"), +QT_TRANSLATE_NOOP("bitcoin-core", "How thorough the block verification is (0-6, default: 1)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Importing blockchain data file."), +QT_TRANSLATE_NOOP("bitcoin-core", "Importing bootstrap blockchain data file."), +QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000?.dat file"), +QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -tor address: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -reservebalance="), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"), +QT_TRANSLATE_NOOP("bitcoin-core", "List commands"), +QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on (default: 12788 or testnet: 22788)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most connections to peers (default: 125)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, *1000 bytes (default: 5000)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, *1000 bytes (default: 1000)"), +QT_TRANSLATE_NOOP("bitcoin-core", "BERN version"), +QT_TRANSLATE_NOOP("bitcoin-core", "BERN"), +QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network (IPv4, IPv6 or Tor)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Options:"), +QT_TRANSLATE_NOOP("bitcoin-core", "Output extra debugging information. Implies all other -debug* options"), +QT_TRANSLATE_NOOP("bitcoin-core", "Output extra network debugging information"), +QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"), +QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp"), +QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"), +QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"), +QT_TRANSLATE_NOOP("bitcoin-core", "SSL options: (see the Bitcoin Wiki for SSL setup instructions)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Select the version of socks proxy to use (4-5, default: 5)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or BERNd"), +QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on (default: 127.0.0.1)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"), +QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to debugger"), +QT_TRANSLATE_NOOP("bitcoin-core", "Sending..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (default: 25)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set database disk log size in megabytes (default: 100)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to (default: 100)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: 250000)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: 0)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: BERN.conf)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout in milliseconds (default: 5000)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: BERNd.pid)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"), +QT_TRANSLATE_NOOP("bitcoin-core", "This help message"), +QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: 100)"), +QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"), +QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %d, %s)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Unable to sign checkpoint, wrong checkpointkey?\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Unknown -socks proxy version requested: %i"), +QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"), +QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"), +QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"), +QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 0)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 1 when listening)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Use proxy to reach tor hidden services (default: same as -proxy)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"), +QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"), +QT_TRANSLATE_NOOP("bitcoin-core", "Verifying database integrity..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart BERN to complete"), +QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low!"), +QT_TRANSLATE_NOOP("bitcoin-core", "Warning: This version is obsolete, upgrade required!"), +QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"), +}; diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp new file mode 100644 index 0000000..4432f01 --- /dev/null +++ b/src/qt/bitcoinunits.cpp @@ -0,0 +1,181 @@ +#include "bitcoinunits.h" + +#include + +BitcoinUnits::BitcoinUnits(QObject *parent): + QAbstractListModel(parent), + unitlist(availableUnits()) +{ +} + +QList BitcoinUnits::availableUnits() +{ + QList unitlist; + unitlist.append(BTC); + unitlist.append(mBTC); + unitlist.append(uBTC); + return unitlist; +} + +bool BitcoinUnits::valid(int unit) +{ + switch(unit) + { + case BTC: + case mBTC: + case uBTC: + return true; + default: + return false; + } +} + +QString BitcoinUnits::name(int unit) +{ + switch(unit) + { + case BTC: return QString("BERN"); + case mBTC: return QString("mBERN"); + case uBTC: return QString::fromUtf8("μBERN"); + default: return QString("???"); + } +} + +QString BitcoinUnits::description(int unit) +{ + switch(unit) + { + case BTC: return QString("BERN"); + case mBTC: return QString("Milli-BERN (1 / 1,000)"); + case uBTC: return QString("Micro-BERN (1 / 1,000,000)"); + default: return QString("???"); + } +} + +qint64 BitcoinUnits::factor(int unit) +{ + switch(unit) + { + case BTC: return 1000000; + case mBTC: return 1000; + case uBTC: return 1; + default: return 1000000; + } +} + +int BitcoinUnits::amountDigits(int unit) +{ + switch(unit) + { + case BTC: return 8; // 21,000,000 (# digits, without commas) + case mBTC: return 11; // 21,000,000,000 + case uBTC: return 14; // 21,000,000,000,000 + default: return 0; + } +} + +int BitcoinUnits::decimals(int unit) +{ + switch(unit) + { + case BTC: return 6; + case mBTC: return 3; + case uBTC: return 0; + default: return 0; + } +} + +QString BitcoinUnits::format(int unit, qint64 n, bool fPlus) +{ + // Note: not using straight sprintf here because we do NOT want + // localized number formatting. + if(!valid(unit)) + return QString(); // Refuse to format invalid unit + qint64 coin = factor(unit); + int num_decimals = decimals(unit); + qint64 n_abs = (n > 0 ? n : -n); + qint64 quotient = n_abs / coin; + qint64 remainder = n_abs % coin; + QString quotient_str = QString::number(quotient); + QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0'); + + // Right-trim excess zeros after the decimal point + int nTrim = 0; + for (int i = remainder_str.size()-1; i>=2 && (remainder_str.at(i) == '0'); --i) + ++nTrim; + remainder_str.chop(nTrim); + + if (n < 0) + quotient_str.insert(0, '-'); + else if (fPlus && n > 0) + quotient_str.insert(0, '+'); + return quotient_str + QString(".") + remainder_str; +} + +QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign) +{ + return format(unit, amount, plussign) + QString(" ") + name(unit); +} + +bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out) +{ + if(!valid(unit) || value.isEmpty()) + return false; // Refuse to parse invalid unit or empty string + int num_decimals = decimals(unit); + QStringList parts = value.split("."); + + if(parts.size() > 2) + { + return false; // More than one dot + } + QString whole = parts[0]; + QString decimals; + + if(parts.size() > 1) + { + decimals = parts[1]; + } + if(decimals.size() > num_decimals) + { + return false; // Exceeds max precision + } + bool ok = false; + QString str = whole + decimals.leftJustified(num_decimals, '0'); + + if(str.size() > 18) + { + return false; // Longer numbers will exceed 63 bits + } + qint64 retvalue = str.toLongLong(&ok); + if(val_out) + { + *val_out = retvalue; + } + return ok; +} + +int BitcoinUnits::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return unitlist.size(); +} + +QVariant BitcoinUnits::data(const QModelIndex &index, int role) const +{ + int row = index.row(); + if(row >= 0 && row < unitlist.size()) + { + Unit unit = unitlist.at(row); + switch(role) + { + case Qt::EditRole: + case Qt::DisplayRole: + return QVariant(name(unit)); + case Qt::ToolTipRole: + return QVariant(description(unit)); + case UnitRole: + return QVariant(static_cast(unit)); + } + } + return QVariant(); +} diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h new file mode 100644 index 0000000..9b7c9e1 --- /dev/null +++ b/src/qt/bitcoinunits.h @@ -0,0 +1,66 @@ +#ifndef BITCOINUNITS_H +#define BITCOINUNITS_H + +#include +#include + +/** Bitcoin unit definitions. Encapsulates parsing and formatting + and serves as list model for drop-down selection boxes. +*/ +class BitcoinUnits: public QAbstractListModel +{ +public: + explicit BitcoinUnits(QObject *parent); + + /** Bitcoin units. + @note Source: https://en.bitcoin.it/wiki/Units . Please add only sensible ones + */ + enum Unit + { + BTC, + mBTC, + uBTC + }; + + //! @name Static API + //! Unit conversion and formatting + ///@{ + + //! Get list of units, for drop-down box + static QList availableUnits(); + //! Is unit ID valid? + static bool valid(int unit); + //! Short name + static QString name(int unit); + //! Longer description + static QString description(int unit); + //! Number of Satoshis (1e-8) per unit + static qint64 factor(int unit); + //! Number of amount digits (to represent max number of coins) + static int amountDigits(int unit); + //! Number of decimals left + static int decimals(int unit); + //! Format as string + static QString format(int unit, qint64 amount, bool plussign=false); + //! Format as string (with unit) + static QString formatWithUnit(int unit, qint64 amount, bool plussign=false); + //! Parse string to coin amount + static bool parse(int unit, const QString &value, qint64 *val_out); + ///@} + + //! @name AbstractListModel implementation + //! List model for unit drop-down selection box. + ///@{ + enum RoleIndex { + /** Unit identifier */ + UnitRole = Qt::UserRole + }; + int rowCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + ///@} +private: + QList unitlist; +}; +typedef BitcoinUnits::Unit BitcoinUnit; + +#endif // BITCOINUNITS_H diff --git a/src/qt/blockbrowser.cpp b/src/qt/blockbrowser.cpp new file mode 100644 index 0000000..0a56ff9 --- /dev/null +++ b/src/qt/blockbrowser.cpp @@ -0,0 +1,440 @@ +#include "blockbrowser.h" +#include "ui_blockbrowser.h" +#include "main.h" +#include "wallet.h" +#include "base58.h" +#include "clientmodel.h" +#include "bitcoinrpc.h" +#include "transactionrecord.h" + +#include +#include +double getBlockHardness(int height) +{ + const CBlockIndex* blockindex = getBlockIndex(height); + + int nShift = (blockindex->nBits >> 24) & 0xff; + + double dDiff = + (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff); + + while (nShift < 29) + { + dDiff *= 256.0; + nShift++; + } + while (nShift > 29) + { + dDiff /= 256.0; + nShift--; + } + + return dDiff; +} + +int getBlockHashrate(int height) +{ + int lookup = height; + + double timeDiff = getBlockTime(height) - getBlockTime(1); + double timePerBlock = timeDiff / lookup; + + return (boost::int64_t)(((double)getBlockHardness(height) * pow(2.0, 32)) / timePerBlock); +} + +const CBlockIndex* getBlockIndex(int height) +{ + std::string hex = getBlockHash(height); + uint256 hash(hex); + return mapBlockIndex[hash]; +} + +std::string getBlockHash(int Height) +{ + if(Height > pindexBest->nHeight) { return "351c6703813172725c6d660aa539ee6a3d7a9fe784c87fae7f36582e3b797058"; } + if(Height < 0) { return "351c6703813172725c6d660aa539ee6a3d7a9fe784c87fae7f36582e3b797058"; } + int desiredheight; + desiredheight = Height; + if (desiredheight < 0 || desiredheight > nBestHeight) + return 0; + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hashBestChain]; + while (pblockindex->nHeight > desiredheight) + pblockindex = pblockindex->pprev; + return pblockindex->phashBlock->GetHex(); +} + +int getBlockTime(int Height) +{ + std::string strHash = getBlockHash(Height); + uint256 hash(strHash); + + if (mapBlockIndex.count(hash) == 0) + return 0; + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + return pblockindex->nTime; +} + +std::string getBlockMerkle(int Height) +{ + std::string strHash = getBlockHash(Height); + uint256 hash(strHash); + + if (mapBlockIndex.count(hash) == 0) + return 0; + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + return pblockindex->hashMerkleRoot.ToString().substr(0,10).c_str(); +} + +int getBlocknBits(int Height) +{ + std::string strHash = getBlockHash(Height); + uint256 hash(strHash); + + if (mapBlockIndex.count(hash) == 0) + return 0; + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + return pblockindex->nBits; +} + +int getBlockNonce(int Height) +{ + std::string strHash = getBlockHash(Height); + uint256 hash(strHash); + + if (mapBlockIndex.count(hash) == 0) + return 0; + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + return pblockindex->nNonce; +} + +std::string getBlockDebug(int Height) +{ + std::string strHash = getBlockHash(Height); + uint256 hash(strHash); + + if (mapBlockIndex.count(hash) == 0) + return 0; + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + return pblockindex->ToString(); +} + +int blocksInPastHours(int hours) +{ + int wayback = hours * 3600; + bool check = true; + int height = pindexBest->nHeight; + int heightHour = pindexBest->nHeight; + int utime = (int)time(NULL); + int target = utime - wayback; + + while(check) + { + if(getBlockTime(heightHour) < target) + { + check = false; + return height - heightHour; + } else { + heightHour = heightHour - 1; + } + } + + return 0; +} + +double getTxTotalValue(std::string txid) +{ + uint256 hash; + hash.SetHex(txid); + + CTransaction tx; + uint256 hashBlock = 0; + if (!GetTransaction(hash, tx, hashBlock)) + { + return -1; + } + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + + double value = 0; + double buffer = 0; + for (unsigned int i = 0; i < tx.vout.size(); i++) + { + const CTxOut& txout = tx.vout[i]; + + buffer = value + convertCoins(txout.nValue); + value = buffer; + } + + return value; +} + +double convertCoins(int64_t amount) +{ + return (double)amount / (double)COIN; +} + +std::string getOutputs(std::string txid) +{ + uint256 hash; + hash.SetHex(txid); + + CTransaction tx; + uint256 hashBlock = 0; + if (!GetTransaction(hash, tx, hashBlock)) + return "fail"; + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + + std::string str = ""; + for (unsigned int i = 0; i < tx.vout.size(); i++) + { + const CTxOut& txout = tx.vout[i]; + CTxDestination source; + ExtractDestination(txout.scriptPubKey, source); + CBitcoinAddress addressSource(source); + std::string lol7 = addressSource.ToString(); + double buffer = convertCoins(txout.nValue); + std::string amount = boost::to_string(buffer); + str.append(lol7); + str.append(": "); + str.append(amount); + str.append(" BERN"); + str.append("\n"); + } + + return str; +} + +std::string getInputs(std::string txid) +{ + uint256 hash; + hash.SetHex(txid); + + CTransaction tx; + uint256 hashBlock = 0; + if (!GetTransaction(hash, tx, hashBlock)) + return "fail"; + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + + std::string str = ""; + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + uint256 hash; + const CTxIn& vin = tx.vin[i]; + hash.SetHex(vin.prevout.hash.ToString()); + CTransaction wtxPrev; + uint256 hashBlock = 0; + if (!GetTransaction(hash, wtxPrev, hashBlock)) + return "fail"; + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << wtxPrev; + + CTxDestination source; + ExtractDestination(wtxPrev.vout[vin.prevout.n].scriptPubKey, source); + CBitcoinAddress addressSource(source); + std::string lol6 = addressSource.ToString(); + const CScript target = wtxPrev.vout[vin.prevout.n].scriptPubKey; + double buffer = convertCoins(getInputValue(wtxPrev, target)); + std::string amount = boost::to_string(buffer); + str.append(lol6); + str.append(": "); + str.append(amount); + str.append(" BERN"); + str.append("\n"); + } + + return str; +} + +int64_t getInputValue(CTransaction tx, CScript target) +{ + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + const CTxOut& txout = tx.vout[i]; + if(txout.scriptPubKey == target) + { + return txout.nValue; + } + } + return 0; +} + +double getTxFees(std::string txid) +{ + uint256 hash; + hash.SetHex(txid); + + + CTransaction tx; + uint256 hashBlock = 0; + if (!GetTransaction(hash, tx, hashBlock)) + return 0; + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + + double value = 0; + double buffer = 0; + for (unsigned int i = 0; i < tx.vout.size(); i++) + { + const CTxOut& txout = tx.vout[i]; + + buffer = value + convertCoins(txout.nValue); + value = buffer; + } + + double value0 = 0; + double buffer0 = 0; + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + uint256 hash0; + const CTxIn& vin = tx.vin[i]; + hash0.SetHex(vin.prevout.hash.ToString()); + CTransaction wtxPrev; + uint256 hashBlock0 = 0; + if (!GetTransaction(hash0, wtxPrev, hashBlock0)) + return 0; + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << wtxPrev; + const CScript target = wtxPrev.vout[vin.prevout.n].scriptPubKey; + buffer0 = value0 + convertCoins(getInputValue(wtxPrev, target)); + value0 = buffer0; + } + + return value0 - value; +} + + +BlockBrowser::BlockBrowser(QWidget *parent) : + QWidget(parent), + ui(new Ui::BlockBrowser) +{ + ui->setupUi(this); + + setFixedSize(400, 420); + + connect(ui->blockButton, SIGNAL(pressed()), this, SLOT(blockClicked())); + connect(ui->txButton, SIGNAL(pressed()), this, SLOT(txClicked())); +} + +void BlockBrowser::updateExplorer(bool block) +{ + if(block) + { + ui->heightLabel->show(); + ui->heightLabel_2->show(); + ui->hashLabel->show(); + ui->hashBox->show(); + ui->merkleLabel->show(); + ui->merkleBox->show(); + ui->nonceLabel->show(); + ui->nonceBox->show(); + ui->bitsLabel->show(); + ui->bitsBox->show(); + ui->timeLabel->show(); + ui->timeBox->show(); + ui->hardLabel->show(); + ui->hardBox->show();; + ui->pawLabel->show(); + ui->pawBox->show(); + int height = ui->heightBox->value(); + if (height > pindexBest->nHeight) + { + ui->heightBox->setValue(pindexBest->nHeight); + height = pindexBest->nHeight; + } + int Pawrate = getBlockHashrate(height); + double Pawrate2 = 0.000; + Pawrate2 = ((double)Pawrate / 1000); + std::string hash = getBlockHash(height); + std::string merkle = getBlockMerkle(height); + int nBits = getBlocknBits(height); + int nNonce = getBlockNonce(height); + int atime = getBlockTime(height); + double hardness = getBlockHardness(height); + QString QHeight = QString::number(height); + QString QHash = QString::fromUtf8(hash.c_str()); + QString QMerkle = QString::fromUtf8(merkle.c_str()); + QString QBits = QString::number(nBits); + QString QNonce = QString::number(nNonce); + QString QTime = QString::number(atime); + QString QHardness = QString::number(hardness, 'f', 6); + QString QPawrate = QString::number(Pawrate2, 'f', 3); + ui->heightLabel->setText(QHeight); + ui->hashBox->setText(QHash); + ui->txBox->setText(QHash); + ui->merkleBox->setText(QMerkle); + ui->bitsBox->setText(QBits); + ui->nonceBox->setText(QNonce); + ui->timeBox->setText(QTime); + ui->hardBox->setText(QHardness); + ui->pawBox->setText(QPawrate + " Hash/sec"); + } + + if(block == false) { + ui->txID->show(); + ui->txLabel->show(); + ui->valueLabel->show(); + ui->valueBox->show(); + ui->inputLabel->show(); + ui->inputBox->show(); + ui->outputLabel->show(); + ui->outputBox->show(); + ui->feesLabel->show(); + ui->feesBox->show(); + std::string txid = ui->txBox->text().toUtf8().constData(); + double value = getTxTotalValue(txid); + double fees = getTxFees(txid); + std::string outputs = getOutputs(txid); + std::string inputs = getInputs(txid); + QString QValue; + if (value==-1) QValue = "Reward"; + else QValue = QString::number(value, 'f', 6); + QString QID = QString::fromUtf8(txid.c_str()); + QString QOutputs = QString::fromUtf8(outputs.c_str()); + QString QInputs = QString::fromUtf8(inputs.c_str()); + QString QFees = QString::number(fees, 'f', 6); + ui->valueBox->setText(QValue + " BERN"); + ui->txID->setText(QID); + ui->outputBox->setText(QOutputs); + ui->inputBox->setText(QInputs); + ui->feesBox->setText(QFees + " BERN"); + } +} + + +void BlockBrowser::txClicked() +{ + updateExplorer(false); +} + +void BlockBrowser::blockClicked() +{ + updateExplorer(true); +} + +void BlockBrowser::setModel(ClientModel *model) +{ + this->model = model; +} + +BlockBrowser::~BlockBrowser() +{ + delete ui; +} diff --git a/src/qt/blockbrowser.h b/src/qt/blockbrowser.h new file mode 100644 index 0000000..a2bf853 --- /dev/null +++ b/src/qt/blockbrowser.h @@ -0,0 +1,67 @@ +#ifndef BLOCKBROWSER_H +#define BLOCKBROWSER_H + +#include "clientmodel.h" +#include "main.h" +#include "wallet.h" +#include "base58.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +double getBlockHardness(int); +double getTxTotalValue(std::string); +double convertCoins(int64_t); +double getTxFees(std::string); +int getBlockTime(int); +int getBlocknBits(int); +int getBlockNonce(int); +int blocksInPastHours(int); +int getBlockHashrate(int); +std::string getInputs(std::string); +std::string getOutputs(std::string); +std::string getBlockHash(int); +std::string getBlockMerkle(int); +bool addnode(std::string); +const CBlockIndex* getBlockIndex(int); +int64_t getInputValue(CTransaction, CScript); + + +namespace Ui { +class BlockBrowser; +} +class ClientModel; + +class BlockBrowser : public QWidget +{ + Q_OBJECT + +public: + explicit BlockBrowser(QWidget *parent = 0); + ~BlockBrowser(); + + void setModel(ClientModel *model); + +public slots: + + void blockClicked(); + void txClicked(); + void updateExplorer(bool); + +private slots: + +private: + Ui::BlockBrowser *ui; + ClientModel *model; + +}; + +#endif // BLOCKBROWSER_H diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp new file mode 100644 index 0000000..c30e159 --- /dev/null +++ b/src/qt/clientmodel.cpp @@ -0,0 +1,308 @@ +#include "clientmodel.h" +#include "guiconstants.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" +#include "transactiontablemodel.h" + +#include "alert.h" +#include "main.h" +#include "init.h" // pwalletMain +#include "ui_interface.h" + +#include +#include + +static const int64 nClientStartupTime = GetTime(); + +ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : + QObject(parent), optionsModel(optionsModel), + cachedNumBlocks(0), cachedNumBlocksOfPeers(0), pollTimer(0) +{ + numBlocksAtStartup = -1; + + pollTimer = new QTimer(this); + pollTimer->setInterval(MODEL_UPDATE_DELAY); + pollTimer->start(); + connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); + + subscribeToCoreSignals(); +} + +ClientModel::~ClientModel() +{ + unsubscribeFromCoreSignals(); +} + +int ClientModel::getNumConnections() const +{ + return vNodes.size(); +} + +int ClientModel::getNumBlocks() const +{ + return nBestHeight; +} + +int ClientModel::getNumBlocksAtStartup() +{ + if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks(); + return numBlocksAtStartup; +} + +QDateTime ClientModel::getLastBlockDate() const +{ + return QDateTime::fromTime_t(pindexBest->GetBlockTime()); +} + +void ClientModel::updateTimer() +{ + // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change. + // Periodically check and update with a timer. + int newNumBlocks = getNumBlocks(); + int newNumBlocksOfPeers = getNumBlocksOfPeers(); + + if(cachedNumBlocks != newNumBlocks || cachedNumBlocksOfPeers != newNumBlocksOfPeers) + { + cachedNumBlocks = newNumBlocks; + cachedNumBlocksOfPeers = newNumBlocksOfPeers; + + emit numBlocksChanged(newNumBlocks, newNumBlocksOfPeers); + } +} + +void ClientModel::updateNumConnections(int numConnections) +{ + emit numConnectionsChanged(numConnections); +} + +void ClientModel::updateAlert(const QString &hash, int status) +{ + // Show error message notification for new alert + if(status == CT_NEW) + { + uint256 hash_256; + hash_256.SetHex(hash.toStdString()); + CAlert alert = CAlert::getAlertByHash(hash_256); + if(!alert.IsNull()) + { + emit error(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), false); + } + } + + // Emit a numBlocksChanged when the status message changes, + // so that the view recomputes and updates the status bar. + emit numBlocksChanged(getNumBlocks(), getNumBlocksOfPeers()); +} + +ClientModel::MiningType ClientModel::getMiningType() const +{ + return miningType; +} + +int ClientModel::getMiningThreads() const +{ + return miningThreads; +} + +bool ClientModel::getMiningStarted() const +{ + return miningStarted; +} + +bool ClientModel::getMiningDebug() const +{ + return miningDebug; +} + +void ClientModel::setMiningDebug(bool debug) +{ + miningDebug = debug; +// WriteSetting("miningDebug", miningDebug); +} + +int ClientModel::getMiningScanTime() const +{ + return miningScanTime; +} + +void ClientModel::setMiningScanTime(int scantime) +{ + miningScanTime = scantime; +// WriteSetting("miningScanTime", miningScanTime); +} + +QString ClientModel::getMiningServer() const +{ + return miningServer; +} + +void ClientModel::setMiningServer(QString server) +{ + miningServer = server; +// WriteSetting("miningServer", miningServer.toStdString()); +} + +QString ClientModel::getMiningPort() const +{ + return miningPort; +} + +void ClientModel::setMiningPort(QString port) +{ + miningPort = port; +// WriteSetting("miningPort", miningPort.toStdString()); +} + +QString ClientModel::getMiningUsername() const +{ + return miningUsername; +} + +void ClientModel::setMiningUsername(QString username) +{ + miningUsername = username; +// WriteSetting("miningUsername", miningUsername.toStdString()); +} + +QString ClientModel::getMiningPassword() const +{ + return miningPassword; +} + +void ClientModel::setMiningPassword(QString password) +{ + miningPassword = password; +// WriteSetting("miningPassword", miningPassword.toStdString()); +} + +int ClientModel::getHashrate() const +{ + if (GetTimeMillis() - nHPSTimerStart > 8000) + return (boost::int64_t)0; + return (boost::int64_t)dHashesPerSec; +} + + +double ClientModel::GetDifficulty() const +{ + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + + if (pindexBest == NULL) + return 1.0; + int nShift = (pindexBest->nBits >> 24) & 0xff; + + double dDiff = + (double)0x0000ffff / (double)(pindexBest->nBits & 0x00ffffff); + + while (nShift < 29) + { + dDiff *= 256.0; + nShift++; + } + while (nShift > 29) + { + dDiff /= 256.0; + nShift--; + } + + return dDiff; +} + + +bool ClientModel::isTestNet() const +{ + return fTestNet; +} + +bool ClientModel::inInitialBlockDownload() const +{ + return IsInitialBlockDownload(); +} + +int ClientModel::getNumBlocksOfPeers() const +{ + return GetNumBlocksOfPeers(); +} + +void ClientModel::setMining(MiningType type, bool mining, int threads, int hashrate) +{ + if (type == SoloMining && mining != miningStarted) + { + GenerateBitcoins(mining ? 1 : 0, pwalletMain); + } + miningType = type; + miningStarted = mining; +// WriteSetting("miningStarted", mining); +// WriteSetting("fLimitProcessors", 1); +// WriteSetting("nLimitProcessors", threads); + emit miningChanged(mining, hashrate); +} + +QString ClientModel::getStatusBarWarnings() const +{ + return QString::fromStdString(GetWarnings("statusbar")); +} + +OptionsModel *ClientModel::getOptionsModel() +{ + return optionsModel; +} + +QString ClientModel::formatFullVersion() const +{ + return QString::fromStdString(FormatFullVersion()); +} + +QString ClientModel::formatBuildDate() const +{ + return QString::fromStdString(CLIENT_DATE); +} + +QString ClientModel::clientName() const +{ + return QString::fromStdString(CLIENT_NAME); +} + +QString ClientModel::formatClientStartupTime() const +{ + return QDateTime::fromTime_t(nClientStartupTime).toString(); +} + +// Handlers for core signals +static void NotifyBlocksChanged(ClientModel *clientmodel) +{ + // This notification is too frequent. Don't trigger a signal. + // Don't remove it, though, as it might be useful later. +} + +static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections) +{ + // Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections); + QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection, + Q_ARG(int, newNumConnections)); +} + +static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status) +{ + OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status); + QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(hash.GetHex())), + Q_ARG(int, status)); +} + +void ClientModel::subscribeToCoreSignals() +{ + // Connect signals to client + uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this)); + uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); + uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); +} + +void ClientModel::unsubscribeFromCoreSignals() +{ + // Disconnect signals from client + uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this)); + uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); + uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); +} diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h new file mode 100644 index 0000000..5f4b732 --- /dev/null +++ b/src/qt/clientmodel.h @@ -0,0 +1,115 @@ +#ifndef CLIENTMODEL_H +#define CLIENTMODEL_H + +#include + +class OptionsModel; +class AddressTableModel; +class TransactionTableModel; +class CWallet; + +QT_BEGIN_NAMESPACE +class QDateTime; +class QTimer; +QT_END_NAMESPACE + +/** Model for Bitcoin network client. */ +class ClientModel : public QObject +{ + Q_OBJECT +public: + explicit ClientModel(OptionsModel *optionsModel, QObject *parent = 0); + ~ClientModel(); + + enum MiningType + { + EasyMining, + SoloMining, + PoolMining + }; + + OptionsModel *getOptionsModel(); + + int getNumConnections() const; + int getNumBlocks() const; + int getNumBlocksAtStartup(); + + MiningType getMiningType() const; + int getMiningThreads() const; + bool getMiningStarted() const; + + bool getMiningDebug() const; + void setMiningDebug(bool debug); + int getMiningScanTime() const; + void setMiningScanTime(int scantime); + QString getMiningServer() const; + void setMiningServer(QString server); + QString getMiningPort() const; + void setMiningPort(QString port); + QString getMiningUsername() const; + void setMiningUsername(QString username); + QString getMiningPassword() const; + void setMiningPassword(QString password); + + int getHashrate() const; + double GetDifficulty() const; + int getMaxHeightAccepted() const; + void setMaxHeightAccepted(int blockheight) const; + + QDateTime getLastBlockDate() const; + + //! Return true if client connected to testnet + bool isTestNet() const; + //! Return true if core is doing initial block download + bool inInitialBlockDownload() const; + //! Return conservative estimate of total number of blocks, or 0 if unknown + int getNumBlocksOfPeers() const; + //! Return warnings to be displayed in status bar + QString getStatusBarWarnings() const; + +void setMining(MiningType type, bool mining, int threads, int hashrate); + + QString formatFullVersion() const; + QString formatBuildDate() const; + QString clientName() const; + QString formatClientStartupTime() const; + +private: + OptionsModel *optionsModel; + + int cachedNumBlocks; + int cachedNumBlocksOfPeers; + + int cachedHashrate; + MiningType miningType; + int miningThreads; + bool miningStarted; + bool miningDebug; + int miningScanTime; + QString miningServer; + QString miningPort; + QString miningUsername; + QString miningPassword; + + int numBlocksAtStartup; + + QTimer *pollTimer; + + void subscribeToCoreSignals(); + void unsubscribeFromCoreSignals(); +signals: + void numConnectionsChanged(int count); + void numBlocksChanged(int count, int countOfPeers); + + void miningChanged(bool mining, int count); + + //! Asynchronous error notification + void error(const QString &title, const QString &message, bool modal); + +public slots: + void updateTimer(); + void updateNumConnections(int numConnections); + void updateAlert(const QString &hash, int status); +}; + +#endif // CLIENTMODEL_H diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp new file mode 100644 index 0000000..2df3c64 --- /dev/null +++ b/src/qt/coincontroldialog.cpp @@ -0,0 +1,738 @@ +#include "coincontroldialog.h" +#include "ui_coincontroldialog.h" + +#include "init.h" +#include "bitcoinunits.h" +#include "walletmodel.h" +#include "addresstablemodel.h" +#include "optionsmodel.h" +#include "coincontrol.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +QList CoinControlDialog::payAmounts; +CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); + +CoinControlDialog::CoinControlDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CoinControlDialog), + model(0) +{ + ui->setupUi(this); + + // context menu actions + QAction *copyAddressAction = new QAction(tr("Copy address"), this); + QAction *copyLabelAction = new QAction(tr("Copy label"), this); + QAction *copyAmountAction = new QAction(tr("Copy amount"), this); + copyTransactionHashAction = new QAction(tr("Copy transaction ID"), this); // we need to enable/disable this + //lockAction = new QAction(tr("Lock unspent"), this); // we need to enable/disable this + //unlockAction = new QAction(tr("Unlock unspent"), this); // we need to enable/disable this + + // context menu + contextMenu = new QMenu(); + contextMenu->addAction(copyAddressAction); + contextMenu->addAction(copyLabelAction); + contextMenu->addAction(copyAmountAction); + contextMenu->addAction(copyTransactionHashAction); + //contextMenu->addSeparator(); + //contextMenu->addAction(lockAction); + //contextMenu->addAction(unlockAction); + + // context menu signals + connect(ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint))); + connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); + connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); + connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); + connect(copyTransactionHashAction, SIGNAL(triggered()), this, SLOT(copyTransactionHash())); + //connect(lockAction, SIGNAL(triggered()), this, SLOT(lockCoin())); + //connect(unlockAction, SIGNAL(triggered()), this, SLOT(unlockCoin())); + + // clipboard actions + QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this); + QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this); + QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this); + QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this); + QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this); + QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this); + QAction *clipboardLowOutputAction = new QAction(tr("Copy low output"), this); + QAction *clipboardChangeAction = new QAction(tr("Copy change"), this); + + connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(clipboardQuantity())); + connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(clipboardAmount())); + connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(clipboardFee())); + connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(clipboardAfterFee())); + connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(clipboardBytes())); + connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(clipboardPriority())); + connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(clipboardLowOutput())); + connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(clipboardChange())); + + ui->labelCoinControlQuantity->addAction(clipboardQuantityAction); + ui->labelCoinControlAmount->addAction(clipboardAmountAction); + ui->labelCoinControlFee->addAction(clipboardFeeAction); + ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction); + ui->labelCoinControlBytes->addAction(clipboardBytesAction); + ui->labelCoinControlPriority->addAction(clipboardPriorityAction); + ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction); + ui->labelCoinControlChange->addAction(clipboardChangeAction); + + // toggle tree/list mode + connect(ui->radioTreeMode, SIGNAL(toggled(bool)), this, SLOT(radioTreeMode(bool))); + connect(ui->radioListMode, SIGNAL(toggled(bool)), this, SLOT(radioListMode(bool))); + + // click on checkbox + connect(ui->treeWidget, SIGNAL(itemChanged( QTreeWidgetItem*, int)), this, SLOT(viewItemChanged( QTreeWidgetItem*, int))); + + // click on header + ui->treeWidget->header()->setClickable(true); + connect(ui->treeWidget->header(), SIGNAL(sectionClicked(int)), this, SLOT(headerSectionClicked(int))); + + // ok button + connect(ui->buttonBox, SIGNAL(clicked( QAbstractButton*)), this, SLOT(buttonBoxClicked(QAbstractButton*))); + + // (un)select all + connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked())); + + ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84); + ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 100); + ui->treeWidget->setColumnWidth(COLUMN_LABEL, 170); + ui->treeWidget->setColumnWidth(COLUMN_ADDRESS, 290); + ui->treeWidget->setColumnWidth(COLUMN_DATE, 110); + ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 100); + ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100); + ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transacton hash in this column, but dont show it + ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but dont show it + ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but dont show it + ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but dont show it + + // default view is sorted by amount desc + sortView(COLUMN_AMOUNT_INT64, Qt::DescendingOrder); +} + +CoinControlDialog::~CoinControlDialog() +{ + delete ui; +} + +void CoinControlDialog::setModel(WalletModel *model) +{ + this->model = model; + + if(model && model->getOptionsModel() && model->getAddressTableModel()) + { + updateView(); + //updateLabelLocked(); + CoinControlDialog::updateLabels(model, this); + } +} + +// helper function str_pad +QString CoinControlDialog::strPad(QString s, int nPadLength, QString sPadding) +{ + while (s.length() < nPadLength) + s = sPadding + s; + + return s; +} + +// ok button +void CoinControlDialog::buttonBoxClicked(QAbstractButton* button) +{ + if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) + done(QDialog::Accepted); // closes the dialog +} + +// (un)select all +void CoinControlDialog::buttonSelectAllClicked() +{ + Qt::CheckState state = Qt::Checked; + for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) + { + if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != Qt::Unchecked) + { + state = Qt::Unchecked; + break; + } + } + ui->treeWidget->setEnabled(false); + for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) + if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != state) + ui->treeWidget->topLevelItem(i)->setCheckState(COLUMN_CHECKBOX, state); + ui->treeWidget->setEnabled(true); + CoinControlDialog::updateLabels(model, this); +} + +// context menu +void CoinControlDialog::showMenu(const QPoint &point) +{ + QTreeWidgetItem *item = ui->treeWidget->itemAt(point); + if(item) + { + contextMenuItem = item; + + // disable some items (like Copy Transaction ID, lock, unlock) for tree roots in context menu + if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode) + { + copyTransactionHashAction->setEnabled(true); + //if (model->isLockedCoin(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt())) + //{ + // lockAction->setEnabled(false); + // unlockAction->setEnabled(true); + //} + //else + //{ + // lockAction->setEnabled(true); + // unlockAction->setEnabled(false); + //} + } + else // this means click on parent node in tree mode -> disable all + { + copyTransactionHashAction->setEnabled(false); + //lockAction->setEnabled(false); + //unlockAction->setEnabled(false); + } + + // show context menu + contextMenu->exec(QCursor::pos()); + } +} + +// context menu action: copy amount +void CoinControlDialog::copyAmount() +{ + QApplication::clipboard()->setText(contextMenuItem->text(COLUMN_AMOUNT)); +} + +// context menu action: copy label +void CoinControlDialog::copyLabel() +{ + if (ui->radioTreeMode->isChecked() && contextMenuItem->text(COLUMN_LABEL).length() == 0 && contextMenuItem->parent()) + QApplication::clipboard()->setText(contextMenuItem->parent()->text(COLUMN_LABEL)); + else + QApplication::clipboard()->setText(contextMenuItem->text(COLUMN_LABEL)); +} + +// context menu action: copy address +void CoinControlDialog::copyAddress() +{ + if (ui->radioTreeMode->isChecked() && contextMenuItem->text(COLUMN_ADDRESS).length() == 0 && contextMenuItem->parent()) + QApplication::clipboard()->setText(contextMenuItem->parent()->text(COLUMN_ADDRESS)); + else + QApplication::clipboard()->setText(contextMenuItem->text(COLUMN_ADDRESS)); +} + +// context menu action: copy transaction id +void CoinControlDialog::copyTransactionHash() +{ + QApplication::clipboard()->setText(contextMenuItem->text(COLUMN_TXHASH)); +} + +// context menu action: lock coin +/*void CoinControlDialog::lockCoin() +{ + if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked) + contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); + + COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); + model->lockCoin(outpt); + contextMenuItem->setDisabled(true); + contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed")); + updateLabelLocked(); +}*/ + +// context menu action: unlock coin +/*void CoinControlDialog::unlockCoin() +{ + COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); + model->unlockCoin(outpt); + contextMenuItem->setDisabled(false); + contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon()); + updateLabelLocked(); +}*/ + +// copy label "Quantity" to clipboard +void CoinControlDialog::clipboardQuantity() +{ + QApplication::clipboard()->setText(ui->labelCoinControlQuantity->text()); +} + +// copy label "Amount" to clipboard +void CoinControlDialog::clipboardAmount() +{ + QApplication::clipboard()->setText(ui->labelCoinControlAmount->text().left(ui->labelCoinControlAmount->text().indexOf(" "))); +} + +// copy label "Fee" to clipboard +void CoinControlDialog::clipboardFee() +{ + QApplication::clipboard()->setText(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" "))); +} + +// copy label "After fee" to clipboard +void CoinControlDialog::clipboardAfterFee() +{ + QApplication::clipboard()->setText(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" "))); +} + +// copy label "Bytes" to clipboard +void CoinControlDialog::clipboardBytes() +{ + QApplication::clipboard()->setText(ui->labelCoinControlBytes->text()); +} + +// copy label "Priority" to clipboard +void CoinControlDialog::clipboardPriority() +{ + QApplication::clipboard()->setText(ui->labelCoinControlPriority->text()); +} + +// copy label "Low output" to clipboard +void CoinControlDialog::clipboardLowOutput() +{ + QApplication::clipboard()->setText(ui->labelCoinControlLowOutput->text()); +} + +// copy label "Change" to clipboard +void CoinControlDialog::clipboardChange() +{ + QApplication::clipboard()->setText(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" "))); +} + +// treeview: sort +void CoinControlDialog::sortView(int column, Qt::SortOrder order) +{ + sortColumn = column; + sortOrder = order; + ui->treeWidget->sortItems(column, order); + ui->treeWidget->header()->setSortIndicator((sortColumn == COLUMN_AMOUNT_INT64 ? COLUMN_AMOUNT : (sortColumn == COLUMN_PRIORITY_INT64 ? COLUMN_PRIORITY : sortColumn)), sortOrder); +} + +// treeview: clicked on header +void CoinControlDialog::headerSectionClicked(int logicalIndex) +{ + if (logicalIndex == COLUMN_CHECKBOX) // click on most left column -> do nothing + { + ui->treeWidget->header()->setSortIndicator((sortColumn == COLUMN_AMOUNT_INT64 ? COLUMN_AMOUNT : (sortColumn == COLUMN_PRIORITY_INT64 ? COLUMN_PRIORITY : sortColumn)), sortOrder); + } + else + { + if (logicalIndex == COLUMN_AMOUNT) // sort by amount + logicalIndex = COLUMN_AMOUNT_INT64; + + if (logicalIndex == COLUMN_PRIORITY) // sort by priority + logicalIndex = COLUMN_PRIORITY_INT64; + + if (sortColumn == logicalIndex) + sortOrder = ((sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder); + else + { + sortColumn = logicalIndex; + sortOrder = ((sortColumn == COLUMN_AMOUNT_INT64 || sortColumn == COLUMN_PRIORITY_INT64 || sortColumn == COLUMN_DATE || sortColumn == COLUMN_CONFIRMATIONS) ? Qt::DescendingOrder : Qt::AscendingOrder); // if amount,date,conf,priority then default => desc, else default => asc + } + + sortView(sortColumn, sortOrder); + } +} + +// toggle tree mode +void CoinControlDialog::radioTreeMode(bool checked) +{ + if (checked && model) + updateView(); +} + +// toggle list mode +void CoinControlDialog::radioListMode(bool checked) +{ + if (checked && model) + updateView(); +} + +// checkbox clicked by user +void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) +{ + if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode) + { + COutPoint outpt(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()); + + if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked) + coinControl->UnSelect(outpt); + else if (item->isDisabled()) // locked (this happens if "check all" through parent node) + item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); + else + coinControl->Select(outpt); + + // selection changed -> update labels + if (ui->treeWidget->isEnabled()) // do not update on every click for (un)select all + CoinControlDialog::updateLabels(model, this); + } +} + +// helper function, return human readable label for priority number +QString CoinControlDialog::getPriorityLabel(double dPriority) +{ + if (dPriority > 576000ULL) // at least medium, this number is from AllowFree(), the other thresholds are kinda random + { + if (dPriority > 5760000000ULL) return tr("highest"); + else if (dPriority > 576000000ULL) return tr("high"); + else if (dPriority > 57600000ULL) return tr("medium-high"); + else return tr("medium"); + } + else + { + if (dPriority > 5760ULL) return tr("low-medium"); + else if (dPriority > 58ULL) return tr("low"); + else return tr("lowest"); + } +} + +// shows count of locked unspent outputs +/*void CoinControlDialog::updateLabelLocked() +{ + vector vOutpts; + model->listLockedCoins(vOutpts); + if (vOutpts.size() > 0) + { + ui->labelLocked->setText(tr("(%1 locked)").arg(vOutpts.size())); + ui->labelLocked->setVisible(true); + } + else ui->labelLocked->setVisible(false); +}*/ + +void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) +{ + if (!model) return; + + // nPayAmount + qint64 nPayAmount = 0; + bool fLowOutput = false; + bool fDust = false; + CTransaction txDummy; + foreach(const qint64 &amount, CoinControlDialog::payAmounts) + { + nPayAmount += amount; + + if (amount > 0) + { + if (amount < CENT) + fLowOutput = true; + + CTxOut txout(amount, (CScript)vector(24, 0)); + txDummy.vout.push_back(txout); + } + } + + QString sPriorityLabel = ""; + int64 nAmount = 0; + int64 nPayFee = 0; + int64 nAfterFee = 0; + int64 nChange = 0; + unsigned int nBytes = 0; + unsigned int nBytesInputs = 0; + double dPriority = 0; + double dPriorityInputs = 0; + unsigned int nQuantity = 0; + + vector vCoinControl; + vector vOutputs; + coinControl->ListSelected(vCoinControl); + model->getOutputs(vCoinControl, vOutputs); + + BOOST_FOREACH(const COutput& out, vOutputs) + { + // Quantity + nQuantity++; + + // Amount + nAmount += out.tx->vout[out.i].nValue; + + // Priority + dPriorityInputs += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); + + // Bytes + CTxDestination address; + if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) + { + CPubKey pubkey; + CKeyID *keyid = boost::get< CKeyID >(&address); + if (keyid && model->getPubKey(*keyid, pubkey)) + nBytesInputs += (pubkey.IsCompressed() ? 148 : 180); + else + nBytesInputs += 148; // in all error cases, simply assume 148 here + } + else nBytesInputs += 148; + } + + // calculation + if (nQuantity > 0) + { + // Bytes + nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here + + // Priority + dPriority = dPriorityInputs / nBytes; + sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority); + + // Fee + int64 nFee = nTransactionFee * (1 + (int64)nBytes / 1000); + + // Min Fee + int64 nMinFee = txDummy.GetMinFee(1, false, GMF_SEND, nBytes); + + nPayFee = max(nFee, nMinFee); + + if (nPayAmount > 0) + { + nChange = nAmount - nPayFee - nPayAmount; + + // if sub-cent change is required, the fee must be raised to at least CTransaction::nMinTxFee + if (nPayFee < CENT && nChange > 0 && nChange < CENT) + { + if (nChange < CENT) // change < 0.01 => simply move all change to fees + { + nPayFee = nChange; + nChange = 0; + } + else + { + nChange = nChange + nPayFee - CENT; + nPayFee = CENT; + } + } + + if (nChange == 0) + nBytes -= 34; + } + + // after fee + nAfterFee = nAmount - nPayFee; + if (nAfterFee < 0) + nAfterFee = 0; + } + + // actually update labels + int nDisplayUnit = BitcoinUnits::BTC; + if (model && model->getOptionsModel()) + nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); + + QLabel *l1 = dialog->findChild("labelCoinControlQuantity"); + QLabel *l2 = dialog->findChild("labelCoinControlAmount"); + QLabel *l3 = dialog->findChild("labelCoinControlFee"); + QLabel *l4 = dialog->findChild("labelCoinControlAfterFee"); + QLabel *l5 = dialog->findChild("labelCoinControlBytes"); + QLabel *l6 = dialog->findChild("labelCoinControlPriority"); + QLabel *l7 = dialog->findChild("labelCoinControlLowOutput"); + QLabel *l8 = dialog->findChild("labelCoinControlChange"); + + // enable/disable "low output" and "change" + dialog->findChild("labelCoinControlLowOutputText")->setEnabled(nPayAmount > 0); + dialog->findChild("labelCoinControlLowOutput") ->setEnabled(nPayAmount > 0); + dialog->findChild("labelCoinControlChangeText") ->setEnabled(nPayAmount > 0); + dialog->findChild("labelCoinControlChange") ->setEnabled(nPayAmount > 0); + + // stats + l1->setText(QString::number(nQuantity)); // Quantity + l2->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAmount)); // Amount + l3->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nPayFee)); // Fee + l4->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAfterFee)); // After Fee + l5->setText(((nBytes > 0) ? "~" : "") + QString::number(nBytes)); // Bytes + l6->setText(sPriorityLabel); // Priority + l7->setText((fLowOutput ? (fDust ? tr("DUST") : tr("yes")) : tr("no"))); // Low Output / Dust + l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change + + // turn labels "red" + l5->setStyleSheet((nBytes >= 10000) ? "color:red;" : ""); // Bytes >= 10000 + l6->setStyleSheet((dPriority <= 576000) ? "color:red;" : ""); // Priority < "medium" + l7->setStyleSheet((fLowOutput) ? "color:red;" : ""); // Low Output = "yes" + l8->setStyleSheet((nChange > 0 && nChange < CENT) ? "color:red;" : ""); // Change < 0.01BTC + + // tool tips + l5->setToolTip(tr("This label turns red, if the transaction size is bigger than 10000 bytes.\n\n This means a fee of at least %1 per kb is required.\n\n Can vary +/- 1 Byte per input.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT))); + l6->setToolTip(tr("Transactions with higher priority get more likely into a block.\n\nThis label turns red, if the priority is smaller than \"medium\".\n\n This means a fee of at least %1 per kb is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT))); + l7->setToolTip(tr("This label turns red, if any recipient receives an amount smaller than %1.\n\n This means a fee of at least %2 is required. \n\n Amounts below 0.546 times the minimum relay fee are shown as DUST.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT)).arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT))); + l8->setToolTip(tr("This label turns red, if the change is smaller than %1.\n\n This means a fee of at least %2 is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT)).arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT))); + dialog->findChild("labelCoinControlBytesText") ->setToolTip(l5->toolTip()); + dialog->findChild("labelCoinControlPriorityText") ->setToolTip(l6->toolTip()); + dialog->findChild("labelCoinControlLowOutputText")->setToolTip(l7->toolTip()); + dialog->findChild("labelCoinControlChangeText") ->setToolTip(l8->toolTip()); + + // Insufficient funds + QLabel *label = dialog->findChild("labelCoinControlInsuffFunds"); + if (label) + label->setVisible(nChange < 0); +} + +void CoinControlDialog::updateView() +{ + bool treeMode = ui->radioTreeMode->isChecked(); + + ui->treeWidget->clear(); + ui->treeWidget->setEnabled(false); // performance, otherwise updateLabels would be called for every checked checkbox + ui->treeWidget->setAlternatingRowColors(!treeMode); + QFlags flgCheckbox=Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; + QFlags flgTristate=Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate; + + int nDisplayUnit = BitcoinUnits::BTC; + if (model && model->getOptionsModel()) + nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); + + map > mapCoins; + model->listCoins(mapCoins); + + BOOST_FOREACH(PAIRTYPE(QString, vector) coins, mapCoins) + { + QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem(); + QString sWalletAddress = coins.first; + QString sWalletLabel = ""; + if (model->getAddressTableModel()) + sWalletLabel = model->getAddressTableModel()->labelForAddress(sWalletAddress); + if (sWalletLabel.length() == 0) + sWalletLabel = tr("(no label)"); + + if (treeMode) + { + // wallet address + ui->treeWidget->addTopLevelItem(itemWalletAddress); + + itemWalletAddress->setFlags(flgTristate); + itemWalletAddress->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); + + for (int i = 0; i < ui->treeWidget->columnCount(); i++) + itemWalletAddress->setBackground(i, QColor(248, 247, 246)); + + // label + itemWalletAddress->setText(COLUMN_LABEL, sWalletLabel); + + // address + itemWalletAddress->setText(COLUMN_ADDRESS, sWalletAddress); + } + + int64 nSum = 0; + double dPrioritySum = 0; + int nChildren = 0; + int nInputSum = 0; + BOOST_FOREACH(const COutput& out, coins.second) + { + int nInputSize = 148; // 180 if uncompressed public key + nSum += out.tx->vout[out.i].nValue; + nChildren++; + + QTreeWidgetItem *itemOutput; + if (treeMode) itemOutput = new QTreeWidgetItem(itemWalletAddress); + else itemOutput = new QTreeWidgetItem(ui->treeWidget); + itemOutput->setFlags(flgCheckbox); + itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); + + // address + CTxDestination outputAddress; + QString sAddress = ""; + if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, outputAddress)) + { + sAddress = CBitcoinAddress(outputAddress).ToString().c_str(); + + // if listMode or change => show bitcoin address. In tree mode, address is not shown again for direct wallet address outputs + if (!treeMode || (!(sAddress == sWalletAddress))) + itemOutput->setText(COLUMN_ADDRESS, sAddress); + + CPubKey pubkey; + CKeyID *keyid = boost::get< CKeyID >(&outputAddress); + if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed()) + nInputSize = 180; + } + + // label + if (!(sAddress == sWalletAddress)) // change + { + // tooltip from where the change comes from + itemOutput->setToolTip(COLUMN_LABEL, tr("change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress)); + itemOutput->setText(COLUMN_LABEL, tr("(change)")); + } + else if (!treeMode) + { + QString sLabel = ""; + if (model->getAddressTableModel()) + sLabel = model->getAddressTableModel()->labelForAddress(sAddress); + if (sLabel.length() == 0) + sLabel = tr("(no label)"); + itemOutput->setText(COLUMN_LABEL, sLabel); + } + + // amount + itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->vout[out.i].nValue)); + itemOutput->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(out.tx->vout[out.i].nValue), 15, " ")); // padding so that sorting works correctly + + // date + itemOutput->setText(COLUMN_DATE, QDateTime::fromTime_t(out.tx->GetTxTime()).toUTC().toString("yy-MM-dd hh:mm")); + + // immature PoS reward + if (out.tx->IsCoinStake() && out.tx->GetBlocksToMaturity() > 0 && out.tx->GetDepthInMainChain() > 0) { + itemOutput->setBackground(COLUMN_CONFIRMATIONS, Qt::red); + itemOutput->setDisabled(true); + } + + // confirmations + itemOutput->setText(COLUMN_CONFIRMATIONS, strPad(QString::number(out.nDepth), 8, " ")); + + // priority + double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10 + itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority)); + itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64)dPriority), 20, " ")); + dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); + nInputSum += nInputSize; + + // transaction hash + uint256 txhash = out.tx->GetHash(); + itemOutput->setText(COLUMN_TXHASH, txhash.GetHex().c_str()); + + // vout index + itemOutput->setText(COLUMN_VOUT_INDEX, QString::number(out.i)); + + // disable locked coins + /*if (model->isLockedCoin(txhash, out.i)) + { + COutPoint outpt(txhash, out.i); + coinControl->UnSelect(outpt); // just to be sure + itemOutput->setDisabled(true); + itemOutput->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed")); + }*/ + + // set checkbox + if (coinControl->IsSelected(txhash, out.i)) + itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Checked); + } + + // amount + if (treeMode) + { + dPrioritySum = dPrioritySum / (nInputSum + 78); + itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")"); + itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum)); + itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " ")); + itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum)); + itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64)dPrioritySum), 20, " ")); + } + } + + // expand all partially selected + if (treeMode) + { + for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) + if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked) + ui->treeWidget->topLevelItem(i)->setExpanded(true); + } + + // sort view + sortView(sortColumn, sortOrder); + ui->treeWidget->setEnabled(true); +} diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h new file mode 100644 index 0000000..5d0a90b --- /dev/null +++ b/src/qt/coincontroldialog.h @@ -0,0 +1,92 @@ +#ifndef COINCONTROLDIALOG_H +#define COINCONTROLDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ui { + class CoinControlDialog; +} +class WalletModel; +class CCoinControl; + +class CoinControlDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CoinControlDialog(QWidget *parent = 0); + ~CoinControlDialog(); + + void setModel(WalletModel *model); + + // static because also called from sendcoinsdialog + static void updateLabels(WalletModel*, QDialog*); + static QString getPriorityLabel(double); + + static QList payAmounts; + static CCoinControl *coinControl; + +private: + Ui::CoinControlDialog *ui; + WalletModel *model; + int sortColumn; + Qt::SortOrder sortOrder; + + QMenu *contextMenu; + QTreeWidgetItem *contextMenuItem; + QAction *copyTransactionHashAction; + //QAction *lockAction; + //QAction *unlockAction; + + QString strPad(QString, int, QString); + void sortView(int, Qt::SortOrder); + void updateView(); + + enum + { + COLUMN_CHECKBOX, + COLUMN_AMOUNT, + COLUMN_LABEL, + COLUMN_ADDRESS, + COLUMN_DATE, + COLUMN_CONFIRMATIONS, + COLUMN_PRIORITY, + COLUMN_TXHASH, + COLUMN_VOUT_INDEX, + COLUMN_AMOUNT_INT64, + COLUMN_PRIORITY_INT64 + }; + +private slots: + void showMenu(const QPoint &); + void copyAmount(); + void copyLabel(); + void copyAddress(); + void copyTransactionHash(); + //void lockCoin(); + //void unlockCoin(); + void clipboardQuantity(); + void clipboardAmount(); + void clipboardFee(); + void clipboardAfterFee(); + void clipboardBytes(); + void clipboardPriority(); + void clipboardLowOutput(); + void clipboardChange(); + void radioTreeMode(bool); + void radioListMode(bool); + void viewItemChanged(QTreeWidgetItem*, int); + void headerSectionClicked(int); + void buttonBoxClicked(QAbstractButton*); + void buttonSelectAllClicked(); + //void updateLabelLocked(); +}; + +#endif // COINCONTROLDIALOG_H diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp new file mode 100644 index 0000000..0c1b514 --- /dev/null +++ b/src/qt/coincontroltreewidget.cpp @@ -0,0 +1,28 @@ +#include "coincontroltreewidget.h" +#include "coincontroldialog.h" + +CoinControlTreeWidget::CoinControlTreeWidget(QWidget *parent) : + QTreeWidget(parent) +{ + +} + +void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Space) // press spacebar -> select checkbox + { + event->ignore(); + int COLUMN_CHECKBOX = 0; + this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked)); + } + else if (event->key() == Qt::Key_Escape) // press esc -> close dialog + { + event->ignore(); + CoinControlDialog *coinControlDialog = (CoinControlDialog*)this->parentWidget(); + coinControlDialog->done(QDialog::Accepted); + } + else + { + this->QTreeWidget::keyPressEvent(event); + } +} diff --git a/src/qt/coincontroltreewidget.h b/src/qt/coincontroltreewidget.h new file mode 100644 index 0000000..d981f72 --- /dev/null +++ b/src/qt/coincontroltreewidget.h @@ -0,0 +1,17 @@ +#ifndef COINCONTROLTREEWIDGET_H +#define COINCONTROLTREEWIDGET_H + +#include +#include + +class CoinControlTreeWidget : public QTreeWidget { +Q_OBJECT + +public: + explicit CoinControlTreeWidget(QWidget *parent = 0); + +protected: + virtual void keyPressEvent(QKeyEvent *event); +}; + +#endif // COINCONTROLTREEWIDGET_H \ No newline at end of file diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp new file mode 100644 index 0000000..8a50bba --- /dev/null +++ b/src/qt/csvmodelwriter.cpp @@ -0,0 +1,88 @@ +#include "csvmodelwriter.h" + +#include +#include +#include + +CSVModelWriter::CSVModelWriter(const QString &filename, QObject *parent) : + QObject(parent), + filename(filename), model(0) +{ +} + +void CSVModelWriter::setModel(const QAbstractItemModel *model) +{ + this->model = model; +} + +void CSVModelWriter::addColumn(const QString &title, int column, int role) +{ + Column col; + col.title = title; + col.column = column; + col.role = role; + + columns.append(col); +} + +static void writeValue(QTextStream &f, const QString &value) +{ + QString escaped = value; + escaped.replace('"', "\"\""); + f << "\"" << escaped << "\""; +} + +static void writeSep(QTextStream &f) +{ + f << ","; +} + +static void writeNewline(QTextStream &f) +{ + f << "\n"; +} + +bool CSVModelWriter::write() +{ + QFile file(filename); + if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) + return false; + QTextStream out(&file); + + int numRows = 0; + if(model) + { + numRows = model->rowCount(); + } + + // Header row + for(int i=0; iindex(j, columns[i].column).data(columns[i].role); + writeValue(out, data.toString()); + } + writeNewline(out); + } + + file.close(); + + return file.error() == QFile::NoError; +} + diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h new file mode 100644 index 0000000..6c9dcba --- /dev/null +++ b/src/qt/csvmodelwriter.h @@ -0,0 +1,46 @@ +#ifndef CSVMODELWRITER_H +#define CSVMODELWRITER_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QAbstractItemModel; +QT_END_NAMESPACE + +/** Export a Qt table model to a CSV file. This is useful for analyzing or post-processing the data in + a spreadsheet. + */ +class CSVModelWriter : public QObject +{ + Q_OBJECT +public: + explicit CSVModelWriter(const QString &filename, QObject *parent = 0); + + void setModel(const QAbstractItemModel *model); + void addColumn(const QString &title, int column, int role=Qt::EditRole); + + /** Perform export of the model to CSV. + @returns true on success, false otherwise + */ + bool write(); + +private: + QString filename; + const QAbstractItemModel *model; + + struct Column + { + QString title; + int column; + int role; + }; + QList columns; + +signals: + +public slots: + +}; + +#endif // CSVMODELWRITER_H diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp new file mode 100644 index 0000000..cfcef1f --- /dev/null +++ b/src/qt/editaddressdialog.cpp @@ -0,0 +1,128 @@ +#include "editaddressdialog.h" +#include "ui_editaddressdialog.h" +#include "addresstablemodel.h" +#include "guiutil.h" + +#include +#include + +EditAddressDialog::EditAddressDialog(Mode mode, QWidget *parent) : + QDialog(parent), + ui(new Ui::EditAddressDialog), mapper(0), mode(mode), model(0) +{ + ui->setupUi(this); + + GUIUtil::setupAddressWidget(ui->addressEdit, this); + + switch(mode) + { + case NewReceivingAddress: + setWindowTitle(tr("New receiving address")); + ui->addressEdit->setEnabled(false); + break; + case NewSendingAddress: + setWindowTitle(tr("New sending address")); + break; + case EditReceivingAddress: + setWindowTitle(tr("Edit receiving address")); + ui->addressEdit->setDisabled(true); + break; + case EditSendingAddress: + setWindowTitle(tr("Edit sending address")); + break; + } + + mapper = new QDataWidgetMapper(this); + mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); +} + +EditAddressDialog::~EditAddressDialog() +{ + delete ui; +} + +void EditAddressDialog::setModel(AddressTableModel *model) +{ + this->model = model; + mapper->setModel(model); + mapper->addMapping(ui->labelEdit, AddressTableModel::Label); + mapper->addMapping(ui->addressEdit, AddressTableModel::Address); +} + +void EditAddressDialog::loadRow(int row) +{ + mapper->setCurrentIndex(row); +} + +bool EditAddressDialog::saveCurrentRow() +{ + if(!model) + return false; + switch(mode) + { + case NewReceivingAddress: + case NewSendingAddress: + address = model->addRow( + mode == NewSendingAddress ? AddressTableModel::Send : AddressTableModel::Receive, + ui->labelEdit->text(), + ui->addressEdit->text()); + break; + case EditReceivingAddress: + case EditSendingAddress: + if(mapper->submit()) + { + address = ui->addressEdit->text(); + } + break; + } + return !address.isEmpty(); +} + +void EditAddressDialog::accept() +{ + if(!model) + return; + if(!saveCurrentRow()) + { + switch(model->getEditStatus()) + { + case AddressTableModel::DUPLICATE_ADDRESS: + QMessageBox::warning(this, windowTitle(), + tr("The entered address \"%1\" is already in the address book.").arg(ui->addressEdit->text()), + QMessageBox::Ok, QMessageBox::Ok); + break; + case AddressTableModel::INVALID_ADDRESS: + QMessageBox::warning(this, windowTitle(), + tr("The entered address \"%1\" is not a valid BERN address.").arg(ui->addressEdit->text()), + QMessageBox::Ok, QMessageBox::Ok); + return; + case AddressTableModel::WALLET_UNLOCK_FAILURE: + QMessageBox::critical(this, windowTitle(), + tr("Could not unlock wallet."), + QMessageBox::Ok, QMessageBox::Ok); + return; + case AddressTableModel::KEY_GENERATION_FAILURE: + QMessageBox::critical(this, windowTitle(), + tr("New key generation failed."), + QMessageBox::Ok, QMessageBox::Ok); + return; + case AddressTableModel::OK: + // Failed with unknown reason. Just reject. + break; + } + + return; + } + QDialog::accept(); +} + +QString EditAddressDialog::getAddress() const +{ + return address; +} + +void EditAddressDialog::setAddress(const QString &address) +{ + this->address = address; + ui->addressEdit->setText(address); +} diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h new file mode 100644 index 0000000..7ec053f --- /dev/null +++ b/src/qt/editaddressdialog.h @@ -0,0 +1,50 @@ +#ifndef EDITADDRESSDIALOG_H +#define EDITADDRESSDIALOG_H + +#include + +QT_BEGIN_NAMESPACE +class QDataWidgetMapper; +QT_END_NAMESPACE + +namespace Ui { + class EditAddressDialog; +} +class AddressTableModel; + +/** Dialog for editing an address and associated information. + */ +class EditAddressDialog : public QDialog +{ + Q_OBJECT + +public: + enum Mode { + NewReceivingAddress, + NewSendingAddress, + EditReceivingAddress, + EditSendingAddress + }; + + explicit EditAddressDialog(Mode mode, QWidget *parent = 0); + ~EditAddressDialog(); + + void setModel(AddressTableModel *model); + void loadRow(int row); + + void accept(); + + QString getAddress() const; + void setAddress(const QString &address); +private: + bool saveCurrentRow(); + + Ui::EditAddressDialog *ui; + QDataWidgetMapper *mapper; + Mode mode; + AddressTableModel *model; + + QString address; +}; + +#endif // EDITADDRESSDIALOG_H diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui new file mode 100644 index 0000000..34dc345 --- /dev/null +++ b/src/qt/forms/aboutdialog.ui @@ -0,0 +1,190 @@ + + + AboutDialog + + + + 0 + 0 + 593 + 331 + + + + About BERN + + + + + + + 0 + 0 + + + + :/images/about + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + IBeamCursor + + + <html><head/><body><p><span style=" font-weight:600;">BERN</span> version</p></body></html> + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + IBeamCursor + + + 2.0.0.0-beta + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + IBeamCursor + + + +Copyright © 2009-2012 Bitcoin Developers +Copyright © 2012 PPCoin Developers +Copyright © 2014 SoleCoin Developers +Copyright © 2016 BERN Developers + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + IBeamCursor + + + +This is experimental software. If you don't treat it as such, you're likely to put an eye out! + +Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + + + + + buttonBox + accepted() + AboutDialog + accept() + + + 360 + 308 + + + 157 + 274 + + + + + buttonBox + rejected() + AboutDialog + reject() + + + 428 + 308 + + + 286 + 274 + + + + + diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui new file mode 100644 index 0000000..be603fc --- /dev/null +++ b/src/qt/forms/addressbookpage.ui @@ -0,0 +1,178 @@ + + + AddressBookPage + + + + 0 + 0 + 902 + 380 + + + + Address Book + + + + + + #labelExplanation { color: #464747; } + + + These are your BERN addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + + + Qt::PlainText + + + true + + + + + + + Qt::CustomContextMenu + + + Double-click to edit address or label + + + false + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + false + + + + + + + + + Create a new address + + + &New Address + + + + :/icons/add:/icons/add + + + + + + + Copy the currently selected address to the system clipboard + + + &Copy Address + + + + :/icons/editcopy:/icons/editcopy + + + + + + + Show &QR Code + + + + :/icons/qrcode:/icons/qrcode + + + + + + + Sign a message to prove you own a SoleCoin address + + + Sign &Message + + + + :/icons/edit:/icons/edit + + + + + + + Verify a message to ensure it was signed with a specified SoleCoin address + + + &Verify Message + + + + :/icons/transaction_0:/icons/transaction_0 + + + + + + + Delete the currently selected address from the list + + + &Delete + + + + :/icons/remove:/icons/remove + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + QDialogButtonBox::Ok + + + + + + + + + + + + diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui new file mode 100644 index 0000000..1c9c05c --- /dev/null +++ b/src/qt/forms/askpassphrasedialog.ui @@ -0,0 +1,167 @@ + + + AskPassphraseDialog + + + + 0 + 0 + 598 + 198 + + + + + 0 + 0 + + + + + 550 + 0 + + + + Passphrase Dialog + + + + + + Qt::RichText + + + true + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Enter BERN passphrase + + + + + + + QLineEdit::Password + + + + + + + New BERN passphrase + + + + + + + QLineEdit::Password + + + + + + + Repeat new BERN passphrase + + + + + + + QLineEdit::Password + + + + + + + + 75 + true + + + + + + + Qt::AlignCenter + + + + + + + true + + + false + + + Serves to disable trivial use of sendmoney when the OS account is compromised. Provides no real security. + + + For staking only + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AskPassphraseDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AskPassphraseDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/forms/blockbrowser.ui b/src/qt/forms/blockbrowser.ui new file mode 100644 index 0000000..39ab457 --- /dev/null +++ b/src/qt/forms/blockbrowser.ui @@ -0,0 +1,418 @@ + + + BlockBrowser + + + Qt::NonModal + + + true + + + + 0 + 0 + 938 + 499 + + + + + 0 + 0 + + + + + 0 + 0 + + + + false + + + Form + + + + QLayout::SetMaximumSize + + + 21 + + + 21 + + + 10 + + + 6 + + + + + + + 0 + 19 + 881 + 431 + + + + + QLayout::SetMaximumSize + + + 7 + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 75 + true + + + + TX Information + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Inputs: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + 0000 KH/s + + + + + + + Value out: + + + + + + + Transaction ID: + + + + + + + 0.00 + + + + + + + 000 + + + + + + + + + + + + + + Block Difficulty: + + + + + + + + 0 + 0 + + + + + + + 99999999 + + + + + + + Block Height: + + + + + + + 0 + + + + + + + Block Merkle: + + + + + + + Block Hash: + + + + + + + + + + + + + + Block Hashrate: + + + + + + + IBeamCursor + + + false + + + true + + + QFrame::NoFrame + + + 0 + + + + + + + Fees: + + + + + + + Block nBits: + + + + + + + 0 + + + + + + + + 187 + 0 + + + + 0x0 + + + + + + + Outputs: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + Block nNonce: + + + + + + + 0 + + + + + + + Block Timestamp: + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + 0x0 + + + + + + + + 0 + 0 + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 300 + 0 + + + + + 16777215 + 16777215 + + + + + 75 + true + + + + Jump to Block + + + true + + + false + + + + + + + Please visit the online explorer for more details. http://transactions.bern.cash + + + + + + + + + + + + diff --git a/src/qt/forms/coincontroldialog.ui b/src/qt/forms/coincontroldialog.ui new file mode 100644 index 0000000..daa8241 --- /dev/null +++ b/src/qt/forms/coincontroldialog.ui @@ -0,0 +1,549 @@ + + + CoinControlDialog + + + + 0 + 0 + 1000 + 500 + + + + Coin Control + + + + + + 0 + + + 10 + + + + + 10 + + + 10 + + + 6 + + + 6 + + + + + font-weight:bold; + + + Quantity: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0 + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + font-weight:bold; + + + Bytes: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0 + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 10 + + + 6 + + + 6 + + + + + font-weight:bold; + + + Amount: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + font-weight:bold; + + + Priority: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 10 + + + 6 + + + 6 + + + + + font-weight:bold; + + + Fee: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + false + + + font-weight:bold; + + + Low Output: + + + + + + + false + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + no + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 10 + + + 6 + + + 6 + + + + + font-weight:bold; + + + After Fee: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + false + + + font-weight:bold; + + + Change: + + + + + + + false + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 40 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + 10 + 0 + 781 + 41 + + + + + 14 + + + + + + 0 + 0 + + + + (un)select all + + + + + + + + 0 + 0 + + + + Tree mode + + + true + + + + + + + + 0 + 0 + + + + List mode + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::CustomContextMenu + + + false + + + 11 + + + true + + + false + + + + + + + + + Amount + + + + + Label + + + + + Address + + + + + Date + + + + + Confirmations + + + Confirmed + + + + + Priority + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + CoinControlTreeWidget + QTreeWidget +
coincontroltreewidget.h
+
+
+ + +
diff --git a/src/qt/forms/editaddressdialog.ui b/src/qt/forms/editaddressdialog.ui new file mode 100644 index 0000000..4f52c6b --- /dev/null +++ b/src/qt/forms/editaddressdialog.ui @@ -0,0 +1,105 @@ + + + EditAddressDialog + + + + 0 + 0 + 457 + 126 + + + + Edit Address + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + &Label + + + labelEdit + + + + + + + The label associated with this address book entry + + + + + + + BERN &Address + + + addressEdit + + + + + + + The address associated with this address book entry. This can only be modified for sending addresses. + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + EditAddressDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + EditAddressDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/forms/miningpage.ui b/src/qt/forms/miningpage.ui new file mode 100644 index 0000000..8efe600 --- /dev/null +++ b/src/qt/forms/miningpage.ui @@ -0,0 +1,406 @@ + + + MiningPage + + + + 0 + 0 + 780 + 636 + + + + Mining + + + + QLayout::SetMaximumSize + + + + + Type + + + + + + + true + + + Qt::LeftToRight + + + Scantime + + + + + + + + 0 + 0 + + + + false + + + 0 + + + + Easy Pool Mining + + + + + Solo Mining + + + + + Custom Pool Mining + + + + + + + + true + + + Threads + + + + + + + + + + 100000 + + + QAbstractItemView::NoEditTriggers + + + false + + + QAbstractItemView::DragOnly + + + QAbstractItemView::ExtendedSelection + + + QListView::Snap + + + 10 + + + + + + + true + + + + 0 + 0 + + + + + 230 + 0 + + + + + + + + true + + + Server + + + + + + + true + + + + 0 + 0 + + + + 1 + + + 10 + + + + + + + true + + + Worker Name + + + + + + + true + + + + 0 + 0 + + + + + + + + true + + + + 0 + 0 + + + + + 50 + 16777215 + + + + 9332 + + + 9332 + + + + + + + true + + + Port + + + + + + + true + + + Password + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 0 + 20 + + + + Qt::Horizontal + + + + + + + true + + + + 0 + 0 + + + + + + + + + + + true + + + + 0 + 0 + + + + 1 + + + 99 + + + 1 + + + 4 + + + + + + + + 10 + 75 + true + + + + + + + + + + + + 0 + 0 + + + + + 300 + 0 + + + + + 280 + 16777215 + + + + + 75 + true + + + + Start / Stop mining + + + background-color:#333333; color:#cecece; + + + Start Mining + + + + + + + Display Debug + + + true + + + + + serverLine + usernameLabel + serverLabel + usernameLine + passwordLabel + portLabel + line + list + shareCount + scantimeLabel + threadsLabel + debugCheckBox + typeLabel + threadsBox + typeBox + scantimeBox + portLine + passwordLine + mineSpeedLabel + startButton + + + + startButton + typeBox + threadsBox + scantimeBox + serverLine + portLine + usernameLine + passwordLine + debugCheckBox + list + + + + diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui new file mode 100644 index 0000000..127927e --- /dev/null +++ b/src/qt/forms/optionsdialog.ui @@ -0,0 +1,470 @@ + + + OptionsDialog + + + + 0 + 0 + 540 + 380 + + + + Options + + + true + + + + + + QTabWidget::North + + + 0 + + + + &Main + + + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + Qt::PlainText + + + true + + + + + + + + + Pay transaction &fee + + + Qt::PlainText + + + transactionFee + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Automatically start SoleCoin after logging in to the system. + + + &Start BERN on system login + + + + + + + Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached. + + + &Detach databases at shutdown + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + &Network + + + + + + Automatically open the SoleCoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + Map port using &UPnP + + + + + + + Connect to the SoleCoin network through a SOCKS proxy (e.g. when connecting through Tor). + + + &Connect through SOCKS proxy: + + + + + + + + + Proxy &IP: + + + Qt::PlainText + + + proxyIp + + + + + + + + 140 + 16777215 + + + + IP address of the proxy (e.g. 127.0.0.1) + + + + + + + &Port: + + + Qt::PlainText + + + proxyPort + + + + + + + + 55 + 16777215 + + + + Port of the proxy (e.g. 9050) + + + + + + + SOCKS &Version: + + + Qt::PlainText + + + socksVersion + + + + + + + SOCKS version of the proxy (e.g. 5) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + &Window + + + + + + Show only a tray icon after minimizing the window. + + + &Minimize to the tray instead of the taskbar + + + + + + + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. + + + M&inimize on close + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + &Display + + + + + + + + User Interface &language: + + + Qt::PlainText + + + lang + + + + + + + The user interface language can be set here. This setting will take effect after restarting SoleCoin. + + + + + + + + + + + &Unit to show amounts in: + + + Qt::PlainText + + + unit + + + + + + + Choose the default subdivision unit to show in the interface and when sending coins. + + + + + + + + + Whether to show SoleCoin addresses in the transaction list or not. + + + &Display addresses in transaction list + + + + + + + Whether to show coin control features or not. + + + Display coin &control features (experts only!) + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + 75 + true + + + + + + + Qt::PlainText + + + true + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + &OK + + + + + + + &Cancel + + + false + + + + + + + &Apply + + + false + + + + + + + + + + BitcoinAmountField + QSpinBox +
bitcoinamountfield.h
+
+ + QValueComboBox + QComboBox +
qvaluecombobox.h
+
+ + QValidatedLineEdit + QLineEdit +
qvalidatedlineedit.h
+
+
+ + +
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui new file mode 100644 index 0000000..2fa9112 --- /dev/null +++ b/src/qt/forms/overviewpage.ui @@ -0,0 +1,382 @@ + + + OverviewPage + + + + 0 + 0 + 625 + 465 + + + + BERN + + + #OverviewPage { color: #464747; } + + + + + + + + #frame { background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70,71,71,15), stop:1.0 rgba(70,71,71,0)); } + + + + + + + + + 11 + 75 + true + + + + color: #464747; + + + BERN Summary + + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the SoleCoin network after a connection is established, but this process has not completed yet. + + + QLabel { color: red; } + + + (out of sync) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + 12 + + + 12 + + + + + color: #464747; + + + Balance: + + + + + + + + 75 + true + + + + IBeamCursor + + + Your current balance + + + color: #464747; + + + 0 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + color: #464747; + + + Stake: + + + + + + + + 75 + true + + + + IBeamCursor + + + Total of coins that was staked, and do not yet count toward the current balance + + + color: #464747; + + + 0 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + color: #464747; + + + Unconfirmed: + + + + + + + + 75 + true + + + + IBeamCursor + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + color: #464747; + + + 0 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + color: #464747; + + + Immature: + + + + + + + + 75 + true + + + + Mined balance that has not yet matured + + + color: #464747; + + + 0 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + color: #464747; + + + Number of transactions: + + + + + + + Total number of transactions in wallet + + + color: #464747; + + + 0 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + :/images/backg + + + false + + + Qt::AlignCenter + + + -2 + + + + + + + + + + + #frame_2 { background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70,71,71,10), stop:1.0 rgba(70,71,71,0)); } + + + + + + + + color: #464747; + + + <html><head/><body><p><span style=" font-weight:600;">Recent BERN transactions</span></p></body></html> + + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the SoleCoin network after a connection is established, but this process has not completed yet. + + + QLabel { color: red; } + + + (out of sync) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QListView { background: transparent; } + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoSelection + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + diff --git a/src/qt/forms/qrcodedialog.ui b/src/qt/forms/qrcodedialog.ui new file mode 100644 index 0000000..5bfa40c --- /dev/null +++ b/src/qt/forms/qrcodedialog.ui @@ -0,0 +1,212 @@ + + + QRCodeDialog + + + + 0 + 0 + 340 + 556 + + + + QR Code Dialog + + + + + + + 0 + 0 + + + + + 300 + 300 + + + + Qt::PlainText + + + Qt::AlignCenter + + + true + + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + true + + + Request BERN Payment + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Label: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lnLabel + + + + + + + + + + Message: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lnMessage + + + + + + + + + + + 0 + 0 + + + + Amount: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lnReqAmount + + + + + + + false + + + + 80 + 0 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Save As... + + + + + + + + + + + + + BitcoinAmountField + QSpinBox +
bitcoinamountfield.h
+
+
+ + + + chkReqPayment + clicked(bool) + lnReqAmount + setEnabled(bool) + + + 92 + 285 + + + 98 + 311 + + + + +
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui new file mode 100644 index 0000000..9e4d618 --- /dev/null +++ b/src/qt/forms/rpcconsole.ui @@ -0,0 +1,456 @@ + + + RPCConsole + + + + 0 + 0 + 740 + 491 + + + + BERN - Debug Window + + + + + + 0 + + + + &Information + + + + 12 + + + + + + 75 + true + + + + BERN Core + + + + + + + Client name + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Client version + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Using OpenSSL version + + + 10 + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Build date + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Startup time + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + 75 + true + + + + Network + + + + + + + Number of connections + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + On testnet + + + + + + + false + + + + + + + + + + + 75 + true + + + + Block chain + + + + + + + Current number of blocks + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Estimated total blocks + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Last block time + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + 75 + true + + + + Debug log file + + + + + + + Open the SoleCoin debug log file from the current data directory. This can take a few seconds for large log files. + + + &Open + + + false + + + + + + + + 75 + true + + + + Command-line options + + + + + + + Show the BERN-Qt help message to get a list with possible BERN command-line options. + + + &Show + + + false + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + &Console + + + + 3 + + + + + + 0 + 100 + + + + true + + + false + + + 2 + + + + + + + 3 + + + + + > + + + + + + + + + + + 24 + 24 + + + + Clear console + + + + + + + :/icons/remove:/icons/remove + + + Ctrl+L + + + false + + + + + + + + + + + + + + + + diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui new file mode 100644 index 0000000..333a0fc --- /dev/null +++ b/src/qt/forms/sendcoinsdialog.ui @@ -0,0 +1,812 @@ + + + SendCoinsDialog + + + + 0 + 0 + 850 + 400 + + + + Send Coins + + + + 8 + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 6 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + 0 + + + 10 + + + 10 + + + + + 15 + + + + + + 0 + 0 + + + + + 75 + true + + + + font-weight:bold; + + + BERN Coin Control Features + + + + + + + + + 8 + + + 10 + + + + + + + + Inputs... + + + + + + + automatically selected + + + 5 + + + + + + + + 75 + true + + + + color:red;font-weight:bold; + + + Insufficient funds! + + + 5 + + + + + + + Qt::Horizontal + + + + 40 + 1 + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 20 + + + 0 + + + 10 + + + + + 10 + + + 14 + + + 10 + + + 4 + + + 6 + + + + + font-weight:bold; + + + Quantity: + + + 0 + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0 + + + 0 + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + font-weight:bold; + + + Bytes: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0 + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 14 + + + 6 + + + 4 + + + 6 + + + + + font-weight:bold; + + + Amount: + + + 0 + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + font-weight:bold; + + + Priority: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + medium + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 14 + + + 6 + + + 4 + + + 6 + + + + + font-weight:bold; + + + Fee: + + + 0 + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + font-weight:bold; + + + Low Output: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + no + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 14 + + + 6 + + + 4 + + + 6 + + + + + font-weight:bold; + + + After Fee: + + + 0 + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + font-weight:bold; + + + Change + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + + + 12 + + + QLayout::SetDefaultConstraint + + + 5 + + + 5 + + + + + custom change address + + + + + + + false + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + 3 + + + + + + + + + Qt::Vertical + + + + 800 + 1 + + + + + + + + + + + + + true + + + + + 0 + 0 + 830 + 152 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Send to multiple recipients at once + + + Add &Recipient + + + + :/icons/add:/icons/add + + + false + + + + + + + + 0 + 0 + + + + Remove all transaction fields + + + Clear &All + + + + :/icons/remove:/icons/remove + + + 300 + + + false + + + + + + + 3 + + + + + + 0 + 0 + + + + #label { color: #464747; } + + + Balance: + + + + + + + + 0 + 0 + + + + IBeamCursor + + + #label { color: #464747; } + + + 123.456 BERN + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 150 + 0 + + + + Confirm the send action + + + S&end + + + + :/icons/send:/icons/send + + + true + + + + + + + + + + + + diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui new file mode 100644 index 0000000..baac142 --- /dev/null +++ b/src/qt/forms/sendcoinsentry.ui @@ -0,0 +1,169 @@ + + + SendCoinsEntry + + + + 0 + 0 + 729 + 117 + + + + Form + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Pay &To: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + payTo + + + + + + + 0 + + + + + The address to send the payment to (e.g. B3rNga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + + + 34 + + + + + + + Choose address from address book + + + + + + + :/icons/address-book:/icons/address-book + + + Alt+A + + + + + + + Paste address from clipboard + + + + + + + :/icons/editpaste:/icons/editpaste + + + Alt+P + + + + + + + Remove this recipient + + + + + + + :/icons/remove:/icons/remove + + + + + + + + + &Label: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + addAsLabel + + + + + + + 0 + + + + + true + + + Enter a label for this address to add it to your address book + + + + + + + + + A&mount: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + payAmount + + + + + + + + + + + QValidatedLineEdit + QLineEdit +
qvalidatedlineedit.h
+
+ + BitcoinAmountField + QLineEdit +
bitcoinamountfield.h
+ 1 +
+
+ + + + +
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui new file mode 100644 index 0000000..ec8cac5 --- /dev/null +++ b/src/qt/forms/signverifymessagedialog.ui @@ -0,0 +1,386 @@ + + + SignVerifyMessageDialog + + + + 0 + 0 + 700 + 380 + + + + Signatures - Sign / Verify a Message + + + true + + + + + + 0 + + + + &Sign Message + + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + Qt::PlainText + + + true + + + + + + + 0 + + + + + The address to sign the message with (e.g. B3rNga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + + + 34 + + + + + + + Choose an address from the address book + + + + + + + :/icons/address-book:/icons/address-book + + + Alt+A + + + false + + + + + + + Paste address from clipboard + + + + + + + :/icons/editpaste:/icons/editpaste + + + Alt+P + + + false + + + + + + + + + Enter the message you want to sign here + + + + + + + 0 + + + + + + true + + + + true + + + + + + + Copy the current signature to the system clipboard + + + + + + + :/icons/editcopy:/icons/editcopy + + + false + + + + + + + + + + + Sign the message to prove you own this SoleCoin address + + + &Sign Message + + + + :/icons/edit:/icons/edit + + + false + + + + + + + Reset all sign message fields + + + Clear &All + + + + :/icons/remove:/icons/remove + + + false + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + 75 + true + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + + + &Verify Message + + + + + + Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + + + Qt::PlainText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + 0 + + + + + The address the message was signed with (e.g. B3rNga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + + + 34 + + + + + + + Choose an address from the address book + + + + + + + :/icons/address-book:/icons/address-book + + + Alt+A + + + false + + + + + + + + + + + + + + + + + Verify the message to ensure it was signed with the specified SoleCoin address + + + &Verify Message + + + + :/icons/transaction_0:/icons/transaction_0 + + + false + + + + + + + Reset all verify message fields + + + Clear &All + + + + :/icons/remove:/icons/remove + + + false + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + 75 + true + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + + + + + + + QValidatedLineEdit + QLineEdit +
qvalidatedlineedit.h
+
+
+ + + + +
diff --git a/src/qt/forms/statisticspage.ui b/src/qt/forms/statisticspage.ui new file mode 100644 index 0000000..0a03780 --- /dev/null +++ b/src/qt/forms/statisticspage.ui @@ -0,0 +1,512 @@ + + + StatisticsPage + + + Qt::NonModal + + + + 0 + 0 + 724 + 529 + + + + Digging + + + + QLayout::SetMaximumSize + + + + + + + + QFormLayout::FieldsStayAtSizeHint + + + 90 + + + 18 + + + 0 + + + + + <html><head/><body><p>Block Height:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + + + + 00000 + + + + + + + <html><head/><body><p>PoW Block Reward:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + + + + 250 + + + + + + + <html><head/><body><p>PoW Difficulty:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + + + + 0.0002 + + + + + + + <html><head/><body><p>PoS Difficulty:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + + + + 0.0002 + + + + + + + <html><head/><body><p>Net Hashrate:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + + + + 0 MH/s + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Last Block Time:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + + + + 0 + + + + + + + <html><head/><body><p>Connections:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + + + + 0 + + + + + + + <html><head/><body><p>Total BERN Volume:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + + + + 250 + + + + + + + <html><head/><body><p>Your Stake Weight:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + 50 + false + + + + 0 + + + + + + + <html><head/><body><p>Network Stake Weight:</p></body></html> + + + + + + + + Open Sans,sans-serif + 10 + 50 + false + + + + 0 + + + + + + + + + 7 + + + + + + 0 + 30 + + + + + Open Sans,sans-serif + + + + <html><head/><body><p><span style=" font-size:18px; font-weight:600; color:#464747;">BERN Network Statistics</span></p></body></html> + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + true + + + + 0 + 0 + + + + + 350 + 450 + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + 10 + 60 + 241 + 31 + + + + <html><head/><body><p><span style=" font-size:12pt; font-weight:600;color:#464747;">Mining Phases</span></p><p><br/></p></body></html> + + + + + + 10 + 100 + 361 + 41 + + + + + 10 + + + + phaselbl1 + + + + + + 10 + 160 + 361 + 41 + + + + + 10 + + + + phaselbl2 + + + + + + 10 + 220 + 361 + 41 + + + + + 10 + + + + phaselbl3 + + + + + + 10 + 280 + 361 + 41 + + + + + 10 + + + + phaselbl4 + + + + + + 10 + 330 + 361 + 41 + + + + + 10 + + + + phaselbl5 + + + + + + 30 + 370 + 251 + 41 + + + + + 7 + + + + <html><head/><body><p>* PoS will always be 10% Annual. <br/>24 hour minimum, 4 year maximum stake age.</p></body></html> + + + + + + 130 + 50 + 171 + 41 + + + + + 9 + + + + <html><head/><body><p><b>(Bold</b> denotes current phase.)</p></body></html> + + + + + + + + + 0 + 0 + + + + + 225 + 35 + + + + + 75 + true + + + + background-color:#333333; color:#cecece; + + + Update Statistics + + + false + + + + + + + + + diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/transactiondescdialog.ui new file mode 100644 index 0000000..b38dffc --- /dev/null +++ b/src/qt/forms/transactiondescdialog.ui @@ -0,0 +1,74 @@ + + + TransactionDescDialog + + + + 0 + 0 + 620 + 250 + + + + Transaction details + + + + + + This pane shows a detailed description of the transaction + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + TransactionDescDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + TransactionDescDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h new file mode 100644 index 0000000..405ba39 --- /dev/null +++ b/src/qt/guiconstants.h @@ -0,0 +1,34 @@ +#ifndef GUICONSTANTS_H +#define GUICONSTANTS_H + +/* Milliseconds between model updates */ +static const int MODEL_UPDATE_DELAY = 500; + +/* AskPassphraseDialog -- Maximum passphrase length */ +static const int MAX_PASSPHRASE_SIZE = 1024; + +/* BitcoinGUI -- Size of icons in status bar */ +static const int STATUSBAR_ICONSIZE = 16; + +/* Invalid field background style */ +#define STYLE_INVALID "background:#FF8080" + +/* Transaction list -- unconfirmed transaction */ +#define COLOR_UNCONFIRMED QColor(128, 128, 128) +/* Transaction list -- negative amount */ +#define COLOR_NEGATIVE QColor(255, 0, 0) +/* Transaction list -- bare address (without label) */ +#define COLOR_BAREADDRESS QColor(140, 140, 140) + +/* Tooltips longer than this (in characters) are converted into rich text, + so that they can be word-wrapped. + */ +static const int TOOLTIP_WRAP_THRESHOLD = 80; + +/* Maximum allowed URI length */ +static const int MAX_URI_LENGTH = 255; + +/* QRCodeDialog -- size of exported QR Code image */ +#define EXPORT_IMAGE_SIZE 256 + +#endif // GUICONSTANTS_H diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp new file mode 100644 index 0000000..0185798 --- /dev/null +++ b/src/qt/guiutil.cpp @@ -0,0 +1,481 @@ +#include "guiutil.h" +#include "bitcoinaddressvalidator.h" +#include "walletmodel.h" +#include "bitcoinunits.h" +#include "util.h" +#include "init.h" + +#include +#include +#include +#include +#include +#if QT_VERSION >= 0x050000 +#include +#else +#include +#endif +#include // for Qt::mightBeRichText +#include +#include +#include +#include +#if QT_VERSION > 0x050000 +#include +#endif +#include +#include + +#include +#include + +#ifdef WIN32 +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include "shlwapi.h" +#include "shlobj.h" +#include "shellapi.h" +#endif + +namespace GUIUtil { + +QString dateTimeStr(const QDateTime &date) +{ + return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") + date.toString("hh:mm"); +} + +QString dateTimeStr(qint64 nTime) +{ + return dateTimeStr(QDateTime::fromTime_t((qint32)nTime)); +} + +QFont bitcoinAddressFont() +{ + QFont font("Monospace"); + font.setStyleHint(QFont::TypeWriter); + return font; +} + +void setupAddressWidget(QLineEdit *widget, QWidget *parent) +{ + widget->setMaxLength(BitcoinAddressValidator::MaxAddressLength); + widget->setValidator(new BitcoinAddressValidator(parent)); + widget->setFont(bitcoinAddressFont()); +} + +void setupAmountWidget(QLineEdit *widget, QWidget *parent) +{ + QDoubleValidator *amountValidator = new QDoubleValidator(parent); + amountValidator->setDecimals(8); + amountValidator->setBottom(0.0); + widget->setValidator(amountValidator); + widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter); +} + +bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) +{ + if(uri.scheme() != QString("bitcoin")) + return false; + + SendCoinsRecipient rv; + rv.address = uri.path(); + rv.amount = 0; +#if QT_VERSION < 0x050000 + QList > items = uri.queryItems(); +#else + QUrlQuery uriQuery(uri); + QList > items = uriQuery.queryItems(); +#endif + for (QList >::iterator i = items.begin(); i != items.end(); i++) + { + bool fShouldReturnFalse = false; + if (i->first.startsWith("req-")) + { + i->first.remove(0, 4); + fShouldReturnFalse = true; + } + + if (i->first == "label") + { + rv.label = i->second; + fShouldReturnFalse = false; + } + else if (i->first == "amount") + { + if(!i->second.isEmpty()) + { + if(!BitcoinUnits::parse(BitcoinUnits::BTC, i->second, &rv.amount)) + { + return false; + } + } + fShouldReturnFalse = false; + } + + if (fShouldReturnFalse) + return false; + } + if(out) + { + *out = rv; + } + return true; +} + +bool parseBitcoinURI(QString uri, SendCoinsRecipient *out) +{ + // Convert bitcoin:// to bitcoin: + // + // Cannot handle this later, because bitcoin:// will cause Qt to see the part after // as host, + // which will lower-case it (and thus invalidate the address). + if(uri.startsWith("bitcoin://")) + { + uri.replace(0, 10, "bitcoin:"); + } + QUrl uriInstance(uri); + return parseBitcoinURI(uriInstance, out); +} + +QString HtmlEscape(const QString& str, bool fMultiLine) +{ +#if QT_VERSION < 0x050000 + QString escaped = Qt::escape(str); +#else + QString escaped = str.toHtmlEscaped(); +#endif + if(fMultiLine) + { + escaped = escaped.replace("\n", "
\n"); + } + return escaped; +} + +QString HtmlEscape(const std::string& str, bool fMultiLine) +{ + return HtmlEscape(QString::fromStdString(str), fMultiLine); +} + +void copyEntryData(QAbstractItemView *view, int column, int role) +{ + if(!view || !view->selectionModel()) + return; + QModelIndexList selection = view->selectionModel()->selectedRows(column); + + if(!selection.isEmpty()) + { + // Copy first item + QApplication::clipboard()->setText(selection.at(0).data(role).toString()); + } +} + +QString getSaveFileName(QWidget *parent, const QString &caption, + const QString &dir, + const QString &filter, + QString *selectedSuffixOut) +{ + QString selectedFilter; + QString myDir; + if(dir.isEmpty()) // Default to user documents location + { +#if QT_VERSION < 0x050000 + myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); +#else + myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); +#endif + } + else + { + myDir = dir; + } + QString result = QFileDialog::getSaveFileName(parent, caption, myDir, filter, &selectedFilter); + + /* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */ + QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]"); + QString selectedSuffix; + if(filter_re.exactMatch(selectedFilter)) + { + selectedSuffix = filter_re.cap(1); + } + + /* Add suffix if needed */ + QFileInfo info(result); + if(!result.isEmpty()) + { + if(info.suffix().isEmpty() && !selectedSuffix.isEmpty()) + { + /* No suffix specified, add selected suffix */ + if(!result.endsWith(".")) + result.append("."); + result.append(selectedSuffix); + } + } + + /* Return selected suffix if asked to */ + if(selectedSuffixOut) + { + *selectedSuffixOut = selectedSuffix; + } + return result; +} + +Qt::ConnectionType blockingGUIThreadConnection() +{ + if(QThread::currentThread() != QCoreApplication::instance()->thread()) + { + return Qt::BlockingQueuedConnection; + } + else + { + return Qt::DirectConnection; + } +} + +bool checkPoint(const QPoint &p, const QWidget *w) +{ + QWidget *atW = qApp->widgetAt(w->mapToGlobal(p)); + if (!atW) return false; + return atW->topLevelWidget() == w; +} + +bool isObscured(QWidget *w) +{ + return !(checkPoint(QPoint(0, 0), w) + && checkPoint(QPoint(w->width() - 1, 0), w) + && checkPoint(QPoint(0, w->height() - 1), w) + && checkPoint(QPoint(w->width() - 1, w->height() - 1), w) + && checkPoint(QPoint(w->width() / 2, w->height() / 2), w)); +} + +void openDebugLogfile() +{ + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + + /* Open debug.log with the associated application */ + if (boost::filesystem::exists(pathDebug)) +#if QT_VERSION < 0x050000 + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(pathDebug.string()))); +#else + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(pathDebug.string()))); +#endif +} + +ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) : + QObject(parent), size_threshold(size_threshold) +{ + +} + +bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt) +{ + if(evt->type() == QEvent::ToolTipChange) + { + QWidget *widget = static_cast(obj); + QString tooltip = widget->toolTip(); + if(tooltip.size() > size_threshold && !tooltip.startsWith("") && !Qt::mightBeRichText(tooltip)) + { + // Prefix to make sure Qt detects this as rich text + // Escape the current message as HTML and replace \n by
+ tooltip = "" + HtmlEscape(tooltip, true); + widget->setToolTip(tooltip); + return true; + } + } + return QObject::eventFilter(obj, evt); +} + +#ifdef WIN32 +boost::filesystem::path static StartupShortcutPath() +{ + return GetSpecialFolderPath(CSIDL_STARTUP) / "BERN.lnk"; +} + +bool GetStartOnSystemStartup() +{ + // check for Bitcoin.lnk + return boost::filesystem::exists(StartupShortcutPath()); +} + +bool SetStartOnSystemStartup(bool fAutoStart) +{ + // If the shortcut exists already, remove it for updating + boost::filesystem::remove(StartupShortcutPath()); + + if (fAutoStart) + { + CoInitialize(NULL); + + // Get a pointer to the IShellLink interface. + IShellLink* psl = NULL; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); + + if (SUCCEEDED(hres)) + { + // Get the current executable path + TCHAR pszExePath[MAX_PATH]; + GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); + + TCHAR pszArgs[5] = TEXT("-min"); + + // Set the path to the shortcut target + psl->SetPath(pszExePath); + PathRemoveFileSpec(pszExePath); + psl->SetWorkingDirectory(pszExePath); + psl->SetShowCmd(SW_SHOWMINNOACTIVE); + psl->SetArguments(pszArgs); + + // Query IShellLink for the IPersistFile interface for + // saving the shortcut in persistent storage. + IPersistFile* ppf = NULL; + hres = psl->QueryInterface(IID_IPersistFile, + reinterpret_cast(&ppf)); + if (SUCCEEDED(hres)) + { + WCHAR pwsz[MAX_PATH]; + // Ensure that the string is ANSI. + MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH); + // Save the link by calling IPersistFile::Save. + hres = ppf->Save(pwsz, TRUE); + ppf->Release(); + psl->Release(); + CoUninitialize(); + return true; + } + psl->Release(); + } + CoUninitialize(); + return false; + } + return true; +} + +#elif defined(LINUX) + +// Follow the Desktop Application Autostart Spec: +// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html + +boost::filesystem::path static GetAutostartDir() +{ + namespace fs = boost::filesystem; + + char* pszConfigHome = getenv("XDG_CONFIG_HOME"); + if (pszConfigHome) return fs::path(pszConfigHome) / "autostart"; + char* pszHome = getenv("HOME"); + if (pszHome) return fs::path(pszHome) / ".config" / "autostart"; + return fs::path(); +} + +boost::filesystem::path static GetAutostartFilePath() +{ + return GetAutostartDir() / "BERN.desktop"; +} + +bool GetStartOnSystemStartup() +{ + boost::filesystem::ifstream optionFile(GetAutostartFilePath()); + if (!optionFile.good()) + return false; + // Scan through file for "Hidden=true": + std::string line; + while (!optionFile.eof()) + { + getline(optionFile, line); + if (line.find("Hidden") != std::string::npos && + line.find("true") != std::string::npos) + return false; + } + optionFile.close(); + + return true; +} + +bool SetStartOnSystemStartup(bool fAutoStart) +{ + if (!fAutoStart) + boost::filesystem::remove(GetAutostartFilePath()); + else + { + char pszExePath[MAX_PATH+1]; + memset(pszExePath, 0, sizeof(pszExePath)); + if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1) + return false; + + boost::filesystem::create_directories(GetAutostartDir()); + + boost::filesystem::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out|std::ios_base::trunc); + if (!optionFile.good()) + return false; + // Write a bitcoin.desktop file to the autostart directory: + optionFile << "[Desktop Entry]\n"; + optionFile << "Type=Application\n"; + optionFile << "Name=BERN\n"; + optionFile << "Exec=" << pszExePath << " -min\n"; + optionFile << "Terminal=false\n"; + optionFile << "Hidden=false\n"; + optionFile.close(); + } + return true; +} +#else + +// TODO: OSX startup stuff; see: +// https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html + +bool GetStartOnSystemStartup() { return false; } +bool SetStartOnSystemStartup(bool fAutoStart) { return false; } + +#endif + +HelpMessageBox::HelpMessageBox(QWidget *parent) : + QMessageBox(parent) +{ + header = tr("BERN-Qt") + " " + tr("version") + " " + + QString::fromStdString(FormatFullVersion()) + "\n\n" + + tr("Usage:") + "\n" + + " BERN-qt [" + tr("command-line options") + "] " + "\n"; + + coreOptions = QString::fromStdString(HelpMessage()); + + uiOptions = tr("UI options") + ":\n" + + " -lang= " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" + + " -min " + tr("Start minimized") + "\n" + + " -splash " + tr("Show splash screen on startup (default: 1)") + "\n"; + + setWindowTitle(tr("BERN-Qt")); + setTextFormat(Qt::PlainText); + // setMinimumWidth is ignored for QMessageBox so put in non-breaking spaces to make it wider. + setText(header + QString(QChar(0x2003)).repeated(50)); + setDetailedText(coreOptions + "\n" + uiOptions); +} + +void HelpMessageBox::printToConsole() +{ + // On other operating systems, the expected action is to print the message to the console. + QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions; + fprintf(stdout, "%s", strUsage.toStdString().c_str()); +} + +void HelpMessageBox::showOrPrint() +{ +#if defined(WIN32) + // On Windows, show a message box, as there is no stderr/stdout in windowed applications + exec(); +#else + // On other operating systems, print help text to console + printToConsole(); +#endif +} + +} // namespace GUIUtil + diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h new file mode 100644 index 0000000..db100bd --- /dev/null +++ b/src/qt/guiutil.h @@ -0,0 +1,120 @@ +#ifndef GUIUTIL_H +#define GUIUTIL_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QFont; +class QLineEdit; +class QWidget; +class QDateTime; +class QUrl; +class QAbstractItemView; +QT_END_NAMESPACE +class SendCoinsRecipient; + +/** Utility functions used by the Bitcoin Qt UI. + */ +namespace GUIUtil +{ + // Create human-readable string from date + QString dateTimeStr(const QDateTime &datetime); + QString dateTimeStr(qint64 nTime); + + // Render Bitcoin addresses in monospace font + QFont bitcoinAddressFont(); + + // Set up widgets for address and amounts + void setupAddressWidget(QLineEdit *widget, QWidget *parent); + void setupAmountWidget(QLineEdit *widget, QWidget *parent); + + // Parse "bitcoin:" URI into recipient object, return true on successful parsing + // See Bitcoin URI definition discussion here: https://bitcointalk.org/index.php?topic=33490.0 + bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out); + bool parseBitcoinURI(QString uri, SendCoinsRecipient *out); + + // HTML escaping for rich text controls + QString HtmlEscape(const QString& str, bool fMultiLine=false); + QString HtmlEscape(const std::string& str, bool fMultiLine=false); + + /** Copy a field of the currently selected entry of a view to the clipboard. Does nothing if nothing + is selected. + @param[in] column Data column to extract from the model + @param[in] role Data role to extract from the model + @see TransactionView::copyLabel, TransactionView::copyAmount, TransactionView::copyAddress + */ + void copyEntryData(QAbstractItemView *view, int column, int role=Qt::EditRole); + + /** Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix + when no suffix is provided by the user. + + @param[in] parent Parent window (or 0) + @param[in] caption Window caption (or empty, for default) + @param[in] dir Starting directory (or empty, to default to documents directory) + @param[in] filter Filter specification such as "Comma Separated Files (*.csv)" + @param[out] selectedSuffixOut Pointer to return the suffix (file type) that was selected (or 0). + Can be useful when choosing the save file format based on suffix. + */ + QString getSaveFileName(QWidget *parent=0, const QString &caption=QString(), + const QString &dir=QString(), const QString &filter=QString(), + QString *selectedSuffixOut=0); + + /** Get connection type to call object slot in GUI thread with invokeMethod. The call will be blocking. + + @returns If called from the GUI thread, return a Qt::DirectConnection. + If called from another thread, return a Qt::BlockingQueuedConnection. + */ + Qt::ConnectionType blockingGUIThreadConnection(); + + // Determine whether a widget is hidden behind other windows + bool isObscured(QWidget *w); + + // Open debug.log + void openDebugLogfile(); + + /** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text + representation if needed. This assures that Qt can word-wrap long tooltip messages. + Tooltips longer than the provided size threshold (in characters) are wrapped. + */ + class ToolTipToRichTextFilter : public QObject + { + Q_OBJECT + + public: + explicit ToolTipToRichTextFilter(int size_threshold, QObject *parent = 0); + + protected: + bool eventFilter(QObject *obj, QEvent *evt); + + private: + int size_threshold; + }; + + bool GetStartOnSystemStartup(); + bool SetStartOnSystemStartup(bool fAutoStart); + + /** Help message for Bitcoin-Qt, shown with --help. */ + class HelpMessageBox : public QMessageBox + { + Q_OBJECT + + public: + HelpMessageBox(QWidget *parent = 0); + + /** Show message box or print help message to standard output, based on operating system. */ + void showOrPrint(); + + /** Print help message to console */ + void printToConsole(); + + private: + QString header; + QString coreOptions; + QString uiOptions; + }; + +} // namespace GUIUtil + +#endif // GUIUTIL_H diff --git a/src/qt/httpsocket.cpp b/src/qt/httpsocket.cpp new file mode 100644 index 0000000..b1d87f2 --- /dev/null +++ b/src/qt/httpsocket.cpp @@ -0,0 +1,46 @@ +#include "httpsocket.h" +#include + +httpsocket::httpsocket(QObject *parent) : + QObject(parent) +{ + response = ""; + useProxy = false; +} + +void httpsocket::getUrl(QString url) +{ + if(this->useProxy==true){ + QNetworkProxy proxy; + proxy.setType(QNetworkProxy::HttpProxy); + proxy.setHostName(this->proxyAddress);//"200.50.166.43" + proxy.setPort(this->proxyPort);//8080 + //proxy.setUser("username"); + //proxy.setPassword("password"); + QNetworkProxy::setApplicationProxy(proxy); + } + + qDebug()<< "Connecting..."; + QNetworkAccessManager *manager = new QNetworkAccessManager(this); + connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); + + manager->get(QNetworkRequest(QUrl(url))); +} + +void httpsocket::replyFinished(QNetworkReply *reply) +{ + if(reply->error()==QNetworkReply::NoError){ + qDebug() << "Response"; + if(reply->isOpen()){ + QString response = reply->readAll(); + this->response = response;//the contents of response = response. + reply->close(); + //qDebug()<<"Finished With Socket Data..."; + } + }else{ + qDebug()<<"Error Occured"; + this->response = "Error"; + this->error = reply->errorString(); + } + emit finished(); +} diff --git a/src/qt/httpsocket.h b/src/qt/httpsocket.h new file mode 100644 index 0000000..f4562d6 --- /dev/null +++ b/src/qt/httpsocket.h @@ -0,0 +1,29 @@ +#ifndef HTTPSOCKET_H +#define HTTPSOCKET_H + +#include +#include +#include +#include +#include + +#include + +class httpsocket : public QObject +{ + Q_OBJECT +public: + explicit httpsocket(QObject *parent = 0); + QString response; + QString error; + QString proxyAddress; + int proxyPort; + bool useProxy; +signals: + void finished(); +public slots: + void getUrl(QString url); + void replyFinished(QNetworkReply *reply); +}; + +#endif // HTTPSOCKET_H diff --git a/src/qt/locale/bitcoin_en.qm b/src/qt/locale/bitcoin_en.qm new file mode 100644 index 0000000..c137951 Binary files /dev/null and b/src/qt/locale/bitcoin_en.qm differ diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts new file mode 100644 index 0000000..b269a1a --- /dev/null +++ b/src/qt/locale/bitcoin_en.ts @@ -0,0 +1,2750 @@ + + + +UTF-8 + + AboutDialog + + + About BERN + About BERN + + + + <b>BERN</b> version + <b>BERN</b> version + + + + Copyright © 2009-2016 The BERN developer + Copyright © 2009-2016 The BERN developer + + + + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + AddressBookPage + + + Address Book + Address Book + + + + Double-click to edit address or label + Double-click to edit address or label + + + + Create a new address + Create a new address + + + + Copy the currently selected address to the system clipboard + Copy the currently selected address to the system clipboard + + + + &New Address + &New Address + + + + These are your BERN addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + These are your BERN addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + + + + &Copy Address + &Copy Address + + + + Show &QR Code + Show &QR Code + + + + Sign a message to prove you own a BERN address + Sign a message to prove you own a BERN address + + + + Sign &Message + + + + + Delete the currently selected address from the list + + + + + Verify a message to ensure it was signed with a specified BERN address + Verify a message to ensure it was signed with a specified BERN address + + + + &Verify Message + &Verify Message + + + + &Delete + &Delete + + + + Copy &Label + Copy &Label + + + + &Edit + &Edit + + + + Export Address Book Data + Export Address Book Data + + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + + Error exporting + Error exporting + + + + Could not write to file %1. + Could not write to file %1. + + + + AddressTableModel + + + Label + Label + + + + Address + Address + + + + (no label) + (no label) + + + + AskPassphraseDialog + + + Passphrase Dialog + Passphrase Dialog + + + + Enter passphrase + Enter passphrase + + + + New passphrase + New passphrase + + + + Repeat new passphrase + Repeat new passphrase + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + + + + Encrypt wallet + Encrypt wallet + + + + This operation needs your wallet passphrase to unlock the wallet. + This operation needs your wallet passphrase to unlock the wallet. + + + + Unlock wallet + Unlock wallet + + + + This operation needs your wallet passphrase to decrypt the wallet. + This operation needs your wallet passphrase to decrypt the wallet. + + + + Decrypt wallet + Decrypt wallet + + + + Change passphrase + Change passphrase + + + + Enter the old and new passphrase to the wallet. + Enter the old and new passphrase to the wallet. + + + + Confirm wallet encryption + Confirm wallet encryption + + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR COINS</b>! + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR COINS</b>! + + + + Are you sure you wish to encrypt your wallet? + Are you sure you wish to encrypt your wallet? + + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + + + + + + Warning: The Caps Lock key is on! + Warning: The Caps Lock key is on! + + + + + Wallet encrypted + Wallet encrypted + + + + BERN will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your coins from being stolen by malware infecting your computer. + BERN will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your coins from being stolen by malware infecting your computer. + + + + + + + Wallet encryption failed + Wallet encryption failed + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + + + The supplied passphrases do not match. + The supplied passphrases do not match. + + + + Wallet unlock failed + Wallet unlock failed + + + + + + The passphrase entered for the wallet decryption was incorrect. + The passphrase entered for the wallet decryption was incorrect. + + + + Wallet decryption failed + Wallet decryption failed + + + + Wallet passphrase was successfully changed. + Wallet passphrase was successfully changed. + + + + BitcoinGUI + + + Sign &message... + Sign &message... + + + + Synchronizing with network... + Synchronizing with network... + + + + &Overview + &Overview + + + + Show general overview of wallet + Show general overview of wallet + + + + &Ledger + &Ledger + + + + Browse transaction history + Browse transaction history + + + + &Addresses + &Addresses + + + + Edit the list of stored addresses and labels + Edit the list of stored addresses and labels + + + + &Receive + &Receive + + + + Show the list of addresses for receiving payments + Show the list of addresses for receiving payments + + + + &Send + &Send + + + + E&xit + E&xit + + + + Quit application + Quit application + + + + Show information about BERN + Show information about BERN + + + + About &Qt + About &Qt + + + + Show information about Qt + Show information about Qt + + + + &Options... + &Options... + + + + &Encrypt Wallet... + &Encrypt Wallet... + + + + &Backup Wallet... + &Backup Wallet... + + + + &Change Passphrase... + &Change Passphrase... + + + + ~%n block(s) remaining + + ~%n block remaining + ~%n blocks remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + &Export... + &Export... + + + + Send to a BERN address + Send to a BERN address + + + + Modify configuration options for BERN + Modify configuration options for BERN + + + + Export the data in the current tab to a file + Export the data in the current tab to a file + + + + Encrypt or decrypt wallet + Encrypt or decrypt wallet + + + + Backup wallet to another location + Backup wallet to another location + + + + Change the passphrase used for wallet encryption + Change the passphrase used for wallet encryption + + + + &Debug Window + &Debug Window + + + + Open debugging and diagnostic console + Open debugging and diagnostic console + + + + &Verify message... + &Verify message... + + + + BERN + BERN + + + + Wallet + Wallet + + + + &About BERN + &About BERN + + + + &Show / Hide + &Show / Hide + + + + &File + &File + + + + &Settings + &Settings + + + + &Help + &Help + + + + Tabs toolbar + Tabs toolbar + + + + Actions toolbar + Actions toolbar + + + + + [testnet] + [testnet] + + + + + BERN Wallet + BERN Wallet + + + + %n active connection(s) to the BERN network + + %n active connection to the BERN network + %n active connections to the BERN network + + + + + Downloaded %1 blocks of transaction history. + Downloaded %1 blocks of transaction history. + + + + %n second(s) ago + + %n second ago + %n seconds ago + + + + + %n minute(s) ago + + %n minute ago + %n minutes ago + + + + + %n hour(s) ago + + %n hour ago + %n hours ago + + + + + %n day(s) ago + + %n day ago + %n days ago + + + + + Up to date + Up to date + + + + Catching up... + Catching up... + + + + Last received block was generated %1. + Last received block was generated %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + + + + + Confirm transaction fee + Confirm transaction fee + + + + Sent transaction + Sent transaction + + + + Incoming transaction + Incoming transaction + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + + URI handling + URI handling + + + + + URI can not be parsed! This can be caused by an invalid BERN address or malformed URI parameters. + URI can not be parsed! This can be caused by an invalid BERN address or malformed URI parameters. + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Wallet is <b>encrypted</b> and currently <b>locked</b> + + + + Backup Wallet + Backup Wallet + + + + Wallet Data (*.dat) + Wallet Data (*.dat) + + + + Backup Failed + Backup Failed + + + + There was an error trying to save the wallet data to the new location. + There was an error trying to save the wallet data to the new location. + + + + A fatal error occurred. BERN can no longer continue safely and will quit. + A fatal error occurred. BERN can no longer continue safely and will quit. + + + + ClientModel + + + Network Alert + Network Alert + + + + EditAddressDialog + + + Edit Address + Edit Address + + + + &Label + &Label + + + + The label associated with this address book entry + The label associated with this address book entry + + + + &Address + &Address + + + + The address associated with this address book entry. This can only be modified for sending addresses. + The address associated with this address book entry. This can only be modified for sending addresses. + + + + New receiving address + New receiving address + + + + New sending address + New sending address + + + + Edit receiving address + Edit receiving address + + + + Edit sending address + Edit sending address + + + + The entered address "%1" is already in the address book. + The entered address "%1" is already in the address book. + + + + The entered address "%1" is not a valid BERN address. + The entered address "%1" is not a valid BERN address. + + + + Could not unlock wallet. + Could not unlock wallet. + + + + New key generation failed. + New key generation failed. + + + + GUIUtil::HelpMessageBox + + + + BERN-Qt + BERN-Qt + + + + version + version + + + + Usage: + Usage: + + + + command-line options + command-line options + + + + UI options + UI options + + + + Set language, for example "de_DE" (default: system locale) + Set language, for example "de_DE" (default: system locale) + + + + Start minimized + Start minimized + + + + Show splash screen on startup (default: 1) + Show splash screen on startup (default: 1) + + + + OptionsDialog + + + Options + Options + + + + &Main + &Main + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + Pay transaction &fee + Pay transaction &fee + + + + Automatically start BERN after logging in to the system. + Automatically start BERN after logging in to the system. + + + + &Start BERN on system login + &Start BERN on system login + + + + Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached. + Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached. + + + + &Detach databases at shutdown + &Detach databases at shutdown + + + + &Network + &Network + + + + Automatically open the BERN client port on the router. This only works when your router supports UPnP and it is enabled. + Automatically open the BERN client port on the router. This only works when your router supports UPnP and it is enabled. + + + + Map port using &UPnP + Map port using &UPnP + + + + Connect to the BERN network through a SOCKS proxy (e.g. when connecting through Tor). + Connect to the BERN network through a SOCKS proxy (e.g. when connecting through Tor). + + + + &Connect through SOCKS proxy: + &Connect through SOCKS proxy: + + + + Proxy &IP: + Proxy &IP: + + + + IP address of the proxy (e.g. 127.0.0.1) + IP address of the proxy (e.g. 127.0.0.1) + + + + &Port: + &Port: + + + + Port of the proxy (e.g. 9050) + Port of the proxy (e.g. 9050) + + + + SOCKS &Version: + SOCKS &Version: + + + + SOCKS version of the proxy (e.g. 5) + SOCKS version of the proxy (e.g. 5) + + + + &Window + &Window + + + + Show only a tray icon after minimizing the window. + Show only a tray icon after minimizing the window. + + + + &Minimize to the tray instead of the taskbar + &Minimize to the tray instead of the taskbar + + + + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. + + + + M&inimize on close + M&inimize on close + + + + &Display + &Display + + + + User Interface &language: + User Interface &language: + + + + The user interface language can be set here. This setting will take effect after restarting BERN. + The user interface language can be set here. This setting will take effect after restarting BERN. + + + + &Unit to show amounts in: + &Unit to show amounts in: + + + + Choose the default subdivision unit to show in the interface and when sending coins. + Choose the default subdivision unit to show in the interface and when sending coins. + + + + Whether to show BERN addresses in the transaction list or not. + Whether to show BERN addresses in the transaction list or not. + + + + &Display addresses in transaction list + &Display addresses in transaction list + + + + &OK + &OK + + + + &Cancel + &Cancel + + + + &Apply + &Apply + + + + default + default + + + + + Warning + Warning + + + + + This setting will take effect after restarting BERN. + This setting will take effect after restarting BERN. + + + + The supplied proxy address is invalid. + The supplied proxy address is invalid. + + + + OverviewPage + + + Form + Form + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the BERN network after a connection is established, but this process has not completed yet. + The displayed information may be out of date. Your wallet automatically synchronizes with the BERN network after a connection is established, but this process has not completed yet. + + + + Balance: + Balance: + + + + Stake: + Stake: + + + + Number of transactions: + Number of transactions: + + + + Unconfirmed: + Unconfirmed: + + + + Wallet + Wallet + + + + Immature: + Immature: + + + + Mined balance that has not yet matured + Mined balance that has not yet matured + + + + <b>Recent transactions</b> + <b>Recent transactions</b> + + + + Your current balance + Your current balance + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + + Total of coins that was staked, and do not yet count toward the current balance + Total of coins that was staked, and do not yet count toward the current balance + + + + Total number of transactions in wallet + Total number of transactions in wallet + + + + + out of sync + out of sync + + + + QRCodeDialog + + + QR Code Dialog + QR Code Dialog + + + + Request Payment + Request Payment + + + + Amount: + Amount: + + + + Label: + Label: + + + + Message: + Message: + + + + &Save As... + &Save As... + + + + Error encoding URI into QR Code. + Error encoding URI into QR Code. + + + + The entered amount is invalid, please check. + The entered amount is invalid, please check. + + + + Resulting URI too long, try to reduce the text for label / message. + Resulting URI too long, try to reduce the text for label / message. + + + + Save QR Code + Save QR Code + + + + PNG Images (*.png) + PNG Images (*.png) + + + + RPCConsole + + + Client name + Client name + + + + + + + + + + + + + N/A + N/A + + + + Client version + Client version + + + + &Information + &Information + + + + Using OpenSSL version + Using OpenSSL version + + + + Startup time + Startup time + + + + Network + Network + + + + Number of connections + Number of connections + + + + On testnet + On testnet + + + + Block chain + Block chain + + + + Current number of blocks + Current number of blocks + + + + Estimated total blocks + Estimated total blocks + + + + Last block time + Last block time + + + + &Open + &Open + + + + Command-line options + Command-line options + + + + Show the BERN-Qt help message to get a list with possible BERN command-line options. + Show the BERN-Qt help message to get a list with possible BERN command-line options. + + + + &Show + &Show + + + + &Console + &Console + + + + Build date + Build date + + + + BERN - Debug Window + BERN - Debug Window + + + + BERN Core + BERN Core + + + + Debug log file + Debug log file + + + + Open the BERN debug log file from the current data directory. This can take a few seconds for large log files. + Open the BERN debug log file from the current data directory. This can take a few seconds for large log files. + + + + Clear console + Clear console + + + + Welcome to the BERN RPC console. + Welcome to the BERN RPC console. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + Type <b>help</b> for an overview of available commands. + Type <b>help</b> for an overview of available commands. + + + + SendCoinsDialog + + + + + + + + + + Send + Send + + + + Send to multiple recipients at once + Send to multiple recipients at once + + + + Add &Recipient + + + + + Remove all transaction fields + Remove all transaction fields + + + + Clear &All + Clear &All + + + + Balance: + Balance: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Confirm the send action + + + + S&end + + + + + <b>%1</b> to %2 (%3) + <b>%1</b> to %2 (%3) + + + + Confirm send coins + Confirm send coins + + + + Are you sure you want to send %1? + Are you sure you want to send %1? + + + + and + and + + + + The recipient address is not valid, please recheck. + The recipient address is not valid, please recheck. + + + + The amount to pay must be larger than 0. + The amount to pay must be larger than 0. + + + + The amount exceeds your balance. + The amount exceeds your balance. + + + + The total exceeds your balance when the %1 transaction fee is included. + The total exceeds your balance when the %1 transaction fee is included. + + + + Duplicate address found, can only send to each address once per send operation. + Duplicate address found, can only send to each address once per send operation. + + + + Error: Transaction creation failed. + Error: Transaction creation failed. + + + + Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + + + + SendCoinsEntry + + + Form + Form + + + + A&mount: + A&mount: + + + + Pay &To: + Pay &To: + + + + + Enter a label for this address to add it to your address book + Enter a label for this address to add it to your address book + + + + &Label: + &Label: + + + + The address to send the payment to (e.g. B3rNga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + + + + + Choose address from address book + Choose address from address book + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Paste address from clipboard + + + + Alt+P + Alt+P + + + + Remove this recipient + Remove this recipient + + + + Enter a valid BERN address + Enter a valid BERN address + + + + SignVerifyMessageDialog + + + Signatures - Sign / Verify a Message + Signatures - Sign / Verify a Message + + + + + &Sign Message + &Sign Message + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + The address to sign the message with + The address to sign the message with + + + + + Choose an address from the address book + Choose an address from the address book + + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Paste address from clipboard + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Enter the message you want to sign here + + + + Copy the current signature to the system clipboard + Copy the current signature to the system clipboard + + + + Sign the message to prove you own this BERN address + Sign the message to prove you own this BERN address + + + + Reset all sign message fields + Reset all sign message fields + + + + + Clear &All + Clear &All + + + + + &Verify Message + &Verify Message + + + + Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + + + + The address the message was signed with + The address the message was signed with + + + + Verify the message to ensure it was signed with the specified BERN address + Verify the message to ensure it was signed with the specified BERN address + + + + Reset all verify message fields + Reset all verify message fields + + + + + Enter a valid BERN address + Enter a valid BERN address + + + + Click "Sign Message" to generate signature + Click "Sign Message" to generate signature + + + + Enter BERN signature + Enter BERN signature + + + + + The entered address is invalid. + The entered address is invalid. + + + + + + + Please check the address and try again. + Please check the address and try again. + + + + + The entered address does not refer to a key. + The entered address does not refer to a key. + + + + Wallet unlock was cancelled. + Wallet unlock was cancelled. + + + + Private key for the entered address is not available. + Private key for the entered address is not available. + + + + Message signing failed. + Message signing failed. + + + + Message signed. + Message signed. + + + + The signature could not be decoded. + The signature could not be decoded. + + + + + Please check the signature and try again. + Please check the signature and try again. + + + + The signature did not match the message digest. + The signature did not match the message digest. + + + + Message verification failed. + Message verification failed. + + + + Message verified. + Message verified. + + + + TransactionDesc + + + Open until %1 + Open until %1 + + + + Open for %n block(s) + + Open for %n block + Open for %n blocks + + + + + %1/offline + %1/offline + + + + %1/unconfirmed + %1/unconfirmed + + + + %1 confirmations + %1 confirmations + + + + Status + Status + + + + , broadcast through %n node(s) + + , broadcast through %n node + , broadcast through %n nodes + + + + + Date + Date + + + + Source + Source + + + + Generated + Generated + + + + + From + From + + + + + + To + To + + + + + own address + own address + + + + label + label + + + + + + + + Credit + Credit + + + + matures in %n more block(s) + + matures in %n more block + matures in %n more blocks + + + + + not accepted + not accepted + + + + + + + Debit + Debit + + + + Transaction fee + Transaction fee + + + + Net amount + Net amount + + + + Message + Message + + + + Comment + Comment + + + + Transaction ID + Transaction ID + + + + Generated coins must mature 520 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. + Generated coins must mature 520 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. + + + + Staked coins must wait 520 blocks before they can return to balance and be spent. When you generated this proof-of-stake block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be a valid stake. This may occasionally happen if another node generates a proof-of-stake block within a few seconds of yours. + Staked coins must wait 520 blocks before they can return to balance and be spent. When you generated this proof-of-stake block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be a valid stake. This may occasionally happen if another node generates a proof-of-stake block within a few seconds of yours. + + + + Debug information + Debug information + + + + Transaction + Transaction + + + + Inputs + Inputs + + + + Amount + Amount + + + + true + true + + + + false + false + + + + , has not been successfully broadcast yet + , has not been successfully broadcast yet + + + + unknown + unknown + + + + TransactionDescDialog + + + Transaction details + Transaction details + + + + This pane shows a detailed description of the transaction + This pane shows a detailed description of the transaction + + + + TransactionTableModel + + + Date + Date + + + + Type + Type + + + + Address + Address + + + + Amount + Amount + + + + Open for %n block(s) + + Open for %n block + Open for %n blocks + + + + + Open until %1 + Open until %1 + + + + Offline (%1 confirmations) + Offline (%1 confirmations) + + + + Unconfirmed (%1 of %2 confirmations) + Unconfirmed (%1 of %2 confirmations) + + + + Confirmed (%1 confirmations) + Confirmed (%1 confirmations) + + + + Mined balance will be available when it matures in %n more block(s) + + Mined balance will be available when it matures in %n more block + Mined balance will be available when it matures in %n more blocks + + + + + This block was not received by any other nodes and will probably not be accepted! + This block was not received by any other nodes and will probably not be accepted! + + + + Generated but not accepted + Generated but not accepted + + + + Received with + Received with + + + + Received from + Received from + + + + Sent to + Sent to + + + + Payment to yourself + Payment to yourself + + + + Mined + Mined + + + + Minted + Minted + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + Transaction status. Hover over this field to show number of confirmations. + + + + Date and time that the transaction was received. + Date and time that the transaction was received. + + + + Type of transaction. + Type of transaction. + + + + Destination address of transaction. + Destination address of transaction. + + + + Amount removed from or added to balance. + Amount removed from or added to balance. + + + + TransactionView + + + + All + All + + + + Today + Today + + + + This week + This week + + + + This month + This month + + + + Last month + Last month + + + + This year + This year + + + + Range... + Range... + + + + Received with + Received with + + + + Sent to + Sent to + + + + To yourself + To yourself + + + + Mined + Mined + + + + Minted + Minted + + + + Other + Other + + + + Enter address or label to search + Enter address or label to search + + + + Min amount + Min amount + + + + Copy address + Copy address + + + + Copy label + Copy label + + + + Copy amount + Copy amount + + + + Edit label + Edit label + + + + Show transaction details + Show transaction details + + + + Export Transaction Data + Export Transaction Data + + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + + Confirmed + Confirmed + + + + Date + Date + + + + Type + Type + + + + Label + Label + + + + Address + Address + + + + Amount + Amount + + + + ID + ID + + + + Error exporting + Error exporting + + + + Could not write to file %1. + Could not write to file %1. + + + + Range: + Range: + + + + to + to + + + + WalletModel + + + Sending... + Sending... + + + + bitcoin-core + + + BERN version + BERN version + + + + Usage: + Usage: + + + + Send command to -server or bitcoind + Send command to -server or bitcoind + + + + List commands + List commands + + + + Get help for a command + Get help for a command + + + + Options: + Options: + + + + Specify configuration file (default: BERN.conf) + Specify configuration file (default: BERN.conf) + + + + Specify pid file (default: BERNd.pid) + Specify pid file (default: BERNd.pid) + + + + Generate coins + Generate coins + + + + Don't generate coins + Don't generate coins + + + + Specify data directory + Specify data directory + + + + Set database cache size in megabytes (default: 25) + Set database cache size in megabytes (default: 25) + + + + Set database disk log size in megabytes (default: 100) + Set database disk log size in megabytes (default: 100) + + + + Listen for connections on <port> (default: 7777 or testnet: 17777) + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Maintain at most <n> connections to peers (default: 125) + + + + Connect to a node to retrieve peer addresses, and disconnect + Connect to a node to retrieve peer addresses, and disconnect + + + + Specify your own public address + Specify your own public address + + + + Bind to given address. Use [host]:port notation for IPv6 + Bind to given address. Use [host]:port notation for IPv6 + + + + Threshold for disconnecting misbehaving peers (default: 100) + Threshold for disconnecting misbehaving peers (default: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + An error occurred while setting up the RPC port %u for listening on IPv4: %s + + + + + Detach block and address databases. Increases shutdown time (default: 0) + Detach block and address databases. Increases shutdown time (default: 0) + + + + Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Listen for JSON-RPC connections on <port> (default: 8344 or testnet: 18344) + + + + + Accept command line and JSON-RPC commands + Accept command line and JSON-RPC commands + + + + Error: Transaction creation failed + + + + + Error: Wallet locked, unable to create transaction + + + + + Importing blockchain data file. + + + + + Importing bootstrap blockchain data file. + + + + + Run in the background as a daemon and accept commands + Run in the background as a daemon and accept commands + + + + Use the test network + Use the test network + + + + Accept connections from outside (default: 1 if no -proxy or -connect) + Accept connections from outside (default: 1 if no -proxy or -connect) + + + + An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s + + + + + Error initializing database environment %s! To recover, BACKUP THAT DIRECTORY, then remove everything from it except for wallet.dat. + + + + + Set maximum size of high-priority/low-fee transactions in bytes (default: 27000) + Set maximum size of high-priority/low-fee transactions in bytes (default: 27000) + + + + Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + + + + Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. + Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. + + + + Warning: Please check that your computer's date and time are correct! If your clock is wrong BERN will not work properly. + Warning: Please check that your computer's date and time are correct! If your clock is wrong BERN will not work properly. + + + + Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + + + + Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. + Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. + + + + Attempt to recover private keys from a corrupt wallet.dat + Attempt to recover private keys from a corrupt wallet.dat + + + + Block creation options: + Block creation options: + + + + Connect only to the specified node(s) + Connect only to the specified node(s) + + + + Discover own IP address (default: 1 when listening and no -externalip) + Discover own IP address (default: 1 when listening and no -externalip) + + + + Failed to listen on any port. Use -listen=0 if you want this. + Failed to listen on any port. Use -listen=0 if you want this. + + + + Find peers using DNS lookup (default: 0) + Find peers using DNS lookup (default: 0) + + + + Invalid -tor address: '%s' + Invalid -tor address: '%s' + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000) + Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 1000) + Maximum per-connection send buffer, <n>*1000 bytes (default: 1000) + + + + Only connect to nodes in network <net> (IPv4, IPv6 or Tor) + Only connect to nodes in network <net> (IPv4, IPv6 or Tor) + + + + Output extra debugging information. Implies all other -debug* options + Output extra debugging information. Implies all other -debug* options + + + + Output extra network debugging information + Output extra network debugging information + + + + Prepend debug output with timestamp + Prepend debug output with timestamp + + + + SSL options: (see the Bitcoin Wiki for SSL setup instructions) + SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + Select the version of socks proxy to use (4-5, default: 5) + Select the version of socks proxy to use (4-5, default: 5) + + + + Send trace/debug info to console instead of debug.log file + Send trace/debug info to console instead of debug.log file + + + + Send trace/debug info to debugger + Send trace/debug info to debugger + + + + Set maximum block size in bytes (default: 250000) + Set maximum block size in bytes (default: 250000) + + + + Set minimum block size in bytes (default: 0) + Set minimum block size in bytes (default: 0) + + + + Shrink debug.log file on client startup (default: 1 when no -debug) + Shrink debug.log file on client startup (default: 1 when no -debug) + + + + Specify connection timeout in milliseconds (default: 5000) + Specify connection timeout in milliseconds (default: 5000) + + + + Use UPnP to map the listening port (default: 0) + Use UPnP to map the listening port (default: 0) + + + + Use UPnP to map the listening port (default: 1 when listening) + Use UPnP to map the listening port (default: 1 when listening) + + + + Use proxy to reach tor hidden services (default: same as -proxy) + Use proxy to reach tor hidden services (default: same as -proxy) + + + + Username for JSON-RPC connections + Username for JSON-RPC connections + + + + Verifying database integrity... + + + + + Warning: Disk space is low! + Warning: Disk space is low! + + + + Warning: This version is obsolete, upgrade required! + Warning: This version is obsolete, upgrade required! + + + + wallet.dat corrupt, salvage failed + + + + + Password for JSON-RPC connections + Password for JSON-RPC connections + + + + Allow JSON-RPC connections from specified IP address + Allow JSON-RPC connections from specified IP address + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Send commands to node running on <ip> (default: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + Upgrade wallet to latest format + Upgrade wallet to latest format + + + + Set key pool size to <n> (default: 100) + Set key pool size to <n> (default: 100) + + + + Rescan the block chain for missing wallet transactions + Rescan the block chain for missing wallet transactions + + + + How many blocks to check at startup (default: 2500, 0 = all) + How many blocks to check at startup (default: 2500, 0 = all) + + + + How thorough the block verification is (0-6, default: 1) + How thorough the block verification is (0-6, default: 1) + + + + Imports blocks from external blk000?.dat file + Imports blocks from external blk000?.dat file + + + + Use OpenSSL (https) for JSON-RPC connections + Use OpenSSL (https) for JSON-RPC connections + + + + Server certificate file (default: server.cert) + Server certificate file (default: server.cert) + + + + Server private key (default: server.pem) + Server private key (default: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + This help message + This help message + + + + Cannot obtain a lock on data directory %s. BERN is probably already running. + Cannot obtain a lock on data directory %s. BERN is probably already running. + + + + BERN + BERN + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + Connect through socks proxy + Connect through socks proxy + + + + Allow DNS lookups for -addnode, -seednode and -connect + Allow DNS lookups for -addnode, -seednode and -connect + + + + Loading addresses... + Loading addresses... + + + + Error loading blkindex.dat + Error loading blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Error loading wallet.dat: Wallet corrupted + + + + Error loading wallet.dat: Wallet requires newer version of BERN + Error loading wallet.dat: Wallet requires newer version of BERN + + + + Wallet needed to be rewritten: restart BERN to complete + Wallet needed to be rewritten: restart BERN to complete + + + + Error loading wallet.dat + Error loading wallet.dat + + + + Invalid -proxy address: '%s' + Invalid -proxy address: '%s' + + + + Unknown network specified in -onlynet: '%s' + Unknown network specified in -onlynet: '%s' + + + + Unknown -socks proxy version requested: %i + Unknown -socks proxy version requested: %i + + + + Cannot resolve -bind address: '%s' + Cannot resolve -bind address: '%s' + + + + Cannot resolve -externalip address: '%s' + Cannot resolve -externalip address: '%s' + + + + Invalid amount for -paytxfee=<amount>: '%s' + Invalid amount for -paytxfee=<amount>: '%s' + + + + Error: could not start node + Error: could not start node + + + + Sending... + Sending... + + + + Invalid amount + Invalid amount + + + + Insufficient funds + Insufficient funds + + + + Loading block index... + Loading block index... + + + + Add a node to connect to and attempt to keep the connection open + Add a node to connect to and attempt to keep the connection open + + + + Unable to bind to %s on this computer. BERN is probably already running. + Unable to bind to %s on this computer. BERN is probably already running. + + + + Find peers using internet relay chat (default: 1) + Find peers using internet relay chat (default: 1) + + + + Fee per KB to add to transactions you send + Fee per KB to add to transactions you send + + + + Loading wallet... + Loading wallet... + + + + Cannot downgrade wallet + Cannot downgrade wallet + + + + Cannot initialize keypool + Cannot initialize keypool + + + + Cannot write default address + Cannot write default address + + + + Rescanning... + Rescanning... + + + + Done loading + Done loading + + + + To use the %s option + To use the %s option + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Error + Error + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h new file mode 100644 index 0000000..2092fb2 --- /dev/null +++ b/src/qt/macdockiconhandler.h @@ -0,0 +1,44 @@ +#ifndef MACDOCKICONHANDLER_H +#define MACDOCKICONHANDLER_H + +#include + +class QMenu; +class QIcon; +class QWidget; + +#ifdef __OBJC__ +@class DockIconClickEventHandler; +#else +class DockIconClickEventHandler; +#endif + +/** Macintosh-specific dock icon handler. + */ +class MacDockIconHandler : public QObject +{ + Q_OBJECT +public: + ~MacDockIconHandler(); + + QMenu *dockMenu(); + void setIcon(const QIcon &icon); + + static MacDockIconHandler *instance(); + + void handleDockIconClickEvent(); + +signals: + void dockIconClicked(); + +public slots: + +private: + MacDockIconHandler(); + + DockIconClickEventHandler *m_dockIconClickEventHandler; + QWidget *m_dummyWidget; + QMenu *m_dockMenu; +}; + +#endif // MACDOCKICONCLICKHANDLER_H diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm new file mode 100644 index 0000000..7568440 --- /dev/null +++ b/src/qt/macdockiconhandler.mm @@ -0,0 +1,99 @@ + +#include "macdockiconhandler.h" + +#include +#include + +extern void qt_mac_set_dock_menu(QMenu*); + +#undef slots +#include + +@interface DockIconClickEventHandler : NSObject +{ + MacDockIconHandler* dockIconHandler; +} + +@end + +@implementation DockIconClickEventHandler + +- (id)initWithDockIconHandler:(MacDockIconHandler *)aDockIconHandler +{ + self = [super init]; + if (self) { + dockIconHandler = aDockIconHandler; + + [[NSAppleEventManager sharedAppleEventManager] + setEventHandler:self + andSelector:@selector(handleDockClickEvent:withReplyEvent:) + forEventClass:kCoreEventClass + andEventID:kAEReopenApplication]; + } + return self; +} + +- (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent +{ + Q_UNUSED(event) + Q_UNUSED(replyEvent) + + if (dockIconHandler) + dockIconHandler->handleDockIconClickEvent(); +} + +@end + +MacDockIconHandler::MacDockIconHandler() : QObject() +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this]; + + this->m_dummyWidget = new QWidget(); + this->m_dockMenu = new QMenu(this->m_dummyWidget); + qt_mac_set_dock_menu(this->m_dockMenu); + [pool release]; +} + +MacDockIconHandler::~MacDockIconHandler() +{ + [this->m_dockIconClickEventHandler release]; + delete this->m_dummyWidget; +} + +QMenu *MacDockIconHandler::dockMenu() +{ + return this->m_dockMenu; +} + +void MacDockIconHandler::setIcon(const QIcon &icon) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSImage *image; + if (icon.isNull()) + image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; + else { + QSize size = icon.actualSize(QSize(128, 128)); + QPixmap pixmap = icon.pixmap(size); + CGImageRef cgImage = pixmap.toMacCGImageRef(); + image = [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize]; + CFRelease(cgImage); + } + + [NSApp setApplicationIconImage:image]; + [image release]; + [pool release]; +} + +MacDockIconHandler *MacDockIconHandler::instance() +{ + static MacDockIconHandler *s_instance = NULL; + if (!s_instance) + s_instance = new MacDockIconHandler(); + return s_instance; +} + +void MacDockIconHandler::handleDockIconClickEvent() +{ + emit this->dockIconClicked(); +} diff --git a/src/qt/miningpage.cpp b/src/qt/miningpage.cpp new file mode 100644 index 0000000..81edbb3 --- /dev/null +++ b/src/qt/miningpage.cpp @@ -0,0 +1,419 @@ +#include "miningpage.h" +#include "ui_miningpage.h" +//#include "addresstablemodel.h" +#include "wallet.h" +CWallet *wallet; +extern QString glbAddress; +MiningPage::MiningPage(QWidget *parent) : + QWidget(parent), + ui(new Ui::MiningPage) +{ + ui->setupUi(this); + + //setFixedSize(400, 420); + + minerActive = false; + + minerProcess = new QProcess(this); + minerProcess->setProcessChannelMode(QProcess::MergedChannels); + + readTimer = new QTimer(this); + + acceptedShares = 0; + rejectedShares = 0; + + roundAcceptedShares = 0; + roundRejectedShares = 0; + + initThreads = 0; + + connect(readTimer, SIGNAL(timeout()), this, SLOT(readProcessOutput())); + + connect(ui->startButton, SIGNAL(pressed()), this, SLOT(startPressed())); + connect(ui->typeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int))); + connect(ui->debugCheckBox, SIGNAL(toggled(bool)), this, SLOT(debugToggled(bool))); + connect(minerProcess, SIGNAL(started()), this, SLOT(minerStarted())); + connect(minerProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(minerError(QProcess::ProcessError))); + connect(minerProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(minerFinished())); + connect(minerProcess, SIGNAL(readyRead()), this, SLOT(readProcessOutput())); +} + +MiningPage::~MiningPage() +{ + minerProcess->kill(); + delete ui; +} + +void MiningPage::setModel(ClientModel *model) +{ + this->model = model; + loadSettings(); + + bool pool = model->getMiningType() == ClientModel::PoolMining; + ui->threadsBox->setValue(4); + ui->scantimeBox->setValue(10); + ui->typeBox->setCurrentIndex(pool ? 2 : 0); + MiningPage::typeChanged(0); // init p2p values +// if (model->getMiningStarted()) +// startPressed(); +} + +void MiningPage::startPressed() +{ + initThreads = ui->threadsBox->value(); + + if (minerActive == false) + { + saveSettings(); + + if (getMiningType() == ClientModel::SoloMining) + minerStarted(); + else + startPoolMining(); + } + else + { + if (getMiningType() == ClientModel::SoloMining) + { + minerFinished(); + enablePoolMiningControls(false); + } + else + stopPoolMining(); + } +} + +void MiningPage::startPoolMining() +{ + QStringList args; + QString url = ui->serverLine->text(); + // if (!url.contains("http://")) + // url.prepend("http://"); + QString urlLine = QString("%1:%2").arg(url, ui->portLine->text()); + QString userpassLine = QString("%1:%2").arg(ui->usernameLine->text(), ui->passwordLine->text()); + args << "--algo" << "x14"; + args << "--scantime" << ui->scantimeBox->text().toAscii(); + args << "--url" << urlLine.toAscii(); + args << "--userpass" << userpassLine.toAscii(); + args << "--threads" << ui->threadsBox->text().toAscii(); + args << "--retries" << "-1"; // Retry forever. + args << "-P"; // This is needed for this to work correctly on Windows. Extra protocol dump helps flush the buffer quicker. + + threadSpeed.clear(); + + acceptedShares = 0; + rejectedShares = 0; + + roundAcceptedShares = 0; + roundRejectedShares = 0; + + // If minerd is in current path, then use that. Otherwise, assume minerd is in the path somewhere. + QString program = QDir::current().filePath("minerd"); + if (!QFile::exists(program)) + program = "minerd"; + + if (ui->debugCheckBox->isChecked()) + ui->list->addItem(args.join(" ").prepend(" ").prepend(program)); + + ui->mineSpeedLabel->setText("Speed: N/A"); + ui->shareCount->setText("Accepted: 0 - Rejected: 0"); + minerProcess->start(program,args); + minerProcess->waitForStarted(-1); + + readTimer->start(500); +} + +void MiningPage::stopPoolMining() +{ + ui->mineSpeedLabel->setText(""); + minerProcess->kill(); + readTimer->stop(); +} + +void MiningPage::saveSettings() +{ + model->setMiningDebug(ui->debugCheckBox->isChecked()); + model->setMiningScanTime(ui->scantimeBox->value()); + model->setMiningServer(ui->serverLine->text()); + model->setMiningPort(ui->portLine->text()); + model->setMiningUsername(ui->usernameLine->text()); + model->setMiningPassword(ui->passwordLine->text()); +} + +void MiningPage::loadSettings() +{ + ui->debugCheckBox->setChecked(model->getMiningDebug()); + ui->scantimeBox->setValue(model->getMiningScanTime()); + ui->serverLine->setText(model->getMiningServer()); + ui->portLine->setText(model->getMiningPort()); + ui->usernameLine->setText(model->getMiningUsername()); + ui->passwordLine->setText(model->getMiningPassword()); +} + +void MiningPage::readProcessOutput() +{ + QByteArray output; + + minerProcess->reset(); + + output = minerProcess->readAll(); + + QString outputString(output); + + if (!outputString.isEmpty()) + { + QStringList list = outputString.split("\n", QString::SkipEmptyParts); + int i; + for (i=0; idebugCheckBox->isChecked()) + { + line.remove(""); + line.remove(""); + line.remove(""); + line.remove(""); + ui->list->addItem(line.trimmed()); + ui->list->scrollToBottom(); + } + + if (line.contains("accepted:")) + reportToList("Share accepted! Woo Hoo! Feel The BERN!!!", SHARE_SUCCESS, getTime(line)); + else if (line.contains("rejected")) + reportToList("Share rejected. No worries, it happens.", SHARE_FAIL, getTime(line)); + else if (line.contains(" x14 block")) + reportToList("New block detected on the BERN network. Beginning work on the new block.", LONGPOLL, getTime(line)); + else if (line.contains("Supported options:")) + reportToList("Miner didn't start properly. Try checking your settings.", ERROR, NULL); + else if (line.contains("The requested URL returned error: 403")) + reportToList("Couldn't connect. Please check your username and password.", ERROR, NULL); + else if (line.contains("HTTP request failed")) + reportToList("Couldn't connect. Please check pool server and port.", ERROR, NULL); + else if (line.contains("JSON-RPC call failed")) + reportToList("Couldn't communicate with server. Retrying in 30 seconds.", ERROR, NULL); + else if (line.contains("CPU") && line.contains("kH/s")) + { + // QString threadIDstr = line.at(line.indexOf("CPU")+5); + QString threadIDstr = line.mid(line.indexOf("CPU")+5,2); + threadIDstr.remove(":"); + int threadID = threadIDstr.toInt(); + //reportToList("threadID->", ERROR, NULL); + // reportToList(threadIDstr, ERROR, NULL); + int threadSpeedindx = line.indexOf("#")+3; + QString threadSpeedstr = line.mid(threadSpeedindx,7); + //threadSpeedstr.chop(8); + //threadSpeedstr= threadSpeedstr.at(line.indexOf(":")); + threadSpeedstr.remove(":"); + threadSpeedstr.remove(" "); + threadSpeedstr.remove("k"); + //threadSpeedstr.remove('\n'); + + + //reportToList(threadSpeedstr, ERROR, NULL); + double speed=0; + speed = threadSpeedstr.toDouble(); + + threadSpeed[threadID] = speed; + + updateSpeed(); + } + } + } +} + +void MiningPage::minerError(QProcess::ProcessError error) +{ + if (error == QProcess::FailedToStart) + { + reportToList("Miner failed to start. Make sure you have the minerd executable and any associated files in the same directory as BERN-qt.", ERROR, NULL); + } +} + +void MiningPage::minerFinished() +{ + if (getMiningType() == ClientModel::SoloMining) + reportToList("Solo mining stopped.", ERROR, NULL); + else + reportToList("Miner exited.", ERROR, NULL); + ui->list->addItem(""); + minerActive = false; + resetMiningButton(); + model->setMining(getMiningType(), false, initThreads, 0); +} + +void MiningPage::minerStarted() +{ + if (!minerActive) + if (getMiningType() == ClientModel::SoloMining) + reportToList("Solo mining started.", ERROR, NULL); + else + reportToList("Miner started. You might not see any output for a few minutes.", STARTED, NULL); + minerActive = true; + resetMiningButton(); + model->setMining(getMiningType(), true, initThreads, 0); +} + +void MiningPage::updateSpeed() +{ + double totalSpeed=0; + int totalThreads=0; + + QMapIterator iter(threadSpeed); + while(iter.hasNext()) + { + iter.next(); + totalSpeed += iter.value(); + totalThreads++; + } + + // If all threads haven't reported the hash speed yet, make an assumption + if (totalThreads != initThreads) + { + totalSpeed = (totalSpeed/totalThreads)*initThreads; + } + + QString speedString = QString("%1").arg(totalSpeed); + QString threadsString = QString("%1").arg(initThreads); + + QString acceptedString = QString("%1").arg(acceptedShares); + QString rejectedString = QString("%1").arg(rejectedShares); + + QString roundAcceptedString = QString("%1").arg(roundAcceptedShares); + QString roundRejectedString = QString("%1").arg(roundRejectedShares); + + if (totalThreads == initThreads) + ui->mineSpeedLabel->setText(QString("Speed: %1 khash/sec - %2 thread(s)").arg(speedString, threadsString)); + else + ui->mineSpeedLabel->setText(QString("Speed: ~%1 khash/sec - %2 thread(s)").arg(speedString, threadsString)); + + ui->shareCount->setText(QString("Accepted: %1 (%3) - Rejected: %2 (%4)").arg(acceptedString, rejectedString, roundAcceptedString, roundRejectedString)); + + model->setMining(getMiningType(), true, initThreads, totalSpeed*1000); +} + +void MiningPage::reportToList(QString msg, int type, QString time) +{ + QString message; + if (time == NULL) + message = QString("[%1] - %2").arg(QTime::currentTime().toString(), msg); + else + message = QString("[%1] - %2").arg(time, msg); + + switch(type) + { + case SHARE_SUCCESS: + acceptedShares++; + roundAcceptedShares++; + updateSpeed(); + break; + + case SHARE_FAIL: + rejectedShares++; + roundRejectedShares++; + updateSpeed(); + break; + + case LONGPOLL: + roundAcceptedShares = 0; + roundRejectedShares = 0; + break; + + default: + break; + } + + ui->list->addItem(message); + ui->list->scrollToBottom(); +} + +// Function for fetching the time +QString MiningPage::getTime(QString time) +{ + if (time.contains("[")) + { + time.resize(21); + time.remove("["); + time.remove("]"); + //time.remove(0,11); + + return time; + } + else + return NULL; +} + +void MiningPage::enableMiningControls(bool enable) +{ + ui->typeBox->setEnabled(enable); + ui->threadsBox->setEnabled(enable); + if (enable) ui->threadsBox->setValue(4); + ui->scantimeBox->setEnabled(enable); + if (enable) ui->scantimeBox->setValue(10); + ui->serverLine->setEnabled(enable); + ui->portLine->setEnabled(enable); + ui->usernameLine->setEnabled(enable); + ui->passwordLine->setEnabled(enable); +} + +void MiningPage::enablePoolMiningControls(bool enable) +{ + ui->scantimeBox->setEnabled(enable); + ui->serverLine->setEnabled(enable); + ui->portLine->setEnabled(enable); + ui->usernameLine->setEnabled(enable); + ui->passwordLine->setEnabled(enable); +} + +ClientModel::MiningType MiningPage::getMiningType() +{ + if (ui->typeBox->currentIndex() == 0) // Easy Mining + { + return ClientModel::EasyMining; + } + else if (ui->typeBox->currentIndex() == 1) // Solo Mining + { + return ClientModel::SoloMining; + } + else if (ui->typeBox->currentIndex() == 2) // Pool Mining + { + return ClientModel::PoolMining; + } + return ClientModel::SoloMining; +} + +void MiningPage::typeChanged(int index) +{ + if (index == 0) // Easy Mining + { + enablePoolMiningControls(false); + ui->passwordLine->setText("x"); + ui->serverLine->setText("stratum+tcp://yiimp.ccminer.org"); + ui->portLine->setText("3933"); + ui->usernameLine->setText(glbAddress); + //} + } + else if (index == 1) // Solo Mining + { + enablePoolMiningControls(false); + } + else if (index == 2) // Pool Mining + { + enablePoolMiningControls(true); + } +} + +void MiningPage::debugToggled(bool checked) +{ + model->setMiningDebug(checked); +} + +void MiningPage::resetMiningButton() +{ + ui->startButton->setText(minerActive ? "Stop Mining" : "Start Mining"); + enableMiningControls(!minerActive); +} diff --git a/src/qt/miningpage.h b/src/qt/miningpage.h new file mode 100644 index 0000000..c589f3e --- /dev/null +++ b/src/qt/miningpage.h @@ -0,0 +1,91 @@ +#ifndef MININGPAGE_H +#define MININGPAGE_H + +#include "clientmodel.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Log types +#define STARTED 0 +#define SHARE_SUCCESS 1 +#define SHARE_FAIL 2 +#define ERROR 3 +#define LONGPOLL 4 + +namespace Ui { + class MiningPage; +} +class ClientModel; + +class MiningPage : public QWidget +{ + Q_OBJECT + +public: + explicit MiningPage(QWidget *parent = 0); + ~MiningPage(); + + bool minerActive; + + QProcess *minerProcess; + + QMap threadSpeed; + + QTimer *readTimer; + + int acceptedShares; + int rejectedShares; + + int roundAcceptedShares; + int roundRejectedShares; + + int initThreads; + + void setModel(ClientModel *model); + +public slots: + void startPressed(); + + void startPoolMining(); + void stopPoolMining(); + + void updateSpeed(); + + void loadSettings(); + void saveSettings(); + + void reportToList(QString, int, QString); + + void minerStarted(); + + void minerError(QProcess::ProcessError); + void minerFinished(); + + void readProcessOutput(); + + QString getTime(QString); + void enableMiningControls(bool enable); + void enablePoolMiningControls(bool enable); + ClientModel::MiningType getMiningType(); + void typeChanged(int index); + void debugToggled(bool checked); + +private slots: + +private: + Ui::MiningPage *ui; + ClientModel *model; + + void resetMiningButton(); +}; + +#endif // MININGPAGE_H diff --git a/src/qt/monitoreddatamapper.cpp b/src/qt/monitoreddatamapper.cpp new file mode 100644 index 0000000..88948d0 --- /dev/null +++ b/src/qt/monitoreddatamapper.cpp @@ -0,0 +1,36 @@ +#include "monitoreddatamapper.h" + +#include +#include +#include + +MonitoredDataMapper::MonitoredDataMapper(QObject *parent) : + QDataWidgetMapper(parent) +{ +} + + +void MonitoredDataMapper::addMapping(QWidget *widget, int section) +{ + QDataWidgetMapper::addMapping(widget, section); + addChangeMonitor(widget); +} + +void MonitoredDataMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName) +{ + QDataWidgetMapper::addMapping(widget, section, propertyName); + addChangeMonitor(widget); +} + +void MonitoredDataMapper::addChangeMonitor(QWidget *widget) +{ + // Watch user property of widget for changes, and connect + // the signal to our viewModified signal. + QMetaProperty prop = widget->metaObject()->userProperty(); + int signal = prop.notifySignalIndex(); + int method = this->metaObject()->indexOfMethod("viewModified()"); + if(signal != -1 && method != -1) + { + QMetaObject::connect(widget, signal, this, method); + } +} diff --git a/src/qt/monitoreddatamapper.h b/src/qt/monitoreddatamapper.h new file mode 100644 index 0000000..33a874e --- /dev/null +++ b/src/qt/monitoreddatamapper.h @@ -0,0 +1,31 @@ +#ifndef MONITOREDDATAMAPPER_H +#define MONITOREDDATAMAPPER_H + +#include + +QT_BEGIN_NAMESPACE +class QWidget; +QT_END_NAMESPACE + +/** Data to Widget mapper that watches for edits and notifies listeners when a field is edited. + This can be used, for example, to enable a commit/apply button in a configuration dialog. + */ +class MonitoredDataMapper : public QDataWidgetMapper +{ + Q_OBJECT +public: + explicit MonitoredDataMapper(QObject *parent=0); + + void addMapping(QWidget *widget, int section); + void addMapping(QWidget *widget, int section, const QByteArray &propertyName); +private: + void addChangeMonitor(QWidget *widget); + +signals: + void viewModified(); + +}; + + + +#endif // MONITOREDDATAMAPPER_H diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp new file mode 100644 index 0000000..8028190 --- /dev/null +++ b/src/qt/notificator.cpp @@ -0,0 +1,302 @@ +#include "notificator.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_DBUS +#include +#include +#endif + +#ifdef Q_OS_MAC +#include +extern bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret); +#endif + +// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128 +const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128; + +Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, QWidget *parent): + QObject(parent), + parent(parent), + programName(programName), + mode(None), + trayIcon(trayicon) +#ifdef USE_DBUS + ,interface(0) +#endif +{ + if(trayicon && trayicon->supportsMessages()) + { + mode = QSystemTray; + } +#ifdef USE_DBUS + interface = new QDBusInterface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); + if(interface->isValid()) + { + mode = Freedesktop; + } +#endif +#ifdef Q_OS_MAC + // Check if Growl is installed (based on Qt's tray icon implementation) + CFURLRef cfurl; + OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl); + if (status != kLSApplicationNotFoundErr) { + CFBundleRef bundle = CFBundleCreate(0, cfurl); + if (CFStringCompare(CFBundleGetIdentifier(bundle), CFSTR("com.Growl.GrowlHelperApp"), kCFCompareCaseInsensitive | kCFCompareBackwards) == kCFCompareEqualTo) { + if (CFStringHasSuffix(CFURLGetString(cfurl), CFSTR("/Growl.app/"))) + mode = Growl13; + else + mode = Growl12; + } + CFRelease(cfurl); + CFRelease(bundle); + } +#endif +} + +Notificator::~Notificator() +{ +#ifdef USE_DBUS + delete interface; +#endif +} + +#ifdef USE_DBUS + +// Loosely based on http://www.qtcentre.org/archive/index.php/t-25879.html +class FreedesktopImage +{ +public: + FreedesktopImage() {} + FreedesktopImage(const QImage &img); + + static int metaType(); + + // Image to variant that can be marshalled over DBus + static QVariant toVariant(const QImage &img); + +private: + int width, height, stride; + bool hasAlpha; + int channels; + int bitsPerSample; + QByteArray image; + + friend QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i); + friend const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i); +}; + +Q_DECLARE_METATYPE(FreedesktopImage); + +// Image configuration settings +const int CHANNELS = 4; +const int BYTES_PER_PIXEL = 4; +const int BITS_PER_SAMPLE = 8; + +FreedesktopImage::FreedesktopImage(const QImage &img): + width(img.width()), + height(img.height()), + stride(img.width() * BYTES_PER_PIXEL), + hasAlpha(true), + channels(CHANNELS), + bitsPerSample(BITS_PER_SAMPLE) +{ + // Convert 00xAARRGGBB to RGBA bytewise (endian-independent) format + QImage tmp = img.convertToFormat(QImage::Format_ARGB32); + const uint32_t *data = reinterpret_cast(tmp.constBits()); + + unsigned int num_pixels = width * height; + image.resize(num_pixels * BYTES_PER_PIXEL); + + for(unsigned int ptr = 0; ptr < num_pixels; ++ptr) + { + image[ptr*BYTES_PER_PIXEL+0] = data[ptr] >> 16; // R + image[ptr*BYTES_PER_PIXEL+1] = data[ptr] >> 8; // G + image[ptr*BYTES_PER_PIXEL+2] = data[ptr]; // B + image[ptr*BYTES_PER_PIXEL+3] = data[ptr] >> 24; // A + } +} + +QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i) +{ + a.beginStructure(); + a << i.width << i.height << i.stride << i.hasAlpha << i.bitsPerSample << i.channels << i.image; + a.endStructure(); + return a; +} + +const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i) +{ + a.beginStructure(); + a >> i.width >> i.height >> i.stride >> i.hasAlpha >> i.bitsPerSample >> i.channels >> i.image; + a.endStructure(); + return a; +} + +int FreedesktopImage::metaType() +{ + return qDBusRegisterMetaType(); +} + +QVariant FreedesktopImage::toVariant(const QImage &img) +{ + FreedesktopImage fimg(img); + return QVariant(FreedesktopImage::metaType(), &fimg); +} + +void Notificator::notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + Q_UNUSED(cls); + // Arguments for DBus call: + QList args; + + // Program Name: + args.append(programName); + + // Unique ID of this notification type: + args.append(0U); + + // Application Icon, empty string + args.append(QString()); + + // Summary + args.append(title); + + // Body + args.append(text); + + // Actions (none, actions are deprecated) + QStringList actions; + args.append(actions); + + // Hints + QVariantMap hints; + + // If no icon specified, set icon based on class + QIcon tmpicon; + if(icon.isNull()) + { + QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion; + switch(cls) + { + case Information: sicon = QStyle::SP_MessageBoxInformation; break; + case Warning: sicon = QStyle::SP_MessageBoxWarning; break; + case Critical: sicon = QStyle::SP_MessageBoxCritical; break; + default: break; + } + tmpicon = QApplication::style()->standardIcon(sicon); + } + else + { + tmpicon = icon; + } + hints["icon_data"] = FreedesktopImage::toVariant(tmpicon.pixmap(FREEDESKTOP_NOTIFICATION_ICON_SIZE).toImage()); + args.append(hints); + + // Timeout (in msec) + args.append(millisTimeout); + + // "Fire and forget" + interface->callWithArgumentList(QDBus::NoBlock, "Notify", args); +} +#endif + +void Notificator::notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + Q_UNUSED(icon); + QSystemTrayIcon::MessageIcon sicon = QSystemTrayIcon::NoIcon; + switch(cls) // Set icon based on class + { + case Information: sicon = QSystemTrayIcon::Information; break; + case Warning: sicon = QSystemTrayIcon::Warning; break; + case Critical: sicon = QSystemTrayIcon::Critical; break; + } + trayIcon->showMessage(title, text, sicon, millisTimeout); +} + +// Based on Qt's tray icon implementation +#ifdef Q_OS_MAC +void Notificator::notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon) +{ + const QString script( + "tell application \"%5\"\n" + " set the allNotificationsList to {\"Notification\"}\n" // -- Make a list of all the notification types (all) + " set the enabledNotificationsList to {\"Notification\"}\n" // -- Make a list of the notifications (enabled) + " register as application \"%1\" all notifications allNotificationsList default notifications enabledNotificationsList\n" // -- Register our script with Growl + " notify with name \"Notification\" title \"%2\" description \"%3\" application name \"%1\"%4\n" // -- Send a Notification + "end tell" + ); + + QString notificationApp(QApplication::applicationName()); + if (notificationApp.isEmpty()) + notificationApp = "Application"; + + QPixmap notificationIconPixmap; + if (icon.isNull()) { // If no icon specified, set icon based on class + QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion; + switch (cls) + { + case Information: sicon = QStyle::SP_MessageBoxInformation; break; + case Warning: sicon = QStyle::SP_MessageBoxWarning; break; + case Critical: sicon = QStyle::SP_MessageBoxCritical; break; + } + notificationIconPixmap = QApplication::style()->standardPixmap(sicon); + } + else { + QSize size = icon.actualSize(QSize(48, 48)); + notificationIconPixmap = icon.pixmap(size); + } + + QString notificationIcon; + QTemporaryFile notificationIconFile; + if (!notificationIconPixmap.isNull() && notificationIconFile.open()) { + QImageWriter writer(¬ificationIconFile, "PNG"); + if (writer.write(notificationIconPixmap.toImage())) + notificationIcon = QString(" image from location \"file://%1\"").arg(notificationIconFile.fileName()); + } + + QString quotedTitle(title), quotedText(text); + quotedTitle.replace("\\", "\\\\").replace("\"", "\\"); + quotedText.replace("\\", "\\\\").replace("\"", "\\"); + QString growlApp(this->mode == Notificator::Growl13 ? "Growl" : "GrowlHelperApp"); + qt_mac_execute_apple_script(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp), 0); +} +#endif + +void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + switch(mode) + { +#ifdef USE_DBUS + case Freedesktop: + notifyDBus(cls, title, text, icon, millisTimeout); + break; +#endif + case QSystemTray: + notifySystray(cls, title, text, icon, millisTimeout); + break; +#ifdef Q_OS_MAC + case Growl12: + case Growl13: + notifyGrowl(cls, title, text, icon); + break; +#endif + default: + if(cls == Critical) + { + // Fall back to old fashioned pop-up dialog if critical and no other notification available + QMessageBox::critical(parent, title, text, QMessageBox::Ok, QMessageBox::Ok); + } + break; + } +} diff --git a/src/qt/notificator.h b/src/qt/notificator.h new file mode 100644 index 0000000..abb4710 --- /dev/null +++ b/src/qt/notificator.h @@ -0,0 +1,69 @@ +#ifndef NOTIFICATOR_H +#define NOTIFICATOR_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QSystemTrayIcon; +#ifdef USE_DBUS +class QDBusInterface; +#endif +QT_END_NAMESPACE + +/** Cross-platform desktop notification client. */ +class Notificator: public QObject +{ + Q_OBJECT +public: + /** Create a new notificator. + @note Ownership of trayIcon is not transferred to this object. + */ + Notificator(const QString &programName=QString(), QSystemTrayIcon *trayIcon=0, QWidget *parent=0); + ~Notificator(); + + // Message class + enum Class + { + Information, /**< Informational message */ + Warning, /**< Notify user of potential problem */ + Critical /**< An error occurred */ + }; + +public slots: + + /** Show notification message. + @param[in] cls general message class + @param[in] title title shown with message + @param[in] text message content + @param[in] icon optional icon to show with message + @param[in] millisTimeout notification timeout in milliseconds (defaults to 10 seconds) + @note Platform implementations are free to ignore any of the provided fields except for \a text. + */ + void notify(Class cls, const QString &title, const QString &text, + const QIcon &icon = QIcon(), int millisTimeout = 10000); + +private: + QWidget *parent; + enum Mode { + None, /**< Ignore informational notifications, and show a modal pop-up dialog for Critical notifications. */ + Freedesktop, /**< Use DBus org.freedesktop.Notifications */ + QSystemTray, /**< Use QSystemTray::showMessage */ + Growl12, /**< Use the Growl 1.2 notification system (Mac only) */ + Growl13 /**< Use the Growl 1.3 notification system (Mac only) */ + }; + QString programName; + Mode mode; + QSystemTrayIcon *trayIcon; +#ifdef USE_DBUS + QDBusInterface *interface; + + void notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); +#endif + void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); +#ifdef Q_OS_MAC + void notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon); +#endif +}; + +#endif // NOTIFICATOR_H diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp new file mode 100644 index 0000000..912e7d6 --- /dev/null +++ b/src/qt/optionsdialog.cpp @@ -0,0 +1,257 @@ +#include "optionsdialog.h" +#include "ui_optionsdialog.h" + +#include "bitcoinunits.h" +#include "monitoreddatamapper.h" +#include "netbase.h" +#include "optionsmodel.h" + +#include +#include +#include +#include +#include +#include + +OptionsDialog::OptionsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::OptionsDialog), + model(0), + mapper(0), + fRestartWarningDisplayed_Proxy(false), + fRestartWarningDisplayed_Lang(false), + fProxyIpValid(true) +{ + ui->setupUi(this); + + /* Network elements init */ +#ifndef USE_UPNP + ui->mapPortUpnp->setEnabled(false); +#endif + + ui->proxyIp->setEnabled(false); + ui->proxyPort->setEnabled(false); + ui->proxyPort->setValidator(new QIntValidator(1, 65535, this)); + + ui->socksVersion->setEnabled(false); + ui->socksVersion->addItem("5", 5); + ui->socksVersion->addItem("4", 4); + ui->socksVersion->setCurrentIndex(0); + + connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool))); + connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool))); + connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->socksVersion, SLOT(setEnabled(bool))); + connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning_Proxy())); + + ui->proxyIp->installEventFilter(this); + + /* Window elements init */ +#ifdef Q_OS_MAC + ui->tabWindow->setVisible(false); +#endif + + /* Display elements init */ + QDir translations(":translations"); + ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant("")); + foreach(const QString &langStr, translations.entryList()) + { + QLocale locale(langStr); + + /** check if the locale name consists of 2 parts (language_country) */ + if(langStr.contains("_")) + { +#if QT_VERSION >= 0x040800 + /** display language strings as "native language - native country (locale name)", e.g. "Deutsch - Deutschland (de)" */ + ui->lang->addItem(locale.nativeLanguageName() + QString(" - ") + locale.nativeCountryName() + QString(" (") + langStr + QString(")"), QVariant(langStr)); +#else + /** display language strings as "language - country (locale name)", e.g. "German - Germany (de)" */ + ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" - ") + QLocale::countryToString(locale.country()) + QString(" (") + langStr + QString(")"), QVariant(langStr)); +#endif + } + else + { +#if QT_VERSION >= 0x040800 + /** display language strings as "native language (locale name)", e.g. "Deutsch (de)" */ + ui->lang->addItem(locale.nativeLanguageName() + QString(" (") + langStr + QString(")"), QVariant(langStr)); +#else + /** display language strings as "language (locale name)", e.g. "German (de)" */ + ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" (") + langStr + QString(")"), QVariant(langStr)); +#endif + } + } + + ui->unit->setModel(new BitcoinUnits(this)); + + /* Widget-to-option mapper */ + mapper = new MonitoredDataMapper(this); + mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); + mapper->setOrientation(Qt::Vertical); + + /* enable apply button when data modified */ + connect(mapper, SIGNAL(viewModified()), this, SLOT(enableApplyButton())); + /* disable apply button when new data loaded */ + connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(disableApplyButton())); + /* setup/change UI elements when proxy IP is invalid/valid */ + connect(this, SIGNAL(proxyIpValid(QValidatedLineEdit *, bool)), this, SLOT(handleProxyIpValid(QValidatedLineEdit *, bool))); +} + +OptionsDialog::~OptionsDialog() +{ + delete ui; +} + +void OptionsDialog::setModel(OptionsModel *model) +{ + this->model = model; + + if(model) + { + connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + + mapper->setModel(model); + setMapper(); + mapper->toFirst(); + } + + /* update the display unit, to not use the default ("BTC") */ + updateDisplayUnit(); + + /* warn only when language selection changes by user action (placed here so init via mapper doesn't trigger this) */ + connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning_Lang())); + + /* disable apply button after settings are loaded as there is nothing to save */ + disableApplyButton(); +} + +void OptionsDialog::setMapper() +{ + /* Main */ + mapper->addMapping(ui->transactionFee, OptionsModel::Fee); + mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup); + mapper->addMapping(ui->detachDatabases, OptionsModel::DetachDatabases); + + /* Network */ + mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP); + + mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse); + mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP); + mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort); + mapper->addMapping(ui->socksVersion, OptionsModel::ProxySocksVersion); + + /* Window */ +#ifndef Q_OS_MAC + mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray); + mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose); +#endif + + /* Display */ + mapper->addMapping(ui->lang, OptionsModel::Language); + mapper->addMapping(ui->unit, OptionsModel::DisplayUnit); + mapper->addMapping(ui->displayAddresses, OptionsModel::DisplayAddresses); + mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures); +} + +void OptionsDialog::enableApplyButton() +{ + ui->applyButton->setEnabled(true); +} + +void OptionsDialog::disableApplyButton() +{ + ui->applyButton->setEnabled(false); +} + +void OptionsDialog::enableSaveButtons() +{ + /* prevent enabling of the save buttons when data modified, if there is an invalid proxy address present */ + if(fProxyIpValid) + setSaveButtonState(true); +} + +void OptionsDialog::disableSaveButtons() +{ + setSaveButtonState(false); +} + +void OptionsDialog::setSaveButtonState(bool fState) +{ + ui->applyButton->setEnabled(fState); + ui->okButton->setEnabled(fState); +} + +void OptionsDialog::on_okButton_clicked() +{ + mapper->submit(); + accept(); +} + +void OptionsDialog::on_cancelButton_clicked() +{ + reject(); +} + +void OptionsDialog::on_applyButton_clicked() +{ + mapper->submit(); + disableApplyButton(); +} + +void OptionsDialog::showRestartWarning_Proxy() +{ + if(!fRestartWarningDisplayed_Proxy) + { + QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting BERN."), QMessageBox::Ok); + fRestartWarningDisplayed_Proxy = true; + } +} + +void OptionsDialog::showRestartWarning_Lang() +{ + if(!fRestartWarningDisplayed_Lang) + { + QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting BERN."), QMessageBox::Ok); + fRestartWarningDisplayed_Lang = true; + } +} + +void OptionsDialog::updateDisplayUnit() +{ + if(model) + { + /* Update transactionFee with the current unit */ + ui->transactionFee->setDisplayUnit(model->getDisplayUnit()); + } +} + +void OptionsDialog::handleProxyIpValid(QValidatedLineEdit *object, bool fState) +{ + // this is used in a check before re-enabling the save buttons + fProxyIpValid = fState; + + if(fProxyIpValid) + { + enableSaveButtons(); + ui->statusLabel->clear(); + } + else + { + disableSaveButtons(); + object->setValid(fProxyIpValid); + ui->statusLabel->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel->setText(tr("The supplied proxy address is invalid.")); + } +} + +bool OptionsDialog::eventFilter(QObject *object, QEvent *event) +{ + if(event->type() == QEvent::FocusOut) + { + if(object == ui->proxyIp) + { + CService addr; + /* Check proxyIp for a valid IPv4/IPv6 address and emit the proxyIpValid signal */ + emit proxyIpValid(ui->proxyIp, LookupNumeric(ui->proxyIp->text().toStdString().c_str(), addr)); + } + } + return QDialog::eventFilter(object, event); +} diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h new file mode 100644 index 0000000..18469f5 --- /dev/null +++ b/src/qt/optionsdialog.h @@ -0,0 +1,60 @@ +#ifndef OPTIONSDIALOG_H +#define OPTIONSDIALOG_H + +#include + +namespace Ui { +class OptionsDialog; +} +class OptionsModel; +class MonitoredDataMapper; +class QValidatedLineEdit; + +/** Preferences dialog. */ +class OptionsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit OptionsDialog(QWidget *parent = 0); + ~OptionsDialog(); + + void setModel(OptionsModel *model); + void setMapper(); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private slots: + /* enable only apply button */ + void enableApplyButton(); + /* disable only apply button */ + void disableApplyButton(); + /* enable apply button and OK button */ + void enableSaveButtons(); + /* disable apply button and OK button */ + void disableSaveButtons(); + /* set apply button and OK button state (enabled / disabled) */ + void setSaveButtonState(bool fState); + void on_okButton_clicked(); + void on_cancelButton_clicked(); + void on_applyButton_clicked(); + + void showRestartWarning_Proxy(); + void showRestartWarning_Lang(); + void updateDisplayUnit(); + void handleProxyIpValid(QValidatedLineEdit *object, bool fState); + +signals: + void proxyIpValid(QValidatedLineEdit *object, bool fValid); + +private: + Ui::OptionsDialog *ui; + OptionsModel *model; + MonitoredDataMapper *mapper; + bool fRestartWarningDisplayed_Proxy; + bool fRestartWarningDisplayed_Lang; + bool fProxyIpValid; +}; + +#endif // OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp new file mode 100644 index 0000000..dd91008 --- /dev/null +++ b/src/qt/optionsmodel.cpp @@ -0,0 +1,309 @@ +#include "optionsmodel.h" +#include "bitcoinunits.h" +#include + +#include "init.h" +#include "walletdb.h" +#include "guiutil.h" + +OptionsModel::OptionsModel(QObject *parent) : + QAbstractListModel(parent) +{ + Init(); +} + +bool static ApplyProxySettings() +{ + QSettings settings; + CService addrProxy(settings.value("addrProxy", "127.0.0.1:9050").toString().toStdString()); + int nSocksVersion(settings.value("nSocksVersion", 5).toInt()); + if (!settings.value("fUseProxy", false).toBool()) { + addrProxy = CService(); + nSocksVersion = 0; + return false; + } + if (nSocksVersion && !addrProxy.IsValid()) + return false; + if (!IsLimited(NET_IPV4)) + SetProxy(NET_IPV4, addrProxy, nSocksVersion); + if (nSocksVersion > 4) { +#ifdef USE_IPV6 + if (!IsLimited(NET_IPV6)) + SetProxy(NET_IPV6, addrProxy, nSocksVersion); +#endif + SetNameProxy(addrProxy, nSocksVersion); + } + return true; +} + +void OptionsModel::Init() +{ + QSettings settings; + + // These are Qt-only settings: + nDisplayUnit = settings.value("nDisplayUnit", BitcoinUnits::BTC).toInt(); + bDisplayAddresses = settings.value("bDisplayAddresses", false).toBool(); + fMinimizeToTray = settings.value("fMinimizeToTray", false).toBool(); + fMinimizeOnClose = settings.value("fMinimizeOnClose", false).toBool(); + fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool(); + nTransactionFee = settings.value("nTransactionFee").toLongLong(); + language = settings.value("language", "").toString(); + + // These are shared with core Bitcoin; we want + // command-line options to override the GUI settings: + if (settings.contains("fUseUPnP")) + SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()); + if (settings.contains("addrProxy") && settings.value("fUseProxy").toBool()) + SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString()); + if (settings.contains("nSocksVersion") && settings.value("fUseProxy").toBool()) + SoftSetArg("-socks", settings.value("nSocksVersion").toString().toStdString()); + if (settings.contains("detachDB")) + SoftSetBoolArg("-detachdb", settings.value("detachDB").toBool()); + if (!language.isEmpty()) + SoftSetArg("-lang", language.toStdString()); +} + +bool OptionsModel::Upgrade() +{ + QSettings settings; + + if (settings.contains("bImportFinished")) + return false; // Already upgraded + + settings.setValue("bImportFinished", true); + + // Move settings from old wallet.dat (if any): + CWalletDB walletdb("wallet.dat"); + + QList intOptions; + intOptions << "nDisplayUnit" << "nTransactionFee"; + foreach(QString key, intOptions) + { + int value = 0; + if (walletdb.ReadSetting(key.toStdString(), value)) + { + settings.setValue(key, value); + walletdb.EraseSetting(key.toStdString()); + } + } + QList boolOptions; + boolOptions << "bDisplayAddresses" << "fMinimizeToTray" << "fMinimizeOnClose" << "fUseProxy" << "fUseUPnP"; + foreach(QString key, boolOptions) + { + bool value = false; + if (walletdb.ReadSetting(key.toStdString(), value)) + { + settings.setValue(key, value); + walletdb.EraseSetting(key.toStdString()); + } + } + try + { + CAddress addrProxyAddress; + if (walletdb.ReadSetting("addrProxy", addrProxyAddress)) + { + settings.setValue("addrProxy", addrProxyAddress.ToStringIPPort().c_str()); + walletdb.EraseSetting("addrProxy"); + } + } + catch (std::ios_base::failure &e) + { + // 0.6.0rc1 saved this as a CService, which causes failure when parsing as a CAddress + CService addrProxy; + if (walletdb.ReadSetting("addrProxy", addrProxy)) + { + settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str()); + walletdb.EraseSetting("addrProxy"); + } + } + ApplyProxySettings(); + Init(); + + return true; +} + + +int OptionsModel::rowCount(const QModelIndex & parent) const +{ + return OptionIDRowCount; +} + +QVariant OptionsModel::data(const QModelIndex & index, int role) const +{ + if(role == Qt::EditRole) + { + QSettings settings; + switch(index.row()) + { + case StartAtStartup: + return QVariant(GUIUtil::GetStartOnSystemStartup()); + case MinimizeToTray: + return QVariant(fMinimizeToTray); + case MapPortUPnP: + return settings.value("fUseUPnP", GetBoolArg("-upnp", true)); + case MinimizeOnClose: + return QVariant(fMinimizeOnClose); + case ProxyUse: + return settings.value("fUseProxy", false); + case ProxyIP: { + proxyType proxy; + if (GetProxy(NET_IPV4, proxy)) + return QVariant(QString::fromStdString(proxy.first.ToStringIP())); + else + return QVariant(QString::fromStdString("127.0.0.1")); + } + case ProxyPort: { + proxyType proxy; + if (GetProxy(NET_IPV4, proxy)) + return QVariant(proxy.first.GetPort()); + else + return QVariant(9050); + } + case ProxySocksVersion: + return settings.value("nSocksVersion", 5); + case Fee: + return QVariant(nTransactionFee); + case DisplayUnit: + return QVariant(nDisplayUnit); + case DisplayAddresses: + return QVariant(bDisplayAddresses); + case DetachDatabases: + return QVariant(bitdb.GetDetach()); + case Language: + return settings.value("language", ""); + case CoinControlFeatures: + return QVariant(fCoinControlFeatures); + default: + return QVariant(); + } + } + return QVariant(); +} + +bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role) +{ + bool successful = true; /* set to false on parse error */ + if(role == Qt::EditRole) + { + QSettings settings; + switch(index.row()) + { + case StartAtStartup: + successful = GUIUtil::SetStartOnSystemStartup(value.toBool()); + break; + case MinimizeToTray: + fMinimizeToTray = value.toBool(); + settings.setValue("fMinimizeToTray", fMinimizeToTray); + break; + case MapPortUPnP: + fUseUPnP = value.toBool(); + settings.setValue("fUseUPnP", fUseUPnP); + MapPort(); + break; + case MinimizeOnClose: + fMinimizeOnClose = value.toBool(); + settings.setValue("fMinimizeOnClose", fMinimizeOnClose); + break; + case ProxyUse: + settings.setValue("fUseProxy", value.toBool()); + ApplyProxySettings(); + break; + case ProxyIP: { + proxyType proxy; + proxy.first = CService("127.0.0.1", 9050); + GetProxy(NET_IPV4, proxy); + + CNetAddr addr(value.toString().toStdString()); + proxy.first.SetIP(addr); + settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str()); + successful = ApplyProxySettings(); + } + break; + case ProxyPort: { + proxyType proxy; + proxy.first = CService("127.0.0.1", 9050); + GetProxy(NET_IPV4, proxy); + + proxy.first.SetPort(value.toInt()); + settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str()); + successful = ApplyProxySettings(); + } + break; + case ProxySocksVersion: { + proxyType proxy; + proxy.second = 5; + GetProxy(NET_IPV4, proxy); + + proxy.second = value.toInt(); + settings.setValue("nSocksVersion", proxy.second); + successful = ApplyProxySettings(); + } + break; + case Fee: + nTransactionFee = value.toLongLong(); + settings.setValue("nTransactionFee", nTransactionFee); + emit transactionFeeChanged(nTransactionFee); + break; + case DisplayUnit: + nDisplayUnit = value.toInt(); + settings.setValue("nDisplayUnit", nDisplayUnit); + emit displayUnitChanged(nDisplayUnit); + break; + case DisplayAddresses: + bDisplayAddresses = value.toBool(); + settings.setValue("bDisplayAddresses", bDisplayAddresses); + break; + case DetachDatabases: { + bool fDetachDB = value.toBool(); + bitdb.SetDetach(fDetachDB); + settings.setValue("detachDB", fDetachDB); + } + break; + case Language: + settings.setValue("language", value); + break; + case CoinControlFeatures: { + fCoinControlFeatures = value.toBool(); + settings.setValue("fCoinControlFeatures", fCoinControlFeatures); + emit coinControlFeaturesChanged(fCoinControlFeatures); + } + break; + default: + break; + } + } + emit dataChanged(index, index); + + return successful; +} + +qint64 OptionsModel::getTransactionFee() +{ + return nTransactionFee; +} + +bool OptionsModel::getCoinControlFeatures() +{ + return fCoinControlFeatures; +} + + +bool OptionsModel::getMinimizeToTray() +{ + return fMinimizeToTray; +} + +bool OptionsModel::getMinimizeOnClose() +{ + return fMinimizeOnClose; +} + +int OptionsModel::getDisplayUnit() +{ + return nDisplayUnit; +} + +bool OptionsModel::getDisplayAddresses() +{ + return bDisplayAddresses; +} diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h new file mode 100644 index 0000000..263b95e --- /dev/null +++ b/src/qt/optionsmodel.h @@ -0,0 +1,69 @@ +#ifndef OPTIONSMODEL_H +#define OPTIONSMODEL_H + +#include + +/** Interface from Qt to configuration data structure for Bitcoin client. + To Qt, the options are presented as a list with the different options + laid out vertically. + This can be changed to a tree once the settings become sufficiently + complex. + */ +class OptionsModel : public QAbstractListModel +{ + Q_OBJECT + +public: + explicit OptionsModel(QObject *parent = 0); + + enum OptionID { + StartAtStartup, // bool + MinimizeToTray, // bool + MapPortUPnP, // bool + MinimizeOnClose, // bool + ProxyUse, // bool + ProxyIP, // QString + ProxyPort, // int + ProxySocksVersion, // int + Fee, // qint64 + DisplayUnit, // BitcoinUnits::Unit + DisplayAddresses, // bool + DetachDatabases, // bool + Language, // QString + CoinControlFeatures, // bool + OptionIDRowCount, + }; + + void Init(); + + /* Migrate settings from wallet.dat after app initialization */ + bool Upgrade(); /* returns true if settings upgraded */ + + int rowCount(const QModelIndex & parent = QModelIndex()) const; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); + + /* Explicit getters */ + qint64 getTransactionFee(); + bool getMinimizeToTray(); + bool getMinimizeOnClose(); + int getDisplayUnit(); + bool getDisplayAddresses(); + bool getCoinControlFeatures(); + QString getLanguage() { return language; } + +private: + int nDisplayUnit; + bool bDisplayAddresses; + bool fMinimizeToTray; + bool fMinimizeOnClose; + bool fCoinControlFeatures; + QString language; + +signals: + void displayUnitChanged(int unit); + void transactionFeeChanged(qint64); + void coinControlFeaturesChanged(bool); +}; + +#endif // OPTIONSMODEL_H diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp new file mode 100644 index 0000000..b9e501a --- /dev/null +++ b/src/qt/overviewpage.cpp @@ -0,0 +1,204 @@ +#include "overviewpage.h" +#include "ui_overviewpage.h" + +#include "walletmodel.h" +#include "bitcoinunits.h" +#include "optionsmodel.h" +#include "transactiontablemodel.h" +#include "transactionfilterproxy.h" +#include "guiutil.h" +#include "guiconstants.h" +#include "askpassphrasedialog.h" + +#include +#include + +#define DECORATION_SIZE 64 +#define NUM_ITEMS 7 + +class TxViewDelegate : public QAbstractItemDelegate +{ + Q_OBJECT +public: + TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC) + { + + } + + inline void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index ) const + { + painter->save(); + + QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); + QRect mainRect = option.rect; + QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE)); + int xspace = DECORATION_SIZE + 8; + int ypad = 6; + int halfheight = (mainRect.height() - 2*ypad)/2; + QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight); + QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight); + icon.paint(painter, decorationRect); + + QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime(); + QString address = index.data(Qt::DisplayRole).toString(); + qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong(); + bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool(); + QVariant value = index.data(Qt::ForegroundRole); + QColor foreground = option.palette.color(QPalette::Text); + if(qVariantCanConvert(value)) + { + foreground = qvariant_cast(value); + } + + painter->setPen(foreground); + painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address); + + if(amount < 0) + { + foreground = COLOR_NEGATIVE; + } + else if(!confirmed) + { + foreground = COLOR_UNCONFIRMED; + } + else + { + foreground = option.palette.color(QPalette::Text); + } + painter->setPen(foreground); + QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true); + if(!confirmed) + { + amountText = QString("[") + amountText + QString("]"); + } + painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText); + + painter->setPen(option.palette.color(QPalette::Text)); + painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date)); + + painter->restore(); + } + + inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + { + return QSize(DECORATION_SIZE, DECORATION_SIZE); + } + + int unit; + +}; +#include "overviewpage.moc" + +OverviewPage::OverviewPage(QWidget *parent) : + QWidget(parent), + ui(new Ui::OverviewPage), + currentBalance(-1), + currentStake(0), + currentUnconfirmedBalance(-1), + currentImmatureBalance(-1), + txdelegate(new TxViewDelegate()), + filter(0) +{ + ui->setupUi(this); + + // Recent transactions + ui->listTransactions->setItemDelegate(txdelegate); + ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE)); + ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2)); + ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false); + + connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex))); + + // init "out of sync" warning labels + ui->labelWalletStatus->setText("(" + tr("out of sync") + ")"); + ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")"); + + // start with displaying the "out of sync" warnings + showOutOfSyncWarning(true); +} + +void OverviewPage::handleTransactionClicked(const QModelIndex &index) +{ + if(filter) + emit transactionClicked(filter->mapToSource(index)); +} + +OverviewPage::~OverviewPage() +{ + delete ui; +} + +void OverviewPage::setBalance(qint64 balance, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance) +{ + int unit = model->getOptionsModel()->getDisplayUnit(); + currentBalance = balance; + currentStake = stake; + currentUnconfirmedBalance = unconfirmedBalance; + currentImmatureBalance = immatureBalance; + ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance)); + ui->labelStake->setText(BitcoinUnits::formatWithUnit(unit, stake)); + ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance)); + ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance)); + + // only show immature (newly mined) balance if it's non-zero, so as not to complicate things + // for the non-mining users + bool showImmature = immatureBalance != 0; + ui->labelImmature->setVisible(showImmature); + ui->labelImmatureText->setVisible(showImmature); +} + +void OverviewPage::setNumTransactions(int count) +{ + ui->labelNumTransactions->setText(QLocale::system().toString(count)); +} + +void OverviewPage::setModel(WalletModel *model) +{ + this->model = model; + if(model && model->getOptionsModel()) + { + // Set up transaction list + filter = new TransactionFilterProxy(); + filter->setSourceModel(model->getTransactionTableModel()); + filter->setLimit(NUM_ITEMS); + filter->setDynamicSortFilter(true); + filter->setSortRole(Qt::EditRole); + filter->sort(TransactionTableModel::Date, Qt::DescendingOrder); + + ui->listTransactions->setModel(filter); + ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); + + // Keep up to date with wallet + setBalance(model->getBalance(), model->getStake(), model->getUnconfirmedBalance(), model->getImmatureBalance()); + connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64))); + + setNumTransactions(model->getNumTransactions()); + connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int))); + + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + } + + // update the display unit, to not use the default ("CLOAK") + updateDisplayUnit(); +} + +void OverviewPage::updateDisplayUnit() +{ + if(model && model->getOptionsModel()) + { + if(currentBalance != -1) + setBalance(currentBalance, model->getStake(), currentUnconfirmedBalance, currentImmatureBalance); + + // Update txdelegate->unit with the current unit + txdelegate->unit = model->getOptionsModel()->getDisplayUnit(); + + ui->listTransactions->update(); + } +} + +void OverviewPage::showOutOfSyncWarning(bool fShow) +{ + ui->labelWalletStatus->setVisible(fShow); + ui->labelTransactionsStatus->setVisible(fShow); +} diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h new file mode 100644 index 0000000..59fbb1d --- /dev/null +++ b/src/qt/overviewpage.h @@ -0,0 +1,52 @@ +#ifndef OVERVIEWPAGE_H +#define OVERVIEWPAGE_H + +#include + +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE + +namespace Ui { + class OverviewPage; +} +class WalletModel; +class TxViewDelegate; +class TransactionFilterProxy; + +/** Overview ("home") page widget */ +class OverviewPage : public QWidget +{ + Q_OBJECT + +public: + explicit OverviewPage(QWidget *parent = 0); + ~OverviewPage(); + + void setModel(WalletModel *model); + void showOutOfSyncWarning(bool fShow); + +public slots: + void setBalance(qint64 balance, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance); + void setNumTransactions(int count); + +signals: + void transactionClicked(const QModelIndex &index); + +private: + Ui::OverviewPage *ui; + WalletModel *model; + qint64 currentBalance; + qint64 currentStake; + qint64 currentUnconfirmedBalance; + qint64 currentImmatureBalance; + + TxViewDelegate *txdelegate; + TransactionFilterProxy *filter; + +private slots: + void updateDisplayUnit(); + void handleTransactionClicked(const QModelIndex &index); +}; + +#endif // OVERVIEWPAGE_H diff --git a/src/qt/qrcodedialog.cpp b/src/qt/qrcodedialog.cpp new file mode 100644 index 0000000..6ddcaaf --- /dev/null +++ b/src/qt/qrcodedialog.cpp @@ -0,0 +1,173 @@ +#include "qrcodedialog.h" +#include "ui_qrcodedialog.h" + +#include "bitcoinunits.h" +#include "guiconstants.h" +#include "guiutil.h" +#include "optionsmodel.h" + +#include +#if QT_VERSION < 0x050000 +#include +#endif + +#include + +QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent) : + QDialog(parent), + ui(new Ui::QRCodeDialog), + model(0), + address(addr) +{ + ui->setupUi(this); + + setWindowTitle(QString("%1").arg(address)); + + ui->chkReqPayment->setVisible(enableReq); + ui->lblAmount->setVisible(enableReq); + ui->lnReqAmount->setVisible(enableReq); + + ui->lnLabel->setText(label); + + ui->btnSaveAs->setEnabled(false); + + genCode(); +} + +QRCodeDialog::~QRCodeDialog() +{ + delete ui; +} + +void QRCodeDialog::setModel(OptionsModel *model) +{ + this->model = model; + + if (model) + connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + + // update the display unit, to not use the default ("BTC") + updateDisplayUnit(); +} + +void QRCodeDialog::genCode() +{ + QString uri = getURI(); + + if (uri != "") + { + ui->lblQRCode->setText(""); + + QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1); + if (!code) + { + ui->lblQRCode->setText(tr("Error encoding URI into QR Code.")); + return; + } + myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + myImage.fill(0xffffff); + unsigned char *p = code->data; + for (int y = 0; y < code->width; y++) + { + for (int x = 0; x < code->width; x++) + { + myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + p++; + } + } + QRcode_free(code); + + ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300)); + + ui->outUri->setPlainText(uri); + } +} + +QString QRCodeDialog::getURI() +{ + QString ret = QString("bitcoin:%1").arg(address); + int paramCount = 0; + + ui->outUri->clear(); + + if (ui->chkReqPayment->isChecked()) + { + if (ui->lnReqAmount->validate()) + { + // even if we allow a non BTC unit input in lnReqAmount, we generate the URI with BTC as unit (as defined in BIP21) + ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, ui->lnReqAmount->value())); + paramCount++; + } + else + { + ui->btnSaveAs->setEnabled(false); + ui->lblQRCode->setText(tr("The entered amount is invalid, please check.")); + return QString(""); + } + } + + if (!ui->lnLabel->text().isEmpty()) + { + QString lbl(QUrl::toPercentEncoding(ui->lnLabel->text())); + ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl); + paramCount++; + } + + if (!ui->lnMessage->text().isEmpty()) + { + QString msg(QUrl::toPercentEncoding(ui->lnMessage->text())); + ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg); + paramCount++; + } + + // limit URI length to prevent a DoS against the QR-Code dialog + if (ret.length() > MAX_URI_LENGTH) + { + ui->btnSaveAs->setEnabled(false); + ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message.")); + return QString(""); + } + + ui->btnSaveAs->setEnabled(true); + return ret; +} + +void QRCodeDialog::on_lnReqAmount_textChanged() +{ + genCode(); +} + +void QRCodeDialog::on_lnLabel_textChanged() +{ + genCode(); +} + +void QRCodeDialog::on_lnMessage_textChanged() +{ + genCode(); +} + +void QRCodeDialog::on_btnSaveAs_clicked() +{ + QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Images (*.png)")); + if (!fn.isEmpty()) + myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn); +} + +void QRCodeDialog::on_chkReqPayment_toggled(bool fChecked) +{ + if (!fChecked) + // if chkReqPayment is not active, don't display lnReqAmount as invalid + ui->lnReqAmount->setValid(true); + + genCode(); +} + +void QRCodeDialog::updateDisplayUnit() +{ + if (model) + { + // Update lnReqAmount with the current unit + ui->lnReqAmount->setDisplayUnit(model->getDisplayUnit()); + } +} diff --git a/src/qt/qrcodedialog.h b/src/qt/qrcodedialog.h new file mode 100644 index 0000000..c55c34b --- /dev/null +++ b/src/qt/qrcodedialog.h @@ -0,0 +1,41 @@ +#ifndef QRCODEDIALOG_H +#define QRCODEDIALOG_H + +#include +#include + +namespace Ui { + class QRCodeDialog; +} +class OptionsModel; + +class QRCodeDialog : public QDialog +{ + Q_OBJECT + +public: + explicit QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent = 0); + ~QRCodeDialog(); + + void setModel(OptionsModel *model); + +private slots: + void on_lnReqAmount_textChanged(); + void on_lnLabel_textChanged(); + void on_lnMessage_textChanged(); + void on_btnSaveAs_clicked(); + void on_chkReqPayment_toggled(bool fChecked); + + void updateDisplayUnit(); + +private: + Ui::QRCodeDialog *ui; + OptionsModel *model; + QString address; + QImage myImage; + + void genCode(); + QString getURI(); +}; + +#endif // QRCODEDIALOG_H diff --git a/src/qt/qtipcserver.cpp b/src/qt/qtipcserver.cpp new file mode 100644 index 0000000..786a74e --- /dev/null +++ b/src/qt/qtipcserver.cpp @@ -0,0 +1,162 @@ +// Copyright (c) 2009-2012 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 +#if defined(WIN32) && BOOST_VERSION == 104900 +#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME +#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME +#endif + +#include "qtipcserver.h" +#include "guiconstants.h" +#include "ui_interface.h" +#include "util.h" + +#include +#include +#include +#include + +#if defined(WIN32) && (!defined(BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME) || !defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) || BOOST_VERSION < 104900) +#warning Compiling without BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME and BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME uncommented in boost/interprocess/detail/tmp_dir_helpers.hpp or using a boost version before 1.49 may have unintended results see svn.boost.org/trac/boost/ticket/5392 +#endif + +using namespace boost; +using namespace boost::interprocess; +using namespace boost::posix_time; + +#if defined MAC_OSX || defined __FreeBSD__ +// URI handling not implemented on OSX yet + +void ipcScanRelay(int argc, char *argv[]) { } +void ipcInit(int argc, char *argv[]) { } + +#else + +static void ipcThread2(void* pArg); + +static bool ipcScanCmd(int argc, char *argv[], bool fRelay) +{ + // Check for URI in argv + bool fSent = false; + for (int i = 1; i < argc; i++) + { + if (boost::algorithm::istarts_with(argv[i], "bitcoin:")) + { + const char *strURI = argv[i]; + try { + boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME); + if (mq.try_send(strURI, strlen(strURI), 0)) + fSent = true; + else if (fRelay) + break; + } + catch (boost::interprocess::interprocess_exception &ex) { + // don't log the "file not found" exception, because that's normal for + // the first start of the first instance + if (ex.get_error_code() != boost::interprocess::not_found_error || !fRelay) + { + printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); + break; + } + } + } + } + return fSent; +} + +void ipcScanRelay(int argc, char *argv[]) +{ + if (ipcScanCmd(argc, argv, true)) + exit(0); +} + +static void ipcThread(void* pArg) +{ + // Make this thread recognisable as the GUI-IPC thread + RenameThread("bitcoin-gui-ipc"); + + try + { + ipcThread2(pArg); + } + catch (std::exception& e) { + PrintExceptionContinue(&e, "ipcThread()"); + } catch (...) { + PrintExceptionContinue(NULL, "ipcThread()"); + } + printf("ipcThread exited\n"); +} + +static void ipcThread2(void* pArg) +{ + printf("ipcThread started\n"); + + message_queue* mq = (message_queue*)pArg; + char buffer[MAX_URI_LENGTH + 1] = ""; + size_t nSize = 0; + unsigned int nPriority = 0; + + while(true) + { + ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100); + if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d)) + { + uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize)); + Sleep(1000); + } + + if (fShutdown) + break; + } + + // Remove message queue + message_queue::remove(BITCOINURI_QUEUE_NAME); + // Cleanup allocated memory + delete mq; +} + +void ipcInit(int argc, char *argv[]) +{ + message_queue* mq = NULL; + char buffer[MAX_URI_LENGTH + 1] = ""; + size_t nSize = 0; + unsigned int nPriority = 0; + + try { + mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH); + + // Make sure we don't lose any bitcoin: URIs + for (int i = 0; i < 2; i++) + { + ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1); + if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d)) + { + uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize)); + } + else + break; + } + + // Make sure only one bitcoin instance is listening + message_queue::remove(BITCOINURI_QUEUE_NAME); + delete mq; + + mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH); + } + catch (interprocess_exception &ex) { + printf("ipcInit() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); + return; + } + + if (!NewThread(ipcThread, mq)) + { + delete mq; + return; + } + + ipcScanCmd(argc, argv, false); +} + +#endif diff --git a/src/qt/qtipcserver.h b/src/qt/qtipcserver.h new file mode 100644 index 0000000..cccf200 --- /dev/null +++ b/src/qt/qtipcserver.h @@ -0,0 +1,10 @@ +#ifndef QTIPCSERVER_H +#define QTIPCSERVER_H + +// Define Bitcoin-Qt message queue name +#define BITCOINURI_QUEUE_NAME "BitcoinURI" + +void ipcScanRelay(int argc, char *argv[]); +void ipcInit(int argc, char *argv[]); + +#endif // QTIPCSERVER_H diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp new file mode 100644 index 0000000..8ca230c --- /dev/null +++ b/src/qt/qvalidatedlineedit.cpp @@ -0,0 +1,45 @@ +#include "qvalidatedlineedit.h" + +#include "guiconstants.h" + +QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) : + QLineEdit(parent), valid(true) +{ + connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid())); +} + +void QValidatedLineEdit::setValid(bool valid) +{ + if(valid == this->valid) + { + return; + } + + if(valid) + { + setStyleSheet(""); + } + else + { + setStyleSheet(STYLE_INVALID); + } + this->valid = valid; +} + +void QValidatedLineEdit::focusInEvent(QFocusEvent *evt) +{ + // Clear invalid flag on focus + setValid(true); + QLineEdit::focusInEvent(evt); +} + +void QValidatedLineEdit::markValid() +{ + setValid(true); +} + +void QValidatedLineEdit::clear() +{ + setValid(true); + QLineEdit::clear(); +} diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h new file mode 100644 index 0000000..66e26be --- /dev/null +++ b/src/qt/qvalidatedlineedit.h @@ -0,0 +1,29 @@ +#ifndef QVALIDATEDLINEEDIT_H +#define QVALIDATEDLINEEDIT_H + +#include + +/** Line edit that can be marked as "invalid" to show input validation feedback. When marked as invalid, + it will get a red background until it is focused. + */ +class QValidatedLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit QValidatedLineEdit(QWidget *parent = 0); + void clear(); + +protected: + void focusInEvent(QFocusEvent *evt); + +private: + bool valid; + +public slots: + void setValid(bool valid); + +private slots: + void markValid(); +}; + +#endif // QVALIDATEDLINEEDIT_H diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp new file mode 100644 index 0000000..d7ce3d0 --- /dev/null +++ b/src/qt/qvaluecombobox.cpp @@ -0,0 +1,27 @@ +#include "qvaluecombobox.h" + +QValueComboBox::QValueComboBox(QWidget *parent) : + QComboBox(parent), role(Qt::UserRole) +{ + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(handleSelectionChanged(int))); +} + +QVariant QValueComboBox::value() const +{ + return itemData(currentIndex(), role); +} + +void QValueComboBox::setValue(const QVariant &value) +{ + setCurrentIndex(findData(value, role)); +} + +void QValueComboBox::setRole(int role) +{ + this->role = role; +} + +void QValueComboBox::handleSelectionChanged(int idx) +{ + emit valueChanged(); +} diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h new file mode 100644 index 0000000..1a47bb6 --- /dev/null +++ b/src/qt/qvaluecombobox.h @@ -0,0 +1,33 @@ +#ifndef QVALUECOMBOBOX_H +#define QVALUECOMBOBOX_H + +#include +#include + +/* QComboBox that can be used with QDataWidgetMapper to select ordinal values from a model. */ +class QValueComboBox : public QComboBox +{ + Q_OBJECT + Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true) +public: + explicit QValueComboBox(QWidget *parent = 0); + + QVariant value() const; + void setValue(const QVariant &value); + + /** Specify model role to use as ordinal value (defaults to Qt::UserRole) */ + void setRole(int role); + +signals: + void valueChanged(); + +public slots: + +private: + int role; + +private slots: + void handleSelectionChanged(int idx); +}; + +#endif // QVALUECOMBOBOX_H diff --git a/src/qt/res/bitcoin-qt.rc b/src/qt/res/bitcoin-qt.rc new file mode 100644 index 0000000..604ec5e --- /dev/null +++ b/src/qt/res/bitcoin-qt.rc @@ -0,0 +1,37 @@ +IDI_ICON1 ICON DISCARDABLE "icons/BERN.ico" + +#include // 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", "BERN" + VALUE "FileDescription", "BERN-Qt (OSS GUI client for BERN)" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "BERN-qt" + VALUE "LegalCopyright", "2009-2012 The Bitcoin developers, 2012-2013 The SoleCoin & PPCoin developers, 2016 BERN developers" + 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", "BERN-qt.exe" + VALUE "ProductName", "BERN-Qt" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) + END +END diff --git a/src/qt/res/icons/BERN-128.png b/src/qt/res/icons/BERN-128.png new file mode 100644 index 0000000..ac4e016 Binary files /dev/null and b/src/qt/res/icons/BERN-128.png differ diff --git a/src/qt/res/icons/BERN-16.png b/src/qt/res/icons/BERN-16.png new file mode 100644 index 0000000..51baab5 Binary files /dev/null and b/src/qt/res/icons/BERN-16.png differ diff --git a/src/qt/res/icons/BERN.icns b/src/qt/res/icons/BERN.icns new file mode 100644 index 0000000..15de88d Binary files /dev/null and b/src/qt/res/icons/BERN.icns differ diff --git a/src/qt/res/icons/BERN.ico b/src/qt/res/icons/BERN.ico new file mode 100644 index 0000000..73cb8e8 Binary files /dev/null and b/src/qt/res/icons/BERN.ico differ diff --git a/src/qt/res/icons/BERN.png b/src/qt/res/icons/BERN.png new file mode 100644 index 0000000..daa4e3b Binary files /dev/null and b/src/qt/res/icons/BERN.png differ diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png new file mode 100644 index 0000000..f98e2a8 Binary files /dev/null and b/src/qt/res/icons/add.png differ diff --git a/src/qt/res/icons/address-book.png b/src/qt/res/icons/address-book.png new file mode 100644 index 0000000..0945d39 Binary files /dev/null and b/src/qt/res/icons/address-book.png differ diff --git a/src/qt/res/icons/bitcoin.png b/src/qt/res/icons/bitcoin.png new file mode 100644 index 0000000..daa4e3b Binary files /dev/null and b/src/qt/res/icons/bitcoin.png differ diff --git a/src/qt/res/icons/bitcoin_testnet.png b/src/qt/res/icons/bitcoin_testnet.png new file mode 100644 index 0000000..daa4e3b Binary files /dev/null and b/src/qt/res/icons/bitcoin_testnet.png differ diff --git a/src/qt/res/icons/block.png b/src/qt/res/icons/block.png new file mode 100644 index 0000000..8382275 Binary files /dev/null and b/src/qt/res/icons/block.png differ diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png new file mode 100644 index 0000000..448e47f Binary files /dev/null and b/src/qt/res/icons/clock1.png differ diff --git a/src/qt/res/icons/clock2.png b/src/qt/res/icons/clock2.png new file mode 100644 index 0000000..c1a6e99 Binary files /dev/null and b/src/qt/res/icons/clock2.png differ diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png new file mode 100644 index 0000000..e429a40 Binary files /dev/null and b/src/qt/res/icons/clock3.png differ diff --git a/src/qt/res/icons/clock4.png b/src/qt/res/icons/clock4.png new file mode 100644 index 0000000..ba036f4 Binary files /dev/null and b/src/qt/res/icons/clock4.png differ diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png new file mode 100644 index 0000000..411d7a7 Binary files /dev/null and b/src/qt/res/icons/clock5.png differ diff --git a/src/qt/res/icons/configure.png b/src/qt/res/icons/configure.png new file mode 100644 index 0000000..95bd319 Binary files /dev/null and b/src/qt/res/icons/configure.png differ diff --git a/src/qt/res/icons/connect0_16.png b/src/qt/res/icons/connect0_16.png new file mode 100644 index 0000000..66f3ae4 Binary files /dev/null and b/src/qt/res/icons/connect0_16.png differ diff --git a/src/qt/res/icons/connect1_16.png b/src/qt/res/icons/connect1_16.png new file mode 100644 index 0000000..76000be Binary files /dev/null and b/src/qt/res/icons/connect1_16.png differ diff --git a/src/qt/res/icons/connect2_16.png b/src/qt/res/icons/connect2_16.png new file mode 100644 index 0000000..6d9a372 Binary files /dev/null and b/src/qt/res/icons/connect2_16.png differ diff --git a/src/qt/res/icons/connect3_16.png b/src/qt/res/icons/connect3_16.png new file mode 100644 index 0000000..a211700 Binary files /dev/null and b/src/qt/res/icons/connect3_16.png differ diff --git a/src/qt/res/icons/connect4_16.png b/src/qt/res/icons/connect4_16.png new file mode 100644 index 0000000..c1232f5 Binary files /dev/null and b/src/qt/res/icons/connect4_16.png differ diff --git a/src/qt/res/icons/debugwindow.png b/src/qt/res/icons/debugwindow.png new file mode 100644 index 0000000..dffdb09 Binary files /dev/null and b/src/qt/res/icons/debugwindow.png differ diff --git a/src/qt/res/icons/edit.png b/src/qt/res/icons/edit.png new file mode 100644 index 0000000..1d69145 Binary files /dev/null and b/src/qt/res/icons/edit.png differ diff --git a/src/qt/res/icons/editcopy.png b/src/qt/res/icons/editcopy.png new file mode 100644 index 0000000..f882aa2 Binary files /dev/null and b/src/qt/res/icons/editcopy.png differ diff --git a/src/qt/res/icons/editpaste.png b/src/qt/res/icons/editpaste.png new file mode 100644 index 0000000..a192060 Binary files /dev/null and b/src/qt/res/icons/editpaste.png differ diff --git a/src/qt/res/icons/export.png b/src/qt/res/icons/export.png new file mode 100644 index 0000000..205d4cd Binary files /dev/null and b/src/qt/res/icons/export.png differ diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png new file mode 100644 index 0000000..ae13a15 Binary files /dev/null and b/src/qt/res/icons/filesave.png differ diff --git a/src/qt/res/icons/history.png b/src/qt/res/icons/history.png new file mode 100644 index 0000000..a90ee0b Binary files /dev/null and b/src/qt/res/icons/history.png differ diff --git a/src/qt/res/icons/key.png b/src/qt/res/icons/key.png new file mode 100644 index 0000000..ece0164 Binary files /dev/null and b/src/qt/res/icons/key.png differ diff --git a/src/qt/res/icons/lock_closed.png b/src/qt/res/icons/lock_closed.png new file mode 100644 index 0000000..c566510 Binary files /dev/null and b/src/qt/res/icons/lock_closed.png differ diff --git a/src/qt/res/icons/lock_open.png b/src/qt/res/icons/lock_open.png new file mode 100644 index 0000000..c98ca86 Binary files /dev/null and b/src/qt/res/icons/lock_open.png differ diff --git a/src/qt/res/icons/mining.png b/src/qt/res/icons/mining.png new file mode 100644 index 0000000..72b067a Binary files /dev/null and b/src/qt/res/icons/mining.png differ diff --git a/src/qt/res/icons/nosynced.png b/src/qt/res/icons/nosynced.png new file mode 100644 index 0000000..74c3cbf Binary files /dev/null and b/src/qt/res/icons/nosynced.png differ diff --git a/src/qt/res/icons/notsynced.png b/src/qt/res/icons/notsynced.png new file mode 100644 index 0000000..c9e7118 Binary files /dev/null and b/src/qt/res/icons/notsynced.png differ diff --git a/src/qt/res/icons/overview.png b/src/qt/res/icons/overview.png new file mode 100644 index 0000000..1c69fc2 Binary files /dev/null and b/src/qt/res/icons/overview.png differ diff --git a/src/qt/res/icons/powmining_active.png b/src/qt/res/icons/powmining_active.png new file mode 100644 index 0000000..040fdab Binary files /dev/null and b/src/qt/res/icons/powmining_active.png differ diff --git a/src/qt/res/icons/powmining_inactive.png b/src/qt/res/icons/powmining_inactive.png new file mode 100644 index 0000000..227f505 Binary files /dev/null and b/src/qt/res/icons/powmining_inactive.png differ diff --git a/src/qt/res/icons/qrcode.png b/src/qt/res/icons/qrcode.png new file mode 100644 index 0000000..a8d9717 Binary files /dev/null and b/src/qt/res/icons/qrcode.png differ diff --git a/src/qt/res/icons/quit.png b/src/qt/res/icons/quit.png new file mode 100644 index 0000000..0dde6f3 Binary files /dev/null and b/src/qt/res/icons/quit.png differ diff --git a/src/qt/res/icons/receive.png b/src/qt/res/icons/receive.png new file mode 100644 index 0000000..e6787f5 Binary files /dev/null and b/src/qt/res/icons/receive.png differ diff --git a/src/qt/res/icons/remove.png b/src/qt/res/icons/remove.png new file mode 100644 index 0000000..a44b6d1 Binary files /dev/null and b/src/qt/res/icons/remove.png differ diff --git a/src/qt/res/icons/send.png b/src/qt/res/icons/send.png new file mode 100644 index 0000000..0269347 Binary files /dev/null and b/src/qt/res/icons/send.png differ diff --git a/src/qt/res/icons/staking_off.png b/src/qt/res/icons/staking_off.png new file mode 100644 index 0000000..91e570e Binary files /dev/null and b/src/qt/res/icons/staking_off.png differ diff --git a/src/qt/res/icons/staking_on.png b/src/qt/res/icons/staking_on.png new file mode 100644 index 0000000..1a5e8c2 Binary files /dev/null and b/src/qt/res/icons/staking_on.png differ diff --git a/src/qt/res/icons/statistics.png b/src/qt/res/icons/statistics.png new file mode 100644 index 0000000..13bd5b4 Binary files /dev/null and b/src/qt/res/icons/statistics.png differ diff --git a/src/qt/res/icons/synced.png b/src/qt/res/icons/synced.png new file mode 100644 index 0000000..4d7e0e8 Binary files /dev/null and b/src/qt/res/icons/synced.png differ diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png new file mode 100644 index 0000000..4578666 Binary files /dev/null and b/src/qt/res/icons/transaction0.png differ diff --git a/src/qt/res/icons/transaction2.png b/src/qt/res/icons/transaction2.png new file mode 100644 index 0000000..01bb558 Binary files /dev/null and b/src/qt/res/icons/transaction2.png differ diff --git a/src/qt/res/icons/transaction_conflicted.png b/src/qt/res/icons/transaction_conflicted.png new file mode 100644 index 0000000..51fff64 Binary files /dev/null and b/src/qt/res/icons/transaction_conflicted.png differ diff --git a/src/qt/res/icons/tx_inout.png b/src/qt/res/icons/tx_inout.png new file mode 100644 index 0000000..5f092f9 Binary files /dev/null and b/src/qt/res/icons/tx_inout.png differ diff --git a/src/qt/res/icons/tx_input.png b/src/qt/res/icons/tx_input.png new file mode 100644 index 0000000..0f5fea3 Binary files /dev/null and b/src/qt/res/icons/tx_input.png differ diff --git a/src/qt/res/icons/tx_mined.png b/src/qt/res/icons/tx_mined.png new file mode 100644 index 0000000..613f30f Binary files /dev/null and b/src/qt/res/icons/tx_mined.png differ diff --git a/src/qt/res/icons/tx_output.png b/src/qt/res/icons/tx_output.png new file mode 100644 index 0000000..9ae39fb Binary files /dev/null and b/src/qt/res/icons/tx_output.png differ diff --git a/src/qt/res/images/about.png b/src/qt/res/images/about.png new file mode 100644 index 0000000..7f3e29c Binary files /dev/null and b/src/qt/res/images/about.png differ diff --git a/src/qt/res/images/shadow9202.png b/src/qt/res/images/shadow9202.png new file mode 100644 index 0000000..b0ef36f Binary files /dev/null and b/src/qt/res/images/shadow9202.png differ diff --git a/src/qt/res/images/splash.png b/src/qt/res/images/splash.png new file mode 100644 index 0000000..daa4e3b Binary files /dev/null and b/src/qt/res/images/splash.png differ diff --git a/src/qt/res/images/splash_testnet.png b/src/qt/res/images/splash_testnet.png new file mode 100644 index 0000000..daa4e3b Binary files /dev/null and b/src/qt/res/images/splash_testnet.png differ diff --git a/src/qt/res/images/wallet.png b/src/qt/res/images/wallet.png new file mode 100644 index 0000000..daa4e3b Binary files /dev/null and b/src/qt/res/images/wallet.png differ diff --git a/src/qt/res/movies/update_spinner.mng b/src/qt/res/movies/update_spinner.mng new file mode 100644 index 0000000..7df3baa Binary files /dev/null and b/src/qt/res/movies/update_spinner.mng differ diff --git a/src/qt/res/src/bitcoin.svg b/src/qt/res/src/bitcoin.svg new file mode 100644 index 0000000..96f1017 --- /dev/null +++ b/src/qt/res/src/bitcoin.svg @@ -0,0 +1,115 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock1.svg b/src/qt/res/src/clock1.svg new file mode 100644 index 0000000..793dc7f --- /dev/null +++ b/src/qt/res/src/clock1.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock2.svg b/src/qt/res/src/clock2.svg new file mode 100644 index 0000000..6a78adf --- /dev/null +++ b/src/qt/res/src/clock2.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock3.svg b/src/qt/res/src/clock3.svg new file mode 100644 index 0000000..09ccc25 --- /dev/null +++ b/src/qt/res/src/clock3.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock4.svg b/src/qt/res/src/clock4.svg new file mode 100644 index 0000000..7d9dc37 --- /dev/null +++ b/src/qt/res/src/clock4.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock5.svg b/src/qt/res/src/clock5.svg new file mode 100644 index 0000000..9fd58d9 --- /dev/null +++ b/src/qt/res/src/clock5.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock_green.svg b/src/qt/res/src/clock_green.svg new file mode 100644 index 0000000..e31f0e7 --- /dev/null +++ b/src/qt/res/src/clock_green.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/inout.svg b/src/qt/res/src/inout.svg new file mode 100644 index 0000000..bfab8ef --- /dev/null +++ b/src/qt/res/src/inout.svg @@ -0,0 +1,122 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/questionmark.svg b/src/qt/res/src/questionmark.svg new file mode 100644 index 0000000..c03c159 --- /dev/null +++ b/src/qt/res/src/questionmark.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ? + ? + + + ? + + diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp new file mode 100644 index 0000000..86122a1 --- /dev/null +++ b/src/qt/rpcconsole.cpp @@ -0,0 +1,439 @@ +#include "rpcconsole.h" +#include "ui_rpcconsole.h" + +#include "clientmodel.h" +#include "bitcoinrpc.h" +#include "guiutil.h" + +#include +#include +#include +#include +#include +#if QT_VERSION < 0x050000 +#include +#endif +#include + +#include + +// TODO: make it possible to filter out categories (esp debug messages when implemented) +// TODO: receive errors and debug messages through ClientModel + +const int CONSOLE_SCROLLBACK = 50; +const int CONSOLE_HISTORY = 50; + +const QSize ICON_SIZE(24, 24); + +const struct { + const char *url; + const char *source; +} ICON_MAPPING[] = { + {"cmd-request", ":/icons/tx_input"}, + {"cmd-reply", ":/icons/tx_output"}, + {"cmd-error", ":/icons/tx_output"}, + {"misc", ":/icons/tx_inout"}, + {NULL, NULL} +}; + +/* Object for executing console RPC commands in a separate thread. +*/ +class RPCExecutor: public QObject +{ + Q_OBJECT +public slots: + void start(); + void request(const QString &command); +signals: + void reply(int category, const QString &command); +}; + +#include "rpcconsole.moc" + +void RPCExecutor::start() +{ + // Nothing to do +} + +/** + * Split shell command line into a list of arguments. Aims to emulate \c bash and friends. + * + * - Arguments are delimited with whitespace + * - Extra whitespace at the beginning and end and between arguments will be ignored + * - Text can be "double" or 'single' quoted + * - The backslash \c \ is used as escape character + * - Outside quotes, any character can be escaped + * - Within double quotes, only escape \c " and backslashes before a \c " or another backslash + * - Within single quotes, no escaping is possible and no special interpretation takes place + * + * @param[out] args Parsed arguments will be appended to this list + * @param[in] strCommand Command line to split + */ +bool parseCommandLine(std::vector &args, const std::string &strCommand) +{ + enum CmdParseState + { + STATE_EATING_SPACES, + STATE_ARGUMENT, + STATE_SINGLEQUOTED, + STATE_DOUBLEQUOTED, + STATE_ESCAPE_OUTER, + STATE_ESCAPE_DOUBLEQUOTED + } state = STATE_EATING_SPACES; + std::string curarg; + foreach(char ch, strCommand) + { + switch(state) + { + case STATE_ARGUMENT: // In or after argument + case STATE_EATING_SPACES: // Handle runs of whitespace + switch(ch) + { + case '"': state = STATE_DOUBLEQUOTED; break; + case '\'': state = STATE_SINGLEQUOTED; break; + case '\\': state = STATE_ESCAPE_OUTER; break; + case ' ': case '\n': case '\t': + if(state == STATE_ARGUMENT) // Space ends argument + { + args.push_back(curarg); + curarg.clear(); + } + state = STATE_EATING_SPACES; + break; + default: curarg += ch; state = STATE_ARGUMENT; + } + break; + case STATE_SINGLEQUOTED: // Single-quoted string + switch(ch) + { + case '\'': state = STATE_ARGUMENT; break; + default: curarg += ch; + } + break; + case STATE_DOUBLEQUOTED: // Double-quoted string + switch(ch) + { + case '"': state = STATE_ARGUMENT; break; + case '\\': state = STATE_ESCAPE_DOUBLEQUOTED; break; + default: curarg += ch; + } + break; + case STATE_ESCAPE_OUTER: // '\' outside quotes + curarg += ch; state = STATE_ARGUMENT; + break; + case STATE_ESCAPE_DOUBLEQUOTED: // '\' in double-quoted text + if(ch != '"' && ch != '\\') curarg += '\\'; // keep '\' for everything but the quote and '\' itself + curarg += ch; state = STATE_DOUBLEQUOTED; + break; + } + } + switch(state) // final state + { + case STATE_EATING_SPACES: + return true; + case STATE_ARGUMENT: + args.push_back(curarg); + return true; + default: // ERROR to end in one of the other states + return false; + } +} + +void RPCExecutor::request(const QString &command) +{ + std::vector args; + if(!parseCommandLine(args, command.toStdString())) + { + emit reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \"")); + return; + } + if(args.empty()) + return; // Nothing to do + try + { + std::string strPrint; + // Convert argument list to JSON objects in method-dependent way, + // and pass it along with the method name to the dispatcher. + json_spirit::Value result = tableRPC.execute( + args[0], + RPCConvertValues(args[0], std::vector(args.begin() + 1, args.end()))); + + // Format result reply + if (result.type() == json_spirit::null_type) + strPrint = ""; + else if (result.type() == json_spirit::str_type) + strPrint = result.get_str(); + else + strPrint = write_string(result, true); + + emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); + } + catch (json_spirit::Object& objError) + { + try // Nice formatting for standard-format error + { + int code = find_value(objError, "code").get_int(); + std::string message = find_value(objError, "message").get_str(); + emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); + } + catch(std::runtime_error &) // raised when converting to invalid type, i.e. missing code or message + { // Show raw JSON object + emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false))); + } + } + catch (std::exception& e) + { + emit reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what())); + } +} + +RPCConsole::RPCConsole(QWidget *parent) : + QDialog(parent), + ui(new Ui::RPCConsole), + historyPtr(0) +{ + ui->setupUi(this); + +#ifndef Q_OS_MAC + ui->openDebugLogfileButton->setIcon(QIcon(":/icons/export")); + ui->showCLOptionsButton->setIcon(QIcon(":/icons/options")); +#endif + + // Install event filter for up and down arrow + ui->lineEdit->installEventFilter(this); + ui->messagesWidget->installEventFilter(this); + + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); + + // set OpenSSL version label + ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); + + startExecutor(); + + clear(); +} + +RPCConsole::~RPCConsole() +{ + emit stopExecutor(); + delete ui; +} + +bool RPCConsole::eventFilter(QObject* obj, QEvent *event) +{ + if(event->type() == QEvent::KeyPress) // Special key handling + { + QKeyEvent *keyevt = static_cast(event); + int key = keyevt->key(); + Qt::KeyboardModifiers mod = keyevt->modifiers(); + switch(key) + { + case Qt::Key_Up: if(obj == ui->lineEdit) { browseHistory(-1); return true; } break; + case Qt::Key_Down: if(obj == ui->lineEdit) { browseHistory(1); return true; } break; + case Qt::Key_PageUp: /* pass paging keys to messages widget */ + case Qt::Key_PageDown: + if(obj == ui->lineEdit) + { + QApplication::postEvent(ui->messagesWidget, new QKeyEvent(*keyevt)); + return true; + } + break; + default: + // Typing in messages widget brings focus to line edit, and redirects key there + // Exclude most combinations and keys that emit no text, except paste shortcuts + if(obj == ui->messagesWidget && ( + (!mod && !keyevt->text().isEmpty() && key != Qt::Key_Tab) || + ((mod & Qt::ControlModifier) && key == Qt::Key_V) || + ((mod & Qt::ShiftModifier) && key == Qt::Key_Insert))) + { + ui->lineEdit->setFocus(); + QApplication::postEvent(ui->lineEdit, new QKeyEvent(*keyevt)); + return true; + } + } + } + return QDialog::eventFilter(obj, event); +} + +void RPCConsole::setClientModel(ClientModel *model) +{ + this->clientModel = model; + if(model) + { + // Subscribe to information, replies, messages, errors + connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); + connect(model, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int))); + + // Provide initial values + ui->clientVersion->setText(model->formatFullVersion()); + ui->clientName->setText(model->clientName()); + ui->buildDate->setText(model->formatBuildDate()); + ui->startupTime->setText(model->formatClientStartupTime()); + + setNumConnections(model->getNumConnections()); + ui->isTestNet->setChecked(model->isTestNet()); + + setNumBlocks(model->getNumBlocks(), model->getNumBlocksOfPeers()); + } +} + +static QString categoryClass(int category) +{ + switch(category) + { + case RPCConsole::CMD_REQUEST: return "cmd-request"; break; + case RPCConsole::CMD_REPLY: return "cmd-reply"; break; + case RPCConsole::CMD_ERROR: return "cmd-error"; break; + default: return "misc"; + } +} + +void RPCConsole::clear() +{ + ui->messagesWidget->clear(); + ui->lineEdit->clear(); + ui->lineEdit->setFocus(); + + // Add smoothly scaled icon images. + // (when using width/height on an img, Qt uses nearest instead of linear interpolation) + for(int i=0; ICON_MAPPING[i].url; ++i) + { + ui->messagesWidget->document()->addResource( + QTextDocument::ImageResource, + QUrl(ICON_MAPPING[i].url), + QImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + } + + // Set default style sheet + ui->messagesWidget->document()->setDefaultStyleSheet( + "table { }" + "td.time { color: #808080; padding-top: 3px; } " + "td.message { font-family: Monospace; font-size: 12px; } " + "td.cmd-request { color: #006060; } " + "td.cmd-error { color: red; } " + "b { color: #006060; } " + ); + + message(CMD_REPLY, (tr("Welcome to the BERN RPC console.") + "
" + + tr("Use up and down arrows to navigate history, and Ctrl-L to clear screen.") + "
" + + tr("Type help for an overview of available commands.")), true); +} + +void RPCConsole::message(int category, const QString &message, bool html) +{ + QTime time = QTime::currentTime(); + QString timeString = time.toString(); + QString out; + out += ""; + out += ""; + out += "
" + timeString + ""; + if(html) + out += message; + else + out += GUIUtil::HtmlEscape(message, true); + out += "
"; + ui->messagesWidget->append(out); +} + +void RPCConsole::setNumConnections(int count) +{ + ui->numberOfConnections->setText(QString::number(count)); +} + +void RPCConsole::setNumBlocks(int count, int countOfPeers) +{ + ui->numberOfBlocks->setText(QString::number(count)); + ui->totalBlocks->setText(QString::number(countOfPeers)); + if(clientModel) + { + // If there is no current number available display N/A instead of 0, which can't ever be true + ui->totalBlocks->setText(clientModel->getNumBlocksOfPeers() == 0 ? tr("N/A") : QString::number(clientModel->getNumBlocksOfPeers())); + ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString()); + } +} + +void RPCConsole::on_lineEdit_returnPressed() +{ + QString cmd = ui->lineEdit->text(); + ui->lineEdit->clear(); + + if(!cmd.isEmpty()) + { + message(CMD_REQUEST, cmd); + emit cmdRequest(cmd); + // Truncate history from current position + history.erase(history.begin() + historyPtr, history.end()); + // Append command to history + history.append(cmd); + // Enforce maximum history size + while(history.size() > CONSOLE_HISTORY) + history.removeFirst(); + // Set pointer to end of history + historyPtr = history.size(); + // Scroll console view to end + scrollToEnd(); + } +} + +void RPCConsole::browseHistory(int offset) +{ + historyPtr += offset; + if(historyPtr < 0) + historyPtr = 0; + if(historyPtr > history.size()) + historyPtr = history.size(); + QString cmd; + if(historyPtr < history.size()) + cmd = history.at(historyPtr); + ui->lineEdit->setText(cmd); +} + +void RPCConsole::startExecutor() +{ + QThread* thread = new QThread; + RPCExecutor *executor = new RPCExecutor(); + executor->moveToThread(thread); + + // Notify executor when thread started (in executor thread) + connect(thread, SIGNAL(started()), executor, SLOT(start())); + // Replies from executor object must go to this object + connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString))); + // Requests from this object must go to executor + connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString))); + // On stopExecutor signal + // - queue executor for deletion (in execution thread) + // - quit the Qt event loop in the execution thread + connect(this, SIGNAL(stopExecutor()), executor, SLOT(deleteLater())); + connect(this, SIGNAL(stopExecutor()), thread, SLOT(quit())); + // Queue the thread for deletion (in this thread) when it is finished + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + + // Default implementation of QThread::run() simply spins up an event loop in the thread, + // which is what we want. + thread->start(); +} + +void RPCConsole::on_tabWidget_currentChanged(int index) +{ + if(ui->tabWidget->widget(index) == ui->tab_console) + { + ui->lineEdit->setFocus(); + } +} + +void RPCConsole::on_openDebugLogfileButton_clicked() +{ + GUIUtil::openDebugLogfile(); +} + +void RPCConsole::scrollToEnd() +{ + QScrollBar *scrollbar = ui->messagesWidget->verticalScrollBar(); + scrollbar->setValue(scrollbar->maximum()); +} + +void RPCConsole::on_showCLOptionsButton_clicked() +{ + GUIUtil::HelpMessageBox help; + help.exec(); +} diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h new file mode 100644 index 0000000..3c38b4b --- /dev/null +++ b/src/qt/rpcconsole.h @@ -0,0 +1,66 @@ +#ifndef RPCCONSOLE_H +#define RPCCONSOLE_H + +#include + +namespace Ui { + class RPCConsole; +} +class ClientModel; + +/** Local Bitcoin RPC console. */ +class RPCConsole: public QDialog +{ + Q_OBJECT + +public: + explicit RPCConsole(QWidget *parent = 0); + ~RPCConsole(); + + void setClientModel(ClientModel *model); + + enum MessageClass { + MC_ERROR, + MC_DEBUG, + CMD_REQUEST, + CMD_REPLY, + CMD_ERROR + }; + +protected: + virtual bool eventFilter(QObject* obj, QEvent *event); + +private slots: + void on_lineEdit_returnPressed(); + void on_tabWidget_currentChanged(int index); + /** open the debug.log from the current datadir */ + void on_openDebugLogfileButton_clicked(); + /** display messagebox with program parameters (same as bitcoin-qt --help) */ + void on_showCLOptionsButton_clicked(); + +public slots: + void clear(); + void message(int category, const QString &message, bool html = false); + /** Set number of connections shown in the UI */ + void setNumConnections(int count); + /** Set number of blocks shown in the UI */ + void setNumBlocks(int count, int countOfPeers); + /** Go forward or back in history */ + void browseHistory(int offset); + /** Scroll console view to end */ + void scrollToEnd(); +signals: + // For RPC command executor + void stopExecutor(); + void cmdRequest(const QString &command); + +private: + Ui::RPCConsole *ui; + ClientModel *clientModel; + QStringList history; + int historyPtr; + + void startExecutor(); +}; + +#endif // RPCCONSOLE_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp new file mode 100644 index 0000000..b6d5c15 --- /dev/null +++ b/src/qt/sendcoinsdialog.cpp @@ -0,0 +1,521 @@ +#include "sendcoinsdialog.h" +#include "ui_sendcoinsdialog.h" +#include "init.h" +#include "walletmodel.h" +#include "addresstablemodel.h" +#include "addressbookpage.h" +#include "bitcoinunits.h" +#include "addressbookpage.h" +#include "optionsmodel.h" +#include "sendcoinsentry.h" +#include "guiutil.h" +#include "askpassphrasedialog.h" +#include "coincontrol.h" +#include "coincontroldialog.h" + +#include +#include +#include +#include +#include + +SendCoinsDialog::SendCoinsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SendCoinsDialog), + model(0) +{ + ui->setupUi(this); + +#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac + ui->addButton->setIcon(QIcon()); + ui->clearButton->setIcon(QIcon()); + ui->sendButton->setIcon(QIcon()); +#endif + +#if QT_VERSION >= 0x040700 + /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + ui->lineEditCoinControlChange->setPlaceholderText(tr("Enter a BERN address (e.g. B3rN1WgLDe7STSwTwLwSaKuATN5M74EL76)")); +#endif + + addEntry(); + + connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry())); + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); + + // Coin Control + ui->lineEditCoinControlChange->setFont(GUIUtil::bitcoinAddressFont()); + connect(ui->pushButtonCoinControl, SIGNAL(clicked()), this, SLOT(coinControlButtonClicked())); + connect(ui->checkBoxCoinControlChange, SIGNAL(stateChanged(int)), this, SLOT(coinControlChangeChecked(int))); + connect(ui->lineEditCoinControlChange, SIGNAL(textEdited(const QString &)), this, SLOT(coinControlChangeEdited(const QString &))); + + // Coin Control: clipboard actions + QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this); + QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this); + QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this); + QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this); + QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this); + QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this); + QAction *clipboardLowOutputAction = new QAction(tr("Copy low output"), this); + QAction *clipboardChangeAction = new QAction(tr("Copy change"), this); + connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardQuantity())); + connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAmount())); + connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardFee())); + connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAfterFee())); + connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardBytes())); + connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardPriority())); + connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardLowOutput())); + connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardChange())); + ui->labelCoinControlQuantity->addAction(clipboardQuantityAction); + ui->labelCoinControlAmount->addAction(clipboardAmountAction); + ui->labelCoinControlFee->addAction(clipboardFeeAction); + ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction); + ui->labelCoinControlBytes->addAction(clipboardBytesAction); + ui->labelCoinControlPriority->addAction(clipboardPriorityAction); + ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction); + ui->labelCoinControlChange->addAction(clipboardChangeAction); + + fNewRecipientAllowed = true; +} + +void SendCoinsDialog::setModel(WalletModel *model) +{ + this->model = model; + + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + { + entry->setModel(model); + } + } + if(model && model->getOptionsModel()) + { + setBalance(model->getBalance(), model->getStake(), model->getUnconfirmedBalance(), model->getImmatureBalance()); + connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64))); + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + + // Coin Control + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels())); + connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool))); + connect(model->getOptionsModel(), SIGNAL(transactionFeeChanged(qint64)), this, SLOT(coinControlUpdateLabels())); + ui->frameCoinControl->setVisible(model->getOptionsModel()->getCoinControlFeatures()); + coinControlUpdateLabels(); + } +} + +SendCoinsDialog::~SendCoinsDialog() +{ + delete ui; +} + + +void SendCoinsDialog::on_sendButton_clicked() +{ + QList recipients; + bool valid = true; + + if(!model) + return; + + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + { + if(entry->validate()) + { + recipients.append(entry->getValue()); + } + else + { + valid = false; + } + } + } + + if(!valid || recipients.isEmpty()) + { + return; + } + + // Format confirmation message + QStringList formatted; + foreach(const SendCoinsRecipient &rcp, recipients) + { +#if QT_VERSION < 0x050000 + formatted.append(tr("%1 to %2 (%3)").arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, rcp.amount), Qt::escape(rcp.label), rcp.address)); +#else + formatted.append(tr("%1 to %2 (%3)").arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, rcp.amount), rcp.label.toHtmlEscaped(), rcp.address)); +#endif + } + + fNewRecipientAllowed = false; + + QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"), + tr("Are you sure you want to send %1?").arg(formatted.join(tr(" and "))), + QMessageBox::Yes|QMessageBox::Cancel, + QMessageBox::Cancel); + + if(retval != QMessageBox::Yes) + { + fNewRecipientAllowed = true; + return; + } + + WalletModel::UnlockContext ctx(model->requestUnlock()); + if(!ctx.isValid()) + { + // Unlock wallet was cancelled + fNewRecipientAllowed = true; + return; + } + + WalletModel::SendCoinsReturn sendstatus; + + if (!model->getOptionsModel() || !model->getOptionsModel()->getCoinControlFeatures()) + sendstatus = model->sendCoins(recipients); + else + sendstatus = model->sendCoins(recipients, CoinControlDialog::coinControl); + + switch(sendstatus.status) + { + case WalletModel::InvalidAddress: + QMessageBox::warning(this, tr("Send Coins"), + tr("The recipient address is not valid, please recheck."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::InvalidAmount: + QMessageBox::warning(this, tr("Send Coins"), + tr("The amount to pay must be larger than 0."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::AmountExceedsBalance: + QMessageBox::warning(this, tr("Send Coins"), + tr("The amount exceeds your balance."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::AmountWithFeeExceedsBalance: + QMessageBox::warning(this, tr("Send Coins"), + tr("The total exceeds your balance when the %1 transaction fee is included."). + arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, sendstatus.fee)), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::DuplicateAddress: + QMessageBox::warning(this, tr("Send Coins"), + tr("Duplicate address found, can only send to each address once per send operation."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::TransactionCreationFailed: + QMessageBox::warning(this, tr("Send Coins"), + tr("Error: Transaction creation failed."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::TransactionCommitFailed: + QMessageBox::warning(this, tr("Send Coins"), + tr("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::Aborted: // User aborted, nothing to do + break; + case WalletModel::OK: + accept(); + CoinControlDialog::coinControl->UnSelectAll(); + coinControlUpdateLabels(); + break; + } + fNewRecipientAllowed = true; +} + +void SendCoinsDialog::clear() +{ + // Remove entries until only one left + while(ui->entries->count()) + { + delete ui->entries->takeAt(0)->widget(); + } + addEntry(); + + updateRemoveEnabled(); + + ui->sendButton->setDefault(true); +} + +void SendCoinsDialog::reject() +{ + clear(); +} + +void SendCoinsDialog::accept() +{ + clear(); +} + +SendCoinsEntry *SendCoinsDialog::addEntry() +{ + SendCoinsEntry *entry = new SendCoinsEntry(this); + entry->setModel(model); + ui->entries->addWidget(entry); + connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*))); + connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels())); + + updateRemoveEnabled(); + + // Focus the field, so that entry can start immediately + entry->clear(); + entry->setFocus(); + ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint()); + QCoreApplication::instance()->processEvents(); + QScrollBar* bar = ui->scrollArea->verticalScrollBar(); + if(bar) + bar->setSliderPosition(bar->maximum()); + return entry; +} + +void SendCoinsDialog::updateRemoveEnabled() +{ + // Remove buttons are enabled as soon as there is more than one send-entry + bool enabled = (ui->entries->count() > 1); + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + { + entry->setRemoveEnabled(enabled); + } + } + setupTabChain(0); + coinControlUpdateLabels(); +} + +void SendCoinsDialog::removeEntry(SendCoinsEntry* entry) +{ + delete entry; + updateRemoveEnabled(); +} + +QWidget *SendCoinsDialog::setupTabChain(QWidget *prev) +{ + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + { + prev = entry->setupTabChain(prev); + } + } + QWidget::setTabOrder(prev, ui->addButton); + QWidget::setTabOrder(ui->addButton, ui->sendButton); + return ui->sendButton; +} + +void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) +{ + if(!fNewRecipientAllowed) + return; + + SendCoinsEntry *entry = 0; + // Replace the first entry if it is still unused + if(ui->entries->count() == 1) + { + SendCoinsEntry *first = qobject_cast(ui->entries->itemAt(0)->widget()); + if(first->isClear()) + { + entry = first; + } + } + if(!entry) + { + entry = addEntry(); + } + + entry->setValue(rv); +} + +bool SendCoinsDialog::handleURI(const QString &uri) +{ + SendCoinsRecipient rv; + // URI has to be valid + if (GUIUtil::parseBitcoinURI(uri, &rv)) + { + CBitcoinAddress address(rv.address.toStdString()); + if (!address.IsValid()) + return false; + pasteEntry(rv); + return true; + } + + return false; +} + +void SendCoinsDialog::setBalance(qint64 balance, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance) +{ + Q_UNUSED(stake); + Q_UNUSED(unconfirmedBalance); + Q_UNUSED(immatureBalance); + if(!model || !model->getOptionsModel()) + return; + + int unit = model->getOptionsModel()->getDisplayUnit(); + ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance)); +} + +void SendCoinsDialog::updateDisplayUnit() +{ + if(model && model->getOptionsModel()) + { + // Update labelBalance with the current balance and the current unit + ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->getBalance())); + } +} + + // Coin Control: copy label "Quantity" to clipboard + void SendCoinsDialog::coinControlClipboardQuantity() + { + QApplication::clipboard()->setText(ui->labelCoinControlQuantity->text()); + } + + // Coin Control: copy label "Amount" to clipboard + void SendCoinsDialog::coinControlClipboardAmount() + { + QApplication::clipboard()->setText(ui->labelCoinControlAmount->text().left(ui->labelCoinControlAmount->text().indexOf(" "))); + } + + // Coin Control: copy label "Fee" to clipboard + void SendCoinsDialog::coinControlClipboardFee() + { + QApplication::clipboard()->setText(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" "))); + } + + // Coin Control: copy label "After fee" to clipboard + void SendCoinsDialog::coinControlClipboardAfterFee() + { + QApplication::clipboard()->setText(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" "))); + } + + // Coin Control: copy label "Bytes" to clipboard + void SendCoinsDialog::coinControlClipboardBytes() + { + QApplication::clipboard()->setText(ui->labelCoinControlBytes->text()); + } + + // Coin Control: copy label "Priority" to clipboard + void SendCoinsDialog::coinControlClipboardPriority() + { + QApplication::clipboard()->setText(ui->labelCoinControlPriority->text()); + } + + // Coin Control: copy label "Low output" to clipboard + void SendCoinsDialog::coinControlClipboardLowOutput() + { + QApplication::clipboard()->setText(ui->labelCoinControlLowOutput->text()); + } + + // Coin Control: copy label "Change" to clipboard + void SendCoinsDialog::coinControlClipboardChange() + { + QApplication::clipboard()->setText(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" "))); + } + + // Coin Control: settings menu - coin control enabled/disabled by user + void SendCoinsDialog::coinControlFeatureChanged(bool checked) + { + ui->frameCoinControl->setVisible(checked); + + if (!checked && model) // coin control features disabled + CoinControlDialog::coinControl->SetNull(); + } + + // Coin Control: button inputs -> show actual coin control dialog + void SendCoinsDialog::coinControlButtonClicked() + { + CoinControlDialog dlg; + dlg.setModel(model); + dlg.exec(); + coinControlUpdateLabels(); + } + + // Coin Control: checkbox custom change address + void SendCoinsDialog::coinControlChangeChecked(int state) + { + if (model) + { + if (state == Qt::Checked) + CoinControlDialog::coinControl->destChange = CBitcoinAddress(ui->lineEditCoinControlChange->text().toStdString()).Get(); + else + CoinControlDialog::coinControl->destChange = CNoDestination(); + } + + ui->lineEditCoinControlChange->setEnabled((state == Qt::Checked)); + ui->labelCoinControlChangeLabel->setEnabled((state == Qt::Checked)); + } + + // Coin Control: custom change address changed + void SendCoinsDialog::coinControlChangeEdited(const QString & text) + { + if (model) + { + CoinControlDialog::coinControl->destChange = CBitcoinAddress(text.toStdString()).Get(); + + // label for the change address + ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:black;}"); + if (text.isEmpty()) + ui->labelCoinControlChangeLabel->setText(""); + else if (!CBitcoinAddress(text.toStdString()).IsValid()) + { + ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}"); + ui->labelCoinControlChangeLabel->setText(tr("WARNING: Invalid Bitcoin address")); + } + else + { + QString associatedLabel = model->getAddressTableModel()->labelForAddress(text); + if (!associatedLabel.isEmpty()) + ui->labelCoinControlChangeLabel->setText(associatedLabel); + else + { + CPubKey pubkey; + CKeyID keyid; + CBitcoinAddress(text.toStdString()).GetKeyID(keyid); + if (model->getPubKey(keyid, pubkey)) + ui->labelCoinControlChangeLabel->setText(tr("(no label)")); + else + { + ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}"); + ui->labelCoinControlChangeLabel->setText(tr("WARNING: unknown change address")); + } + } + } + } + } + + // Coin Control: update labels + void SendCoinsDialog::coinControlUpdateLabels() + { + if (!model || !model->getOptionsModel() || !model->getOptionsModel()->getCoinControlFeatures()) + return; + // set pay amounts + CoinControlDialog::payAmounts.clear(); + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + CoinControlDialog::payAmounts.append(entry->getValue().amount); + } + if (CoinControlDialog::coinControl->HasSelected()) + { + // actual coin control calculation + CoinControlDialog::updateLabels(model, this); + // show coin control stats + ui->labelCoinControlAutomaticallySelected->hide(); + ui->widgetCoinControl->show(); + } + else + { + // hide coin control stats + ui->labelCoinControlAutomaticallySelected->show(); + ui->widgetCoinControl->hide(); + ui->labelCoinControlInsuffFunds->hide(); + } +} + + diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h new file mode 100644 index 0000000..68424bb --- /dev/null +++ b/src/qt/sendcoinsdialog.h @@ -0,0 +1,68 @@ +#ifndef SENDCOINSDIALOG_H +#define SENDCOINSDIALOG_H + +#include +#include + +namespace Ui { + class SendCoinsDialog; +} +class WalletModel; +class SendCoinsEntry; +class SendCoinsRecipient; + +QT_BEGIN_NAMESPACE +class QUrl; +QT_END_NAMESPACE + +/** Dialog for sending bitcoins */ +class SendCoinsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SendCoinsDialog(QWidget *parent = 0); + ~SendCoinsDialog(); + + void setModel(WalletModel *model); + + /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907). + */ + QWidget *setupTabChain(QWidget *prev); + + void pasteEntry(const SendCoinsRecipient &rv); + bool handleURI(const QString &uri); + +public slots: + void clear(); + void reject(); + void accept(); + SendCoinsEntry *addEntry(); + void updateRemoveEnabled(); + void setBalance(qint64 balance, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance); + +private: + Ui::SendCoinsDialog *ui; + WalletModel *model; + bool fNewRecipientAllowed; + +private slots: + void on_sendButton_clicked(); + void removeEntry(SendCoinsEntry* entry); + void updateDisplayUnit(); + void coinControlFeatureChanged(bool); + void coinControlButtonClicked(); + void coinControlChangeChecked(int); + void coinControlChangeEdited(const QString &); + void coinControlUpdateLabels(); + void coinControlClipboardQuantity(); + void coinControlClipboardAmount(); + void coinControlClipboardFee(); + void coinControlClipboardAfterFee(); + void coinControlClipboardBytes(); + void coinControlClipboardPriority(); + void coinControlClipboardLowOutput(); + void coinControlClipboardChange(); +}; + +#endif // SENDCOINSDIALOG_H diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp new file mode 100644 index 0000000..6bf56ea --- /dev/null +++ b/src/qt/sendcoinsentry.cpp @@ -0,0 +1,175 @@ +#include "sendcoinsentry.h" +#include "ui_sendcoinsentry.h" +#include "guiutil.h" +#include "bitcoinunits.h" +#include "addressbookpage.h" +#include "walletmodel.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" + +#include +#include + +SendCoinsEntry::SendCoinsEntry(QWidget *parent) : + QFrame(parent), + ui(new Ui::SendCoinsEntry), + model(0) +{ + ui->setupUi(this); + +#ifdef Q_OS_MAC + ui->payToLayout->setSpacing(4); +#endif +#if QT_VERSION >= 0x040700 + /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book")); + ui->payTo->setPlaceholderText(tr("Enter a valid BERN address")); +#endif + setFocusPolicy(Qt::TabFocus); + setFocusProxy(ui->payTo); + + GUIUtil::setupAddressWidget(ui->payTo, this); +} + +SendCoinsEntry::~SendCoinsEntry() +{ + delete ui; +} + +void SendCoinsEntry::on_pasteButton_clicked() +{ + // Paste text from clipboard into recipient field + ui->payTo->setText(QApplication::clipboard()->text()); +} + +void SendCoinsEntry::on_addressBookButton_clicked() +{ + if(!model) + return; + AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::SendingTab, this); + dlg.setModel(model->getAddressTableModel()); + if(dlg.exec()) + { + ui->payTo->setText(dlg.getReturnValue()); + ui->payAmount->setFocus(); + } +} + +void SendCoinsEntry::on_payTo_textChanged(const QString &address) +{ + if(!model) + return; + // Fill in label from address book, if address has an associated label + QString associatedLabel = model->getAddressTableModel()->labelForAddress(address); + if(!associatedLabel.isEmpty()) + ui->addAsLabel->setText(associatedLabel); +} + +void SendCoinsEntry::setModel(WalletModel *model) +{ + this->model = model; + + if(model && model->getOptionsModel()) + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + + connect(ui->payAmount, SIGNAL(textChanged()), this, SIGNAL(payAmountChanged())); + + clear(); +} + +void SendCoinsEntry::setRemoveEnabled(bool enabled) +{ + ui->deleteButton->setEnabled(enabled); +} + +void SendCoinsEntry::clear() +{ + ui->payTo->clear(); + ui->addAsLabel->clear(); + ui->payAmount->clear(); + ui->payTo->setFocus(); + // update the display unit, to not use the default ("BTC") + updateDisplayUnit(); +} + +void SendCoinsEntry::on_deleteButton_clicked() +{ + emit removeEntry(this); +} + +bool SendCoinsEntry::validate() +{ + // Check input validity + bool retval = true; + + if(!ui->payAmount->validate()) + { + retval = false; + } + else + { + if(ui->payAmount->value() <= 0) + { + // Cannot send 0 coins or less + ui->payAmount->setValid(false); + retval = false; + } + } + + if(!ui->payTo->hasAcceptableInput() || + (model && !model->validateAddress(ui->payTo->text()))) + { + ui->payTo->setValid(false); + retval = false; + } + + return retval; +} + +SendCoinsRecipient SendCoinsEntry::getValue() +{ + SendCoinsRecipient rv; + + rv.address = ui->payTo->text(); + rv.label = ui->addAsLabel->text(); + rv.amount = ui->payAmount->value(); + + return rv; +} + +QWidget *SendCoinsEntry::setupTabChain(QWidget *prev) +{ + QWidget::setTabOrder(prev, ui->payTo); + QWidget::setTabOrder(ui->payTo, ui->addressBookButton); + QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton); + QWidget::setTabOrder(ui->pasteButton, ui->deleteButton); + QWidget::setTabOrder(ui->deleteButton, ui->addAsLabel); + + return ui->payAmount->setupTabChain(ui->addAsLabel); +} + +void SendCoinsEntry::setValue(const SendCoinsRecipient &value) +{ + ui->payTo->setText(value.address); + ui->addAsLabel->setText(value.label); + ui->payAmount->setValue(value.amount); +} + +bool SendCoinsEntry::isClear() +{ + return ui->payTo->text().isEmpty(); +} + +void SendCoinsEntry::setFocus() +{ + ui->payTo->setFocus(); +} + +void SendCoinsEntry::updateDisplayUnit() +{ + if(model && model->getOptionsModel()) + { + // Update payAmount with the current unit + ui->payAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit()); + } +} diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h new file mode 100644 index 0000000..4148128 --- /dev/null +++ b/src/qt/sendcoinsentry.h @@ -0,0 +1,56 @@ +#ifndef SENDCOINSENTRY_H +#define SENDCOINSENTRY_H + +#include + +namespace Ui { + class SendCoinsEntry; +} +class WalletModel; +class SendCoinsRecipient; + +/** A single entry in the dialog for sending bitcoins. */ +class SendCoinsEntry : public QFrame +{ + Q_OBJECT + +public: + explicit SendCoinsEntry(QWidget *parent = 0); + ~SendCoinsEntry(); + + void setModel(WalletModel *model); + bool validate(); + SendCoinsRecipient getValue(); + + /** Return whether the entry is still empty and unedited */ + bool isClear(); + + void setValue(const SendCoinsRecipient &value); + + /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907). + */ + QWidget *setupTabChain(QWidget *prev); + + void setFocus(); + +public slots: + void setRemoveEnabled(bool enabled); + void clear(); + +signals: + void removeEntry(SendCoinsEntry *entry); + void payAmountChanged(); + +private slots: + void on_deleteButton_clicked(); + void on_payTo_textChanged(const QString &address); + void on_addressBookButton_clicked(); + void on_pasteButton_clicked(); + void updateDisplayUnit(); + +private: + Ui::SendCoinsEntry *ui; + WalletModel *model; +}; + +#endif // SENDCOINSENTRY_H diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp new file mode 100644 index 0000000..4304db5 --- /dev/null +++ b/src/qt/signverifymessagedialog.cpp @@ -0,0 +1,274 @@ +#include "signverifymessagedialog.h" +#include "ui_signverifymessagedialog.h" + +#include "addressbookpage.h" +#include "base58.h" +#include "guiutil.h" +#include "init.h" +#include "main.h" +#include "optionsmodel.h" +#include "walletmodel.h" +#include "wallet.h" + +#include +#include + +#include + +SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SignVerifyMessageDialog), + model(0) +{ + ui->setupUi(this); + +#if (QT_VERSION >= 0x040700) + /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + ui->addressIn_SM->setPlaceholderText(tr("Enter a valid BERN address")); + ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature")); + + ui->addressIn_VM->setPlaceholderText(tr("Enter a valid BERN address")); + ui->signatureIn_VM->setPlaceholderText(tr("Enter BERN signature")); +#endif + + GUIUtil::setupAddressWidget(ui->addressIn_SM, this); + GUIUtil::setupAddressWidget(ui->addressIn_VM, this); + + ui->addressIn_SM->installEventFilter(this); + ui->messageIn_SM->installEventFilter(this); + ui->signatureOut_SM->installEventFilter(this); + ui->addressIn_VM->installEventFilter(this); + ui->messageIn_VM->installEventFilter(this); + ui->signatureIn_VM->installEventFilter(this); + + ui->signatureOut_SM->setFont(GUIUtil::bitcoinAddressFont()); + ui->signatureIn_VM->setFont(GUIUtil::bitcoinAddressFont()); +} + +SignVerifyMessageDialog::~SignVerifyMessageDialog() +{ + delete ui; +} + +void SignVerifyMessageDialog::setModel(WalletModel *model) +{ + this->model = model; +} + +void SignVerifyMessageDialog::setAddress_SM(QString address) +{ + ui->addressIn_SM->setText(address); + ui->messageIn_SM->setFocus(); +} + +void SignVerifyMessageDialog::setAddress_VM(QString address) +{ + ui->addressIn_VM->setText(address); + ui->messageIn_VM->setFocus(); +} + +void SignVerifyMessageDialog::showTab_SM(bool fShow) +{ + ui->tabWidget->setCurrentIndex(0); + + if (fShow) + this->show(); +} + +void SignVerifyMessageDialog::showTab_VM(bool fShow) +{ + ui->tabWidget->setCurrentIndex(1); + if (fShow) + this->show(); +} + +void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() +{ + if (model && model->getAddressTableModel()) + { + AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::ReceivingTab, this); + dlg.setModel(model->getAddressTableModel()); + if (dlg.exec()) + { + setAddress_SM(dlg.getReturnValue()); + } + } +} + +void SignVerifyMessageDialog::on_pasteButton_SM_clicked() +{ + setAddress_SM(QApplication::clipboard()->text()); +} + +void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() +{ + /* Clear old signature to ensure users don't get confused on error with an old signature displayed */ + ui->signatureOut_SM->clear(); + + CBitcoinAddress addr(ui->addressIn_SM->text().toStdString()); + if (!addr.IsValid()) + { + ui->addressIn_SM->setValid(false); + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); + return; + } + CKeyID keyID; + if (!addr.GetKeyID(keyID)) + { + ui->addressIn_SM->setValid(false); + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); + return; + } + + WalletModel::UnlockContext ctx(model->requestUnlock()); + if (!ctx.isValid()) + { + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled.")); + return; + } + + CKey key; + if (!pwalletMain->GetKey(keyID, key)) + { + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(tr("Private key for the entered address is not available.")); + return; + } + + CDataStream ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << ui->messageIn_SM->document()->toPlainText().toStdString(); + + std::vector vchSig; + if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) + { + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(QString("") + tr("Message signing failed.") + QString("")); + return; + } + + ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }"); + ui->statusLabel_SM->setText(QString("") + tr("Message signed.") + QString("")); + + ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size()))); +} + +void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked() +{ + QApplication::clipboard()->setText(ui->signatureOut_SM->text()); +} + +void SignVerifyMessageDialog::on_clearButton_SM_clicked() +{ + ui->addressIn_SM->clear(); + ui->messageIn_SM->clear(); + ui->signatureOut_SM->clear(); + ui->statusLabel_SM->clear(); + + ui->addressIn_SM->setFocus(); +} + +void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() +{ + if (model && model->getAddressTableModel()) + { + AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::SendingTab, this); + dlg.setModel(model->getAddressTableModel()); + if (dlg.exec()) + { + setAddress_VM(dlg.getReturnValue()); + } + } +} + +void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() +{ + CBitcoinAddress addr(ui->addressIn_VM->text().toStdString()); + if (!addr.IsValid()) + { + ui->addressIn_VM->setValid(false); + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); + return; + } + CKeyID keyID; + if (!addr.GetKeyID(keyID)) + { + ui->addressIn_VM->setValid(false); + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); + return; + } + + bool fInvalid = false; + std::vector vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid); + + if (fInvalid) + { + ui->signatureIn_VM->setValid(false); + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again.")); + return; + } + + CDataStream ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << ui->messageIn_VM->document()->toPlainText().toStdString(); + + CKey key; + if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig)) + { + ui->signatureIn_VM->setValid(false); + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again.")); + return; + } + + if (!(CBitcoinAddress(key.GetPubKey().GetID()) == addr)) + { + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->setText(QString("") + tr("Message verification failed.") + QString("")); + return; + } + + ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }"); + ui->statusLabel_VM->setText(QString("") + tr("Message verified.") + QString("")); +} + +void SignVerifyMessageDialog::on_clearButton_VM_clicked() +{ + ui->addressIn_VM->clear(); + ui->signatureIn_VM->clear(); + ui->messageIn_VM->clear(); + ui->statusLabel_VM->clear(); + + ui->addressIn_VM->setFocus(); +} + +bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn) + { + if (ui->tabWidget->currentIndex() == 0) + { + /* Clear status message on focus change */ + ui->statusLabel_SM->clear(); + + /* Select generated signature */ + if (object == ui->signatureOut_SM) + { + ui->signatureOut_SM->selectAll(); + return true; + } + } + else if (ui->tabWidget->currentIndex() == 1) + { + /* Clear status message on focus change */ + ui->statusLabel_VM->clear(); + } + } + return QDialog::eventFilter(object, event); +} diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h new file mode 100644 index 0000000..5569c8b --- /dev/null +++ b/src/qt/signverifymessagedialog.h @@ -0,0 +1,49 @@ +#ifndef SIGNVERIFYMESSAGEDIALOG_H +#define SIGNVERIFYMESSAGEDIALOG_H + +#include + +namespace Ui { + class SignVerifyMessageDialog; +} +class WalletModel; + +QT_BEGIN_NAMESPACE +QT_END_NAMESPACE + +class SignVerifyMessageDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SignVerifyMessageDialog(QWidget *parent = 0); + ~SignVerifyMessageDialog(); + + void setModel(WalletModel *model); + void setAddress_SM(QString address); + void setAddress_VM(QString address); + + void showTab_SM(bool fShow); + void showTab_VM(bool fShow); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private: + Ui::SignVerifyMessageDialog *ui; + WalletModel *model; + +private slots: + /* sign message */ + void on_addressBookButton_SM_clicked(); + void on_pasteButton_SM_clicked(); + void on_signMessageButton_SM_clicked(); + void on_copySignatureButton_SM_clicked(); + void on_clearButton_SM_clicked(); + /* verify message */ + void on_addressBookButton_VM_clicked(); + void on_verifyMessageButton_VM_clicked(); + void on_clearButton_VM_clicked(); +}; + +#endif // SIGNVERIFYMESSAGEDIALOG_H diff --git a/src/qt/statisticspage.cpp b/src/qt/statisticspage.cpp new file mode 100644 index 0000000..3d8cd64 --- /dev/null +++ b/src/qt/statisticspage.cpp @@ -0,0 +1,239 @@ +#include "statisticspage.h" +#include "ui_statisticspage.h" +#include "main.h" +#include "wallet.h" +#include "init.h" +#include "base58.h" +#include "clientmodel.h" +#include "bitcoinrpc.h" +#include +#include + +using namespace json_spirit; + +StatisticsPage::StatisticsPage(QWidget *parent) : + QWidget(parent), + ui(new Ui::StatisticsPage) +{ + ui->setupUi(this); + + resize(400, 420); + + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(timerCountDown())); + timer->start(1000); +} + +int heightPrevious = -1; +int connectionPrevious = -1; +int volumePrevious = -1; +double rewardPrevious = -1; +double netPawratePrevious = -1; +double pawratePrevious = -1; +double hardnessPrevious = -1; +double hardnessPrevious2 = -1; +int stakeminPrevious = -1; +int stakemaxPrevious = -1; +QString stakecPrevious = ""; +int dec1 = 10; + + +void StatisticsPage::updateStatistics() +{ + double pHardness = GetDifficulty(); + double pHardness2 = GetDifficulty(GetLastBlockIndex(pindexBest, true)); + double pPawrate2 = 0.000; + int nHeight = pindexBest->nHeight; + int pPawrate = getBlockHashrate(nHeight); + double nSubsidy; + if (pindexBest->nHeight > 6519080) + nSubsidy = 0; + else if (pindexBest->nHeight > 4927680) + nSubsidy = 10; + else if (pindexBest->nHeight > 3875760) + nSubsidy = 100; + else if (pindexBest->nHeight > 720000) + nSubsidy = 10; + else + nSubsidy = 250; + + uint64_t nMinWeight = 0, nMaxWeight = 0, nWeight = 0; + pwalletMain->GetStakeWeight(*pwalletMain, nMinWeight, nMaxWeight, nWeight); + uint64_t nNetworkWeight = GetPoSKernelPS(); + int64_t volume = ((pindexBest->nMoneySupply)/1000000); + int peers = this->model->getNumConnections(); + pPawrate2 = (double)pPawrate; + QString height = QString::number(nHeight); + QString stakemin = QString::number(nMinWeight); + QString stakemax = QString::number(nNetworkWeight); + QString subsidy = QString::number(nSubsidy, 'f', 0); + QString hardness = QString::number(pHardness, 'f', 6); + QString hardness2 = QString::number(pHardness2, 'f', 6); + QString pawrate = QString::number((pPawrate2/ 1000), 'f', 3); + QString Qlpawrate = model->getLastBlockDate().toString(); + QString QPeers = QString::number(peers); + QString qVolume = QString::number(volume); + + if(nHeight > heightPrevious) + { + ui->heightBox->setText("" + height + ""); + } else { + ui->heightBox->setText(height); + } + + if((int)nMinWeight > stakeminPrevious) + { + ui->minBox->setText("" + stakemin + ""); + } else if((int)nMinWeight < stakeminPrevious) { + ui->minBox->setText("" + stakemin + ""); + } else { + ui->minBox->setText(stakemin); + } + + if((int)nNetworkWeight > stakemaxPrevious) + { + ui->maxBox->setText("" + stakemax + ""); + } else if((int)nNetworkWeight < stakemaxPrevious) { + ui->maxBox->setText("" + stakemax + ""); + } else { + ui->maxBox->setText(stakemax); + } + + if(nSubsidy < rewardPrevious) + { + ui->rewardBox->setText("" + subsidy + " BERN"); + } else if(nSubsidy > rewardPrevious) { + ui->rewardBox->setText("" + subsidy + " BERN"); + } else { + ui->rewardBox->setText(subsidy+" BERN"); + } + + if(pHardness > hardnessPrevious) + { + ui->diffBox->setText("" + hardness + ""); + } else if(pHardness < hardnessPrevious) { + ui->diffBox->setText("" + hardness + ""); + } else { + ui->diffBox->setText(hardness); + } + + if(pHardness2 > hardnessPrevious2) + { + ui->diffBox2->setText("" + hardness2 + ""); + } else if(pHardness2 < hardnessPrevious2) { + ui->diffBox2->setText("" + hardness2 + ""); + } else { + ui->diffBox2->setText(hardness2); + } + + if(pPawrate2 > netPawratePrevious) + { + ui->pawrateBox->setText("" + pawrate + " Hash/sec"); + } else if(pPawrate2 < netPawratePrevious) { + ui->pawrateBox->setText("" + pawrate + " Hash/sec"); + } else { + ui->pawrateBox->setText(pawrate + " Hash/sec"); + } + + if(Qlpawrate != pawratePrevious) + { + ui->localBox->setText("" + Qlpawrate + ""); + } else { + ui->localBox->setText(Qlpawrate); + } + + if(peers > connectionPrevious) + { + ui->connectionBox->setText("" + QPeers + ""); + } else if(peers < connectionPrevious) { + ui->connectionBox->setText("" + QPeers + ""); + } else { + ui->connectionBox->setText(QPeers); + } + + if(volume > volumePrevious) + { + ui->volumeBox->setText("" + qVolume + " BERN" + ""); + } else if(volume < volumePrevious) { + ui->volumeBox->setText("" + qVolume + " BERN" + ""); + } else { + ui->volumeBox->setText(qVolume + " BERN"); + } + updatePrevious(nHeight, nMinWeight, nNetworkWeight, nSubsidy, pHardness, pHardness2, pPawrate2, Qlpawrate, peers, volume); + + if (pindexBest->nHeight < 7200001) + { + int daysLeft =(720000 - nHeight) / (1440 * 2); + ui->phaselbl1->setText(QString("Block 2 -> 720000 : PoW (250 BERN) & PoS
Approximately %1 days remain." ).arg(daysLeft)); + + } + else + ui->phaselbl1->setText("Block 2 -> 720000 : PoW (250 BERN) & PoS"); + if (pindexBest->nHeight > 720000 && pindexBest->nHeight < 3875761) + { + int daysLeft =((3875760 - 720000) - (nHeight - 720000)) / (1440 * 2); + ui->phaselbl2->setText(QString("Block 7200001 -> 3875760 : PoW (10 BERN) & PoS
Approximately %1 days remain." ).arg(daysLeft)); + } + else + ui->phaselbl2->setText("Block 7200001 -> 3875760 : PoW (10 BERN) & PoS"); + if (pindexBest->nHeight > 3875760 && pindexBest->nHeight < 4927681) + { + int daysLeft =((4927680 - 3875760) - (nHeight - 3875760)) / (1440 * 2); + ui->phaselbl3->setText(QString("Block 3875761 -> 4927680 : PoW (100 BERN) & PoS
Approximately %1 days remain." ).arg(daysLeft)); + } + else + ui->phaselbl3->setText("Block 3875761 -> 4927680 : PoW (100 BERN) & PoS"); + if (pindexBest->nHeight > 4927680 && pindexBest->nHeight < 6519081) + { + int daysLeft =((6519080 - 4927680) - (nHeight - 4927681)) / (1440 * 2); + ui->phaselbl4->setText(QString("Block 4927681 -> 6519080 : PoW (10 BERN) & PoS
Approximately %1 days remain." ).arg(daysLeft)); + } + else + ui->phaselbl4->setText("Block 4927681 -> 6519080 : PoW (10 BERN) & PoS"); + if (pindexBest->nHeight > 6519080) + ui->phaselbl5->setText("Block 6519081 -> ... : Full PoS"); + else + ui->phaselbl5->setText("Block 6519081 -> ... : Full PoS"); +} + +void StatisticsPage::updatePrevious(int nHeight, int nMinWeight, int nNetworkWeight, double nSubsidy, double pHardness, double pHardness2, double pPawrate2, QString Qlpawrate, int peers, int volume) +{ + heightPrevious = nHeight; + stakeminPrevious = nMinWeight; + stakemaxPrevious = nNetworkWeight; + rewardPrevious = nSubsidy; + hardnessPrevious = pHardness; + hardnessPrevious2 = pHardness2; + netPawratePrevious = pPawrate2; + pawratePrevious = Qlpawrate; + connectionPrevious = peers; + volumePrevious = volume; +} + +void StatisticsPage::setModel(ClientModel *model) +{ + updateStatistics(); + this->model = model; +} + +StatisticsPage::~StatisticsPage() +{ + delete ui; +} + +void StatisticsPage::timerCountDown() +{ + dec1 = dec1 - 1; + ui->startButton->setText("Update Statistics " + QString::number(dec1)); + if (dec1 == 0) + { + updateStatistics(); + dec1 = 10; + } +} + +void StatisticsPage::on_startButton_released() +{ + updateStatistics(); + dec1 = 11; +} diff --git a/src/qt/statisticspage.h b/src/qt/statisticspage.h new file mode 100644 index 0000000..a941c64 --- /dev/null +++ b/src/qt/statisticspage.h @@ -0,0 +1,63 @@ +#ifndef STATISTICSPAGE_H +#define STATISTICSPAGE_H + +#include "clientmodel.h" +#include "main.h" +#include "wallet.h" +#include "base58.h" +#include "blockbrowser.h" // some shared functions +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ui { +class StatisticsPage; +} +class ClientModel; + +class StatisticsPage : public QWidget +{ + Q_OBJECT + +public: + explicit StatisticsPage(QWidget *parent = 0); + ~StatisticsPage(); + + void setModel(ClientModel *model); + + int heightPrevious; + int connectionPrevious; + int volumePrevious; + int stakeminPrevious; + int stakemaxPrevious; + QString stakecPrevious; + double rewardPrevious; + double netPawratePrevious; + QString pawratePrevious; + double hardnessPrevious; + double hardnessPrevious2; + +public slots: + + void updateStatistics(); + void updatePrevious(int, int, int, double, double, double, double, QString, int, int); + void timerCountDown(); + +private slots: + + void on_startButton_released(); + +private: + Ui::StatisticsPage *ui; + ClientModel *model; + +}; + +#endif // STATISTICSPAGE_H diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp new file mode 100644 index 0000000..3c7794b --- /dev/null +++ b/src/qt/test/test_main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#include "uritests.h" + +// This is all you need to run all the tests +int main(int argc, char *argv[]) +{ + bool fInvalid = false; + + URITests test1; + if (QTest::qExec(&test1) != 0) + fInvalid = true; + + return fInvalid; +} diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp new file mode 100644 index 0000000..4662f5e --- /dev/null +++ b/src/qt/test/uritests.cpp @@ -0,0 +1,71 @@ +#include "uritests.h" +#include "../guiutil.h" +#include "../walletmodel.h" + +#include + +/* +struct SendCoinsRecipient +{ + QString address; + QString label; + qint64 amount; +}; +*/ + +void URITests::uriTests() +{ + SendCoinsRecipient rv; + QUrl uri; + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-dontexist=")); + QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?dontexist=")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.amount == 0); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Wikipedia Example Address")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString("Wikipedia Example Address")); + QVERIFY(rv.amount == 0); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=0.001")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.amount == 100000); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1.001")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.amount == 100100000); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=100&label=Wikipedia Example")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.amount == 10000000000LL); + QVERIFY(rv.label == QString("Wikipedia Example")); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + + QVERIFY(GUIUtil::parseBitcoinURI("bitcoin://175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address", &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + + // We currently don't implement the message parameter (ok, yea, we break spec...) + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-message=Wikipedia Example Address")); + QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000&label=Wikipedia Example")); + QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000.0&label=Wikipedia Example")); + QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); +} diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h new file mode 100644 index 0000000..1237516 --- /dev/null +++ b/src/qt/test/uritests.h @@ -0,0 +1,15 @@ +#ifndef URITESTS_H +#define URITESTS_H + +#include +#include + +class URITests : public QObject +{ + Q_OBJECT + +private slots: + void uriTests(); +}; + +#endif // URITESTS_H diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp new file mode 100644 index 0000000..7065d76 --- /dev/null +++ b/src/qt/transactiondesc.cpp @@ -0,0 +1,278 @@ +#include "transactiondesc.h" + +#include "guiutil.h" +#include "bitcoinunits.h" + +#include "main.h" +#include "wallet.h" +#include "db.h" +#include "ui_interface.h" +#include "base58.h" + +QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) +{ + if (!wtx.IsFinal()) + { + if (wtx.nLockTime < LOCKTIME_THRESHOLD) + return tr("Open for %n block(s)", "", nBestHeight - wtx.nLockTime); + else + return tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.nLockTime)); + } + else + { + int nDepth = wtx.GetDepthInMainChain(); + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + return tr("%1/offline").arg(nDepth); + else if (nDepth < 6) + return tr("%1/unconfirmed").arg(nDepth); + else + return tr("%1 confirmations").arg(nDepth); + } +} + +QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) +{ + QString strHTML; + + { + LOCK(wallet->cs_wallet); + strHTML.reserve(4000); + strHTML += ""; + + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + + strHTML += "" + tr("Status") + ": " + FormatTxStatus(wtx); + int nRequests = wtx.GetRequestCount(); + if (nRequests != -1) + { + if (nRequests == 0) + strHTML += tr(", has not been successfully broadcast yet"); + else if (nRequests > 0) + strHTML += tr(", broadcast through %n node(s)", "", nRequests); + } + strHTML += "
"; + + strHTML += "" + tr("Date") + ": " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "
"; + + // + // From + // + if (wtx.IsCoinBase()) + { + strHTML += "" + tr("Source") + ": " + tr("Generated") + "
"; + } + else if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty()) + { + // Online transaction + strHTML += "" + tr("From") + ": " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "
"; + } + else + { + // Offline transaction + if (nNet > 0) + { + // Credit + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if (wallet->IsMine(txout)) + { + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) + { + if (wallet->mapAddressBook.count(address)) + { + strHTML += "" + tr("From") + ": " + tr("unknown") + "
"; + strHTML += "" + tr("To") + ": "; + strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); + if (!wallet->mapAddressBook[address].empty()) + strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")"; + else + strHTML += " (" + tr("own address") + ")"; + strHTML += "
"; + } + } + break; + } + } + } + } + + // + // To + // + if (wtx.mapValue.count("to") && !wtx.mapValue["to"].empty()) + { + // Online transaction + std::string strAddress = wtx.mapValue["to"]; + strHTML += "" + tr("To") + ": "; + CTxDestination dest = CBitcoinAddress(strAddress).Get(); + if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].empty()) + strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest]) + " "; + strHTML += GUIUtil::HtmlEscape(strAddress) + "
"; + } + + // + // Amount + // + if (wtx.IsCoinBase() && nCredit == 0) + { + // + // Coinbase + // + int64 nUnmatured = 0; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + nUnmatured += wallet->GetCredit(txout); + strHTML += "" + tr("Credit") + ": "; + if (wtx.IsInMainChain()) + strHTML += BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")"; + else + strHTML += "(" + tr("not accepted") + ")"; + strHTML += "
"; + } + else if (nNet > 0) + { + // + // Credit + // + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nNet) + "
"; + } + else + { + bool fAllFromMe = true; + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && wallet->IsMine(txin); + + bool fAllToMe = true; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && wallet->IsMine(txout); + + if (fAllFromMe) + { + // + // Debit + // + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if (wallet->IsMine(txout)) + continue; + + if (!wtx.mapValue.count("to") || wtx.mapValue["to"].empty()) + { + // Offline transaction + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address)) + { + strHTML += "" + tr("To") + ": "; + if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty()) + strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " "; + strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); + strHTML += "
"; + } + } + + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -txout.nValue) + "
"; + } + + if (fAllToMe) + { + // Payment to self + int64 nChange = wtx.GetChange(); + int64 nValue = nCredit - nChange; + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -nValue) + "
"; + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nValue) + "
"; + } + + int64 nTxFee = nDebit - wtx.GetValueOut(); + if (nTxFee > 0) + strHTML += "" + tr("Transaction fee") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -nTxFee) + "
"; + } + else + { + // + // Mixed debit transaction + // + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + if (wallet->IsMine(txin)) + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "
"; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (wallet->IsMine(txout)) + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "
"; + } + } + + strHTML += "" + tr("Net amount") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nNet, true) + "
"; + + // + // Message + // + if (!wtx.mapValue["message"].empty()) + strHTML += "
" + tr("Message") + ":
" + GUIUtil::HtmlEscape(wtx.mapValue["message"], true) + "
"; + + if (!wtx.mapValue["comment"].empty()) + strHTML += "
" + tr("Comment") + ":
" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "
"; + + strHTML += "" + tr("Transaction ID") + ": " + wtx.GetHash().ToString().c_str() + "
"; + + + + if (wtx.IsCoinBase() || wtx.IsCoinStake()) + strHTML += "
" + tr("Generated coins must mature 30 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "
"; + + // + // Debug view + // + if (fDebug) + { + strHTML += "

" + tr("Debug information") + "

"; + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + if(wallet->IsMine(txin)) + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "
"; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if(wallet->IsMine(txout)) + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "
"; + + strHTML += "
" + tr("Transaction") + ":
"; + strHTML += GUIUtil::HtmlEscape(wtx.ToString(), true); + + CTxDB txdb("r"); // To fetch source txouts + + strHTML += "
" + tr("Inputs") + ":"; + strHTML += "
    "; + + { + LOCK(wallet->cs_wallet); + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + { + COutPoint prevout = txin.prevout; + + CTransaction prev; + if(txdb.ReadDiskTx(prevout.hash, prev)) + { + if (prevout.n < prev.vout.size()) + { + strHTML += "
  • "; + const CTxOut &vout = prev.vout[prevout.n]; + CTxDestination address; + if (ExtractDestination(vout.scriptPubKey, address)) + { + if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty()) + strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " "; + strHTML += QString::fromStdString(CBitcoinAddress(address).ToString()); + } + strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, vout.nValue); + strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? tr("true") : tr("false")) + "
  • "; + } + } + } + } + + strHTML += "
"; + } + + strHTML += "
"; + } + return strHTML; +} diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h new file mode 100644 index 0000000..2523f9a --- /dev/null +++ b/src/qt/transactiondesc.h @@ -0,0 +1,24 @@ +#ifndef TRANSACTIONDESC_H +#define TRANSACTIONDESC_H + +#include +#include +#include + +class CWallet; +class CWalletTx; + +/** Provide a human-readable extended HTML description of a transaction. + */ +class TransactionDesc: public QObject +{ + Q_OBJECT +public: + static QString toHTML(CWallet *wallet, CWalletTx &wtx); +private: + TransactionDesc() {} + + static QString FormatTxStatus(const CWalletTx& wtx); +}; + +#endif // TRANSACTIONDESC_H diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp new file mode 100644 index 0000000..3bd4808 --- /dev/null +++ b/src/qt/transactiondescdialog.cpp @@ -0,0 +1,20 @@ +#include "transactiondescdialog.h" +#include "ui_transactiondescdialog.h" + +#include "transactiontablemodel.h" + +#include + +TransactionDescDialog::TransactionDescDialog(const QModelIndex &idx, QWidget *parent) : + QDialog(parent), + ui(new Ui::TransactionDescDialog) +{ + ui->setupUi(this); + QString desc = idx.data(TransactionTableModel::LongDescriptionRole).toString(); + ui->detailText->setHtml(desc); +} + +TransactionDescDialog::~TransactionDescDialog() +{ + delete ui; +} diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h new file mode 100644 index 0000000..e86fb58 --- /dev/null +++ b/src/qt/transactiondescdialog.h @@ -0,0 +1,26 @@ +#ifndef TRANSACTIONDESCDIALOG_H +#define TRANSACTIONDESCDIALOG_H + +#include + +namespace Ui { + class TransactionDescDialog; +} +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE + +/** Dialog showing transaction details. */ +class TransactionDescDialog : public QDialog +{ + Q_OBJECT + +public: + explicit TransactionDescDialog(const QModelIndex &idx, QWidget *parent = 0); + ~TransactionDescDialog(); + +private: + Ui::TransactionDescDialog *ui; +}; + +#endif // TRANSACTIONDESCDIALOG_H diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp new file mode 100644 index 0000000..16fb4da --- /dev/null +++ b/src/qt/transactionfilterproxy.cpp @@ -0,0 +1,86 @@ +#include "transactionfilterproxy.h" +#include "transactiontablemodel.h" + +#include + +#include + +// Earliest date that can be represented (far in the past) +const QDateTime TransactionFilterProxy::MIN_DATE = QDateTime::fromTime_t(0); +// Last date that can be represented (far in the future) +const QDateTime TransactionFilterProxy::MAX_DATE = QDateTime::fromTime_t(0xFFFFFFFF); + +TransactionFilterProxy::TransactionFilterProxy(QObject *parent) : + QSortFilterProxyModel(parent), + dateFrom(MIN_DATE), + dateTo(MAX_DATE), + addrPrefix(), + typeFilter(ALL_TYPES), + minAmount(0), + limitRows(-1) +{ +} + +bool TransactionFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + + int type = index.data(TransactionTableModel::TypeRole).toInt(); + QDateTime datetime = index.data(TransactionTableModel::DateRole).toDateTime(); + QString address = index.data(TransactionTableModel::AddressRole).toString(); + QString label = index.data(TransactionTableModel::LabelRole).toString(); + qint64 amount = llabs(index.data(TransactionTableModel::AmountRole).toLongLong()); + + if(!(TYPE(type) & typeFilter)) + return false; + if(datetime < dateFrom || datetime > dateTo) + return false; + if (!address.contains(addrPrefix, Qt::CaseInsensitive) && !label.contains(addrPrefix, Qt::CaseInsensitive)) + return false; + if(amount < minAmount) + return false; + + return true; +} + +void TransactionFilterProxy::setDateRange(const QDateTime &from, const QDateTime &to) +{ + this->dateFrom = from; + this->dateTo = to; + invalidateFilter(); +} + +void TransactionFilterProxy::setAddressPrefix(const QString &addrPrefix) +{ + this->addrPrefix = addrPrefix; + invalidateFilter(); +} + +void TransactionFilterProxy::setTypeFilter(quint32 modes) +{ + this->typeFilter = modes; + invalidateFilter(); +} + +void TransactionFilterProxy::setMinAmount(qint64 minimum) +{ + this->minAmount = minimum; + invalidateFilter(); +} + +void TransactionFilterProxy::setLimit(int limit) +{ + this->limitRows = limit; +} + +int TransactionFilterProxy::rowCount(const QModelIndex &parent) const +{ + if(limitRows != -1) + { + return std::min(QSortFilterProxyModel::rowCount(parent), limitRows); + } + else + { + return QSortFilterProxyModel::rowCount(parent); + } +} diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h new file mode 100644 index 0000000..30b9858 --- /dev/null +++ b/src/qt/transactionfilterproxy.h @@ -0,0 +1,52 @@ +#ifndef TRANSACTIONFILTERPROXY_H +#define TRANSACTIONFILTERPROXY_H + +#include +#include + +/** Filter the transaction list according to pre-specified rules. */ +class TransactionFilterProxy : public QSortFilterProxyModel +{ + Q_OBJECT +public: + explicit TransactionFilterProxy(QObject *parent = 0); + + /** Earliest date that can be represented (far in the past) */ + static const QDateTime MIN_DATE; + /** Last date that can be represented (far in the future) */ + static const QDateTime MAX_DATE; + /** Type filter bit field (all types) */ + static const quint32 ALL_TYPES = 0xFFFFFFFF; + + static quint32 TYPE(int type) { return 1< TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx) +{ + QList parts; + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(true); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + uint256 hash = wtx.GetHash(); + std::map mapValue = wtx.mapValue; + + if (wtx.IsCoinStake()) + { + // Stake generation + parts.append(TransactionRecord(hash, nTime, TransactionRecord::StakeMint, "", -nDebit, wtx.GetValueOut())); + } + else if (nNet > 0 || wtx.IsCoinBase()) + { + // + // Credit + // + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if(wallet->IsMine(txout)) + { + TransactionRecord sub(hash, nTime); + CTxDestination address; + sub.idx = parts.size(); // sequence number + sub.credit = txout.nValue; + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) + { + // Received by Bitcoin Address + sub.type = TransactionRecord::RecvWithAddress; + sub.address = CBitcoinAddress(address).ToString(); + } + else + { + // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction + sub.type = TransactionRecord::RecvFromOther; + sub.address = mapValue["from"]; + } + if (wtx.IsCoinBase()) + { + // Generated + sub.type = TransactionRecord::Generated; + } + + parts.append(sub); + } + } + } + else + { + bool fAllFromMe = true; + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && wallet->IsMine(txin); + + bool fAllToMe = true; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && wallet->IsMine(txout); + + if (fAllFromMe && fAllToMe) + { + // Payment to self + int64 nChange = wtx.GetChange(); + + parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", + -(nDebit - nChange), nCredit - nChange)); + } + else if (fAllFromMe) + { + // + // Debit + // + int64 nTxFee = nDebit - wtx.GetValueOut(); + + for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) + { + const CTxOut& txout = wtx.vout[nOut]; + TransactionRecord sub(hash, nTime); + sub.idx = parts.size(); + + if(wallet->IsMine(txout)) + { + // Ignore parts sent to self, as this is usually the change + // from a transaction sent back to our own address. + continue; + } + + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address)) + { + // Sent to Bitcoin Address + sub.type = TransactionRecord::SendToAddress; + sub.address = CBitcoinAddress(address).ToString(); + } + else + { + // Sent to IP, or other non-address transaction like OP_EVAL + sub.type = TransactionRecord::SendToOther; + sub.address = mapValue["to"]; + } + + int64 nValue = txout.nValue; + /* Add fee to first output */ + if (nTxFee > 0) + { + nValue += nTxFee; + nTxFee = 0; + } + sub.debit = -nValue; + + parts.append(sub); + } + } + else + { + // + // Mixed debit transaction, can't break down payees + // + parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0)); + } + } + + return parts; +} + +void TransactionRecord::updateStatus(const CWalletTx &wtx) +{ + // Determine transaction status + + // Find the block the tx is in + CBlockIndex* pindex = NULL; + std::map::iterator mi = mapBlockIndex.find(wtx.hashBlock); + if (mi != mapBlockIndex.end()) + pindex = (*mi).second; + + // Sort order, unrecorded transactions sort to the top + status.sortKey = strprintf("%010d-%01d-%010u-%03d", + (pindex ? pindex->nHeight : std::numeric_limits::max()), + (wtx.IsCoinBase() ? 1 : 0), + wtx.nTimeReceived, + idx); + status.confirmed = wtx.IsConfirmed(); + status.depth = wtx.GetDepthInMainChain(); + status.cur_num_blocks = nBestHeight; + + if (!wtx.IsFinal()) + { + if (wtx.nLockTime < LOCKTIME_THRESHOLD) + { + status.status = TransactionStatus::OpenUntilBlock; + status.open_for = nBestHeight - wtx.nLockTime; + } + else + { + status.status = TransactionStatus::OpenUntilDate; + status.open_for = wtx.nLockTime; + } + } + else + { + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + { + status.status = TransactionStatus::Offline; + } + else if (status.depth < NumConfirmations) + { + status.status = TransactionStatus::Unconfirmed; + } + else + { + status.status = TransactionStatus::HaveConfirmations; + } + } + + // For generated transactions, determine maturity + if(type == TransactionRecord::Generated || type == TransactionRecord::StakeMint) + { + int64 nCredit = wtx.GetCredit(true); + if (nCredit == 0) + { + status.maturity = TransactionStatus::Immature; + + if (wtx.IsInMainChain()) + { + status.matures_in = wtx.GetBlocksToMaturity(); + + // Check if the block was requested by anyone + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + status.maturity = TransactionStatus::MaturesWarning; + } + else + { + status.maturity = TransactionStatus::NotAccepted; + } + } + else + { + status.maturity = TransactionStatus::Mature; + } + } +} + +bool TransactionRecord::statusUpdateNeeded() +{ + return status.cur_num_blocks != nBestHeight; +} + +std::string TransactionRecord::getTxID() +{ + return hash.ToString() + strprintf("-%03d", idx); +} + diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h new file mode 100644 index 0000000..3e36fff --- /dev/null +++ b/src/qt/transactionrecord.h @@ -0,0 +1,130 @@ +#ifndef TRANSACTIONRECORD_H +#define TRANSACTIONRECORD_H + +#include "uint256.h" + +#include + +class CWallet; +class CWalletTx; + +/** UI model for transaction status. The transaction status is the part of a transaction that will change over time. + */ +class TransactionStatus +{ +public: + TransactionStatus(): + confirmed(false), sortKey(""), maturity(Mature), + matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1) + { } + + enum Maturity + { + Immature, + Mature, + MaturesWarning, /**< Transaction will likely not mature because no nodes have confirmed */ + NotAccepted + }; + + enum Status { + OpenUntilDate, + OpenUntilBlock, + Offline, + Unconfirmed, + HaveConfirmations + }; + + bool confirmed; + std::string sortKey; + + /** @name Generated (mined) transactions + @{*/ + Maturity maturity; + int matures_in; + /**@}*/ + + /** @name Reported status + @{*/ + Status status; + int64 depth; + int64 open_for; /**< Timestamp if status==OpenUntilDate, otherwise number of blocks */ + /**@}*/ + + /** Current number of blocks (to know whether cached status is still valid) */ + int cur_num_blocks; +}; + +/** UI model for a transaction. A core transaction can be represented by multiple UI transactions if it has + multiple outputs. + */ +class TransactionRecord +{ +public: + enum Type + { + Other, + Generated, + SendToAddress, + SendToOther, + RecvWithAddress, + RecvFromOther, + SendToSelf, + StakeMint + }; + + /** Number of confirmation needed for transaction */ + static const int NumConfirmations = 4; + + TransactionRecord(): + hash(), time(0), type(Other), address(""), debit(0), credit(0), idx(0) + { + } + + TransactionRecord(uint256 hash, int64 time): + hash(hash), time(time), type(Other), address(""), debit(0), + credit(0), idx(0) + { + } + + TransactionRecord(uint256 hash, int64 time, + Type type, const std::string &address, + int64 debit, int64 credit): + hash(hash), time(time), type(type), address(address), debit(debit), credit(credit), + idx(0) + { + } + + /** Decompose CWallet transaction to model transaction records. + */ + static bool showTransaction(const CWalletTx &wtx); + static QList decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx); + + /** @name Immutable transaction attributes + @{*/ + uint256 hash; + int64 time; + Type type; + std::string address; + int64 debit; + int64 credit; + /**@}*/ + + /** Subtransaction index, for sort key */ + int idx; + + /** Status: can change with block chain update */ + TransactionStatus status; + + /** Return the unique identifier for this transaction (part) */ + std::string getTxID(); + + /** Update status from core wallet tx. + */ + void updateStatus(const CWalletTx &wtx); + + /** Return whether a status update is needed. + */ + bool statusUpdateNeeded(); +}; + +#endif // TRANSACTIONRECORD_H diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp new file mode 100644 index 0000000..2e9cc46 --- /dev/null +++ b/src/qt/transactiontablemodel.cpp @@ -0,0 +1,639 @@ +#include "transactiontablemodel.h" +#include "guiutil.h" +#include "transactionrecord.h" +#include "guiconstants.h" +#include "transactiondesc.h" +#include "walletmodel.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" +#include "bitcoinunits.h" + +#include "wallet.h" +#include "ui_interface.h" + +#include +#include +#include +#include +#include +#include +#include + +// Amount column is right-aligned it contains numbers +static int column_alignments[] = { + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignRight|Qt::AlignVCenter + }; + +// Comparison operator for sort/binary search of model tx list +struct TxLessThan +{ + bool operator()(const TransactionRecord &a, const TransactionRecord &b) const + { + return a.hash < b.hash; + } + bool operator()(const TransactionRecord &a, const uint256 &b) const + { + return a.hash < b; + } + bool operator()(const uint256 &a, const TransactionRecord &b) const + { + return a < b.hash; + } +}; + +// Private implementation +class TransactionTablePriv +{ +public: + TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent): + wallet(wallet), + parent(parent) + { + } + CWallet *wallet; + TransactionTableModel *parent; + + /* Local cache of wallet. + * As it is in the same order as the CWallet, by definition + * this is sorted by sha256. + */ + QList cachedWallet; + + /* Query entire wallet anew from core. + */ + void refreshWallet() + { + OutputDebugStringF("refreshWallet\n"); + cachedWallet.clear(); + { + LOCK(wallet->cs_wallet); + for(std::map::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it) + { + if(TransactionRecord::showTransaction(it->second)) + cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second)); + } + } + } + + /* Update our model of the wallet incrementally, to synchronize our model of the wallet + with that of the core. + + Call with transaction that was added, removed or changed. + */ + void updateWallet(const uint256 &hash, int status) + { + OutputDebugStringF("updateWallet %s %i\n", hash.ToString().c_str(), status); + { + LOCK(wallet->cs_wallet); + + // Find transaction in wallet + std::map::iterator mi = wallet->mapWallet.find(hash); + bool inWallet = mi != wallet->mapWallet.end(); + + // Find bounds of this transaction in model + QList::iterator lower = qLowerBound( + cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); + QList::iterator upper = qUpperBound( + cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); + int lowerIndex = (lower - cachedWallet.begin()); + int upperIndex = (upper - cachedWallet.begin()); + bool inModel = (lower != upper); + + // Determine whether to show transaction or not + bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); + + if(status == CT_UPDATED) + { + if(showTransaction && !inModel) + status = CT_NEW; /* Not in model, but want to show, treat as new */ + if(!showTransaction && inModel) + status = CT_DELETED; /* In model, but want to hide, treat as deleted */ + } + + OutputDebugStringF(" inWallet=%i inModel=%i Index=%i-%i showTransaction=%i derivedStatus=%i\n", + inWallet, inModel, lowerIndex, upperIndex, showTransaction, status); + + switch(status) + { + case CT_NEW: + if(inModel) + { + OutputDebugStringF("Warning: updateWallet: Got CT_NEW, but transaction is already in model\n"); + break; + } + if(!inWallet) + { + OutputDebugStringF("Warning: updateWallet: Got CT_NEW, but transaction is not in wallet\n"); + break; + } + if(showTransaction) + { + // Added -- insert at the right position + QList toInsert = + TransactionRecord::decomposeTransaction(wallet, mi->second); + if(!toInsert.isEmpty()) /* only if something to insert */ + { + parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); + int insert_idx = lowerIndex; + foreach(const TransactionRecord &rec, toInsert) + { + cachedWallet.insert(insert_idx, rec); + insert_idx += 1; + } + parent->endInsertRows(); + } + } + break; + case CT_DELETED: + if(!inModel) + { + OutputDebugStringF("Warning: updateWallet: Got CT_DELETED, but transaction is not in model\n"); + break; + } + // Removed -- remove entire transaction from table + parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); + cachedWallet.erase(lower, upper); + parent->endRemoveRows(); + break; + case CT_UPDATED: + // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for + // visible transactions. + break; + } + } + } + + int size() + { + return cachedWallet.size(); + } + + TransactionRecord *index(int idx) + { + if(idx >= 0 && idx < cachedWallet.size()) + { + TransactionRecord *rec = &cachedWallet[idx]; + + // If a status update is needed (blocks came in since last check), + // update the status of this transaction from the wallet. Otherwise, + // simply re-use the cached status. + if(rec->statusUpdateNeeded()) + { + { + LOCK(wallet->cs_wallet); + std::map::iterator mi = wallet->mapWallet.find(rec->hash); + + if(mi != wallet->mapWallet.end()) + { + rec->updateStatus(mi->second); + } + } + } + return rec; + } + else + { + return 0; + } + } + + QString describe(TransactionRecord *rec) + { + { + LOCK(wallet->cs_wallet); + std::map::iterator mi = wallet->mapWallet.find(rec->hash); + if(mi != wallet->mapWallet.end()) + { + return TransactionDesc::toHTML(wallet, mi->second); + } + } + return QString(""); + } + +}; + +TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *parent): + QAbstractTableModel(parent), + wallet(wallet), + walletModel(parent), + priv(new TransactionTablePriv(wallet, this)), + cachedNumBlocks(0) +{ + columns << QString() << tr("Date") << tr("Type") << tr("Address") << tr("Amount"); + + priv->refreshWallet(); + + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(updateConfirmations())); + timer->start(MODEL_UPDATE_DELAY); + + connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); +} + +TransactionTableModel::~TransactionTableModel() +{ + delete priv; +} + +void TransactionTableModel::updateTransaction(const QString &hash, int status) +{ + uint256 updated; + updated.SetHex(hash.toStdString()); + + priv->updateWallet(updated, status); +} + +void TransactionTableModel::updateConfirmations() +{ + if(nBestHeight != cachedNumBlocks) + { + cachedNumBlocks = nBestHeight; + // Blocks came in since last poll. + // Invalidate status (number of confirmations) and (possibly) description + // for all rows. Qt is smart enough to only actually request the data for the + // visible rows. + emit dataChanged(index(0, Status), index(priv->size()-1, Status)); + emit dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress)); + } +} + +int TransactionTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int TransactionTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns.length(); +} + +QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) const +{ + QString status; + + switch(wtx->status.status) + { + case TransactionStatus::OpenUntilBlock: + status = tr("Open for %n block(s)","",wtx->status.open_for); + break; + case TransactionStatus::OpenUntilDate: + status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for)); + break; + case TransactionStatus::Offline: + status = tr("Offline (%1 confirmations)").arg(wtx->status.depth); + break; + case TransactionStatus::Unconfirmed: + status = tr("Unconfirmed (%1 of %2 confirmations)").arg(wtx->status.depth).arg(TransactionRecord::NumConfirmations); + break; + case TransactionStatus::HaveConfirmations: + status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth); + break; + } + if(wtx->type == TransactionRecord::Generated || wtx->type == TransactionRecord::StakeMint) + { + switch(wtx->status.maturity) + { + case TransactionStatus::Immature: + status += "\n" + tr("Mined balance will be available when it matures in %n more block(s)", "", wtx->status.matures_in); + break; + case TransactionStatus::Mature: + break; + case TransactionStatus::MaturesWarning: + status += "\n" + tr("This block was not received by any other nodes and will probably not be accepted!"); + break; + case TransactionStatus::NotAccepted: + status += "\n" + tr("Generated but not accepted"); + break; + } + } + + return status; +} + +QString TransactionTableModel::formatTxDate(const TransactionRecord *wtx) const +{ + if(wtx->time) + { + return GUIUtil::dateTimeStr(wtx->time); + } + else + { + return QString(); + } +} + +/* Look up address in address book, if found return label (address) + otherwise just return (address) + */ +QString TransactionTableModel::lookupAddress(const std::string &address, bool tooltip) const +{ + QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(address)); + QString description; + if(!label.isEmpty()) + { + description += label + QString(" "); + } + if(label.isEmpty() || walletModel->getOptionsModel()->getDisplayAddresses() || tooltip) + { + description += QString("(") + QString::fromStdString(address) + QString(")"); + } + return description; +} + +QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const +{ + switch(wtx->type) + { + case TransactionRecord::RecvWithAddress: + return tr("Received with"); + case TransactionRecord::RecvFromOther: + return tr("Received from"); + case TransactionRecord::SendToAddress: + case TransactionRecord::SendToOther: + return tr("Sent to"); + case TransactionRecord::SendToSelf: + return tr("Payment to yourself"); + case TransactionRecord::StakeMint: + case TransactionRecord::Generated: + return tr("Mined"); + default: + return QString(); + } +} + +QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx) const +{ + switch(wtx->type) + { + case TransactionRecord::Generated: + case TransactionRecord::StakeMint: + { + QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit); + float dd = str.toFloat(); + return QIcon(":/icons/tx_mined"); + } + case TransactionRecord::RecvWithAddress: + case TransactionRecord::RecvFromOther: + return QIcon(":/icons/tx_input"); + case TransactionRecord::SendToAddress: + case TransactionRecord::SendToOther: + return QIcon(":/icons/tx_output"); + default: + return QIcon(":/icons/tx_inout"); + } + return QVariant(); +} + +QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const +{ + switch(wtx->type) + { + case TransactionRecord::RecvFromOther: + return QString::fromStdString(wtx->address); + case TransactionRecord::RecvWithAddress: + case TransactionRecord::SendToAddress: + case TransactionRecord::Generated: + return lookupAddress(wtx->address, tooltip); + case TransactionRecord::SendToOther: + return QString::fromStdString(wtx->address); + case TransactionRecord::SendToSelf: + default: + return tr("(n/a)"); + } +} + +QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const +{ + // Show addresses without label in a less visible color + switch(wtx->type) + { + case TransactionRecord::RecvWithAddress: + case TransactionRecord::SendToAddress: + case TransactionRecord::Generated: + { + QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address)); + if(label.isEmpty()) + return COLOR_BAREADDRESS; + } break; + case TransactionRecord::SendToSelf: + return COLOR_BAREADDRESS; + default: + break; + } + return QVariant(); +} + +QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed) const +{ + QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit); + if(showUnconfirmed) + { + if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature) + { + str = QString("[") + str + QString("]"); + } + } + return QString(str); +} + +QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) const +{ + if(wtx->type == TransactionRecord::Generated || wtx->type == TransactionRecord::StakeMint) + { + switch(wtx->status.maturity) + { + case TransactionStatus::Immature: { + int total = wtx->status.depth + wtx->status.matures_in; + int part = (wtx->status.depth * 4 / total) + 1; + return QIcon(QString(":/icons/transaction_%1").arg(part)); + } + case TransactionStatus::Mature: + return QIcon(":/icons/transaction_confirmed"); + case TransactionStatus::MaturesWarning: + case TransactionStatus::NotAccepted: + return QIcon(":/icons/transaction_0"); + } + } + else + { + switch(wtx->status.status) + { + case TransactionStatus::OpenUntilBlock: + case TransactionStatus::OpenUntilDate: + return QColor(64,64,255); + break; + case TransactionStatus::Offline: + return QColor(192,192,192); + case TransactionStatus::Unconfirmed: + switch(wtx->status.depth) + { + case 0: return QIcon(":/icons/transaction_0"); + case 1: return QIcon(":/icons/transaction_1"); + case 2: return QIcon(":/icons/transaction_2"); + case 3: return QIcon(":/icons/transaction_3"); + case 4: return QIcon(":/icons/transaction_4"); + default: return QIcon(":/icons/transaction_5"); + }; + case TransactionStatus::HaveConfirmations: + return QIcon(":/icons/transaction_confirmed"); + } + } + return QColor(0,0,0); +} + +QString TransactionTableModel::formatTooltip(const TransactionRecord *rec) const +{ + QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec); + if(rec->type==TransactionRecord::RecvFromOther || rec->type==TransactionRecord::SendToOther || + rec->type==TransactionRecord::SendToAddress || rec->type==TransactionRecord::RecvWithAddress) + { + tooltip += QString(" ") + formatTxToAddress(rec, true); + } + return tooltip; +} + +QVariant TransactionTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + TransactionRecord *rec = static_cast(index.internalPointer()); + + switch(role) + { + case Qt::DecorationRole: + switch(index.column()) + { + case Status: + return txStatusDecoration(rec); + case ToAddress: + return txAddressDecoration(rec); + } + break; + case Qt::DisplayRole: + switch(index.column()) + { + case Date: + return formatTxDate(rec); + case Type: + return formatTxType(rec); + case ToAddress: + return formatTxToAddress(rec, false); + case Amount: + return formatTxAmount(rec); + } + break; + case Qt::EditRole: + // Edit role is used for sorting, so return the unformatted values + switch(index.column()) + { + case Status: + return QString::fromStdString(rec->status.sortKey); + case Date: + return rec->time; + case Type: + return formatTxType(rec); + case ToAddress: + return formatTxToAddress(rec, true); + case Amount: + return rec->credit + rec->debit; + } + break; + case Qt::ToolTipRole: + return formatTooltip(rec); + case Qt::TextAlignmentRole: + return column_alignments[index.column()]; + case Qt::ForegroundRole: + // Non-confirmed transactions are grey + if(!rec->status.confirmed) + { + return COLOR_UNCONFIRMED; + } + if(index.column() == Amount && (rec->credit+rec->debit) < 0) + { + return COLOR_NEGATIVE; + } + if(index.column() == ToAddress) + { + return addressColor(rec); + } + break; + case TypeRole: + return rec->type; + case DateRole: + return QDateTime::fromTime_t(static_cast(rec->time)); + case LongDescriptionRole: + return priv->describe(rec); + case AddressRole: + return QString::fromStdString(rec->address); + case LabelRole: + return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); + case AmountRole: + return rec->credit + rec->debit; + case TxIDRole: + return QString::fromStdString(rec->getTxID()); + case ConfirmedRole: + // Return True if transaction counts for balance + return rec->status.confirmed && !((rec->type == TransactionRecord::Generated || rec->type == TransactionRecord::StakeMint) && + rec->status.maturity != TransactionStatus::Mature); + case FormattedAmountRole: + return formatTxAmount(rec, false); + } + return QVariant(); +} + +QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole) + { + return columns[section]; + } + else if (role == Qt::TextAlignmentRole) + { + return column_alignments[section]; + } else if (role == Qt::ToolTipRole) + { + switch(section) + { + case Status: + return tr("Transaction status. Hover over this field to show number of confirmations."); + case Date: + return tr("Date and time that the transaction was received."); + case Type: + return tr("Type of transaction."); + case ToAddress: + return tr("Destination address of transaction."); + case Amount: + return tr("Amount removed from or added to balance."); + } + } + } + return QVariant(); +} + +QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + TransactionRecord *data = priv->index(row); + if(data) + { + return createIndex(row, column, priv->index(row)); + } + else + { + return QModelIndex(); + } +} + +void TransactionTableModel::updateDisplayUnit() +{ + // emit dataChanged to update Amount column with the current unit + emit dataChanged(index(0, Amount), index(priv->size()-1, Amount)); +} diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h new file mode 100644 index 0000000..fd321ce --- /dev/null +++ b/src/qt/transactiontablemodel.h @@ -0,0 +1,85 @@ +#ifndef TRANSACTIONTABLEMODEL_H +#define TRANSACTIONTABLEMODEL_H + +#include +#include + +class CWallet; +class TransactionTablePriv; +class TransactionRecord; +class WalletModel; + +/** UI model for the transaction table of a wallet. + */ +class TransactionTableModel : public QAbstractTableModel +{ + Q_OBJECT +public: + explicit TransactionTableModel(CWallet* wallet, WalletModel *parent = 0); + ~TransactionTableModel(); + + enum ColumnIndex { + Status = 0, + Date = 1, + Type = 2, + ToAddress = 3, + Amount = 4 + }; + + /** Roles to get specific information from a transaction row. + These are independent of column. + */ + enum RoleIndex { + /** Type of transaction */ + TypeRole = Qt::UserRole, + /** Date and time this transaction was created */ + DateRole, + /** Long description (HTML format) */ + LongDescriptionRole, + /** Address of transaction */ + AddressRole, + /** Label of address related to transaction */ + LabelRole, + /** Net amount of transaction */ + AmountRole, + /** Unique identifier */ + TxIDRole, + /** Is transaction confirmed? */ + ConfirmedRole, + /** Formatted amount, without brackets when unconfirmed */ + FormattedAmountRole + }; + + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; +private: + CWallet* wallet; + WalletModel *walletModel; + QStringList columns; + TransactionTablePriv *priv; + int cachedNumBlocks; + + QString lookupAddress(const std::string &address, bool tooltip) const; + QVariant addressColor(const TransactionRecord *wtx) const; + QString formatTxStatus(const TransactionRecord *wtx) const; + QString formatTxDate(const TransactionRecord *wtx) const; + QString formatTxType(const TransactionRecord *wtx) const; + QString formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const; + QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true) const; + QString formatTooltip(const TransactionRecord *rec) const; + QVariant txStatusDecoration(const TransactionRecord *wtx) const; + QVariant txAddressDecoration(const TransactionRecord *wtx) const; + +public slots: + void updateTransaction(const QString &hash, int status); + void updateConfirmations(); + void updateDisplayUnit(); + + friend class TransactionTablePriv; +}; + +#endif + diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp new file mode 100644 index 0000000..8575f05 --- /dev/null +++ b/src/qt/transactionview.cpp @@ -0,0 +1,435 @@ +#include "transactionview.h" + +#include "transactionfilterproxy.h" +#include "transactionrecord.h" +#include "walletmodel.h" +#include "addresstablemodel.h" +#include "transactiontablemodel.h" +#include "bitcoinunits.h" +#include "csvmodelwriter.h" +#include "transactiondescdialog.h" +#include "editaddressdialog.h" +#include "optionsmodel.h" +#include "guiutil.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +TransactionView::TransactionView(QWidget *parent) : + QWidget(parent), model(0), transactionProxyModel(0), + transactionView(0) +{ + // Build filter row + setContentsMargins(0,0,0,0); + + QHBoxLayout *hlayout = new QHBoxLayout(); + hlayout->setContentsMargins(0,0,0,0); +#ifdef Q_OS_MAC + hlayout->setSpacing(5); + hlayout->addSpacing(26); +#else + hlayout->setSpacing(0); + hlayout->addSpacing(23); +#endif + + dateWidget = new QComboBox(this); +#ifdef Q_OS_MAC + dateWidget->setFixedWidth(121); +#else + dateWidget->setFixedWidth(120); +#endif + dateWidget->addItem(tr("All"), All); + dateWidget->addItem(tr("Today"), Today); + dateWidget->addItem(tr("This week"), ThisWeek); + dateWidget->addItem(tr("This month"), ThisMonth); + dateWidget->addItem(tr("Last month"), LastMonth); + dateWidget->addItem(tr("This year"), ThisYear); + dateWidget->addItem(tr("Range..."), Range); + hlayout->addWidget(dateWidget); + + typeWidget = new QComboBox(this); +#ifdef Q_OS_MAC + typeWidget->setFixedWidth(121); +#else + typeWidget->setFixedWidth(120); +#endif + + typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES); + typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) | + TransactionFilterProxy::TYPE(TransactionRecord::RecvFromOther)); + typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) | + TransactionFilterProxy::TYPE(TransactionRecord::SendToOther)); + typeWidget->addItem(tr("To yourself"), TransactionFilterProxy::TYPE(TransactionRecord::SendToSelf)); + typeWidget->addItem(tr("Minted"), TransactionFilterProxy::TYPE(TransactionRecord::StakeMint)); + typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated)); + typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other)); + + hlayout->addWidget(typeWidget); + + addressWidget = new QLineEdit(this); +#if QT_VERSION >= 0x040700 + /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + addressWidget->setPlaceholderText(tr("Enter address or label to search")); +#endif + hlayout->addWidget(addressWidget); + + amountWidget = new QLineEdit(this); +#if QT_VERSION >= 0x040700 + /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + amountWidget->setPlaceholderText(tr("Min amount")); +#endif +#ifdef Q_OS_MAC + amountWidget->setFixedWidth(97); +#else + amountWidget->setFixedWidth(100); +#endif + amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this)); + hlayout->addWidget(amountWidget); + + QVBoxLayout *vlayout = new QVBoxLayout(this); + vlayout->setContentsMargins(0,0,0,0); + vlayout->setSpacing(0); + + QTableView *view = new QTableView(this); + vlayout->addLayout(hlayout); + vlayout->addWidget(createDateRangeWidget()); + vlayout->addWidget(view); + vlayout->setSpacing(0); + int width = view->verticalScrollBar()->sizeHint().width(); + // Cover scroll bar width with spacing +#ifdef Q_OS_MAC + hlayout->addSpacing(width+2); +#else + hlayout->addSpacing(width); +#endif + // Always show scroll bar + view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + view->setTabKeyNavigation(false); + view->setContextMenuPolicy(Qt::CustomContextMenu); + + transactionView = view; + + // Actions + QAction *copyAddressAction = new QAction(tr("Copy address"), this); + QAction *copyLabelAction = new QAction(tr("Copy label"), this); + QAction *copyAmountAction = new QAction(tr("Copy amount"), this); + QAction *editLabelAction = new QAction(tr("Edit label"), this); + QAction *showDetailsAction = new QAction(tr("Show transaction details"), this); + + contextMenu = new QMenu(); + contextMenu->addAction(copyAddressAction); + contextMenu->addAction(copyLabelAction); + contextMenu->addAction(copyAmountAction); + contextMenu->addAction(editLabelAction); + contextMenu->addAction(showDetailsAction); + + // Connect actions + connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int))); + connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int))); + connect(addressWidget, SIGNAL(textChanged(QString)), this, SLOT(changedPrefix(QString))); + connect(amountWidget, SIGNAL(textChanged(QString)), this, SLOT(changedAmount(QString))); + + connect(view, SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(doubleClicked(QModelIndex))); + connect(view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); + + connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); + connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); + connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); + connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel())); + connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); +} + +void TransactionView::setModel(WalletModel *model) +{ + this->model = model; + if(model) + { + transactionProxyModel = new TransactionFilterProxy(this); + transactionProxyModel->setSourceModel(model->getTransactionTableModel()); + transactionProxyModel->setDynamicSortFilter(true); + transactionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + + transactionProxyModel->setSortRole(Qt::EditRole); + + transactionView->setModel(transactionProxyModel); + transactionView->setAlternatingRowColors(true); + transactionView->setSelectionBehavior(QAbstractItemView::SelectRows); + transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection); + transactionView->setSortingEnabled(true); + transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder); + transactionView->verticalHeader()->hide(); + + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Status, 23); + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Date, 120); + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Type, 120); +#if QT_VERSION < 0x050000 + transactionView->horizontalHeader()->setResizeMode(TransactionTableModel::ToAddress, QHeaderView::Stretch); +#else + transactionView->horizontalHeader()->setSectionResizeMode(TransactionTableModel::ToAddress, QHeaderView::Stretch); +#endif + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Amount, 100); + } +} + +void TransactionView::chooseDate(int idx) +{ + if(!transactionProxyModel) + return; + QDate current = QDate::currentDate(); + dateRangeWidget->setVisible(false); + switch(dateWidget->itemData(idx).toInt()) + { + case All: + transactionProxyModel->setDateRange( + TransactionFilterProxy::MIN_DATE, + TransactionFilterProxy::MAX_DATE); + break; + case Today: + transactionProxyModel->setDateRange( + QDateTime(current), + TransactionFilterProxy::MAX_DATE); + break; + case ThisWeek: { + // Find last Monday + QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1)); + transactionProxyModel->setDateRange( + QDateTime(startOfWeek), + TransactionFilterProxy::MAX_DATE); + + } break; + case ThisMonth: + transactionProxyModel->setDateRange( + QDateTime(QDate(current.year(), current.month(), 1)), + TransactionFilterProxy::MAX_DATE); + break; + case LastMonth: + transactionProxyModel->setDateRange( + QDateTime(QDate(current.year(), current.month()-1, 1)), + QDateTime(QDate(current.year(), current.month(), 1))); + break; + case ThisYear: + transactionProxyModel->setDateRange( + QDateTime(QDate(current.year(), 1, 1)), + TransactionFilterProxy::MAX_DATE); + break; + case Range: + dateRangeWidget->setVisible(true); + dateRangeChanged(); + break; + } +} + +void TransactionView::chooseType(int idx) +{ + if(!transactionProxyModel) + return; + transactionProxyModel->setTypeFilter( + typeWidget->itemData(idx).toInt()); +} + +void TransactionView::changedPrefix(const QString &prefix) +{ + if(!transactionProxyModel) + return; + transactionProxyModel->setAddressPrefix(prefix); +} + +void TransactionView::changedAmount(const QString &amount) +{ + if(!transactionProxyModel) + return; + qint64 amount_parsed = 0; + if(BitcoinUnits::parse(model->getOptionsModel()->getDisplayUnit(), amount, &amount_parsed)) + { + transactionProxyModel->setMinAmount(amount_parsed); + } + else + { + transactionProxyModel->setMinAmount(0); + } +} + +void TransactionView::exportClicked() +{ + // CSV is currently the only supported format + QString filename = GUIUtil::getSaveFileName( + this, + tr("Export Transaction Data"), QString(), + tr("Comma separated file (*.csv)")); + + if (filename.isNull()) return; + + CSVModelWriter writer(filename); + + // name, column, role + writer.setModel(transactionProxyModel); + writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole); + writer.addColumn(tr("Date"), 0, TransactionTableModel::DateRole); + writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole); + writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole); + writer.addColumn(tr("Address"), 0, TransactionTableModel::AddressRole); + writer.addColumn(tr("Amount"), 0, TransactionTableModel::FormattedAmountRole); + writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole); + + if(!writer.write()) + { + QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename), + QMessageBox::Abort, QMessageBox::Abort); + } +} + +void TransactionView::contextualMenu(const QPoint &point) +{ + QModelIndex index = transactionView->indexAt(point); + if(index.isValid()) + { + contextMenu->exec(QCursor::pos()); + } +} + +void TransactionView::copyAddress() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::AddressRole); +} + +void TransactionView::copyLabel() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::LabelRole); +} + +void TransactionView::copyAmount() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::FormattedAmountRole); +} + +void TransactionView::editLabel() +{ + if(!transactionView->selectionModel() ||!model) + return; + QModelIndexList selection = transactionView->selectionModel()->selectedRows(); + if(!selection.isEmpty()) + { + AddressTableModel *addressBook = model->getAddressTableModel(); + if(!addressBook) + return; + QString address = selection.at(0).data(TransactionTableModel::AddressRole).toString(); + if(address.isEmpty()) + { + // If this transaction has no associated address, exit + return; + } + // Is address in address book? Address book can miss address when a transaction is + // sent from outside the UI. + int idx = addressBook->lookupAddress(address); + if(idx != -1) + { + // Edit sending / receiving address + QModelIndex modelIdx = addressBook->index(idx, 0, QModelIndex()); + // Determine type of address, launch appropriate editor dialog type + QString type = modelIdx.data(AddressTableModel::TypeRole).toString(); + + EditAddressDialog dlg(type==AddressTableModel::Receive + ? EditAddressDialog::EditReceivingAddress + : EditAddressDialog::EditSendingAddress, + this); + dlg.setModel(addressBook); + dlg.loadRow(idx); + dlg.exec(); + } + else + { + // Add sending address + EditAddressDialog dlg(EditAddressDialog::NewSendingAddress, + this); + dlg.setModel(addressBook); + dlg.setAddress(address); + dlg.exec(); + } + } +} + +void TransactionView::showDetails() +{ + if(!transactionView->selectionModel()) + return; + QModelIndexList selection = transactionView->selectionModel()->selectedRows(); + if(!selection.isEmpty()) + { + TransactionDescDialog dlg(selection.at(0)); + dlg.exec(); + } +} + +QWidget *TransactionView::createDateRangeWidget() +{ + dateRangeWidget = new QFrame(); + dateRangeWidget->setFrameStyle(QFrame::Panel | QFrame::Raised); + dateRangeWidget->setContentsMargins(1,1,1,1); + QHBoxLayout *layout = new QHBoxLayout(dateRangeWidget); + layout->setContentsMargins(0,0,0,0); + layout->addSpacing(23); + layout->addWidget(new QLabel(tr("Range:"))); + + dateFrom = new QDateTimeEdit(this); + dateFrom->setDisplayFormat("dd/MM/yy"); + dateFrom->setCalendarPopup(true); + dateFrom->setMinimumWidth(100); + dateFrom->setDate(QDate::currentDate().addDays(-7)); + layout->addWidget(dateFrom); + layout->addWidget(new QLabel(tr("to"))); + + dateTo = new QDateTimeEdit(this); + dateTo->setDisplayFormat("dd/MM/yy"); + dateTo->setCalendarPopup(true); + dateTo->setMinimumWidth(100); + dateTo->setDate(QDate::currentDate()); + layout->addWidget(dateTo); + layout->addStretch(); + + // Hide by default + dateRangeWidget->setVisible(false); + + // Notify on change + connect(dateFrom, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged())); + connect(dateTo, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged())); + + return dateRangeWidget; +} + +void TransactionView::dateRangeChanged() +{ + if(!transactionProxyModel) + return; + transactionProxyModel->setDateRange( + QDateTime(dateFrom->date()), + QDateTime(dateTo->date()).addDays(1)); +} + +void TransactionView::focusTransaction(const QModelIndex &idx) +{ + if(!transactionProxyModel) + return; + QModelIndex targetIdx = transactionProxyModel->mapFromSource(idx); + transactionView->scrollTo(targetIdx); + transactionView->setCurrentIndex(targetIdx); + transactionView->setFocus(); +} diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h new file mode 100644 index 0000000..4ade3ec --- /dev/null +++ b/src/qt/transactionview.h @@ -0,0 +1,82 @@ +#ifndef TRANSACTIONVIEW_H +#define TRANSACTIONVIEW_H + +#include + +class WalletModel; +class TransactionFilterProxy; + +QT_BEGIN_NAMESPACE +class QTableView; +class QComboBox; +class QLineEdit; +class QModelIndex; +class QMenu; +class QFrame; +class QDateTimeEdit; +QT_END_NAMESPACE + +/** Widget showing the transaction list for a wallet, including a filter row. + Using the filter row, the user can view or export a subset of the transactions. + */ +class TransactionView : public QWidget +{ + Q_OBJECT +public: + explicit TransactionView(QWidget *parent = 0); + + void setModel(WalletModel *model); + + // Date ranges for filter + enum DateEnum + { + All, + Today, + ThisWeek, + ThisMonth, + LastMonth, + ThisYear, + Range + }; + +private: + WalletModel *model; + TransactionFilterProxy *transactionProxyModel; + QTableView *transactionView; + + QComboBox *dateWidget; + QComboBox *typeWidget; + QLineEdit *addressWidget; + QLineEdit *amountWidget; + + QMenu *contextMenu; + + QFrame *dateRangeWidget; + QDateTimeEdit *dateFrom; + QDateTimeEdit *dateTo; + + QWidget *createDateRangeWidget(); + +private slots: + void contextualMenu(const QPoint &); + void dateRangeChanged(); + void showDetails(); + void copyAddress(); + void editLabel(); + void copyLabel(); + void copyAmount(); + +signals: + void doubleClicked(const QModelIndex&); + +public slots: + void chooseDate(int idx); + void chooseType(int idx); + void changedPrefix(const QString &prefix); + void changedAmount(const QString &amount); + void exportClicked(); + void focusTransaction(const QModelIndex&); + +}; + +#endif // TRANSACTIONVIEW_H diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp new file mode 100644 index 0000000..59bf104 --- /dev/null +++ b/src/qt/walletmodel.cpp @@ -0,0 +1,456 @@ +#include "walletmodel.h" +#include "guiconstants.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" +#include "transactiontablemodel.h" + +#include "ui_interface.h" +#include "wallet.h" +#include "walletdb.h" // for BackupWallet +#include "base58.h" + +#include +#include + +WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : + QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), + transactionTableModel(0), + cachedBalance(0), cachedStake(0), cachedUnconfirmedBalance(0), cachedImmatureBalance(0), + cachedNumTransactions(0), + cachedEncryptionStatus(Unencrypted), + cachedNumBlocks(0) +{ + addressTableModel = new AddressTableModel(wallet, this); + transactionTableModel = new TransactionTableModel(wallet, this); + + // This timer will be fired repeatedly to update the balance + pollTimer = new QTimer(this); + connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollBalanceChanged())); + pollTimer->start(MODEL_UPDATE_DELAY); + + subscribeToCoreSignals(); +} + +WalletModel::~WalletModel() +{ + unsubscribeFromCoreSignals(); +} + +qint64 WalletModel::getBalance() const +{ + return wallet->GetBalance(); +} + +qint64 WalletModel::getUnconfirmedBalance() const +{ + return wallet->GetUnconfirmedBalance(); +} + +qint64 WalletModel::getStake() const +{ + return wallet->GetStake(); +} + +qint64 WalletModel::getImmatureBalance() const +{ + return wallet->GetImmatureBalance(); +} + +int WalletModel::getNumTransactions() const +{ + int numTransactions = 0; + { + LOCK(wallet->cs_wallet); + numTransactions = wallet->mapWallet.size(); + } + return numTransactions; +} + +void WalletModel::updateStatus() +{ + EncryptionStatus newEncryptionStatus = getEncryptionStatus(); + + if(cachedEncryptionStatus != newEncryptionStatus) + emit encryptionStatusChanged(newEncryptionStatus); +} + +void WalletModel::pollBalanceChanged() +{ + if(nBestHeight != cachedNumBlocks) + { + // Balance and number of transactions might have changed + cachedNumBlocks = nBestHeight; + checkBalanceChanged(); + } +} + +void WalletModel::checkBalanceChanged() +{ + qint64 newBalance = getBalance(); + qint64 newStake = getStake(); + qint64 newUnconfirmedBalance = getUnconfirmedBalance(); + qint64 newImmatureBalance = getImmatureBalance(); + + if(cachedBalance != newBalance || cachedStake != newStake || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance) + { + cachedBalance = newBalance; + cachedStake = newStake; + cachedUnconfirmedBalance = newUnconfirmedBalance; + cachedImmatureBalance = newImmatureBalance; + emit balanceChanged(newBalance, newStake, newUnconfirmedBalance, newImmatureBalance); + } +} + +void WalletModel::updateTransaction(const QString &hash, int status) +{ + if(transactionTableModel) + transactionTableModel->updateTransaction(hash, status); + + // Balance and number of transactions might have changed + checkBalanceChanged(); + + int newNumTransactions = getNumTransactions(); + if(cachedNumTransactions != newNumTransactions) + { + cachedNumTransactions = newNumTransactions; + emit numTransactionsChanged(newNumTransactions); + } +} + +void WalletModel::updateAddressBook(const QString &address, const QString &label, bool isMine, int status) +{ + if(addressTableModel) + addressTableModel->updateEntry(address, label, isMine, status); +} + +bool WalletModel::validateAddress(const QString &address) +{ + CBitcoinAddress addressParsed(address.toStdString()); + return addressParsed.IsValid(); +} + +WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList &recipients, const CCoinControl *coinControl) +{ + qint64 total = 0; + QSet setAddress; + QString hex; + + if(recipients.empty()) + { + return OK; + } + + // Pre-check input data for validity + foreach(const SendCoinsRecipient &rcp, recipients) + { + if(!validateAddress(rcp.address)) + { + return InvalidAddress; + } + setAddress.insert(rcp.address); + + if(rcp.amount <= 0) + { + return InvalidAmount; + } + total += rcp.amount; + } + + if(recipients.size() > setAddress.size()) + { + return DuplicateAddress; + } + + int64 nBalance = 0; + std::vector vCoins; + wallet->AvailableCoins(vCoins, true, coinControl); + + BOOST_FOREACH(const COutput& out, vCoins) + nBalance += out.tx->vout[out.i].nValue; + if(total > nBalance) + { + return AmountExceedsBalance; + } + + if((total + nTransactionFee) > nBalance) + { + return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); + } + + { + LOCK2(cs_main, wallet->cs_wallet); + + // Sendmany + std::vector > vecSend; + foreach(const SendCoinsRecipient &rcp, recipients) + { + CScript scriptPubKey; + scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); + vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); + } + + CWalletTx wtx; + CReserveKey keyChange(wallet); + int64 nFeeRequired = 0; + bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, coinControl); + + if(!fCreated) + { + if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future + { + return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); + } + return TransactionCreationFailed; + } + if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) + { + return Aborted; + } + if(!wallet->CommitTransaction(wtx, keyChange)) + { + return TransactionCommitFailed; + } + hex = QString::fromStdString(wtx.GetHash().GetHex()); + } + + // Add addresses / update labels that we've sent to to the address book + foreach(const SendCoinsRecipient &rcp, recipients) + { + std::string strAddress = rcp.address.toStdString(); + CTxDestination dest = CBitcoinAddress(strAddress).Get(); + std::string strLabel = rcp.label.toStdString(); + { + LOCK(wallet->cs_wallet); + + std::map::iterator mi = wallet->mapAddressBook.find(dest); + + // Check if we have a new address or an updated label + if (mi == wallet->mapAddressBook.end() || mi->second != strLabel) + { + wallet->SetAddressBookName(dest, strLabel); + } + } + } + + return SendCoinsReturn(OK, 0, hex); +} + +OptionsModel *WalletModel::getOptionsModel() +{ + return optionsModel; +} + +AddressTableModel *WalletModel::getAddressTableModel() +{ + return addressTableModel; +} + +TransactionTableModel *WalletModel::getTransactionTableModel() +{ + return transactionTableModel; +} + +WalletModel::EncryptionStatus WalletModel::getEncryptionStatus() const +{ + if(!wallet->IsCrypted()) + { + return Unencrypted; + } + else if(wallet->IsLocked()) + { + return Locked; + } + else + { + return Unlocked; + } +} + +bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphrase) +{ + if(encrypted) + { + // Encrypt + return wallet->EncryptWallet(passphrase); + } + else + { + // Decrypt -- TODO; not supported yet + return false; + } +} + +bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase) +{ + if(locked) + { + // Lock + return wallet->Lock(); + } + else + { + // Unlock + return wallet->Unlock(passPhrase); + } +} + +bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass) +{ + bool retval; + { + LOCK(wallet->cs_wallet); + wallet->Lock(); // Make sure wallet is locked before attempting pass change + retval = wallet->ChangeWalletPassphrase(oldPass, newPass); + } + return retval; +} + +bool WalletModel::backupWallet(const QString &filename) +{ + return BackupWallet(*wallet, filename.toLocal8Bit().data()); +} + +// Handlers for core signals +static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet) +{ + OutputDebugStringF("NotifyKeyStoreStatusChanged\n"); + QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection); +} + +static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status) +{ + OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", CBitcoinAddress(address).ToString().c_str(), label.c_str(), isMine, status); + QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())), + Q_ARG(QString, QString::fromStdString(label)), + Q_ARG(bool, isMine), + Q_ARG(int, status)); +} + +static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status) +{ + OutputDebugStringF("NotifyTransactionChanged %s status=%i\n", hash.GetHex().c_str(), status); + QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(hash.GetHex())), + Q_ARG(int, status)); +} + +void WalletModel::subscribeToCoreSignals() +{ + // Connect signals to wallet + wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1)); + wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5)); + wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); +} + +void WalletModel::unsubscribeFromCoreSignals() +{ + // Disconnect signals from wallet + wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1)); + wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5)); + wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); +} + +// WalletModel::UnlockContext implementation +WalletModel::UnlockContext WalletModel::requestUnlock() +{ + bool was_locked = getEncryptionStatus() == Locked; + if(was_locked) + { + // Request UI to unlock wallet + emit requireUnlock(); + } + // If wallet is still locked, unlock was failed or cancelled, mark context as invalid + bool valid = getEncryptionStatus() != Locked; + + return UnlockContext(this, valid, was_locked); +} + +WalletModel::UnlockContext::UnlockContext(WalletModel *wallet, bool valid, bool relock): + wallet(wallet), + valid(valid), + relock(relock) +{ +} + +WalletModel::UnlockContext::~UnlockContext() +{ + if(valid && relock) + { + wallet->setWalletLocked(true); + } +} + +void WalletModel::UnlockContext::CopyFrom(const UnlockContext& rhs) +{ + // Transfer context; old object no longer relocks wallet + *this = rhs; + rhs.relock = false; +} + + bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const + { + return wallet->GetPubKey(address, vchPubKeyOut); + } + + // returns a list of COutputs from COutPoints + void WalletModel::getOutputs(const std::vector& vOutpoints, std::vector& vOutputs) + { + BOOST_FOREACH(const COutPoint& outpoint, vOutpoints) + { + if (!wallet->mapWallet.count(outpoint.hash)) continue; + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain()); + vOutputs.push_back(out); + } + } + + // AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address) + void WalletModel::listCoins(std::map >& mapCoins) const + { + std::vector vCoins; + wallet->AvailableCoins(vCoins); + std::vector vLockedCoins; + + // add locked coins + BOOST_FOREACH(const COutPoint& outpoint, vLockedCoins) + { + if (!wallet->mapWallet.count(outpoint.hash)) continue; + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain()); + vCoins.push_back(out); + } + + BOOST_FOREACH(const COutput& out, vCoins) + { + COutput cout = out; + + while (wallet->IsChange(cout.tx->vout[cout.i]) && cout.tx->vin.size() > 0 && wallet->IsMine(cout.tx->vin[0])) + { + if (!wallet->mapWallet.count(cout.tx->vin[0].prevout.hash)) break; + cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0); + } + + CTxDestination address; + if(!ExtractDestination(cout.tx->vout[cout.i].scriptPubKey, address)) continue; + mapCoins[CBitcoinAddress(address).ToString().c_str()].push_back(out); + } + } + + bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const + { + return false; + } + + void WalletModel::lockCoin(COutPoint& output) + { + return; + } + + void WalletModel::unlockCoin(COutPoint& output) + { + return; + } + + void WalletModel::listLockedCoins(std::vector& vOutpts) + { + return; + } diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h new file mode 100644 index 0000000..0a1ffd5 --- /dev/null +++ b/src/qt/walletmodel.h @@ -0,0 +1,185 @@ +#ifndef WALLETMODEL_H +#define WALLETMODEL_H + +#include +#include +#include + +#include "allocators.h" /* for SecureString */ + +class OptionsModel; +class AddressTableModel; +class TransactionTableModel; +class CWallet; +class CKeyID; +class CPubKey; +class COutput; +class COutPoint; +class uint256; +class CCoinControl; + +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + +class SendCoinsRecipient +{ +public: + QString address; + QString label; + qint64 amount; +}; + +/** Interface to Bitcoin wallet from Qt view code. */ +class WalletModel : public QObject +{ + Q_OBJECT + +public: + explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); + ~WalletModel(); + + enum StatusCode // Returned by sendCoins + { + OK, + InvalidAmount, + InvalidAddress, + AmountExceedsBalance, + AmountWithFeeExceedsBalance, + DuplicateAddress, + TransactionCreationFailed, // Error returned when wallet is still locked + TransactionCommitFailed, + Aborted + }; + + enum EncryptionStatus + { + Unencrypted, // !wallet->IsCrypted() + Locked, // wallet->IsCrypted() && wallet->IsLocked() + Unlocked // wallet->IsCrypted() && !wallet->IsLocked() + }; + + OptionsModel *getOptionsModel(); + AddressTableModel *getAddressTableModel(); + TransactionTableModel *getTransactionTableModel(); + + qint64 getBalance() const; + qint64 getStake() const; + qint64 getUnconfirmedBalance() const; + qint64 getImmatureBalance() const; + int getNumTransactions() const; + EncryptionStatus getEncryptionStatus() const; + + // Check address for validity + bool validateAddress(const QString &address); + + // Return status record for SendCoins, contains error id + information + struct SendCoinsReturn + { + SendCoinsReturn(StatusCode status=Aborted, + qint64 fee=0, + QString hex=QString()): + status(status), fee(fee), hex(hex) {} + StatusCode status; + qint64 fee; // is used in case status is "AmountWithFeeExceedsBalance" + QString hex; // is filled with the transaction hash if status is "OK" + }; + + // Send coins to a list of recipients + SendCoinsReturn sendCoins(const QList &recipients, const CCoinControl *coinControl=NULL); + + // Wallet encryption + bool setWalletEncrypted(bool encrypted, const SecureString &passphrase); + // Passphrase only needed when unlocking + bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString()); + bool changePassphrase(const SecureString &oldPass, const SecureString &newPass); + // Wallet backup + bool backupWallet(const QString &filename); + + // RAI object for unlocking wallet, returned by requestUnlock() + class UnlockContext + { + public: + UnlockContext(WalletModel *wallet, bool valid, bool relock); + ~UnlockContext(); + + bool isValid() const { return valid; } + + // Copy operator and constructor transfer the context + UnlockContext(const UnlockContext& obj) { CopyFrom(obj); } + UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; } + private: + WalletModel *wallet; + bool valid; + mutable bool relock; // mutable, as it can be set to false by copying + + void CopyFrom(const UnlockContext& rhs); + }; + + UnlockContext requestUnlock(); + + bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + void getOutputs(const std::vector& vOutpoints, std::vector& vOutputs); + void listCoins(std::map >& mapCoins) const; + bool isLockedCoin(uint256 hash, unsigned int n) const; + void lockCoin(COutPoint& output); + void unlockCoin(COutPoint& output); + void listLockedCoins(std::vector& vOutpts); + +private: + CWallet *wallet; + + // Wallet has an options model for wallet-specific options + // (transaction fee, for example) + OptionsModel *optionsModel; + + AddressTableModel *addressTableModel; + TransactionTableModel *transactionTableModel; + + // Cache some values to be able to detect changes + qint64 cachedBalance; + qint64 cachedStake; + qint64 cachedUnconfirmedBalance; + qint64 cachedImmatureBalance; + qint64 cachedNumTransactions; + EncryptionStatus cachedEncryptionStatus; + int cachedNumBlocks; + + QTimer *pollTimer; + + void subscribeToCoreSignals(); + void unsubscribeFromCoreSignals(); + void checkBalanceChanged(); + + +public slots: + /* Wallet status might have changed */ + void updateStatus(); + /* New transaction, or transaction changed status */ + void updateTransaction(const QString &hash, int status); + /* New, updated or removed address book entry */ + void updateAddressBook(const QString &address, const QString &label, bool isMine, int status); + /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */ + void pollBalanceChanged(); + +signals: + // Signal that balance in wallet changed + void balanceChanged(qint64 balance, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance); + + // Number of transactions in wallet changed + void numTransactionsChanged(int count); + + // Encryption status of wallet changed + void encryptionStatusChanged(int status); + + // Signal emitted when wallet needs to be unlocked + // It is valid behaviour for listeners to keep the wallet locked after this signal; + // this means that the unlocking failed or was cancelled. + void requireUnlock(); + + // Asynchronous error notification + void error(const QString &title, const QString &message, bool modal); +}; + + +#endif // WALLETMODEL_H diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp new file mode 100644 index 0000000..dd8628b --- /dev/null +++ b/src/rpcblockchain.cpp @@ -0,0 +1,284 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "main.h" +#include "bitcoinrpc.h" + +using namespace json_spirit; +using namespace std; + +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry); + +double GetDifficulty(const CBlockIndex* blockindex) +{ + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + if (blockindex == NULL) + { + if (pindexBest == NULL) + return 1.0; + else + blockindex = GetLastBlockIndex(pindexBest, false); + } + + int nShift = (blockindex->nBits >> 24) & 0xff; + + double dDiff = + (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff); + + while (nShift < 29) + { + dDiff *= 256.0; + nShift++; + } + while (nShift > 29) + { + dDiff /= 256.0; + nShift--; + } + + return dDiff; +} + +double GetPoWMHashPS() +{ + + if (pindexBest->nHeight > 6519080) + return 0; + + int nPoWInterval = 72; + int64_t nTargetSpacingWorkMin = 30, nTargetSpacingWork = 30; + + CBlockIndex* pindex = pindexGenesisBlock; + CBlockIndex* pindexPrevWork = pindexGenesisBlock; + + while (pindex) + { + if (pindex->IsProofOfWork()) + { + int64_t nActualSpacingWork = pindex->GetBlockTime() - pindexPrevWork->GetBlockTime(); + nTargetSpacingWork = ((nPoWInterval - 1) * nTargetSpacingWork + nActualSpacingWork + nActualSpacingWork) / (nPoWInterval + 1); + nTargetSpacingWork = max(nTargetSpacingWork, nTargetSpacingWorkMin); + pindexPrevWork = pindex; + } + + pindex = pindex->pnext; + } + + return GetDifficulty() * 4294.967296 / nTargetSpacingWork * 2.778; +} + +double GetPoSKernelPS() +{ + int nPoSInterval = 72; + double dStakeKernelsTriedAvg = 0; + int nStakesHandled = 0, nStakesTime = 0; + + CBlockIndex* pindex = pindexBest;; + CBlockIndex* pindexPrevStake = NULL; + + while (pindex && nStakesHandled < nPoSInterval) + { + if (pindex->IsProofOfStake()) + { + dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0; + nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0; + pindexPrevStake = pindex; + nStakesHandled++; + } + + pindex = pindex->pprev; + } + + return nStakesTime ? dStakeKernelsTriedAvg / nStakesTime : 0; +} + +Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail) +{ + Object result; + result.push_back(Pair("hash", block.GetHash().GetHex())); + CMerkleTx txGen(block.vtx[0]); + txGen.SetMerkleBranch(&block); + result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain())); + result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); + result.push_back(Pair("mint", ValueFromAmount(blockindex->nMint))); + result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime())); + result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce)); + result.push_back(Pair("bits", HexBits(block.nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + if (blockindex->pnext) + result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex())); + + result.push_back(Pair("flags", strprintf("%s%s", blockindex->IsProofOfStake()? "proof-of-stake" : "proof-of-work", blockindex->GeneratedStakeModifier()? " stake-modifier": ""))); + result.push_back(Pair("proofhash", blockindex->IsProofOfStake()? blockindex->hashProofOfStake.GetHex() : blockindex->GetBlockHash().GetHex())); + result.push_back(Pair("entropybit", (int)blockindex->GetStakeEntropyBit())); + result.push_back(Pair("modifier", strprintf("%016"PRI64x, blockindex->nStakeModifier))); + result.push_back(Pair("modifierchecksum", strprintf("%08x", blockindex->nStakeModifierChecksum))); + Array txinfo; + BOOST_FOREACH (const CTransaction& tx, block.vtx) + { + if (fPrintTransactionDetail) + { + Object entry; + + entry.push_back(Pair("txid", tx.GetHash().GetHex())); + TxToJSON(tx, 0, entry); + + txinfo.push_back(entry); + } + else + txinfo.push_back(tx.GetHash().GetHex()); + } + + result.push_back(Pair("tx", txinfo)); + result.push_back(Pair("signature", HexStr(block.vchBlockSig.begin(), block.vchBlockSig.end()))); + + return result; +} + + +Value getblockcount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getblockcount\n" + "Returns the number of blocks in the longest block chain."); + + return nBestHeight; +} + + +Value getdifficulty(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getdifficulty\n" + "Returns the difficulty as a multiple of the minimum difficulty."); + + Object obj; + obj.push_back(Pair("proof-of-work", GetDifficulty())); + obj.push_back(Pair("proof-of-stake", GetDifficulty(GetLastBlockIndex(pindexBest, true)))); + obj.push_back(Pair("search-interval", (int)nLastCoinStakeSearchInterval)); + return obj; +} + + +Value settxfee(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1 || AmountFromValue(params[0]) < MIN_TX_FEE) + throw runtime_error( + "settxfee \n" + " is a real and is rounded to the nearest 0.01"); + + nTransactionFee = AmountFromValue(params[0]); + nTransactionFee = (nTransactionFee / CENT) * CENT; // round to cent + + return true; +} + +Value getrawmempool(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getrawmempool\n" + "Returns all transaction ids in memory pool."); + + vector vtxid; + mempool.queryHashes(vtxid); + + Array a; + BOOST_FOREACH(const uint256& hash, vtxid) + a.push_back(hash.ToString()); + + return a; +} + +Value getblockhash(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getblockhash \n" + "Returns hash of block in best-block-chain at ."); + + int nHeight = params[0].get_int(); + if (nHeight < 0 || nHeight > nBestHeight) + throw runtime_error("Block number out of range."); + + CBlockIndex* pblockindex = FindBlockByHeight(nHeight); + return pblockindex->phashBlock->GetHex(); +} + +Value getblock(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getblock [txinfo]\n" + "txinfo optional to print more detailed tx info\n" + "Returns details of a block with given block-hash."); + + std::string strHash = params[0].get_str(); + uint256 hash(strHash); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + block.ReadFromDisk(pblockindex, true); + + return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false); +} + +Value getblockbynumber(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getblock [txinfo]\n" + "txinfo optional to print more detailed tx info\n" + "Returns details of a block with given block-number."); + + int nHeight = params[0].get_int(); + if (nHeight < 0 || nHeight > nBestHeight) + throw runtime_error("Block number out of range."); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hashBestChain]; + while (pblockindex->nHeight > nHeight) + pblockindex = pblockindex->pprev; + + uint256 hash = *pblockindex->phashBlock; + + pblockindex = mapBlockIndex[hash]; + block.ReadFromDisk(pblockindex, true); + + return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false); +} + +// ppcoin: get information of sync-checkpoint +Value getcheckpoint(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getcheckpoint\n" + "Show info of synchronized checkpoint.\n"); + + Object result; + CBlockIndex* pindexCheckpoint; + + result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str())); + pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint]; + result.push_back(Pair("height", pindexCheckpoint->nHeight)); + result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str())); + if (mapArgs.count("-checkpointkey")) + result.push_back(Pair("checkpointmaster", true)); + + return result; +} diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp new file mode 100644 index 0000000..eb4a0f4 --- /dev/null +++ b/src/rpcdump.cpp @@ -0,0 +1,95 @@ +// Copyright (c) 2009-2012 Bitcoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "init.h" // for pwalletMain +#include "bitcoinrpc.h" +#include "ui_interface.h" +#include "base58.h" + +#include + +#define printf OutputDebugStringF + +using namespace json_spirit; +using namespace std; + +class CTxDump +{ +public: + CBlockIndex *pindex; + int64 nValue; + bool fSpent; + CWalletTx* ptx; + int nOut; + CTxDump(CWalletTx* ptx = NULL, int nOut = -1) + { + pindex = NULL; + nValue = 0; + fSpent = false; + this->ptx = ptx; + this->nOut = nOut; + } +}; + +Value importprivkey(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "importprivkey [label]\n" + "Adds a private key (as returned by dumpprivkey) to your wallet."); + + string strSecret = params[0].get_str(); + string strLabel = ""; + if (params.size() > 1) + strLabel = params[1].get_str(); + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(strSecret); + + if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); + if (fWalletUnlockMintOnly) // ppcoin: no importprivkey in mint-only mode + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for staking only."); + + CKey key; + bool fCompressed; + CSecret secret = vchSecret.GetSecret(fCompressed); + key.SetSecret(secret, fCompressed); + CKeyID vchAddress = key.GetPubKey().GetID(); + { + LOCK2(cs_main, pwalletMain->cs_wallet); + + pwalletMain->MarkDirty(); + pwalletMain->SetAddressBookName(vchAddress, strLabel); + + if (!pwalletMain->AddKey(key)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); + + pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true); + pwalletMain->ReacceptWalletTransactions(); + } + + return Value::null; +} + +Value dumpprivkey(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "dumpprivkey \n" + "Reveals the private key corresponding to ."); + + string strAddress = params[0].get_str(); + CBitcoinAddress address; + if (!address.SetString(strAddress)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid BERN address"); + if (fWalletUnlockMintOnly) // ppcoin: no dumpprivkey in mint-only mode + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for staking only."); + CKeyID keyID; + if (!address.GetKeyID(keyID)) + throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); + CSecret vchSecret; + bool fCompressed; + if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed)) + throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known"); + return CBitcoinSecret(vchSecret, fCompressed).ToString(); +} diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp new file mode 100644 index 0000000..b94fa8b --- /dev/null +++ b/src/rpcmining.cpp @@ -0,0 +1,552 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "main.h" +#include "db.h" +#include "init.h" +#include "bitcoinrpc.h" + +using namespace json_spirit; +using namespace std; + +Value getgenerate(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getgenerate\n" + "Returns true or false."); + + return GetBoolArg("-gen"); +} + + +Value setgenerate(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "setgenerate [genproclimit]\n" + " is true or false to turn generation on or off.\n" + "Generation is limited to [genproclimit] processors, -1 is unlimited."); + + bool fGenerate = true; + if (params.size() > 0) + fGenerate = params[0].get_bool(); + + if (params.size() > 1) + { + int nGenProcLimit = params[1].get_int(); + mapArgs["-genproclimit"] = itostr(nGenProcLimit); + if (nGenProcLimit == 0) + fGenerate = false; + } + mapArgs["-gen"] = (fGenerate ? "1" : "0"); + + GenerateBitcoins(fGenerate, pwalletMain); + return Value::null; +} + + +Value gethashespersec(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "gethashespersec\n" + "Returns a recent hashes per second performance measurement while generating."); + + if (GetTimeMillis() - nHPSTimerStart > 8000) + return (boost::int64_t)0; + return (boost::int64_t)dHashesPerSec; +} + + +Value getmininginfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getmininginfo\n" + "Returns an object containing mining-related information."); + + Object obj; + obj.push_back(Pair("blocks", (int)nBestHeight)); + obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize)); + obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx)); + obj.push_back(Pair("difficulty", (double)GetDifficulty())); + obj.push_back(Pair("errors", GetWarnings("statusbar"))); + obj.push_back(Pair("generate", GetBoolArg("-gen"))); + obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); + obj.push_back(Pair("hashespersec", gethashespersec(params, false))); + obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); + obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); + obj.push_back(Pair("testnet", fTestNet)); + return obj; +} + +// Litecoin: Return average network hashes per second based on last number of blocks. +Value GetNetworkHashPS(int lookup) { + if (pindexBest == NULL) + return 0; + + // If lookup is -1, then use blocks since last difficulty change. + if (lookup <= 0) + lookup = pindexBest->nHeight % 2016 + 1; + + // If lookup is larger than chain, then set it to chain length. + if (lookup > pindexBest->nHeight) + lookup = pindexBest->nHeight; + + CBlockIndex* pindexPrev = pindexBest; + for (int i = 0; i < lookup; i++) + pindexPrev = pindexPrev->pprev; + + double timeDiff = pindexBest->GetBlockTime() - pindexPrev->GetBlockTime(); + double timePerBlock = timeDiff / lookup; + + return (boost::int64_t)(((double)GetDifficulty() * pow(2.0, 32)) / timePerBlock); +} + +Value getnetworkhashps(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getnetworkhashps [blocks]\n" + "Returns the estimated network hashes per second based on the last 120 blocks.\n" + "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change."); + + return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120); +} + + +Value getworkex(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "getworkex [data, coinbase]\n" + "If [data, coinbase] is not specified, returns extended work data.\n" + ); + + if (vNodes.empty()) + throw JSONRPCError(-9, "BERN is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(-10, "BERN is downloading blocks..."); + + typedef map > mapNewBlock_t; + static mapNewBlock_t mapNewBlock; + static vector vNewBlock; + static CReserveKey reservekey(pwalletMain); + + if (params.size() == 0) + { + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)) + { + if (pindexPrev != pindexBest) + { + // Deallocate old blocks since they're obsolete now + mapNewBlock.clear(); + BOOST_FOREACH(CBlock* pblock, vNewBlock) + delete pblock; + vNewBlock.clear(); + } + nTransactionsUpdatedLast = nTransactionsUpdated; + pindexPrev = pindexBest; + nStart = GetTime(); + + // Create new block + pblock = CreateNewBlock(pwalletMain); + if (!pblock) + throw JSONRPCError(-7, "Out of memory"); + vNewBlock.push_back(pblock); + } + + // Update nTime + pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + pblock->nNonce = 0; + + // Update nExtraNonce + static unsigned int nExtraNonce = 0; + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); + + // Save + mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig); + + // Prebuild hash buffers + char pmidstate[32]; + char pdata[128]; + char phash1[64]; + FormatHashBuffers(pblock, pmidstate, pdata, phash1); + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + CTransaction coinbaseTx = pblock->vtx[0]; + std::vector merkle = pblock->GetMerkleBranch(0); + + Object result; + result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); + result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << coinbaseTx; + result.push_back(Pair("coinbase", HexStr(ssTx.begin(), ssTx.end()))); + + Array merkle_arr; + + BOOST_FOREACH(uint256 merkleh, merkle) { + merkle_arr.push_back(HexStr(BEGIN(merkleh), END(merkleh))); + } + + result.push_back(Pair("merkle", merkle_arr)); + + + return result; + } + else + { + // Parse parameters + vector vchData = ParseHex(params[0].get_str()); + vector coinbase; + + if(params.size() == 2) + coinbase = ParseHex(params[1].get_str()); + + if (vchData.size() != 128) + throw JSONRPCError(-8, "Invalid parameter"); + + CBlock* pdata = (CBlock*)&vchData[0]; + + // Byte reverse + for (int i = 0; i < 128/4; i++) + ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]); + + // Get saved block + if (!mapNewBlock.count(pdata->hashMerkleRoot)) + return false; + CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first; + + pblock->nTime = pdata->nTime; + pblock->nNonce = pdata->nNonce; + + if(coinbase.size() == 0) + pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second; + else + CDataStream(coinbase, SER_NETWORK, PROTOCOL_VERSION) >> pblock->vtx[0]; // FIXME - HACK! + + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + + if (!pblock->SignBlock(*pwalletMain)) + throw JSONRPCError(-100, "Unable to sign block, wallet locked?"); + + return CheckWork(pblock, *pwalletMain, reservekey); + } +} + + +Value getwork(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getwork [data]\n" + "If [data] is not specified, returns formatted hash data to work on:\n" + " \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated + " \"data\" : block data\n" + " \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated + " \"target\" : little endian hash target\n" + "If [data] is specified, tries to solve the block and returns true if it was successful."); + + if (vNodes.empty()) + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "BERN is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "BERN is downloading blocks..."); + + typedef map > mapNewBlock_t; + static mapNewBlock_t mapNewBlock; // FIXME: thread safety + static vector vNewBlock; + static CReserveKey reservekey(pwalletMain); + + if (params.size() == 0) + { + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)) + { + if (pindexPrev != pindexBest) + { + // Deallocate old blocks since they're obsolete now + mapNewBlock.clear(); + BOOST_FOREACH(CBlock* pblock, vNewBlock) + delete pblock; + vNewBlock.clear(); + } + + // Clear pindexPrev so future getworks make a new block, despite any failures from here on + pindexPrev = NULL; + + // Store the pindexBest used before CreateNewBlock, to avoid races + nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrevNew = pindexBest; + nStart = GetTime(); + + // Create new block + pblock = CreateNewBlock(pwalletMain); + if (!pblock) + throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); + vNewBlock.push_back(pblock); + + // Need to update only after we know CreateNewBlock succeeded + pindexPrev = pindexPrevNew; + } + + // Update nTime + pblock->UpdateTime(pindexPrev); + pblock->nNonce = 0; + + // Update nExtraNonce + static unsigned int nExtraNonce = 0; + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); + + // Save + mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig); + + // Pre-build hash buffers + char pmidstate[32]; + char pdata[128]; + char phash1[64]; + FormatHashBuffers(pblock, pmidstate, pdata, phash1); + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + Object result; + result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated + result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); + result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated + result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); + return result; + } + else + { + // Parse parameters + vector vchData = ParseHex(params[0].get_str()); + if (vchData.size() != 128) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter"); + CBlock* pdata = (CBlock*)&vchData[0]; + + // Byte reverse + for (int i = 0; i < 128/4; i++) + ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]); + + // Get saved block + if (!mapNewBlock.count(pdata->hashMerkleRoot)) + return false; + CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first; + + pblock->nTime = pdata->nTime; + pblock->nNonce = pdata->nNonce; + pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second; + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + + if (!pblock->SignBlock(*pwalletMain)) + throw JSONRPCError(-100, "Unable to sign block, wallet locked?"); + + return CheckWork(pblock, *pwalletMain, reservekey); + } +} + + +Value getblocktemplate(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getblocktemplate [params]\n" + "Returns data needed to construct a block to work on:\n" + " \"version\" : block version\n" + " \"previousblockhash\" : hash of current highest block\n" + " \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n" + " \"coinbaseaux\" : data that should be included in coinbase\n" + " \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n" + " \"target\" : hash target\n" + " \"mintime\" : minimum timestamp appropriate for next block\n" + " \"curtime\" : current timestamp\n" + " \"mutable\" : list of ways the block template may be changed\n" + " \"noncerange\" : range of valid nonces\n" + " \"sigoplimit\" : limit of sigops in blocks\n" + " \"sizelimit\" : limit of block size\n" + " \"bits\" : compressed target of next block\n" + " \"height\" : height of the next block\n" + "See https://en.bitcoin.it/wiki/BIP_0022 for full specification."); + + std::string strMode = "template"; + if (params.size() > 0) + { + const Object& oparam = params[0].get_obj(); + const Value& modeval = find_value(oparam, "mode"); + if (modeval.type() == str_type) + strMode = modeval.get_str(); + else if (modeval.type() == null_type) + { + /* Do nothing */ + } + else + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); + } + + if (strMode != "template") + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); + + if (vNodes.empty()) + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "BERN is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "BERN is downloading blocks..."); + + static CReserveKey reservekey(pwalletMain); + + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5)) + { + // Clear pindexPrev so future calls make a new block, despite any failures from here on + pindexPrev = NULL; + + // Store the pindexBest used before CreateNewBlock, to avoid races + nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrevNew = pindexBest; + nStart = GetTime(); + + // Create new block + if(pblock) + { + delete pblock; + pblock = NULL; + } + pblock = CreateNewBlock(pwalletMain); + if (!pblock) + throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); + + // Need to update only after we know CreateNewBlock succeeded + pindexPrev = pindexPrevNew; + } + + // Update nTime + pblock->UpdateTime(pindexPrev); + pblock->nNonce = 0; + + Array transactions; + map setTxIndex; + int i = 0; + CTxDB txdb("r"); + BOOST_FOREACH (CTransaction& tx, pblock->vtx) + { + uint256 txHash = tx.GetHash(); + setTxIndex[txHash] = i++; + + if (tx.IsCoinBase() || tx.IsCoinStake()) + continue; + + Object entry; + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end()))); + + entry.push_back(Pair("hash", txHash.GetHex())); + + MapPrevTx mapInputs; + map mapUnused; + bool fInvalid = false; + if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) + { + entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut()))); + + Array deps; + BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs) + { + if (setTxIndex.count(inp.first)) + deps.push_back(setTxIndex[inp.first]); + } + entry.push_back(Pair("depends", deps)); + + int64_t nSigOps = tx.GetLegacySigOpCount(); + nSigOps += tx.GetP2SHSigOpCount(mapInputs); + entry.push_back(Pair("sigops", nSigOps)); + } + + transactions.push_back(entry); + } + + Object aux; + aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + static Array aMutable; + if (aMutable.empty()) + { + aMutable.push_back("time"); + aMutable.push_back("transactions"); + aMutable.push_back("prevblock"); + } + + Object result; + result.push_back(Pair("version", pblock->nVersion)); + result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); + result.push_back(Pair("transactions", transactions)); + result.push_back(Pair("coinbaseaux", aux)); + result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); + result.push_back(Pair("target", hashTarget.GetHex())); + result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); + result.push_back(Pair("mutable", aMutable)); + result.push_back(Pair("noncerange", "00000000ffffffff")); + result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE)); + result.push_back(Pair("curtime", (int64_t)pblock->nTime)); + result.push_back(Pair("bits", HexBits(pblock->nBits))); + result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); + + return result; +} + +Value submitblock(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "submitblock [optional-params-obj]\n" + "[optional-params-obj] parameter is currently ignored.\n" + "Attempts to submit new block to network.\n" + "See https://en.bitcoin.it/wiki/BIP_0022 for full specification."); + + vector blockData(ParseHex(params[0].get_str())); + CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION); + CBlock block; + try { + ssBlock >> block; + } + catch (std::exception &e) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); + } + + if (!block.SignBlock(*pwalletMain)) + throw JSONRPCError(-100, "Unable to sign block, wallet locked?"); + + bool fAccepted = ProcessBlock(NULL, &block); + if (!fAccepted) + return "rejected"; + + return Value::null; +} + diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp new file mode 100644 index 0000000..04ea310 --- /dev/null +++ b/src/rpcnet.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2009-2012 Bitcoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "net.h" +#include "bitcoinrpc.h" +#include "alert.h" +#include "wallet.h" +#include "db.h" +#include "walletdb.h" + +using namespace json_spirit; +using namespace std; + +Value getconnectioncount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getconnectioncount\n" + "Returns the number of connections to other nodes."); + + LOCK(cs_vNodes); + return (int)vNodes.size(); +} + +static void CopyNodeStats(std::vector& vstats) +{ + vstats.clear(); + + LOCK(cs_vNodes); + vstats.reserve(vNodes.size()); + BOOST_FOREACH(CNode* pnode, vNodes) { + CNodeStats stats; + pnode->copyStats(stats); + vstats.push_back(stats); + } +} + +Value getpeerinfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getpeerinfo\n" + "Returns data about each connected network node."); + + vector vstats; + CopyNodeStats(vstats); + + Array ret; + + BOOST_FOREACH(const CNodeStats& stats, vstats) { + Object obj; + + obj.push_back(Pair("addr", stats.addrName)); + obj.push_back(Pair("services", strprintf("%08"PRI64x, stats.nServices))); + obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend)); + obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv)); + obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected)); + obj.push_back(Pair("version", stats.nVersion)); + obj.push_back(Pair("subver", stats.strSubVer)); + obj.push_back(Pair("inbound", stats.fInbound)); + obj.push_back(Pair("releasetime", (boost::int64_t)stats.nReleaseTime)); + obj.push_back(Pair("startingheight", stats.nStartingHeight)); + obj.push_back(Pair("banscore", stats.nMisbehavior)); + + ret.push_back(obj); + } + + return ret; +} + +extern CCriticalSection cs_mapAlerts; +extern map mapAlerts; + +// ppcoin: send alert. +// There is a known deadlock situation with ThreadMessageHandler +// ThreadMessageHandler: holds cs_vSend and acquiring cs_main in SendMessages() +// ThreadRPCServer: holds cs_main and acquiring cs_vSend in alert.RelayTo()/PushMessage()/BeginMessage() +Value sendalert(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 6) + throw runtime_error( + "sendalert [cancelupto]\n" + " is the alert text message\n" + " is hex string of alert master private key\n" + " is the minimum applicable internal client version\n" + " is the maximum applicable internal client version\n" + " is integer priority number\n" + " is the alert id\n" + "[cancelupto] cancels all alert id's up to this number\n" + "Returns true or false."); + + CAlert alert; + CKey key; + + alert.strStatusBar = params[0].get_str(); + alert.nMinVer = params[2].get_int(); + alert.nMaxVer = params[3].get_int(); + alert.nPriority = params[4].get_int(); + alert.nID = params[5].get_int(); + if (params.size() > 6) + alert.nCancel = params[6].get_int(); + alert.nVersion = PROTOCOL_VERSION; + alert.nRelayUntil = GetAdjustedTime() + 365*24*60*60; + alert.nExpiration = GetAdjustedTime() + 365*24*60*60; + + CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); + sMsg << (CUnsignedAlert)alert; + alert.vchMsg = vector(sMsg.begin(), sMsg.end()); + + vector vchPrivKey = ParseHex(params[1].get_str()); + key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash + if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig)) + throw runtime_error( + "Unable to sign alert, check private key?\n"); + if(!alert.ProcessAlert()) + throw runtime_error( + "Failed to process alert.\n"); + // Relay alert + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + alert.RelayTo(pnode); + } + + Object result; + result.push_back(Pair("strStatusBar", alert.strStatusBar)); + result.push_back(Pair("nVersion", alert.nVersion)); + result.push_back(Pair("nMinVer", alert.nMinVer)); + result.push_back(Pair("nMaxVer", alert.nMaxVer)); + result.push_back(Pair("nPriority", alert.nPriority)); + result.push_back(Pair("nID", alert.nID)); + if (alert.nCancel > 0) + result.push_back(Pair("nCancel", alert.nCancel)); + return result; +} diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp new file mode 100644 index 0000000..140b208 --- /dev/null +++ b/src/rpcrawtransaction.cpp @@ -0,0 +1,532 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 + +#include "base58.h" +#include "bitcoinrpc.h" +#include "db.h" +#include "init.h" +#include "main.h" +#include "net.h" +#include "wallet.h" + +using namespace std; +using namespace boost; +using namespace boost::assign; +using namespace json_spirit; + +void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out) +{ + txnouttype type; + vector addresses; + int nRequired; + + out.push_back(Pair("asm", scriptPubKey.ToString())); + out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + + if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) + { + out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD))); + return; + } + + out.push_back(Pair("reqSigs", nRequired)); + out.push_back(Pair("type", GetTxnOutputType(type))); + + Array a; + BOOST_FOREACH(const CTxDestination& addr, addresses) + a.push_back(CBitcoinAddress(addr).ToString()); + out.push_back(Pair("addresses", a)); +} + +void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) +{ + entry.push_back(Pair("txid", tx.GetHash().GetHex())); + entry.push_back(Pair("version", tx.nVersion)); + entry.push_back(Pair("time", (boost::int64_t)tx.nTime)); + entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); + Array vin; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + Object in; + if (tx.IsCoinBase()) + in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + else + { + in.push_back(Pair("txid", txin.prevout.hash.GetHex())); + in.push_back(Pair("vout", (boost::int64_t)txin.prevout.n)); + Object o; + o.push_back(Pair("asm", txin.scriptSig.ToString())); + o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + in.push_back(Pair("scriptSig", o)); + } + in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); + vin.push_back(in); + } + entry.push_back(Pair("vin", vin)); + Array vout; + for (unsigned int i = 0; i < tx.vout.size(); i++) + { + const CTxOut& txout = tx.vout[i]; + Object out; + out.push_back(Pair("value", ValueFromAmount(txout.nValue))); + out.push_back(Pair("n", (boost::int64_t)i)); + Object o; + ScriptPubKeyToJSON(txout.scriptPubKey, o); + out.push_back(Pair("scriptPubKey", o)); + vout.push_back(out); + } + entry.push_back(Pair("vout", vout)); + + if (hashBlock != 0) + { + entry.push_back(Pair("blockhash", hashBlock.GetHex())); + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end() && (*mi).second) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + { + entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); + entry.push_back(Pair("time", (boost::int64_t)pindex->nTime)); + entry.push_back(Pair("blocktime", (boost::int64_t)pindex->nTime)); + } + else + entry.push_back(Pair("confirmations", 0)); + } + } +} + +Value getrawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getrawtransaction [verbose=0]\n" + "If verbose=0, returns a string that is\n" + "serialized, hex-encoded data for .\n" + "If verbose is non-zero, returns an Object\n" + "with information about ."); + + uint256 hash; + hash.SetHex(params[0].get_str()); + + bool fVerbose = false; + if (params.size() > 1) + fVerbose = (params[1].get_int() != 0); + + CTransaction tx; + uint256 hashBlock = 0; + if (!GetTransaction(hash, tx, hashBlock)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + string strHex = HexStr(ssTx.begin(), ssTx.end()); + + if (!fVerbose) + return strHex; + + Object result; + result.push_back(Pair("hex", strHex)); + TxToJSON(tx, hashBlock, result); + return result; +} + +Value listunspent(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 3) + throw runtime_error( + "listunspent [minconf=1] [maxconf=9999999] [\"address\",...]\n" + "Returns array of unspent transaction outputs\n" + "with between minconf and maxconf (inclusive) confirmations.\n" + "Optionally filtered to only include txouts paid to specified addresses.\n" + "Results are an array of Objects, each of which has:\n" + "{txid, vout, scriptPubKey, amount, confirmations}"); + + RPCTypeCheck(params, list_of(int_type)(int_type)(array_type)); + + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + int nMaxDepth = 9999999; + if (params.size() > 1) + nMaxDepth = params[1].get_int(); + + set setAddress; + if (params.size() > 2) + { + Array inputs = params[2].get_array(); + BOOST_FOREACH(Value& input, inputs) + { + CBitcoinAddress address(input.get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid BERN address: ")+input.get_str()); + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); + setAddress.insert(address); + } + } + + Array results; + vector vecOutputs; + pwalletMain->AvailableCoins(vecOutputs, false); + BOOST_FOREACH(const COutput& out, vecOutputs) + { + if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) + continue; + + if(setAddress.size()) + { + CTxDestination address; + if(!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) + continue; + + if (!setAddress.count(address)) + continue; + } + + int64 nValue = out.tx->vout[out.i].nValue; + const CScript& pk = out.tx->vout[out.i].scriptPubKey; + Object entry; + entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); + entry.push_back(Pair("vout", out.i)); + entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); + entry.push_back(Pair("amount",ValueFromAmount(nValue))); + entry.push_back(Pair("confirmations",out.nDepth)); + results.push_back(entry); + } + + return results; +} + +Value createrawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error( + "createrawtransaction [{\"txid\":txid,\"vout\":n},...] {address:amount,...}\n" + "Create a transaction spending given inputs\n" + "(array of objects containing transaction id and output number),\n" + "sending to given address(es).\n" + "Returns hex-encoded raw transaction.\n" + "Note that the transaction's inputs are not signed, and\n" + "it is not stored in the wallet or transmitted to the network."); + + RPCTypeCheck(params, list_of(array_type)(obj_type)); + + Array inputs = params[0].get_array(); + Object sendTo = params[1].get_obj(); + + CTransaction rawTx; + + BOOST_FOREACH(Value& input, inputs) + { + const Object& o = input.get_obj(); + + const Value& txid_v = find_value(o, "txid"); + if (txid_v.type() != str_type) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing txid key"); + string txid = txid_v.get_str(); + if (!IsHex(txid)) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid"); + + const Value& vout_v = find_value(o, "vout"); + if (vout_v.type() != int_type) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); + int nOutput = vout_v.get_int(); + if (nOutput < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); + + CTxIn in(COutPoint(uint256(txid), nOutput)); + rawTx.vin.push_back(in); + } + + set setAddress; + BOOST_FOREACH(const Pair& s, sendTo) + { + CBitcoinAddress address(s.name_); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid BERN address: ")+s.name_); + + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); + setAddress.insert(address); + + CScript scriptPubKey; + scriptPubKey.SetDestination(address.Get()); + int64 nAmount = AmountFromValue(s.value_); + + CTxOut out(nAmount, scriptPubKey); + rawTx.vout.push_back(out); + } + + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << rawTx; + return HexStr(ss.begin(), ss.end()); +} + +Value decoderawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "decoderawtransaction \n" + "Return a JSON object representing the serialized, hex-encoded transaction."); + + RPCTypeCheck(params, list_of(str_type)); + + vector txData(ParseHex(params[0].get_str())); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + try { + ssData >> tx; + } + catch (std::exception &e) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + } + + Object result; + TxToJSON(tx, 0, result); + + return result; +} + +Value signrawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 4) + throw runtime_error( + "signrawtransaction [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [,...] [sighashtype=\"ALL\"]\n" + "Sign inputs for raw transaction (serialized, hex-encoded).\n" + "Second optional argument (may be null) is an array of previous transaction outputs that\n" + "this transaction depends on but may not yet be in the blockchain.\n" + "Third optional argument (may be null) is an array of base58-encoded private\n" + "keys that, if given, will be the only keys used to sign the transaction.\n" + "Fourth optional argument is a string that is one of six values; ALL, NONE, SINGLE or\n" + "ALL|ANYONECANPAY, NONE|ANYONECANPAY, SINGLE|ANYONECANPAY.\n" + "Returns json object with keys:\n" + " hex : raw transaction with signature(s) (hex-encoded string)\n" + " complete : 1 if transaction has a complete set of signature (0 if not)" + + HelpRequiringPassphrase()); + + RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true); + + vector txData(ParseHex(params[0].get_str())); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + vector txVariants; + while (!ssData.empty()) + { + try { + CTransaction tx; + ssData >> tx; + txVariants.push_back(tx); + } + catch (std::exception &e) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + } + } + + if (txVariants.empty()) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction"); + + // mergedTx will end up with all the signatures; it + // starts as a clone of the rawtx: + CTransaction mergedTx(txVariants[0]); + bool fComplete = true; + + // Fetch previous transactions (inputs): + map mapPrevOut; + for (unsigned int i = 0; i < mergedTx.vin.size(); i++) + { + CTransaction tempTx; + MapPrevTx mapPrevTx; + CTxDB txdb("r"); + map unused; + bool fInvalid; + + // FetchInputs aborts on failure, so we go one at a time. + tempTx.vin.push_back(mergedTx.vin[i]); + tempTx.FetchInputs(txdb, unused, false, false, mapPrevTx, fInvalid); + + // Copy results into mapPrevOut: + BOOST_FOREACH(const CTxIn& txin, tempTx.vin) + { + const uint256& prevHash = txin.prevout.hash; + if (mapPrevTx.count(prevHash) && mapPrevTx[prevHash].second.vout.size()>txin.prevout.n) + mapPrevOut[txin.prevout] = mapPrevTx[prevHash].second.vout[txin.prevout.n].scriptPubKey; + } + } + + // Add previous txouts given in the RPC call: + if (params.size() > 1 && params[1].type() != null_type) + { + Array prevTxs = params[1].get_array(); + BOOST_FOREACH(Value& p, prevTxs) + { + if (p.type() != obj_type) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); + + Object prevOut = p.get_obj(); + + RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); + + string txidHex = find_value(prevOut, "txid").get_str(); + if (!IsHex(txidHex)) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "txid must be hexadecimal"); + uint256 txid; + txid.SetHex(txidHex); + + int nOut = find_value(prevOut, "vout").get_int(); + if (nOut < 0) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive"); + + string pkHex = find_value(prevOut, "scriptPubKey").get_str(); + if (!IsHex(pkHex)) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "scriptPubKey must be hexadecimal"); + vector pkData(ParseHex(pkHex)); + CScript scriptPubKey(pkData.begin(), pkData.end()); + + COutPoint outpoint(txid, nOut); + if (mapPrevOut.count(outpoint)) + { + // Complain if scriptPubKey doesn't match + if (mapPrevOut[outpoint] != scriptPubKey) + { + string err("Previous output scriptPubKey mismatch:\n"); + err = err + mapPrevOut[outpoint].ToString() + "\nvs:\n"+ + scriptPubKey.ToString(); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); + } + } + else + mapPrevOut[outpoint] = scriptPubKey; + } + } + + bool fGivenKeys = false; + CBasicKeyStore tempKeystore; + if (params.size() > 2 && params[2].type() != null_type) + { + fGivenKeys = true; + Array keys = params[2].get_array(); + BOOST_FOREACH(Value k, keys) + { + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(k.get_str()); + if (!fGood) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,"Invalid private key"); + CKey key; + bool fCompressed; + CSecret secret = vchSecret.GetSecret(fCompressed); + key.SetSecret(secret, fCompressed); + tempKeystore.AddKey(key); + } + } + else + EnsureWalletIsUnlocked(); + + const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain); + + int nHashType = SIGHASH_ALL; + if (params.size() > 3 && params[3].type() != null_type) + { + static map mapSigHashValues = + boost::assign::map_list_of + (string("ALL"), int(SIGHASH_ALL)) + (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)) + (string("NONE"), int(SIGHASH_NONE)) + (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)) + (string("SINGLE"), int(SIGHASH_SINGLE)) + (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)) + ; + string strHashType = params[3].get_str(); + if (mapSigHashValues.count(strHashType)) + nHashType = mapSigHashValues[strHashType]; + else + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param"); + } + + 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]; + if (mapPrevOut.count(txin.prevout) == 0) + { + fComplete = false; + continue; + } + const CScript& prevPubKey = mapPrevOut[txin.prevout]; + + 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: + BOOST_FOREACH(const CTransaction& txv, txVariants) + { + txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); + } + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, true, 0)) + fComplete = false; + } + + Object result; + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << mergedTx; + result.push_back(Pair("hex", HexStr(ssTx.begin(), ssTx.end()))); + result.push_back(Pair("complete", fComplete)); + + return result; +} + +Value sendrawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1) + throw runtime_error( + "sendrawtransaction \n" + "Submits raw transaction (serialized, hex-encoded) to local node and network."); + + RPCTypeCheck(params, list_of(str_type)); + + // parse hex string from parameter + vector txData(ParseHex(params[0].get_str())); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + + // deserialize binary data stream + try { + ssData >> tx; + } + catch (std::exception &e) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + } + uint256 hashTx = tx.GetHash(); + + // See if the transaction is already in a block + // or in the memory pool: + CTransaction existingTx; + uint256 hashBlock = 0; + if (GetTransaction(hashTx, existingTx, hashBlock)) + { + if (hashBlock != 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("transaction already in block ")+hashBlock.GetHex()); + // Not in block, but already in the memory pool; will drop + // through to re-relay it. + } + else + { + // push to local node + CTxDB txdb("r"); + if (!tx.AcceptToMemoryPool(txdb)) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); + + SyncWithWallets(tx, NULL, true); + } + RelayMessage(CInv(MSG_TX, hashTx), tx); + + return hashTx.GetHex(); +} diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp new file mode 100644 index 0000000..d2a5b92 --- /dev/null +++ b/src/rpcwallet.cpp @@ -0,0 +1,1763 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "wallet.h" +#include "walletdb.h" +#include "bitcoinrpc.h" +#include "init.h" +#include "base58.h" + +using namespace json_spirit; +using namespace std; + +int64 nWalletUnlockTime; +static CCriticalSection cs_nWalletUnlockTime; + +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry); + +std::string HelpRequiringPassphrase() +{ + return pwalletMain->IsCrypted() + ? "\nrequires wallet passphrase to be set with walletpassphrase first" + : ""; +} + +void EnsureWalletIsUnlocked() +{ + if (pwalletMain->IsLocked()) + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); + if (fWalletUnlockMintOnly) + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Wallet unlocked for block staking only."); +} + +void WalletTxToJSON(const CWalletTx& wtx, Object& entry) +{ + int confirms = wtx.GetDepthInMainChain(); + entry.push_back(Pair("confirmations", confirms)); + if (wtx.IsCoinBase() || wtx.IsCoinStake()) + entry.push_back(Pair("generated", true)); + if (confirms) + { + entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); + entry.push_back(Pair("blockindex", wtx.nIndex)); + entry.push_back(Pair("blocktime", (boost::int64_t)(mapBlockIndex[wtx.hashBlock]->nTime))); + } + entry.push_back(Pair("txid", wtx.GetHash().GetHex())); + entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime())); + entry.push_back(Pair("timereceived", (boost::int64_t)wtx.nTimeReceived)); + BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) + entry.push_back(Pair(item.first, item.second)); +} + +string AccountFromValue(const Value& value) +{ + string strAccount = value.get_str(); + if (strAccount == "*") + throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name"); + return strAccount; +} + +Value getinfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getinfo\n" + "Returns an object containing various state info."); + + proxyType proxy; + GetProxy(NET_IPV4, proxy); + + Object obj; + obj.push_back(Pair("version", FormatFullVersion())); + obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION)); + obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); + obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); + obj.push_back(Pair("newmint", ValueFromAmount(pwalletMain->GetNewMint()))); + obj.push_back(Pair("stake", ValueFromAmount(pwalletMain->GetStake()))); + obj.push_back(Pair("blocks", (int)nBestHeight)); + obj.push_back(Pair("moneysupply", ValueFromAmount(pindexBest->nMoneySupply))); + obj.push_back(Pair("connections", (int)vNodes.size())); + obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string()))); + obj.push_back(Pair("ip", addrSeenByPeer.ToStringIP())); + obj.push_back(Pair("difficulty", (double)GetDifficulty())); + obj.push_back(Pair("testnet", fTestNet)); + obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); + obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize())); + obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); + if (pwalletMain->IsCrypted()) + obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000)); + obj.push_back(Pair("errors", GetWarnings("statusbar"))); + return obj; +} + + +Value getnewpubkey(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getnewpubkey [account]\n" + "Returns new public key for coinbase generation."); + + // Parse the account first so we don't generate a key if there's an error + string strAccount; + if (params.size() > 0) + strAccount = AccountFromValue(params[0]); + + if (!pwalletMain->IsLocked()) + pwalletMain->TopUpKeyPool(); + + // Generate a new key that is added to wallet + CPubKey newKey; + if (!pwalletMain->GetKeyFromPool(newKey, false)) + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + CKeyID keyID = newKey.GetID(); + + pwalletMain->SetAddressBookName(keyID, strAccount); + vector vchPubKey = newKey.Raw(); + + return HexStr(vchPubKey.begin(), vchPubKey.end()); +} + + +Value getnewaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getnewaddress [account]\n" + "Returns a new BERN address for receiving payments. " + "If [account] is specified (recommended), it is added to the address book " + "so payments received with the address will be credited to [account]."); + + // Parse the account first so we don't generate a key if there's an error + string strAccount; + if (params.size() > 0) + strAccount = AccountFromValue(params[0]); + + if (!pwalletMain->IsLocked()) + pwalletMain->TopUpKeyPool(); + + // Generate a new key that is added to wallet + CPubKey newKey; + if (!pwalletMain->GetKeyFromPool(newKey, false)) + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + CKeyID keyID = newKey.GetID(); + + pwalletMain->SetAddressBookName(keyID, strAccount); + + return CBitcoinAddress(keyID).ToString(); +} + + +CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) +{ + CWalletDB walletdb(pwalletMain->strWalletFile); + + CAccount account; + walletdb.ReadAccount(strAccount, account); + + bool bKeyUsed = false; + + // Check if the current key has been used + if (account.vchPubKey.IsValid()) + { + CScript scriptPubKey; + scriptPubKey.SetDestination(account.vchPubKey.GetID()); + for (map::iterator it = pwalletMain->mapWallet.begin(); + it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); + ++it) + { + const CWalletTx& wtx = (*it).second; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + bKeyUsed = true; + } + } + + // Generate a new key + if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed) + { + if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + + pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), strAccount); + walletdb.WriteAccount(strAccount, account); + } + + return CBitcoinAddress(account.vchPubKey.GetID()); +} + +Value getaccountaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaccountaddress \n" + "Returns the current BERN address for receiving payments to this account."); + + // Parse the account first so we don't generate a key if there's an error + string strAccount = AccountFromValue(params[0]); + + Value ret; + + ret = GetAccountAddress(strAccount).ToString(); + + return ret; +} + + + +Value setaccount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "setaccount \n" + "Sets the account associated with the given address."); + + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid BERN address"); + + + string strAccount; + if (params.size() > 1) + strAccount = AccountFromValue(params[1]); + + // Detect when changing the account of an address that is the 'unused current key' of another account: + if (pwalletMain->mapAddressBook.count(address.Get())) + { + string strOldAccount = pwalletMain->mapAddressBook[address.Get()]; + if (address == GetAccountAddress(strOldAccount)) + GetAccountAddress(strOldAccount, true); + } + + pwalletMain->SetAddressBookName(address.Get(), strAccount); + + return Value::null; +} + + +Value getaccount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaccount \n" + "Returns the account associated with the given address."); + + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid BERN address"); + + string strAccount; + map::iterator mi = pwalletMain->mapAddressBook.find(address.Get()); + if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) + strAccount = (*mi).second; + return strAccount; +} + + +Value getaddressesbyaccount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressesbyaccount \n" + "Returns the list of addresses for the given account."); + + string strAccount = AccountFromValue(params[0]); + + // Find all addresses that have the given account + Array ret; + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + const string& strName = item.second; + if (strName == strAccount) + ret.push_back(address.ToString()); + } + return ret; +} + +Value sendtoaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 4) + throw runtime_error( + "sendtoaddress [comment] [comment-to]\n" + " is a real and is rounded to the nearest 0.000001" + + HelpRequiringPassphrase()); + + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid BERN address"); + + // Amount + int64 nAmount = AmountFromValue(params[1]); + + if (nAmount < MIN_TXOUT_AMOUNT) + throw JSONRPCError(-101, "Send amount too small"); + + // Wallet comments + CWalletTx wtx; + if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty()) + wtx.mapValue["comment"] = params[2].get_str(); + if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + wtx.mapValue["to"] = params[3].get_str(); + + if (pwalletMain->IsLocked()) + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); + + string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); + if (strError != "") + throw JSONRPCError(RPC_WALLET_ERROR, strError); + + return wtx.GetHash().GetHex(); +} + +Value listaddressgroupings(const Array& params, bool fHelp) +{ + if (fHelp) + throw runtime_error( + "listaddressgroupings\n" + "Lists groups of addresses which have had their common ownership\n" + "made public by common use as inputs or as the resulting change\n" + "in past transactions"); + + Array jsonGroupings; + map balances = pwalletMain->GetAddressBalances(); + BOOST_FOREACH(set grouping, pwalletMain->GetAddressGroupings()) + { + Array jsonGrouping; + BOOST_FOREACH(CTxDestination address, grouping) + { + Array addressInfo; + addressInfo.push_back(CBitcoinAddress(address).ToString()); + addressInfo.push_back(ValueFromAmount(balances[address])); + { + LOCK(pwalletMain->cs_wallet); + if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end()) + addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second); + } + jsonGrouping.push_back(addressInfo); + } + jsonGroupings.push_back(jsonGrouping); + } + return jsonGroupings; +} + +Value signmessage(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error( + "signmessage \n" + "Sign a message with the private key of an address"); + + EnsureWalletIsUnlocked(); + + string strAddress = params[0].get_str(); + string strMessage = params[1].get_str(); + + CBitcoinAddress addr(strAddress); + if (!addr.IsValid()) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); + + CKeyID keyID; + if (!addr.GetKeyID(keyID)) + throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); + + CKey key; + if (!pwalletMain->GetKey(keyID, key)) + throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available"); + + CDataStream ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << strMessage; + + vector vchSig; + if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); + + return EncodeBase64(&vchSig[0], vchSig.size()); +} + +Value verifymessage(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 3) + throw runtime_error( + "verifymessage \n" + "Verify a signed message"); + + string strAddress = params[0].get_str(); + string strSign = params[1].get_str(); + string strMessage = params[2].get_str(); + + CBitcoinAddress addr(strAddress); + if (!addr.IsValid()) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); + + CKeyID keyID; + if (!addr.GetKeyID(keyID)) + throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); + + bool fInvalid = false; + vector vchSig = DecodeBase64(strSign.c_str(), &fInvalid); + + if (fInvalid) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding"); + + CDataStream ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << strMessage; + + CKey key; + if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig)) + return false; + + return (key.GetPubKey().GetID() == keyID); +} + + +Value getreceivedbyaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getreceivedbyaddress [minconf=1]\n" + "Returns the total amount received by in transactions with at least [minconf] confirmations."); + + // Bitcoin address + CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); + CScript scriptPubKey; + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid BERN address"); + scriptPubKey.SetDestination(address.Get()); + if (!IsMine(*pwalletMain,scriptPubKey)) + return (double)0.0; + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + // Tally + int64 nAmount = 0; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || wtx.IsCoinStake() || !wtx.IsFinal()) + continue; + + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + + return ValueFromAmount(nAmount); +} + + +void GetAccountAddresses(string strAccount, set& setAddress) +{ + BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& item, pwalletMain->mapAddressBook) + { + const CTxDestination& address = item.first; + const string& strName = item.second; + if (strName == strAccount) + setAddress.insert(address); + } +} + +Value getreceivedbyaccount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getreceivedbyaccount [minconf=1]\n" + "Returns the total amount received by addresses with in transactions with at least [minconf] confirmations."); + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + // Get the set of pub keys assigned to account + string strAccount = AccountFromValue(params[0]); + set setAddress; + GetAccountAddresses(strAccount, setAddress); + + // Tally + int64 nAmount = 0; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || wtx.IsCoinStake() || !wtx.IsFinal()) + continue; + + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + } + + return (double)nAmount / (double)COIN; +} + + +int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth) +{ + int64 nBalance = 0; + + // Tally wallet transactions + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (!wtx.IsFinal()) + continue; + + int64 nGeneratedImmature, nGeneratedMature, nReceived, nSent, nFee; + wtx.GetAccountAmounts(strAccount, nGeneratedImmature, nGeneratedMature, nReceived, nSent, nFee); + + if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) + nBalance += nReceived; + + if((wtx.IsCoinBaseOrStake() && wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetBlocksToMaturity() == 0) + || !wtx.IsCoinBaseOrStake()) + { + nBalance += nGeneratedMature - nSent - nFee; + } + } + + // Tally internal accounting entries + nBalance += walletdb.GetAccountCreditDebit(strAccount); + + return nBalance; +} + +int64 GetAccountBalance(const string& strAccount, int nMinDepth) +{ + CWalletDB walletdb(pwalletMain->strWalletFile); + return GetAccountBalance(walletdb, strAccount, nMinDepth); +} + + +Value getbalance(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "getbalance [account] [minconf=1]\n" + "If [account] is not specified, returns the server's total available balance.\n" + "If [account] is specified, returns the balance in the account."); + + if (params.size() == 0) + return ValueFromAmount(pwalletMain->GetBalance()); + + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + if (params[0].get_str() == "*") { + // Calculate total balance a different way from GetBalance() + // (GetBalance() sums up all unspent TxOuts) + // getbalance and getbalance '*' should always return the same number. + int64 nBalance = 0; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (!wtx.IsFinal()) + continue; + + int64 allGeneratedImmature, allGeneratedMature, allFee; + allGeneratedImmature = allGeneratedMature = allFee = 0; + + string strSentAccount; + list > listReceived; + list > listSent; + wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); + if (wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived) + nBalance += r.second; + } + + if((wtx.IsCoinBaseOrStake() && wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetBlocksToMaturity() == 0) + || !wtx.IsCoinBaseOrStake()) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent) + nBalance -= r.second; + nBalance -= allFee; + nBalance += allGeneratedMature; + } + } + return ValueFromAmount(nBalance); + } + + string strAccount = AccountFromValue(params[0]); + + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + + return ValueFromAmount(nBalance); +} + + +Value movecmd(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 3 || params.size() > 5) + throw runtime_error( + "move [minconf=1] [comment]\n" + "Move from one account in your wallet to another."); + + string strFrom = AccountFromValue(params[0]); + string strTo = AccountFromValue(params[1]); + int64 nAmount = AmountFromValue(params[2]); + + if (nAmount < MIN_TXOUT_AMOUNT) + throw JSONRPCError(-101, "Send amount too small"); + + if (params.size() > 3) + // unused parameter, used to be nMinDepth, keep type-checking it though + (void)params[3].get_int(); + string strComment; + if (params.size() > 4) + strComment = params[4].get_str(); + + CWalletDB walletdb(pwalletMain->strWalletFile); + if (!walletdb.TxnBegin()) + throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); + + int64 nNow = GetAdjustedTime(); + + // Debit + CAccountingEntry debit; + debit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb); + debit.strAccount = strFrom; + debit.nCreditDebit = -nAmount; + debit.nTime = nNow; + debit.strOtherAccount = strTo; + debit.strComment = strComment; + walletdb.WriteAccountingEntry(debit); + + // Credit + CAccountingEntry credit; + credit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb); + credit.strAccount = strTo; + credit.nCreditDebit = nAmount; + credit.nTime = nNow; + credit.strOtherAccount = strFrom; + credit.strComment = strComment; + walletdb.WriteAccountingEntry(credit); + + if (!walletdb.TxnCommit()) + throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); + + return true; +} + + +Value sendfrom(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 3 || params.size() > 6) + throw runtime_error( + "sendfrom [minconf=1] [comment] [comment-to]\n" + " is a real and is rounded to the nearest 0.000001" + + HelpRequiringPassphrase()); + + string strAccount = AccountFromValue(params[0]); + CBitcoinAddress address(params[1].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid BERN address"); + int64 nAmount = AmountFromValue(params[2]); + + if (nAmount < MIN_TXOUT_AMOUNT) + throw JSONRPCError(-101, "Send amount too small"); + + int nMinDepth = 1; + if (params.size() > 3) + nMinDepth = params[3].get_int(); + + CWalletTx wtx; + wtx.strFromAccount = strAccount; + if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty()) + wtx.mapValue["comment"] = params[4].get_str(); + if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty()) + wtx.mapValue["to"] = params[5].get_str(); + + EnsureWalletIsUnlocked(); + + // Check funds + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + if (nAmount > nBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); + + // Send + string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); + if (strError != "") + throw JSONRPCError(RPC_WALLET_ERROR, strError); + + return wtx.GetHash().GetHex(); +} + + +Value sendmany(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 4) + throw runtime_error( + "sendmany {address:amount,...} [minconf=1] [comment]\n" + "amounts are double-precision floating point numbers" + + HelpRequiringPassphrase()); + + string strAccount = AccountFromValue(params[0]); + Object sendTo = params[1].get_obj(); + int nMinDepth = 1; + if (params.size() > 2) + nMinDepth = params[2].get_int(); + + CWalletTx wtx; + + wtx.strFromAccount = strAccount; + if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + wtx.mapValue["comment"] = params[3].get_str(); + + set setAddress; + vector > vecSend; + + int64 totalAmount = 0; + BOOST_FOREACH(const Pair& s, sendTo) + { + CBitcoinAddress address(s.name_); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid BERN address: ")+s.name_); + + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); + setAddress.insert(address); + + CScript scriptPubKey; + scriptPubKey.SetDestination(address.Get()); + int64 nAmount = AmountFromValue(s.value_); + + if (nAmount < MIN_TXOUT_AMOUNT) + throw JSONRPCError(-101, "Send amount too small"); + + totalAmount += nAmount; + + vecSend.push_back(make_pair(scriptPubKey, nAmount)); + } + + EnsureWalletIsUnlocked(); + + // Check funds + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + if (totalAmount > nBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); + + // Send + CReserveKey keyChange(pwalletMain); + int64 nFeeRequired = 0; + bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); + if (!fCreated) + { + if (totalAmount + nFeeRequired > pwalletMain->GetBalance()) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + throw JSONRPCError(RPC_WALLET_ERROR, "Transaction creation failed"); + } + if (!pwalletMain->CommitTransaction(wtx, keyChange)) + throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed"); + + return wtx.GetHash().GetHex(); +} + +Value addmultisigaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 3) + { + string msg = "addmultisigaddress <'[\"key\",\"key\"]'> [account]\n" + "Add a nrequired-to-sign multisignature address to the wallet\"\n" + "each key is a BERN address or hex-encoded public key\n" + "If [account] is specified, assign address to [account]."; + throw runtime_error(msg); + } + + int nRequired = params[0].get_int(); + const Array& keys = params[1].get_array(); + string strAccount; + if (params.size() > 2) + strAccount = AccountFromValue(params[2]); + + // Gather public keys + if (nRequired < 1) + throw runtime_error("a multisignature address must require at least one key to redeem"); + if ((int)keys.size() < nRequired) + throw runtime_error( + strprintf("not enough keys supplied " + "(got %"PRIszu" keys, but need at least %d to redeem)", keys.size(), nRequired)); + std::vector pubkeys; + pubkeys.resize(keys.size()); + for (unsigned int i = 0; i < keys.size(); i++) + { + const std::string& ks = keys[i].get_str(); + + // Case 1: Bitcoin address and we have full public key: + CBitcoinAddress address(ks); + if (address.IsValid()) + { + CKeyID keyID; + if (!address.GetKeyID(keyID)) + throw runtime_error( + strprintf("%s does not refer to a key",ks.c_str())); + CPubKey vchPubKey; + if (!pwalletMain->GetPubKey(keyID, vchPubKey)) + throw runtime_error( + strprintf("no full public key for address %s",ks.c_str())); + if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey)) + throw runtime_error(" Invalid public key: "+ks); + } + + // Case 2: hex public key + else if (IsHex(ks)) + { + CPubKey vchPubKey(ParseHex(ks)); + if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey)) + throw runtime_error(" Invalid public key: "+ks); + } + else + { + throw runtime_error(" Invalid public key: "+ks); + } + } + + // Construct using pay-to-script-hash: + CScript inner; + inner.SetMultisig(nRequired, pubkeys); + CScriptID innerID = inner.GetID(); + pwalletMain->AddCScript(inner); + + pwalletMain->SetAddressBookName(innerID, strAccount); + return CBitcoinAddress(innerID).ToString(); +} + + +struct tallyitem +{ + int64 nAmount; + int nConf; + tallyitem() + { + nAmount = 0; + nConf = std::numeric_limits::max(); + } +}; + +Value ListReceived(const Array& params, bool fByAccounts) +{ + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + // Whether to include empty accounts + bool fIncludeEmpty = false; + if (params.size() > 1) + fIncludeEmpty = params[1].get_bool(); + + // Tally + map mapTally; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + + if (wtx.IsCoinBase() || wtx.IsCoinStake() || !wtx.IsFinal()) + continue; + + int nDepth = wtx.GetDepthInMainChain(); + if (nDepth < nMinDepth) + continue; + + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + CTxDestination address; + if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address)) + continue; + + tallyitem& item = mapTally[address]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); + } + } + + // Reply + Array ret; + map mapAccountTally; + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + const string& strAccount = item.second; + map::iterator it = mapTally.find(address); + if (it == mapTally.end() && !fIncludeEmpty) + continue; + + int64 nAmount = 0; + int nConf = std::numeric_limits::max(); + if (it != mapTally.end()) + { + nAmount = (*it).second.nAmount; + nConf = (*it).second.nConf; + } + + if (fByAccounts) + { + tallyitem& item = mapAccountTally[strAccount]; + item.nAmount += nAmount; + item.nConf = min(item.nConf, nConf); + } + else + { + Object obj; + obj.push_back(Pair("address", address.ToString())); + obj.push_back(Pair("account", strAccount)); + obj.push_back(Pair("amount", ValueFromAmount(nAmount))); + obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); + ret.push_back(obj); + } + } + + if (fByAccounts) + { + for (map::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it) + { + int64 nAmount = (*it).second.nAmount; + int nConf = (*it).second.nConf; + Object obj; + obj.push_back(Pair("account", (*it).first)); + obj.push_back(Pair("amount", ValueFromAmount(nAmount))); + obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); + ret.push_back(obj); + } + } + + return ret; +} + +Value listreceivedbyaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "listreceivedbyaddress [minconf=1] [includeempty=false]\n" + "[minconf] is the minimum number of confirmations before payments are included.\n" + "[includeempty] whether to include addresses that haven't received any payments.\n" + "Returns an array of objects containing:\n" + " \"address\" : receiving address\n" + " \"account\" : the account of the receiving address\n" + " \"amount\" : total amount received by the address\n" + " \"confirmations\" : number of confirmations of the most recent transaction included"); + + return ListReceived(params, false); +} + +Value listreceivedbyaccount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "listreceivedbyaccount [minconf=1] [includeempty=false]\n" + "[minconf] is the minimum number of confirmations before payments are included.\n" + "[includeempty] whether to include accounts that haven't received any payments.\n" + "Returns an array of objects containing:\n" + " \"account\" : the account of the receiving addresses\n" + " \"amount\" : total amount received by addresses with this account\n" + " \"confirmations\" : number of confirmations of the most recent transaction included"); + + return ListReceived(params, true); +} + +void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret) +{ + int64 nGeneratedImmature, nGeneratedMature, nFee; + string strSentAccount; + list > listReceived; + list > listSent; + + wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); + + bool fAllAccounts = (strAccount == string("*")); + + // Generated blocks assigned to account "" + if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount == "")) + { + Object entry; + entry.push_back(Pair("account", string(""))); + if (nGeneratedImmature) + { + entry.push_back(Pair("category", wtx.GetDepthInMainChain() ? "immature" : "orphan")); + entry.push_back(Pair("amount", ValueFromAmount(nGeneratedImmature))); + } + else + { + entry.push_back(Pair("category", "generate")); + entry.push_back(Pair("amount", ValueFromAmount(nGeneratedMature))); + } + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + + // Sent + if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent) + { + Object entry; + entry.push_back(Pair("account", strSentAccount)); + entry.push_back(Pair("address", CBitcoinAddress(s.first).ToString())); + entry.push_back(Pair("category", "send")); + entry.push_back(Pair("amount", ValueFromAmount(-s.second))); + entry.push_back(Pair("fee", ValueFromAmount(-nFee))); + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + } + + // Received + if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived) + { + string account; + if (pwalletMain->mapAddressBook.count(r.first)) + account = pwalletMain->mapAddressBook[r.first]; + if (fAllAccounts || (account == strAccount)) + { + Object entry; + entry.push_back(Pair("account", account)); + entry.push_back(Pair("address", CBitcoinAddress(r.first).ToString())); + if (wtx.IsCoinBase()) + { + if (wtx.GetDepthInMainChain() < 1) + entry.push_back(Pair("category", "orphan")); + else if (wtx.GetBlocksToMaturity() > 0) + entry.push_back(Pair("category", "immature")); + else + entry.push_back(Pair("category", "generate")); + } + else + entry.push_back(Pair("category", "receive")); + entry.push_back(Pair("amount", ValueFromAmount(r.second))); + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + } + } +} + +void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) +{ + bool fAllAccounts = (strAccount == string("*")); + + if (fAllAccounts || acentry.strAccount == strAccount) + { + Object entry; + entry.push_back(Pair("account", acentry.strAccount)); + entry.push_back(Pair("category", "move")); + entry.push_back(Pair("time", (boost::int64_t)acentry.nTime)); + entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit))); + entry.push_back(Pair("otheraccount", acentry.strOtherAccount)); + entry.push_back(Pair("comment", acentry.strComment)); + ret.push_back(entry); + } +} + +Value listtransactions(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 3) + throw runtime_error( + "listtransactions [account] [count=10] [from=0]\n" + "Returns up to [count] most recent transactions skipping the first [from] transactions for account [account]."); + + string strAccount = "*"; + if (params.size() > 0) + strAccount = params[0].get_str(); + int nCount = 10; + if (params.size() > 1) + nCount = params[1].get_int(); + int nFrom = 0; + if (params.size() > 2) + nFrom = params[2].get_int(); + + if (nCount < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); + if (nFrom < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); + + Array ret; + + std::list acentries; + CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount); + + // iterate backwards until we have nCount items to return: + for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx != 0) + ListTransactions(*pwtx, strAccount, 0, true, ret); + CAccountingEntry *const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); + + if ((int)ret.size() >= (nCount+nFrom)) break; + } + // ret is newest to oldest + + if (nFrom > (int)ret.size()) + nFrom = ret.size(); + if ((nFrom + nCount) > (int)ret.size()) + nCount = ret.size() - nFrom; + Array::iterator first = ret.begin(); + std::advance(first, nFrom); + Array::iterator last = ret.begin(); + std::advance(last, nFrom+nCount); + + if (last != ret.end()) ret.erase(last, ret.end()); + if (first != ret.begin()) ret.erase(ret.begin(), first); + + std::reverse(ret.begin(), ret.end()); // Return oldest to newest + + return ret; +} + +Value listaccounts(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "listaccounts [minconf=1]\n" + "Returns Object that has account names as keys, account balances as values."); + + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + map mapAccountBalances; + BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) { + if (IsMine(*pwalletMain, entry.first)) // This address belongs to me + mapAccountBalances[entry.second] = 0; + } + + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + + if(!wtx.IsFinal()) + continue; + + int64 nGeneratedImmature, nGeneratedMature, nFee; + string strSentAccount; + list > listReceived; + list > listSent; + wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); + if (wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived) + if (pwalletMain->mapAddressBook.count(r.first)) + mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; + else + mapAccountBalances[""] += r.second; + } + + if((wtx.IsCoinBaseOrStake() && wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetBlocksToMaturity() == 0) + || !wtx.IsCoinBaseOrStake()) + { + mapAccountBalances[strSentAccount] -= nFee; + mapAccountBalances[""] += nGeneratedMature; + + BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent) + mapAccountBalances[strSentAccount] -= s.second; + + } + } + + list acentries; + CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries); + BOOST_FOREACH(const CAccountingEntry& entry, acentries) + mapAccountBalances[entry.strAccount] += entry.nCreditDebit; + + Object ret; + BOOST_FOREACH(const PAIRTYPE(string, int64)& accountBalance, mapAccountBalances) { + ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); + } + return ret; +} + +Value listsinceblock(const Array& params, bool fHelp) +{ + if (fHelp) + throw runtime_error( + "listsinceblock [blockhash] [target-confirmations]\n" + "Get all transactions in blocks since block [blockhash], or all transactions if omitted"); + + CBlockIndex *pindex = NULL; + int target_confirms = 1; + + if (params.size() > 0) + { + uint256 blockId = 0; + + blockId.SetHex(params[0].get_str()); + pindex = CBlockLocator(blockId).GetBlockIndex(); + } + + if (params.size() > 1) + { + target_confirms = params[1].get_int(); + + if (target_confirms < 1) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter"); + } + + int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1; + + Array transactions; + + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) + { + CWalletTx tx = (*it).second; + + if (depth == -1 || tx.GetDepthInMainChain() < depth) + ListTransactions(tx, "*", 0, true, transactions); + } + + uint256 lastblock; + + if (target_confirms == 1) + { + lastblock = hashBestChain; + } + else + { + int target_height = pindexBest->nHeight + 1 - target_confirms; + + CBlockIndex *block; + for (block = pindexBest; + block && block->nHeight > target_height; + block = block->pprev) { } + + lastblock = block ? block->GetBlockHash() : 0; + } + + Object ret; + ret.push_back(Pair("transactions", transactions)); + ret.push_back(Pair("lastblock", lastblock.GetHex())); + + return ret; +} + +Value gettransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "gettransaction \n" + "Get detailed information about "); + + uint256 hash; + hash.SetHex(params[0].get_str()); + + Object entry; + + if (pwalletMain->mapWallet.count(hash)) + { + const CWalletTx& wtx = pwalletMain->mapWallet[hash]; + + TxToJSON(wtx, 0, entry); + + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0); + + entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); + if (wtx.IsFromMe()) + entry.push_back(Pair("fee", ValueFromAmount(nFee))); + + WalletTxToJSON(wtx, entry); + + Array details; + ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details); + entry.push_back(Pair("details", details)); + } + else + { + CTransaction tx; + uint256 hashBlock = 0; + if (GetTransaction(hash, tx, hashBlock)) + { + entry.push_back(Pair("txid", hash.GetHex())); + TxToJSON(tx, 0, entry); + if (hashBlock == 0) + entry.push_back(Pair("confirmations", 0)); + else + { + entry.push_back(Pair("blockhash", hashBlock.GetHex())); + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end() && (*mi).second) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + { + entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); + entry.push_back(Pair("txntime", (boost::int64_t)tx.nTime)); + entry.push_back(Pair("time", (boost::int64_t)pindex->nTime)); + } + else + entry.push_back(Pair("confirmations", 0)); + } + } + } + else + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); + } + + return entry; +} + + +Value backupwallet(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "backupwallet \n" + "Safely copies wallet.dat to destination, which can be a directory or a path with filename."); + + string strDest = params[0].get_str(); + if (!BackupWallet(*pwalletMain, strDest)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); + + return Value::null; +} + + +Value keypoolrefill(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 0) + throw runtime_error( + "keypoolrefill\n" + "Fills the keypool." + + HelpRequiringPassphrase()); + + EnsureWalletIsUnlocked(); + + pwalletMain->TopUpKeyPool(); + + if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); + + return Value::null; +} + + +void ThreadTopUpKeyPool(void* parg) +{ + // Make this thread recognisable as the key-topping-up thread + RenameThread("bitcoin-key-top"); + + pwalletMain->TopUpKeyPool(); +} + +void ThreadCleanWalletPassphrase(void* parg) +{ + // Make this thread recognisable as the wallet relocking thread + RenameThread("bitcoin-lock-wa"); + + int64 nMyWakeTime = GetTimeMillis() + *((int64*)parg) * 1000; + + ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime); + + if (nWalletUnlockTime == 0) + { + nWalletUnlockTime = nMyWakeTime; + + do + { + if (nWalletUnlockTime==0) + break; + int64 nToSleep = nWalletUnlockTime - GetTimeMillis(); + if (nToSleep <= 0) + break; + + LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime); + Sleep(nToSleep); + ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime); + + } while(1); + + if (nWalletUnlockTime) + { + nWalletUnlockTime = 0; + pwalletMain->Lock(); + } + } + else + { + if (nWalletUnlockTime < nMyWakeTime) + nWalletUnlockTime = nMyWakeTime; + } + + LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime); + + delete (int64*)parg; +} + +Value walletpassphrase(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 3)) + throw runtime_error( + "walletpassphrase [stakeonly]\n" + "Stores the wallet decryption key in memory for seconds.\n" + "stakeonly is optional true/false allowing only block staking."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called."); + + if (!pwalletMain->IsLocked()) + throw JSONRPCError(RPC_WALLET_ALREADY_UNLOCKED, "Error: Wallet is already unlocked, use walletlock first if need to change unlock settings."); + // Note that the walletpassphrase is stored in params[0] which is not mlock()ed + SecureString strWalletPass; + strWalletPass.reserve(100); + // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) + // Alternately, find a way to make params[0] mlock()'d to begin with. + strWalletPass = params[0].get_str().c_str(); + + if (strWalletPass.length() > 0) + { + if (!pwalletMain->Unlock(strWalletPass)) + throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); + } + else + throw runtime_error( + "walletpassphrase \n" + "Stores the wallet decryption key in memory for seconds."); + + NewThread(ThreadTopUpKeyPool, NULL); + int64* pnSleepTime = new int64(params[1].get_int64()); + NewThread(ThreadCleanWalletPassphrase, pnSleepTime); + + // ppcoin: if user OS account compromised prevent trivial sendmoney commands + if (params.size() > 2) + fWalletUnlockMintOnly = params[2].get_bool(); + else + fWalletUnlockMintOnly = false; + + return Value::null; +} + + +Value walletpassphrasechange(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + throw runtime_error( + "walletpassphrasechange \n" + "Changes the wallet passphrase from to ."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); + + // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string) + // Alternately, find a way to make params[0] mlock()'d to begin with. + SecureString strOldWalletPass; + strOldWalletPass.reserve(100); + strOldWalletPass = params[0].get_str().c_str(); + + SecureString strNewWalletPass; + strNewWalletPass.reserve(100); + strNewWalletPass = params[1].get_str().c_str(); + + if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1) + throw runtime_error( + "walletpassphrasechange \n" + "Changes the wallet passphrase from to ."); + + if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) + throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); + + return Value::null; +} + + +Value walletlock(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) + throw runtime_error( + "walletlock\n" + "Removes the wallet encryption key from memory, locking the wallet.\n" + "After calling this method, you will need to call walletpassphrase again\n" + "before being able to call any methods which require the wallet to be unlocked."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called."); + + { + LOCK(cs_nWalletUnlockTime); + pwalletMain->Lock(); + nWalletUnlockTime = 0; + } + + return Value::null; +} + + +Value encryptwallet(const Array& params, bool fHelp) +{ + if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) + throw runtime_error( + "encryptwallet \n" + "Encrypts the wallet with ."); + if (fHelp) + return true; + if (pwalletMain->IsCrypted()) + throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called."); + + // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) + // Alternately, find a way to make params[0] mlock()'d to begin with. + SecureString strWalletPass; + strWalletPass.reserve(100); + strWalletPass = params[0].get_str().c_str(); + + if (strWalletPass.length() < 1) + throw runtime_error( + "encryptwallet \n" + "Encrypts the wallet with ."); + + if (!pwalletMain->EncryptWallet(strWalletPass)) + throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet."); + + // BDB seems to have a bad habit of writing old data into + // slack space in .dat files; that is bad if the old data is + // unencrypted private keys. So: + StartShutdown(); + return "wallet encrypted; BERN server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; +} + +class DescribeAddressVisitor : public boost::static_visitor +{ +public: + Object operator()(const CNoDestination &dest) const { return Object(); } + + Object operator()(const CKeyID &keyID) const { + Object obj; + CPubKey vchPubKey; + pwalletMain->GetPubKey(keyID, vchPubKey); + obj.push_back(Pair("isscript", false)); + obj.push_back(Pair("pubkey", HexStr(vchPubKey.Raw()))); + obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed())); + return obj; + } + + Object operator()(const CScriptID &scriptID) const { + Object obj; + obj.push_back(Pair("isscript", true)); + CScript subscript; + pwalletMain->GetCScript(scriptID, subscript); + std::vector addresses; + txnouttype whichType; + int nRequired; + ExtractDestinations(subscript, whichType, addresses, nRequired); + obj.push_back(Pair("script", GetTxnOutputType(whichType))); + Array a; + BOOST_FOREACH(const CTxDestination& addr, addresses) + a.push_back(CBitcoinAddress(addr).ToString()); + obj.push_back(Pair("addresses", a)); + if (whichType == TX_MULTISIG) + obj.push_back(Pair("sigsrequired", nRequired)); + return obj; + } +}; + +Value validateaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "validateaddress \n" + "Return information about ."); + + CBitcoinAddress address(params[0].get_str()); + bool isValid = address.IsValid(); + + Object ret; + ret.push_back(Pair("isvalid", isValid)); + if (isValid) + { + CTxDestination dest = address.Get(); + string currentAddress = address.ToString(); + ret.push_back(Pair("address", currentAddress)); + bool fMine = IsMine(*pwalletMain, dest); + ret.push_back(Pair("ismine", fMine)); + if (fMine) { + Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest); + ret.insert(ret.end(), detail.begin(), detail.end()); + } + if (pwalletMain->mapAddressBook.count(dest)) + ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest])); + } + return ret; +} + +Value validatepubkey(const Array& params, bool fHelp) +{ + if (fHelp || !params.size() || params.size() > 2) + throw runtime_error( + "validatepubkey \n" + "Return information about ."); + + std::vector vchPubKey = ParseHex(params[0].get_str()); + CPubKey pubKey(vchPubKey); + + bool isValid = pubKey.IsValid(); + bool isCompressed = pubKey.IsCompressed(); + CKeyID keyID = pubKey.GetID(); + + CBitcoinAddress address; + address.Set(keyID); + + Object ret; + ret.push_back(Pair("isvalid", isValid)); + if (isValid) + { + CTxDestination dest = address.Get(); + string currentAddress = address.ToString(); + ret.push_back(Pair("address", currentAddress)); + bool fMine = IsMine(*pwalletMain, dest); + ret.push_back(Pair("ismine", fMine)); + ret.push_back(Pair("iscompressed", isCompressed)); + if (fMine) { + Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest); + ret.insert(ret.end(), detail.begin(), detail.end()); + } + if (pwalletMain->mapAddressBook.count(dest)) + ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest])); + } + return ret; +} + +// ppcoin: reserve balance from being staked for network protection +Value reservebalance(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "reservebalance [ [amount]]\n" + " is true or false to turn balance reserve on or off.\n" + " is a real and rounded to cent.\n" + "Set reserve amount not participating in network protection.\n" + "If no parameters provided current setting is printed.\n"); + + if (params.size() > 0) + { + bool fReserve = params[0].get_bool(); + if (fReserve) + { + if (params.size() == 1) + throw runtime_error("must provide amount to reserve balance.\n"); + int64 nAmount = AmountFromValue(params[1]); + nAmount = (nAmount / CENT) * CENT; // round to cent + if (nAmount < 0) + throw runtime_error("amount cannot be negative.\n"); + mapArgs["-reservebalance"] = FormatMoney(nAmount).c_str(); + } + else + { + if (params.size() > 1) + throw runtime_error("cannot specify amount to turn off reserve.\n"); + mapArgs["-reservebalance"] = "0"; + } + } + + Object result; + int64 nReserveBalance = 0; + if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) + throw runtime_error("invalid reserve balance amount\n"); + result.push_back(Pair("reserve", (nReserveBalance > 0))); + result.push_back(Pair("amount", ValueFromAmount(nReserveBalance))); + return result; +} + + +// ppcoin: check wallet integrity +Value checkwallet(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 0) + throw runtime_error( + "checkwallet\n" + "Check wallet for integrity.\n"); + + int nMismatchSpent; + int64 nBalanceInQuestion; + pwalletMain->FixSpentCoins(nMismatchSpent, nBalanceInQuestion, true); + Object result; + if (nMismatchSpent == 0) + result.push_back(Pair("wallet check passed", true)); + else + { + result.push_back(Pair("mismatched spent coins", nMismatchSpent)); + result.push_back(Pair("amount in question", ValueFromAmount(nBalanceInQuestion))); + } + return result; +} + + +// ppcoin: repair wallet +Value repairwallet(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 0) + throw runtime_error( + "repairwallet\n" + "Repair wallet if checkwallet reports any problem.\n"); + + int nMismatchSpent; + int64 nBalanceInQuestion; + pwalletMain->FixSpentCoins(nMismatchSpent, nBalanceInQuestion); + Object result; + if (nMismatchSpent == 0) + result.push_back(Pair("wallet check passed", true)); + else + { + result.push_back(Pair("mismatched spent coins", nMismatchSpent)); + result.push_back(Pair("amount affected by repair", ValueFromAmount(nBalanceInQuestion))); + } + return result; +} + +// BERN: resend unconfirmed wallet transactions +Value resendtx(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "resendtx\n" + "Re-send unconfirmed transactions.\n" + ); + + ResendWalletTransactions(); + + return Value::null; +} + +// ppcoin: make a public-private key pair +Value makekeypair(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "makekeypair [prefix]\n" + "Make a public/private key pair.\n" + "[prefix] is optional preferred prefix for the public key.\n"); + + string strPrefix = ""; + if (params.size() > 0) + strPrefix = params[0].get_str(); + + CKey key; + key.MakeNewKey(false); + + CPrivKey vchPrivKey = key.GetPrivKey(); + Object result; + result.push_back(Pair("PrivateKey", HexStr(vchPrivKey.begin(), vchPrivKey.end()))); + result.push_back(Pair("PublicKey", HexStr(key.GetPubKey().Raw()))); + return result; +} diff --git a/src/script.cpp b/src/script.cpp new file mode 100644 index 0000000..7184679 --- /dev/null +++ b/src/script.cpp @@ -0,0 +1,1885 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 +#include + +using namespace std; +using namespace boost; + +#include "script.h" +#include "keystore.h" +#include "bignum.h" +#include "key.h" +#include "main.h" +#include "sync.h" +#include "util.h" + +bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); + +static const valtype vchFalse(0); +static const valtype vchZero(0); +static const valtype vchTrue(1, 1); +static const CBigNum bnZero(0); +static const CBigNum bnOne(1); +static const CBigNum bnFalse(0); +static const CBigNum bnTrue(1); +static const size_t nMaxNumSize = 4; + + +CBigNum CastToBigNum(const valtype& vch) +{ + if (vch.size() > nMaxNumSize) + throw runtime_error("CastToBigNum() : overflow"); + // Get rid of extra leading zeros + return CBigNum(CBigNum(vch).getvch()); +} + +bool CastToBool(const valtype& vch) +{ + for (unsigned int i = 0; i < vch.size(); i++) + { + if (vch[i] != 0) + { + // Can be negative zero + if (i == vch.size()-1 && vch[i] == 0x80) + return false; + return true; + } + } + return false; +} + +// +// WARNING: This does not work as expected for signed integers; the sign-bit +// is left in place as the integer is zero-extended. The correct behavior +// would be to move the most significant bit of the last byte during the +// resize process. MakeSameSize() is currently only used by the disabled +// opcodes OP_AND, OP_OR, and OP_XOR. +// +void MakeSameSize(valtype& vch1, valtype& vch2) +{ + // Lengthen the shorter one + if (vch1.size() < vch2.size()) + // PATCH: + // +unsigned char msb = vch1[vch1.size()-1]; + // +vch1[vch1.size()-1] &= 0x7f; + // vch1.resize(vch2.size(), 0); + // +vch1[vch1.size()-1] = msb; + vch1.resize(vch2.size(), 0); + if (vch2.size() < vch1.size()) + // PATCH: + // +unsigned char msb = vch2[vch2.size()-1]; + // +vch2[vch2.size()-1] &= 0x7f; + // vch2.resize(vch1.size(), 0); + // +vch2[vch2.size()-1] = msb; + vch2.resize(vch1.size(), 0); +} + + + +// +// Script is a stack machine (like Forth) that evaluates a predicate +// returning a bool indicating valid or not. There are no loops. +// +#define stacktop(i) (stack.at(stack.size()+(i))) +#define altstacktop(i) (altstack.at(altstack.size()+(i))) +static inline void popstack(vector& stack) +{ + if (stack.empty()) + throw runtime_error("popstack() : stack empty"); + stack.pop_back(); +} + + +const char* GetTxnOutputType(txnouttype t) +{ + switch (t) + { + case TX_NONSTANDARD: return "nonstandard"; + case TX_PUBKEY: return "pubkey"; + case TX_PUBKEYHASH: return "pubkeyhash"; + case TX_SCRIPTHASH: return "scripthash"; + case TX_MULTISIG: return "multisig"; + } + return NULL; +} + + +const char* GetOpName(opcodetype opcode) +{ + switch (opcode) + { + // push value + case OP_0 : return "0"; + case OP_PUSHDATA1 : return "OP_PUSHDATA1"; + case OP_PUSHDATA2 : return "OP_PUSHDATA2"; + case OP_PUSHDATA4 : return "OP_PUSHDATA4"; + case OP_1NEGATE : return "-1"; + case OP_RESERVED : return "OP_RESERVED"; + case OP_1 : return "1"; + case OP_2 : return "2"; + case OP_3 : return "3"; + case OP_4 : return "4"; + case OP_5 : return "5"; + case OP_6 : return "6"; + case OP_7 : return "7"; + case OP_8 : return "8"; + case OP_9 : return "9"; + case OP_10 : return "10"; + case OP_11 : return "11"; + case OP_12 : return "12"; + case OP_13 : return "13"; + case OP_14 : return "14"; + case OP_15 : return "15"; + case OP_16 : return "16"; + + // control + case OP_NOP : return "OP_NOP"; + case OP_VER : return "OP_VER"; + case OP_IF : return "OP_IF"; + case OP_NOTIF : return "OP_NOTIF"; + case OP_VERIF : return "OP_VERIF"; + case OP_VERNOTIF : return "OP_VERNOTIF"; + case OP_ELSE : return "OP_ELSE"; + case OP_ENDIF : return "OP_ENDIF"; + case OP_VERIFY : return "OP_VERIFY"; + case OP_RETURN : return "OP_RETURN"; + + // stack ops + case OP_TOALTSTACK : return "OP_TOALTSTACK"; + case OP_FROMALTSTACK : return "OP_FROMALTSTACK"; + case OP_2DROP : return "OP_2DROP"; + case OP_2DUP : return "OP_2DUP"; + case OP_3DUP : return "OP_3DUP"; + case OP_2OVER : return "OP_2OVER"; + case OP_2ROT : return "OP_2ROT"; + case OP_2SWAP : return "OP_2SWAP"; + case OP_IFDUP : return "OP_IFDUP"; + case OP_DEPTH : return "OP_DEPTH"; + case OP_DROP : return "OP_DROP"; + case OP_DUP : return "OP_DUP"; + case OP_NIP : return "OP_NIP"; + case OP_OVER : return "OP_OVER"; + case OP_PICK : return "OP_PICK"; + case OP_ROLL : return "OP_ROLL"; + case OP_ROT : return "OP_ROT"; + case OP_SWAP : return "OP_SWAP"; + case OP_TUCK : return "OP_TUCK"; + + // splice ops + case OP_CAT : return "OP_CAT"; + case OP_SUBSTR : return "OP_SUBSTR"; + case OP_LEFT : return "OP_LEFT"; + case OP_RIGHT : return "OP_RIGHT"; + case OP_SIZE : return "OP_SIZE"; + + // bit logic + case OP_INVERT : return "OP_INVERT"; + case OP_AND : return "OP_AND"; + case OP_OR : return "OP_OR"; + case OP_XOR : return "OP_XOR"; + case OP_EQUAL : return "OP_EQUAL"; + case OP_EQUALVERIFY : return "OP_EQUALVERIFY"; + case OP_RESERVED1 : return "OP_RESERVED1"; + case OP_RESERVED2 : return "OP_RESERVED2"; + + // numeric + case OP_1ADD : return "OP_1ADD"; + case OP_1SUB : return "OP_1SUB"; + case OP_2MUL : return "OP_2MUL"; + case OP_2DIV : return "OP_2DIV"; + case OP_NEGATE : return "OP_NEGATE"; + case OP_ABS : return "OP_ABS"; + case OP_NOT : return "OP_NOT"; + case OP_0NOTEQUAL : return "OP_0NOTEQUAL"; + case OP_ADD : return "OP_ADD"; + case OP_SUB : return "OP_SUB"; + case OP_MUL : return "OP_MUL"; + case OP_DIV : return "OP_DIV"; + case OP_MOD : return "OP_MOD"; + case OP_LSHIFT : return "OP_LSHIFT"; + case OP_RSHIFT : return "OP_RSHIFT"; + case OP_BOOLAND : return "OP_BOOLAND"; + case OP_BOOLOR : return "OP_BOOLOR"; + case OP_NUMEQUAL : return "OP_NUMEQUAL"; + case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY"; + case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL"; + case OP_LESSTHAN : return "OP_LESSTHAN"; + case OP_GREATERTHAN : return "OP_GREATERTHAN"; + case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL"; + case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL"; + case OP_MIN : return "OP_MIN"; + case OP_MAX : return "OP_MAX"; + case OP_WITHIN : return "OP_WITHIN"; + + // crypto + case OP_RIPEMD160 : return "OP_RIPEMD160"; + case OP_SHA1 : return "OP_SHA1"; + case OP_SHA256 : return "OP_SHA256"; + case OP_HASH160 : return "OP_HASH160"; + case OP_HASH256 : return "OP_HASH256"; + case OP_CODESEPARATOR : return "OP_CODESEPARATOR"; + case OP_CHECKSIG : return "OP_CHECKSIG"; + case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY"; + case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG"; + case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY"; + + // expanson + case OP_NOP1 : return "OP_NOP1"; + case OP_NOP2 : return "OP_NOP2"; + case OP_NOP3 : return "OP_NOP3"; + case OP_NOP4 : return "OP_NOP4"; + case OP_NOP5 : return "OP_NOP5"; + case OP_NOP6 : return "OP_NOP6"; + case OP_NOP7 : return "OP_NOP7"; + case OP_NOP8 : return "OP_NOP8"; + case OP_NOP9 : return "OP_NOP9"; + case OP_NOP10 : return "OP_NOP10"; + + + + // template matching params + case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; + case OP_PUBKEY : return "OP_PUBKEY"; + + case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; + default: + return "OP_UNKNOWN"; + } +} + +bool EvalScript(vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + CAutoBN_CTX pctx; + CScript::const_iterator pc = script.begin(); + CScript::const_iterator pend = script.end(); + CScript::const_iterator pbegincodehash = script.begin(); + opcodetype opcode; + valtype vchPushValue; + vector vfExec; + vector altstack; + if (script.size() > 10000) + return false; + int nOpCount = 0; + + + try + { + while (pc < pend) + { + bool fExec = !count(vfExec.begin(), vfExec.end(), false); + + // + // Read instruction + // + if (!script.GetOp(pc, opcode, vchPushValue)) + return false; + if (vchPushValue.size() > 520) + return false; + if (opcode > OP_16 && ++nOpCount > 201) + return false; + + if (opcode == OP_CAT || + opcode == OP_SUBSTR || + opcode == OP_LEFT || + opcode == OP_RIGHT || + opcode == OP_INVERT || + opcode == OP_AND || + opcode == OP_OR || + opcode == OP_XOR || + opcode == OP_2MUL || + opcode == OP_2DIV || + opcode == OP_MUL || + opcode == OP_DIV || + opcode == OP_MOD || + opcode == OP_LSHIFT || + opcode == OP_RSHIFT) + return false; + + if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) + stack.push_back(vchPushValue); + else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) + switch (opcode) + { + // + // Push value + // + case OP_1NEGATE: + case OP_1: + case OP_2: + case OP_3: + case OP_4: + case OP_5: + case OP_6: + case OP_7: + case OP_8: + case OP_9: + case OP_10: + case OP_11: + case OP_12: + case OP_13: + case OP_14: + case OP_15: + case OP_16: + { + // ( -- value) + CBigNum bn((int)opcode - (int)(OP_1 - 1)); + stack.push_back(bn.getvch()); + } + break; + + + // + // Control + // + case OP_NOP: + case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: + case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: + break; + + case OP_IF: + case OP_NOTIF: + { + // if [statements] [else [statements]] endif + bool fValue = false; + if (fExec) + { + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + fValue = CastToBool(vch); + if (opcode == OP_NOTIF) + fValue = !fValue; + popstack(stack); + } + vfExec.push_back(fValue); + } + break; + + case OP_ELSE: + { + if (vfExec.empty()) + return false; + vfExec.back() = !vfExec.back(); + } + break; + + case OP_ENDIF: + { + if (vfExec.empty()) + return false; + vfExec.pop_back(); + } + break; + + case OP_VERIFY: + { + // (true -- ) or + // (false -- false) and return + if (stack.size() < 1) + return false; + bool fValue = CastToBool(stacktop(-1)); + if (fValue) + popstack(stack); + else + return false; + } + break; + + case OP_RETURN: + { + return false; + } + break; + + + // + // Stack ops + // + case OP_TOALTSTACK: + { + if (stack.size() < 1) + return false; + altstack.push_back(stacktop(-1)); + popstack(stack); + } + break; + + case OP_FROMALTSTACK: + { + if (altstack.size() < 1) + return false; + stack.push_back(altstacktop(-1)); + popstack(altstack); + } + break; + + case OP_2DROP: + { + // (x1 x2 -- ) + if (stack.size() < 2) + return false; + popstack(stack); + popstack(stack); + } + break; + + case OP_2DUP: + { + // (x1 x2 -- x1 x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch1 = stacktop(-2); + valtype vch2 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_3DUP: + { + // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) + if (stack.size() < 3) + return false; + valtype vch1 = stacktop(-3); + valtype vch2 = stacktop(-2); + valtype vch3 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + stack.push_back(vch3); + } + break; + + case OP_2OVER: + { + // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) + if (stack.size() < 4) + return false; + valtype vch1 = stacktop(-4); + valtype vch2 = stacktop(-3); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2ROT: + { + // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) + if (stack.size() < 6) + return false; + valtype vch1 = stacktop(-6); + valtype vch2 = stacktop(-5); + stack.erase(stack.end()-6, stack.end()-4); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2SWAP: + { + // (x1 x2 x3 x4 -- x3 x4 x1 x2) + if (stack.size() < 4) + return false; + swap(stacktop(-4), stacktop(-2)); + swap(stacktop(-3), stacktop(-1)); + } + break; + + case OP_IFDUP: + { + // (x - 0 | x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + if (CastToBool(vch)) + stack.push_back(vch); + } + break; + + case OP_DEPTH: + { + // -- stacksize + CBigNum bn(stack.size()); + stack.push_back(bn.getvch()); + } + break; + + case OP_DROP: + { + // (x -- ) + if (stack.size() < 1) + return false; + popstack(stack); + } + break; + + case OP_DUP: + { + // (x -- x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + stack.push_back(vch); + } + break; + + case OP_NIP: + { + // (x1 x2 -- x2) + if (stack.size() < 2) + return false; + stack.erase(stack.end() - 2); + } + break; + + case OP_OVER: + { + // (x1 x2 -- x1 x2 x1) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-2); + stack.push_back(vch); + } + break; + + case OP_PICK: + case OP_ROLL: + { + // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) + // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) + if (stack.size() < 2) + return false; + int n = CastToBigNum(stacktop(-1)).getint(); + popstack(stack); + if (n < 0 || n >= (int)stack.size()) + return false; + valtype vch = stacktop(-n-1); + if (opcode == OP_ROLL) + stack.erase(stack.end()-n-1); + stack.push_back(vch); + } + break; + + case OP_ROT: + { + // (x1 x2 x3 -- x2 x3 x1) + // x2 x1 x3 after first swap + // x2 x3 x1 after second swap + if (stack.size() < 3) + return false; + swap(stacktop(-3), stacktop(-2)); + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_SWAP: + { + // (x1 x2 -- x2 x1) + if (stack.size() < 2) + return false; + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_TUCK: + { + // (x1 x2 -- x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-1); + stack.insert(stack.end()-2, vch); + } + break; + + + // + // Splice ops + // + case OP_CAT: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + vch1.insert(vch1.end(), vch2.begin(), vch2.end()); + popstack(stack); + if (stacktop(-1).size() > 520) + return false; + } + break; + + case OP_SUBSTR: + { + // (in begin size -- out) + if (stack.size() < 3) + return false; + valtype& vch = stacktop(-3); + int nBegin = CastToBigNum(stacktop(-2)).getint(); + int nEnd = nBegin + CastToBigNum(stacktop(-1)).getint(); + if (nBegin < 0 || nEnd < nBegin) + return false; + if (nBegin > (int)vch.size()) + nBegin = vch.size(); + if (nEnd > (int)vch.size()) + nEnd = vch.size(); + vch.erase(vch.begin() + nEnd, vch.end()); + vch.erase(vch.begin(), vch.begin() + nBegin); + popstack(stack); + popstack(stack); + } + break; + + case OP_LEFT: + case OP_RIGHT: + { + // (in size -- out) + if (stack.size() < 2) + return false; + valtype& vch = stacktop(-2); + int nSize = CastToBigNum(stacktop(-1)).getint(); + if (nSize < 0) + return false; + if (nSize > (int)vch.size()) + nSize = vch.size(); + if (opcode == OP_LEFT) + vch.erase(vch.begin() + nSize, vch.end()); + else + vch.erase(vch.begin(), vch.end() - nSize); + popstack(stack); + } + break; + + case OP_SIZE: + { + // (in -- in size) + if (stack.size() < 1) + return false; + CBigNum bn(stacktop(-1).size()); + stack.push_back(bn.getvch()); + } + break; + + + // + // Bitwise logic + // + case OP_INVERT: + { + // (in - out) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + for (unsigned int i = 0; i < vch.size(); i++) + vch[i] = ~vch[i]; + } + break; + + // + // WARNING: These disabled opcodes exhibit unexpected behavior + // when used on signed integers due to a bug in MakeSameSize() + // [see definition of MakeSameSize() above]. + // + case OP_AND: + case OP_OR: + case OP_XOR: + { + // (x1 x2 - out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + MakeSameSize(vch1, vch2); // <-- NOT SAFE FOR SIGNED VALUES + if (opcode == OP_AND) + { + for (unsigned int i = 0; i < vch1.size(); i++) + vch1[i] &= vch2[i]; + } + else if (opcode == OP_OR) + { + for (unsigned int i = 0; i < vch1.size(); i++) + vch1[i] |= vch2[i]; + } + else if (opcode == OP_XOR) + { + for (unsigned int i = 0; i < vch1.size(); i++) + vch1[i] ^= vch2[i]; + } + popstack(stack); + } + break; + + case OP_EQUAL: + case OP_EQUALVERIFY: + //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL + { + // (x1 x2 - bool) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + bool fEqual = (vch1 == vch2); + // OP_NOTEQUAL is disabled because it would be too easy to say + // something like n != 1 and have some wiseguy pass in 1 with extra + // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) + //if (opcode == OP_NOTEQUAL) + // fEqual = !fEqual; + popstack(stack); + popstack(stack); + stack.push_back(fEqual ? vchTrue : vchFalse); + if (opcode == OP_EQUALVERIFY) + { + if (fEqual) + popstack(stack); + else + return false; + } + } + break; + + + // + // Numeric + // + case OP_1ADD: + case OP_1SUB: + case OP_2MUL: + case OP_2DIV: + case OP_NEGATE: + case OP_ABS: + case OP_NOT: + case OP_0NOTEQUAL: + { + // (in -- out) + if (stack.size() < 1) + return false; + CBigNum bn = CastToBigNum(stacktop(-1)); + switch (opcode) + { + case OP_1ADD: bn += bnOne; break; + case OP_1SUB: bn -= bnOne; break; + case OP_2MUL: bn <<= 1; break; + case OP_2DIV: bn >>= 1; break; + case OP_NEGATE: bn = -bn; break; + case OP_ABS: if (bn < bnZero) bn = -bn; break; + case OP_NOT: bn = (bn == bnZero); break; + case OP_0NOTEQUAL: bn = (bn != bnZero); break; + default: assert(!"invalid opcode"); break; + } + popstack(stack); + stack.push_back(bn.getvch()); + } + break; + + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_MOD: + case OP_LSHIFT: + case OP_RSHIFT: + case OP_BOOLAND: + case OP_BOOLOR: + case OP_NUMEQUAL: + case OP_NUMEQUALVERIFY: + case OP_NUMNOTEQUAL: + case OP_LESSTHAN: + case OP_GREATERTHAN: + case OP_LESSTHANOREQUAL: + case OP_GREATERTHANOREQUAL: + case OP_MIN: + case OP_MAX: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + CBigNum bn1 = CastToBigNum(stacktop(-2)); + CBigNum bn2 = CastToBigNum(stacktop(-1)); + CBigNum bn; + switch (opcode) + { + case OP_ADD: + bn = bn1 + bn2; + break; + + case OP_SUB: + bn = bn1 - bn2; + break; + + case OP_MUL: + if (!BN_mul(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_DIV: + if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) + return false; + break; + + case OP_MOD: + if (!BN_mod(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_LSHIFT: + if (bn2 < bnZero || bn2 > CBigNum(2048)) + return false; + bn = bn1 << bn2.getulong(); + break; + + case OP_RSHIFT: + if (bn2 < bnZero || bn2 > CBigNum(2048)) + return false; + bn = bn1 >> bn2.getulong(); + break; + + case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; + case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; + case OP_NUMEQUAL: bn = (bn1 == bn2); break; + case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; + case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; + case OP_LESSTHAN: bn = (bn1 < bn2); break; + case OP_GREATERTHAN: bn = (bn1 > bn2); break; + case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; + case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; + case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; + case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; + default: assert(!"invalid opcode"); break; + } + popstack(stack); + popstack(stack); + stack.push_back(bn.getvch()); + + if (opcode == OP_NUMEQUALVERIFY) + { + if (CastToBool(stacktop(-1))) + popstack(stack); + else + return false; + } + } + break; + + case OP_WITHIN: + { + // (x min max -- out) + if (stack.size() < 3) + return false; + CBigNum bn1 = CastToBigNum(stacktop(-3)); + CBigNum bn2 = CastToBigNum(stacktop(-2)); + CBigNum bn3 = CastToBigNum(stacktop(-1)); + bool fValue = (bn2 <= bn1 && bn1 < bn3); + popstack(stack); + popstack(stack); + popstack(stack); + stack.push_back(fValue ? vchTrue : vchFalse); + } + break; + + + // + // Crypto + // + case OP_RIPEMD160: + case OP_SHA1: + case OP_SHA256: + case OP_HASH160: + case OP_HASH256: + { + // (in -- hash) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); + if (opcode == OP_RIPEMD160) + RIPEMD160(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA1) + SHA1(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA256) + SHA256(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_HASH160) + { + uint160 hash160 = Hash160(vch); + memcpy(&vchHash[0], &hash160, sizeof(hash160)); + } + else if (opcode == OP_HASH256) + { + uint256 hash = Hash(vch.begin(), vch.end()); + memcpy(&vchHash[0], &hash, sizeof(hash)); + } + popstack(stack); + stack.push_back(vchHash); + } + break; + + case OP_CODESEPARATOR: + { + // Hash starts after the code separator + pbegincodehash = pc; + } + break; + + case OP_CHECKSIG: + case OP_CHECKSIGVERIFY: + { + // (sig pubkey -- bool) + if (stack.size() < 2) + return false; + + valtype& vchSig = stacktop(-2); + valtype& vchPubKey = stacktop(-1); + + ////// debug print + //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); + //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signature, since there's no way for a signature to sign itself + scriptCode.FindAndDelete(CScript(vchSig)); + + bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); + + popstack(stack); + popstack(stack); + stack.push_back(fSuccess ? vchTrue : vchFalse); + if (opcode == OP_CHECKSIGVERIFY) + { + if (fSuccess) + popstack(stack); + else + return false; + } + } + break; + + case OP_CHECKMULTISIG: + case OP_CHECKMULTISIGVERIFY: + { + // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) + + int i = 1; + if ((int)stack.size() < i) + return false; + + int nKeysCount = CastToBigNum(stacktop(-i)).getint(); + if (nKeysCount < 0 || nKeysCount > 20) + return false; + nOpCount += nKeysCount; + if (nOpCount > 201) + return false; + int ikey = ++i; + i += nKeysCount; + if ((int)stack.size() < i) + return false; + + int nSigsCount = CastToBigNum(stacktop(-i)).getint(); + if (nSigsCount < 0 || nSigsCount > nKeysCount) + return false; + int isig = ++i; + i += nSigsCount; + if ((int)stack.size() < i) + return false; + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signatures, since there's no way for a signature to sign itself + for (int k = 0; k < nSigsCount; k++) + { + valtype& vchSig = stacktop(-isig-k); + scriptCode.FindAndDelete(CScript(vchSig)); + } + + bool fSuccess = true; + while (fSuccess && nSigsCount > 0) + { + valtype& vchSig = stacktop(-isig); + valtype& vchPubKey = stacktop(-ikey); + + // Check signature + if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)) + { + isig++; + nSigsCount--; + } + ikey++; + nKeysCount--; + + // If there are more signatures left than keys left, + // then too many signatures have failed + if (nSigsCount > nKeysCount) + fSuccess = false; + } + + while (i-- > 0) + popstack(stack); + stack.push_back(fSuccess ? vchTrue : vchFalse); + + if (opcode == OP_CHECKMULTISIGVERIFY) + { + if (fSuccess) + popstack(stack); + else + return false; + } + } + break; + + default: + return false; + } + + // Size limits + if (stack.size() + altstack.size() > 1000) + return false; + } + } + catch (...) + { + return false; + } + + + if (!vfExec.empty()) + return false; + + return true; +} + + + + + + + + + +uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + if (nIn >= txTo.vin.size()) + { + printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); + return 1; + } + CTransaction txTmp(txTo); + + // In case concatenating two scripts ends up with two codeseparators, + // or an extra one at the end, this prevents all those possible incompatibilities. + scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); + + // Blank out other inputs' signatures + for (unsigned int i = 0; i < txTmp.vin.size(); i++) + txTmp.vin[i].scriptSig = CScript(); + txTmp.vin[nIn].scriptSig = scriptCode; + + // Blank out some of the outputs + if ((nHashType & 0x1f) == SIGHASH_NONE) + { + // Wildcard payee + txTmp.vout.clear(); + + // Let the others update at will + for (unsigned int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + else if ((nHashType & 0x1f) == SIGHASH_SINGLE) + { + // Only lock-in the txout payee at same index as txin + unsigned int nOut = nIn; + if (nOut >= txTmp.vout.size()) + { + printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); + return 1; + } + txTmp.vout.resize(nOut+1); + for (unsigned int i = 0; i < nOut; i++) + txTmp.vout[i].SetNull(); + + // Let the others update at will + for (unsigned int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + + // Blank out other inputs completely, not recommended for open transactions + if (nHashType & SIGHASH_ANYONECANPAY) + { + txTmp.vin[0] = txTmp.vin[nIn]; + txTmp.vin.resize(1); + } + + // Serialize and hash + CDataStream ss(SER_GETHASH, 0); + ss.reserve(10000); + ss << txTmp << nHashType; + return Hash(ss.begin(), ss.end()); +} + + +// Valid signature cache, to avoid doing expensive ECDSA signature checking +// twice for every transaction (once when accepted into memory pool, and +// again when accepted into the block chain) + +class CSignatureCache +{ +private: + // sigdata_type is (signature hash, signature, public key): + typedef boost::tuple, std::vector > sigdata_type; + std::set< sigdata_type> setValid; + CCriticalSection cs_sigcache; + +public: + bool + Get(uint256 hash, const std::vector& vchSig, const std::vector& pubKey) + { + LOCK(cs_sigcache); + + sigdata_type k(hash, vchSig, pubKey); + std::set::iterator mi = setValid.find(k); + if (mi != setValid.end()) + return true; + return false; + } + + void Set(uint256 hash, const std::vector& vchSig, const std::vector& pubKey) + { + // DoS prevention: limit cache size to less than 10MB + // (~200 bytes per cache entry times 50,000 entries) + // Since there are a maximum of 20,000 signature operations per block + // 50,000 is a reasonable default. + int64 nMaxCacheSize = GetArg("-maxsigcachesize", 50000); + if (nMaxCacheSize <= 0) return; + + LOCK(cs_sigcache); + + while (static_cast(setValid.size()) > nMaxCacheSize) + { + // Evict a random entry. Random because that helps + // foil would-be DoS attackers who might try to pre-generate + // and re-use a set of valid signatures just-slightly-greater + // than our cache size. + uint256 randomHash = GetRandHash(); + std::vector unused; + std::set::iterator it = + setValid.lower_bound(sigdata_type(randomHash, unused, unused)); + if (it == setValid.end()) + it = setValid.begin(); + setValid.erase(*it); + } + + sigdata_type k(hash, vchSig, pubKey); + setValid.insert(k); + } +}; + +bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, + const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + static CSignatureCache signatureCache; + + // Hash type is one byte tacked on to the end of the signature + if (vchSig.empty()) + return false; + if (nHashType == 0) + nHashType = vchSig.back(); + else if (nHashType != vchSig.back()) + return false; + vchSig.pop_back(); + + uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType); + + if (signatureCache.Get(sighash, vchSig, vchPubKey)) + return true; + + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + + if (!key.Verify(sighash, vchSig)) + return false; + + signatureCache.Set(sighash, vchSig, vchPubKey); + return true; +} + + + + + + + + + +// +// Return public keys or hashes from scriptPubKey, for 'standard' transaction types. +// +bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector >& vSolutionsRet) +{ + // Templates + static map mTemplates; + if (mTemplates.empty()) + { + // Standard tx, sender provides pubkey, receiver adds signature + mTemplates.insert(make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG)); + + // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey + mTemplates.insert(make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG)); + + // Sender provides N pubkeys, receivers provides M signatures + mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG)); + } + + // Shortcut for pay-to-script-hash, which are more constrained than the other types: + // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL + if (scriptPubKey.IsPayToScriptHash()) + { + typeRet = TX_SCRIPTHASH; + vector hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22); + vSolutionsRet.push_back(hashBytes); + return true; + } + + // Scan templates + const CScript& script1 = scriptPubKey; + BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates) + { + const CScript& script2 = tplate.second; + vSolutionsRet.clear(); + + opcodetype opcode1, opcode2; + vector vch1, vch2; + + // Compare + CScript::const_iterator pc1 = script1.begin(); + CScript::const_iterator pc2 = script2.begin(); + while (true) + { + if (pc1 == script1.end() && pc2 == script2.end()) + { + // Found a match + typeRet = tplate.first; + if (typeRet == TX_MULTISIG) + { + // Additional checks for TX_MULTISIG: + unsigned char m = vSolutionsRet.front()[0]; + unsigned char n = vSolutionsRet.back()[0]; + if (m < 1 || n < 1 || m > n || vSolutionsRet.size()-2 != n) + return false; + } + return true; + } + if (!script1.GetOp(pc1, opcode1, vch1)) + break; + if (!script2.GetOp(pc2, opcode2, vch2)) + break; + + // Template matching opcodes: + if (opcode2 == OP_PUBKEYS) + { + while (vch1.size() >= 33 && vch1.size() <= 120) + { + vSolutionsRet.push_back(vch1); + if (!script1.GetOp(pc1, opcode1, vch1)) + break; + } + if (!script2.GetOp(pc2, opcode2, vch2)) + break; + // Normal situation is to fall through + // to other if/else statements + } + + if (opcode2 == OP_PUBKEY) + { + if (vch1.size() < 33 || vch1.size() > 120) + break; + vSolutionsRet.push_back(vch1); + } + else if (opcode2 == OP_PUBKEYHASH) + { + if (vch1.size() != sizeof(uint160)) + break; + vSolutionsRet.push_back(vch1); + } + else if (opcode2 == OP_SMALLINTEGER) + { // Single-byte small integer pushed onto vSolutions + if (opcode1 == OP_0 || + (opcode1 >= OP_1 && opcode1 <= OP_16)) + { + char n = (char)CScript::DecodeOP_N(opcode1); + vSolutionsRet.push_back(valtype(1, n)); + } + else + break; + } + else if (opcode1 != opcode2 || vch1 != vch2) + { + // Others must match exactly + break; + } + } + } + + vSolutionsRet.clear(); + typeRet = TX_NONSTANDARD; + return false; +} + + +bool Sign1(const CKeyID& address, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet) +{ + CKey key; + if (!keystore.GetKey(address, key)) + return false; + + vector vchSig; + if (!key.Sign(hash, vchSig)) + return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig; + + return true; +} + +bool SignN(const vector& multisigdata, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet) +{ + int nSigned = 0; + int nRequired = multisigdata.front()[0]; + for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++) + { + const valtype& pubkey = multisigdata[i]; + CKeyID keyID = CPubKey(pubkey).GetID(); + if (Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) + ++nSigned; + } + return nSigned==nRequired; +} + +// +// Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type. +// Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), +// unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. +// Returns false if scriptPubKey could not be completely satisfied. +// +bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType, + CScript& scriptSigRet, txnouttype& whichTypeRet) +{ + scriptSigRet.clear(); + + vector vSolutions; + if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) + return false; + + CKeyID keyID; + switch (whichTypeRet) + { + case TX_NONSTANDARD: + return false; + case TX_PUBKEY: + keyID = CPubKey(vSolutions[0]).GetID(); + return Sign1(keyID, keystore, hash, nHashType, scriptSigRet); + case TX_PUBKEYHASH: + keyID = CKeyID(uint160(vSolutions[0])); + if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) + return false; + else + { + CPubKey vch; + keystore.GetPubKey(keyID, vch); + scriptSigRet << vch; + } + return true; + case TX_SCRIPTHASH: + return keystore.GetCScript(uint160(vSolutions[0]), scriptSigRet); + + case TX_MULTISIG: + scriptSigRet << OP_0; // workaround CHECKMULTISIG bug + return (SignN(vSolutions, keystore, hash, nHashType, scriptSigRet)); + } + return false; +} + +int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions) +{ + switch (t) + { + case TX_NONSTANDARD: + return -1; + case TX_PUBKEY: + return 1; + case TX_PUBKEYHASH: + return 2; + case TX_MULTISIG: + if (vSolutions.size() < 1 || vSolutions[0].size() < 1) + return -1; + return vSolutions[0][0] + 1; + case TX_SCRIPTHASH: + return 1; // doesn't include args needed by the script + } + return -1; +} + +bool IsStandard(const CScript& scriptPubKey) +{ + vector vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_MULTISIG) + { + unsigned char m = vSolutions.front()[0]; + unsigned char n = vSolutions.back()[0]; + // Support up to x-of-3 multisig txns as standard + if (n < 1 || n > 3) + return false; + if (m < 1 || m > n) + return false; + } + + return whichType != TX_NONSTANDARD; +} + + +unsigned int HaveKeys(const vector& pubkeys, const CKeyStore& keystore) +{ + unsigned int nResult = 0; + BOOST_FOREACH(const valtype& pubkey, pubkeys) + { + CKeyID keyID = CPubKey(pubkey).GetID(); + if (keystore.HaveKey(keyID)) + ++nResult; + } + return nResult; +} + + +class CKeyStoreIsMineVisitor : public boost::static_visitor +{ +private: + const CKeyStore *keystore; +public: + CKeyStoreIsMineVisitor(const CKeyStore *keystoreIn) : keystore(keystoreIn) { } + bool operator()(const CNoDestination &dest) const { return false; } + bool operator()(const CKeyID &keyID) const { return keystore->HaveKey(keyID); } + bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); } +}; + +bool IsMine(const CKeyStore &keystore, const CTxDestination &dest) +{ + return boost::apply_visitor(CKeyStoreIsMineVisitor(&keystore), dest); +} + +bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) +{ + vector vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + CKeyID keyID; + switch (whichType) + { + case TX_NONSTANDARD: + return false; + case TX_PUBKEY: + keyID = CPubKey(vSolutions[0]).GetID(); + return keystore.HaveKey(keyID); + case TX_PUBKEYHASH: + keyID = CKeyID(uint160(vSolutions[0])); + return keystore.HaveKey(keyID); + case TX_SCRIPTHASH: + { + CScript subscript; + if (!keystore.GetCScript(CScriptID(uint160(vSolutions[0])), subscript)) + return false; + return IsMine(keystore, subscript); + } + case TX_MULTISIG: + { + // Only consider transactions "mine" if we own ALL the + // keys involved. multi-signature transactions that are + // partially owned (somebody else has a key that can spend + // them) enable spend-out-from-under-you attacks, especially + // in shared-wallet situations. + vector keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); + return HaveKeys(keys, keystore) == keys.size(); + } + } + return false; +} + +bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) +{ + vector vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_PUBKEY) + { + addressRet = CPubKey(vSolutions[0]).GetID(); + return true; + } + else if (whichType == TX_PUBKEYHASH) + { + addressRet = CKeyID(uint160(vSolutions[0])); + return true; + } + else if (whichType == TX_SCRIPTHASH) + { + addressRet = CScriptID(uint160(vSolutions[0])); + return true; + } + // Multisig txns have more than one address... + return false; +} + +bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vector& addressRet, int& nRequiredRet) +{ + addressRet.clear(); + typeRet = TX_NONSTANDARD; + vector vSolutions; + if (!Solver(scriptPubKey, typeRet, vSolutions)) + return false; + + if (typeRet == TX_MULTISIG) + { + nRequiredRet = vSolutions.front()[0]; + for (unsigned int i = 1; i < vSolutions.size()-1; i++) + { + CTxDestination address = CPubKey(vSolutions[i]).GetID(); + addressRet.push_back(address); + } + } + else + { + nRequiredRet = 1; + CTxDestination address; + if (!ExtractDestination(scriptPubKey, address)) + return false; + addressRet.push_back(address); + } + + return true; +} + +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType) +{ + vector > stack, stackCopy; + if (!EvalScript(stack, scriptSig, txTo, nIn, nHashType)) + return false; + if (fValidatePayToScriptHash) + stackCopy = stack; + if (!EvalScript(stack, scriptPubKey, txTo, nIn, nHashType)) + return false; + if (stack.empty()) + return false; + + if (CastToBool(stack.back()) == false) + return false; + + // Additional validation for spend-to-script-hash transactions: + if (fValidatePayToScriptHash && scriptPubKey.IsPayToScriptHash()) + { + if (!scriptSig.IsPushOnly()) // scriptSig must be literals-only + return false; // or validation fails + + const valtype& pubKeySerialized = stackCopy.back(); + CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); + popstack(stackCopy); + + if (!EvalScript(stackCopy, pubKey2, txTo, nIn, nHashType)) + return false; + if (stackCopy.empty()) + return false; + return CastToBool(stackCopy.back()); + } + + return true; +} + + +bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType) +{ + assert(nIn < txTo.vin.size()); + CTxIn& txin = txTo.vin[nIn]; + + // Leave out the signature from the hash, since a signature can't sign itself. + // The checksig op will also drop the signatures from its hash. + uint256 hash = SignatureHash(fromPubKey, txTo, nIn, nHashType); + + txnouttype whichType; + if (!Solver(keystore, fromPubKey, hash, nHashType, txin.scriptSig, whichType)) + return false; + + if (whichType == TX_SCRIPTHASH) + { + // Solver returns the subscript that need to be evaluated; + // the final scriptSig is the signatures from that + // and then the serialized subscript: + CScript subscript = txin.scriptSig; + + // Recompute txn hash using subscript in place of scriptPubKey: + uint256 hash2 = SignatureHash(subscript, txTo, nIn, nHashType); + + txnouttype subType; + bool fSolved = + Solver(keystore, subscript, hash2, nHashType, txin.scriptSig, subType) && subType != TX_SCRIPTHASH; + // Append serialized subscript whether or not it is completely signed: + txin.scriptSig << static_cast(subscript); + if (!fSolved) return false; + } + + // Test solution + return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, true, 0); +} + +bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType) +{ + assert(nIn < txTo.vin.size()); + CTxIn& txin = txTo.vin[nIn]; + assert(txin.prevout.n < txFrom.vout.size()); + assert(txin.prevout.hash == txFrom.GetHash()); + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, nHashType); +} + +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType) +{ + assert(nIn < txTo.vin.size()); + const CTxIn& txin = txTo.vin[nIn]; + if (txin.prevout.n >= txFrom.vout.size()) + return false; + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + if (txin.prevout.hash != txFrom.GetHash()) + return false; + + return VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, fValidatePayToScriptHash, nHashType); +} + +static CScript PushAll(const vector& values) +{ + CScript result; + BOOST_FOREACH(const valtype& v, values) + result << v; + return result; +} + +static CScript CombineMultisig(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, + const vector& vSolutions, + vector& sigs1, vector& sigs2) +{ + // Combine all the signatures we've got: + set allsigs; + BOOST_FOREACH(const valtype& v, sigs1) + { + if (!v.empty()) + allsigs.insert(v); + } + BOOST_FOREACH(const valtype& v, sigs2) + { + if (!v.empty()) + allsigs.insert(v); + } + + // Build a map of pubkey -> signature by matching sigs to pubkeys: + assert(vSolutions.size() > 1); + unsigned int nSigsRequired = vSolutions.front()[0]; + unsigned int nPubKeys = vSolutions.size()-2; + map sigs; + BOOST_FOREACH(const valtype& sig, allsigs) + { + for (unsigned int i = 0; i < nPubKeys; i++) + { + const valtype& pubkey = vSolutions[i+1]; + if (sigs.count(pubkey)) + continue; // Already got a sig for this pubkey + + if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0)) + { + sigs[pubkey] = sig; + break; + } + } + } + // Now build a merged CScript: + unsigned int nSigsHave = 0; + CScript result; result << OP_0; // pop-one-too-many workaround + for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++) + { + if (sigs.count(vSolutions[i+1])) + { + result << sigs[vSolutions[i+1]]; + ++nSigsHave; + } + } + // Fill any missing with OP_0: + for (unsigned int i = nSigsHave; i < nSigsRequired; i++) + result << OP_0; + + return result; +} + +static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, + const txnouttype txType, const vector& vSolutions, + vector& sigs1, vector& sigs2) +{ + switch (txType) + { + case TX_NONSTANDARD: + // Don't know anything about this, assume bigger one is correct: + if (sigs1.size() >= sigs2.size()) + return PushAll(sigs1); + return PushAll(sigs2); + case TX_PUBKEY: + case TX_PUBKEYHASH: + // Signatures are bigger than placeholders or empty scripts: + if (sigs1.empty() || sigs1[0].empty()) + return PushAll(sigs2); + return PushAll(sigs1); + case TX_SCRIPTHASH: + if (sigs1.empty() || sigs1.back().empty()) + return PushAll(sigs2); + else if (sigs2.empty() || sigs2.back().empty()) + return PushAll(sigs1); + else + { + // Recur to combine: + valtype spk = sigs1.back(); + CScript pubKey2(spk.begin(), spk.end()); + + txnouttype txType2; + vector > vSolutions2; + Solver(pubKey2, txType2, vSolutions2); + sigs1.pop_back(); + sigs2.pop_back(); + CScript result = CombineSignatures(pubKey2, txTo, nIn, txType2, vSolutions2, sigs1, sigs2); + result << spk; + return result; + } + case TX_MULTISIG: + return CombineMultisig(scriptPubKey, txTo, nIn, vSolutions, sigs1, sigs2); + } + + return CScript(); +} + +CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, + const CScript& scriptSig1, const CScript& scriptSig2) +{ + txnouttype txType; + vector > vSolutions; + Solver(scriptPubKey, txType, vSolutions); + + vector stack1; + EvalScript(stack1, scriptSig1, CTransaction(), 0, 0); + vector stack2; + EvalScript(stack2, scriptSig2, CTransaction(), 0, 0); + + return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2); +} + +unsigned int CScript::GetSigOpCount(bool fAccurate) const +{ + unsigned int n = 0; + const_iterator pc = begin(); + opcodetype lastOpcode = OP_INVALIDOPCODE; + while (pc < end()) + { + opcodetype opcode; + if (!GetOp(pc, opcode)) + break; + if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY) + n++; + else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY) + { + if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16) + n += DecodeOP_N(lastOpcode); + else + n += 20; + } + lastOpcode = opcode; + } + return n; +} + +unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const +{ + if (!IsPayToScriptHash()) + return GetSigOpCount(true); + + // This is a pay-to-script-hash scriptPubKey; + // get the last item that the scriptSig + // pushes onto the stack: + const_iterator pc = scriptSig.begin(); + vector data; + while (pc < scriptSig.end()) + { + opcodetype opcode; + if (!scriptSig.GetOp(pc, opcode, data)) + return 0; + if (opcode > OP_16) + return 0; + } + + /// ... and return its opcount: + CScript subscript(data.begin(), data.end()); + return subscript.GetSigOpCount(true); +} + +bool CScript::IsPayToScriptHash() const +{ + // Extra-fast test for pay-to-script-hash CScripts: + return (this->size() == 23 && + this->at(0) == OP_HASH160 && + this->at(1) == 0x14 && + this->at(22) == OP_EQUAL); +} + +class CScriptVisitor : public boost::static_visitor +{ +private: + CScript *script; +public: + CScriptVisitor(CScript *scriptin) { script = scriptin; } + + bool operator()(const CNoDestination &dest) const { + script->clear(); + return false; + } + + bool operator()(const CKeyID &keyID) const { + script->clear(); + *script << OP_DUP << OP_HASH160 << keyID << OP_EQUALVERIFY << OP_CHECKSIG; + return true; + } + + bool operator()(const CScriptID &scriptID) const { + script->clear(); + *script << OP_HASH160 << scriptID << OP_EQUAL; + return true; + } +}; + +void CScript::SetDestination(const CTxDestination& dest) +{ + boost::apply_visitor(CScriptVisitor(this), dest); +} + +void CScript::SetMultisig(int nRequired, const std::vector& keys) +{ + this->clear(); + + *this << EncodeOP_N(nRequired); + BOOST_FOREACH(const CKey& key, keys) + *this << key.GetPubKey(); + *this << EncodeOP_N(keys.size()) << OP_CHECKMULTISIG; +} diff --git a/src/script.h b/src/script.h new file mode 100644 index 0000000..99465cb --- /dev/null +++ b/src/script.h @@ -0,0 +1,606 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 H_BITCOIN_SCRIPT +#define H_BITCOIN_SCRIPT + +#include +#include + +#include +#include + +#include "keystore.h" +#include "bignum.h" + +typedef std::vector valtype; + +class CTransaction; + +/** Signature hash types/flags */ +enum +{ + SIGHASH_ALL = 1, + SIGHASH_NONE = 2, + SIGHASH_SINGLE = 3, + SIGHASH_ANYONECANPAY = 0x80, +}; + + +enum txnouttype +{ + TX_NONSTANDARD, + // 'standard' transaction types: + TX_PUBKEY, + TX_PUBKEYHASH, + TX_SCRIPTHASH, + TX_MULTISIG, +}; + +class CNoDestination { +public: + friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; } + friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } +}; + +/** A txout script template with a specific destination. It is either: + * * CNoDestination: no destination set + * * CKeyID: TX_PUBKEYHASH destination + * * CScriptID: TX_SCRIPTHASH destination + * A CTxDestination is the internal data type encoded in a CBitcoinAddress + */ +typedef boost::variant CTxDestination; + +const char* GetTxnOutputType(txnouttype t); + +/** Script opcodes */ +enum opcodetype +{ + // push value + OP_0 = 0x00, + OP_FALSE = OP_0, + OP_PUSHDATA1 = 0x4c, + OP_PUSHDATA2 = 0x4d, + OP_PUSHDATA4 = 0x4e, + OP_1NEGATE = 0x4f, + OP_RESERVED = 0x50, + OP_1 = 0x51, + OP_TRUE=OP_1, + OP_2 = 0x52, + OP_3 = 0x53, + OP_4 = 0x54, + OP_5 = 0x55, + OP_6 = 0x56, + OP_7 = 0x57, + OP_8 = 0x58, + OP_9 = 0x59, + OP_10 = 0x5a, + OP_11 = 0x5b, + OP_12 = 0x5c, + OP_13 = 0x5d, + OP_14 = 0x5e, + OP_15 = 0x5f, + OP_16 = 0x60, + + // control + OP_NOP = 0x61, + OP_VER = 0x62, + OP_IF = 0x63, + OP_NOTIF = 0x64, + OP_VERIF = 0x65, + OP_VERNOTIF = 0x66, + OP_ELSE = 0x67, + OP_ENDIF = 0x68, + OP_VERIFY = 0x69, + OP_RETURN = 0x6a, + + // stack ops + OP_TOALTSTACK = 0x6b, + OP_FROMALTSTACK = 0x6c, + OP_2DROP = 0x6d, + OP_2DUP = 0x6e, + OP_3DUP = 0x6f, + OP_2OVER = 0x70, + OP_2ROT = 0x71, + OP_2SWAP = 0x72, + OP_IFDUP = 0x73, + OP_DEPTH = 0x74, + OP_DROP = 0x75, + OP_DUP = 0x76, + OP_NIP = 0x77, + OP_OVER = 0x78, + OP_PICK = 0x79, + OP_ROLL = 0x7a, + OP_ROT = 0x7b, + OP_SWAP = 0x7c, + OP_TUCK = 0x7d, + + // splice ops + OP_CAT = 0x7e, + OP_SUBSTR = 0x7f, + OP_LEFT = 0x80, + OP_RIGHT = 0x81, + OP_SIZE = 0x82, + + // bit logic + OP_INVERT = 0x83, + OP_AND = 0x84, + OP_OR = 0x85, + OP_XOR = 0x86, + OP_EQUAL = 0x87, + OP_EQUALVERIFY = 0x88, + OP_RESERVED1 = 0x89, + OP_RESERVED2 = 0x8a, + + // numeric + OP_1ADD = 0x8b, + OP_1SUB = 0x8c, + OP_2MUL = 0x8d, + OP_2DIV = 0x8e, + OP_NEGATE = 0x8f, + OP_ABS = 0x90, + OP_NOT = 0x91, + OP_0NOTEQUAL = 0x92, + + OP_ADD = 0x93, + OP_SUB = 0x94, + OP_MUL = 0x95, + OP_DIV = 0x96, + OP_MOD = 0x97, + OP_LSHIFT = 0x98, + OP_RSHIFT = 0x99, + + OP_BOOLAND = 0x9a, + OP_BOOLOR = 0x9b, + OP_NUMEQUAL = 0x9c, + OP_NUMEQUALVERIFY = 0x9d, + OP_NUMNOTEQUAL = 0x9e, + OP_LESSTHAN = 0x9f, + OP_GREATERTHAN = 0xa0, + OP_LESSTHANOREQUAL = 0xa1, + OP_GREATERTHANOREQUAL = 0xa2, + OP_MIN = 0xa3, + OP_MAX = 0xa4, + + OP_WITHIN = 0xa5, + + // crypto + OP_RIPEMD160 = 0xa6, + OP_SHA1 = 0xa7, + OP_SHA256 = 0xa8, + OP_HASH160 = 0xa9, + OP_HASH256 = 0xaa, + OP_CODESEPARATOR = 0xab, + OP_CHECKSIG = 0xac, + OP_CHECKSIGVERIFY = 0xad, + OP_CHECKMULTISIG = 0xae, + OP_CHECKMULTISIGVERIFY = 0xaf, + + // expansion + OP_NOP1 = 0xb0, + OP_NOP2 = 0xb1, + OP_NOP3 = 0xb2, + OP_NOP4 = 0xb3, + OP_NOP5 = 0xb4, + OP_NOP6 = 0xb5, + OP_NOP7 = 0xb6, + OP_NOP8 = 0xb7, + OP_NOP9 = 0xb8, + OP_NOP10 = 0xb9, + + + + // template matching params + OP_SMALLINTEGER = 0xfa, + OP_PUBKEYS = 0xfb, + OP_PUBKEYHASH = 0xfd, + OP_PUBKEY = 0xfe, + + OP_INVALIDOPCODE = 0xff, +}; + +const char* GetOpName(opcodetype opcode); + + + +inline std::string ValueString(const std::vector& vch) +{ + if (vch.size() <= 4) + return strprintf("%d", CBigNum(vch).getint()); + else + return HexStr(vch); +} + +inline std::string StackString(const std::vector >& vStack) +{ + std::string str; + BOOST_FOREACH(const std::vector& vch, vStack) + { + if (!str.empty()) + str += " "; + str += ValueString(vch); + } + return str; +} + + + + + + + + +/** Serialized script, used inside transaction inputs and outputs */ +class CScript : public std::vector +{ +protected: + CScript& push_int64(int64 n) + { + if (n == -1 || (n >= 1 && n <= 16)) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return *this; + } + + CScript& push_uint64(uint64 n) + { + if (n >= 1 && n <= 16) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return *this; + } + +public: + CScript() { } + CScript(const CScript& b) : std::vector(b.begin(), b.end()) { } + CScript(const_iterator pbegin, const_iterator pend) : std::vector(pbegin, pend) { } +#ifndef _MSC_VER + CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector(pbegin, pend) { } +#endif + + CScript& operator+=(const CScript& b) + { + insert(end(), b.begin(), b.end()); + return *this; + } + + friend CScript operator+(const CScript& a, const CScript& b) + { + CScript ret = a; + ret += b; + return ret; + } + + + //explicit CScript(char b) is not portable. Use 'signed char' or 'unsigned char'. + explicit CScript(signed char b) { operator<<(b); } + explicit CScript(short b) { operator<<(b); } + explicit CScript(int b) { operator<<(b); } + explicit CScript(long b) { operator<<(b); } + explicit CScript(int64 b) { operator<<(b); } + explicit CScript(unsigned char b) { operator<<(b); } + explicit CScript(unsigned int b) { operator<<(b); } + explicit CScript(unsigned short b) { operator<<(b); } + explicit CScript(unsigned long b) { operator<<(b); } + explicit CScript(uint64 b) { operator<<(b); } + + explicit CScript(opcodetype b) { operator<<(b); } + explicit CScript(const uint256& b) { operator<<(b); } + explicit CScript(const CBigNum& b) { operator<<(b); } + explicit CScript(const std::vector& b) { operator<<(b); } + + + //CScript& operator<<(char b) is not portable. Use 'signed char' or 'unsigned char'. + CScript& operator<<(signed char b) { return push_int64(b); } + CScript& operator<<(short b) { return push_int64(b); } + CScript& operator<<(int b) { return push_int64(b); } + CScript& operator<<(long b) { return push_int64(b); } + CScript& operator<<(int64 b) { return push_int64(b); } + CScript& operator<<(unsigned char b) { return push_uint64(b); } + CScript& operator<<(unsigned int b) { return push_uint64(b); } + CScript& operator<<(unsigned short b) { return push_uint64(b); } + CScript& operator<<(unsigned long b) { return push_uint64(b); } + CScript& operator<<(uint64 b) { return push_uint64(b); } + + CScript& operator<<(opcodetype opcode) + { + if (opcode < 0 || opcode > 0xff) + throw std::runtime_error("CScript::operator<<() : invalid opcode"); + insert(end(), (unsigned char)opcode); + return *this; + } + + CScript& operator<<(const uint160& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return *this; + } + + CScript& operator<<(const uint256& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return *this; + } + + CScript& operator<<(const CPubKey& key) + { + std::vector vchKey = key.Raw(); + return (*this) << vchKey; + } + + CScript& operator<<(const CBigNum& b) + { + *this << b.getvch(); + return *this; + } + + CScript& operator<<(const std::vector& b) + { + if (b.size() < OP_PUSHDATA1) + { + insert(end(), (unsigned char)b.size()); + } + else if (b.size() <= 0xff) + { + insert(end(), OP_PUSHDATA1); + insert(end(), (unsigned char)b.size()); + } + else if (b.size() <= 0xffff) + { + insert(end(), OP_PUSHDATA2); + unsigned short nSize = b.size(); + insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + } + else + { + insert(end(), OP_PUSHDATA4); + unsigned int nSize = b.size(); + insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + } + insert(end(), b.begin(), b.end()); + return *this; + } + + CScript& operator<<(const CScript& b) + { + // I'm not sure if this should push the script or concatenate scripts. + // If there's ever a use for pushing a script onto a script, delete this member fn + assert(!"Warning: Pushing a CScript onto a CScript with << is probably not intended, use + to concatenate!"); + return *this; + } + + + bool GetOp(iterator& pc, opcodetype& opcodeRet, std::vector& vchRet) + { + // Wrapper so it can be called with either iterator or const_iterator + const_iterator pc2 = pc; + bool fRet = GetOp2(pc2, opcodeRet, &vchRet); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(iterator& pc, opcodetype& opcodeRet) + { + const_iterator pc2 = pc; + bool fRet = GetOp2(pc2, opcodeRet, NULL); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet, std::vector& vchRet) const + { + return GetOp2(pc, opcodeRet, &vchRet); + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const + { + return GetOp2(pc, opcodeRet, NULL); + } + + bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, std::vector* pvchRet) const + { + opcodeRet = OP_INVALIDOPCODE; + if (pvchRet) + pvchRet->clear(); + if (pc >= end()) + return false; + + // Read instruction + if (end() - pc < 1) + return false; + unsigned int opcode = *pc++; + + // Immediate operand + if (opcode <= OP_PUSHDATA4) + { + unsigned int nSize; + if (opcode < OP_PUSHDATA1) + { + nSize = opcode; + } + else if (opcode == OP_PUSHDATA1) + { + if (end() - pc < 1) + return false; + nSize = *pc++; + } + else if (opcode == OP_PUSHDATA2) + { + if (end() - pc < 2) + return false; + nSize = 0; + memcpy(&nSize, &pc[0], 2); + pc += 2; + } + else if (opcode == OP_PUSHDATA4) + { + if (end() - pc < 4) + return false; + memcpy(&nSize, &pc[0], 4); + pc += 4; + } + if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize) + return false; + if (pvchRet) + pvchRet->assign(pc, pc + nSize); + pc += nSize; + } + + opcodeRet = (opcodetype)opcode; + return true; + } + + // Encode/decode small integers: + static int DecodeOP_N(opcodetype opcode) + { + if (opcode == OP_0) + return 0; + assert(opcode >= OP_1 && opcode <= OP_16); + return (int)opcode - (int)(OP_1 - 1); + } + static opcodetype EncodeOP_N(int n) + { + assert(n >= 0 && n <= 16); + if (n == 0) + return OP_0; + return (opcodetype)(OP_1+n-1); + } + + int FindAndDelete(const CScript& b) + { + int nFound = 0; + if (b.empty()) + return nFound; + iterator pc = begin(); + opcodetype opcode; + do + { + while (end() - pc >= (long)b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) + { + erase(pc, pc + b.size()); + ++nFound; + } + } + while (GetOp(pc, opcode)); + return nFound; + } + int Find(opcodetype op) const + { + int nFound = 0; + opcodetype opcode; + for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);) + if (opcode == op) + ++nFound; + return nFound; + } + + // Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs + // as 20 sigops. With pay-to-script-hash, that changed: + // CHECKMULTISIGs serialized in scriptSigs are + // counted more accurately, assuming they are of the form + // ... OP_N CHECKMULTISIG ... + unsigned int GetSigOpCount(bool fAccurate) const; + + // Accurately count sigOps, including sigOps in + // pay-to-script-hash transactions: + unsigned int GetSigOpCount(const CScript& scriptSig) const; + + bool IsPayToScriptHash() const; + + // Called by CTransaction::IsStandard + bool IsPushOnly() const + { + const_iterator pc = begin(); + while (pc < end()) + { + opcodetype opcode; + if (!GetOp(pc, opcode)) + return false; + if (opcode > OP_16) + return false; + } + return true; + } + + + void SetDestination(const CTxDestination& address); + void SetMultisig(int nRequired, const std::vector& keys); + + + void PrintHex() const + { + printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str()); + } + + std::string ToString(bool fShort=false) const + { + std::string str; + opcodetype opcode; + std::vector vch; + const_iterator pc = begin(); + while (pc < end()) + { + if (!str.empty()) + str += " "; + if (!GetOp(pc, opcode, vch)) + { + str += "[error]"; + return str; + } + if (0 <= opcode && opcode <= OP_PUSHDATA4) + str += fShort? ValueString(vch).substr(0, 10) : ValueString(vch); + else + str += GetOpName(opcode); + } + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } + + CScriptID GetID() const + { + return CScriptID(Hash160(*this)); + } +}; + + + + + +bool EvalScript(std::vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType); +bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet); +int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions); +bool IsStandard(const CScript& scriptPubKey); +bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); +bool IsMine(const CKeyStore& keystore, const CTxDestination &dest); +bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); +bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector& addressRet, int& nRequiredRet); +bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); +bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType); +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType); + +// Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders, +// combine them intelligently and return the result. +CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); + +#endif diff --git a/src/scrypt-x86.S b/src/scrypt-x86.S new file mode 100644 index 0000000..33b6cd1 --- /dev/null +++ b/src/scrypt-x86.S @@ -0,0 +1,908 @@ +# Copyright 2011 pooler@litecoinpool.org +# 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. + +#if defined(__i386__) + +#define gen_salsa8_core_quadround() \ + movl 52(%esp), %ecx; \ + movl 4(%esp), %edx; \ + movl 20(%esp), %ebx; \ + movl 8(%esp), %esi; \ + leal (%ecx, %edx), %edi; \ + roll $7, %edi; \ + xorl %edi, %ebx; \ + movl %ebx, 4(%esp); \ + movl 36(%esp), %edi; \ + leal (%edx, %ebx), %ebp; \ + roll $9, %ebp; \ + xorl %ebp, %edi; \ + movl 24(%esp), %ebp; \ + movl %edi, 8(%esp); \ + addl %edi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %ecx; \ + movl 40(%esp), %ebx; \ + movl %ecx, 20(%esp); \ + addl %edi, %ecx; \ + roll $18, %ecx; \ + leal (%esi, %ebp), %edi; \ + roll $7, %edi; \ + xorl %edi, %ebx; \ + movl %ebx, 24(%esp); \ + movl 56(%esp), %edi; \ + xorl %ecx, %edx; \ + leal (%ebp, %ebx), %ecx; \ + roll $9, %ecx; \ + xorl %ecx, %edi; \ + movl %edi, 36(%esp); \ + movl 28(%esp), %ecx; \ + movl %edx, 28(%esp); \ + movl 44(%esp), %edx; \ + addl %edi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %esi; \ + movl 60(%esp), %ebx; \ + movl %esi, 40(%esp); \ + addl %edi, %esi; \ + roll $18, %esi; \ + leal (%ecx, %edx), %edi; \ + roll $7, %edi; \ + xorl %edi, %ebx; \ + movl %ebx, 44(%esp); \ + movl 12(%esp), %edi; \ + xorl %esi, %ebp; \ + leal (%edx, %ebx), %esi; \ + roll $9, %esi; \ + xorl %esi, %edi; \ + movl %edi, 12(%esp); \ + movl 48(%esp), %esi; \ + movl %ebp, 48(%esp); \ + movl 64(%esp), %ebp; \ + addl %edi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %ecx; \ + movl 16(%esp), %ebx; \ + movl %ecx, 16(%esp); \ + addl %edi, %ecx; \ + roll $18, %ecx; \ + leal (%esi, %ebp), %edi; \ + roll $7, %edi; \ + xorl %edi, %ebx; \ + movl 32(%esp), %edi; \ + xorl %ecx, %edx; \ + leal (%ebp, %ebx), %ecx; \ + roll $9, %ecx; \ + xorl %ecx, %edi; \ + movl %edi, 32(%esp); \ + movl %ebx, %ecx; \ + movl %edx, 52(%esp); \ + movl 28(%esp), %edx; \ + addl %edi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %esi; \ + movl 40(%esp), %ebx; \ + movl %esi, 28(%esp); \ + addl %edi, %esi; \ + roll $18, %esi; \ + leal (%ecx, %edx), %edi; \ + roll $7, %edi; \ + xorl %edi, %ebx; \ + movl %ebx, 40(%esp); \ + movl 12(%esp), %edi; \ + xorl %esi, %ebp; \ + leal (%edx, %ebx), %esi; \ + roll $9, %esi; \ + xorl %esi, %edi; \ + movl %edi, 12(%esp); \ + movl 4(%esp), %esi; \ + movl %ebp, 4(%esp); \ + movl 48(%esp), %ebp; \ + addl %edi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %ecx; \ + movl 16(%esp), %ebx; \ + movl %ecx, 16(%esp); \ + addl %edi, %ecx; \ + roll $18, %ecx; \ + leal (%esi, %ebp), %edi; \ + roll $7, %edi; \ + xorl %edi, %ebx; \ + movl %ebx, 48(%esp); \ + movl 32(%esp), %edi; \ + xorl %ecx, %edx; \ + leal (%ebp, %ebx), %ecx; \ + roll $9, %ecx; \ + xorl %ecx, %edi; \ + movl %edi, 32(%esp); \ + movl 24(%esp), %ecx; \ + movl %edx, 24(%esp); \ + movl 52(%esp), %edx; \ + addl %edi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %esi; \ + movl 28(%esp), %ebx; \ + movl %esi, 28(%esp); \ + addl %edi, %esi; \ + roll $18, %esi; \ + leal (%ecx, %edx), %edi; \ + roll $7, %edi; \ + xorl %edi, %ebx; \ + movl %ebx, 52(%esp); \ + movl 8(%esp), %edi; \ + xorl %esi, %ebp; \ + leal (%edx, %ebx), %esi; \ + roll $9, %esi; \ + xorl %esi, %edi; \ + movl %edi, 8(%esp); \ + movl 44(%esp), %esi; \ + movl %ebp, 44(%esp); \ + movl 4(%esp), %ebp; \ + addl %edi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %ecx; \ + movl 20(%esp), %ebx; \ + movl %ecx, 4(%esp); \ + addl %edi, %ecx; \ + roll $18, %ecx; \ + leal (%esi, %ebp), %edi; \ + roll $7, %edi; \ + xorl %edi, %ebx; \ + movl 36(%esp), %edi; \ + xorl %ecx, %edx; \ + leal (%ebp, %ebx), %ecx; \ + roll $9, %ecx; \ + xorl %ecx, %edi; \ + movl %edi, 20(%esp); \ + movl %ebx, %ecx; \ + movl %edx, 36(%esp); \ + movl 24(%esp), %edx; \ + addl %edi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %esi; \ + movl 28(%esp), %ebx; \ + movl %esi, 24(%esp); \ + addl %edi, %esi; \ + roll $18, %esi; \ + leal (%ecx, %edx), %edi; \ + roll $7, %edi; \ + xorl %edi, %ebx; \ + movl %ebx, 28(%esp); \ + xorl %esi, %ebp; \ + movl 8(%esp), %esi; \ + leal (%edx, %ebx), %edi; \ + roll $9, %edi; \ + xorl %edi, %esi; \ + movl 40(%esp), %edi; \ + movl %ebp, 8(%esp); \ + movl 44(%esp), %ebp; \ + movl %esi, 40(%esp); \ + addl %esi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %ecx; \ + movl 4(%esp), %ebx; \ + movl %ecx, 44(%esp); \ + addl %esi, %ecx; \ + roll $18, %ecx; \ + leal (%edi, %ebp), %esi; \ + roll $7, %esi; \ + xorl %esi, %ebx; \ + movl %ebx, 4(%esp); \ + movl 20(%esp), %esi; \ + xorl %ecx, %edx; \ + leal (%ebp, %ebx), %ecx; \ + roll $9, %ecx; \ + xorl %ecx, %esi; \ + movl %esi, 56(%esp); \ + movl 48(%esp), %ecx; \ + movl %edx, 20(%esp); \ + movl 36(%esp), %edx; \ + addl %esi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %edi; \ + movl 24(%esp), %ebx; \ + movl %edi, 24(%esp); \ + addl %esi, %edi; \ + roll $18, %edi; \ + leal (%ecx, %edx), %esi; \ + roll $7, %esi; \ + xorl %esi, %ebx; \ + movl %ebx, 60(%esp); \ + movl 12(%esp), %esi; \ + xorl %edi, %ebp; \ + leal (%edx, %ebx), %edi; \ + roll $9, %edi; \ + xorl %edi, %esi; \ + movl %esi, 12(%esp); \ + movl 52(%esp), %edi; \ + movl %ebp, 36(%esp); \ + movl 8(%esp), %ebp; \ + addl %esi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %ecx; \ + movl 16(%esp), %ebx; \ + movl %ecx, 16(%esp); \ + addl %esi, %ecx; \ + roll $18, %ecx; \ + leal (%edi, %ebp), %esi; \ + roll $7, %esi; \ + xorl %esi, %ebx; \ + movl 32(%esp), %esi; \ + xorl %ecx, %edx; \ + leal (%ebp, %ebx), %ecx; \ + roll $9, %ecx; \ + xorl %ecx, %esi; \ + movl %esi, 32(%esp); \ + movl %ebx, %ecx; \ + movl %edx, 48(%esp); \ + movl 20(%esp), %edx; \ + addl %esi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %edi; \ + movl 24(%esp), %ebx; \ + movl %edi, 20(%esp); \ + addl %esi, %edi; \ + roll $18, %edi; \ + leal (%ecx, %edx), %esi; \ + roll $7, %esi; \ + xorl %esi, %ebx; \ + movl %ebx, 8(%esp); \ + movl 12(%esp), %esi; \ + xorl %edi, %ebp; \ + leal (%edx, %ebx), %edi; \ + roll $9, %edi; \ + xorl %edi, %esi; \ + movl %esi, 12(%esp); \ + movl 28(%esp), %edi; \ + movl %ebp, 52(%esp); \ + movl 36(%esp), %ebp; \ + addl %esi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %ecx; \ + movl 16(%esp), %ebx; \ + movl %ecx, 16(%esp); \ + addl %esi, %ecx; \ + roll $18, %ecx; \ + leal (%edi, %ebp), %esi; \ + roll $7, %esi; \ + xorl %esi, %ebx; \ + movl %ebx, 28(%esp); \ + movl 32(%esp), %esi; \ + xorl %ecx, %edx; \ + leal (%ebp, %ebx), %ecx; \ + roll $9, %ecx; \ + xorl %ecx, %esi; \ + movl %esi, 32(%esp); \ + movl 4(%esp), %ecx; \ + movl %edx, 4(%esp); \ + movl 48(%esp), %edx; \ + addl %esi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %edi; \ + movl 20(%esp), %ebx; \ + movl %edi, 20(%esp); \ + addl %esi, %edi; \ + roll $18, %edi; \ + leal (%ecx, %edx), %esi; \ + roll $7, %esi; \ + xorl %esi, %ebx; \ + movl %ebx, 48(%esp); \ + movl 40(%esp), %esi; \ + xorl %edi, %ebp; \ + leal (%edx, %ebx), %edi; \ + roll $9, %edi; \ + xorl %edi, %esi; \ + movl %esi, 36(%esp); \ + movl 60(%esp), %edi; \ + movl %ebp, 24(%esp); \ + movl 52(%esp), %ebp; \ + addl %esi, %ebx; \ + roll $13, %ebx; \ + xorl %ebx, %ecx; \ + movl 44(%esp), %ebx; \ + movl %ecx, 40(%esp); \ + addl %esi, %ecx; \ + roll $18, %ecx; \ + leal (%edi, %ebp), %esi; \ + roll $7, %esi; \ + xorl %esi, %ebx; \ + movl %ebx, 52(%esp); \ + movl 56(%esp), %esi; \ + xorl %ecx, %edx; \ + leal (%ebp, %ebx), %ecx; \ + roll $9, %ecx; \ + xorl %ecx, %esi; \ + movl %esi, 56(%esp); \ + addl %esi, %ebx; \ + movl %edx, 44(%esp); \ + roll $13, %ebx; \ + xorl %ebx, %edi; \ + movl %edi, 60(%esp); \ + addl %esi, %edi; \ + roll $18, %edi; \ + xorl %edi, %ebp; \ + movl %ebp, 64(%esp); \ + + + .text + .align 32 +gen_salsa8_core: + gen_salsa8_core_quadround() + gen_salsa8_core_quadround() + ret + + + .text + .align 32 + .globl scrypt_core + .globl _scrypt_core +scrypt_core: +_scrypt_core: + pushl %ebx + pushl %ebp + pushl %edi + pushl %esi + + # Check for SSE2 availability + movl $1, %eax + cpuid + andl $0x04000000, %edx + jnz xmm_scrypt_core + +gen_scrypt_core: + movl 20(%esp), %edi + movl 24(%esp), %esi + subl $72, %esp + +#define scrypt_core_macro1a(p, q) \ + movl p(%edi), %eax; \ + movl q(%edi), %edx; \ + movl %eax, p(%esi); \ + movl %edx, q(%esi); \ + xorl %edx, %eax; \ + movl %eax, p(%edi); \ + movl %eax, p(%esp); \ + + +#define scrypt_core_macro1b(p, q) \ + movl p(%edi), %eax; \ + xorl p(%esi, %edx), %eax; \ + movl q(%edi), %ebx; \ + xorl q(%esi, %edx), %ebx; \ + movl %ebx, q(%edi); \ + xorl %ebx, %eax; \ + movl %eax, p(%edi); \ + movl %eax, p(%esp); \ + + +#define scrypt_core_macro2(p, q) \ + movl p(%esp), %eax; \ + addl p(%edi), %eax; \ + movl %eax, p(%edi); \ + xorl q(%edi), %eax; \ + movl %eax, q(%edi); \ + movl %eax, p(%esp); \ + + +#define scrypt_core_macro3(p, q) \ + movl p(%esp), %eax; \ + addl q(%edi), %eax; \ + movl %eax, q(%edi); \ + + + leal 131072(%esi), %ecx +gen_scrypt_core_loop1: + movl %esi, 64(%esp) + movl %ecx, 68(%esp) + + scrypt_core_macro1a(0, 64) + scrypt_core_macro1a(4, 68) + scrypt_core_macro1a(8, 72) + scrypt_core_macro1a(12, 76) + scrypt_core_macro1a(16, 80) + scrypt_core_macro1a(20, 84) + scrypt_core_macro1a(24, 88) + scrypt_core_macro1a(28, 92) + scrypt_core_macro1a(32, 96) + scrypt_core_macro1a(36, 100) + scrypt_core_macro1a(40, 104) + scrypt_core_macro1a(44, 108) + scrypt_core_macro1a(48, 112) + scrypt_core_macro1a(52, 116) + scrypt_core_macro1a(56, 120) + scrypt_core_macro1a(60, 124) + + call gen_salsa8_core + + movl 92(%esp), %edi + scrypt_core_macro2(0, 64) + scrypt_core_macro2(4, 68) + scrypt_core_macro2(8, 72) + scrypt_core_macro2(12, 76) + scrypt_core_macro2(16, 80) + scrypt_core_macro2(20, 84) + scrypt_core_macro2(24, 88) + scrypt_core_macro2(28, 92) + scrypt_core_macro2(32, 96) + scrypt_core_macro2(36, 100) + scrypt_core_macro2(40, 104) + scrypt_core_macro2(44, 108) + scrypt_core_macro2(48, 112) + scrypt_core_macro2(52, 116) + scrypt_core_macro2(56, 120) + scrypt_core_macro2(60, 124) + + call gen_salsa8_core + + movl 92(%esp), %edi + scrypt_core_macro3(0, 64) + scrypt_core_macro3(4, 68) + scrypt_core_macro3(8, 72) + scrypt_core_macro3(12, 76) + scrypt_core_macro3(16, 80) + scrypt_core_macro3(20, 84) + scrypt_core_macro3(24, 88) + scrypt_core_macro3(28, 92) + scrypt_core_macro3(32, 96) + scrypt_core_macro3(36, 100) + scrypt_core_macro3(40, 104) + scrypt_core_macro3(44, 108) + scrypt_core_macro3(48, 112) + scrypt_core_macro3(52, 116) + scrypt_core_macro3(56, 120) + scrypt_core_macro3(60, 124) + + movl 64(%esp), %esi + movl 68(%esp), %ecx + addl $128, %esi + cmpl %ecx, %esi + jne gen_scrypt_core_loop1 + + movl 96(%esp), %esi + movl $1024, %ecx +gen_scrypt_core_loop2: + movl %ecx, 68(%esp) + + movl 64(%edi), %edx + andl $1023, %edx + shll $7, %edx + + scrypt_core_macro1b(0, 64) + scrypt_core_macro1b(4, 68) + scrypt_core_macro1b(8, 72) + scrypt_core_macro1b(12, 76) + scrypt_core_macro1b(16, 80) + scrypt_core_macro1b(20, 84) + scrypt_core_macro1b(24, 88) + scrypt_core_macro1b(28, 92) + scrypt_core_macro1b(32, 96) + scrypt_core_macro1b(36, 100) + scrypt_core_macro1b(40, 104) + scrypt_core_macro1b(44, 108) + scrypt_core_macro1b(48, 112) + scrypt_core_macro1b(52, 116) + scrypt_core_macro1b(56, 120) + scrypt_core_macro1b(60, 124) + + call gen_salsa8_core + + movl 92(%esp), %edi + scrypt_core_macro2(0, 64) + scrypt_core_macro2(4, 68) + scrypt_core_macro2(8, 72) + scrypt_core_macro2(12, 76) + scrypt_core_macro2(16, 80) + scrypt_core_macro2(20, 84) + scrypt_core_macro2(24, 88) + scrypt_core_macro2(28, 92) + scrypt_core_macro2(32, 96) + scrypt_core_macro2(36, 100) + scrypt_core_macro2(40, 104) + scrypt_core_macro2(44, 108) + scrypt_core_macro2(48, 112) + scrypt_core_macro2(52, 116) + scrypt_core_macro2(56, 120) + scrypt_core_macro2(60, 124) + + call gen_salsa8_core + + movl 92(%esp), %edi + movl 96(%esp), %esi + scrypt_core_macro3(0, 64) + scrypt_core_macro3(4, 68) + scrypt_core_macro3(8, 72) + scrypt_core_macro3(12, 76) + scrypt_core_macro3(16, 80) + scrypt_core_macro3(20, 84) + scrypt_core_macro3(24, 88) + scrypt_core_macro3(28, 92) + scrypt_core_macro3(32, 96) + scrypt_core_macro3(36, 100) + scrypt_core_macro3(40, 104) + scrypt_core_macro3(44, 108) + scrypt_core_macro3(48, 112) + scrypt_core_macro3(52, 116) + scrypt_core_macro3(56, 120) + scrypt_core_macro3(60, 124) + + movl 68(%esp), %ecx + subl $1, %ecx + ja gen_scrypt_core_loop2 + + addl $72, %esp + popl %esi + popl %edi + popl %ebp + popl %ebx + ret + + +#define xmm_salsa8_core_doubleround() \ + movdqa %xmm1, %xmm4; \ + paddd %xmm0, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $7, %xmm4; \ + psrld $25, %xmm5; \ + pxor %xmm4, %xmm3; \ + pxor %xmm5, %xmm3; \ + movdqa %xmm0, %xmm4; \ + paddd %xmm3, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $9, %xmm4; \ + psrld $23, %xmm5; \ + pxor %xmm4, %xmm2; \ + movdqa %xmm3, %xmm4; \ + pshufd $0x93, %xmm3, %xmm3; \ + pxor %xmm5, %xmm2; \ + paddd %xmm2, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $13, %xmm4; \ + psrld $19, %xmm5; \ + pxor %xmm4, %xmm1; \ + movdqa %xmm2, %xmm4; \ + pshufd $0x4e, %xmm2, %xmm2; \ + pxor %xmm5, %xmm1; \ + paddd %xmm1, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $18, %xmm4; \ + psrld $14, %xmm5; \ + pxor %xmm4, %xmm0; \ + pshufd $0x39, %xmm1, %xmm1; \ + pxor %xmm5, %xmm0; \ + movdqa %xmm3, %xmm4; \ + paddd %xmm0, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $7, %xmm4; \ + psrld $25, %xmm5; \ + pxor %xmm4, %xmm1; \ + pxor %xmm5, %xmm1; \ + movdqa %xmm0, %xmm4; \ + paddd %xmm1, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $9, %xmm4; \ + psrld $23, %xmm5; \ + pxor %xmm4, %xmm2; \ + movdqa %xmm1, %xmm4; \ + pshufd $0x93, %xmm1, %xmm1; \ + pxor %xmm5, %xmm2; \ + paddd %xmm2, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $13, %xmm4; \ + psrld $19, %xmm5; \ + pxor %xmm4, %xmm3; \ + movdqa %xmm2, %xmm4; \ + pshufd $0x4e, %xmm2, %xmm2; \ + pxor %xmm5, %xmm3; \ + paddd %xmm3, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $18, %xmm4; \ + psrld $14, %xmm5; \ + pxor %xmm4, %xmm0; \ + pshufd $0x39, %xmm3, %xmm3; \ + pxor %xmm5, %xmm0; \ + + +#define xmm_salsa8_core() \ + xmm_salsa8_core_doubleround(); \ + xmm_salsa8_core_doubleround(); \ + xmm_salsa8_core_doubleround(); \ + xmm_salsa8_core_doubleround(); \ + + + .align 32 +xmm_scrypt_core: + movl 20(%esp), %edi + movl 24(%esp), %esi + movl %esp, %ebp + subl $128, %esp + andl $-16, %esp + + # shuffle 1st block to (%esp) + movl 60(%edi), %edx + movl 44(%edi), %ecx + movl 28(%edi), %ebx + movl 12(%edi), %eax + movl %edx, 12(%esp) + movl %ecx, 28(%esp) + movl %ebx, 44(%esp) + movl %eax, 60(%esp) + movl 40(%edi), %ecx + movl 24(%edi), %ebx + movl 8(%edi), %eax + movl 56(%edi), %edx + movl %ecx, 8(%esp) + movl %ebx, 24(%esp) + movl %eax, 40(%esp) + movl %edx, 56(%esp) + movl 20(%edi), %ebx + movl 4(%edi), %eax + movl 52(%edi), %edx + movl 36(%edi), %ecx + movl %ebx, 4(%esp) + movl %eax, 20(%esp) + movl %edx, 36(%esp) + movl %ecx, 52(%esp) + movl 0(%edi), %eax + movl 48(%edi), %edx + movl 32(%edi), %ecx + movl 16(%edi), %ebx + movl %eax, 0(%esp) + movl %edx, 16(%esp) + movl %ecx, 32(%esp) + movl %ebx, 48(%esp) + + # shuffle 2nd block to 64(%esp) + movl 124(%edi), %edx + movl 108(%edi), %ecx + movl 92(%edi), %ebx + movl 76(%edi), %eax + movl %edx, 76(%esp) + movl %ecx, 92(%esp) + movl %ebx, 108(%esp) + movl %eax, 124(%esp) + movl 104(%edi), %ecx + movl 88(%edi), %ebx + movl 72(%edi), %eax + movl 120(%edi), %edx + movl %ecx, 72(%esp) + movl %ebx, 88(%esp) + movl %eax, 104(%esp) + movl %edx, 120(%esp) + movl 84(%edi), %ebx + movl 68(%edi), %eax + movl 116(%edi), %edx + movl 100(%edi), %ecx + movl %ebx, 68(%esp) + movl %eax, 84(%esp) + movl %edx, 100(%esp) + movl %ecx, 116(%esp) + movl 64(%edi), %eax + movl 112(%edi), %edx + movl 96(%edi), %ecx + movl 80(%edi), %ebx + movl %eax, 64(%esp) + movl %edx, 80(%esp) + movl %ecx, 96(%esp) + movl %ebx, 112(%esp) + + movl %esi, %edx + leal 131072(%esi), %ecx +xmm_scrypt_core_loop1: + movdqa 0(%esp), %xmm0 + movdqa 16(%esp), %xmm1 + movdqa 32(%esp), %xmm2 + movdqa 48(%esp), %xmm3 + movdqa 64(%esp), %xmm4 + movdqa 80(%esp), %xmm5 + movdqa 96(%esp), %xmm6 + movdqa 112(%esp), %xmm7 + movdqa %xmm0, 0(%edx) + movdqa %xmm1, 16(%edx) + movdqa %xmm2, 32(%edx) + movdqa %xmm3, 48(%edx) + movdqa %xmm4, 64(%edx) + movdqa %xmm5, 80(%edx) + movdqa %xmm6, 96(%edx) + movdqa %xmm7, 112(%edx) + + pxor %xmm4, %xmm0 + pxor %xmm5, %xmm1 + pxor %xmm6, %xmm2 + pxor %xmm7, %xmm3 + movdqa %xmm0, 0(%esp) + movdqa %xmm1, 16(%esp) + movdqa %xmm2, 32(%esp) + movdqa %xmm3, 48(%esp) + xmm_salsa8_core() + paddd 0(%esp), %xmm0 + paddd 16(%esp), %xmm1 + paddd 32(%esp), %xmm2 + paddd 48(%esp), %xmm3 + movdqa %xmm0, 0(%esp) + movdqa %xmm1, 16(%esp) + movdqa %xmm2, 32(%esp) + movdqa %xmm3, 48(%esp) + + pxor 64(%esp), %xmm0 + pxor 80(%esp), %xmm1 + pxor 96(%esp), %xmm2 + pxor 112(%esp), %xmm3 + movdqa %xmm0, 64(%esp) + movdqa %xmm1, 80(%esp) + movdqa %xmm2, 96(%esp) + movdqa %xmm3, 112(%esp) + xmm_salsa8_core() + paddd 64(%esp), %xmm0 + paddd 80(%esp), %xmm1 + paddd 96(%esp), %xmm2 + paddd 112(%esp), %xmm3 + movdqa %xmm0, 64(%esp) + movdqa %xmm1, 80(%esp) + movdqa %xmm2, 96(%esp) + movdqa %xmm3, 112(%esp) + + addl $128, %edx + cmpl %ecx, %edx + jne xmm_scrypt_core_loop1 + + movl $1024, %ecx +xmm_scrypt_core_loop2: + movdqa 0(%esp), %xmm0 + movdqa 16(%esp), %xmm1 + movdqa 32(%esp), %xmm2 + movdqa 48(%esp), %xmm3 + movdqa 64(%esp), %xmm4 + movdqa 80(%esp), %xmm5 + movdqa 96(%esp), %xmm6 + movdqa 112(%esp), %xmm7 + movd %xmm4, %edx + andl $1023, %edx + shll $7, %edx + pxor 0(%esi, %edx), %xmm0 + pxor 16(%esi, %edx), %xmm1 + pxor 32(%esi, %edx), %xmm2 + pxor 48(%esi, %edx), %xmm3 + pxor 64(%esi, %edx), %xmm4 + pxor 80(%esi, %edx), %xmm5 + pxor 96(%esi, %edx), %xmm6 + pxor 112(%esi, %edx), %xmm7 + movdqa %xmm4, 64(%esp) + movdqa %xmm5, 80(%esp) + movdqa %xmm6, 96(%esp) + movdqa %xmm7, 112(%esp) + + pxor %xmm4, %xmm0 + pxor %xmm5, %xmm1 + pxor %xmm6, %xmm2 + pxor %xmm7, %xmm3 + movdqa %xmm0, 0(%esp) + movdqa %xmm1, 16(%esp) + movdqa %xmm2, 32(%esp) + movdqa %xmm3, 48(%esp) + xmm_salsa8_core() + paddd 0(%esp), %xmm0 + paddd 16(%esp), %xmm1 + paddd 32(%esp), %xmm2 + paddd 48(%esp), %xmm3 + movdqa %xmm0, 0(%esp) + movdqa %xmm1, 16(%esp) + movdqa %xmm2, 32(%esp) + movdqa %xmm3, 48(%esp) + + pxor 64(%esp), %xmm0 + pxor 80(%esp), %xmm1 + pxor 96(%esp), %xmm2 + pxor 112(%esp), %xmm3 + movdqa %xmm0, 64(%esp) + movdqa %xmm1, 80(%esp) + movdqa %xmm2, 96(%esp) + movdqa %xmm3, 112(%esp) + xmm_salsa8_core() + paddd 64(%esp), %xmm0 + paddd 80(%esp), %xmm1 + paddd 96(%esp), %xmm2 + paddd 112(%esp), %xmm3 + movdqa %xmm0, 64(%esp) + movdqa %xmm1, 80(%esp) + movdqa %xmm2, 96(%esp) + movdqa %xmm3, 112(%esp) + + subl $1, %ecx + ja xmm_scrypt_core_loop2 + + # re-shuffle 1st block back + movl 60(%esp), %edx + movl 44(%esp), %ecx + movl 28(%esp), %ebx + movl 12(%esp), %eax + movl %edx, 12(%edi) + movl %ecx, 28(%edi) + movl %ebx, 44(%edi) + movl %eax, 60(%edi) + movl 40(%esp), %ecx + movl 24(%esp), %ebx + movl 8(%esp), %eax + movl 56(%esp), %edx + movl %ecx, 8(%edi) + movl %ebx, 24(%edi) + movl %eax, 40(%edi) + movl %edx, 56(%edi) + movl 20(%esp), %ebx + movl 4(%esp), %eax + movl 52(%esp), %edx + movl 36(%esp), %ecx + movl %ebx, 4(%edi) + movl %eax, 20(%edi) + movl %edx, 36(%edi) + movl %ecx, 52(%edi) + movl 0(%esp), %eax + movl 48(%esp), %edx + movl 32(%esp), %ecx + movl 16(%esp), %ebx + movl %eax, 0(%edi) + movl %edx, 16(%edi) + movl %ecx, 32(%edi) + movl %ebx, 48(%edi) + + # re-shuffle 2nd block back + movl 124(%esp), %edx + movl 108(%esp), %ecx + movl 92(%esp), %ebx + movl 76(%esp), %eax + movl %edx, 76(%edi) + movl %ecx, 92(%edi) + movl %ebx, 108(%edi) + movl %eax, 124(%edi) + movl 104(%esp), %ecx + movl 88(%esp), %ebx + movl 72(%esp), %eax + movl 120(%esp), %edx + movl %ecx, 72(%edi) + movl %ebx, 88(%edi) + movl %eax, 104(%edi) + movl %edx, 120(%edi) + movl 84(%esp), %ebx + movl 68(%esp), %eax + movl 116(%esp), %edx + movl 100(%esp), %ecx + movl %ebx, 68(%edi) + movl %eax, 84(%edi) + movl %edx, 100(%edi) + movl %ecx, 116(%edi) + movl 64(%esp), %eax + movl 112(%esp), %edx + movl 96(%esp), %ecx + movl 80(%esp), %ebx + movl %eax, 64(%edi) + movl %edx, 80(%edi) + movl %ecx, 96(%edi) + movl %ebx, 112(%edi) + + movl %ebp, %esp + popl %esi + popl %edi + popl %ebp + popl %ebx + ret + +#endif diff --git a/src/scrypt-x86_64.S b/src/scrypt-x86_64.S new file mode 100644 index 0000000..f0a3fdd --- /dev/null +++ b/src/scrypt-x86_64.S @@ -0,0 +1,1831 @@ +# Copyright 2011-2012 pooler@litecoinpool.org +# 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. + +#if defined(__linux__) && defined(__ELF__) + .section .note.GNU-stack,"",%progbits +#endif + +#if defined(__x86_64__) + +#define scrypt_shuffle(src, so, dest, do) \ + movl so+60(src), %r8d; \ + movl so+44(src), %r9d; \ + movl so+28(src), %r10d; \ + movl so+12(src), %r11d; \ + movl %r8d, do+12(dest); \ + movl %r9d, do+28(dest); \ + movl %r10d, do+44(dest); \ + movl %r11d, do+60(dest); \ + movl so+40(src), %r8d; \ + movl so+8(src), %r9d; \ + movl so+48(src), %r10d; \ + movl so+16(src), %r11d; \ + movl %r8d, do+8(dest); \ + movl %r9d, do+40(dest); \ + movl %r10d, do+16(dest); \ + movl %r11d, do+48(dest); \ + movl so+20(src), %r8d; \ + movl so+4(src), %r9d; \ + movl so+52(src), %r10d; \ + movl so+36(src), %r11d; \ + movl %r8d, do+4(dest); \ + movl %r9d, do+20(dest); \ + movl %r10d, do+36(dest); \ + movl %r11d, do+52(dest); \ + movl so+0(src), %r8d; \ + movl so+24(src), %r9d; \ + movl so+32(src), %r10d; \ + movl so+56(src), %r11d; \ + movl %r8d, do+0(dest); \ + movl %r9d, do+24(dest); \ + movl %r10d, do+32(dest); \ + movl %r11d, do+56(dest); \ + + +#define gen_salsa8_core_doubleround() \ + movq 72(%rsp), %r15; \ + leaq (%r14, %rdx), %rbp; \ + roll $7, %ebp; \ + xorq %rbp, %r9; \ + leaq (%rdi, %r15), %rbp; \ + roll $7, %ebp; \ + xorq %rbp, %r10; \ + leaq (%rdx, %r9), %rbp; \ + roll $9, %ebp; \ + xorq %rbp, %r11; \ + leaq (%r15, %r10), %rbp; \ + roll $9, %ebp; \ + xorq %rbp, %r13; \ + leaq (%r9, %r11), %rbp; \ + roll $13, %ebp; \ + xorq %rbp, %r14; \ + leaq (%r10, %r13), %rbp; \ + roll $13, %ebp; \ + xorq %rbp, %rdi; \ + leaq (%r11, %r14), %rbp; \ + roll $18, %ebp; \ + xorq %rbp, %rdx; \ + leaq (%r13, %rdi), %rbp; \ + roll $18, %ebp; \ + xorq %rbp, %r15; \ + movq 48(%rsp), %rbp; \ + movq %r15, 72(%rsp); \ + leaq (%rax, %rbp), %r15; \ + roll $7, %r15d; \ + xorq %r15, %rbx; \ + leaq (%rbp, %rbx), %r15; \ + roll $9, %r15d; \ + xorq %r15, %rcx; \ + leaq (%rbx, %rcx), %r15; \ + roll $13, %r15d; \ + xorq %r15, %rax; \ + leaq (%rcx, %rax), %r15; \ + roll $18, %r15d; \ + xorq %r15, %rbp; \ + movq 88(%rsp), %r15; \ + movq %rbp, 48(%rsp); \ + leaq (%r12, %r15), %rbp; \ + roll $7, %ebp; \ + xorq %rbp, %rsi; \ + leaq (%r15, %rsi), %rbp; \ + roll $9, %ebp; \ + xorq %rbp, %r8; \ + leaq (%rsi, %r8), %rbp; \ + roll $13, %ebp; \ + xorq %rbp, %r12; \ + leaq (%r8, %r12), %rbp; \ + roll $18, %ebp; \ + xorq %rbp, %r15; \ + movq %r15, 88(%rsp); \ + movq 72(%rsp), %r15; \ + leaq (%rsi, %rdx), %rbp; \ + roll $7, %ebp; \ + xorq %rbp, %rdi; \ + leaq (%r9, %r15), %rbp; \ + roll $7, %ebp; \ + xorq %rbp, %rax; \ + leaq (%rdx, %rdi), %rbp; \ + roll $9, %ebp; \ + xorq %rbp, %rcx; \ + leaq (%r15, %rax), %rbp; \ + roll $9, %ebp; \ + xorq %rbp, %r8; \ + leaq (%rdi, %rcx), %rbp; \ + roll $13, %ebp; \ + xorq %rbp, %rsi; \ + leaq (%rax, %r8), %rbp; \ + roll $13, %ebp; \ + xorq %rbp, %r9; \ + leaq (%rcx, %rsi), %rbp; \ + roll $18, %ebp; \ + xorq %rbp, %rdx; \ + leaq (%r8, %r9), %rbp; \ + roll $18, %ebp; \ + xorq %rbp, %r15; \ + movq 48(%rsp), %rbp; \ + movq %r15, 72(%rsp); \ + leaq (%r10, %rbp), %r15; \ + roll $7, %r15d; \ + xorq %r15, %r12; \ + leaq (%rbp, %r12), %r15; \ + roll $9, %r15d; \ + xorq %r15, %r11; \ + leaq (%r12, %r11), %r15; \ + roll $13, %r15d; \ + xorq %r15, %r10; \ + leaq (%r11, %r10), %r15; \ + roll $18, %r15d; \ + xorq %r15, %rbp; \ + movq 88(%rsp), %r15; \ + movq %rbp, 48(%rsp); \ + leaq (%rbx, %r15), %rbp; \ + roll $7, %ebp; \ + xorq %rbp, %r14; \ + leaq (%r15, %r14), %rbp; \ + roll $9, %ebp; \ + xorq %rbp, %r13; \ + leaq (%r14, %r13), %rbp; \ + roll $13, %ebp; \ + xorq %rbp, %rbx; \ + leaq (%r13, %rbx), %rbp; \ + roll $18, %ebp; \ + xorq %rbp, %r15; \ + movq %r15, 88(%rsp); \ + + + .text + .align 32 +gen_salsa8_core: + # 0: %rdx, %rdi, %rcx, %rsi + movq 8(%rsp), %rdi + movq %rdi, %rdx + shrq $32, %rdi + movq 16(%rsp), %rsi + movq %rsi, %rcx + shrq $32, %rsi + # 1: %r9, 72(%rsp), %rax, %r8 + movq 24(%rsp), %r8 + movq %r8, %r9 + shrq $32, %r8 + movq %r8, 72(%rsp) + movq 32(%rsp), %r8 + movq %r8, %rax + shrq $32, %r8 + # 2: %r11, %r10, 48(%rsp), %r12 + movq 40(%rsp), %r10 + movq %r10, %r11 + shrq $32, %r10 + movq 48(%rsp), %r12 + #movq %r12, %r13 + #movq %r13, 48(%rsp) + shrq $32, %r12 + # 3: %r14, %r13, %rbx, 88(%rsp) + movq 56(%rsp), %r13 + movq %r13, %r14 + shrq $32, %r13 + movq 64(%rsp), %r15 + movq %r15, %rbx + shrq $32, %r15 + movq %r15, 88(%rsp) + + gen_salsa8_core_doubleround() + gen_salsa8_core_doubleround() + gen_salsa8_core_doubleround() + gen_salsa8_core_doubleround() + + movl %edx, %edx + shlq $32, %rdi + addq %rdi, %rdx + movd %rdx, %xmm0 + + movl %ecx, %ecx + shlq $32, %rsi + addq %rsi, %rcx + movd %rcx, %xmm4 + + movq 72(%rsp), %rdi + movl %r9d, %r9d + shlq $32, %rdi + addq %rdi, %r9 + movd %r9, %xmm1 + + movl %eax, %eax + shlq $32, %r8 + addq %r8, %rax + movd %rax, %xmm5 + + movl %r11d, %r11d + shlq $32, %r10 + addq %r10, %r11 + movd %r11, %xmm2 + + movl 48(%rsp), %r8d + shlq $32, %r12 + addq %r12, %r8 + movd %r8, %xmm6 + + movl %r14d, %r14d + shlq $32, %r13 + addq %r13, %r14 + movd %r14, %xmm3 + + movq 88(%rsp), %rdi + movl %ebx, %ebx + shlq $32, %rdi + addq %rdi, %rbx + movd %rbx, %xmm7 + + punpcklqdq %xmm4, %xmm0 + punpcklqdq %xmm5, %xmm1 + punpcklqdq %xmm6, %xmm2 + punpcklqdq %xmm7, %xmm3 + + #movq %rdx, 8(%rsp) + #movq %rcx, 16(%rsp) + #movq %r9, 24(%rsp) + #movq %rax, 32(%rsp) + #movq %r11, 40(%rsp) + #movq %r8, 48(%rsp) + #movq %r14, 56(%rsp) + #movq %rbx, 64(%rsp) + + ret + + + .text + .align 32 + .globl scrypt_core + .globl _scrypt_core +scrypt_core: +_scrypt_core: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 +#if defined(WIN64) + subq $176, %rsp + movdqa %xmm6, 8(%rsp) + movdqa %xmm7, 24(%rsp) + movdqa %xmm8, 40(%rsp) + movdqa %xmm9, 56(%rsp) + movdqa %xmm10, 72(%rsp) + movdqa %xmm11, 88(%rsp) + movdqa %xmm12, 104(%rsp) + movdqa %xmm13, 120(%rsp) + movdqa %xmm14, 136(%rsp) + movdqa %xmm15, 152(%rsp) + pushq %rdi + pushq %rsi + movq %rcx, %rdi + movq %rdx, %rsi +#endif + +#define scrypt_core_cleanup() \ + popq %r15; \ + popq %r14; \ + popq %r13; \ + popq %r12; \ + popq %rbp; \ + popq %rbx; \ + + + # GenuineIntel processors have fast SIMD + xorl %eax, %eax + cpuid + cmpl $0x6c65746e, %ecx + jne gen_scrypt_core + cmpl $0x49656e69, %edx + jne gen_scrypt_core + cmpl $0x756e6547, %ebx + je xmm_scrypt_core + +gen_scrypt_core: + subq $136, %rsp + movdqa 0(%rdi), %xmm8 + movdqa 16(%rdi), %xmm9 + movdqa 32(%rdi), %xmm10 + movdqa 48(%rdi), %xmm11 + movdqa 64(%rdi), %xmm12 + movdqa 80(%rdi), %xmm13 + movdqa 96(%rdi), %xmm14 + movdqa 112(%rdi), %xmm15 + + leaq 131072(%rsi), %rcx + movq %rdi, 104(%rsp) + movq %rsi, 112(%rsp) + movq %rcx, 120(%rsp) +gen_scrypt_core_loop1: + movdqa %xmm8, 0(%rsi) + movdqa %xmm9, 16(%rsi) + movdqa %xmm10, 32(%rsi) + movdqa %xmm11, 48(%rsi) + movdqa %xmm12, 64(%rsi) + movdqa %xmm13, 80(%rsi) + movdqa %xmm14, 96(%rsi) + movdqa %xmm15, 112(%rsi) + + pxor %xmm12, %xmm8 + pxor %xmm13, %xmm9 + pxor %xmm14, %xmm10 + pxor %xmm15, %xmm11 + movdqa %xmm8, 0(%rsp) + movdqa %xmm9, 16(%rsp) + movdqa %xmm10, 32(%rsp) + movdqa %xmm11, 48(%rsp) + movq %rsi, 128(%rsp) + call gen_salsa8_core + paddd %xmm0, %xmm8 + paddd %xmm1, %xmm9 + paddd %xmm2, %xmm10 + paddd %xmm3, %xmm11 + + pxor %xmm8, %xmm12 + pxor %xmm9, %xmm13 + pxor %xmm10, %xmm14 + pxor %xmm11, %xmm15 + movdqa %xmm12, 0(%rsp) + movdqa %xmm13, 16(%rsp) + movdqa %xmm14, 32(%rsp) + movdqa %xmm15, 48(%rsp) + call gen_salsa8_core + movq 128(%rsp), %rsi + paddd %xmm0, %xmm12 + paddd %xmm1, %xmm13 + paddd %xmm2, %xmm14 + paddd %xmm3, %xmm15 + + addq $128, %rsi + movq 120(%rsp), %rcx + cmpq %rcx, %rsi + jne gen_scrypt_core_loop1 + + movq $1024, %rcx +gen_scrypt_core_loop2: + movq 112(%rsp), %rsi + movd %xmm12, %edx + andl $1023, %edx + shll $7, %edx + movdqa 0(%rsi, %rdx), %xmm0 + movdqa 16(%rsi, %rdx), %xmm1 + movdqa 32(%rsi, %rdx), %xmm2 + movdqa 48(%rsi, %rdx), %xmm3 + movdqa 64(%rsi, %rdx), %xmm4 + movdqa 80(%rsi, %rdx), %xmm5 + movdqa 96(%rsi, %rdx), %xmm6 + movdqa 112(%rsi, %rdx), %xmm7 + pxor %xmm0, %xmm8 + pxor %xmm1, %xmm9 + pxor %xmm2, %xmm10 + pxor %xmm3, %xmm11 + pxor %xmm4, %xmm12 + pxor %xmm5, %xmm13 + pxor %xmm6, %xmm14 + pxor %xmm7, %xmm15 + + pxor %xmm12, %xmm8 + pxor %xmm13, %xmm9 + pxor %xmm14, %xmm10 + pxor %xmm15, %xmm11 + movdqa %xmm8, 0(%rsp) + movdqa %xmm9, 16(%rsp) + movdqa %xmm10, 32(%rsp) + movdqa %xmm11, 48(%rsp) + movq %rcx, 128(%rsp) + call gen_salsa8_core + paddd %xmm0, %xmm8 + paddd %xmm1, %xmm9 + paddd %xmm2, %xmm10 + paddd %xmm3, %xmm11 + + pxor %xmm8, %xmm12 + pxor %xmm9, %xmm13 + pxor %xmm10, %xmm14 + pxor %xmm11, %xmm15 + movdqa %xmm12, 0(%rsp) + movdqa %xmm13, 16(%rsp) + movdqa %xmm14, 32(%rsp) + movdqa %xmm15, 48(%rsp) + call gen_salsa8_core + movq 128(%rsp), %rcx + paddd %xmm0, %xmm12 + paddd %xmm1, %xmm13 + paddd %xmm2, %xmm14 + paddd %xmm3, %xmm15 + + subq $1, %rcx + ja gen_scrypt_core_loop2 + + movq 104(%rsp), %rdi + movdqa %xmm8, 0(%rdi) + movdqa %xmm9, 16(%rdi) + movdqa %xmm10, 32(%rdi) + movdqa %xmm11, 48(%rdi) + movdqa %xmm12, 64(%rdi) + movdqa %xmm13, 80(%rdi) + movdqa %xmm14, 96(%rdi) + movdqa %xmm15, 112(%rdi) + + addq $136, %rsp + scrypt_core_cleanup() + ret + + +#define xmm_salsa8_core_doubleround() \ + movdqa %xmm1, %xmm4; \ + paddd %xmm0, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $7, %xmm4; \ + psrld $25, %xmm5; \ + pxor %xmm4, %xmm3; \ + pxor %xmm5, %xmm3; \ + movdqa %xmm0, %xmm4; \ + paddd %xmm3, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $9, %xmm4; \ + psrld $23, %xmm5; \ + pxor %xmm4, %xmm2; \ + movdqa %xmm3, %xmm4; \ + pshufd $0x93, %xmm3, %xmm3; \ + pxor %xmm5, %xmm2; \ + paddd %xmm2, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $13, %xmm4; \ + psrld $19, %xmm5; \ + pxor %xmm4, %xmm1; \ + movdqa %xmm2, %xmm4; \ + pshufd $0x4e, %xmm2, %xmm2; \ + pxor %xmm5, %xmm1; \ + paddd %xmm1, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $18, %xmm4; \ + psrld $14, %xmm5; \ + pxor %xmm4, %xmm0; \ + pshufd $0x39, %xmm1, %xmm1; \ + pxor %xmm5, %xmm0; \ + movdqa %xmm3, %xmm4; \ + paddd %xmm0, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $7, %xmm4; \ + psrld $25, %xmm5; \ + pxor %xmm4, %xmm1; \ + pxor %xmm5, %xmm1; \ + movdqa %xmm0, %xmm4; \ + paddd %xmm1, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $9, %xmm4; \ + psrld $23, %xmm5; \ + pxor %xmm4, %xmm2; \ + movdqa %xmm1, %xmm4; \ + pshufd $0x93, %xmm1, %xmm1; \ + pxor %xmm5, %xmm2; \ + paddd %xmm2, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $13, %xmm4; \ + psrld $19, %xmm5; \ + pxor %xmm4, %xmm3; \ + movdqa %xmm2, %xmm4; \ + pshufd $0x4e, %xmm2, %xmm2; \ + pxor %xmm5, %xmm3; \ + paddd %xmm3, %xmm4; \ + movdqa %xmm4, %xmm5; \ + pslld $18, %xmm4; \ + psrld $14, %xmm5; \ + pxor %xmm4, %xmm0; \ + pshufd $0x39, %xmm3, %xmm3; \ + pxor %xmm5, %xmm0; \ + + +#define xmm_salsa8_core() \ + xmm_salsa8_core_doubleround(); \ + xmm_salsa8_core_doubleround(); \ + xmm_salsa8_core_doubleround(); \ + xmm_salsa8_core_doubleround(); \ + + + .align 32 +xmm_scrypt_core: + # shuffle 1st block into %xmm8-%xmm11 + movl 60(%rdi), %edx + movl 44(%rdi), %ecx + movl 28(%rdi), %ebx + movl 12(%rdi), %eax + movd %edx, %xmm0 + movd %ecx, %xmm1 + movd %ebx, %xmm2 + movd %eax, %xmm3 + movl 40(%rdi), %ecx + movl 24(%rdi), %ebx + movl 8(%rdi), %eax + movl 56(%rdi), %edx + pshufd $0x93, %xmm0, %xmm0 + pshufd $0x93, %xmm1, %xmm1 + pshufd $0x93, %xmm2, %xmm2 + pshufd $0x93, %xmm3, %xmm3 + movd %ecx, %xmm4 + movd %ebx, %xmm5 + movd %eax, %xmm6 + movd %edx, %xmm7 + paddd %xmm4, %xmm0 + paddd %xmm5, %xmm1 + paddd %xmm6, %xmm2 + paddd %xmm7, %xmm3 + movl 20(%rdi), %ebx + movl 4(%rdi), %eax + movl 52(%rdi), %edx + movl 36(%rdi), %ecx + pshufd $0x93, %xmm0, %xmm0 + pshufd $0x93, %xmm1, %xmm1 + pshufd $0x93, %xmm2, %xmm2 + pshufd $0x93, %xmm3, %xmm3 + movd %ebx, %xmm4 + movd %eax, %xmm5 + movd %edx, %xmm6 + movd %ecx, %xmm7 + paddd %xmm4, %xmm0 + paddd %xmm5, %xmm1 + paddd %xmm6, %xmm2 + paddd %xmm7, %xmm3 + movl 0(%rdi), %eax + movl 48(%rdi), %edx + movl 32(%rdi), %ecx + movl 16(%rdi), %ebx + pshufd $0x93, %xmm0, %xmm0 + pshufd $0x93, %xmm1, %xmm1 + pshufd $0x93, %xmm2, %xmm2 + pshufd $0x93, %xmm3, %xmm3 + movd %eax, %xmm8 + movd %edx, %xmm9 + movd %ecx, %xmm10 + movd %ebx, %xmm11 + paddd %xmm0, %xmm8 + paddd %xmm1, %xmm9 + paddd %xmm2, %xmm10 + paddd %xmm3, %xmm11 + + # shuffle 2nd block into %xmm12-%xmm15 + movl 124(%rdi), %edx + movl 108(%rdi), %ecx + movl 92(%rdi), %ebx + movl 76(%rdi), %eax + movd %edx, %xmm0 + movd %ecx, %xmm1 + movd %ebx, %xmm2 + movd %eax, %xmm3 + movl 104(%rdi), %ecx + movl 88(%rdi), %ebx + movl 72(%rdi), %eax + movl 120(%rdi), %edx + pshufd $0x93, %xmm0, %xmm0 + pshufd $0x93, %xmm1, %xmm1 + pshufd $0x93, %xmm2, %xmm2 + pshufd $0x93, %xmm3, %xmm3 + movd %ecx, %xmm4 + movd %ebx, %xmm5 + movd %eax, %xmm6 + movd %edx, %xmm7 + paddd %xmm4, %xmm0 + paddd %xmm5, %xmm1 + paddd %xmm6, %xmm2 + paddd %xmm7, %xmm3 + movl 84(%rdi), %ebx + movl 68(%rdi), %eax + movl 116(%rdi), %edx + movl 100(%rdi), %ecx + pshufd $0x93, %xmm0, %xmm0 + pshufd $0x93, %xmm1, %xmm1 + pshufd $0x93, %xmm2, %xmm2 + pshufd $0x93, %xmm3, %xmm3 + movd %ebx, %xmm4 + movd %eax, %xmm5 + movd %edx, %xmm6 + movd %ecx, %xmm7 + paddd %xmm4, %xmm0 + paddd %xmm5, %xmm1 + paddd %xmm6, %xmm2 + paddd %xmm7, %xmm3 + movl 64(%rdi), %eax + movl 112(%rdi), %edx + movl 96(%rdi), %ecx + movl 80(%rdi), %ebx + pshufd $0x93, %xmm0, %xmm0 + pshufd $0x93, %xmm1, %xmm1 + pshufd $0x93, %xmm2, %xmm2 + pshufd $0x93, %xmm3, %xmm3 + movd %eax, %xmm12 + movd %edx, %xmm13 + movd %ecx, %xmm14 + movd %ebx, %xmm15 + paddd %xmm0, %xmm12 + paddd %xmm1, %xmm13 + paddd %xmm2, %xmm14 + paddd %xmm3, %xmm15 + + movq %rsi, %rdx + leaq 131072(%rsi), %rcx +xmm_scrypt_core_loop1: + movdqa %xmm8, 0(%rdx) + movdqa %xmm9, 16(%rdx) + movdqa %xmm10, 32(%rdx) + movdqa %xmm11, 48(%rdx) + movdqa %xmm12, 64(%rdx) + movdqa %xmm13, 80(%rdx) + movdqa %xmm14, 96(%rdx) + movdqa %xmm15, 112(%rdx) + + pxor %xmm12, %xmm8 + pxor %xmm13, %xmm9 + pxor %xmm14, %xmm10 + pxor %xmm15, %xmm11 + movdqa %xmm8, %xmm0 + movdqa %xmm9, %xmm1 + movdqa %xmm10, %xmm2 + movdqa %xmm11, %xmm3 + xmm_salsa8_core() + paddd %xmm0, %xmm8 + paddd %xmm1, %xmm9 + paddd %xmm2, %xmm10 + paddd %xmm3, %xmm11 + + pxor %xmm8, %xmm12 + pxor %xmm9, %xmm13 + pxor %xmm10, %xmm14 + pxor %xmm11, %xmm15 + movdqa %xmm12, %xmm0 + movdqa %xmm13, %xmm1 + movdqa %xmm14, %xmm2 + movdqa %xmm15, %xmm3 + xmm_salsa8_core() + paddd %xmm0, %xmm12 + paddd %xmm1, %xmm13 + paddd %xmm2, %xmm14 + paddd %xmm3, %xmm15 + + addq $128, %rdx + cmpq %rcx, %rdx + jne xmm_scrypt_core_loop1 + + movq $1024, %rcx +xmm_scrypt_core_loop2: + movd %xmm12, %edx + andl $1023, %edx + shll $7, %edx + movdqa 0(%rsi, %rdx), %xmm0 + movdqa 16(%rsi, %rdx), %xmm1 + movdqa 32(%rsi, %rdx), %xmm2 + movdqa 48(%rsi, %rdx), %xmm3 + movdqa 64(%rsi, %rdx), %xmm4 + movdqa 80(%rsi, %rdx), %xmm5 + movdqa 96(%rsi, %rdx), %xmm6 + movdqa 112(%rsi, %rdx), %xmm7 + pxor %xmm0, %xmm8 + pxor %xmm1, %xmm9 + pxor %xmm2, %xmm10 + pxor %xmm3, %xmm11 + pxor %xmm4, %xmm12 + pxor %xmm5, %xmm13 + pxor %xmm6, %xmm14 + pxor %xmm7, %xmm15 + + pxor %xmm12, %xmm8 + pxor %xmm13, %xmm9 + pxor %xmm14, %xmm10 + pxor %xmm15, %xmm11 + movdqa %xmm8, %xmm0 + movdqa %xmm9, %xmm1 + movdqa %xmm10, %xmm2 + movdqa %xmm11, %xmm3 + xmm_salsa8_core() + paddd %xmm0, %xmm8 + paddd %xmm1, %xmm9 + paddd %xmm2, %xmm10 + paddd %xmm3, %xmm11 + + pxor %xmm8, %xmm12 + pxor %xmm9, %xmm13 + pxor %xmm10, %xmm14 + pxor %xmm11, %xmm15 + movdqa %xmm12, %xmm0 + movdqa %xmm13, %xmm1 + movdqa %xmm14, %xmm2 + movdqa %xmm15, %xmm3 + xmm_salsa8_core() + paddd %xmm0, %xmm12 + paddd %xmm1, %xmm13 + paddd %xmm2, %xmm14 + paddd %xmm3, %xmm15 + + subq $1, %rcx + ja xmm_scrypt_core_loop2 + + # re-shuffle 1st block back + movd %xmm8, %eax + movd %xmm9, %edx + movd %xmm10, %ecx + movd %xmm11, %ebx + pshufd $0x39, %xmm8, %xmm8 + pshufd $0x39, %xmm9, %xmm9 + pshufd $0x39, %xmm10, %xmm10 + pshufd $0x39, %xmm11, %xmm11 + movl %eax, 0(%rdi) + movl %edx, 48(%rdi) + movl %ecx, 32(%rdi) + movl %ebx, 16(%rdi) + movd %xmm8, %ebx + movd %xmm9, %eax + movd %xmm10, %edx + movd %xmm11, %ecx + pshufd $0x39, %xmm8, %xmm8 + pshufd $0x39, %xmm9, %xmm9 + pshufd $0x39, %xmm10, %xmm10 + pshufd $0x39, %xmm11, %xmm11 + movl %ebx, 20(%rdi) + movl %eax, 4(%rdi) + movl %edx, 52(%rdi) + movl %ecx, 36(%rdi) + movd %xmm8, %ecx + movd %xmm9, %ebx + movd %xmm10, %eax + movd %xmm11, %edx + pshufd $0x39, %xmm8, %xmm8 + pshufd $0x39, %xmm9, %xmm9 + pshufd $0x39, %xmm10, %xmm10 + pshufd $0x39, %xmm11, %xmm11 + movl %ecx, 40(%rdi) + movl %ebx, 24(%rdi) + movl %eax, 8(%rdi) + movl %edx, 56(%rdi) + movd %xmm8, %edx + movd %xmm9, %ecx + movd %xmm10, %ebx + movd %xmm11, %eax + movl %edx, 60(%rdi) + movl %ecx, 44(%rdi) + movl %ebx, 28(%rdi) + movl %eax, 12(%rdi) + + # re-shuffle 2nd block back + movd %xmm12, %eax + movd %xmm13, %edx + movd %xmm14, %ecx + movd %xmm15, %ebx + pshufd $0x39, %xmm12, %xmm12 + pshufd $0x39, %xmm13, %xmm13 + pshufd $0x39, %xmm14, %xmm14 + pshufd $0x39, %xmm15, %xmm15 + movl %eax, 64(%rdi) + movl %edx, 112(%rdi) + movl %ecx, 96(%rdi) + movl %ebx, 80(%rdi) + movd %xmm12, %ebx + movd %xmm13, %eax + movd %xmm14, %edx + movd %xmm15, %ecx + pshufd $0x39, %xmm12, %xmm12 + pshufd $0x39, %xmm13, %xmm13 + pshufd $0x39, %xmm14, %xmm14 + pshufd $0x39, %xmm15, %xmm15 + movl %ebx, 84(%rdi) + movl %eax, 68(%rdi) + movl %edx, 116(%rdi) + movl %ecx, 100(%rdi) + movd %xmm12, %ecx + movd %xmm13, %ebx + movd %xmm14, %eax + movd %xmm15, %edx + pshufd $0x39, %xmm12, %xmm12 + pshufd $0x39, %xmm13, %xmm13 + pshufd $0x39, %xmm14, %xmm14 + pshufd $0x39, %xmm15, %xmm15 + movl %ecx, 104(%rdi) + movl %ebx, 88(%rdi) + movl %eax, 72(%rdi) + movl %edx, 120(%rdi) + movd %xmm12, %edx + movd %xmm13, %ecx + movd %xmm14, %ebx + movd %xmm15, %eax + movl %edx, 124(%rdi) + movl %ecx, 108(%rdi) + movl %ebx, 92(%rdi) + movl %eax, 76(%rdi) + + scrypt_core_cleanup() + ret + + + .text + .align 32 + .globl scrypt_best_throughput + .globl _scrypt_best_throughput +scrypt_best_throughput: +_scrypt_best_throughput: + pushq %rbx + xorq %rax, %rax + cpuid + movl $3, %eax + cmpl $0x444d4163, %ecx + jne scrypt_best_throughput_exit + cmpl $0x69746e65, %edx + jne scrypt_best_throughput_exit + cmpl $0x68747541, %ebx + jne scrypt_best_throughput_exit + movl $1, %eax + cpuid + andl $0x0ff00000, %eax + movl $3, %eax + jnz scrypt_best_throughput_exit + movl $1, %eax +scrypt_best_throughput_exit: + popq %rbx + ret + + +#define xmm_salsa8_core_2way_doubleround() \ + movdqa %xmm1, %xmm4; \ + movdqa %xmm9, %xmm6; \ + paddd %xmm0, %xmm4; \ + paddd %xmm8, %xmm6; \ + movdqa %xmm4, %xmm5; \ + movdqa %xmm6, %xmm7; \ + pslld $7, %xmm4; \ + pslld $7, %xmm6; \ + psrld $25, %xmm5; \ + psrld $25, %xmm7; \ + pxor %xmm4, %xmm3; \ + pxor %xmm6, %xmm11; \ + pxor %xmm5, %xmm3; \ + pxor %xmm7, %xmm11; \ + movdqa %xmm0, %xmm4; \ + movdqa %xmm8, %xmm6; \ + paddd %xmm3, %xmm4; \ + paddd %xmm11, %xmm6; \ + movdqa %xmm4, %xmm5; \ + movdqa %xmm6, %xmm7; \ + pslld $9, %xmm4; \ + pslld $9, %xmm6; \ + psrld $23, %xmm5; \ + psrld $23, %xmm7; \ + pxor %xmm4, %xmm2; \ + pxor %xmm6, %xmm10; \ + movdqa %xmm3, %xmm4; \ + movdqa %xmm11, %xmm6; \ + pshufd $0x93, %xmm3, %xmm3; \ + pshufd $0x93, %xmm11, %xmm11; \ + pxor %xmm5, %xmm2; \ + pxor %xmm7, %xmm10; \ + paddd %xmm2, %xmm4; \ + paddd %xmm10, %xmm6; \ + movdqa %xmm4, %xmm5; \ + movdqa %xmm6, %xmm7; \ + pslld $13, %xmm4; \ + pslld $13, %xmm6; \ + psrld $19, %xmm5; \ + psrld $19, %xmm7; \ + pxor %xmm4, %xmm1; \ + pxor %xmm6, %xmm9; \ + movdqa %xmm2, %xmm4; \ + movdqa %xmm10, %xmm6; \ + pshufd $0x4e, %xmm2, %xmm2; \ + pshufd $0x4e, %xmm10, %xmm10; \ + pxor %xmm5, %xmm1; \ + pxor %xmm7, %xmm9; \ + paddd %xmm1, %xmm4; \ + paddd %xmm9, %xmm6; \ + movdqa %xmm4, %xmm5; \ + movdqa %xmm6, %xmm7; \ + pslld $18, %xmm4; \ + pslld $18, %xmm6; \ + psrld $14, %xmm5; \ + psrld $14, %xmm7; \ + pxor %xmm4, %xmm0; \ + pxor %xmm6, %xmm8; \ + pshufd $0x39, %xmm1, %xmm1; \ + pshufd $0x39, %xmm9, %xmm9; \ + pxor %xmm5, %xmm0; \ + pxor %xmm7, %xmm8; \ + movdqa %xmm3, %xmm4; \ + movdqa %xmm11, %xmm6; \ + paddd %xmm0, %xmm4; \ + paddd %xmm8, %xmm6; \ + movdqa %xmm4, %xmm5; \ + movdqa %xmm6, %xmm7; \ + pslld $7, %xmm4; \ + pslld $7, %xmm6; \ + psrld $25, %xmm5; \ + psrld $25, %xmm7; \ + pxor %xmm4, %xmm1; \ + pxor %xmm6, %xmm9; \ + pxor %xmm5, %xmm1; \ + pxor %xmm7, %xmm9; \ + movdqa %xmm0, %xmm4; \ + movdqa %xmm8, %xmm6; \ + paddd %xmm1, %xmm4; \ + paddd %xmm9, %xmm6; \ + movdqa %xmm4, %xmm5; \ + movdqa %xmm6, %xmm7; \ + pslld $9, %xmm4; \ + pslld $9, %xmm6; \ + psrld $23, %xmm5; \ + psrld $23, %xmm7; \ + pxor %xmm4, %xmm2; \ + pxor %xmm6, %xmm10; \ + movdqa %xmm1, %xmm4; \ + movdqa %xmm9, %xmm6; \ + pshufd $0x93, %xmm1, %xmm1; \ + pshufd $0x93, %xmm9, %xmm9; \ + pxor %xmm5, %xmm2; \ + pxor %xmm7, %xmm10; \ + paddd %xmm2, %xmm4; \ + paddd %xmm10, %xmm6; \ + movdqa %xmm4, %xmm5; \ + movdqa %xmm6, %xmm7; \ + pslld $13, %xmm4; \ + pslld $13, %xmm6; \ + psrld $19, %xmm5; \ + psrld $19, %xmm7; \ + pxor %xmm4, %xmm3; \ + pxor %xmm6, %xmm11; \ + movdqa %xmm2, %xmm4; \ + movdqa %xmm10, %xmm6; \ + pshufd $0x4e, %xmm2, %xmm2; \ + pshufd $0x4e, %xmm10, %xmm10; \ + pxor %xmm5, %xmm3; \ + pxor %xmm7, %xmm11; \ + paddd %xmm3, %xmm4; \ + paddd %xmm11, %xmm6; \ + movdqa %xmm4, %xmm5; \ + movdqa %xmm6, %xmm7; \ + pslld $18, %xmm4; \ + pslld $18, %xmm6; \ + psrld $14, %xmm5; \ + psrld $14, %xmm7; \ + pxor %xmm4, %xmm0; \ + pxor %xmm6, %xmm8; \ + pshufd $0x39, %xmm3, %xmm3; \ + pshufd $0x39, %xmm11, %xmm11; \ + pxor %xmm5, %xmm0; \ + pxor %xmm7, %xmm8; \ + + +#define xmm_salsa8_core_2way() \ + xmm_salsa8_core_2way_doubleround(); \ + xmm_salsa8_core_2way_doubleround(); \ + xmm_salsa8_core_2way_doubleround(); \ + xmm_salsa8_core_2way_doubleround(); \ + + + + .text + .align 32 + .globl scrypt_core_2way + .globl _scrypt_core_2way +scrypt_core_2way: +_scrypt_core_2way: + pushq %rbx + pushq %rbp +#if defined(WIN64) + subq $176, %rsp + movdqa %xmm6, 8(%rsp) + movdqa %xmm7, 24(%rsp) + movdqa %xmm8, 40(%rsp) + movdqa %xmm9, 56(%rsp) + movdqa %xmm10, 72(%rsp) + movdqa %xmm11, 88(%rsp) + movdqa %xmm12, 104(%rsp) + movdqa %xmm13, 120(%rsp) + movdqa %xmm14, 136(%rsp) + movdqa %xmm15, 152(%rsp) + pushq %rdi + pushq %rsi + movq %rcx, %rdi + movq %rdx, %rsi + movq %r8, %rdx +#endif + subq $264, %rsp + + scrypt_shuffle(%rdi, 0, %rsp, 0) + scrypt_shuffle(%rdi, 64, %rsp, 64) + scrypt_shuffle(%rsi, 0, %rsp, 128) + scrypt_shuffle(%rsi, 64, %rsp, 192) + + movdqa 192(%rsp), %xmm12 + movdqa 208(%rsp), %xmm13 + movdqa 224(%rsp), %xmm14 + movdqa 240(%rsp), %xmm15 + + movq %rdx, %rbp + leaq 262144(%rdx), %rcx +scrypt_core_2way_loop1: + movdqa 0(%rsp), %xmm0 + movdqa 16(%rsp), %xmm1 + movdqa 32(%rsp), %xmm2 + movdqa 48(%rsp), %xmm3 + movdqa 64(%rsp), %xmm4 + movdqa 80(%rsp), %xmm5 + movdqa 96(%rsp), %xmm6 + movdqa 112(%rsp), %xmm7 + movdqa 128(%rsp), %xmm8 + movdqa 144(%rsp), %xmm9 + movdqa 160(%rsp), %xmm10 + movdqa 176(%rsp), %xmm11 + pxor %xmm4, %xmm0 + pxor %xmm5, %xmm1 + pxor %xmm6, %xmm2 + pxor %xmm7, %xmm3 + movdqa %xmm0, 0(%rbp) + movdqa %xmm1, 16(%rbp) + movdqa %xmm2, 32(%rbp) + movdqa %xmm3, 48(%rbp) + movdqa %xmm4, 64(%rbp) + movdqa %xmm5, 80(%rbp) + movdqa %xmm6, 96(%rbp) + movdqa %xmm7, 112(%rbp) + pxor %xmm12, %xmm8 + pxor %xmm13, %xmm9 + pxor %xmm14, %xmm10 + pxor %xmm15, %xmm11 + movdqa %xmm8, 128(%rbp) + movdqa %xmm9, 144(%rbp) + movdqa %xmm10, 160(%rbp) + movdqa %xmm11, 176(%rbp) + movdqa %xmm12, 192(%rbp) + movdqa %xmm13, 208(%rbp) + movdqa %xmm14, 224(%rbp) + movdqa %xmm15, 240(%rbp) + + xmm_salsa8_core_2way() + paddd 0(%rbp), %xmm0 + paddd 16(%rbp), %xmm1 + paddd 32(%rbp), %xmm2 + paddd 48(%rbp), %xmm3 + paddd 128(%rbp), %xmm8 + paddd 144(%rbp), %xmm9 + paddd 160(%rbp), %xmm10 + paddd 176(%rbp), %xmm11 + movdqa %xmm0, 0(%rsp) + movdqa %xmm1, 16(%rsp) + movdqa %xmm2, 32(%rsp) + movdqa %xmm3, 48(%rsp) + movdqa %xmm8, 128(%rsp) + movdqa %xmm9, 144(%rsp) + movdqa %xmm10, 160(%rsp) + movdqa %xmm11, 176(%rsp) + + pxor 64(%rsp), %xmm0 + pxor 80(%rsp), %xmm1 + pxor 96(%rsp), %xmm2 + pxor 112(%rsp), %xmm3 + pxor %xmm12, %xmm8 + pxor %xmm13, %xmm9 + pxor %xmm14, %xmm10 + pxor %xmm15, %xmm11 + movdqa %xmm0, 64(%rsp) + movdqa %xmm1, 80(%rsp) + movdqa %xmm2, 96(%rsp) + movdqa %xmm3, 112(%rsp) + movdqa %xmm8, %xmm12 + movdqa %xmm9, %xmm13 + movdqa %xmm10, %xmm14 + movdqa %xmm11, %xmm15 + xmm_salsa8_core_2way() + paddd 64(%rsp), %xmm0 + paddd 80(%rsp), %xmm1 + paddd 96(%rsp), %xmm2 + paddd 112(%rsp), %xmm3 + paddd %xmm8, %xmm12 + paddd %xmm9, %xmm13 + paddd %xmm10, %xmm14 + paddd %xmm11, %xmm15 + movdqa %xmm0, 64(%rsp) + movdqa %xmm1, 80(%rsp) + movdqa %xmm2, 96(%rsp) + movdqa %xmm3, 112(%rsp) + + addq $256, %rbp + cmpq %rcx, %rbp + jne scrypt_core_2way_loop1 + + movq $1024, %rcx +scrypt_core_2way_loop2: + movdqa 0(%rsp), %xmm0 + movdqa 16(%rsp), %xmm1 + movdqa 32(%rsp), %xmm2 + movdqa 48(%rsp), %xmm3 + movdqa 64(%rsp), %xmm4 + movdqa 80(%rsp), %xmm5 + movdqa 96(%rsp), %xmm6 + movdqa 112(%rsp), %xmm7 + movdqa 128(%rsp), %xmm8 + movdqa 144(%rsp), %xmm9 + movdqa 160(%rsp), %xmm10 + movdqa 176(%rsp), %xmm11 + movd %xmm4, %ebp + andl $1023, %ebp + shll $8, %ebp + pxor 0(%rdx, %rbp), %xmm0 + pxor 16(%rdx, %rbp), %xmm1 + pxor 32(%rdx, %rbp), %xmm2 + pxor 48(%rdx, %rbp), %xmm3 + movd %xmm12, %ebx + andl $1023, %ebx + shll $8, %ebx + addl $128, %ebx + pxor 0(%rdx, %rbx), %xmm8 + pxor 16(%rdx, %rbx), %xmm9 + pxor 32(%rdx, %rbx), %xmm10 + pxor 48(%rdx, %rbx), %xmm11 + + pxor %xmm4, %xmm0 + pxor %xmm5, %xmm1 + pxor %xmm6, %xmm2 + pxor %xmm7, %xmm3 + pxor %xmm12, %xmm8 + pxor %xmm13, %xmm9 + pxor %xmm14, %xmm10 + pxor %xmm15, %xmm11 + movdqa %xmm0, 0(%rsp) + movdqa %xmm1, 16(%rsp) + movdqa %xmm2, 32(%rsp) + movdqa %xmm3, 48(%rsp) + movdqa %xmm8, 128(%rsp) + movdqa %xmm9, 144(%rsp) + movdqa %xmm10, 160(%rsp) + movdqa %xmm11, 176(%rsp) + xmm_salsa8_core_2way() + paddd 0(%rsp), %xmm0 + paddd 16(%rsp), %xmm1 + paddd 32(%rsp), %xmm2 + paddd 48(%rsp), %xmm3 + paddd 128(%rsp), %xmm8 + paddd 144(%rsp), %xmm9 + paddd 160(%rsp), %xmm10 + paddd 176(%rsp), %xmm11 + movdqa %xmm0, 0(%rsp) + movdqa %xmm1, 16(%rsp) + movdqa %xmm2, 32(%rsp) + movdqa %xmm3, 48(%rsp) + movdqa %xmm8, 128(%rsp) + movdqa %xmm9, 144(%rsp) + movdqa %xmm10, 160(%rsp) + movdqa %xmm11, 176(%rsp) + + pxor 64(%rdx, %rbp), %xmm0 + pxor 80(%rdx, %rbp), %xmm1 + pxor 96(%rdx, %rbp), %xmm2 + pxor 112(%rdx, %rbp), %xmm3 + pxor 64(%rdx, %rbx), %xmm8 + pxor 80(%rdx, %rbx), %xmm9 + pxor 96(%rdx, %rbx), %xmm10 + pxor 112(%rdx, %rbx), %xmm11 + pxor 64(%rsp), %xmm0 + pxor 80(%rsp), %xmm1 + pxor 96(%rsp), %xmm2 + pxor 112(%rsp), %xmm3 + pxor %xmm12, %xmm8 + pxor %xmm13, %xmm9 + pxor %xmm14, %xmm10 + pxor %xmm15, %xmm11 + movdqa %xmm0, 64(%rsp) + movdqa %xmm1, 80(%rsp) + movdqa %xmm2, 96(%rsp) + movdqa %xmm3, 112(%rsp) + movdqa %xmm8, %xmm12 + movdqa %xmm9, %xmm13 + movdqa %xmm10, %xmm14 + movdqa %xmm11, %xmm15 + xmm_salsa8_core_2way() + paddd 64(%rsp), %xmm0 + paddd 80(%rsp), %xmm1 + paddd 96(%rsp), %xmm2 + paddd 112(%rsp), %xmm3 + paddd %xmm8, %xmm12 + paddd %xmm9, %xmm13 + paddd %xmm10, %xmm14 + paddd %xmm11, %xmm15 + movdqa %xmm0, 64(%rsp) + movdqa %xmm1, 80(%rsp) + movdqa %xmm2, 96(%rsp) + movdqa %xmm3, 112(%rsp) + + subq $1, %rcx + ja scrypt_core_2way_loop2 + + movdqa %xmm12, 192(%rsp) + movdqa %xmm13, 208(%rsp) + movdqa %xmm14, 224(%rsp) + movdqa %xmm15, 240(%rsp) + + scrypt_shuffle(%rsp, 0, %rdi, 0) + scrypt_shuffle(%rsp, 64, %rdi, 64) + scrypt_shuffle(%rsp, 128, %rsi, 0) + scrypt_shuffle(%rsp, 192, %rsi, 64) + + addq $264, %rsp +#if defined(WIN64) + popq %rsi + popq %rdi + movdqa 8(%rsp), %xmm6 + movdqa 24(%rsp), %xmm7 + movdqa 40(%rsp), %xmm8 + movdqa 56(%rsp), %xmm9 + movdqa 72(%rsp), %xmm10 + movdqa 88(%rsp), %xmm11 + movdqa 104(%rsp), %xmm12 + movdqa 120(%rsp), %xmm13 + movdqa 136(%rsp), %xmm14 + movdqa 152(%rsp), %xmm15 + addq $176, %rsp +#endif + popq %rbp + popq %rbx + ret + + +#define xmm_salsa8_core_3way_doubleround() \ + movdqa %xmm1, %xmm4; \ + movdqa %xmm9, %xmm6; \ + movdqa %xmm13, %xmm7; \ + paddd %xmm0, %xmm4; \ + paddd %xmm8, %xmm6; \ + paddd %xmm12, %xmm7; \ + movdqa %xmm4, %xmm5; \ + pslld $7, %xmm4; \ + psrld $25, %xmm5; \ + pxor %xmm4, %xmm3; \ + pxor %xmm5, %xmm3; \ + movdqa %xmm0, %xmm4; \ + movdqa %xmm6, %xmm5; \ + pslld $7, %xmm6; \ + psrld $25, %xmm5; \ + pxor %xmm6, %xmm11; \ + pxor %xmm5, %xmm11; \ + movdqa %xmm8, %xmm6; \ + movdqa %xmm7, %xmm5; \ + pslld $7, %xmm7; \ + psrld $25, %xmm5; \ + pxor %xmm7, %xmm15; \ + pxor %xmm5, %xmm15; \ + movdqa %xmm12, %xmm7; \ + paddd %xmm3, %xmm4; \ + paddd %xmm11, %xmm6; \ + paddd %xmm15, %xmm7; \ + movdqa %xmm4, %xmm5; \ + pslld $9, %xmm4; \ + psrld $23, %xmm5; \ + pxor %xmm4, %xmm2; \ + movdqa %xmm3, %xmm4; \ + pshufd $0x93, %xmm3, %xmm3; \ + pxor %xmm5, %xmm2; \ + movdqa %xmm6, %xmm5; \ + pslld $9, %xmm6; \ + psrld $23, %xmm5; \ + pxor %xmm6, %xmm10; \ + movdqa %xmm11, %xmm6; \ + pshufd $0x93, %xmm11, %xmm11; \ + pxor %xmm5, %xmm10; \ + movdqa %xmm7, %xmm5; \ + pslld $9, %xmm7; \ + psrld $23, %xmm5; \ + pxor %xmm7, %xmm14; \ + movdqa %xmm15, %xmm7; \ + pshufd $0x93, %xmm15, %xmm15; \ + pxor %xmm5, %xmm14; \ + paddd %xmm2, %xmm4; \ + paddd %xmm10, %xmm6; \ + paddd %xmm14, %xmm7; \ + movdqa %xmm4, %xmm5; \ + pslld $13, %xmm4; \ + psrld $19, %xmm5; \ + pxor %xmm4, %xmm1; \ + movdqa %xmm2, %xmm4; \ + pshufd $0x4e, %xmm2, %xmm2; \ + pxor %xmm5, %xmm1; \ + movdqa %xmm6, %xmm5; \ + pslld $13, %xmm6; \ + psrld $19, %xmm5; \ + pxor %xmm6, %xmm9; \ + movdqa %xmm10, %xmm6; \ + pshufd $0x4e, %xmm10, %xmm10; \ + pxor %xmm5, %xmm9; \ + movdqa %xmm7, %xmm5; \ + pslld $13, %xmm7; \ + psrld $19, %xmm5; \ + pxor %xmm7, %xmm13; \ + movdqa %xmm14, %xmm7; \ + pshufd $0x4e, %xmm14, %xmm14; \ + pxor %xmm5, %xmm13; \ + paddd %xmm1, %xmm4; \ + paddd %xmm9, %xmm6; \ + paddd %xmm13, %xmm7; \ + movdqa %xmm4, %xmm5; \ + pslld $18, %xmm4; \ + psrld $14, %xmm5; \ + pxor %xmm4, %xmm0; \ + pshufd $0x39, %xmm1, %xmm1; \ + pxor %xmm5, %xmm0; \ + movdqa %xmm3, %xmm4; \ + movdqa %xmm6, %xmm5; \ + pslld $18, %xmm6; \ + psrld $14, %xmm5; \ + pxor %xmm6, %xmm8; \ + pshufd $0x39, %xmm9, %xmm9; \ + pxor %xmm5, %xmm8; \ + movdqa %xmm11, %xmm6; \ + movdqa %xmm7, %xmm5; \ + pslld $18, %xmm7; \ + psrld $14, %xmm5; \ + pxor %xmm7, %xmm12; \ + pshufd $0x39, %xmm13, %xmm13; \ + pxor %xmm5, %xmm12; \ + movdqa %xmm15, %xmm7; \ + paddd %xmm0, %xmm4; \ + paddd %xmm8, %xmm6; \ + paddd %xmm12, %xmm7; \ + movdqa %xmm4, %xmm5; \ + pslld $7, %xmm4; \ + psrld $25, %xmm5; \ + pxor %xmm4, %xmm1; \ + pxor %xmm5, %xmm1; \ + movdqa %xmm0, %xmm4; \ + movdqa %xmm6, %xmm5; \ + pslld $7, %xmm6; \ + psrld $25, %xmm5; \ + pxor %xmm6, %xmm9; \ + pxor %xmm5, %xmm9; \ + movdqa %xmm8, %xmm6; \ + movdqa %xmm7, %xmm5; \ + pslld $7, %xmm7; \ + psrld $25, %xmm5; \ + pxor %xmm7, %xmm13; \ + pxor %xmm5, %xmm13; \ + movdqa %xmm12, %xmm7; \ + paddd %xmm1, %xmm4; \ + paddd %xmm9, %xmm6; \ + paddd %xmm13, %xmm7; \ + movdqa %xmm4, %xmm5; \ + pslld $9, %xmm4; \ + psrld $23, %xmm5; \ + pxor %xmm4, %xmm2; \ + movdqa %xmm1, %xmm4; \ + pshufd $0x93, %xmm1, %xmm1; \ + pxor %xmm5, %xmm2; \ + movdqa %xmm6, %xmm5; \ + pslld $9, %xmm6; \ + psrld $23, %xmm5; \ + pxor %xmm6, %xmm10; \ + movdqa %xmm9, %xmm6; \ + pshufd $0x93, %xmm9, %xmm9; \ + pxor %xmm5, %xmm10; \ + movdqa %xmm7, %xmm5; \ + pslld $9, %xmm7; \ + psrld $23, %xmm5; \ + pxor %xmm7, %xmm14; \ + movdqa %xmm13, %xmm7; \ + pshufd $0x93, %xmm13, %xmm13; \ + pxor %xmm5, %xmm14; \ + paddd %xmm2, %xmm4; \ + paddd %xmm10, %xmm6; \ + paddd %xmm14, %xmm7; \ + movdqa %xmm4, %xmm5; \ + pslld $13, %xmm4; \ + psrld $19, %xmm5; \ + pxor %xmm4, %xmm3; \ + movdqa %xmm2, %xmm4; \ + pshufd $0x4e, %xmm2, %xmm2; \ + pxor %xmm5, %xmm3; \ + movdqa %xmm6, %xmm5; \ + pslld $13, %xmm6; \ + psrld $19, %xmm5; \ + pxor %xmm6, %xmm11; \ + movdqa %xmm10, %xmm6; \ + pshufd $0x4e, %xmm10, %xmm10; \ + pxor %xmm5, %xmm11; \ + movdqa %xmm7, %xmm5; \ + pslld $13, %xmm7; \ + psrld $19, %xmm5; \ + pxor %xmm7, %xmm15; \ + movdqa %xmm14, %xmm7; \ + pshufd $0x4e, %xmm14, %xmm14; \ + pxor %xmm5, %xmm15; \ + paddd %xmm3, %xmm4; \ + paddd %xmm11, %xmm6; \ + paddd %xmm15, %xmm7; \ + movdqa %xmm4, %xmm5; \ + pslld $18, %xmm4; \ + psrld $14, %xmm5; \ + pxor %xmm4, %xmm0; \ + pshufd $0x39, %xmm3, %xmm3; \ + pxor %xmm5, %xmm0; \ + movdqa %xmm6, %xmm5; \ + pslld $18, %xmm6; \ + psrld $14, %xmm5; \ + pxor %xmm6, %xmm8; \ + pshufd $0x39, %xmm11, %xmm11; \ + pxor %xmm5, %xmm8; \ + movdqa %xmm7, %xmm5; \ + pslld $18, %xmm7; \ + psrld $14, %xmm5; \ + pxor %xmm7, %xmm12; \ + pshufd $0x39, %xmm15, %xmm15; \ + pxor %xmm5, %xmm12; \ + + +#define xmm_salsa8_core_3way() \ + xmm_salsa8_core_3way_doubleround(); \ + xmm_salsa8_core_3way_doubleround(); \ + xmm_salsa8_core_3way_doubleround(); \ + xmm_salsa8_core_3way_doubleround(); \ + + + .text + .align 32 + .globl scrypt_core_3way + .globl _scrypt_core_3way +scrypt_core_3way: +_scrypt_core_3way: + pushq %rbx + pushq %rbp +#if defined(WIN64) + subq $176, %rsp + movdqa %xmm6, 8(%rsp) + movdqa %xmm7, 24(%rsp) + movdqa %xmm8, 40(%rsp) + movdqa %xmm9, 56(%rsp) + movdqa %xmm10, 72(%rsp) + movdqa %xmm11, 88(%rsp) + movdqa %xmm12, 104(%rsp) + movdqa %xmm13, 120(%rsp) + movdqa %xmm14, 136(%rsp) + movdqa %xmm15, 152(%rsp) + pushq %rdi + pushq %rsi + movq %rcx, %rdi + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx +#endif + subq $392, %rsp + + scrypt_shuffle(%rdi, 0, %rsp, 0) + scrypt_shuffle(%rdi, 64, %rsp, 64) + scrypt_shuffle(%rsi, 0, %rsp, 128) + scrypt_shuffle(%rsi, 64, %rsp, 192) + scrypt_shuffle(%rdx, 0, %rsp, 256) + scrypt_shuffle(%rdx, 64, %rsp, 320) + + movdqa 128+64(%rsp), %xmm8 + movdqa 128+80(%rsp), %xmm9 + movdqa 128+96(%rsp), %xmm10 + movdqa 128+112(%rsp), %xmm11 + + movq %rcx, %rbp + leaq 3*131072(%rcx), %rax +scrypt_core_3way_loop1: + movdqa %xmm8, %xmm12 + movdqa %xmm9, %xmm13 + movdqa %xmm10, %xmm14 + movdqa %xmm11, %xmm15 + movdqa 0(%rsp), %xmm0 + movdqa 16(%rsp), %xmm1 + movdqa 32(%rsp), %xmm2 + movdqa 48(%rsp), %xmm3 + movdqa 64(%rsp), %xmm4 + movdqa 80(%rsp), %xmm5 + movdqa 96(%rsp), %xmm6 + movdqa 112(%rsp), %xmm7 + movdqa 128+0(%rsp), %xmm8 + movdqa 128+16(%rsp), %xmm9 + movdqa 128+32(%rsp), %xmm10 + movdqa 128+48(%rsp), %xmm11 + pxor %xmm4, %xmm0 + pxor %xmm5, %xmm1 + pxor %xmm6, %xmm2 + pxor %xmm7, %xmm3 + movdqa %xmm0, 0(%rbp) + movdqa %xmm1, 16(%rbp) + movdqa %xmm2, 32(%rbp) + movdqa %xmm3, 48(%rbp) + movdqa %xmm4, 64(%rbp) + movdqa %xmm5, 80(%rbp) + movdqa %xmm6, 96(%rbp) + movdqa %xmm7, 112(%rbp) + pxor %xmm12, %xmm8 + pxor %xmm13, %xmm9 + pxor %xmm14, %xmm10 + pxor %xmm15, %xmm11 + movdqa %xmm8, 128+0(%rbp) + movdqa %xmm9, 128+16(%rbp) + movdqa %xmm10, 128+32(%rbp) + movdqa %xmm11, 128+48(%rbp) + movdqa %xmm12, 128+64(%rbp) + movdqa %xmm13, 128+80(%rbp) + movdqa %xmm14, 128+96(%rbp) + movdqa %xmm15, 128+112(%rbp) + movdqa 256+0(%rsp), %xmm12 + movdqa 256+16(%rsp), %xmm13 + movdqa 256+32(%rsp), %xmm14 + movdqa 256+48(%rsp), %xmm15 + movdqa 256+64(%rsp), %xmm4 + movdqa 256+80(%rsp), %xmm5 + movdqa 256+96(%rsp), %xmm6 + movdqa 256+112(%rsp), %xmm7 + pxor %xmm4, %xmm12 + pxor %xmm5, %xmm13 + pxor %xmm6, %xmm14 + pxor %xmm7, %xmm15 + movdqa %xmm12, 256+0(%rbp) + movdqa %xmm13, 256+16(%rbp) + movdqa %xmm14, 256+32(%rbp) + movdqa %xmm15, 256+48(%rbp) + movdqa %xmm4, 256+64(%rbp) + movdqa %xmm5, 256+80(%rbp) + movdqa %xmm6, 256+96(%rbp) + movdqa %xmm7, 256+112(%rbp) + + xmm_salsa8_core_3way() + paddd 0(%rbp), %xmm0 + paddd 16(%rbp), %xmm1 + paddd 32(%rbp), %xmm2 + paddd 48(%rbp), %xmm3 + paddd 128+0(%rbp), %xmm8 + paddd 128+16(%rbp), %xmm9 + paddd 128+32(%rbp), %xmm10 + paddd 128+48(%rbp), %xmm11 + paddd 256+0(%rbp), %xmm12 + paddd 256+16(%rbp), %xmm13 + paddd 256+32(%rbp), %xmm14 + paddd 256+48(%rbp), %xmm15 + movdqa %xmm0, 0(%rsp) + movdqa %xmm1, 16(%rsp) + movdqa %xmm2, 32(%rsp) + movdqa %xmm3, 48(%rsp) + movdqa %xmm8, 128+0(%rsp) + movdqa %xmm9, 128+16(%rsp) + movdqa %xmm10, 128+32(%rsp) + movdqa %xmm11, 128+48(%rsp) + movdqa %xmm12, 256+0(%rsp) + movdqa %xmm13, 256+16(%rsp) + movdqa %xmm14, 256+32(%rsp) + movdqa %xmm15, 256+48(%rsp) + + pxor 64(%rsp), %xmm0 + pxor 80(%rsp), %xmm1 + pxor 96(%rsp), %xmm2 + pxor 112(%rsp), %xmm3 + pxor 128+64(%rsp), %xmm8 + pxor 128+80(%rsp), %xmm9 + pxor 128+96(%rsp), %xmm10 + pxor 128+112(%rsp), %xmm11 + pxor 256+64(%rsp), %xmm12 + pxor 256+80(%rsp), %xmm13 + pxor 256+96(%rsp), %xmm14 + pxor 256+112(%rsp), %xmm15 + movdqa %xmm0, 64(%rsp) + movdqa %xmm1, 80(%rsp) + movdqa %xmm2, 96(%rsp) + movdqa %xmm3, 112(%rsp) + movdqa %xmm8, 128+64(%rsp) + movdqa %xmm9, 128+80(%rsp) + movdqa %xmm10, 128+96(%rsp) + movdqa %xmm11, 128+112(%rsp) + movdqa %xmm12, 256+64(%rsp) + movdqa %xmm13, 256+80(%rsp) + movdqa %xmm14, 256+96(%rsp) + movdqa %xmm15, 256+112(%rsp) + xmm_salsa8_core_3way() + paddd 64(%rsp), %xmm0 + paddd 80(%rsp), %xmm1 + paddd 96(%rsp), %xmm2 + paddd 112(%rsp), %xmm3 + paddd 128+64(%rsp), %xmm8 + paddd 128+80(%rsp), %xmm9 + paddd 128+96(%rsp), %xmm10 + paddd 128+112(%rsp), %xmm11 + paddd 256+64(%rsp), %xmm12 + paddd 256+80(%rsp), %xmm13 + paddd 256+96(%rsp), %xmm14 + paddd 256+112(%rsp), %xmm15 + movdqa %xmm0, 64(%rsp) + movdqa %xmm1, 80(%rsp) + movdqa %xmm2, 96(%rsp) + movdqa %xmm3, 112(%rsp) + movdqa %xmm8, 128+64(%rsp) + movdqa %xmm9, 128+80(%rsp) + movdqa %xmm10, 128+96(%rsp) + movdqa %xmm11, 128+112(%rsp) + movdqa %xmm12, 256+64(%rsp) + movdqa %xmm13, 256+80(%rsp) + movdqa %xmm14, 256+96(%rsp) + movdqa %xmm15, 256+112(%rsp) + + addq $3*128, %rbp + cmpq %rax, %rbp + jne scrypt_core_3way_loop1 + + movq $1024, %rax +scrypt_core_3way_loop2: + movl 64(%rsp), %ebp + andl $1023, %ebp + leal (%ebp, %ebp, 2), %ebp + shll $7, %ebp + movl 128+64(%rsp), %ebx + andl $1023, %ebx + leal (%ebx, %ebx, 2), %ebx + shll $7, %ebx + addl $128, %ebx + movl 256+64(%rsp), %r8d + andl $1023, %r8d + leal (%r8d, %r8d, 2), %r8d + shll $7, %r8d + addl $256, %r8d + movdqa 0(%rsp), %xmm0 + movdqa 16(%rsp), %xmm1 + movdqa 32(%rsp), %xmm2 + movdqa 48(%rsp), %xmm3 + movdqa 128+0(%rsp), %xmm8 + movdqa 128+16(%rsp), %xmm9 + movdqa 128+32(%rsp), %xmm10 + movdqa 128+48(%rsp), %xmm11 + movdqa 256+0(%rsp), %xmm12 + movdqa 256+16(%rsp), %xmm13 + movdqa 256+32(%rsp), %xmm14 + movdqa 256+48(%rsp), %xmm15 + pxor 0(%rcx, %rbp), %xmm0 + pxor 16(%rcx, %rbp), %xmm1 + pxor 32(%rcx, %rbp), %xmm2 + pxor 48(%rcx, %rbp), %xmm3 + pxor 0(%rcx, %rbx), %xmm8 + pxor 16(%rcx, %rbx), %xmm9 + pxor 32(%rcx, %rbx), %xmm10 + pxor 48(%rcx, %rbx), %xmm11 + pxor 0(%rcx, %r8), %xmm12 + pxor 16(%rcx, %r8), %xmm13 + pxor 32(%rcx, %r8), %xmm14 + pxor 48(%rcx, %r8), %xmm15 + + pxor 64(%rsp), %xmm0 + pxor 80(%rsp), %xmm1 + pxor 96(%rsp), %xmm2 + pxor 112(%rsp), %xmm3 + pxor 128+64(%rsp), %xmm8 + pxor 128+80(%rsp), %xmm9 + pxor 128+96(%rsp), %xmm10 + pxor 128+112(%rsp), %xmm11 + pxor 256+64(%rsp), %xmm12 + pxor 256+80(%rsp), %xmm13 + pxor 256+96(%rsp), %xmm14 + pxor 256+112(%rsp), %xmm15 + movdqa %xmm0, 0(%rsp) + movdqa %xmm1, 16(%rsp) + movdqa %xmm2, 32(%rsp) + movdqa %xmm3, 48(%rsp) + movdqa %xmm8, 128+0(%rsp) + movdqa %xmm9, 128+16(%rsp) + movdqa %xmm10, 128+32(%rsp) + movdqa %xmm11, 128+48(%rsp) + movdqa %xmm12, 256+0(%rsp) + movdqa %xmm13, 256+16(%rsp) + movdqa %xmm14, 256+32(%rsp) + movdqa %xmm15, 256+48(%rsp) + xmm_salsa8_core_3way() + paddd 0(%rsp), %xmm0 + paddd 16(%rsp), %xmm1 + paddd 32(%rsp), %xmm2 + paddd 48(%rsp), %xmm3 + paddd 128+0(%rsp), %xmm8 + paddd 128+16(%rsp), %xmm9 + paddd 128+32(%rsp), %xmm10 + paddd 128+48(%rsp), %xmm11 + paddd 256+0(%rsp), %xmm12 + paddd 256+16(%rsp), %xmm13 + paddd 256+32(%rsp), %xmm14 + paddd 256+48(%rsp), %xmm15 + movdqa %xmm0, 0(%rsp) + movdqa %xmm1, 16(%rsp) + movdqa %xmm2, 32(%rsp) + movdqa %xmm3, 48(%rsp) + movdqa %xmm8, 128+0(%rsp) + movdqa %xmm9, 128+16(%rsp) + movdqa %xmm10, 128+32(%rsp) + movdqa %xmm11, 128+48(%rsp) + movdqa %xmm12, 256+0(%rsp) + movdqa %xmm13, 256+16(%rsp) + movdqa %xmm14, 256+32(%rsp) + movdqa %xmm15, 256+48(%rsp) + + pxor 64(%rcx, %rbp), %xmm0 + pxor 80(%rcx, %rbp), %xmm1 + pxor 96(%rcx, %rbp), %xmm2 + pxor 112(%rcx, %rbp), %xmm3 + pxor 64(%rcx, %rbx), %xmm8 + pxor 80(%rcx, %rbx), %xmm9 + pxor 96(%rcx, %rbx), %xmm10 + pxor 112(%rcx, %rbx), %xmm11 + pxor 64(%rcx, %r8), %xmm12 + pxor 80(%rcx, %r8), %xmm13 + pxor 96(%rcx, %r8), %xmm14 + pxor 112(%rcx, %r8), %xmm15 + pxor 64(%rsp), %xmm0 + pxor 80(%rsp), %xmm1 + pxor 96(%rsp), %xmm2 + pxor 112(%rsp), %xmm3 + pxor 128+64(%rsp), %xmm8 + pxor 128+80(%rsp), %xmm9 + pxor 128+96(%rsp), %xmm10 + pxor 128+112(%rsp), %xmm11 + pxor 256+64(%rsp), %xmm12 + pxor 256+80(%rsp), %xmm13 + pxor 256+96(%rsp), %xmm14 + pxor 256+112(%rsp), %xmm15 + movdqa %xmm0, 64(%rsp) + movdqa %xmm1, 80(%rsp) + movdqa %xmm2, 96(%rsp) + movdqa %xmm3, 112(%rsp) + movdqa %xmm8, 128+64(%rsp) + movdqa %xmm9, 128+80(%rsp) + movdqa %xmm10, 128+96(%rsp) + movdqa %xmm11, 128+112(%rsp) + movdqa %xmm12, 256+64(%rsp) + movdqa %xmm13, 256+80(%rsp) + movdqa %xmm14, 256+96(%rsp) + movdqa %xmm15, 256+112(%rsp) + xmm_salsa8_core_3way() + paddd 64(%rsp), %xmm0 + paddd 80(%rsp), %xmm1 + paddd 96(%rsp), %xmm2 + paddd 112(%rsp), %xmm3 + paddd 128+64(%rsp), %xmm8 + paddd 128+80(%rsp), %xmm9 + paddd 128+96(%rsp), %xmm10 + paddd 128+112(%rsp), %xmm11 + paddd 256+64(%rsp), %xmm12 + paddd 256+80(%rsp), %xmm13 + paddd 256+96(%rsp), %xmm14 + paddd 256+112(%rsp), %xmm15 + movdqa %xmm0, 64(%rsp) + movdqa %xmm1, 80(%rsp) + movdqa %xmm2, 96(%rsp) + movdqa %xmm3, 112(%rsp) + movdqa %xmm8, 128+64(%rsp) + movdqa %xmm9, 128+80(%rsp) + movdqa %xmm10, 128+96(%rsp) + movdqa %xmm11, 128+112(%rsp) + movdqa %xmm12, 256+64(%rsp) + movdqa %xmm13, 256+80(%rsp) + movdqa %xmm14, 256+96(%rsp) + movdqa %xmm15, 256+112(%rsp) + + subq $1, %rax + ja scrypt_core_3way_loop2 + + scrypt_shuffle(%rsp, 0, %rdi, 0) + scrypt_shuffle(%rsp, 64, %rdi, 64) + scrypt_shuffle(%rsp, 128, %rsi, 0) + scrypt_shuffle(%rsp, 192, %rsi, 64) + scrypt_shuffle(%rsp, 256, %rdx, 0) + scrypt_shuffle(%rsp, 320, %rdx, 64) + + addq $392, %rsp +#if defined(WIN64) + popq %rsi + popq %rdi + movdqa 8(%rsp), %xmm6 + movdqa 24(%rsp), %xmm7 + movdqa 40(%rsp), %xmm8 + movdqa 56(%rsp), %xmm9 + movdqa 72(%rsp), %xmm10 + movdqa 88(%rsp), %xmm11 + movdqa 104(%rsp), %xmm12 + movdqa 120(%rsp), %xmm13 + movdqa 136(%rsp), %xmm14 + movdqa 152(%rsp), %xmm15 + addq $176, %rsp +#endif + popq %rbp + popq %rbx + ret + +#endif \ No newline at end of file diff --git a/src/scrypt.cpp b/src/scrypt.cpp new file mode 100644 index 0000000..06ef53c --- /dev/null +++ b/src/scrypt.cpp @@ -0,0 +1,198 @@ +/*- + * Copyright 2009 Colin Percival, 2011 ArtForz, 2011 pooler, 2013 Balthazar + * 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 +#include + +#include "scrypt.h" +#include "pbkdf2.h" + +#include "util.h" +#include "net.h" + +#define SCRYPT_BUFFER_SIZE (131072 + 63) + +#if defined (OPTIMIZED_SALSA) && ( defined (__x86_64__) || defined (__i386__) || defined(__arm__) ) +extern "C" void scrypt_core(unsigned int *X, unsigned int *V); +#else +// Generic scrypt_core implementation + +static inline void xor_salsa8(unsigned int B[16], const unsigned int Bx[16]) +{ + unsigned int x00,x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15; + int i; + + x00 = (B[0] ^= Bx[0]); + x01 = (B[1] ^= Bx[1]); + x02 = (B[2] ^= Bx[2]); + x03 = (B[3] ^= Bx[3]); + x04 = (B[4] ^= Bx[4]); + x05 = (B[5] ^= Bx[5]); + x06 = (B[6] ^= Bx[6]); + x07 = (B[7] ^= Bx[7]); + x08 = (B[8] ^= Bx[8]); + x09 = (B[9] ^= Bx[9]); + x10 = (B[10] ^= Bx[10]); + x11 = (B[11] ^= Bx[11]); + x12 = (B[12] ^= Bx[12]); + x13 = (B[13] ^= Bx[13]); + x14 = (B[14] ^= Bx[14]); + x15 = (B[15] ^= Bx[15]); + for (i = 0; i < 8; i += 2) { +#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) + /* Operate on columns. */ + x04 ^= R(x00+x12, 7); x09 ^= R(x05+x01, 7); + x14 ^= R(x10+x06, 7); x03 ^= R(x15+x11, 7); + + x08 ^= R(x04+x00, 9); x13 ^= R(x09+x05, 9); + x02 ^= R(x14+x10, 9); x07 ^= R(x03+x15, 9); + + x12 ^= R(x08+x04,13); x01 ^= R(x13+x09,13); + x06 ^= R(x02+x14,13); x11 ^= R(x07+x03,13); + + x00 ^= R(x12+x08,18); x05 ^= R(x01+x13,18); + x10 ^= R(x06+x02,18); x15 ^= R(x11+x07,18); + + /* Operate on rows. */ + x01 ^= R(x00+x03, 7); x06 ^= R(x05+x04, 7); + x11 ^= R(x10+x09, 7); x12 ^= R(x15+x14, 7); + + x02 ^= R(x01+x00, 9); x07 ^= R(x06+x05, 9); + x08 ^= R(x11+x10, 9); x13 ^= R(x12+x15, 9); + + x03 ^= R(x02+x01,13); x04 ^= R(x07+x06,13); + x09 ^= R(x08+x11,13); x14 ^= R(x13+x12,13); + + x00 ^= R(x03+x02,18); x05 ^= R(x04+x07,18); + x10 ^= R(x09+x08,18); x15 ^= R(x14+x13,18); +#undef R + } + B[0] += x00; + B[1] += x01; + B[2] += x02; + B[3] += x03; + B[4] += x04; + B[5] += x05; + B[6] += x06; + B[7] += x07; + B[8] += x08; + B[9] += x09; + B[10] += x10; + B[11] += x11; + B[12] += x12; + B[13] += x13; + B[14] += x14; + B[15] += x15; +} + +static inline void scrypt_core(unsigned int *X, unsigned int *V) +{ + unsigned int i, j, k; + + for (i = 0; i < 1024; i++) { + memcpy(&V[i * 32], X, 128); + xor_salsa8(&X[0], &X[16]); + xor_salsa8(&X[16], &X[0]); + } + for (i = 0; i < 1024; i++) { + j = 32 * (X[16] & 1023); + for (k = 0; k < 32; k++) + X[k] ^= V[j + k]; + xor_salsa8(&X[0], &X[16]); + xor_salsa8(&X[16], &X[0]); + } +} + +#endif + +/* cpu and memory intensive function to transform a 80 byte buffer into a 32 byte output + scratchpad size needs to be at least 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) bytes + r = 1, p = 1, N = 1024 + */ + +uint256 scrypt_nosalt(const void* input, size_t inputlen, void *scratchpad) +{ + unsigned int *V; + unsigned int X[32]; + uint256 result = 0; + V = (unsigned int *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + + PBKDF2_SHA256((const uint8_t*)input, inputlen, (const uint8_t*)input, inputlen, 1, (uint8_t *)X, 128); + scrypt_core(X, V); + PBKDF2_SHA256((const uint8_t*)input, inputlen, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32); + + return result; +} + +uint256 scrypt(const void* data, size_t datalen, const void* salt, size_t saltlen, void *scratchpad) +{ + unsigned int *V; + unsigned int X[32]; + uint256 result = 0; + V = (unsigned int *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + + PBKDF2_SHA256((const uint8_t*)data, datalen, (const uint8_t*)salt, saltlen, 1, (uint8_t *)X, 128); + scrypt_core(X, V); + PBKDF2_SHA256((const uint8_t*)data, datalen, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32); + + return result; +} + +uint256 scrypt_hash(const void* input, size_t inputlen) +{ + unsigned char scratchpad[SCRYPT_BUFFER_SIZE]; + return scrypt_nosalt(input, inputlen, scratchpad); +} + +uint256 scrypt_salted_hash(const void* input, size_t inputlen, const void* salt, size_t saltlen) +{ + unsigned char scratchpad[SCRYPT_BUFFER_SIZE]; + return scrypt(input, inputlen, salt, saltlen, scratchpad); +} + +uint256 scrypt_salted_multiround_hash(const void* input, size_t inputlen, const void* salt, size_t saltlen, const unsigned int nRounds) +{ + uint256 resultHash = scrypt_salted_hash(input, inputlen, salt, saltlen); + uint256 transitionalHash = resultHash; + + for(unsigned int i = 1; i < nRounds; i++) + { + resultHash = scrypt_salted_hash(input, inputlen, (const void*)&transitionalHash, 32); + transitionalHash = resultHash; + } + + return resultHash; +} + +uint256 scrypt_blockhash(const void* input) +{ + unsigned char scratchpad[SCRYPT_BUFFER_SIZE]; + return scrypt_nosalt(input, 80, scratchpad); +} + diff --git a/src/scrypt.h b/src/scrypt.h new file mode 100644 index 0000000..17afd85 --- /dev/null +++ b/src/scrypt.h @@ -0,0 +1,15 @@ +#ifndef SCRYPT_MINE_H +#define SCRYPT_MINE_H + +#include +#include + +#include "util.h" +#include "net.h" + +uint256 scrypt_salted_multiround_hash(const void* input, size_t inputlen, const void* salt, size_t saltlen, const unsigned int nRounds); +uint256 scrypt_salted_hash(const void* input, size_t inputlen, const void* salt, size_t saltlen); +uint256 scrypt_hash(const void* input, size_t inputlen); +uint256 scrypt_blockhash(const void* input); + +#endif // SCRYPT_MINE_H diff --git a/src/scrypt_mine.cpp b/src/scrypt_mine.cpp new file mode 100644 index 0000000..afca59d --- /dev/null +++ b/src/scrypt_mine.cpp @@ -0,0 +1,208 @@ +/*- + * Copyright 2009 Colin Percival, 2011 ArtForz, 2011 pooler, 2013 Balthazar + * 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 +#include +#include + +#include "scrypt_mine.h" +#include "pbkdf2.h" + +#include "util.h" +#include "net.h" + +extern bool fShutdown; +extern bool fGenerateBitcoins; + +extern CBlockIndex* pindexBest; +extern uint32_t nTransactionsUpdated; + + +#if defined(__x86_64__) + +#define SCRYPT_3WAY +#define SCRYPT_BUFFER_SIZE (3 * 131072 + 63) + +extern "C" int scrypt_best_throughput(); +extern "C" void scrypt_core(uint32_t *X, uint32_t *V); +extern "C" void scrypt_core_2way(uint32_t *X, uint32_t *Y, uint32_t *V); +extern "C" void scrypt_core_3way(uint32_t *X, uint32_t *Y, uint32_t *Z, uint32_t *V); + +#elif defined(__i386__) + +#define SCRYPT_BUFFER_SIZE (131072 + 63) + +extern "C" void scrypt_core(uint32_t *X, uint32_t *V); + +#endif + +void *scrypt_buffer_alloc() { + return malloc(SCRYPT_BUFFER_SIZE); +} + +void scrypt_buffer_free(void *scratchpad) +{ + free(scratchpad); +} + +/* cpu and memory intensive function to transform a 80 byte buffer into a 32 byte output + scratchpad size needs to be at least 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) bytes + r = 1, p = 1, N = 1024 + */ + +static void scrypt(const void* input, size_t inputlen, uint32_t *res, void *scratchpad) +{ + uint32_t *V; + uint32_t X[32]; + V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + + PBKDF2_SHA256((const uint8_t*)input, inputlen, (const uint8_t*)input, sizeof(block_header), 1, (uint8_t *)X, 128); + + scrypt_core(X, V); + + PBKDF2_SHA256((const uint8_t*)input, inputlen, (uint8_t *)X, 128, 1, (uint8_t*)res, 32); +} + +void scrypt_hash(const void* input, size_t inputlen, uint32_t *res, void *scratchpad) +{ + return scrypt(input, inputlen, res, scratchpad); +} + +#ifdef SCRYPT_3WAY +static void scrypt_2way(const void *input1, const void *input2, size_t input1len, size_t input2len, uint32_t *res1, uint32_t *res2, void *scratchpad) +{ + uint32_t *V; + uint32_t X[32], Y[32]; + V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + + PBKDF2_SHA256((const uint8_t*)input1, input1len, (const uint8_t*)input1, input1len, 1, (uint8_t *)X, 128); + PBKDF2_SHA256((const uint8_t*)input2, input2len, (const uint8_t*)input2, input2len, 1, (uint8_t *)Y, 128); + + scrypt_core_2way(X, Y, V); + + PBKDF2_SHA256((const uint8_t*)input1, input1len, (uint8_t *)X, 128, 1, (uint8_t*)res1, 32); + PBKDF2_SHA256((const uint8_t*)input2, input2len, (uint8_t *)Y, 128, 1, (uint8_t*)res2, 32); +} + +static void scrypt_3way(const void *input1, const void *input2, const void *input3, + size_t input1len, size_t input2len, size_t input3len, uint32_t *res1, uint32_t *res2, uint32_t *res3, + void *scratchpad) +{ + uint32_t *V; + uint32_t X[32], Y[32], Z[32]; + V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + + PBKDF2_SHA256((const uint8_t*)input1, input1len, (const uint8_t*)input1, input1len, 1, (uint8_t *)X, 128); + PBKDF2_SHA256((const uint8_t*)input2, input2len, (const uint8_t*)input2, input2len, 1, (uint8_t *)Y, 128); + PBKDF2_SHA256((const uint8_t*)input3, input3len, (const uint8_t*)input3, input3len, 1, (uint8_t *)Z, 128); + + scrypt_core_3way(X, Y, Z, V); + + PBKDF2_SHA256((const uint8_t*)input1, input1len, (uint8_t *)X, 128, 1, (uint8_t*)res1, 32); + PBKDF2_SHA256((const uint8_t*)input2, input2len, (uint8_t *)Y, 128, 1, (uint8_t*)res2, 32); + PBKDF2_SHA256((const uint8_t*)input3, input3len, (uint8_t *)Z, 128, 1, (uint8_t*)res3, 32); +} +#endif + +unsigned int scanhash_scrypt(block_header *pdata, void *scratchbuf, + uint32_t max_nonce, uint32_t &hash_count, + void *result, block_header *res_header) +{ + hash_count = 0; + block_header data = *pdata; + uint32_t hash[8]; + unsigned char *hashc = (unsigned char *) &hash; + +#ifdef SCRYPT_3WAY + block_header data2 = *pdata; + uint32_t hash2[8]; + unsigned char *hashc2 = (unsigned char *) &hash2; + + block_header data3 = *pdata; + uint32_t hash3[8]; + unsigned char *hashc3 = (unsigned char *) &hash3; + + int throughput = scrypt_best_throughput(); +#endif + + uint32_t n = 0; + + while (true) { + + data.nonce = n++; + +#ifdef SCRYPT_3WAY + if (throughput >= 2 && n < max_nonce) { + data2.nonce = n++; + if(throughput >= 3) + { + data3.nonce = n++; + scrypt_3way(&data, &data2, &data3, 80, 80, 80, hash, hash2, hash3, scratchbuf); + hash_count += 3; + + if (hashc3[31] == 0 && hashc3[30] == 0) { + memcpy(result, hash3, 32); + *res_header = data3; + + return data3.nonce; + } + } + else + { + scrypt_2way(&data, &data2, 80, 80, hash, hash2, scratchbuf); + hash_count += 2; + } + + if (hashc2[31] == 0 && hashc2[30] == 0) { + memcpy(result, hash2, 32); + + return data2.nonce; + } + } else { + scrypt(&data, 80, hash, scratchbuf); + hash_count += 1; + } +#else + scrypt(&data, 80, hash, scratchbuf); + hash_count += 1; +#endif + if (hashc[31] == 0 && hashc[30] == 0) { + memcpy(result, hash, 32); + + return data.nonce; + } + + if (n >= max_nonce) { + hash_count = 0xffff + 1; + break; + } + } + + return (unsigned int) -1; +} diff --git a/src/scrypt_mine.h b/src/scrypt_mine.h new file mode 100644 index 0000000..e316e28 --- /dev/null +++ b/src/scrypt_mine.h @@ -0,0 +1,30 @@ +#ifndef SCRYPT_MINE_H +#define SCRYPT_MINE_H + +#include +#include + +#include "util.h" +#include "net.h" + +typedef struct +{ + unsigned int version; + uint256 prev_block; + uint256 merkle_root; + unsigned int timestamp; + unsigned int bits; + unsigned int nonce; + +} block_header; + +void *scrypt_buffer_alloc(); +void scrypt_buffer_free(void *scratchpad); + +unsigned int scanhash_scrypt(block_header *pdata, void *scratchbuf, + uint32_t max_nonce, uint32_t &hash_count, + void *result, block_header *res_header); + +void scrypt_hash(const void* input, size_t inputlen, uint32_t *res, void *scratchpad); + +#endif // SCRYPT_MINE_H diff --git a/src/serialize.h b/src/serialize.h new file mode 100644 index 0000000..3b3dcd4 --- /dev/null +++ b/src/serialize.h @@ -0,0 +1,1141 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_SERIALIZE_H +#define BITCOIN_SERIALIZE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "allocators.h" +#include "version.h" + +typedef long long int64; +typedef unsigned long long uint64; + +class CScript; +class CDataStream; +class CAutoFile; +static const unsigned int MAX_SIZE = 0x02000000; + +// Used to bypass the rule against non-const reference to temporary +// where it makes sense with wrappers such as CFlatData or CTxDB +template +inline T& REF(const T& val) +{ + return const_cast(val); +} + +///////////////////////////////////////////////////////////////// +// +// Templates for serializing to anything that looks like a stream, +// i.e. anything that supports .read(char*, int) and .write(char*, int) +// + +enum +{ + // primary actions + SER_NETWORK = (1 << 0), + SER_DISK = (1 << 1), + SER_GETHASH = (1 << 2), + + // modifiers + SER_SKIPSIG = (1 << 16), + SER_BLOCKHEADERONLY = (1 << 17), +}; + +#define IMPLEMENT_SERIALIZE(statements) \ + unsigned int GetSerializeSize(int nType, int nVersion) const \ + { \ + CSerActionGetSerializeSize ser_action; \ + const bool fGetSize = true; \ + const bool fWrite = false; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + ser_streamplaceholder s; \ + assert(fGetSize||fWrite||fRead); /* suppress warning */ \ + s.nType = nType; \ + s.nVersion = nVersion; \ + {statements} \ + return nSerSize; \ + } \ + template \ + void Serialize(Stream& s, int nType, int nVersion) const \ + { \ + CSerActionSerialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = true; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + assert(fGetSize||fWrite||fRead); /* suppress warning */ \ + {statements} \ + } \ + template \ + void Unserialize(Stream& s, int nType, int nVersion) \ + { \ + CSerActionUnserialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = false; \ + const bool fRead = true; \ + unsigned int nSerSize = 0; \ + assert(fGetSize||fWrite||fRead); /* suppress warning */ \ + {statements} \ + } + +#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) + + + + + + +// +// Basic types +// +#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) +#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj)) + +inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(int64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(uint64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); } + +template inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, int64 a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, uint64 a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); } + +template inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, int64& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, uint64& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); } + +inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); } +template inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); } +template inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; } + + +#ifndef THROW_WITH_STACKTRACE +#define THROW_WITH_STACKTRACE(exception) \ +{ \ + LogStackTrace(); \ + throw (exception); \ +} +void LogStackTrace(); +#endif + +// +// Compact size +// size < 253 -- 1 byte +// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) +// size <= UINT_MAX -- 5 bytes (254 + 4 bytes) +// size > UINT_MAX -- 9 bytes (255 + 8 bytes) +// +inline unsigned int GetSizeOfCompactSize(uint64 nSize) +{ + if (nSize < 253) return sizeof(unsigned char); + else if (nSize <= std::numeric_limits::max()) return sizeof(unsigned char) + sizeof(unsigned short); + else if (nSize <= std::numeric_limits::max()) return sizeof(unsigned char) + sizeof(unsigned int); + else return sizeof(unsigned char) + sizeof(uint64); +} + +template +void WriteCompactSize(Stream& os, uint64 nSize) +{ + if (nSize < 253) + { + unsigned char chSize = nSize; + WRITEDATA(os, chSize); + } + else if (nSize <= std::numeric_limits::max()) + { + unsigned char chSize = 253; + unsigned short xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else if (nSize <= std::numeric_limits::max()) + { + unsigned char chSize = 254; + unsigned int xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else + { + unsigned char chSize = 255; + uint64 xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + return; +} + +template +uint64 ReadCompactSize(Stream& is) +{ + unsigned char chSize; + READDATA(is, chSize); + uint64 nSizeRet = 0; + if (chSize < 253) + { + nSizeRet = chSize; + } + else if (chSize == 253) + { + unsigned short xSize; + READDATA(is, xSize); + nSizeRet = xSize; + } + else if (chSize == 254) + { + unsigned int xSize; + READDATA(is, xSize); + nSizeRet = xSize; + } + else + { + uint64 xSize; + READDATA(is, xSize); + nSizeRet = xSize; + } + if (nSizeRet > (uint64)MAX_SIZE) + THROW_WITH_STACKTRACE(std::ios_base::failure("ReadCompactSize() : size too large")); + return nSizeRet; +} + + + +#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) + +/** Wrapper for serializing arrays and POD. + */ +class CFlatData +{ +protected: + char* pbegin; + char* pend; +public: + CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { } + char* begin() { return pbegin; } + const char* begin() const { return pbegin; } + char* end() { return pend; } + const char* end() const { return pend; } + + unsigned int GetSerializeSize(int, int=0) const + { + return pend - pbegin; + } + + template + void Serialize(Stream& s, int, int=0) const + { + s.write(pbegin, pend - pbegin); + } + + template + void Unserialize(Stream& s, int, int=0) + { + s.read(pbegin, pend - pbegin); + } +}; + +// +// Forward declarations +// + +// string +template unsigned int GetSerializeSize(const std::basic_string& str, int, int=0); +template void Serialize(Stream& os, const std::basic_string& str, int, int=0); +template void Unserialize(Stream& is, std::basic_string& str, int, int=0); + +// vector +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&); +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion); + +// others derived from vector +extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion); +template void Serialize(Stream& os, const CScript& v, int nType, int nVersion); +template void Unserialize(Stream& is, CScript& v, int nType, int nVersion); + +// pair +template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion); +template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion); +template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion); + +// 3 tuple +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); + +// 4 tuple +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); + +// map +template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::map& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::map& m, int nType, int nVersion); + +// set +template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::set& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::set& m, int nType, int nVersion); + + + + + +// +// If none of the specialized versions above matched, default to calling member function. +// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error. +// The compiler will only cast int to long if none of the other templates matched. +// Thanks to Boost serialization for this idea. +// +template +inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion) +{ + return a.GetSerializeSize((int)nType, nVersion); +} + +template +inline void Serialize(Stream& os, const T& a, long nType, int nVersion) +{ + a.Serialize(os, (int)nType, nVersion); +} + +template +inline void Unserialize(Stream& is, T& a, long nType, int nVersion) +{ + a.Unserialize(is, (int)nType, nVersion); +} + + + + + +// +// string +// +template +unsigned int GetSerializeSize(const std::basic_string& str, int, int) +{ + return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]); +} + +template +void Serialize(Stream& os, const std::basic_string& str, int, int) +{ + WriteCompactSize(os, str.size()); + if (!str.empty()) + os.write((char*)&str[0], str.size() * sizeof(str[0])); +} + +template +void Unserialize(Stream& is, std::basic_string& str, int, int) +{ + unsigned int nSize = ReadCompactSize(is); + str.resize(nSize); + if (nSize != 0) + is.read((char*)&str[0], nSize * sizeof(str[0])); +} + + + +// +// vector +// +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); +} + +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + unsigned int nSize = GetSizeOfCompactSize(v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + nSize += GetSerializeSize((*vi), nType, nVersion); + return nSize; +} + +template +inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion) +{ + return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + WriteCompactSize(os, v.size()); + if (!v.empty()) + os.write((char*)&v[0], v.size() * sizeof(T)); +} + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + WriteCompactSize(os, v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + ::Serialize(os, (*vi), nType, nVersion); +} + +template +inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion) +{ + Serialize_impl(os, v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + // Limit size per read so bogus size value won't cause out of memory + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + while (i < nSize) + { + unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); + v.resize(i + blk); + is.read((char*)&v[i], blk * sizeof(T)); + i += blk; + } +} + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + unsigned int nMid = 0; + while (nMid < nSize) + { + nMid += 5000000 / sizeof(T); + if (nMid > nSize) + nMid = nSize; + v.resize(nMid); + for (; i < nMid; i++) + Unserialize(is, v[i], nType, nVersion); + } +} + +template +inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion) +{ + Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental()); +} + + + +// +// others derived from vector +// +inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion) +{ + return GetSerializeSize((const std::vector&)v, nType, nVersion); +} + +template +void Serialize(Stream& os, const CScript& v, int nType, int nVersion) +{ + Serialize(os, (const std::vector&)v, nType, nVersion); +} + +template +void Unserialize(Stream& is, CScript& v, int nType, int nVersion) +{ + Unserialize(is, (std::vector&)v, nType, nVersion); +} + + + +// +// pair +// +template +unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion) +{ + return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion); +} + +template +void Serialize(Stream& os, const std::pair& item, int nType, int nVersion) +{ + Serialize(os, item.first, nType, nVersion); + Serialize(os, item.second, nType, nVersion); +} + +template +void Unserialize(Stream& is, std::pair& item, int nType, int nVersion) +{ + Unserialize(is, item.first, nType, nVersion); + Unserialize(is, item.second, nType, nVersion); +} + + + +// +// 3 tuple +// +template +unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion) +{ + unsigned int nSize = 0; + nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion) +{ + Serialize(os, boost::get<0>(item), nType, nVersion); + Serialize(os, boost::get<1>(item), nType, nVersion); + Serialize(os, boost::get<2>(item), nType, nVersion); +} + +template +void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion) +{ + Unserialize(is, boost::get<0>(item), nType, nVersion); + Unserialize(is, boost::get<1>(item), nType, nVersion); + Unserialize(is, boost::get<2>(item), nType, nVersion); +} + + + +// +// 4 tuple +// +template +unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion) +{ + unsigned int nSize = 0; + nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion) +{ + Serialize(os, boost::get<0>(item), nType, nVersion); + Serialize(os, boost::get<1>(item), nType, nVersion); + Serialize(os, boost::get<2>(item), nType, nVersion); + Serialize(os, boost::get<3>(item), nType, nVersion); +} + +template +void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion) +{ + Unserialize(is, boost::get<0>(item), nType, nVersion); + Unserialize(is, boost::get<1>(item), nType, nVersion); + Unserialize(is, boost::get<2>(item), nType, nVersion); + Unserialize(is, boost::get<3>(item), nType, nVersion); +} + + + +// +// map +// +template +unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + nSize += GetSerializeSize((*mi), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::map& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + Serialize(os, (*mi), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::map& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::map::iterator mi = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + std::pair item; + Unserialize(is, item, nType, nVersion); + mi = m.insert(mi, item); + } +} + + + +// +// set +// +template +unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + nSize += GetSerializeSize((*it), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::set& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + Serialize(os, (*it), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::set& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::set::iterator it = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + K key; + Unserialize(is, key, nType, nVersion); + it = m.insert(it, key); + } +} + + + +// +// Support for IMPLEMENT_SERIALIZE and READWRITE macro +// +class CSerActionGetSerializeSize { }; +class CSerActionSerialize { }; +class CSerActionUnserialize { }; + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action) +{ + return ::GetSerializeSize(obj, nType, nVersion); +} + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action) +{ + ::Serialize(s, obj, nType, nVersion); + return 0; +} + +template +inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action) +{ + ::Unserialize(s, obj, nType, nVersion); + return 0; +} + +struct ser_streamplaceholder +{ + int nType; + int nVersion; +}; + + + + + + + + + + + + +/** Double ended buffer combining vector and stream-like interfaces. + * + * >> and << read and write unformatted data using the above serialization templates. + * Fills with data in linear time; some stringstream implementations take N^2 time. + */ +class CDataStream +{ +protected: + typedef std::vector > vector_type; + vector_type vch; + unsigned int nReadPos; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + typedef vector_type::allocator_type allocator_type; + typedef vector_type::size_type size_type; + typedef vector_type::difference_type difference_type; + typedef vector_type::reference reference; + typedef vector_type::const_reference const_reference; + typedef vector_type::value_type value_type; + typedef vector_type::iterator iterator; + typedef vector_type::const_iterator const_iterator; + typedef vector_type::reverse_iterator reverse_iterator; + + explicit CDataStream(int nTypeIn, int nVersionIn) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } +#endif + + CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + { + Init(nTypeIn, nVersionIn); + } + + void Init(int nTypeIn, int nVersionIn) + { + nReadPos = 0; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = std::ios::badbit | std::ios::failbit; + } + + CDataStream& operator+=(const CDataStream& b) + { + vch.insert(vch.end(), b.begin(), b.end()); + return *this; + } + + friend CDataStream operator+(const CDataStream& a, const CDataStream& b) + { + CDataStream ret = a; + ret += b; + return (ret); + } + + std::string str() const + { + return (std::string(begin(), end())); + } + + + // + // Vector subset + // + const_iterator begin() const { return vch.begin() + nReadPos; } + iterator begin() { return vch.begin() + nReadPos; } + const_iterator end() const { return vch.end(); } + iterator end() { return vch.end(); } + size_type size() const { return vch.size() - nReadPos; } + bool empty() const { return vch.size() == nReadPos; } + void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } + void reserve(size_type n) { vch.reserve(n + nReadPos); } + const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } + reference operator[](size_type pos) { return vch[pos + nReadPos]; } + void clear() { vch.clear(); nReadPos = 0; } + iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); } + + void insert(iterator it, const_iterator first, const_iterator last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + + void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + void insert(iterator it, const char* first, const char* last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } +#endif + + iterator erase(iterator it) + { + if (it == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (++nReadPos >= vch.size()) + { + // whenever we reach the end, we take the opportunity to clear the buffer + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + return vch.begin() + nReadPos; + } + else + return vch.erase(it); + } + + iterator erase(iterator first, iterator last) + { + if (first == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (last == vch.end()) + { + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + else + { + nReadPos = (last - vch.begin()); + return last; + } + } + else + return vch.erase(first, last); + } + + inline void Compact() + { + vch.erase(vch.begin(), vch.begin() + nReadPos); + nReadPos = 0; + } + + bool Rewind(size_type n) + { + // Rewind by n characters if the buffer hasn't been compacted yet + if (n > nReadPos) + return false; + nReadPos -= n; + return true; + } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + THROW_WITH_STACKTRACE(std::ios_base::failure(psz)); + } + + bool eof() const { return size() == 0; } + bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } + bool good() const { return !eof() && (state == 0); } + void clear(short n) { state = n; } // name conflict with vector clear() + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; } + CDataStream* rdbuf() { return this; } + int in_avail() { return size(); } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CDataStream& read(char* pch, int nSize) + { + // Read from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(std::ios::failbit, "CDataStream::read() : end of data"); + memset(pch, 0, nSize); + nSize = vch.size() - nReadPos; + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = 0; + vch.clear(); + return (*this); + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& ignore(int nSize) + { + // Ignore from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(std::ios::failbit, "CDataStream::ignore() : end of data"); + nSize = vch.size() - nReadPos; + } + nReadPos = 0; + vch.clear(); + return (*this); + } + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& write(const char* pch, int nSize) + { + // Write to the end of the buffer + assert(nSize >= 0); + vch.insert(vch.end(), pch, pch + nSize); + return (*this); + } + + template + void Serialize(Stream& s, int nType, int nVersion) const + { + // Special case: stream << stream concatenates like stream += stream + if (!vch.empty()) + s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CDataStream& operator<<(const T& obj) + { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CDataStream& operator>>(T& obj) + { + // Unserialize from this stream + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; + + + + + + + + + + +/** RAII wrapper for FILE*. + * + * Will automatically close the file when it goes out of scope if not null. + * If you're returning the file pointer, return file.release(). + * If you need to close the file early, use file.fclose() instead of fclose(file). + */ +class CAutoFile +{ +protected: + FILE* file; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) + { + file = filenew; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = std::ios::badbit | std::ios::failbit; + } + + ~CAutoFile() + { + fclose(); + } + + void fclose() + { + if (file != NULL && file != stdin && file != stdout && file != stderr) + ::fclose(file); + file = NULL; + } + + FILE* release() { FILE* ret = file; file = NULL; return ret; } + operator FILE*() { return file; } + FILE* operator->() { return file; } + FILE& operator*() { return *file; } + FILE** operator&() { return &file; } + FILE* operator=(FILE* pnew) { return file = pnew; } + bool operator!() { return (file == NULL); } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + THROW_WITH_STACKTRACE(std::ios_base::failure(psz)); + } + + bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } + bool good() const { return state == 0; } + void clear(short n = 0) { state = n; } + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CAutoFile& read(char* pch, size_t nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); + if (fread(pch, 1, nSize, file) != nSize) + setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); + return (*this); + } + + CAutoFile& write(const char* pch, size_t nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); + if (fwrite(pch, 1, nSize, file) != nSize) + setstate(std::ios::failbit, "CAutoFile::write : write failed"); + return (*this); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CAutoFile& operator<<(const T& obj) + { + // Serialize to this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CAutoFile& operator>>(T& obj) + { + // Unserialize from this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; + +#endif diff --git a/src/shabal.c b/src/shabal.c new file mode 100644 index 0000000..bfbab0e --- /dev/null +++ b/src/shabal.c @@ -0,0 +1,806 @@ +/* $Id: shabal.c 175 2010-05-07 16:03:20Z tp $ */ +/* + * Shabal 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 + */ + +#include +#include + +#include "sph_shabal.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +/* + * Part of this code was automatically generated (the part between + * the "BEGIN" and "END" markers). + */ + +#define sM 16 + +#define C32 SPH_C32 +#define T32 SPH_T32 + +#define O1 13 +#define O2 9 +#define O3 6 + +/* + * We copy the state into local variables, so that the compiler knows + * that it can optimize them at will. + */ + +/* BEGIN -- automatically generated code. */ + +#define DECL_STATE \ + sph_u32 A00, A01, A02, A03, A04, A05, A06, A07, \ + A08, A09, A0A, A0B; \ + sph_u32 B0, B1, B2, B3, B4, B5, B6, B7, \ + B8, B9, BA, BB, BC, BD, BE, BF; \ + sph_u32 C0, C1, C2, C3, C4, C5, C6, C7, \ + C8, C9, CA, CB, CC, CD, CE, CF; \ + sph_u32 M0, M1, M2, M3, M4, M5, M6, M7, \ + M8, M9, MA, MB, MC, MD, ME, MF; \ + sph_u32 Wlow, Whigh; + +#define READ_STATE(state) do { \ + A00 = (state)->A[0]; \ + A01 = (state)->A[1]; \ + A02 = (state)->A[2]; \ + A03 = (state)->A[3]; \ + A04 = (state)->A[4]; \ + A05 = (state)->A[5]; \ + A06 = (state)->A[6]; \ + A07 = (state)->A[7]; \ + A08 = (state)->A[8]; \ + A09 = (state)->A[9]; \ + A0A = (state)->A[10]; \ + A0B = (state)->A[11]; \ + B0 = (state)->B[0]; \ + B1 = (state)->B[1]; \ + B2 = (state)->B[2]; \ + B3 = (state)->B[3]; \ + B4 = (state)->B[4]; \ + B5 = (state)->B[5]; \ + B6 = (state)->B[6]; \ + B7 = (state)->B[7]; \ + B8 = (state)->B[8]; \ + B9 = (state)->B[9]; \ + BA = (state)->B[10]; \ + BB = (state)->B[11]; \ + BC = (state)->B[12]; \ + BD = (state)->B[13]; \ + BE = (state)->B[14]; \ + BF = (state)->B[15]; \ + C0 = (state)->C[0]; \ + C1 = (state)->C[1]; \ + C2 = (state)->C[2]; \ + C3 = (state)->C[3]; \ + C4 = (state)->C[4]; \ + C5 = (state)->C[5]; \ + C6 = (state)->C[6]; \ + C7 = (state)->C[7]; \ + C8 = (state)->C[8]; \ + C9 = (state)->C[9]; \ + CA = (state)->C[10]; \ + CB = (state)->C[11]; \ + CC = (state)->C[12]; \ + CD = (state)->C[13]; \ + CE = (state)->C[14]; \ + CF = (state)->C[15]; \ + Wlow = (state)->Wlow; \ + Whigh = (state)->Whigh; \ + } while (0) + +#define WRITE_STATE(state) do { \ + (state)->A[0] = A00; \ + (state)->A[1] = A01; \ + (state)->A[2] = A02; \ + (state)->A[3] = A03; \ + (state)->A[4] = A04; \ + (state)->A[5] = A05; \ + (state)->A[6] = A06; \ + (state)->A[7] = A07; \ + (state)->A[8] = A08; \ + (state)->A[9] = A09; \ + (state)->A[10] = A0A; \ + (state)->A[11] = A0B; \ + (state)->B[0] = B0; \ + (state)->B[1] = B1; \ + (state)->B[2] = B2; \ + (state)->B[3] = B3; \ + (state)->B[4] = B4; \ + (state)->B[5] = B5; \ + (state)->B[6] = B6; \ + (state)->B[7] = B7; \ + (state)->B[8] = B8; \ + (state)->B[9] = B9; \ + (state)->B[10] = BA; \ + (state)->B[11] = BB; \ + (state)->B[12] = BC; \ + (state)->B[13] = BD; \ + (state)->B[14] = BE; \ + (state)->B[15] = BF; \ + (state)->C[0] = C0; \ + (state)->C[1] = C1; \ + (state)->C[2] = C2; \ + (state)->C[3] = C3; \ + (state)->C[4] = C4; \ + (state)->C[5] = C5; \ + (state)->C[6] = C6; \ + (state)->C[7] = C7; \ + (state)->C[8] = C8; \ + (state)->C[9] = C9; \ + (state)->C[10] = CA; \ + (state)->C[11] = CB; \ + (state)->C[12] = CC; \ + (state)->C[13] = CD; \ + (state)->C[14] = CE; \ + (state)->C[15] = CF; \ + (state)->Wlow = Wlow; \ + (state)->Whigh = Whigh; \ + } while (0) + +#define DECODE_BLOCK do { \ + M0 = sph_dec32le_aligned(buf + 0); \ + M1 = sph_dec32le_aligned(buf + 4); \ + M2 = sph_dec32le_aligned(buf + 8); \ + M3 = sph_dec32le_aligned(buf + 12); \ + M4 = sph_dec32le_aligned(buf + 16); \ + M5 = sph_dec32le_aligned(buf + 20); \ + M6 = sph_dec32le_aligned(buf + 24); \ + M7 = sph_dec32le_aligned(buf + 28); \ + M8 = sph_dec32le_aligned(buf + 32); \ + M9 = sph_dec32le_aligned(buf + 36); \ + MA = sph_dec32le_aligned(buf + 40); \ + MB = sph_dec32le_aligned(buf + 44); \ + MC = sph_dec32le_aligned(buf + 48); \ + MD = sph_dec32le_aligned(buf + 52); \ + ME = sph_dec32le_aligned(buf + 56); \ + MF = sph_dec32le_aligned(buf + 60); \ + } while (0) + +#define INPUT_BLOCK_ADD do { \ + B0 = T32(B0 + M0); \ + B1 = T32(B1 + M1); \ + B2 = T32(B2 + M2); \ + B3 = T32(B3 + M3); \ + B4 = T32(B4 + M4); \ + B5 = T32(B5 + M5); \ + B6 = T32(B6 + M6); \ + B7 = T32(B7 + M7); \ + B8 = T32(B8 + M8); \ + B9 = T32(B9 + M9); \ + BA = T32(BA + MA); \ + BB = T32(BB + MB); \ + BC = T32(BC + MC); \ + BD = T32(BD + MD); \ + BE = T32(BE + ME); \ + BF = T32(BF + MF); \ + } while (0) + +#define INPUT_BLOCK_SUB do { \ + C0 = T32(C0 - M0); \ + C1 = T32(C1 - M1); \ + C2 = T32(C2 - M2); \ + C3 = T32(C3 - M3); \ + C4 = T32(C4 - M4); \ + C5 = T32(C5 - M5); \ + C6 = T32(C6 - M6); \ + C7 = T32(C7 - M7); \ + C8 = T32(C8 - M8); \ + C9 = T32(C9 - M9); \ + CA = T32(CA - MA); \ + CB = T32(CB - MB); \ + CC = T32(CC - MC); \ + CD = T32(CD - MD); \ + CE = T32(CE - ME); \ + CF = T32(CF - MF); \ + } while (0) + +#define XOR_W do { \ + A00 ^= Wlow; \ + A01 ^= Whigh; \ + } while (0) + +#define SWAP(v1, v2) do { \ + sph_u32 tmp = (v1); \ + (v1) = (v2); \ + (v2) = tmp; \ + } while (0) + +#define SWAP_BC do { \ + SWAP(B0, C0); \ + SWAP(B1, C1); \ + SWAP(B2, C2); \ + SWAP(B3, C3); \ + SWAP(B4, C4); \ + SWAP(B5, C5); \ + SWAP(B6, C6); \ + SWAP(B7, C7); \ + SWAP(B8, C8); \ + SWAP(B9, C9); \ + SWAP(BA, CA); \ + SWAP(BB, CB); \ + SWAP(BC, CC); \ + SWAP(BD, CD); \ + SWAP(BE, CE); \ + SWAP(BF, CF); \ + } while (0) + +#define PERM_ELT(xa0, xa1, xb0, xb1, xb2, xb3, xc, xm) do { \ + xa0 = T32((xa0 \ + ^ (((xa1 << 15) | (xa1 >> 17)) * 5U) \ + ^ xc) * 3U) \ + ^ xb1 ^ (xb2 & ~xb3) ^ xm; \ + xb0 = T32(~(((xb0 << 1) | (xb0 >> 31)) ^ xa0)); \ + } while (0) + +#define PERM_STEP_0 do { \ + PERM_ELT(A00, A0B, B0, BD, B9, B6, C8, M0); \ + PERM_ELT(A01, A00, B1, BE, BA, B7, C7, M1); \ + PERM_ELT(A02, A01, B2, BF, BB, B8, C6, M2); \ + PERM_ELT(A03, A02, B3, B0, BC, B9, C5, M3); \ + PERM_ELT(A04, A03, B4, B1, BD, BA, C4, M4); \ + PERM_ELT(A05, A04, B5, B2, BE, BB, C3, M5); \ + PERM_ELT(A06, A05, B6, B3, BF, BC, C2, M6); \ + PERM_ELT(A07, A06, B7, B4, B0, BD, C1, M7); \ + PERM_ELT(A08, A07, B8, B5, B1, BE, C0, M8); \ + PERM_ELT(A09, A08, B9, B6, B2, BF, CF, M9); \ + PERM_ELT(A0A, A09, BA, B7, B3, B0, CE, MA); \ + PERM_ELT(A0B, A0A, BB, B8, B4, B1, CD, MB); \ + PERM_ELT(A00, A0B, BC, B9, B5, B2, CC, MC); \ + PERM_ELT(A01, A00, BD, BA, B6, B3, CB, MD); \ + PERM_ELT(A02, A01, BE, BB, B7, B4, CA, ME); \ + PERM_ELT(A03, A02, BF, BC, B8, B5, C9, MF); \ + } while (0) + +#define PERM_STEP_1 do { \ + PERM_ELT(A04, A03, B0, BD, B9, B6, C8, M0); \ + PERM_ELT(A05, A04, B1, BE, BA, B7, C7, M1); \ + PERM_ELT(A06, A05, B2, BF, BB, B8, C6, M2); \ + PERM_ELT(A07, A06, B3, B0, BC, B9, C5, M3); \ + PERM_ELT(A08, A07, B4, B1, BD, BA, C4, M4); \ + PERM_ELT(A09, A08, B5, B2, BE, BB, C3, M5); \ + PERM_ELT(A0A, A09, B6, B3, BF, BC, C2, M6); \ + PERM_ELT(A0B, A0A, B7, B4, B0, BD, C1, M7); \ + PERM_ELT(A00, A0B, B8, B5, B1, BE, C0, M8); \ + PERM_ELT(A01, A00, B9, B6, B2, BF, CF, M9); \ + PERM_ELT(A02, A01, BA, B7, B3, B0, CE, MA); \ + PERM_ELT(A03, A02, BB, B8, B4, B1, CD, MB); \ + PERM_ELT(A04, A03, BC, B9, B5, B2, CC, MC); \ + PERM_ELT(A05, A04, BD, BA, B6, B3, CB, MD); \ + PERM_ELT(A06, A05, BE, BB, B7, B4, CA, ME); \ + PERM_ELT(A07, A06, BF, BC, B8, B5, C9, MF); \ + } while (0) + +#define PERM_STEP_2 do { \ + PERM_ELT(A08, A07, B0, BD, B9, B6, C8, M0); \ + PERM_ELT(A09, A08, B1, BE, BA, B7, C7, M1); \ + PERM_ELT(A0A, A09, B2, BF, BB, B8, C6, M2); \ + PERM_ELT(A0B, A0A, B3, B0, BC, B9, C5, M3); \ + PERM_ELT(A00, A0B, B4, B1, BD, BA, C4, M4); \ + PERM_ELT(A01, A00, B5, B2, BE, BB, C3, M5); \ + PERM_ELT(A02, A01, B6, B3, BF, BC, C2, M6); \ + PERM_ELT(A03, A02, B7, B4, B0, BD, C1, M7); \ + PERM_ELT(A04, A03, B8, B5, B1, BE, C0, M8); \ + PERM_ELT(A05, A04, B9, B6, B2, BF, CF, M9); \ + PERM_ELT(A06, A05, BA, B7, B3, B0, CE, MA); \ + PERM_ELT(A07, A06, BB, B8, B4, B1, CD, MB); \ + PERM_ELT(A08, A07, BC, B9, B5, B2, CC, MC); \ + PERM_ELT(A09, A08, BD, BA, B6, B3, CB, MD); \ + PERM_ELT(A0A, A09, BE, BB, B7, B4, CA, ME); \ + PERM_ELT(A0B, A0A, BF, BC, B8, B5, C9, MF); \ + } while (0) + +#define APPLY_P do { \ + B0 = T32(B0 << 17) | (B0 >> 15); \ + B1 = T32(B1 << 17) | (B1 >> 15); \ + B2 = T32(B2 << 17) | (B2 >> 15); \ + B3 = T32(B3 << 17) | (B3 >> 15); \ + B4 = T32(B4 << 17) | (B4 >> 15); \ + B5 = T32(B5 << 17) | (B5 >> 15); \ + B6 = T32(B6 << 17) | (B6 >> 15); \ + B7 = T32(B7 << 17) | (B7 >> 15); \ + B8 = T32(B8 << 17) | (B8 >> 15); \ + B9 = T32(B9 << 17) | (B9 >> 15); \ + BA = T32(BA << 17) | (BA >> 15); \ + BB = T32(BB << 17) | (BB >> 15); \ + BC = T32(BC << 17) | (BC >> 15); \ + BD = T32(BD << 17) | (BD >> 15); \ + BE = T32(BE << 17) | (BE >> 15); \ + BF = T32(BF << 17) | (BF >> 15); \ + PERM_STEP_0; \ + PERM_STEP_1; \ + PERM_STEP_2; \ + A0B = T32(A0B + C6); \ + A0A = T32(A0A + C5); \ + A09 = T32(A09 + C4); \ + A08 = T32(A08 + C3); \ + A07 = T32(A07 + C2); \ + A06 = T32(A06 + C1); \ + A05 = T32(A05 + C0); \ + A04 = T32(A04 + CF); \ + A03 = T32(A03 + CE); \ + A02 = T32(A02 + CD); \ + A01 = T32(A01 + CC); \ + A00 = T32(A00 + CB); \ + A0B = T32(A0B + CA); \ + A0A = T32(A0A + C9); \ + A09 = T32(A09 + C8); \ + A08 = T32(A08 + C7); \ + A07 = T32(A07 + C6); \ + A06 = T32(A06 + C5); \ + A05 = T32(A05 + C4); \ + A04 = T32(A04 + C3); \ + A03 = T32(A03 + C2); \ + A02 = T32(A02 + C1); \ + A01 = T32(A01 + C0); \ + A00 = T32(A00 + CF); \ + A0B = T32(A0B + CE); \ + A0A = T32(A0A + CD); \ + A09 = T32(A09 + CC); \ + A08 = T32(A08 + CB); \ + A07 = T32(A07 + CA); \ + A06 = T32(A06 + C9); \ + A05 = T32(A05 + C8); \ + A04 = T32(A04 + C7); \ + A03 = T32(A03 + C6); \ + A02 = T32(A02 + C5); \ + A01 = T32(A01 + C4); \ + A00 = T32(A00 + C3); \ + } while (0) + +#define INCR_W do { \ + if ((Wlow = T32(Wlow + 1)) == 0) \ + Whigh = T32(Whigh + 1); \ + } while (0) + +static const sph_u32 A_init_192[] = { + C32(0xFD749ED4), C32(0xB798E530), C32(0x33904B6F), C32(0x46BDA85E), + C32(0x076934B4), C32(0x454B4058), C32(0x77F74527), C32(0xFB4CF465), + C32(0x62931DA9), C32(0xE778C8DB), C32(0x22B3998E), C32(0xAC15CFB9) +}; + +static const sph_u32 B_init_192[] = { + C32(0x58BCBAC4), C32(0xEC47A08E), C32(0xAEE933B2), C32(0xDFCBC824), + C32(0xA7944804), C32(0xBF65BDB0), C32(0x5A9D4502), C32(0x59979AF7), + C32(0xC5CEA54E), C32(0x4B6B8150), C32(0x16E71909), C32(0x7D632319), + C32(0x930573A0), C32(0xF34C63D1), C32(0xCAF914B4), C32(0xFDD6612C) +}; + +static const sph_u32 C_init_192[] = { + C32(0x61550878), C32(0x89EF2B75), C32(0xA1660C46), C32(0x7EF3855B), + C32(0x7297B58C), C32(0x1BC67793), C32(0x7FB1C723), C32(0xB66FC640), + C32(0x1A48B71C), C32(0xF0976D17), C32(0x088CE80A), C32(0xA454EDF3), + C32(0x1C096BF4), C32(0xAC76224B), C32(0x5215781C), C32(0xCD5D2669) +}; + +static const sph_u32 A_init_224[] = { + C32(0xA5201467), C32(0xA9B8D94A), C32(0xD4CED997), C32(0x68379D7B), + C32(0xA7FC73BA), C32(0xF1A2546B), C32(0x606782BF), C32(0xE0BCFD0F), + C32(0x2F25374E), C32(0x069A149F), C32(0x5E2DFF25), C32(0xFAECF061) +}; + +static const sph_u32 B_init_224[] = { + C32(0xEC9905D8), C32(0xF21850CF), C32(0xC0A746C8), C32(0x21DAD498), + C32(0x35156EEB), C32(0x088C97F2), C32(0x26303E40), C32(0x8A2D4FB5), + C32(0xFEEE44B6), C32(0x8A1E9573), C32(0x7B81111A), C32(0xCBC139F0), + C32(0xA3513861), C32(0x1D2C362E), C32(0x918C580E), C32(0xB58E1B9C) +}; + +static const sph_u32 C_init_224[] = { + C32(0xE4B573A1), C32(0x4C1A0880), C32(0x1E907C51), C32(0x04807EFD), + C32(0x3AD8CDE5), C32(0x16B21302), C32(0x02512C53), C32(0x2204CB18), + C32(0x99405F2D), C32(0xE5B648A1), C32(0x70AB1D43), C32(0xA10C25C2), + C32(0x16F1AC05), C32(0x38BBEB56), C32(0x9B01DC60), C32(0xB1096D83) +}; + +static const sph_u32 A_init_256[] = { + C32(0x52F84552), C32(0xE54B7999), C32(0x2D8EE3EC), C32(0xB9645191), + C32(0xE0078B86), C32(0xBB7C44C9), C32(0xD2B5C1CA), C32(0xB0D2EB8C), + C32(0x14CE5A45), C32(0x22AF50DC), C32(0xEFFDBC6B), C32(0xEB21B74A) +}; + +static const sph_u32 B_init_256[] = { + C32(0xB555C6EE), C32(0x3E710596), C32(0xA72A652F), C32(0x9301515F), + C32(0xDA28C1FA), C32(0x696FD868), C32(0x9CB6BF72), C32(0x0AFE4002), + C32(0xA6E03615), C32(0x5138C1D4), C32(0xBE216306), C32(0xB38B8890), + C32(0x3EA8B96B), C32(0x3299ACE4), C32(0x30924DD4), C32(0x55CB34A5) +}; + +static const sph_u32 C_init_256[] = { + C32(0xB405F031), C32(0xC4233EBA), C32(0xB3733979), C32(0xC0DD9D55), + C32(0xC51C28AE), C32(0xA327B8E1), C32(0x56C56167), C32(0xED614433), + C32(0x88B59D60), C32(0x60E2CEBA), C32(0x758B4B8B), C32(0x83E82A7F), + C32(0xBC968828), C32(0xE6E00BF7), C32(0xBA839E55), C32(0x9B491C60) +}; + +static const sph_u32 A_init_384[] = { + C32(0xC8FCA331), C32(0xE55C504E), C32(0x003EBF26), C32(0xBB6B8D83), + C32(0x7B0448C1), C32(0x41B82789), C32(0x0A7C9601), C32(0x8D659CFF), + C32(0xB6E2673E), C32(0xCA54C77B), C32(0x1460FD7E), C32(0x3FCB8F2D) +}; + +static const sph_u32 B_init_384[] = { + C32(0x527291FC), C32(0x2A16455F), C32(0x78E627E5), C32(0x944F169F), + C32(0x1CA6F016), C32(0xA854EA25), C32(0x8DB98ABE), C32(0xF2C62641), + C32(0x30117DCB), C32(0xCF5C4309), C32(0x93711A25), C32(0xF9F671B8), + C32(0xB01D2116), C32(0x333F4B89), C32(0xB285D165), C32(0x86829B36) +}; + +static const sph_u32 C_init_384[] = { + C32(0xF764B11A), C32(0x76172146), C32(0xCEF6934D), C32(0xC6D28399), + C32(0xFE095F61), C32(0x5E6018B4), C32(0x5048ECF5), C32(0x51353261), + C32(0x6E6E36DC), C32(0x63130DAD), C32(0xA9C69BD6), C32(0x1E90EA0C), + C32(0x7C35073B), C32(0x28D95E6D), C32(0xAA340E0D), C32(0xCB3DEE70) +}; + +static const sph_u32 A_init_512[] = { + C32(0x20728DFD), C32(0x46C0BD53), C32(0xE782B699), C32(0x55304632), + C32(0x71B4EF90), C32(0x0EA9E82C), C32(0xDBB930F1), C32(0xFAD06B8B), + C32(0xBE0CAE40), C32(0x8BD14410), C32(0x76D2ADAC), C32(0x28ACAB7F) +}; + +static const sph_u32 B_init_512[] = { + C32(0xC1099CB7), C32(0x07B385F3), C32(0xE7442C26), C32(0xCC8AD640), + C32(0xEB6F56C7), C32(0x1EA81AA9), C32(0x73B9D314), C32(0x1DE85D08), + C32(0x48910A5A), C32(0x893B22DB), C32(0xC5A0DF44), C32(0xBBC4324E), + C32(0x72D2F240), C32(0x75941D99), C32(0x6D8BDE82), C32(0xA1A7502B) +}; + +static const sph_u32 C_init_512[] = { + C32(0xD9BF68D1), C32(0x58BAD750), C32(0x56028CB2), C32(0x8134F359), + C32(0xB5D469D8), C32(0x941A8CC2), C32(0x418B2A6E), C32(0x04052780), + C32(0x7F07D787), C32(0x5194358F), C32(0x3C60D665), C32(0xBE97D79A), + C32(0x950C3434), C32(0xAED9A06D), C32(0x2537DC8D), C32(0x7CDB5969) +}; + +/* END -- automatically generated code. */ + +static void +shabal_init(void *cc, unsigned size) +{ + /* + * We have precomputed initial states for all the supported + * output bit lengths. + */ + const sph_u32 *A_init, *B_init, *C_init; + sph_shabal_context *sc; + + switch (size) { + case 192: + A_init = A_init_192; + B_init = B_init_192; + C_init = C_init_192; + break; + case 224: + A_init = A_init_224; + B_init = B_init_224; + C_init = C_init_224; + break; + case 256: + A_init = A_init_256; + B_init = B_init_256; + C_init = C_init_256; + break; + case 384: + A_init = A_init_384; + B_init = B_init_384; + C_init = C_init_384; + break; + case 512: + A_init = A_init_512; + B_init = B_init_512; + C_init = C_init_512; + break; + default: + return; + } + sc = cc; + memcpy(sc->A, A_init, sizeof sc->A); + memcpy(sc->B, B_init, sizeof sc->B); + memcpy(sc->C, C_init, sizeof sc->C); + sc->Wlow = 1; + sc->Whigh = 0; + sc->ptr = 0; +} + +static void +shabal_core(void *cc, const unsigned char *data, size_t len) +{ + sph_shabal_context *sc; + unsigned char *buf; + size_t ptr; + DECL_STATE + + sc = cc; + buf = sc->buf; + ptr = sc->ptr; + + /* + * We do not want to copy the state to local variables if the + * amount of data is less than what is needed to complete the + * current block. Note that it is anyway suboptimal to call + * this method many times for small chunks of data. + */ + 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 += clen; + len -= clen; + if (ptr == sizeof sc->buf) { + DECODE_BLOCK; + INPUT_BLOCK_ADD; + XOR_W; + APPLY_P; + INPUT_BLOCK_SUB; + SWAP_BC; + INCR_W; + ptr = 0; + } + } + WRITE_STATE(sc); + sc->ptr = ptr; +} + +static void +shabal_close(void *cc, unsigned ub, unsigned n, void *dst, unsigned size_words) +{ + sph_shabal_context *sc; + unsigned char *buf; + size_t ptr; + int i; + unsigned z; + union { + unsigned char tmp_out[64]; + sph_u32 dummy; + } u; + size_t out_len; + DECL_STATE + + sc = cc; + buf = sc->buf; + ptr = sc->ptr; + z = 0x80 >> n; + buf[ptr] = ((ub & -z) | z) & 0xFF; + memset(buf + ptr + 1, 0, (sizeof sc->buf) - (ptr + 1)); + READ_STATE(sc); + DECODE_BLOCK; + INPUT_BLOCK_ADD; + XOR_W; + APPLY_P; + for (i = 0; i < 3; i ++) { + SWAP_BC; + XOR_W; + APPLY_P; + } + + /* + * We just use our local variables; no need to go through + * the state structure. In order to share some code, we + * emit the relevant words into a temporary buffer, which + * we finally copy into the destination array. + */ + switch (size_words) { + case 16: + sph_enc32le_aligned(u.tmp_out + 0, B0); + sph_enc32le_aligned(u.tmp_out + 4, B1); + sph_enc32le_aligned(u.tmp_out + 8, B2); + sph_enc32le_aligned(u.tmp_out + 12, B3); + /* fall through */ + case 12: + sph_enc32le_aligned(u.tmp_out + 16, B4); + sph_enc32le_aligned(u.tmp_out + 20, B5); + sph_enc32le_aligned(u.tmp_out + 24, B6); + sph_enc32le_aligned(u.tmp_out + 28, B7); + /* fall through */ + case 8: + sph_enc32le_aligned(u.tmp_out + 32, B8); + /* fall through */ + case 7: + sph_enc32le_aligned(u.tmp_out + 36, B9); + /* fall through */ + case 6: + sph_enc32le_aligned(u.tmp_out + 40, BA); + sph_enc32le_aligned(u.tmp_out + 44, BB); + sph_enc32le_aligned(u.tmp_out + 48, BC); + sph_enc32le_aligned(u.tmp_out + 52, BD); + sph_enc32le_aligned(u.tmp_out + 56, BE); + sph_enc32le_aligned(u.tmp_out + 60, BF); + break; + default: + return; + } + out_len = size_words << 2; + memcpy(dst, u.tmp_out + (sizeof u.tmp_out) - out_len, out_len); + shabal_init(sc, size_words << 5); +} + +/* see sph_shabal.h */ +void +sph_shabal192_init(void *cc) +{ + shabal_init(cc, 192); +} + +/* see sph_shabal.h */ +void +sph_shabal192(void *cc, const void *data, size_t len) +{ + shabal_core(cc, data, len); +} + +/* see sph_shabal.h */ +void +sph_shabal192_close(void *cc, void *dst) +{ + shabal_close(cc, 0, 0, dst, 6); +} + +/* see sph_shabal.h */ +void +sph_shabal192_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shabal_close(cc, ub, n, dst, 6); +} + +/* see sph_shabal.h */ +void +sph_shabal224_init(void *cc) +{ + shabal_init(cc, 224); +} + +/* see sph_shabal.h */ +void +sph_shabal224(void *cc, const void *data, size_t len) +{ + shabal_core(cc, data, len); +} + +/* see sph_shabal.h */ +void +sph_shabal224_close(void *cc, void *dst) +{ + shabal_close(cc, 0, 0, dst, 7); +} + +/* see sph_shabal.h */ +void +sph_shabal224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shabal_close(cc, ub, n, dst, 7); +} + +/* see sph_shabal.h */ +void +sph_shabal256_init(void *cc) +{ + shabal_init(cc, 256); +} + +/* see sph_shabal.h */ +void +sph_shabal256(void *cc, const void *data, size_t len) +{ + shabal_core(cc, data, len); +} + +/* see sph_shabal.h */ +void +sph_shabal256_close(void *cc, void *dst) +{ + shabal_close(cc, 0, 0, dst, 8); +} + +/* see sph_shabal.h */ +void +sph_shabal256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shabal_close(cc, ub, n, dst, 8); +} + +/* see sph_shabal.h */ +void +sph_shabal384_init(void *cc) +{ + shabal_init(cc, 384); +} + +/* see sph_shabal.h */ +void +sph_shabal384(void *cc, const void *data, size_t len) +{ + shabal_core(cc, data, len); +} + +/* see sph_shabal.h */ +void +sph_shabal384_close(void *cc, void *dst) +{ + shabal_close(cc, 0, 0, dst, 12); +} + +/* see sph_shabal.h */ +void +sph_shabal384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shabal_close(cc, ub, n, dst, 12); +} + +/* see sph_shabal.h */ +void +sph_shabal512_init(void *cc) +{ + shabal_init(cc, 512); +} + +/* see sph_shabal.h */ +void +sph_shabal512(void *cc, const void *data, size_t len) +{ + shabal_core(cc, data, len); +} + +/* see sph_shabal.h */ +void +sph_shabal512_close(void *cc, void *dst) +{ + shabal_close(cc, 0, 0, dst, 16); +} + +/* see sph_shabal.h */ +void +sph_shabal512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shabal_close(cc, ub, n, dst, 16); +} +#ifdef __cplusplus +} +#endif diff --git a/src/shavite.c b/src/shavite.c new file mode 100644 index 0000000..85074f3 --- /dev/null +++ b/src/shavite.c @@ -0,0 +1,1764 @@ +/* $Id: shavite.c 227 2010-06-16 17:28:38Z tp $ */ +/* + * SHAvite-3 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 + */ + +#include +#include + +#include "sph_shavite.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_SHAVITE +#define SPH_SMALL_FOOTPRINT_SHAVITE 1 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +#define C32 SPH_C32 + +/* + * As of round 2 of the SHA-3 competition, the published reference + * implementation and test vectors are wrong, because they use + * big-endian AES tables while the internal decoding uses little-endian. + * The code below follows the specification. To turn it into a code + * which follows the reference implementation (the one called "BugFix" + * on the SHAvite-3 web site, published on Nov 23rd, 2009), comment out + * the code below (from the '#define AES_BIG_ENDIAN...' to the definition + * of the AES_ROUND_NOKEY macro) and replace it with the version which + * is commented out afterwards. + */ + +#define AES_BIG_ENDIAN 0 +#include "aes_helper.c" + +static const sph_u32 IV224[] = { + C32(0x6774F31C), C32(0x990AE210), C32(0xC87D4274), C32(0xC9546371), + C32(0x62B2AEA8), C32(0x4B5801D8), C32(0x1B702860), C32(0x842F3017) +}; + +static const sph_u32 IV256[] = { + C32(0x49BB3E47), C32(0x2674860D), C32(0xA8B392AC), C32(0x021AC4E6), + C32(0x409283CF), C32(0x620E5D86), C32(0x6D929DCB), C32(0x96CC2A8B) +}; + +static const sph_u32 IV384[] = { + C32(0x83DF1545), C32(0xF9AAEC13), C32(0xF4803CB0), C32(0x11FE1F47), + C32(0xDA6CD269), C32(0x4F53FCD7), C32(0x950529A2), C32(0x97908147), + C32(0xB0A4D7AF), C32(0x2B9132BF), C32(0x226E607D), C32(0x3C0F8D7C), + C32(0x487B3F0F), C32(0x04363E22), C32(0x0155C99C), C32(0xEC2E20D3) +}; + +static const sph_u32 IV512[] = { + C32(0x72FCCDD8), C32(0x79CA4727), C32(0x128A077B), C32(0x40D55AEC), + C32(0xD1901A06), C32(0x430AE307), C32(0xB29F5CD1), C32(0xDF07FBFC), + C32(0x8E45D73D), C32(0x681AB538), C32(0xBDE86578), C32(0xDD577E47), + C32(0xE275EADE), C32(0x502D9FCD), C32(0xB9357178), C32(0x022A4B9A) +}; + +#define AES_ROUND_NOKEY(x0, x1, x2, x3) do { \ + sph_u32 t0 = (x0); \ + sph_u32 t1 = (x1); \ + sph_u32 t2 = (x2); \ + sph_u32 t3 = (x3); \ + AES_ROUND_NOKEY_LE(t0, t1, t2, t3, x0, x1, x2, x3); \ + } while (0) + +/* + * This is the code needed to match the "reference implementation" as + * published on Nov 23rd, 2009, instead of the published specification. + * + +#define AES_BIG_ENDIAN 1 +#include "aes_helper.c" + +static const sph_u32 IV224[] = { + C32(0xC4C67795), C32(0xC0B1817F), C32(0xEAD88924), C32(0x1ABB1BB0), + C32(0xE0C29152), C32(0xBDE046BA), C32(0xAEEECF99), C32(0x58D509D8) +}; + +static const sph_u32 IV256[] = { + C32(0x3EECF551), C32(0xBF10819B), C32(0xE6DC8559), C32(0xF3E23FD5), + C32(0x431AEC73), C32(0x79E3F731), C32(0x98325F05), C32(0xA92A31F1) +}; + +static const sph_u32 IV384[] = { + C32(0x71F48510), C32(0xA903A8AC), C32(0xFE3216DD), C32(0x0B2D2AD4), + C32(0x6672900A), C32(0x41032819), C32(0x15A7D780), C32(0xB3CAB8D9), + C32(0x34EF4711), C32(0xDE019FE8), C32(0x4D674DC4), C32(0xE056D96B), + C32(0xA35C016B), C32(0xDD903BA7), C32(0x8C1B09B4), C32(0x2C3E9F25) +}; + +static const sph_u32 IV512[] = { + C32(0xD5652B63), C32(0x25F1E6EA), C32(0xB18F48FA), C32(0xA1EE3A47), + C32(0xC8B67B07), C32(0xBDCE48D3), C32(0xE3937B78), C32(0x05DB5186), + C32(0x613BE326), C32(0xA11FA303), C32(0x90C833D4), C32(0x79CEE316), + C32(0x1E1AF00F), C32(0x2829B165), C32(0x23B25F80), C32(0x21E11499) +}; + +#define AES_ROUND_NOKEY(x0, x1, x2, x3) do { \ + sph_u32 t0 = (x0); \ + sph_u32 t1 = (x1); \ + sph_u32 t2 = (x2); \ + sph_u32 t3 = (x3); \ + AES_ROUND_NOKEY_BE(t0, t1, t2, t3, x0, x1, x2, x3); \ + } while (0) + + */ + +#define KEY_EXPAND_ELT(k0, k1, k2, k3) do { \ + sph_u32 kt; \ + AES_ROUND_NOKEY(k1, k2, k3, k0); \ + kt = (k0); \ + (k0) = (k1); \ + (k1) = (k2); \ + (k2) = (k3); \ + (k3) = kt; \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_SHAVITE + +/* + * This function assumes that "msg" is aligned for 32-bit access. + */ +static void +c256(sph_shavite_small_context *sc, const void *msg) +{ + sph_u32 p0, p1, p2, p3, p4, p5, p6, p7; + sph_u32 rk[144]; + size_t u; + int r, s; + +#if SPH_LITTLE_ENDIAN + memcpy(rk, msg, 64); +#else + for (u = 0; u < 16; u += 4) { + rk[u + 0] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 0); + rk[u + 1] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 4); + rk[u + 2] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 8); + rk[u + 3] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 12); + } +#endif + u = 16; + for (r = 0; r < 4; r ++) { + for (s = 0; s < 2; s ++) { + sph_u32 x0, x1, x2, x3; + + x0 = rk[u - 15]; + x1 = rk[u - 14]; + x2 = rk[u - 13]; + x3 = rk[u - 16]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk[u + 0] = x0 ^ rk[u - 4]; + rk[u + 1] = x1 ^ rk[u - 3]; + rk[u + 2] = x2 ^ rk[u - 2]; + rk[u + 3] = x3 ^ rk[u - 1]; + if (u == 16) { + rk[ 16] ^= sc->count0; + rk[ 17] ^= SPH_T32(~sc->count1); + } else if (u == 56) { + rk[ 57] ^= sc->count1; + rk[ 58] ^= SPH_T32(~sc->count0); + } + u += 4; + + x0 = rk[u - 15]; + x1 = rk[u - 14]; + x2 = rk[u - 13]; + x3 = rk[u - 16]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk[u + 0] = x0 ^ rk[u - 4]; + rk[u + 1] = x1 ^ rk[u - 3]; + rk[u + 2] = x2 ^ rk[u - 2]; + rk[u + 3] = x3 ^ rk[u - 1]; + if (u == 84) { + rk[ 86] ^= sc->count1; + rk[ 87] ^= SPH_T32(~sc->count0); + } else if (u == 124) { + rk[124] ^= sc->count0; + rk[127] ^= SPH_T32(~sc->count1); + } + u += 4; + } + for (s = 0; s < 4; s ++) { + rk[u + 0] = rk[u - 16] ^ rk[u - 3]; + rk[u + 1] = rk[u - 15] ^ rk[u - 2]; + rk[u + 2] = rk[u - 14] ^ rk[u - 1]; + rk[u + 3] = rk[u - 13] ^ rk[u - 0]; + u += 4; + } + } + + p0 = sc->h[0x0]; + p1 = sc->h[0x1]; + p2 = sc->h[0x2]; + p3 = sc->h[0x3]; + p4 = sc->h[0x4]; + p5 = sc->h[0x5]; + p6 = sc->h[0x6]; + p7 = sc->h[0x7]; + u = 0; + for (r = 0; r < 6; r ++) { + sph_u32 x0, x1, x2, x3; + + x0 = p4 ^ rk[u ++]; + x1 = p5 ^ rk[u ++]; + x2 = p6 ^ rk[u ++]; + x3 = p7 ^ rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + x0 ^= rk[u ++]; + x1 ^= rk[u ++]; + x2 ^= rk[u ++]; + x3 ^= rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + x0 ^= rk[u ++]; + x1 ^= rk[u ++]; + x2 ^= rk[u ++]; + x3 ^= rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + + x0 = p0 ^ rk[u ++]; + x1 = p1 ^ rk[u ++]; + x2 = p2 ^ rk[u ++]; + x3 = p3 ^ rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + x0 ^= rk[u ++]; + x1 ^= rk[u ++]; + x2 ^= rk[u ++]; + x3 ^= rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + x0 ^= rk[u ++]; + x1 ^= rk[u ++]; + x2 ^= rk[u ++]; + x3 ^= rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + } + sc->h[0x0] ^= p0; + sc->h[0x1] ^= p1; + sc->h[0x2] ^= p2; + sc->h[0x3] ^= p3; + sc->h[0x4] ^= p4; + sc->h[0x5] ^= p5; + sc->h[0x6] ^= p6; + sc->h[0x7] ^= p7; +} + +#else + +/* + * This function assumes that "msg" is aligned for 32-bit access. + */ +static void +c256(sph_shavite_small_context *sc, const void *msg) +{ + sph_u32 p0, p1, p2, p3, p4, p5, p6, p7; + sph_u32 x0, x1, x2, x3; + sph_u32 rk0, rk1, rk2, rk3, rk4, rk5, rk6, rk7; + sph_u32 rk8, rk9, rkA, rkB, rkC, rkD, rkE, rkF; + + p0 = sc->h[0x0]; + p1 = sc->h[0x1]; + p2 = sc->h[0x2]; + p3 = sc->h[0x3]; + p4 = sc->h[0x4]; + p5 = sc->h[0x5]; + p6 = sc->h[0x6]; + p7 = sc->h[0x7]; + /* round 0 */ + rk0 = sph_dec32le_aligned((const unsigned char *)msg + 0); + x0 = p4 ^ rk0; + rk1 = sph_dec32le_aligned((const unsigned char *)msg + 4); + x1 = p5 ^ rk1; + rk2 = sph_dec32le_aligned((const unsigned char *)msg + 8); + x2 = p6 ^ rk2; + rk3 = sph_dec32le_aligned((const unsigned char *)msg + 12); + x3 = p7 ^ rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk4 = sph_dec32le_aligned((const unsigned char *)msg + 16); + x0 ^= rk4; + rk5 = sph_dec32le_aligned((const unsigned char *)msg + 20); + x1 ^= rk5; + rk6 = sph_dec32le_aligned((const unsigned char *)msg + 24); + x2 ^= rk6; + rk7 = sph_dec32le_aligned((const unsigned char *)msg + 28); + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk8 = sph_dec32le_aligned((const unsigned char *)msg + 32); + x0 ^= rk8; + rk9 = sph_dec32le_aligned((const unsigned char *)msg + 36); + x1 ^= rk9; + rkA = sph_dec32le_aligned((const unsigned char *)msg + 40); + x2 ^= rkA; + rkB = sph_dec32le_aligned((const unsigned char *)msg + 44); + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 1 */ + rkC = sph_dec32le_aligned((const unsigned char *)msg + 48); + x0 = p0 ^ rkC; + rkD = sph_dec32le_aligned((const unsigned char *)msg + 52); + x1 = p1 ^ rkD; + rkE = sph_dec32le_aligned((const unsigned char *)msg + 56); + x2 = p2 ^ rkE; + rkF = sph_dec32le_aligned((const unsigned char *)msg + 60); + x3 = p3 ^ rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0, rk1, rk2, rk3); + rk0 ^= rkC ^ sc->count0; + rk1 ^= rkD ^ SPH_T32(~sc->count1); + rk2 ^= rkE; + rk3 ^= rkF; + x0 ^= rk0; + x1 ^= rk1; + x2 ^= rk2; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk4, rk5, rk6, rk7); + rk4 ^= rk0; + rk5 ^= rk1; + rk6 ^= rk2; + rk7 ^= rk3; + x0 ^= rk4; + x1 ^= rk5; + x2 ^= rk6; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 2 */ + KEY_EXPAND_ELT(rk8, rk9, rkA, rkB); + rk8 ^= rk4; + rk9 ^= rk5; + rkA ^= rk6; + rkB ^= rk7; + x0 = p4 ^ rk8; + x1 = p5 ^ rk9; + x2 = p6 ^ rkA; + x3 = p7 ^ rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rkC, rkD, rkE, rkF); + rkC ^= rk8; + rkD ^= rk9; + rkE ^= rkA; + rkF ^= rkB; + x0 ^= rkC; + x1 ^= rkD; + x2 ^= rkE; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0 ^= rkD; + x0 ^= rk0; + rk1 ^= rkE; + x1 ^= rk1; + rk2 ^= rkF; + x2 ^= rk2; + rk3 ^= rk0; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 3 */ + rk4 ^= rk1; + x0 = p0 ^ rk4; + rk5 ^= rk2; + x1 = p1 ^ rk5; + rk6 ^= rk3; + x2 = p2 ^ rk6; + rk7 ^= rk4; + x3 = p3 ^ rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk8 ^= rk5; + x0 ^= rk8; + rk9 ^= rk6; + x1 ^= rk9; + rkA ^= rk7; + x2 ^= rkA; + rkB ^= rk8; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rkC ^= rk9; + x0 ^= rkC; + rkD ^= rkA; + x1 ^= rkD; + rkE ^= rkB; + x2 ^= rkE; + rkF ^= rkC; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 4 */ + KEY_EXPAND_ELT(rk0, rk1, rk2, rk3); + rk0 ^= rkC; + rk1 ^= rkD; + rk2 ^= rkE; + rk3 ^= rkF; + x0 = p4 ^ rk0; + x1 = p5 ^ rk1; + x2 = p6 ^ rk2; + x3 = p7 ^ rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk4, rk5, rk6, rk7); + rk4 ^= rk0; + rk5 ^= rk1; + rk6 ^= rk2; + rk7 ^= rk3; + x0 ^= rk4; + x1 ^= rk5; + x2 ^= rk6; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk8, rk9, rkA, rkB); + rk8 ^= rk4; + rk9 ^= rk5 ^ sc->count1; + rkA ^= rk6 ^ SPH_T32(~sc->count0); + rkB ^= rk7; + x0 ^= rk8; + x1 ^= rk9; + x2 ^= rkA; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 5 */ + KEY_EXPAND_ELT(rkC, rkD, rkE, rkF); + rkC ^= rk8; + rkD ^= rk9; + rkE ^= rkA; + rkF ^= rkB; + x0 = p0 ^ rkC; + x1 = p1 ^ rkD; + x2 = p2 ^ rkE; + x3 = p3 ^ rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0 ^= rkD; + x0 ^= rk0; + rk1 ^= rkE; + x1 ^= rk1; + rk2 ^= rkF; + x2 ^= rk2; + rk3 ^= rk0; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk4 ^= rk1; + x0 ^= rk4; + rk5 ^= rk2; + x1 ^= rk5; + rk6 ^= rk3; + x2 ^= rk6; + rk7 ^= rk4; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 6 */ + rk8 ^= rk5; + x0 = p4 ^ rk8; + rk9 ^= rk6; + x1 = p5 ^ rk9; + rkA ^= rk7; + x2 = p6 ^ rkA; + rkB ^= rk8; + x3 = p7 ^ rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rkC ^= rk9; + x0 ^= rkC; + rkD ^= rkA; + x1 ^= rkD; + rkE ^= rkB; + x2 ^= rkE; + rkF ^= rkC; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0, rk1, rk2, rk3); + rk0 ^= rkC; + rk1 ^= rkD; + rk2 ^= rkE; + rk3 ^= rkF; + x0 ^= rk0; + x1 ^= rk1; + x2 ^= rk2; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 7 */ + KEY_EXPAND_ELT(rk4, rk5, rk6, rk7); + rk4 ^= rk0; + rk5 ^= rk1; + rk6 ^= rk2 ^ sc->count1; + rk7 ^= rk3 ^ SPH_T32(~sc->count0); + x0 = p0 ^ rk4; + x1 = p1 ^ rk5; + x2 = p2 ^ rk6; + x3 = p3 ^ rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk8, rk9, rkA, rkB); + rk8 ^= rk4; + rk9 ^= rk5; + rkA ^= rk6; + rkB ^= rk7; + x0 ^= rk8; + x1 ^= rk9; + x2 ^= rkA; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rkC, rkD, rkE, rkF); + rkC ^= rk8; + rkD ^= rk9; + rkE ^= rkA; + rkF ^= rkB; + x0 ^= rkC; + x1 ^= rkD; + x2 ^= rkE; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 8 */ + rk0 ^= rkD; + x0 = p4 ^ rk0; + rk1 ^= rkE; + x1 = p5 ^ rk1; + rk2 ^= rkF; + x2 = p6 ^ rk2; + rk3 ^= rk0; + x3 = p7 ^ rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk4 ^= rk1; + x0 ^= rk4; + rk5 ^= rk2; + x1 ^= rk5; + rk6 ^= rk3; + x2 ^= rk6; + rk7 ^= rk4; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk8 ^= rk5; + x0 ^= rk8; + rk9 ^= rk6; + x1 ^= rk9; + rkA ^= rk7; + x2 ^= rkA; + rkB ^= rk8; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 9 */ + rkC ^= rk9; + x0 = p0 ^ rkC; + rkD ^= rkA; + x1 = p1 ^ rkD; + rkE ^= rkB; + x2 = p2 ^ rkE; + rkF ^= rkC; + x3 = p3 ^ rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0, rk1, rk2, rk3); + rk0 ^= rkC; + rk1 ^= rkD; + rk2 ^= rkE; + rk3 ^= rkF; + x0 ^= rk0; + x1 ^= rk1; + x2 ^= rk2; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk4, rk5, rk6, rk7); + rk4 ^= rk0; + rk5 ^= rk1; + rk6 ^= rk2; + rk7 ^= rk3; + x0 ^= rk4; + x1 ^= rk5; + x2 ^= rk6; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 10 */ + KEY_EXPAND_ELT(rk8, rk9, rkA, rkB); + rk8 ^= rk4; + rk9 ^= rk5; + rkA ^= rk6; + rkB ^= rk7; + x0 = p4 ^ rk8; + x1 = p5 ^ rk9; + x2 = p6 ^ rkA; + x3 = p7 ^ rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rkC, rkD, rkE, rkF); + rkC ^= rk8 ^ sc->count0; + rkD ^= rk9; + rkE ^= rkA; + rkF ^= rkB ^ SPH_T32(~sc->count1); + x0 ^= rkC; + x1 ^= rkD; + x2 ^= rkE; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0 ^= rkD; + x0 ^= rk0; + rk1 ^= rkE; + x1 ^= rk1; + rk2 ^= rkF; + x2 ^= rk2; + rk3 ^= rk0; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 11 */ + rk4 ^= rk1; + x0 = p0 ^ rk4; + rk5 ^= rk2; + x1 = p1 ^ rk5; + rk6 ^= rk3; + x2 = p2 ^ rk6; + rk7 ^= rk4; + x3 = p3 ^ rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk8 ^= rk5; + x0 ^= rk8; + rk9 ^= rk6; + x1 ^= rk9; + rkA ^= rk7; + x2 ^= rkA; + rkB ^= rk8; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rkC ^= rk9; + x0 ^= rkC; + rkD ^= rkA; + x1 ^= rkD; + rkE ^= rkB; + x2 ^= rkE; + rkF ^= rkC; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + sc->h[0x0] ^= p0; + sc->h[0x1] ^= p1; + sc->h[0x2] ^= p2; + sc->h[0x3] ^= p3; + sc->h[0x4] ^= p4; + sc->h[0x5] ^= p5; + sc->h[0x6] ^= p6; + sc->h[0x7] ^= p7; +} + +#endif + +#if SPH_SMALL_FOOTPRINT_SHAVITE + +/* + * This function assumes that "msg" is aligned for 32-bit access. + */ +static void +c512(sph_shavite_big_context *sc, const void *msg) +{ + sph_u32 p0, p1, p2, p3, p4, p5, p6, p7; + sph_u32 p8, p9, pA, pB, pC, pD, pE, pF; + sph_u32 rk[448]; + size_t u; + int r, s; + +#if SPH_LITTLE_ENDIAN + memcpy(rk, msg, 128); +#else + for (u = 0; u < 32; u += 4) { + rk[u + 0] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 0); + rk[u + 1] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 4); + rk[u + 2] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 8); + rk[u + 3] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 12); + } +#endif + u = 32; + for (;;) { + for (s = 0; s < 4; s ++) { + sph_u32 x0, x1, x2, x3; + + x0 = rk[u - 31]; + x1 = rk[u - 30]; + x2 = rk[u - 29]; + x3 = rk[u - 32]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk[u + 0] = x0 ^ rk[u - 4]; + rk[u + 1] = x1 ^ rk[u - 3]; + rk[u + 2] = x2 ^ rk[u - 2]; + rk[u + 3] = x3 ^ rk[u - 1]; + if (u == 32) { + rk[ 32] ^= sc->count0; + rk[ 33] ^= sc->count1; + rk[ 34] ^= sc->count2; + rk[ 35] ^= SPH_T32(~sc->count3); + } else if (u == 440) { + rk[440] ^= sc->count1; + rk[441] ^= sc->count0; + rk[442] ^= sc->count3; + rk[443] ^= SPH_T32(~sc->count2); + } + u += 4; + + x0 = rk[u - 31]; + x1 = rk[u - 30]; + x2 = rk[u - 29]; + x3 = rk[u - 32]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk[u + 0] = x0 ^ rk[u - 4]; + rk[u + 1] = x1 ^ rk[u - 3]; + rk[u + 2] = x2 ^ rk[u - 2]; + rk[u + 3] = x3 ^ rk[u - 1]; + if (u == 164) { + rk[164] ^= sc->count3; + rk[165] ^= sc->count2; + rk[166] ^= sc->count1; + rk[167] ^= SPH_T32(~sc->count0); + } else if (u == 316) { + rk[316] ^= sc->count2; + rk[317] ^= sc->count3; + rk[318] ^= sc->count0; + rk[319] ^= SPH_T32(~sc->count1); + } + u += 4; + } + if (u == 448) + break; + for (s = 0; s < 8; s ++) { + rk[u + 0] = rk[u - 32] ^ rk[u - 7]; + rk[u + 1] = rk[u - 31] ^ rk[u - 6]; + rk[u + 2] = rk[u - 30] ^ rk[u - 5]; + rk[u + 3] = rk[u - 29] ^ rk[u - 4]; + u += 4; + } + } + + p0 = sc->h[0x0]; + p1 = sc->h[0x1]; + p2 = sc->h[0x2]; + p3 = sc->h[0x3]; + p4 = sc->h[0x4]; + p5 = sc->h[0x5]; + p6 = sc->h[0x6]; + p7 = sc->h[0x7]; + p8 = sc->h[0x8]; + p9 = sc->h[0x9]; + pA = sc->h[0xA]; + pB = sc->h[0xB]; + pC = sc->h[0xC]; + pD = sc->h[0xD]; + pE = sc->h[0xE]; + pF = sc->h[0xF]; + u = 0; + for (r = 0; r < 14; r ++) { +#define C512_ELT(l0, l1, l2, l3, r0, r1, r2, r3) do { \ + sph_u32 x0, x1, x2, x3; \ + x0 = r0 ^ rk[u ++]; \ + x1 = r1 ^ rk[u ++]; \ + x2 = r2 ^ rk[u ++]; \ + x3 = r3 ^ rk[u ++]; \ + AES_ROUND_NOKEY(x0, x1, x2, x3); \ + x0 ^= rk[u ++]; \ + x1 ^= rk[u ++]; \ + x2 ^= rk[u ++]; \ + x3 ^= rk[u ++]; \ + AES_ROUND_NOKEY(x0, x1, x2, x3); \ + x0 ^= rk[u ++]; \ + x1 ^= rk[u ++]; \ + x2 ^= rk[u ++]; \ + x3 ^= rk[u ++]; \ + AES_ROUND_NOKEY(x0, x1, x2, x3); \ + x0 ^= rk[u ++]; \ + x1 ^= rk[u ++]; \ + x2 ^= rk[u ++]; \ + x3 ^= rk[u ++]; \ + AES_ROUND_NOKEY(x0, x1, x2, x3); \ + l0 ^= x0; \ + l1 ^= x1; \ + l2 ^= x2; \ + l3 ^= x3; \ + } while (0) + +#define WROT(a, b, c, d) do { \ + sph_u32 t = d; \ + d = c; \ + c = b; \ + b = a; \ + a = t; \ + } while (0) + + C512_ELT(p0, p1, p2, p3, p4, p5, p6, p7); + C512_ELT(p8, p9, pA, pB, pC, pD, pE, pF); + + WROT(p0, p4, p8, pC); + WROT(p1, p5, p9, pD); + WROT(p2, p6, pA, pE); + WROT(p3, p7, pB, pF); + +#undef C512_ELT +#undef WROT + } + sc->h[0x0] ^= p0; + sc->h[0x1] ^= p1; + sc->h[0x2] ^= p2; + sc->h[0x3] ^= p3; + sc->h[0x4] ^= p4; + sc->h[0x5] ^= p5; + sc->h[0x6] ^= p6; + sc->h[0x7] ^= p7; + sc->h[0x8] ^= p8; + sc->h[0x9] ^= p9; + sc->h[0xA] ^= pA; + sc->h[0xB] ^= pB; + sc->h[0xC] ^= pC; + sc->h[0xD] ^= pD; + sc->h[0xE] ^= pE; + sc->h[0xF] ^= pF; +} + +#else + +/* + * This function assumes that "msg" is aligned for 32-bit access. + */ +static void +c512(sph_shavite_big_context *sc, const void *msg) +{ + sph_u32 p0, p1, p2, p3, p4, p5, p6, p7; + sph_u32 p8, p9, pA, pB, pC, pD, pE, pF; + sph_u32 x0, x1, x2, x3; + sph_u32 rk00, rk01, rk02, rk03, rk04, rk05, rk06, rk07; + sph_u32 rk08, rk09, rk0A, rk0B, rk0C, rk0D, rk0E, rk0F; + sph_u32 rk10, rk11, rk12, rk13, rk14, rk15, rk16, rk17; + sph_u32 rk18, rk19, rk1A, rk1B, rk1C, rk1D, rk1E, rk1F; + int r; + + p0 = sc->h[0x0]; + p1 = sc->h[0x1]; + p2 = sc->h[0x2]; + p3 = sc->h[0x3]; + p4 = sc->h[0x4]; + p5 = sc->h[0x5]; + p6 = sc->h[0x6]; + p7 = sc->h[0x7]; + p8 = sc->h[0x8]; + p9 = sc->h[0x9]; + pA = sc->h[0xA]; + pB = sc->h[0xB]; + pC = sc->h[0xC]; + pD = sc->h[0xD]; + pE = sc->h[0xE]; + pF = sc->h[0xF]; + /* round 0 */ + rk00 = sph_dec32le_aligned((const unsigned char *)msg + 0); + x0 = p4 ^ rk00; + rk01 = sph_dec32le_aligned((const unsigned char *)msg + 4); + x1 = p5 ^ rk01; + rk02 = sph_dec32le_aligned((const unsigned char *)msg + 8); + x2 = p6 ^ rk02; + rk03 = sph_dec32le_aligned((const unsigned char *)msg + 12); + x3 = p7 ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk04 = sph_dec32le_aligned((const unsigned char *)msg + 16); + x0 ^= rk04; + rk05 = sph_dec32le_aligned((const unsigned char *)msg + 20); + x1 ^= rk05; + rk06 = sph_dec32le_aligned((const unsigned char *)msg + 24); + x2 ^= rk06; + rk07 = sph_dec32le_aligned((const unsigned char *)msg + 28); + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk08 = sph_dec32le_aligned((const unsigned char *)msg + 32); + x0 ^= rk08; + rk09 = sph_dec32le_aligned((const unsigned char *)msg + 36); + x1 ^= rk09; + rk0A = sph_dec32le_aligned((const unsigned char *)msg + 40); + x2 ^= rk0A; + rk0B = sph_dec32le_aligned((const unsigned char *)msg + 44); + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0C = sph_dec32le_aligned((const unsigned char *)msg + 48); + x0 ^= rk0C; + rk0D = sph_dec32le_aligned((const unsigned char *)msg + 52); + x1 ^= rk0D; + rk0E = sph_dec32le_aligned((const unsigned char *)msg + 56); + x2 ^= rk0E; + rk0F = sph_dec32le_aligned((const unsigned char *)msg + 60); + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + rk10 = sph_dec32le_aligned((const unsigned char *)msg + 64); + x0 = pC ^ rk10; + rk11 = sph_dec32le_aligned((const unsigned char *)msg + 68); + x1 = pD ^ rk11; + rk12 = sph_dec32le_aligned((const unsigned char *)msg + 72); + x2 = pE ^ rk12; + rk13 = sph_dec32le_aligned((const unsigned char *)msg + 76); + x3 = pF ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk14 = sph_dec32le_aligned((const unsigned char *)msg + 80); + x0 ^= rk14; + rk15 = sph_dec32le_aligned((const unsigned char *)msg + 84); + x1 ^= rk15; + rk16 = sph_dec32le_aligned((const unsigned char *)msg + 88); + x2 ^= rk16; + rk17 = sph_dec32le_aligned((const unsigned char *)msg + 92); + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk18 = sph_dec32le_aligned((const unsigned char *)msg + 96); + x0 ^= rk18; + rk19 = sph_dec32le_aligned((const unsigned char *)msg + 100); + x1 ^= rk19; + rk1A = sph_dec32le_aligned((const unsigned char *)msg + 104); + x2 ^= rk1A; + rk1B = sph_dec32le_aligned((const unsigned char *)msg + 108); + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk1C = sph_dec32le_aligned((const unsigned char *)msg + 112); + x0 ^= rk1C; + rk1D = sph_dec32le_aligned((const unsigned char *)msg + 116); + x1 ^= rk1D; + rk1E = sph_dec32le_aligned((const unsigned char *)msg + 120); + x2 ^= rk1E; + rk1F = sph_dec32le_aligned((const unsigned char *)msg + 124); + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p8 ^= x0; + p9 ^= x1; + pA ^= x2; + pB ^= x3; + + for (r = 0; r < 3; r ++) { + /* round 1, 5, 9 */ + KEY_EXPAND_ELT(rk00, rk01, rk02, rk03); + rk00 ^= rk1C; + rk01 ^= rk1D; + rk02 ^= rk1E; + rk03 ^= rk1F; + if (r == 0) { + rk00 ^= sc->count0; + rk01 ^= sc->count1; + rk02 ^= sc->count2; + rk03 ^= SPH_T32(~sc->count3); + } + x0 = p0 ^ rk00; + x1 = p1 ^ rk01; + x2 = p2 ^ rk02; + x3 = p3 ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk04, rk05, rk06, rk07); + rk04 ^= rk00; + rk05 ^= rk01; + rk06 ^= rk02; + rk07 ^= rk03; + if (r == 1) { + rk04 ^= sc->count3; + rk05 ^= sc->count2; + rk06 ^= sc->count1; + rk07 ^= SPH_T32(~sc->count0); + } + x0 ^= rk04; + x1 ^= rk05; + x2 ^= rk06; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk08, rk09, rk0A, rk0B); + rk08 ^= rk04; + rk09 ^= rk05; + rk0A ^= rk06; + rk0B ^= rk07; + x0 ^= rk08; + x1 ^= rk09; + x2 ^= rk0A; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0C, rk0D, rk0E, rk0F); + rk0C ^= rk08; + rk0D ^= rk09; + rk0E ^= rk0A; + rk0F ^= rk0B; + x0 ^= rk0C; + x1 ^= rk0D; + x2 ^= rk0E; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + pC ^= x0; + pD ^= x1; + pE ^= x2; + pF ^= x3; + KEY_EXPAND_ELT(rk10, rk11, rk12, rk13); + rk10 ^= rk0C; + rk11 ^= rk0D; + rk12 ^= rk0E; + rk13 ^= rk0F; + x0 = p8 ^ rk10; + x1 = p9 ^ rk11; + x2 = pA ^ rk12; + x3 = pB ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk14, rk15, rk16, rk17); + rk14 ^= rk10; + rk15 ^= rk11; + rk16 ^= rk12; + rk17 ^= rk13; + x0 ^= rk14; + x1 ^= rk15; + x2 ^= rk16; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk18, rk19, rk1A, rk1B); + rk18 ^= rk14; + rk19 ^= rk15; + rk1A ^= rk16; + rk1B ^= rk17; + x0 ^= rk18; + x1 ^= rk19; + x2 ^= rk1A; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk1C, rk1D, rk1E, rk1F); + rk1C ^= rk18; + rk1D ^= rk19; + rk1E ^= rk1A; + rk1F ^= rk1B; + if (r == 2) { + rk1C ^= sc->count2; + rk1D ^= sc->count3; + rk1E ^= sc->count0; + rk1F ^= SPH_T32(~sc->count1); + } + x0 ^= rk1C; + x1 ^= rk1D; + x2 ^= rk1E; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 2, 6, 10 */ + rk00 ^= rk19; + x0 = pC ^ rk00; + rk01 ^= rk1A; + x1 = pD ^ rk01; + rk02 ^= rk1B; + x2 = pE ^ rk02; + rk03 ^= rk1C; + x3 = pF ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk04 ^= rk1D; + x0 ^= rk04; + rk05 ^= rk1E; + x1 ^= rk05; + rk06 ^= rk1F; + x2 ^= rk06; + rk07 ^= rk00; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk08 ^= rk01; + x0 ^= rk08; + rk09 ^= rk02; + x1 ^= rk09; + rk0A ^= rk03; + x2 ^= rk0A; + rk0B ^= rk04; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0C ^= rk05; + x0 ^= rk0C; + rk0D ^= rk06; + x1 ^= rk0D; + rk0E ^= rk07; + x2 ^= rk0E; + rk0F ^= rk08; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p8 ^= x0; + p9 ^= x1; + pA ^= x2; + pB ^= x3; + rk10 ^= rk09; + x0 = p4 ^ rk10; + rk11 ^= rk0A; + x1 = p5 ^ rk11; + rk12 ^= rk0B; + x2 = p6 ^ rk12; + rk13 ^= rk0C; + x3 = p7 ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk14 ^= rk0D; + x0 ^= rk14; + rk15 ^= rk0E; + x1 ^= rk15; + rk16 ^= rk0F; + x2 ^= rk16; + rk17 ^= rk10; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk18 ^= rk11; + x0 ^= rk18; + rk19 ^= rk12; + x1 ^= rk19; + rk1A ^= rk13; + x2 ^= rk1A; + rk1B ^= rk14; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk1C ^= rk15; + x0 ^= rk1C; + rk1D ^= rk16; + x1 ^= rk1D; + rk1E ^= rk17; + x2 ^= rk1E; + rk1F ^= rk18; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 3, 7, 11 */ + KEY_EXPAND_ELT(rk00, rk01, rk02, rk03); + rk00 ^= rk1C; + rk01 ^= rk1D; + rk02 ^= rk1E; + rk03 ^= rk1F; + x0 = p8 ^ rk00; + x1 = p9 ^ rk01; + x2 = pA ^ rk02; + x3 = pB ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk04, rk05, rk06, rk07); + rk04 ^= rk00; + rk05 ^= rk01; + rk06 ^= rk02; + rk07 ^= rk03; + x0 ^= rk04; + x1 ^= rk05; + x2 ^= rk06; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk08, rk09, rk0A, rk0B); + rk08 ^= rk04; + rk09 ^= rk05; + rk0A ^= rk06; + rk0B ^= rk07; + x0 ^= rk08; + x1 ^= rk09; + x2 ^= rk0A; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0C, rk0D, rk0E, rk0F); + rk0C ^= rk08; + rk0D ^= rk09; + rk0E ^= rk0A; + rk0F ^= rk0B; + x0 ^= rk0C; + x1 ^= rk0D; + x2 ^= rk0E; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + KEY_EXPAND_ELT(rk10, rk11, rk12, rk13); + rk10 ^= rk0C; + rk11 ^= rk0D; + rk12 ^= rk0E; + rk13 ^= rk0F; + x0 = p0 ^ rk10; + x1 = p1 ^ rk11; + x2 = p2 ^ rk12; + x3 = p3 ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk14, rk15, rk16, rk17); + rk14 ^= rk10; + rk15 ^= rk11; + rk16 ^= rk12; + rk17 ^= rk13; + x0 ^= rk14; + x1 ^= rk15; + x2 ^= rk16; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk18, rk19, rk1A, rk1B); + rk18 ^= rk14; + rk19 ^= rk15; + rk1A ^= rk16; + rk1B ^= rk17; + x0 ^= rk18; + x1 ^= rk19; + x2 ^= rk1A; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk1C, rk1D, rk1E, rk1F); + rk1C ^= rk18; + rk1D ^= rk19; + rk1E ^= rk1A; + rk1F ^= rk1B; + x0 ^= rk1C; + x1 ^= rk1D; + x2 ^= rk1E; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + pC ^= x0; + pD ^= x1; + pE ^= x2; + pF ^= x3; + /* round 4, 8, 12 */ + rk00 ^= rk19; + x0 = p4 ^ rk00; + rk01 ^= rk1A; + x1 = p5 ^ rk01; + rk02 ^= rk1B; + x2 = p6 ^ rk02; + rk03 ^= rk1C; + x3 = p7 ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk04 ^= rk1D; + x0 ^= rk04; + rk05 ^= rk1E; + x1 ^= rk05; + rk06 ^= rk1F; + x2 ^= rk06; + rk07 ^= rk00; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk08 ^= rk01; + x0 ^= rk08; + rk09 ^= rk02; + x1 ^= rk09; + rk0A ^= rk03; + x2 ^= rk0A; + rk0B ^= rk04; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0C ^= rk05; + x0 ^= rk0C; + rk0D ^= rk06; + x1 ^= rk0D; + rk0E ^= rk07; + x2 ^= rk0E; + rk0F ^= rk08; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + rk10 ^= rk09; + x0 = pC ^ rk10; + rk11 ^= rk0A; + x1 = pD ^ rk11; + rk12 ^= rk0B; + x2 = pE ^ rk12; + rk13 ^= rk0C; + x3 = pF ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk14 ^= rk0D; + x0 ^= rk14; + rk15 ^= rk0E; + x1 ^= rk15; + rk16 ^= rk0F; + x2 ^= rk16; + rk17 ^= rk10; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk18 ^= rk11; + x0 ^= rk18; + rk19 ^= rk12; + x1 ^= rk19; + rk1A ^= rk13; + x2 ^= rk1A; + rk1B ^= rk14; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk1C ^= rk15; + x0 ^= rk1C; + rk1D ^= rk16; + x1 ^= rk1D; + rk1E ^= rk17; + x2 ^= rk1E; + rk1F ^= rk18; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p8 ^= x0; + p9 ^= x1; + pA ^= x2; + pB ^= x3; + } + /* round 13 */ + KEY_EXPAND_ELT(rk00, rk01, rk02, rk03); + rk00 ^= rk1C; + rk01 ^= rk1D; + rk02 ^= rk1E; + rk03 ^= rk1F; + x0 = p0 ^ rk00; + x1 = p1 ^ rk01; + x2 = p2 ^ rk02; + x3 = p3 ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk04, rk05, rk06, rk07); + rk04 ^= rk00; + rk05 ^= rk01; + rk06 ^= rk02; + rk07 ^= rk03; + x0 ^= rk04; + x1 ^= rk05; + x2 ^= rk06; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk08, rk09, rk0A, rk0B); + rk08 ^= rk04; + rk09 ^= rk05; + rk0A ^= rk06; + rk0B ^= rk07; + x0 ^= rk08; + x1 ^= rk09; + x2 ^= rk0A; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0C, rk0D, rk0E, rk0F); + rk0C ^= rk08; + rk0D ^= rk09; + rk0E ^= rk0A; + rk0F ^= rk0B; + x0 ^= rk0C; + x1 ^= rk0D; + x2 ^= rk0E; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + pC ^= x0; + pD ^= x1; + pE ^= x2; + pF ^= x3; + KEY_EXPAND_ELT(rk10, rk11, rk12, rk13); + rk10 ^= rk0C; + rk11 ^= rk0D; + rk12 ^= rk0E; + rk13 ^= rk0F; + x0 = p8 ^ rk10; + x1 = p9 ^ rk11; + x2 = pA ^ rk12; + x3 = pB ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk14, rk15, rk16, rk17); + rk14 ^= rk10; + rk15 ^= rk11; + rk16 ^= rk12; + rk17 ^= rk13; + x0 ^= rk14; + x1 ^= rk15; + x2 ^= rk16; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk18, rk19, rk1A, rk1B); + rk18 ^= rk14 ^ sc->count1; + rk19 ^= rk15 ^ sc->count0; + rk1A ^= rk16 ^ sc->count3; + rk1B ^= rk17 ^ SPH_T32(~sc->count2); + x0 ^= rk18; + x1 ^= rk19; + x2 ^= rk1A; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk1C, rk1D, rk1E, rk1F); + rk1C ^= rk18; + rk1D ^= rk19; + rk1E ^= rk1A; + rk1F ^= rk1B; + x0 ^= rk1C; + x1 ^= rk1D; + x2 ^= rk1E; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + sc->h[0x0] ^= p8; + sc->h[0x1] ^= p9; + sc->h[0x2] ^= pA; + sc->h[0x3] ^= pB; + sc->h[0x4] ^= pC; + sc->h[0x5] ^= pD; + sc->h[0x6] ^= pE; + sc->h[0x7] ^= pF; + sc->h[0x8] ^= p0; + sc->h[0x9] ^= p1; + sc->h[0xA] ^= p2; + sc->h[0xB] ^= p3; + sc->h[0xC] ^= p4; + sc->h[0xD] ^= p5; + sc->h[0xE] ^= p6; + sc->h[0xF] ^= p7; +} + +#endif + +static void +shavite_small_init(sph_shavite_small_context *sc, const sph_u32 *iv) +{ + memcpy(sc->h, iv, sizeof sc->h); + sc->ptr = 0; + sc->count0 = 0; + sc->count1 = 0; +} + +static void +shavite_small_core(sph_shavite_small_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + + buf = sc->buf; + ptr = sc->ptr; + 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; + ptr += clen; + len -= clen; + if (ptr == sizeof sc->buf) { + if ((sc->count0 = SPH_T32(sc->count0 + 512)) == 0) + sc->count1 = SPH_T32(sc->count1 + 1); + c256(sc, buf); + ptr = 0; + } + } + sc->ptr = ptr; +} + +static void +shavite_small_close(sph_shavite_small_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_size_w32) +{ + unsigned char *buf; + size_t ptr, u; + unsigned z; + sph_u32 count0, count1; + + buf = sc->buf; + ptr = sc->ptr; + count0 = (sc->count0 += (ptr << 3) + n); + count1 = sc->count1; + z = 0x80 >> n; + z = ((ub & -z) | z) & 0xFF; + if (ptr == 0 && n == 0) { + buf[0] = 0x80; + memset(buf + 1, 0, 53); + sc->count0 = sc->count1 = 0; + } else if (ptr < 54) { + buf[ptr ++] = z; + memset(buf + ptr, 0, 54 - ptr); + } else { + buf[ptr ++] = z; + memset(buf + ptr, 0, 64 - ptr); + c256(sc, buf); + memset(buf, 0, 54); + sc->count0 = sc->count1 = 0; + } + sph_enc32le(buf + 54, count0); + sph_enc32le(buf + 58, count1); + buf[62] = out_size_w32 << 5; + buf[63] = out_size_w32 >> 3; + c256(sc, buf); + for (u = 0; u < out_size_w32; u ++) + sph_enc32le((unsigned char *)dst + (u << 2), sc->h[u]); +} + +static void +shavite_big_init(sph_shavite_big_context *sc, const sph_u32 *iv) +{ + memcpy(sc->h, iv, sizeof sc->h); + sc->ptr = 0; + sc->count0 = 0; + sc->count1 = 0; + sc->count2 = 0; + sc->count3 = 0; +} + +static void +shavite_big_core(sph_shavite_big_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + + buf = sc->buf; + ptr = sc->ptr; + 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; + ptr += clen; + len -= clen; + if (ptr == sizeof sc->buf) { + if ((sc->count0 = SPH_T32(sc->count0 + 1024)) == 0) { + sc->count1 = SPH_T32(sc->count1 + 1); + if (sc->count1 == 0) { + sc->count2 = SPH_T32(sc->count2 + 1); + if (sc->count2 == 0) { + sc->count3 = SPH_T32( + sc->count3 + 1); + } + } + } + c512(sc, buf); + ptr = 0; + } + } + sc->ptr = ptr; +} + +static void +shavite_big_close(sph_shavite_big_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_size_w32) +{ + unsigned char *buf; + size_t ptr, u; + unsigned z; + sph_u32 count0, count1, count2, count3; + + buf = sc->buf; + ptr = sc->ptr; + count0 = (sc->count0 += (ptr << 3) + n); + count1 = sc->count1; + count2 = sc->count2; + count3 = sc->count3; + z = 0x80 >> n; + z = ((ub & -z) | z) & 0xFF; + if (ptr == 0 && n == 0) { + buf[0] = 0x80; + memset(buf + 1, 0, 109); + sc->count0 = sc->count1 = sc->count2 = sc->count3 = 0; + } else if (ptr < 110) { + buf[ptr ++] = z; + memset(buf + ptr, 0, 110 - ptr); + } else { + buf[ptr ++] = z; + memset(buf + ptr, 0, 128 - ptr); + c512(sc, buf); + memset(buf, 0, 110); + sc->count0 = sc->count1 = sc->count2 = sc->count3 = 0; + } + sph_enc32le(buf + 110, count0); + sph_enc32le(buf + 114, count1); + sph_enc32le(buf + 118, count2); + sph_enc32le(buf + 122, count3); + buf[126] = out_size_w32 << 5; + buf[127] = out_size_w32 >> 3; + c512(sc, buf); + for (u = 0; u < out_size_w32; u ++) + sph_enc32le((unsigned char *)dst + (u << 2), sc->h[u]); +} + +/* see sph_shavite.h */ +void +sph_shavite224_init(void *cc) +{ + shavite_small_init(cc, IV224); +} + +/* see sph_shavite.h */ +void +sph_shavite224(void *cc, const void *data, size_t len) +{ + shavite_small_core(cc, data, len); +} + +/* see sph_shavite.h */ +void +sph_shavite224_close(void *cc, void *dst) +{ + shavite_small_close(cc, 0, 0, dst, 7); + shavite_small_init(cc, IV224); +} + +/* see sph_shavite.h */ +void +sph_shavite224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shavite_small_close(cc, ub, n, dst, 7); + shavite_small_init(cc, IV224); +} + +/* see sph_shavite.h */ +void +sph_shavite256_init(void *cc) +{ + shavite_small_init(cc, IV256); +} + +/* see sph_shavite.h */ +void +sph_shavite256(void *cc, const void *data, size_t len) +{ + shavite_small_core(cc, data, len); +} + +/* see sph_shavite.h */ +void +sph_shavite256_close(void *cc, void *dst) +{ + shavite_small_close(cc, 0, 0, dst, 8); + shavite_small_init(cc, IV256); +} + +/* see sph_shavite.h */ +void +sph_shavite256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shavite_small_close(cc, ub, n, dst, 8); + shavite_small_init(cc, IV256); +} + +/* see sph_shavite.h */ +void +sph_shavite384_init(void *cc) +{ + shavite_big_init(cc, IV384); +} + +/* see sph_shavite.h */ +void +sph_shavite384(void *cc, const void *data, size_t len) +{ + shavite_big_core(cc, data, len); +} + +/* see sph_shavite.h */ +void +sph_shavite384_close(void *cc, void *dst) +{ + shavite_big_close(cc, 0, 0, dst, 12); + shavite_big_init(cc, IV384); +} + +/* see sph_shavite.h */ +void +sph_shavite384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shavite_big_close(cc, ub, n, dst, 12); + shavite_big_init(cc, IV384); +} + +/* see sph_shavite.h */ +void +sph_shavite512_init(void *cc) +{ + shavite_big_init(cc, IV512); +} + +/* see sph_shavite.h */ +void +sph_shavite512(void *cc, const void *data, size_t len) +{ + shavite_big_core(cc, data, len); +} + +/* see sph_shavite.h */ +void +sph_shavite512_close(void *cc, void *dst) +{ + shavite_big_close(cc, 0, 0, dst, 16); + shavite_big_init(cc, IV512); +} + +/* see sph_shavite.h */ +void +sph_shavite512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shavite_big_close(cc, ub, n, dst, 16); + shavite_big_init(cc, IV512); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/simd.c b/src/simd.c new file mode 100644 index 0000000..2c80626 --- /dev/null +++ b/src/simd.c @@ -0,0 +1,1799 @@ +/* $Id: simd.c 227 2010-06-16 17:28:38Z tp $ */ +/* + * SIMD 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 + */ + +#include +#include +#include + +#include "sph_simd.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_SIMD +#define SPH_SMALL_FOOTPRINT_SIMD 1 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +typedef sph_u32 u32; +typedef sph_s32 s32; +#define C32 SPH_C32 +#define T32 SPH_T32 +#define ROL32 SPH_ROTL32 + +#define XCAT(x, y) XCAT_(x, y) +#define XCAT_(x, y) x ## y + +/* + * The powers of 41 modulo 257. We use exponents from 0 to 255, inclusive. + */ +static const s32 alpha_tab[] = { + 1, 41, 139, 45, 46, 87, 226, 14, 60, 147, 116, 130, + 190, 80, 196, 69, 2, 82, 21, 90, 92, 174, 195, 28, + 120, 37, 232, 3, 123, 160, 135, 138, 4, 164, 42, 180, + 184, 91, 133, 56, 240, 74, 207, 6, 246, 63, 13, 19, + 8, 71, 84, 103, 111, 182, 9, 112, 223, 148, 157, 12, + 235, 126, 26, 38, 16, 142, 168, 206, 222, 107, 18, 224, + 189, 39, 57, 24, 213, 252, 52, 76, 32, 27, 79, 155, + 187, 214, 36, 191, 121, 78, 114, 48, 169, 247, 104, 152, + 64, 54, 158, 53, 117, 171, 72, 125, 242, 156, 228, 96, + 81, 237, 208, 47, 128, 108, 59, 106, 234, 85, 144, 250, + 227, 55, 199, 192, 162, 217, 159, 94, 256, 216, 118, 212, + 211, 170, 31, 243, 197, 110, 141, 127, 67, 177, 61, 188, + 255, 175, 236, 167, 165, 83, 62, 229, 137, 220, 25, 254, + 134, 97, 122, 119, 253, 93, 215, 77, 73, 166, 124, 201, + 17, 183, 50, 251, 11, 194, 244, 238, 249, 186, 173, 154, + 146, 75, 248, 145, 34, 109, 100, 245, 22, 131, 231, 219, + 241, 115, 89, 51, 35, 150, 239, 33, 68, 218, 200, 233, + 44, 5, 205, 181, 225, 230, 178, 102, 70, 43, 221, 66, + 136, 179, 143, 209, 88, 10, 153, 105, 193, 203, 99, 204, + 140, 86, 185, 132, 15, 101, 29, 161, 176, 20, 49, 210, + 129, 149, 198, 151, 23, 172, 113, 7, 30, 202, 58, 65, + 95, 40, 98, 163 +}; + +/* + * Ranges: + * REDS1: from -32768..98302 to -383..383 + * REDS2: from -2^31..2^31-1 to -32768..98302 + */ +#define REDS1(x) (((x) & 0xFF) - ((x) >> 8)) +#define REDS2(x) (((x) & 0xFFFF) + ((x) >> 16)) + +/* + * If, upon entry, the values of q[] are all in the -N..N range (where + * N >= 98302) then the new values of q[] are in the -2N..2N range. + * + * Since alpha_tab[v] <= 256, maximum allowed range is for N = 8388608. + */ +#define FFT_LOOP(rb, hk, as, id) do { \ + size_t u, v; \ + s32 m = q[(rb)]; \ + s32 n = q[(rb) + (hk)]; \ + q[(rb)] = m + n; \ + q[(rb) + (hk)] = m - n; \ + u = v = 0; \ + goto id; \ + for (; u < (hk); u += 4, v += 4 * (as)) { \ + s32 t; \ + m = q[(rb) + u + 0]; \ + n = q[(rb) + u + 0 + (hk)]; \ + t = REDS2(n * alpha_tab[v + 0 * (as)]); \ + q[(rb) + u + 0] = m + t; \ + q[(rb) + u + 0 + (hk)] = m - t; \ + id: \ + m = q[(rb) + u + 1]; \ + n = q[(rb) + u + 1 + (hk)]; \ + t = REDS2(n * alpha_tab[v + 1 * (as)]); \ + q[(rb) + u + 1] = m + t; \ + q[(rb) + u + 1 + (hk)] = m - t; \ + m = q[(rb) + u + 2]; \ + n = q[(rb) + u + 2 + (hk)]; \ + t = REDS2(n * alpha_tab[v + 2 * (as)]); \ + q[(rb) + u + 2] = m + t; \ + q[(rb) + u + 2 + (hk)] = m - t; \ + m = q[(rb) + u + 3]; \ + n = q[(rb) + u + 3 + (hk)]; \ + t = REDS2(n * alpha_tab[v + 3 * (as)]); \ + q[(rb) + u + 3] = m + t; \ + q[(rb) + u + 3 + (hk)] = m - t; \ + } \ + } while (0) + +/* + * Output ranges: + * d0: min= 0 max= 1020 + * d1: min= -67 max= 4587 + * d2: min=-4335 max= 4335 + * d3: min=-4147 max= 507 + * d4: min= -510 max= 510 + * d5: min= -252 max= 4402 + * d6: min=-4335 max= 4335 + * d7: min=-4332 max= 322 + */ +#define FFT8(xb, xs, d) do { \ + s32 x0 = x[(xb)]; \ + s32 x1 = x[(xb) + (xs)]; \ + s32 x2 = x[(xb) + 2 * (xs)]; \ + s32 x3 = x[(xb) + 3 * (xs)]; \ + s32 a0 = x0 + x2; \ + s32 a1 = x0 + (x2 << 4); \ + s32 a2 = x0 - x2; \ + s32 a3 = x0 - (x2 << 4); \ + s32 b0 = x1 + x3; \ + s32 b1 = REDS1((x1 << 2) + (x3 << 6)); \ + s32 b2 = (x1 << 4) - (x3 << 4); \ + s32 b3 = REDS1((x1 << 6) + (x3 << 2)); \ + d ## 0 = a0 + b0; \ + d ## 1 = a1 + b1; \ + d ## 2 = a2 + b2; \ + d ## 3 = a3 + b3; \ + d ## 4 = a0 - b0; \ + d ## 5 = a1 - b1; \ + d ## 6 = a2 - b2; \ + d ## 7 = a3 - b3; \ + } while (0) + +/* + * When k=16, we have alpha=2. Multiplication by alpha^i is then reduced + * to some shifting. + * + * Output: within -591471..591723 + */ +#define FFT16(xb, xs, rb) do { \ + s32 d1_0, d1_1, d1_2, d1_3, d1_4, d1_5, d1_6, d1_7; \ + s32 d2_0, d2_1, d2_2, d2_3, d2_4, d2_5, d2_6, d2_7; \ + FFT8(xb, (xs) << 1, d1_); \ + FFT8((xb) + (xs), (xs) << 1, d2_); \ + q[(rb) + 0] = d1_0 + d2_0; \ + q[(rb) + 1] = d1_1 + (d2_1 << 1); \ + q[(rb) + 2] = d1_2 + (d2_2 << 2); \ + q[(rb) + 3] = d1_3 + (d2_3 << 3); \ + q[(rb) + 4] = d1_4 + (d2_4 << 4); \ + q[(rb) + 5] = d1_5 + (d2_5 << 5); \ + q[(rb) + 6] = d1_6 + (d2_6 << 6); \ + q[(rb) + 7] = d1_7 + (d2_7 << 7); \ + q[(rb) + 8] = d1_0 - d2_0; \ + q[(rb) + 9] = d1_1 - (d2_1 << 1); \ + q[(rb) + 10] = d1_2 - (d2_2 << 2); \ + q[(rb) + 11] = d1_3 - (d2_3 << 3); \ + q[(rb) + 12] = d1_4 - (d2_4 << 4); \ + q[(rb) + 13] = d1_5 - (d2_5 << 5); \ + q[(rb) + 14] = d1_6 - (d2_6 << 6); \ + q[(rb) + 15] = d1_7 - (d2_7 << 7); \ + } while (0) + +/* + * Output range: |q| <= 1183446 + */ +#define FFT32(xb, xs, rb, id) do { \ + FFT16(xb, (xs) << 1, rb); \ + FFT16((xb) + (xs), (xs) << 1, (rb) + 16); \ + FFT_LOOP(rb, 16, 8, id); \ + } while (0) + +/* + * Output range: |q| <= 2366892 + */ +#define FFT64(xb, xs, rb, id) do { \ + FFT32(xb, (xs) << 1, rb, XCAT(id, a)); \ + FFT32((xb) + (xs), (xs) << 1, (rb) + 32, XCAT(id, b)); \ + FFT_LOOP(rb, 32, 4, id); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_SIMD + +static void +fft32(unsigned char *x, size_t xs, s32 *q) +{ + size_t xd; + + xd = xs << 1; + FFT16(0, xd, 0); + FFT16(xs, xd, 16); + FFT_LOOP(0, 16, 8, label_); +} + +#define FFT128(xb, xs, rb, id) do { \ + fft32(x + (xb) + ((xs) * 0), (xs) << 2, &q[(rb) + 0]); \ + fft32(x + (xb) + ((xs) * 2), (xs) << 2, &q[(rb) + 32]); \ + FFT_LOOP(rb, 32, 4, XCAT(id, aa)); \ + fft32(x + (xb) + ((xs) * 1), (xs) << 2, &q[(rb) + 64]); \ + fft32(x + (xb) + ((xs) * 3), (xs) << 2, &q[(rb) + 96]); \ + FFT_LOOP((rb) + 64, 32, 4, XCAT(id, ab)); \ + FFT_LOOP(rb, 64, 2, XCAT(id, a)); \ + } while (0) + +#else + +/* + * Output range: |q| <= 4733784 + */ +#define FFT128(xb, xs, rb, id) do { \ + FFT64(xb, (xs) << 1, rb, XCAT(id, a)); \ + FFT64((xb) + (xs), (xs) << 1, (rb) + 64, XCAT(id, b)); \ + FFT_LOOP(rb, 64, 2, id); \ + } while (0) + +#endif + +/* + * For SIMD-384 / SIMD-512, the fully unrolled FFT yields a compression + * function which does not fit in the 32 kB L1 cache of a typical x86 + * Intel. We therefore add a function call layer at the FFT64 level. + */ + +static void +fft64(unsigned char *x, size_t xs, s32 *q) +{ + size_t xd; + + xd = xs << 1; + FFT32(0, xd, 0, label_a); + FFT32(xs, xd, 32, label_b); + FFT_LOOP(0, 32, 4, label_); +} + +/* + * Output range: |q| <= 9467568 + */ +#define FFT256(xb, xs, rb, id) do { \ + fft64(x + (xb) + ((xs) * 0), (xs) << 2, &q[(rb) + 0]); \ + fft64(x + (xb) + ((xs) * 2), (xs) << 2, &q[(rb) + 64]); \ + FFT_LOOP(rb, 64, 2, XCAT(id, aa)); \ + fft64(x + (xb) + ((xs) * 1), (xs) << 2, &q[(rb) + 128]); \ + fft64(x + (xb) + ((xs) * 3), (xs) << 2, &q[(rb) + 192]); \ + FFT_LOOP((rb) + 128, 64, 2, XCAT(id, ab)); \ + FFT_LOOP(rb, 128, 1, XCAT(id, a)); \ + } while (0) + +/* + * alpha^(127*i) mod 257 + */ +static const unsigned short yoff_s_n[] = { + 1, 98, 95, 58, 30, 113, 23, 198, 129, 49, 176, 29, + 15, 185, 140, 99, 193, 153, 88, 143, 136, 221, 70, 178, + 225, 205, 44, 200, 68, 239, 35, 89, 241, 231, 22, 100, + 34, 248, 146, 173, 249, 244, 11, 50, 17, 124, 73, 215, + 253, 122, 134, 25, 137, 62, 165, 236, 255, 61, 67, 141, + 197, 31, 211, 118, 256, 159, 162, 199, 227, 144, 234, 59, + 128, 208, 81, 228, 242, 72, 117, 158, 64, 104, 169, 114, + 121, 36, 187, 79, 32, 52, 213, 57, 189, 18, 222, 168, + 16, 26, 235, 157, 223, 9, 111, 84, 8, 13, 246, 207, + 240, 133, 184, 42, 4, 135, 123, 232, 120, 195, 92, 21, + 2, 196, 190, 116, 60, 226, 46, 139 +}; + +/* + * alpha^(127*i) + alpha^(125*i) mod 257 + */ +static const unsigned short yoff_s_f[] = { + 2, 156, 118, 107, 45, 212, 111, 162, 97, 249, 211, 3, + 49, 101, 151, 223, 189, 178, 253, 204, 76, 82, 232, 65, + 96, 176, 161, 47, 189, 61, 248, 107, 0, 131, 133, 113, + 17, 33, 12, 111, 251, 103, 57, 148, 47, 65, 249, 143, + 189, 8, 204, 230, 205, 151, 187, 227, 247, 111, 140, 6, + 77, 10, 21, 149, 255, 101, 139, 150, 212, 45, 146, 95, + 160, 8, 46, 254, 208, 156, 106, 34, 68, 79, 4, 53, + 181, 175, 25, 192, 161, 81, 96, 210, 68, 196, 9, 150, + 0, 126, 124, 144, 240, 224, 245, 146, 6, 154, 200, 109, + 210, 192, 8, 114, 68, 249, 53, 27, 52, 106, 70, 30, + 10, 146, 117, 251, 180, 247, 236, 108 +}; + +/* + * beta^(255*i) mod 257 + */ +static const unsigned short yoff_b_n[] = { + 1, 163, 98, 40, 95, 65, 58, 202, 30, 7, 113, 172, + 23, 151, 198, 149, 129, 210, 49, 20, 176, 161, 29, 101, + 15, 132, 185, 86, 140, 204, 99, 203, 193, 105, 153, 10, + 88, 209, 143, 179, 136, 66, 221, 43, 70, 102, 178, 230, + 225, 181, 205, 5, 44, 233, 200, 218, 68, 33, 239, 150, + 35, 51, 89, 115, 241, 219, 231, 131, 22, 245, 100, 109, + 34, 145, 248, 75, 146, 154, 173, 186, 249, 238, 244, 194, + 11, 251, 50, 183, 17, 201, 124, 166, 73, 77, 215, 93, + 253, 119, 122, 97, 134, 254, 25, 220, 137, 229, 62, 83, + 165, 167, 236, 175, 255, 188, 61, 177, 67, 127, 141, 110, + 197, 243, 31, 170, 211, 212, 118, 216, 256, 94, 159, 217, + 162, 192, 199, 55, 227, 250, 144, 85, 234, 106, 59, 108, + 128, 47, 208, 237, 81, 96, 228, 156, 242, 125, 72, 171, + 117, 53, 158, 54, 64, 152, 104, 247, 169, 48, 114, 78, + 121, 191, 36, 214, 187, 155, 79, 27, 32, 76, 52, 252, + 213, 24, 57, 39, 189, 224, 18, 107, 222, 206, 168, 142, + 16, 38, 26, 126, 235, 12, 157, 148, 223, 112, 9, 182, + 111, 103, 84, 71, 8, 19, 13, 63, 246, 6, 207, 74, + 240, 56, 133, 91, 184, 180, 42, 164, 4, 138, 135, 160, + 123, 3, 232, 37, 120, 28, 195, 174, 92, 90, 21, 82, + 2, 69, 196, 80, 190, 130, 116, 147, 60, 14, 226, 87, + 46, 45, 139, 41 +}; + +/* + * beta^(255*i) + beta^(253*i) mod 257 + */ +static const unsigned short yoff_b_f[] = { + 2, 203, 156, 47, 118, 214, 107, 106, 45, 93, 212, 20, + 111, 73, 162, 251, 97, 215, 249, 53, 211, 19, 3, 89, + 49, 207, 101, 67, 151, 130, 223, 23, 189, 202, 178, 239, + 253, 127, 204, 49, 76, 236, 82, 137, 232, 157, 65, 79, + 96, 161, 176, 130, 161, 30, 47, 9, 189, 247, 61, 226, + 248, 90, 107, 64, 0, 88, 131, 243, 133, 59, 113, 115, + 17, 236, 33, 213, 12, 191, 111, 19, 251, 61, 103, 208, + 57, 35, 148, 248, 47, 116, 65, 119, 249, 178, 143, 40, + 189, 129, 8, 163, 204, 227, 230, 196, 205, 122, 151, 45, + 187, 19, 227, 72, 247, 125, 111, 121, 140, 220, 6, 107, + 77, 69, 10, 101, 21, 65, 149, 171, 255, 54, 101, 210, + 139, 43, 150, 151, 212, 164, 45, 237, 146, 184, 95, 6, + 160, 42, 8, 204, 46, 238, 254, 168, 208, 50, 156, 190, + 106, 127, 34, 234, 68, 55, 79, 18, 4, 130, 53, 208, + 181, 21, 175, 120, 25, 100, 192, 178, 161, 96, 81, 127, + 96, 227, 210, 248, 68, 10, 196, 31, 9, 167, 150, 193, + 0, 169, 126, 14, 124, 198, 144, 142, 240, 21, 224, 44, + 245, 66, 146, 238, 6, 196, 154, 49, 200, 222, 109, 9, + 210, 141, 192, 138, 8, 79, 114, 217, 68, 128, 249, 94, + 53, 30, 27, 61, 52, 135, 106, 212, 70, 238, 30, 185, + 10, 132, 146, 136, 117, 37, 251, 150, 180, 188, 247, 156, + 236, 192, 108, 86 +}; + +#define INNER(l, h, mm) (((u32)((l) * (mm)) & 0xFFFFU) \ + + ((u32)((h) * (mm)) << 16)) + +#define W_SMALL(sb, o1, o2, mm) \ + (INNER(q[8 * (sb) + 2 * 0 + o1], q[8 * (sb) + 2 * 0 + o2], mm), \ + INNER(q[8 * (sb) + 2 * 1 + o1], q[8 * (sb) + 2 * 1 + o2], mm), \ + INNER(q[8 * (sb) + 2 * 2 + o1], q[8 * (sb) + 2 * 2 + o2], mm), \ + INNER(q[8 * (sb) + 2 * 3 + o1], q[8 * (sb) + 2 * 3 + o2], mm) + +#define WS_0_0 W_SMALL( 4, 0, 1, 185) +#define WS_0_1 W_SMALL( 6, 0, 1, 185) +#define WS_0_2 W_SMALL( 0, 0, 1, 185) +#define WS_0_3 W_SMALL( 2, 0, 1, 185) +#define WS_0_4 W_SMALL( 7, 0, 1, 185) +#define WS_0_5 W_SMALL( 5, 0, 1, 185) +#define WS_0_6 W_SMALL( 3, 0, 1, 185) +#define WS_0_7 W_SMALL( 1, 0, 1, 185) +#define WS_1_0 W_SMALL(15, 0, 1, 185) +#define WS_1_1 W_SMALL(11, 0, 1, 185) +#define WS_1_2 W_SMALL(12, 0, 1, 185) +#define WS_1_3 W_SMALL( 8, 0, 1, 185) +#define WS_1_4 W_SMALL( 9, 0, 1, 185) +#define WS_1_5 W_SMALL(13, 0, 1, 185) +#define WS_1_6 W_SMALL(10, 0, 1, 185) +#define WS_1_7 W_SMALL(14, 0, 1, 185) +#define WS_2_0 W_SMALL(17, -128, -64, 233) +#define WS_2_1 W_SMALL(18, -128, -64, 233) +#define WS_2_2 W_SMALL(23, -128, -64, 233) +#define WS_2_3 W_SMALL(20, -128, -64, 233) +#define WS_2_4 W_SMALL(22, -128, -64, 233) +#define WS_2_5 W_SMALL(21, -128, -64, 233) +#define WS_2_6 W_SMALL(16, -128, -64, 233) +#define WS_2_7 W_SMALL(19, -128, -64, 233) +#define WS_3_0 W_SMALL(30, -191, -127, 233) +#define WS_3_1 W_SMALL(24, -191, -127, 233) +#define WS_3_2 W_SMALL(25, -191, -127, 233) +#define WS_3_3 W_SMALL(31, -191, -127, 233) +#define WS_3_4 W_SMALL(27, -191, -127, 233) +#define WS_3_5 W_SMALL(29, -191, -127, 233) +#define WS_3_6 W_SMALL(28, -191, -127, 233) +#define WS_3_7 W_SMALL(26, -191, -127, 233) + +#define W_BIG(sb, o1, o2, mm) \ + (INNER(q[16 * (sb) + 2 * 0 + o1], q[16 * (sb) + 2 * 0 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 1 + o1], q[16 * (sb) + 2 * 1 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 2 + o1], q[16 * (sb) + 2 * 2 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 3 + o1], q[16 * (sb) + 2 * 3 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 4 + o1], q[16 * (sb) + 2 * 4 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 5 + o1], q[16 * (sb) + 2 * 5 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 6 + o1], q[16 * (sb) + 2 * 6 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 7 + o1], q[16 * (sb) + 2 * 7 + o2], mm) + +#define WB_0_0 W_BIG( 4, 0, 1, 185) +#define WB_0_1 W_BIG( 6, 0, 1, 185) +#define WB_0_2 W_BIG( 0, 0, 1, 185) +#define WB_0_3 W_BIG( 2, 0, 1, 185) +#define WB_0_4 W_BIG( 7, 0, 1, 185) +#define WB_0_5 W_BIG( 5, 0, 1, 185) +#define WB_0_6 W_BIG( 3, 0, 1, 185) +#define WB_0_7 W_BIG( 1, 0, 1, 185) +#define WB_1_0 W_BIG(15, 0, 1, 185) +#define WB_1_1 W_BIG(11, 0, 1, 185) +#define WB_1_2 W_BIG(12, 0, 1, 185) +#define WB_1_3 W_BIG( 8, 0, 1, 185) +#define WB_1_4 W_BIG( 9, 0, 1, 185) +#define WB_1_5 W_BIG(13, 0, 1, 185) +#define WB_1_6 W_BIG(10, 0, 1, 185) +#define WB_1_7 W_BIG(14, 0, 1, 185) +#define WB_2_0 W_BIG(17, -256, -128, 233) +#define WB_2_1 W_BIG(18, -256, -128, 233) +#define WB_2_2 W_BIG(23, -256, -128, 233) +#define WB_2_3 W_BIG(20, -256, -128, 233) +#define WB_2_4 W_BIG(22, -256, -128, 233) +#define WB_2_5 W_BIG(21, -256, -128, 233) +#define WB_2_6 W_BIG(16, -256, -128, 233) +#define WB_2_7 W_BIG(19, -256, -128, 233) +#define WB_3_0 W_BIG(30, -383, -255, 233) +#define WB_3_1 W_BIG(24, -383, -255, 233) +#define WB_3_2 W_BIG(25, -383, -255, 233) +#define WB_3_3 W_BIG(31, -383, -255, 233) +#define WB_3_4 W_BIG(27, -383, -255, 233) +#define WB_3_5 W_BIG(29, -383, -255, 233) +#define WB_3_6 W_BIG(28, -383, -255, 233) +#define WB_3_7 W_BIG(26, -383, -255, 233) + +#define IF(x, y, z) ((((y) ^ (z)) & (x)) ^ (z)) +#define MAJ(x, y, z) (((x) & (y)) | (((x) | (y)) & (z))) + +#define PP4_0_0 1 +#define PP4_0_1 0 +#define PP4_0_2 3 +#define PP4_0_3 2 +#define PP4_1_0 2 +#define PP4_1_1 3 +#define PP4_1_2 0 +#define PP4_1_3 1 +#define PP4_2_0 3 +#define PP4_2_1 2 +#define PP4_2_2 1 +#define PP4_2_3 0 + +#define PP8_0_0 1 +#define PP8_0_1 0 +#define PP8_0_2 3 +#define PP8_0_3 2 +#define PP8_0_4 5 +#define PP8_0_5 4 +#define PP8_0_6 7 +#define PP8_0_7 6 + +#define PP8_1_0 6 +#define PP8_1_1 7 +#define PP8_1_2 4 +#define PP8_1_3 5 +#define PP8_1_4 2 +#define PP8_1_5 3 +#define PP8_1_6 0 +#define PP8_1_7 1 + +#define PP8_2_0 2 +#define PP8_2_1 3 +#define PP8_2_2 0 +#define PP8_2_3 1 +#define PP8_2_4 6 +#define PP8_2_5 7 +#define PP8_2_6 4 +#define PP8_2_7 5 + +#define PP8_3_0 3 +#define PP8_3_1 2 +#define PP8_3_2 1 +#define PP8_3_3 0 +#define PP8_3_4 7 +#define PP8_3_5 6 +#define PP8_3_6 5 +#define PP8_3_7 4 + +#define PP8_4_0 5 +#define PP8_4_1 4 +#define PP8_4_2 7 +#define PP8_4_3 6 +#define PP8_4_4 1 +#define PP8_4_5 0 +#define PP8_4_6 3 +#define PP8_4_7 2 + +#define PP8_5_0 7 +#define PP8_5_1 6 +#define PP8_5_2 5 +#define PP8_5_3 4 +#define PP8_5_4 3 +#define PP8_5_5 2 +#define PP8_5_6 1 +#define PP8_5_7 0 + +#define PP8_6_0 4 +#define PP8_6_1 5 +#define PP8_6_2 6 +#define PP8_6_3 7 +#define PP8_6_4 0 +#define PP8_6_5 1 +#define PP8_6_6 2 +#define PP8_6_7 3 + +#if SPH_SIMD_NOCOPY + +#define DECL_STATE_SMALL +#define READ_STATE_SMALL(sc) +#define WRITE_STATE_SMALL(sc) +#define DECL_STATE_BIG +#define READ_STATE_BIG(sc) +#define WRITE_STATE_BIG(sc) + +#else + +#define DECL_STATE_SMALL \ + u32 A0, A1, A2, A3, B0, B1, B2, B3, C0, C1, C2, C3, D0, D1, D2, D3; + +#define READ_STATE_SMALL(sc) do { \ + A0 = (sc)->state[ 0]; \ + A1 = (sc)->state[ 1]; \ + A2 = (sc)->state[ 2]; \ + A3 = (sc)->state[ 3]; \ + B0 = (sc)->state[ 4]; \ + B1 = (sc)->state[ 5]; \ + B2 = (sc)->state[ 6]; \ + B3 = (sc)->state[ 7]; \ + C0 = (sc)->state[ 8]; \ + C1 = (sc)->state[ 9]; \ + C2 = (sc)->state[10]; \ + C3 = (sc)->state[11]; \ + D0 = (sc)->state[12]; \ + D1 = (sc)->state[13]; \ + D2 = (sc)->state[14]; \ + D3 = (sc)->state[15]; \ + } while (0) + +#define WRITE_STATE_SMALL(sc) do { \ + (sc)->state[ 0] = A0; \ + (sc)->state[ 1] = A1; \ + (sc)->state[ 2] = A2; \ + (sc)->state[ 3] = A3; \ + (sc)->state[ 4] = B0; \ + (sc)->state[ 5] = B1; \ + (sc)->state[ 6] = B2; \ + (sc)->state[ 7] = B3; \ + (sc)->state[ 8] = C0; \ + (sc)->state[ 9] = C1; \ + (sc)->state[10] = C2; \ + (sc)->state[11] = C3; \ + (sc)->state[12] = D0; \ + (sc)->state[13] = D1; \ + (sc)->state[14] = D2; \ + (sc)->state[15] = D3; \ + } while (0) + +#define DECL_STATE_BIG \ + u32 A0, A1, A2, A3, A4, A5, A6, A7; \ + u32 B0, B1, B2, B3, B4, B5, B6, B7; \ + u32 C0, C1, C2, C3, C4, C5, C6, C7; \ + u32 D0, D1, D2, D3, D4, D5, D6, D7; + +#define READ_STATE_BIG(sc) do { \ + A0 = (sc)->state[ 0]; \ + A1 = (sc)->state[ 1]; \ + A2 = (sc)->state[ 2]; \ + A3 = (sc)->state[ 3]; \ + A4 = (sc)->state[ 4]; \ + A5 = (sc)->state[ 5]; \ + A6 = (sc)->state[ 6]; \ + A7 = (sc)->state[ 7]; \ + B0 = (sc)->state[ 8]; \ + B1 = (sc)->state[ 9]; \ + B2 = (sc)->state[10]; \ + B3 = (sc)->state[11]; \ + B4 = (sc)->state[12]; \ + B5 = (sc)->state[13]; \ + B6 = (sc)->state[14]; \ + B7 = (sc)->state[15]; \ + C0 = (sc)->state[16]; \ + C1 = (sc)->state[17]; \ + C2 = (sc)->state[18]; \ + C3 = (sc)->state[19]; \ + C4 = (sc)->state[20]; \ + C5 = (sc)->state[21]; \ + C6 = (sc)->state[22]; \ + C7 = (sc)->state[23]; \ + D0 = (sc)->state[24]; \ + D1 = (sc)->state[25]; \ + D2 = (sc)->state[26]; \ + D3 = (sc)->state[27]; \ + D4 = (sc)->state[28]; \ + D5 = (sc)->state[29]; \ + D6 = (sc)->state[30]; \ + D7 = (sc)->state[31]; \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + (sc)->state[ 0] = A0; \ + (sc)->state[ 1] = A1; \ + (sc)->state[ 2] = A2; \ + (sc)->state[ 3] = A3; \ + (sc)->state[ 4] = A4; \ + (sc)->state[ 5] = A5; \ + (sc)->state[ 6] = A6; \ + (sc)->state[ 7] = A7; \ + (sc)->state[ 8] = B0; \ + (sc)->state[ 9] = B1; \ + (sc)->state[10] = B2; \ + (sc)->state[11] = B3; \ + (sc)->state[12] = B4; \ + (sc)->state[13] = B5; \ + (sc)->state[14] = B6; \ + (sc)->state[15] = B7; \ + (sc)->state[16] = C0; \ + (sc)->state[17] = C1; \ + (sc)->state[18] = C2; \ + (sc)->state[19] = C3; \ + (sc)->state[20] = C4; \ + (sc)->state[21] = C5; \ + (sc)->state[22] = C6; \ + (sc)->state[23] = C7; \ + (sc)->state[24] = D0; \ + (sc)->state[25] = D1; \ + (sc)->state[26] = D2; \ + (sc)->state[27] = D3; \ + (sc)->state[28] = D4; \ + (sc)->state[29] = D5; \ + (sc)->state[30] = D6; \ + (sc)->state[31] = D7; \ + } while (0) + +#endif + +#define STEP_ELT(n, w, fun, s, ppb) do { \ + u32 tt = T32(D ## n + (w) + fun(A ## n, B ## n, C ## n)); \ + A ## n = T32(ROL32(tt, s) + XCAT(tA, XCAT(ppb, n))); \ + D ## n = C ## n; \ + C ## n = B ## n; \ + B ## n = tA ## n; \ + } while (0) + +#define STEP_SMALL(w0, w1, w2, w3, fun, r, s, pp4b) do { \ + u32 tA0 = ROL32(A0, r); \ + u32 tA1 = ROL32(A1, r); \ + u32 tA2 = ROL32(A2, r); \ + u32 tA3 = ROL32(A3, r); \ + STEP_ELT(0, w0, fun, s, pp4b); \ + STEP_ELT(1, w1, fun, s, pp4b); \ + STEP_ELT(2, w2, fun, s, pp4b); \ + STEP_ELT(3, w3, fun, s, pp4b); \ + } while (0) + +#define STEP_BIG(w0, w1, w2, w3, w4, w5, w6, w7, fun, r, s, pp8b) do { \ + u32 tA0 = ROL32(A0, r); \ + u32 tA1 = ROL32(A1, r); \ + u32 tA2 = ROL32(A2, r); \ + u32 tA3 = ROL32(A3, r); \ + u32 tA4 = ROL32(A4, r); \ + u32 tA5 = ROL32(A5, r); \ + u32 tA6 = ROL32(A6, r); \ + u32 tA7 = ROL32(A7, r); \ + STEP_ELT(0, w0, fun, s, pp8b); \ + STEP_ELT(1, w1, fun, s, pp8b); \ + STEP_ELT(2, w2, fun, s, pp8b); \ + STEP_ELT(3, w3, fun, s, pp8b); \ + STEP_ELT(4, w4, fun, s, pp8b); \ + STEP_ELT(5, w5, fun, s, pp8b); \ + STEP_ELT(6, w6, fun, s, pp8b); \ + STEP_ELT(7, w7, fun, s, pp8b); \ + } while (0) + +#define M3_0_0 0_ +#define M3_1_0 1_ +#define M3_2_0 2_ +#define M3_3_0 0_ +#define M3_4_0 1_ +#define M3_5_0 2_ +#define M3_6_0 0_ +#define M3_7_0 1_ + +#define M3_0_1 1_ +#define M3_1_1 2_ +#define M3_2_1 0_ +#define M3_3_1 1_ +#define M3_4_1 2_ +#define M3_5_1 0_ +#define M3_6_1 1_ +#define M3_7_1 2_ + +#define M3_0_2 2_ +#define M3_1_2 0_ +#define M3_2_2 1_ +#define M3_3_2 2_ +#define M3_4_2 0_ +#define M3_5_2 1_ +#define M3_6_2 2_ +#define M3_7_2 0_ + +#define STEP_SMALL_(w, fun, r, s, pp4b) STEP_SMALL w, fun, r, s, pp4b) + +#define ONE_ROUND_SMALL(ri, isp, p0, p1, p2, p3) do { \ + STEP_SMALL_(WS_ ## ri ## 0, \ + IF, p0, p1, XCAT(PP4_, M3_0_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 1, \ + IF, p1, p2, XCAT(PP4_, M3_1_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 2, \ + IF, p2, p3, XCAT(PP4_, M3_2_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 3, \ + IF, p3, p0, XCAT(PP4_, M3_3_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 4, \ + MAJ, p0, p1, XCAT(PP4_, M3_4_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 5, \ + MAJ, p1, p2, XCAT(PP4_, M3_5_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 6, \ + MAJ, p2, p3, XCAT(PP4_, M3_6_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 7, \ + MAJ, p3, p0, XCAT(PP4_, M3_7_ ## isp)); \ + } while (0) + +#define M7_0_0 0_ +#define M7_1_0 1_ +#define M7_2_0 2_ +#define M7_3_0 3_ +#define M7_4_0 4_ +#define M7_5_0 5_ +#define M7_6_0 6_ +#define M7_7_0 0_ + +#define M7_0_1 1_ +#define M7_1_1 2_ +#define M7_2_1 3_ +#define M7_3_1 4_ +#define M7_4_1 5_ +#define M7_5_1 6_ +#define M7_6_1 0_ +#define M7_7_1 1_ + +#define M7_0_2 2_ +#define M7_1_2 3_ +#define M7_2_2 4_ +#define M7_3_2 5_ +#define M7_4_2 6_ +#define M7_5_2 0_ +#define M7_6_2 1_ +#define M7_7_2 2_ + +#define M7_0_3 3_ +#define M7_1_3 4_ +#define M7_2_3 5_ +#define M7_3_3 6_ +#define M7_4_3 0_ +#define M7_5_3 1_ +#define M7_6_3 2_ +#define M7_7_3 3_ + +#define STEP_BIG_(w, fun, r, s, pp8b) STEP_BIG w, fun, r, s, pp8b) + +#define ONE_ROUND_BIG(ri, isp, p0, p1, p2, p3) do { \ + STEP_BIG_(WB_ ## ri ## 0, \ + IF, p0, p1, XCAT(PP8_, M7_0_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 1, \ + IF, p1, p2, XCAT(PP8_, M7_1_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 2, \ + IF, p2, p3, XCAT(PP8_, M7_2_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 3, \ + IF, p3, p0, XCAT(PP8_, M7_3_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 4, \ + MAJ, p0, p1, XCAT(PP8_, M7_4_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 5, \ + MAJ, p1, p2, XCAT(PP8_, M7_5_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 6, \ + MAJ, p2, p3, XCAT(PP8_, M7_6_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 7, \ + MAJ, p3, p0, XCAT(PP8_, M7_7_ ## isp)); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_SIMD + +#define A0 state[ 0] +#define A1 state[ 1] +#define A2 state[ 2] +#define A3 state[ 3] +#define B0 state[ 4] +#define B1 state[ 5] +#define B2 state[ 6] +#define B3 state[ 7] +#define C0 state[ 8] +#define C1 state[ 9] +#define C2 state[10] +#define C3 state[11] +#define D0 state[12] +#define D1 state[13] +#define D2 state[14] +#define D3 state[15] + +#define STEP2_ELT(n, w, fun, s, ppb) do { \ + u32 tt = T32(D ## n + (w) + fun(A ## n, B ## n, C ## n)); \ + A ## n = T32(ROL32(tt, s) + tA[(ppb) ^ n]); \ + D ## n = C ## n; \ + C ## n = B ## n; \ + B ## n = tA[n]; \ + } while (0) + +#define STEP2_SMALL(w0, w1, w2, w3, fun, r, s, pp4b) do { \ + u32 tA[4]; \ + tA[0] = ROL32(A0, r); \ + tA[1] = ROL32(A1, r); \ + tA[2] = ROL32(A2, r); \ + tA[3] = ROL32(A3, r); \ + STEP2_ELT(0, w0, fun, s, pp4b); \ + STEP2_ELT(1, w1, fun, s, pp4b); \ + STEP2_ELT(2, w2, fun, s, pp4b); \ + STEP2_ELT(3, w3, fun, s, pp4b); \ + } while (0) + +static void +one_round_small(u32 *state, u32 *w, int isp, int p0, int p1, int p2, int p3) +{ + static const int pp4k[] = { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2 }; + + STEP2_SMALL(w[ 0], w[ 1], w[ 2], w[ 3], IF, p0, p1, pp4k[isp + 0]); + STEP2_SMALL(w[ 4], w[ 5], w[ 6], w[ 7], IF, p1, p2, pp4k[isp + 1]); + STEP2_SMALL(w[ 8], w[ 9], w[10], w[11], IF, p2, p3, pp4k[isp + 2]); + STEP2_SMALL(w[12], w[13], w[14], w[15], IF, p3, p0, pp4k[isp + 3]); + STEP2_SMALL(w[16], w[17], w[18], w[19], MAJ, p0, p1, pp4k[isp + 4]); + STEP2_SMALL(w[20], w[21], w[22], w[23], MAJ, p1, p2, pp4k[isp + 5]); + STEP2_SMALL(w[24], w[25], w[26], w[27], MAJ, p2, p3, pp4k[isp + 6]); + STEP2_SMALL(w[28], w[29], w[30], w[31], MAJ, p3, p0, pp4k[isp + 7]); +} + +static void +compress_small(sph_simd_small_context *sc, int last) +{ + unsigned char *x; + s32 q[128]; + int i; + u32 w[32]; + u32 state[16]; + size_t u; + + static const size_t wsp[32] = { + 4 << 3, 6 << 3, 0 << 3, 2 << 3, + 7 << 3, 5 << 3, 3 << 3, 1 << 3, + 15 << 3, 11 << 3, 12 << 3, 8 << 3, + 9 << 3, 13 << 3, 10 << 3, 14 << 3, + 17 << 3, 18 << 3, 23 << 3, 20 << 3, + 22 << 3, 21 << 3, 16 << 3, 19 << 3, + 30 << 3, 24 << 3, 25 << 3, 31 << 3, + 27 << 3, 29 << 3, 28 << 3, 26 << 3 + }; + + x = sc->buf; + FFT128(0, 1, 0, ll); + if (last) { + for (i = 0; i < 128; i ++) { + s32 tq; + + tq = q[i] + yoff_s_f[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (i = 0; i < 128; i ++) { + s32 tq; + + tq = q[i] + yoff_s_n[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + + for (i = 0; i < 16; i += 4) { + state[i + 0] = sc->state[i + 0] + ^ sph_dec32le_aligned(x + 4 * (i + 0)); + state[i + 1] = sc->state[i + 1] + ^ sph_dec32le_aligned(x + 4 * (i + 1)); + state[i + 2] = sc->state[i + 2] + ^ sph_dec32le_aligned(x + 4 * (i + 2)); + state[i + 3] = sc->state[i + 3] + ^ sph_dec32le_aligned(x + 4 * (i + 3)); + } + +#define WSREAD(sb, o1, o2, mm) do { \ + for (u = 0; u < 32; u += 4) { \ + size_t v = wsp[(u >> 2) + (sb)]; \ + w[u + 0] = INNER(q[v + 2 * 0 + (o1)], \ + q[v + 2 * 0 + (o2)], mm); \ + w[u + 1] = INNER(q[v + 2 * 1 + (o1)], \ + q[v + 2 * 1 + (o2)], mm); \ + w[u + 2] = INNER(q[v + 2 * 2 + (o1)], \ + q[v + 2 * 2 + (o2)], mm); \ + w[u + 3] = INNER(q[v + 2 * 3 + (o1)], \ + q[v + 2 * 3 + (o2)], mm); \ + } \ + } while (0) + + WSREAD( 0, 0, 1, 185); + one_round_small(state, w, 0, 3, 23, 17, 27); + WSREAD( 8, 0, 1, 185); + one_round_small(state, w, 2, 28, 19, 22, 7); + WSREAD(16, -128, -64, 233); + one_round_small(state, w, 1, 29, 9, 15, 5); + WSREAD(24, -191, -127, 233); + one_round_small(state, w, 0, 4, 13, 10, 25); + +#undef WSREAD + + STEP_SMALL(sc->state[ 0], sc->state[ 1], sc->state[ 2], sc->state[ 3], + IF, 4, 13, PP4_2_); + STEP_SMALL(sc->state[ 4], sc->state[ 5], sc->state[ 6], sc->state[ 7], + IF, 13, 10, PP4_0_); + STEP_SMALL(sc->state[ 8], sc->state[ 9], sc->state[10], sc->state[11], + IF, 10, 25, PP4_1_); + STEP_SMALL(sc->state[12], sc->state[13], sc->state[14], sc->state[15], + IF, 25, 4, PP4_2_); + + memcpy(sc->state, state, sizeof state); +} + +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef B0 +#undef B1 +#undef B2 +#undef B3 +#undef C0 +#undef C1 +#undef C2 +#undef C3 +#undef D0 +#undef D1 +#undef D2 +#undef D3 + +#else + +#if SPH_SIMD_NOCOPY +#define A0 (sc->state[ 0]) +#define A1 (sc->state[ 1]) +#define A2 (sc->state[ 2]) +#define A3 (sc->state[ 3]) +#define B0 (sc->state[ 4]) +#define B1 (sc->state[ 5]) +#define B2 (sc->state[ 6]) +#define B3 (sc->state[ 7]) +#define C0 (sc->state[ 8]) +#define C1 (sc->state[ 9]) +#define C2 (sc->state[10]) +#define C3 (sc->state[11]) +#define D0 (sc->state[12]) +#define D1 (sc->state[13]) +#define D2 (sc->state[14]) +#define D3 (sc->state[15]) +#endif + +static void +compress_small(sph_simd_small_context *sc, int last) +{ + unsigned char *x; + s32 q[128]; + int i; + DECL_STATE_SMALL +#if SPH_SIMD_NOCOPY + sph_u32 saved[16]; +#endif + +#if SPH_SIMD_NOCOPY + memcpy(saved, sc->state, sizeof saved); +#endif + x = sc->buf; + FFT128(0, 1, 0, ll); + if (last) { + for (i = 0; i < 128; i ++) { + s32 tq; + + tq = q[i] + yoff_s_f[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (i = 0; i < 128; i ++) { + s32 tq; + + tq = q[i] + yoff_s_n[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + READ_STATE_SMALL(sc); + A0 ^= sph_dec32le_aligned(x + 0); + A1 ^= sph_dec32le_aligned(x + 4); + A2 ^= sph_dec32le_aligned(x + 8); + A3 ^= sph_dec32le_aligned(x + 12); + B0 ^= sph_dec32le_aligned(x + 16); + B1 ^= sph_dec32le_aligned(x + 20); + B2 ^= sph_dec32le_aligned(x + 24); + B3 ^= sph_dec32le_aligned(x + 28); + C0 ^= sph_dec32le_aligned(x + 32); + C1 ^= sph_dec32le_aligned(x + 36); + C2 ^= sph_dec32le_aligned(x + 40); + C3 ^= sph_dec32le_aligned(x + 44); + D0 ^= sph_dec32le_aligned(x + 48); + D1 ^= sph_dec32le_aligned(x + 52); + D2 ^= sph_dec32le_aligned(x + 56); + D3 ^= sph_dec32le_aligned(x + 60); + ONE_ROUND_SMALL(0_, 0, 3, 23, 17, 27); + ONE_ROUND_SMALL(1_, 2, 28, 19, 22, 7); + ONE_ROUND_SMALL(2_, 1, 29, 9, 15, 5); + ONE_ROUND_SMALL(3_, 0, 4, 13, 10, 25); +#if SPH_SIMD_NOCOPY + STEP_SMALL(saved[ 0], saved[ 1], saved[ 2], saved[ 3], + IF, 4, 13, PP4_2_); + STEP_SMALL(saved[ 4], saved[ 5], saved[ 6], saved[ 7], + IF, 13, 10, PP4_0_); + STEP_SMALL(saved[ 8], saved[ 9], saved[10], saved[11], + IF, 10, 25, PP4_1_); + STEP_SMALL(saved[12], saved[13], saved[14], saved[15], + IF, 25, 4, PP4_2_); +#else + STEP_SMALL(sc->state[ 0], sc->state[ 1], sc->state[ 2], sc->state[ 3], + IF, 4, 13, PP4_2_); + STEP_SMALL(sc->state[ 4], sc->state[ 5], sc->state[ 6], sc->state[ 7], + IF, 13, 10, PP4_0_); + STEP_SMALL(sc->state[ 8], sc->state[ 9], sc->state[10], sc->state[11], + IF, 10, 25, PP4_1_); + STEP_SMALL(sc->state[12], sc->state[13], sc->state[14], sc->state[15], + IF, 25, 4, PP4_2_); + WRITE_STATE_SMALL(sc); +#endif +} + +#if SPH_SIMD_NOCOPY +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef B0 +#undef B1 +#undef B2 +#undef B3 +#undef C0 +#undef C1 +#undef C2 +#undef C3 +#undef D0 +#undef D1 +#undef D2 +#undef D3 +#endif + +#endif + +#if SPH_SMALL_FOOTPRINT_SIMD + +#define A0 state[ 0] +#define A1 state[ 1] +#define A2 state[ 2] +#define A3 state[ 3] +#define A4 state[ 4] +#define A5 state[ 5] +#define A6 state[ 6] +#define A7 state[ 7] +#define B0 state[ 8] +#define B1 state[ 9] +#define B2 state[10] +#define B3 state[11] +#define B4 state[12] +#define B5 state[13] +#define B6 state[14] +#define B7 state[15] +#define C0 state[16] +#define C1 state[17] +#define C2 state[18] +#define C3 state[19] +#define C4 state[20] +#define C5 state[21] +#define C6 state[22] +#define C7 state[23] +#define D0 state[24] +#define D1 state[25] +#define D2 state[26] +#define D3 state[27] +#define D4 state[28] +#define D5 state[29] +#define D6 state[30] +#define D7 state[31] + +/* + * Not needed -- already defined for SIMD-224 / SIMD-256 + * +#define STEP2_ELT(n, w, fun, s, ppb) do { \ + u32 tt = T32(D ## n + (w) + fun(A ## n, B ## n, C ## n)); \ + A ## n = T32(ROL32(tt, s) + tA[(ppb) ^ n]); \ + D ## n = C ## n; \ + C ## n = B ## n; \ + B ## n = tA[n]; \ + } while (0) + */ + +#define STEP2_BIG(w0, w1, w2, w3, w4, w5, w6, w7, fun, r, s, pp8b) do { \ + u32 tA[8]; \ + tA[0] = ROL32(A0, r); \ + tA[1] = ROL32(A1, r); \ + tA[2] = ROL32(A2, r); \ + tA[3] = ROL32(A3, r); \ + tA[4] = ROL32(A4, r); \ + tA[5] = ROL32(A5, r); \ + tA[6] = ROL32(A6, r); \ + tA[7] = ROL32(A7, r); \ + STEP2_ELT(0, w0, fun, s, pp8b); \ + STEP2_ELT(1, w1, fun, s, pp8b); \ + STEP2_ELT(2, w2, fun, s, pp8b); \ + STEP2_ELT(3, w3, fun, s, pp8b); \ + STEP2_ELT(4, w4, fun, s, pp8b); \ + STEP2_ELT(5, w5, fun, s, pp8b); \ + STEP2_ELT(6, w6, fun, s, pp8b); \ + STEP2_ELT(7, w7, fun, s, pp8b); \ + } while (0) + +static void +one_round_big(u32 *state, u32 *w, int isp, int p0, int p1, int p2, int p3) +{ + static const int pp8k[] = { 1, 6, 2, 3, 5, 7, 4, 1, 6, 2, 3 }; + + STEP2_BIG(w[ 0], w[ 1], w[ 2], w[ 3], w[ 4], w[ 5], w[ 6], w[ 7], + IF, p0, p1, pp8k[isp + 0]); + STEP2_BIG(w[ 8], w[ 9], w[10], w[11], w[12], w[13], w[14], w[15], + IF, p1, p2, pp8k[isp + 1]); + STEP2_BIG(w[16], w[17], w[18], w[19], w[20], w[21], w[22], w[23], + IF, p2, p3, pp8k[isp + 2]); + STEP2_BIG(w[24], w[25], w[26], w[27], w[28], w[29], w[30], w[31], + IF, p3, p0, pp8k[isp + 3]); + STEP2_BIG(w[32], w[33], w[34], w[35], w[36], w[37], w[38], w[39], + MAJ, p0, p1, pp8k[isp + 4]); + STEP2_BIG(w[40], w[41], w[42], w[43], w[44], w[45], w[46], w[47], + MAJ, p1, p2, pp8k[isp + 5]); + STEP2_BIG(w[48], w[49], w[50], w[51], w[52], w[53], w[54], w[55], + MAJ, p2, p3, pp8k[isp + 6]); + STEP2_BIG(w[56], w[57], w[58], w[59], w[60], w[61], w[62], w[63], + MAJ, p3, p0, pp8k[isp + 7]); +} + +static void +compress_big(sph_simd_big_context *sc, int last) +{ + unsigned char *x; + s32 q[256]; + int i; + u32 w[64]; + u32 state[32]; + size_t u; + + static const size_t wbp[32] = { + 4 << 4, 6 << 4, 0 << 4, 2 << 4, + 7 << 4, 5 << 4, 3 << 4, 1 << 4, + 15 << 4, 11 << 4, 12 << 4, 8 << 4, + 9 << 4, 13 << 4, 10 << 4, 14 << 4, + 17 << 4, 18 << 4, 23 << 4, 20 << 4, + 22 << 4, 21 << 4, 16 << 4, 19 << 4, + 30 << 4, 24 << 4, 25 << 4, 31 << 4, + 27 << 4, 29 << 4, 28 << 4, 26 << 4 + }; + + x = sc->buf; + FFT256(0, 1, 0, ll); + if (last) { + for (i = 0; i < 256; i ++) { + s32 tq; + + tq = q[i] + yoff_b_f[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (i = 0; i < 256; i ++) { + s32 tq; + + tq = q[i] + yoff_b_n[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + + for (i = 0; i < 32; i += 8) { + state[i + 0] = sc->state[i + 0] + ^ sph_dec32le_aligned(x + 4 * (i + 0)); + state[i + 1] = sc->state[i + 1] + ^ sph_dec32le_aligned(x + 4 * (i + 1)); + state[i + 2] = sc->state[i + 2] + ^ sph_dec32le_aligned(x + 4 * (i + 2)); + state[i + 3] = sc->state[i + 3] + ^ sph_dec32le_aligned(x + 4 * (i + 3)); + state[i + 4] = sc->state[i + 4] + ^ sph_dec32le_aligned(x + 4 * (i + 4)); + state[i + 5] = sc->state[i + 5] + ^ sph_dec32le_aligned(x + 4 * (i + 5)); + state[i + 6] = sc->state[i + 6] + ^ sph_dec32le_aligned(x + 4 * (i + 6)); + state[i + 7] = sc->state[i + 7] + ^ sph_dec32le_aligned(x + 4 * (i + 7)); + } + +#define WBREAD(sb, o1, o2, mm) do { \ + for (u = 0; u < 64; u += 8) { \ + size_t v = wbp[(u >> 3) + (sb)]; \ + w[u + 0] = INNER(q[v + 2 * 0 + (o1)], \ + q[v + 2 * 0 + (o2)], mm); \ + w[u + 1] = INNER(q[v + 2 * 1 + (o1)], \ + q[v + 2 * 1 + (o2)], mm); \ + w[u + 2] = INNER(q[v + 2 * 2 + (o1)], \ + q[v + 2 * 2 + (o2)], mm); \ + w[u + 3] = INNER(q[v + 2 * 3 + (o1)], \ + q[v + 2 * 3 + (o2)], mm); \ + w[u + 4] = INNER(q[v + 2 * 4 + (o1)], \ + q[v + 2 * 4 + (o2)], mm); \ + w[u + 5] = INNER(q[v + 2 * 5 + (o1)], \ + q[v + 2 * 5 + (o2)], mm); \ + w[u + 6] = INNER(q[v + 2 * 6 + (o1)], \ + q[v + 2 * 6 + (o2)], mm); \ + w[u + 7] = INNER(q[v + 2 * 7 + (o1)], \ + q[v + 2 * 7 + (o2)], mm); \ + } \ + } while (0) + + WBREAD( 0, 0, 1, 185); + one_round_big(state, w, 0, 3, 23, 17, 27); + WBREAD( 8, 0, 1, 185); + one_round_big(state, w, 1, 28, 19, 22, 7); + WBREAD(16, -256, -128, 233); + one_round_big(state, w, 2, 29, 9, 15, 5); + WBREAD(24, -383, -255, 233); + one_round_big(state, w, 3, 4, 13, 10, 25); + +#undef WBREAD + + STEP_BIG( + sc->state[ 0], sc->state[ 1], sc->state[ 2], sc->state[ 3], + sc->state[ 4], sc->state[ 5], sc->state[ 6], sc->state[ 7], + IF, 4, 13, PP8_4_); + STEP_BIG( + sc->state[ 8], sc->state[ 9], sc->state[10], sc->state[11], + sc->state[12], sc->state[13], sc->state[14], sc->state[15], + IF, 13, 10, PP8_5_); + STEP_BIG( + sc->state[16], sc->state[17], sc->state[18], sc->state[19], + sc->state[20], sc->state[21], sc->state[22], sc->state[23], + IF, 10, 25, PP8_6_); + STEP_BIG( + sc->state[24], sc->state[25], sc->state[26], sc->state[27], + sc->state[28], sc->state[29], sc->state[30], sc->state[31], + IF, 25, 4, PP8_0_); + + memcpy(sc->state, state, sizeof state); +} + +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef A4 +#undef A5 +#undef A6 +#undef A7 +#undef B0 +#undef B1 +#undef B2 +#undef B3 +#undef B4 +#undef B5 +#undef B6 +#undef B7 +#undef C0 +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#undef D0 +#undef D1 +#undef D2 +#undef D3 +#undef D4 +#undef D5 +#undef D6 +#undef D7 + +#else + +#if SPH_SIMD_NOCOPY +#define A0 (sc->state[ 0]) +#define A1 (sc->state[ 1]) +#define A2 (sc->state[ 2]) +#define A3 (sc->state[ 3]) +#define A4 (sc->state[ 4]) +#define A5 (sc->state[ 5]) +#define A6 (sc->state[ 6]) +#define A7 (sc->state[ 7]) +#define B0 (sc->state[ 8]) +#define B1 (sc->state[ 9]) +#define B2 (sc->state[10]) +#define B3 (sc->state[11]) +#define B4 (sc->state[12]) +#define B5 (sc->state[13]) +#define B6 (sc->state[14]) +#define B7 (sc->state[15]) +#define C0 (sc->state[16]) +#define C1 (sc->state[17]) +#define C2 (sc->state[18]) +#define C3 (sc->state[19]) +#define C4 (sc->state[20]) +#define C5 (sc->state[21]) +#define C6 (sc->state[22]) +#define C7 (sc->state[23]) +#define D0 (sc->state[24]) +#define D1 (sc->state[25]) +#define D2 (sc->state[26]) +#define D3 (sc->state[27]) +#define D4 (sc->state[28]) +#define D5 (sc->state[29]) +#define D6 (sc->state[30]) +#define D7 (sc->state[31]) +#endif + +static void +compress_big(sph_simd_big_context *sc, int last) +{ + unsigned char *x; + s32 q[256]; + int i; + DECL_STATE_BIG +#if SPH_SIMD_NOCOPY + sph_u32 saved[32]; +#endif + +#if SPH_SIMD_NOCOPY + memcpy(saved, sc->state, sizeof saved); +#endif + + x = sc->buf; + FFT256(0, 1, 0, ll); + if (last) { + for (i = 0; i < 256; i ++) { + s32 tq; + + tq = q[i] + yoff_b_f[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (i = 0; i < 256; i ++) { + s32 tq; + + tq = q[i] + yoff_b_n[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + READ_STATE_BIG(sc); + A0 ^= sph_dec32le_aligned(x + 0); + A1 ^= sph_dec32le_aligned(x + 4); + A2 ^= sph_dec32le_aligned(x + 8); + A3 ^= sph_dec32le_aligned(x + 12); + A4 ^= sph_dec32le_aligned(x + 16); + A5 ^= sph_dec32le_aligned(x + 20); + A6 ^= sph_dec32le_aligned(x + 24); + A7 ^= sph_dec32le_aligned(x + 28); + B0 ^= sph_dec32le_aligned(x + 32); + B1 ^= sph_dec32le_aligned(x + 36); + B2 ^= sph_dec32le_aligned(x + 40); + B3 ^= sph_dec32le_aligned(x + 44); + B4 ^= sph_dec32le_aligned(x + 48); + B5 ^= sph_dec32le_aligned(x + 52); + B6 ^= sph_dec32le_aligned(x + 56); + B7 ^= sph_dec32le_aligned(x + 60); + C0 ^= sph_dec32le_aligned(x + 64); + C1 ^= sph_dec32le_aligned(x + 68); + C2 ^= sph_dec32le_aligned(x + 72); + C3 ^= sph_dec32le_aligned(x + 76); + C4 ^= sph_dec32le_aligned(x + 80); + C5 ^= sph_dec32le_aligned(x + 84); + C6 ^= sph_dec32le_aligned(x + 88); + C7 ^= sph_dec32le_aligned(x + 92); + D0 ^= sph_dec32le_aligned(x + 96); + D1 ^= sph_dec32le_aligned(x + 100); + D2 ^= sph_dec32le_aligned(x + 104); + D3 ^= sph_dec32le_aligned(x + 108); + D4 ^= sph_dec32le_aligned(x + 112); + D5 ^= sph_dec32le_aligned(x + 116); + D6 ^= sph_dec32le_aligned(x + 120); + D7 ^= sph_dec32le_aligned(x + 124); + + ONE_ROUND_BIG(0_, 0, 3, 23, 17, 27); + ONE_ROUND_BIG(1_, 1, 28, 19, 22, 7); + ONE_ROUND_BIG(2_, 2, 29, 9, 15, 5); + ONE_ROUND_BIG(3_, 3, 4, 13, 10, 25); +#if SPH_SIMD_NOCOPY + STEP_BIG( + saved[ 0], saved[ 1], saved[ 2], saved[ 3], + saved[ 4], saved[ 5], saved[ 6], saved[ 7], + IF, 4, 13, PP8_4_); + STEP_BIG( + saved[ 8], saved[ 9], saved[10], saved[11], + saved[12], saved[13], saved[14], saved[15], + IF, 13, 10, PP8_5_); + STEP_BIG( + saved[16], saved[17], saved[18], saved[19], + saved[20], saved[21], saved[22], saved[23], + IF, 10, 25, PP8_6_); + STEP_BIG( + saved[24], saved[25], saved[26], saved[27], + saved[28], saved[29], saved[30], saved[31], + IF, 25, 4, PP8_0_); +#else + STEP_BIG( + sc->state[ 0], sc->state[ 1], sc->state[ 2], sc->state[ 3], + sc->state[ 4], sc->state[ 5], sc->state[ 6], sc->state[ 7], + IF, 4, 13, PP8_4_); + STEP_BIG( + sc->state[ 8], sc->state[ 9], sc->state[10], sc->state[11], + sc->state[12], sc->state[13], sc->state[14], sc->state[15], + IF, 13, 10, PP8_5_); + STEP_BIG( + sc->state[16], sc->state[17], sc->state[18], sc->state[19], + sc->state[20], sc->state[21], sc->state[22], sc->state[23], + IF, 10, 25, PP8_6_); + STEP_BIG( + sc->state[24], sc->state[25], sc->state[26], sc->state[27], + sc->state[28], sc->state[29], sc->state[30], sc->state[31], + IF, 25, 4, PP8_0_); + WRITE_STATE_BIG(sc); +#endif +} + +#if SPH_SIMD_NOCOPY +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef A4 +#undef A5 +#undef A6 +#undef A7 +#undef B0 +#undef B1 +#undef B2 +#undef B3 +#undef B4 +#undef B5 +#undef B6 +#undef B7 +#undef C0 +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#undef D0 +#undef D1 +#undef D2 +#undef D3 +#undef D4 +#undef D5 +#undef D6 +#undef D7 +#endif + +#endif + +static const u32 IV224[] = { + C32(0x33586E9F), C32(0x12FFF033), C32(0xB2D9F64D), C32(0x6F8FEA53), + C32(0xDE943106), C32(0x2742E439), C32(0x4FBAB5AC), C32(0x62B9FF96), + C32(0x22E7B0AF), C32(0xC862B3A8), C32(0x33E00CDC), C32(0x236B86A6), + C32(0xF64AE77C), C32(0xFA373B76), C32(0x7DC1EE5B), C32(0x7FB29CE8) +}; + +static const u32 IV256[] = { + C32(0x4D567983), C32(0x07190BA9), C32(0x8474577B), C32(0x39D726E9), + C32(0xAAF3D925), C32(0x3EE20B03), C32(0xAFD5E751), C32(0xC96006D3), + C32(0xC2C2BA14), C32(0x49B3BCB4), C32(0xF67CAF46), C32(0x668626C9), + C32(0xE2EAA8D2), C32(0x1FF47833), C32(0xD0C661A5), C32(0x55693DE1) +}; + +static const u32 IV384[] = { + C32(0x8A36EEBC), C32(0x94A3BD90), C32(0xD1537B83), C32(0xB25B070B), + C32(0xF463F1B5), C32(0xB6F81E20), C32(0x0055C339), C32(0xB4D144D1), + C32(0x7360CA61), C32(0x18361A03), C32(0x17DCB4B9), C32(0x3414C45A), + C32(0xA699A9D2), C32(0xE39E9664), C32(0x468BFE77), C32(0x51D062F8), + C32(0xB9E3BFE8), C32(0x63BECE2A), C32(0x8FE506B9), C32(0xF8CC4AC2), + C32(0x7AE11542), C32(0xB1AADDA1), C32(0x64B06794), C32(0x28D2F462), + C32(0xE64071EC), C32(0x1DEB91A8), C32(0x8AC8DB23), C32(0x3F782AB5), + C32(0x039B5CB8), C32(0x71DDD962), C32(0xFADE2CEA), C32(0x1416DF71) +}; + +static const u32 IV512[] = { + C32(0x0BA16B95), C32(0x72F999AD), C32(0x9FECC2AE), C32(0xBA3264FC), + C32(0x5E894929), C32(0x8E9F30E5), C32(0x2F1DAA37), C32(0xF0F2C558), + C32(0xAC506643), C32(0xA90635A5), C32(0xE25B878B), C32(0xAAB7878F), + C32(0x88817F7A), C32(0x0A02892B), C32(0x559A7550), C32(0x598F657E), + C32(0x7EEF60A1), C32(0x6B70E3E8), C32(0x9C1714D1), C32(0xB958E2A8), + C32(0xAB02675E), C32(0xED1C014F), C32(0xCD8D65BB), C32(0xFDB7A257), + C32(0x09254899), C32(0xD699C7BC), C32(0x9019B6DC), C32(0x2B9022E4), + C32(0x8FA14956), C32(0x21BF9BD3), C32(0xB94D0943), C32(0x6FFDDC22) +}; + +static void +init_small(void *cc, const u32 *iv) +{ + sph_simd_small_context *sc; + + sc = cc; + memcpy(sc->state, iv, sizeof sc->state); + sc->count_low = sc->count_high = 0; + sc->ptr = 0; +} + +static void +init_big(void *cc, const u32 *iv) +{ + sph_simd_big_context *sc; + + sc = cc; + memcpy(sc->state, iv, sizeof sc->state); + sc->count_low = sc->count_high = 0; + sc->ptr = 0; +} + +static void +update_small(void *cc, const void *data, size_t len) +{ + sph_simd_small_context *sc; + + sc = cc; + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - sc->ptr; + if (clen > len) + clen = len; + memcpy(sc->buf + sc->ptr, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + if ((sc->ptr += clen) == sizeof sc->buf) { + compress_small(sc, 0); + sc->ptr = 0; + sc->count_low = T32(sc->count_low + 1); + if (sc->count_low == 0) + sc->count_high ++; + } + } +} + +static void +update_big(void *cc, const void *data, size_t len) +{ + sph_simd_big_context *sc; + + sc = cc; + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - sc->ptr; + if (clen > len) + clen = len; + memcpy(sc->buf + sc->ptr, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + if ((sc->ptr += clen) == sizeof sc->buf) { + compress_big(sc, 0); + sc->ptr = 0; + sc->count_low = T32(sc->count_low + 1); + if (sc->count_low == 0) + sc->count_high ++; + } + } +} + +static void +encode_count_small(unsigned char *dst, + u32 low, u32 high, size_t ptr, unsigned n) +{ + low = T32(low << 9); + high = T32(high << 9) + (low >> 23); + low += (ptr << 3) + n; + sph_enc32le(dst, low); + sph_enc32le(dst + 4, high); +} + +static void +encode_count_big(unsigned char *dst, + u32 low, u32 high, size_t ptr, unsigned n) +{ + low = T32(low << 10); + high = T32(high << 10) + (low >> 22); + low += (ptr << 3) + n; + sph_enc32le(dst, low); + sph_enc32le(dst + 4, high); +} + +static void +finalize_small(void *cc, unsigned ub, unsigned n, void *dst, size_t dst_len) +{ + sph_simd_small_context *sc; + unsigned char *d; + size_t u; + + sc = cc; + if (sc->ptr > 0 || n > 0) { + memset(sc->buf + sc->ptr, 0, + (sizeof sc->buf) - sc->ptr); + sc->buf[sc->ptr] = ub & (0xFF << (8 - n)); + compress_small(sc, 0); + } + memset(sc->buf, 0, sizeof sc->buf); + encode_count_small(sc->buf, sc->count_low, sc->count_high, sc->ptr, n); + compress_small(sc, 1); + d = dst; + for (d = dst, u = 0; u < dst_len; u ++) + sph_enc32le(d + (u << 2), sc->state[u]); +} + +static void +finalize_big(void *cc, unsigned ub, unsigned n, void *dst, size_t dst_len) +{ + sph_simd_big_context *sc; + unsigned char *d; + size_t u; + + sc = cc; + if (sc->ptr > 0 || n > 0) { + memset(sc->buf + sc->ptr, 0, + (sizeof sc->buf) - sc->ptr); + sc->buf[sc->ptr] = ub & (0xFF << (8 - n)); + compress_big(sc, 0); + } + memset(sc->buf, 0, sizeof sc->buf); + encode_count_big(sc->buf, sc->count_low, sc->count_high, sc->ptr, n); + compress_big(sc, 1); + d = dst; + for (d = dst, u = 0; u < dst_len; u ++) + sph_enc32le(d + (u << 2), sc->state[u]); +} + +void +sph_simd224_init(void *cc) +{ + init_small(cc, IV224); +} + +void +sph_simd224(void *cc, const void *data, size_t len) +{ + update_small(cc, data, len); +} + +void +sph_simd224_close(void *cc, void *dst) +{ + sph_simd224_addbits_and_close(cc, 0, 0, dst); +} + +void +sph_simd224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + finalize_small(cc, ub, n, dst, 7); + sph_simd224_init(cc); +} + +void +sph_simd256_init(void *cc) +{ + init_small(cc, IV256); +} + +void +sph_simd256(void *cc, const void *data, size_t len) +{ + update_small(cc, data, len); +} + +void +sph_simd256_close(void *cc, void *dst) +{ + sph_simd256_addbits_and_close(cc, 0, 0, dst); +} + +void +sph_simd256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + finalize_small(cc, ub, n, dst, 8); + sph_simd256_init(cc); +} + +void +sph_simd384_init(void *cc) +{ + init_big(cc, IV384); +} + +void +sph_simd384(void *cc, const void *data, size_t len) +{ + update_big(cc, data, len); +} + +void +sph_simd384_close(void *cc, void *dst) +{ + sph_simd384_addbits_and_close(cc, 0, 0, dst); +} + +void +sph_simd384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + finalize_big(cc, ub, n, dst, 12); + sph_simd384_init(cc); +} + +void +sph_simd512_init(void *cc) +{ + init_big(cc, IV512); +} + +void +sph_simd512(void *cc, const void *data, size_t len) +{ + update_big(cc, data, len); +} + +void +sph_simd512_close(void *cc, void *dst) +{ + sph_simd512_addbits_and_close(cc, 0, 0, dst); +} + +void +sph_simd512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + finalize_big(cc, ub, n, dst, 16); + sph_simd512_init(cc); +} +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/skein.c b/src/skein.c new file mode 100644 index 0000000..7e47e35 --- /dev/null +++ b/src/skein.c @@ -0,0 +1,1254 @@ +/* $Id: skein.c 254 2011-06-07 19:38:58Z tp $ */ +/* + * Skein 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 + */ + +#include +#include + +#include "sph_skein.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_SKEIN +#define SPH_SMALL_FOOTPRINT_SKEIN 1 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +#if SPH_64 + +#if 0 +/* obsolete */ +/* + * M5_ ## s ## _ ## i evaluates to s+i mod 5 (0 <= s <= 18, 0 <= i <= 3). + */ + +#define M5_0_0 0 +#define M5_0_1 1 +#define M5_0_2 2 +#define M5_0_3 3 + +#define M5_1_0 1 +#define M5_1_1 2 +#define M5_1_2 3 +#define M5_1_3 4 + +#define M5_2_0 2 +#define M5_2_1 3 +#define M5_2_2 4 +#define M5_2_3 0 + +#define M5_3_0 3 +#define M5_3_1 4 +#define M5_3_2 0 +#define M5_3_3 1 + +#define M5_4_0 4 +#define M5_4_1 0 +#define M5_4_2 1 +#define M5_4_3 2 + +#define M5_5_0 0 +#define M5_5_1 1 +#define M5_5_2 2 +#define M5_5_3 3 + +#define M5_6_0 1 +#define M5_6_1 2 +#define M5_6_2 3 +#define M5_6_3 4 + +#define M5_7_0 2 +#define M5_7_1 3 +#define M5_7_2 4 +#define M5_7_3 0 + +#define M5_8_0 3 +#define M5_8_1 4 +#define M5_8_2 0 +#define M5_8_3 1 + +#define M5_9_0 4 +#define M5_9_1 0 +#define M5_9_2 1 +#define M5_9_3 2 + +#define M5_10_0 0 +#define M5_10_1 1 +#define M5_10_2 2 +#define M5_10_3 3 + +#define M5_11_0 1 +#define M5_11_1 2 +#define M5_11_2 3 +#define M5_11_3 4 + +#define M5_12_0 2 +#define M5_12_1 3 +#define M5_12_2 4 +#define M5_12_3 0 + +#define M5_13_0 3 +#define M5_13_1 4 +#define M5_13_2 0 +#define M5_13_3 1 + +#define M5_14_0 4 +#define M5_14_1 0 +#define M5_14_2 1 +#define M5_14_3 2 + +#define M5_15_0 0 +#define M5_15_1 1 +#define M5_15_2 2 +#define M5_15_3 3 + +#define M5_16_0 1 +#define M5_16_1 2 +#define M5_16_2 3 +#define M5_16_3 4 + +#define M5_17_0 2 +#define M5_17_1 3 +#define M5_17_2 4 +#define M5_17_3 0 + +#define M5_18_0 3 +#define M5_18_1 4 +#define M5_18_2 0 +#define M5_18_3 1 +#endif + +/* + * M9_ ## s ## _ ## i evaluates to s+i mod 9 (0 <= s <= 18, 0 <= i <= 7). + */ + +#define M9_0_0 0 +#define M9_0_1 1 +#define M9_0_2 2 +#define M9_0_3 3 +#define M9_0_4 4 +#define M9_0_5 5 +#define M9_0_6 6 +#define M9_0_7 7 + +#define M9_1_0 1 +#define M9_1_1 2 +#define M9_1_2 3 +#define M9_1_3 4 +#define M9_1_4 5 +#define M9_1_5 6 +#define M9_1_6 7 +#define M9_1_7 8 + +#define M9_2_0 2 +#define M9_2_1 3 +#define M9_2_2 4 +#define M9_2_3 5 +#define M9_2_4 6 +#define M9_2_5 7 +#define M9_2_6 8 +#define M9_2_7 0 + +#define M9_3_0 3 +#define M9_3_1 4 +#define M9_3_2 5 +#define M9_3_3 6 +#define M9_3_4 7 +#define M9_3_5 8 +#define M9_3_6 0 +#define M9_3_7 1 + +#define M9_4_0 4 +#define M9_4_1 5 +#define M9_4_2 6 +#define M9_4_3 7 +#define M9_4_4 8 +#define M9_4_5 0 +#define M9_4_6 1 +#define M9_4_7 2 + +#define M9_5_0 5 +#define M9_5_1 6 +#define M9_5_2 7 +#define M9_5_3 8 +#define M9_5_4 0 +#define M9_5_5 1 +#define M9_5_6 2 +#define M9_5_7 3 + +#define M9_6_0 6 +#define M9_6_1 7 +#define M9_6_2 8 +#define M9_6_3 0 +#define M9_6_4 1 +#define M9_6_5 2 +#define M9_6_6 3 +#define M9_6_7 4 + +#define M9_7_0 7 +#define M9_7_1 8 +#define M9_7_2 0 +#define M9_7_3 1 +#define M9_7_4 2 +#define M9_7_5 3 +#define M9_7_6 4 +#define M9_7_7 5 + +#define M9_8_0 8 +#define M9_8_1 0 +#define M9_8_2 1 +#define M9_8_3 2 +#define M9_8_4 3 +#define M9_8_5 4 +#define M9_8_6 5 +#define M9_8_7 6 + +#define M9_9_0 0 +#define M9_9_1 1 +#define M9_9_2 2 +#define M9_9_3 3 +#define M9_9_4 4 +#define M9_9_5 5 +#define M9_9_6 6 +#define M9_9_7 7 + +#define M9_10_0 1 +#define M9_10_1 2 +#define M9_10_2 3 +#define M9_10_3 4 +#define M9_10_4 5 +#define M9_10_5 6 +#define M9_10_6 7 +#define M9_10_7 8 + +#define M9_11_0 2 +#define M9_11_1 3 +#define M9_11_2 4 +#define M9_11_3 5 +#define M9_11_4 6 +#define M9_11_5 7 +#define M9_11_6 8 +#define M9_11_7 0 + +#define M9_12_0 3 +#define M9_12_1 4 +#define M9_12_2 5 +#define M9_12_3 6 +#define M9_12_4 7 +#define M9_12_5 8 +#define M9_12_6 0 +#define M9_12_7 1 + +#define M9_13_0 4 +#define M9_13_1 5 +#define M9_13_2 6 +#define M9_13_3 7 +#define M9_13_4 8 +#define M9_13_5 0 +#define M9_13_6 1 +#define M9_13_7 2 + +#define M9_14_0 5 +#define M9_14_1 6 +#define M9_14_2 7 +#define M9_14_3 8 +#define M9_14_4 0 +#define M9_14_5 1 +#define M9_14_6 2 +#define M9_14_7 3 + +#define M9_15_0 6 +#define M9_15_1 7 +#define M9_15_2 8 +#define M9_15_3 0 +#define M9_15_4 1 +#define M9_15_5 2 +#define M9_15_6 3 +#define M9_15_7 4 + +#define M9_16_0 7 +#define M9_16_1 8 +#define M9_16_2 0 +#define M9_16_3 1 +#define M9_16_4 2 +#define M9_16_5 3 +#define M9_16_6 4 +#define M9_16_7 5 + +#define M9_17_0 8 +#define M9_17_1 0 +#define M9_17_2 1 +#define M9_17_3 2 +#define M9_17_4 3 +#define M9_17_5 4 +#define M9_17_6 5 +#define M9_17_7 6 + +#define M9_18_0 0 +#define M9_18_1 1 +#define M9_18_2 2 +#define M9_18_3 3 +#define M9_18_4 4 +#define M9_18_5 5 +#define M9_18_6 6 +#define M9_18_7 7 + +/* + * M3_ ## s ## _ ## i evaluates to s+i mod 3 (0 <= s <= 18, 0 <= i <= 1). + */ + +#define M3_0_0 0 +#define M3_0_1 1 +#define M3_1_0 1 +#define M3_1_1 2 +#define M3_2_0 2 +#define M3_2_1 0 +#define M3_3_0 0 +#define M3_3_1 1 +#define M3_4_0 1 +#define M3_4_1 2 +#define M3_5_0 2 +#define M3_5_1 0 +#define M3_6_0 0 +#define M3_6_1 1 +#define M3_7_0 1 +#define M3_7_1 2 +#define M3_8_0 2 +#define M3_8_1 0 +#define M3_9_0 0 +#define M3_9_1 1 +#define M3_10_0 1 +#define M3_10_1 2 +#define M3_11_0 2 +#define M3_11_1 0 +#define M3_12_0 0 +#define M3_12_1 1 +#define M3_13_0 1 +#define M3_13_1 2 +#define M3_14_0 2 +#define M3_14_1 0 +#define M3_15_0 0 +#define M3_15_1 1 +#define M3_16_0 1 +#define M3_16_1 2 +#define M3_17_0 2 +#define M3_17_1 0 +#define M3_18_0 0 +#define M3_18_1 1 + +#define XCAT(x, y) XCAT_(x, y) +#define XCAT_(x, y) x ## y + +#if 0 +/* obsolete */ +#define SKSI(k, s, i) XCAT(k, XCAT(XCAT(XCAT(M5_, s), _), i)) +#define SKST(t, s, v) XCAT(t, XCAT(XCAT(XCAT(M3_, s), _), v)) +#endif + +#define SKBI(k, s, i) XCAT(k, XCAT(XCAT(XCAT(M9_, s), _), i)) +#define SKBT(t, s, v) XCAT(t, XCAT(XCAT(XCAT(M3_, s), _), v)) + +#if 0 +/* obsolete */ +#define TFSMALL_KINIT(k0, k1, k2, k3, k4, t0, t1, t2) do { \ + k4 = (k0 ^ k1) ^ (k2 ^ k3) ^ SPH_C64(0x1BD11BDAA9FC1A22); \ + t2 = t0 ^ t1; \ + } while (0) +#endif + +#define TFBIG_KINIT(k0, k1, k2, k3, k4, k5, k6, k7, k8, t0, t1, t2) do { \ + k8 = ((k0 ^ k1) ^ (k2 ^ k3)) ^ ((k4 ^ k5) ^ (k6 ^ k7)) \ + ^ SPH_C64(0x1BD11BDAA9FC1A22); \ + t2 = t0 ^ t1; \ + } while (0) + +#if 0 +/* obsolete */ +#define TFSMALL_ADDKEY(w0, w1, w2, w3, k, t, s) do { \ + w0 = SPH_T64(w0 + SKSI(k, s, 0)); \ + w1 = SPH_T64(w1 + SKSI(k, s, 1) + SKST(t, s, 0)); \ + w2 = SPH_T64(w2 + SKSI(k, s, 2) + SKST(t, s, 1)); \ + w3 = SPH_T64(w3 + SKSI(k, s, 3) + (sph_u64)s); \ + } while (0) +#endif + +#if SPH_SMALL_FOOTPRINT_SKEIN + +#define TFBIG_ADDKEY(s, tt0, tt1) do { \ + p0 = SPH_T64(p0 + h[s + 0]); \ + p1 = SPH_T64(p1 + h[s + 1]); \ + p2 = SPH_T64(p2 + h[s + 2]); \ + p3 = SPH_T64(p3 + h[s + 3]); \ + p4 = SPH_T64(p4 + h[s + 4]); \ + p5 = SPH_T64(p5 + h[s + 5] + tt0); \ + p6 = SPH_T64(p6 + h[s + 6] + tt1); \ + p7 = SPH_T64(p7 + h[s + 7] + (sph_u64)s); \ + } while (0) + +#else + +#define TFBIG_ADDKEY(w0, w1, w2, w3, w4, w5, w6, w7, k, t, s) do { \ + w0 = SPH_T64(w0 + SKBI(k, s, 0)); \ + w1 = SPH_T64(w1 + SKBI(k, s, 1)); \ + w2 = SPH_T64(w2 + SKBI(k, s, 2)); \ + w3 = SPH_T64(w3 + SKBI(k, s, 3)); \ + w4 = SPH_T64(w4 + SKBI(k, s, 4)); \ + w5 = SPH_T64(w5 + SKBI(k, s, 5) + SKBT(t, s, 0)); \ + w6 = SPH_T64(w6 + SKBI(k, s, 6) + SKBT(t, s, 1)); \ + w7 = SPH_T64(w7 + SKBI(k, s, 7) + (sph_u64)s); \ + } while (0) + +#endif + +#if 0 +/* obsolete */ +#define TFSMALL_MIX(x0, x1, rc) do { \ + x0 = SPH_T64(x0 + x1); \ + x1 = SPH_ROTL64(x1, rc) ^ x0; \ + } while (0) +#endif + +#define TFBIG_MIX(x0, x1, rc) do { \ + x0 = SPH_T64(x0 + x1); \ + x1 = SPH_ROTL64(x1, rc) ^ x0; \ + } while (0) + +#if 0 +/* obsolete */ +#define TFSMALL_MIX4(w0, w1, w2, w3, rc0, rc1) do { \ + TFSMALL_MIX(w0, w1, rc0); \ + TFSMALL_MIX(w2, w3, rc1); \ + } while (0) +#endif + +#define TFBIG_MIX8(w0, w1, w2, w3, w4, w5, w6, w7, rc0, rc1, rc2, rc3) do { \ + TFBIG_MIX(w0, w1, rc0); \ + TFBIG_MIX(w2, w3, rc1); \ + TFBIG_MIX(w4, w5, rc2); \ + TFBIG_MIX(w6, w7, rc3); \ + } while (0) + +#if 0 +/* obsolete */ +#define TFSMALL_4e(s) do { \ + TFSMALL_ADDKEY(p0, p1, p2, p3, h, t, s); \ + TFSMALL_MIX4(p0, p1, p2, p3, 14, 16); \ + TFSMALL_MIX4(p0, p3, p2, p1, 52, 57); \ + TFSMALL_MIX4(p0, p1, p2, p3, 23, 40); \ + TFSMALL_MIX4(p0, p3, p2, p1, 5, 37); \ + } while (0) + +#define TFSMALL_4o(s) do { \ + TFSMALL_ADDKEY(p0, p1, p2, p3, h, t, s); \ + TFSMALL_MIX4(p0, p1, p2, p3, 25, 33); \ + TFSMALL_MIX4(p0, p3, p2, p1, 46, 12); \ + TFSMALL_MIX4(p0, p1, p2, p3, 58, 22); \ + TFSMALL_MIX4(p0, p3, p2, p1, 32, 32); \ + } while (0) +#endif + +#if SPH_SMALL_FOOTPRINT_SKEIN + +#define TFBIG_4e(s) do { \ + TFBIG_ADDKEY(s, t0, t1); \ + TFBIG_MIX8(p0, p1, p2, p3, p4, p5, p6, p7, 46, 36, 19, 37); \ + TFBIG_MIX8(p2, p1, p4, p7, p6, p5, p0, p3, 33, 27, 14, 42); \ + TFBIG_MIX8(p4, p1, p6, p3, p0, p5, p2, p7, 17, 49, 36, 39); \ + TFBIG_MIX8(p6, p1, p0, p7, p2, p5, p4, p3, 44, 9, 54, 56); \ + } while (0) + +#define TFBIG_4o(s) do { \ + TFBIG_ADDKEY(s, t1, t2); \ + TFBIG_MIX8(p0, p1, p2, p3, p4, p5, p6, p7, 39, 30, 34, 24); \ + TFBIG_MIX8(p2, p1, p4, p7, p6, p5, p0, p3, 13, 50, 10, 17); \ + TFBIG_MIX8(p4, p1, p6, p3, p0, p5, p2, p7, 25, 29, 39, 43); \ + TFBIG_MIX8(p6, p1, p0, p7, p2, p5, p4, p3, 8, 35, 56, 22); \ + } while (0) + +#else + +#define TFBIG_4e(s) do { \ + TFBIG_ADDKEY(p0, p1, p2, p3, p4, p5, p6, p7, h, t, s); \ + TFBIG_MIX8(p0, p1, p2, p3, p4, p5, p6, p7, 46, 36, 19, 37); \ + TFBIG_MIX8(p2, p1, p4, p7, p6, p5, p0, p3, 33, 27, 14, 42); \ + TFBIG_MIX8(p4, p1, p6, p3, p0, p5, p2, p7, 17, 49, 36, 39); \ + TFBIG_MIX8(p6, p1, p0, p7, p2, p5, p4, p3, 44, 9, 54, 56); \ + } while (0) + +#define TFBIG_4o(s) do { \ + TFBIG_ADDKEY(p0, p1, p2, p3, p4, p5, p6, p7, h, t, s); \ + TFBIG_MIX8(p0, p1, p2, p3, p4, p5, p6, p7, 39, 30, 34, 24); \ + TFBIG_MIX8(p2, p1, p4, p7, p6, p5, p0, p3, 13, 50, 10, 17); \ + TFBIG_MIX8(p4, p1, p6, p3, p0, p5, p2, p7, 25, 29, 39, 43); \ + TFBIG_MIX8(p6, p1, p0, p7, p2, p5, p4, p3, 8, 35, 56, 22); \ + } while (0) + +#endif + +#if 0 +/* obsolete */ +#define UBI_SMALL(etype, extra) do { \ + sph_u64 h4, t0, t1, t2; \ + sph_u64 m0 = sph_dec64le(buf + 0); \ + sph_u64 m1 = sph_dec64le(buf + 8); \ + sph_u64 m2 = sph_dec64le(buf + 16); \ + sph_u64 m3 = sph_dec64le(buf + 24); \ + sph_u64 p0 = m0; \ + sph_u64 p1 = m1; \ + sph_u64 p2 = m2; \ + sph_u64 p3 = m3; \ + t0 = SPH_T64(bcount << 5) + (sph_u64)(extra); \ + t1 = (bcount >> 59) + ((sph_u64)(etype) << 55); \ + TFSMALL_KINIT(h0, h1, h2, h3, h4, t0, t1, t2); \ + TFSMALL_4e(0); \ + TFSMALL_4o(1); \ + TFSMALL_4e(2); \ + TFSMALL_4o(3); \ + TFSMALL_4e(4); \ + TFSMALL_4o(5); \ + TFSMALL_4e(6); \ + TFSMALL_4o(7); \ + TFSMALL_4e(8); \ + TFSMALL_4o(9); \ + TFSMALL_4e(10); \ + TFSMALL_4o(11); \ + TFSMALL_4e(12); \ + TFSMALL_4o(13); \ + TFSMALL_4e(14); \ + TFSMALL_4o(15); \ + TFSMALL_4e(16); \ + TFSMALL_4o(17); \ + TFSMALL_ADDKEY(p0, p1, p2, p3, h, t, 18); \ + h0 = m0 ^ p0; \ + h1 = m1 ^ p1; \ + h2 = m2 ^ p2; \ + h3 = m3 ^ p3; \ + } while (0) +#endif + +#if SPH_SMALL_FOOTPRINT_SKEIN + +#define UBI_BIG(etype, extra) do { \ + sph_u64 t0, t1, t2; \ + unsigned u; \ + sph_u64 m0 = sph_dec64le_aligned(buf + 0); \ + sph_u64 m1 = sph_dec64le_aligned(buf + 8); \ + sph_u64 m2 = sph_dec64le_aligned(buf + 16); \ + sph_u64 m3 = sph_dec64le_aligned(buf + 24); \ + sph_u64 m4 = sph_dec64le_aligned(buf + 32); \ + sph_u64 m5 = sph_dec64le_aligned(buf + 40); \ + sph_u64 m6 = sph_dec64le_aligned(buf + 48); \ + sph_u64 m7 = sph_dec64le_aligned(buf + 56); \ + sph_u64 p0 = m0; \ + sph_u64 p1 = m1; \ + sph_u64 p2 = m2; \ + sph_u64 p3 = m3; \ + sph_u64 p4 = m4; \ + sph_u64 p5 = m5; \ + sph_u64 p6 = m6; \ + sph_u64 p7 = m7; \ + t0 = SPH_T64(bcount << 6) + (sph_u64)(extra); \ + t1 = (bcount >> 58) + ((sph_u64)(etype) << 55); \ + TFBIG_KINIT(h[0], h[1], h[2], h[3], h[4], h[5], \ + h[6], h[7], h[8], t0, t1, t2); \ + for (u = 0; u <= 15; u += 3) { \ + h[u + 9] = h[u + 0]; \ + h[u + 10] = h[u + 1]; \ + h[u + 11] = h[u + 2]; \ + } \ + for (u = 0; u < 9; u ++) { \ + sph_u64 s = u << 1; \ + sph_u64 tmp; \ + TFBIG_4e(s); \ + TFBIG_4o(s + 1); \ + tmp = t2; \ + t2 = t1; \ + t1 = t0; \ + t0 = tmp; \ + } \ + TFBIG_ADDKEY(18, t0, t1); \ + h[0] = m0 ^ p0; \ + h[1] = m1 ^ p1; \ + h[2] = m2 ^ p2; \ + h[3] = m3 ^ p3; \ + h[4] = m4 ^ p4; \ + h[5] = m5 ^ p5; \ + h[6] = m6 ^ p6; \ + h[7] = m7 ^ p7; \ + } while (0) + +#else + +#define UBI_BIG(etype, extra) do { \ + sph_u64 h8, t0, t1, t2; \ + sph_u64 m0 = sph_dec64le_aligned(buf + 0); \ + sph_u64 m1 = sph_dec64le_aligned(buf + 8); \ + sph_u64 m2 = sph_dec64le_aligned(buf + 16); \ + sph_u64 m3 = sph_dec64le_aligned(buf + 24); \ + sph_u64 m4 = sph_dec64le_aligned(buf + 32); \ + sph_u64 m5 = sph_dec64le_aligned(buf + 40); \ + sph_u64 m6 = sph_dec64le_aligned(buf + 48); \ + sph_u64 m7 = sph_dec64le_aligned(buf + 56); \ + sph_u64 p0 = m0; \ + sph_u64 p1 = m1; \ + sph_u64 p2 = m2; \ + sph_u64 p3 = m3; \ + sph_u64 p4 = m4; \ + sph_u64 p5 = m5; \ + sph_u64 p6 = m6; \ + sph_u64 p7 = m7; \ + t0 = SPH_T64(bcount << 6) + (sph_u64)(extra); \ + t1 = (bcount >> 58) + ((sph_u64)(etype) << 55); \ + TFBIG_KINIT(h0, h1, h2, h3, h4, h5, h6, h7, h8, t0, t1, t2); \ + TFBIG_4e(0); \ + TFBIG_4o(1); \ + TFBIG_4e(2); \ + TFBIG_4o(3); \ + TFBIG_4e(4); \ + TFBIG_4o(5); \ + TFBIG_4e(6); \ + TFBIG_4o(7); \ + TFBIG_4e(8); \ + TFBIG_4o(9); \ + TFBIG_4e(10); \ + TFBIG_4o(11); \ + TFBIG_4e(12); \ + TFBIG_4o(13); \ + TFBIG_4e(14); \ + TFBIG_4o(15); \ + TFBIG_4e(16); \ + TFBIG_4o(17); \ + TFBIG_ADDKEY(p0, p1, p2, p3, p4, p5, p6, p7, h, t, 18); \ + h0 = m0 ^ p0; \ + h1 = m1 ^ p1; \ + h2 = m2 ^ p2; \ + h3 = m3 ^ p3; \ + h4 = m4 ^ p4; \ + h5 = m5 ^ p5; \ + h6 = m6 ^ p6; \ + h7 = m7 ^ p7; \ + } while (0) + +#endif + +#if 0 +/* obsolete */ +#define DECL_STATE_SMALL \ + sph_u64 h0, h1, h2, h3; \ + sph_u64 bcount; + +#define READ_STATE_SMALL(sc) do { \ + h0 = (sc)->h0; \ + h1 = (sc)->h1; \ + h2 = (sc)->h2; \ + h3 = (sc)->h3; \ + bcount = sc->bcount; \ + } while (0) + +#define WRITE_STATE_SMALL(sc) do { \ + (sc)->h0 = h0; \ + (sc)->h1 = h1; \ + (sc)->h2 = h2; \ + (sc)->h3 = h3; \ + sc->bcount = bcount; \ + } while (0) +#endif + +#if SPH_SMALL_FOOTPRINT_SKEIN + +#define DECL_STATE_BIG \ + sph_u64 h[27]; \ + sph_u64 bcount; + +#define READ_STATE_BIG(sc) do { \ + h[0] = (sc)->h0; \ + h[1] = (sc)->h1; \ + h[2] = (sc)->h2; \ + h[3] = (sc)->h3; \ + h[4] = (sc)->h4; \ + h[5] = (sc)->h5; \ + h[6] = (sc)->h6; \ + h[7] = (sc)->h7; \ + bcount = sc->bcount; \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + (sc)->h0 = h[0]; \ + (sc)->h1 = h[1]; \ + (sc)->h2 = h[2]; \ + (sc)->h3 = h[3]; \ + (sc)->h4 = h[4]; \ + (sc)->h5 = h[5]; \ + (sc)->h6 = h[6]; \ + (sc)->h7 = h[7]; \ + sc->bcount = bcount; \ + } while (0) + +#else + +#define DECL_STATE_BIG \ + sph_u64 h0, h1, h2, h3, h4, h5, h6, h7; \ + sph_u64 bcount; + +#define READ_STATE_BIG(sc) do { \ + h0 = (sc)->h0; \ + h1 = (sc)->h1; \ + h2 = (sc)->h2; \ + h3 = (sc)->h3; \ + h4 = (sc)->h4; \ + h5 = (sc)->h5; \ + h6 = (sc)->h6; \ + h7 = (sc)->h7; \ + bcount = sc->bcount; \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + (sc)->h0 = h0; \ + (sc)->h1 = h1; \ + (sc)->h2 = h2; \ + (sc)->h3 = h3; \ + (sc)->h4 = h4; \ + (sc)->h5 = h5; \ + (sc)->h6 = h6; \ + (sc)->h7 = h7; \ + sc->bcount = bcount; \ + } while (0) + +#endif + +#if 0 +/* obsolete */ +static void +skein_small_init(sph_skein_small_context *sc, const sph_u64 *iv) +{ + sc->h0 = iv[0]; + sc->h1 = iv[1]; + sc->h2 = iv[2]; + sc->h3 = iv[3]; + sc->bcount = 0; + sc->ptr = 0; +} +#endif + +static void +skein_big_init(sph_skein_big_context *sc, const sph_u64 *iv) +{ + sc->h0 = iv[0]; + sc->h1 = iv[1]; + sc->h2 = iv[2]; + sc->h3 = iv[3]; + sc->h4 = iv[4]; + sc->h5 = iv[5]; + sc->h6 = iv[6]; + sc->h7 = iv[7]; + sc->bcount = 0; + sc->ptr = 0; +} + +#if 0 +/* obsolete */ +static void +skein_small_core(sph_skein_small_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr, clen; + unsigned first; + DECL_STATE_SMALL + + buf = sc->buf; + ptr = sc->ptr; + clen = (sizeof sc->buf) - ptr; + if (len <= clen) { + memcpy(buf + ptr, data, len); + sc->ptr = ptr + len; + return; + } + if (clen != 0) { + memcpy(buf + ptr, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + } + +#if SPH_SMALL_FOOTPRINT_SKEIN + + READ_STATE_SMALL(sc); + first = (bcount == 0) << 7; + for (;;) { + bcount ++; + UBI_SMALL(96 + first, 0); + if (len <= sizeof sc->buf) + break; + first = 0; + memcpy(buf, data, sizeof sc->buf); + data = (const unsigned char *)data + sizeof sc->buf; + len -= sizeof sc->buf; + } + WRITE_STATE_SMALL(sc); + sc->ptr = len; + memcpy(buf, data, len); + +#else + + /* + * Unrolling the loop yields a slight performance boost, while + * keeping the code size aorund 24 kB on 32-bit x86. + */ + READ_STATE_SMALL(sc); + first = (bcount == 0) << 7; + for (;;) { + bcount ++; + UBI_SMALL(96 + first, 0); + if (len <= sizeof sc->buf) + break; + buf = (unsigned char *)data; + bcount ++; + UBI_SMALL(96, 0); + if (len <= 2 * sizeof sc->buf) { + data = buf + sizeof sc->buf; + len -= sizeof sc->buf; + break; + } + buf += sizeof sc->buf; + data = buf + sizeof sc->buf; + first = 0; + len -= 2 * sizeof sc->buf; + } + WRITE_STATE_SMALL(sc); + sc->ptr = len; + memcpy(sc->buf, data, len); + +#endif +} +#endif + +static void +skein_big_core(sph_skein_big_context *sc, const void *data, size_t len) +{ + /* + * The Skein "final bit" in the tweak is troublesome here, + * because if the input has a length which is a multiple of the + * block size (512 bits) then that bit must be set for the + * final block, which is full of message bits (padding in + * Skein can be reduced to no extra bit at all). However, this + * function cannot know whether it processes the last chunks of + * the message or not. Hence we may keep a full block of buffered + * data (64 bytes). + */ + unsigned char *buf; + size_t ptr; + unsigned first; + DECL_STATE_BIG + + 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_BIG(sc); + first = (bcount == 0) << 7; + do { + size_t clen; + + if (ptr == sizeof sc->buf) { + bcount ++; + UBI_BIG(96 + first, 0); + first = 0; + ptr = 0; + } + 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; + } while (len > 0); + WRITE_STATE_BIG(sc); + sc->ptr = ptr; +} + +#if 0 +/* obsolete */ +static void +skein_small_close(sph_skein_small_context *sc, unsigned ub, unsigned n, + void *dst, size_t out_len) +{ + unsigned char *buf; + size_t ptr; + unsigned et; + int i; + DECL_STATE_SMALL + + if (n != 0) { + unsigned z; + unsigned char x; + + z = 0x80 >> n; + x = ((ub & -z) | z) & 0xFF; + skein_small_core(sc, &x, 1); + } + + buf = sc->buf; + ptr = sc->ptr; + READ_STATE_SMALL(sc); + memset(buf + ptr, 0, (sizeof sc->buf) - ptr); + et = 352 + ((bcount == 0) << 7) + (n != 0); + for (i = 0; i < 2; i ++) { + UBI_SMALL(et, ptr); + if (i == 0) { + memset(buf, 0, sizeof sc->buf); + bcount = 0; + et = 510; + ptr = 8; + } + } + + sph_enc64le_aligned(buf + 0, h0); + sph_enc64le_aligned(buf + 8, h1); + sph_enc64le_aligned(buf + 16, h2); + sph_enc64le_aligned(buf + 24, h3); + memcpy(dst, buf, out_len); +} +#endif + +static void +skein_big_close(sph_skein_big_context *sc, unsigned ub, unsigned n, + void *dst, size_t out_len) +{ + unsigned char *buf; + size_t ptr; + unsigned et; + int i; +#if SPH_SMALL_FOOTPRINT_SKEIN + size_t u; +#endif + DECL_STATE_BIG + + /* + * Add bit padding if necessary. + */ + if (n != 0) { + unsigned z; + unsigned char x; + + z = 0x80 >> n; + x = ((ub & -z) | z) & 0xFF; + skein_big_core(sc, &x, 1); + } + + buf = sc->buf; + ptr = sc->ptr; + + /* + * At that point, if ptr == 0, then the message was empty; + * otherwise, there is between 1 and 64 bytes (inclusive) which + * are yet to be processed. Either way, we complete the buffer + * to a full block with zeros (the Skein specification mandates + * that an empty message is padded so that there is at least + * one block to process). + * + * Once this block has been processed, we do it again, with + * a block full of zeros, for the output (that block contains + * the encoding of "0", over 8 bytes, then padded with zeros). + */ + READ_STATE_BIG(sc); + memset(buf + ptr, 0, (sizeof sc->buf) - ptr); + et = 352 + ((bcount == 0) << 7) + (n != 0); + for (i = 0; i < 2; i ++) { + UBI_BIG(et, ptr); + if (i == 0) { + memset(buf, 0, sizeof sc->buf); + bcount = 0; + et = 510; + ptr = 8; + } + } + +#if SPH_SMALL_FOOTPRINT_SKEIN + + /* + * We use a temporary buffer because we must support the case + * where output size is not a multiple of 64 (namely, a 224-bit + * output). + */ + for (u = 0; u < out_len; u += 8) + sph_enc64le_aligned(buf + u, h[u >> 3]); + memcpy(dst, buf, out_len); + +#else + + sph_enc64le_aligned(buf + 0, h0); + sph_enc64le_aligned(buf + 8, h1); + sph_enc64le_aligned(buf + 16, h2); + sph_enc64le_aligned(buf + 24, h3); + sph_enc64le_aligned(buf + 32, h4); + sph_enc64le_aligned(buf + 40, h5); + sph_enc64le_aligned(buf + 48, h6); + sph_enc64le_aligned(buf + 56, h7); + memcpy(dst, buf, out_len); + +#endif +} + +#if 0 +/* obsolete */ +static const sph_u64 IV224[] = { + SPH_C64(0xC6098A8C9AE5EA0B), SPH_C64(0x876D568608C5191C), + SPH_C64(0x99CB88D7D7F53884), SPH_C64(0x384BDDB1AEDDB5DE) +}; + +static const sph_u64 IV256[] = { + SPH_C64(0xFC9DA860D048B449), SPH_C64(0x2FCA66479FA7D833), + SPH_C64(0xB33BC3896656840F), SPH_C64(0x6A54E920FDE8DA69) +}; +#endif + +static const sph_u64 IV224[] = { + SPH_C64(0xCCD0616248677224), SPH_C64(0xCBA65CF3A92339EF), + SPH_C64(0x8CCD69D652FF4B64), SPH_C64(0x398AED7B3AB890B4), + SPH_C64(0x0F59D1B1457D2BD0), SPH_C64(0x6776FE6575D4EB3D), + SPH_C64(0x99FBC70E997413E9), SPH_C64(0x9E2CFCCFE1C41EF7) +}; + +static const sph_u64 IV256[] = { + SPH_C64(0xCCD044A12FDB3E13), SPH_C64(0xE83590301A79A9EB), + SPH_C64(0x55AEA0614F816E6F), SPH_C64(0x2A2767A4AE9B94DB), + SPH_C64(0xEC06025E74DD7683), SPH_C64(0xE7A436CDC4746251), + SPH_C64(0xC36FBAF9393AD185), SPH_C64(0x3EEDBA1833EDFC13) +}; + +static const sph_u64 IV384[] = { + SPH_C64(0xA3F6C6BF3A75EF5F), SPH_C64(0xB0FEF9CCFD84FAA4), + SPH_C64(0x9D77DD663D770CFE), SPH_C64(0xD798CBF3B468FDDA), + SPH_C64(0x1BC4A6668A0E4465), SPH_C64(0x7ED7D434E5807407), + SPH_C64(0x548FC1ACD4EC44D6), SPH_C64(0x266E17546AA18FF8) +}; + +static const sph_u64 IV512[] = { + SPH_C64(0x4903ADFF749C51CE), SPH_C64(0x0D95DE399746DF03), + SPH_C64(0x8FD1934127C79BCE), SPH_C64(0x9A255629FF352CB1), + SPH_C64(0x5DB62599DF6CA7B0), SPH_C64(0xEABE394CA9D5C3F4), + SPH_C64(0x991112C71A75B523), SPH_C64(0xAE18A40B660FCC33) +}; + +#if 0 +/* obsolete */ +/* see sph_skein.h */ +void +sph_skein224_init(void *cc) +{ + skein_small_init(cc, IV224); +} + +/* see sph_skein.h */ +void +sph_skein224(void *cc, const void *data, size_t len) +{ + skein_small_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein224_close(void *cc, void *dst) +{ + sph_skein224_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_small_close(cc, ub, n, dst, 28); + sph_skein224_init(cc); +} + +/* see sph_skein.h */ +void +sph_skein256_init(void *cc) +{ + skein_small_init(cc, IV256); +} + +/* see sph_skein.h */ +void +sph_skein256(void *cc, const void *data, size_t len) +{ + skein_small_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein256_close(void *cc, void *dst) +{ + sph_skein256_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_small_close(cc, ub, n, dst, 32); + sph_skein256_init(cc); +} +#endif + +/* see sph_skein.h */ +void +sph_skein224_init(void *cc) +{ + skein_big_init(cc, IV224); +} + +/* see sph_skein.h */ +void +sph_skein224(void *cc, const void *data, size_t len) +{ + skein_big_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein224_close(void *cc, void *dst) +{ + sph_skein224_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_big_close(cc, ub, n, dst, 28); + sph_skein224_init(cc); +} + +/* see sph_skein.h */ +void +sph_skein256_init(void *cc) +{ + skein_big_init(cc, IV256); +} + +/* see sph_skein.h */ +void +sph_skein256(void *cc, const void *data, size_t len) +{ + skein_big_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein256_close(void *cc, void *dst) +{ + sph_skein256_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_big_close(cc, ub, n, dst, 32); + sph_skein256_init(cc); +} + +/* see sph_skein.h */ +void +sph_skein384_init(void *cc) +{ + skein_big_init(cc, IV384); +} + +/* see sph_skein.h */ +void +sph_skein384(void *cc, const void *data, size_t len) +{ + skein_big_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein384_close(void *cc, void *dst) +{ + sph_skein384_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_big_close(cc, ub, n, dst, 48); + sph_skein384_init(cc); +} + +/* see sph_skein.h */ +void +sph_skein512_init(void *cc) +{ + skein_big_init(cc, IV512); +} + +/* see sph_skein.h */ +void +sph_skein512(void *cc, const void *data, size_t len) +{ + skein_big_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein512_close(void *cc, void *dst) +{ + sph_skein512_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_big_close(cc, ub, n, dst, 64); + sph_skein512_init(cc); +} + +#endif + + +#ifdef __cplusplus +} +#endif diff --git a/src/sph_blake.h b/src/sph_blake.h new file mode 100644 index 0000000..d8d7943 --- /dev/null +++ b/src/sph_blake.h @@ -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 + */ + +#ifndef SPH_BLAKE_H__ +#define SPH_BLAKE_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#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 + * memcpy()). + */ +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 sph_blake_small_context. + */ +typedef sph_blake_small_context sph_blake224_context; + +/** + * This structure is a context for BLAKE-256 computations. It is + * identical to the common sph_blake_small_context. + */ +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 + * memcpy()). + */ +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 sph_blake_small_context. + */ +typedef sph_blake_big_context sph_blake384_context; + +/** + * This structure is a context for BLAKE-512 computations. It is + * identical to the common sph_blake_small_context. + */ +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 + * sph_blake224_context) + */ +void sph_blake224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_blake256_context) + */ +void sph_blake256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_blake384_context) + */ +void sph_blake384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_blake512_context) + */ +void sph_blake512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 diff --git a/src/sph_bmw.h b/src/sph_bmw.h new file mode 100644 index 0000000..d386b0c --- /dev/null +++ b/src/sph_bmw.h @@ -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 + */ + +#ifndef SPH_BMW_H__ +#define SPH_BMW_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#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 + * memcpy()). + */ +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 sph_bmw_small_context. + */ +typedef sph_bmw_small_context sph_bmw224_context; + +/** + * This structure is a context for BMW-256 computations. It is + * identical to the common sph_bmw_small_context. + */ +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 + * memcpy()). + */ +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 sph_bmw_small_context. + */ +typedef sph_bmw_big_context sph_bmw384_context; + +/** + * This structure is a context for BMW-512 computations. It is + * identical to the common sph_bmw_small_context. + */ +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 + * sph_bmw224_context) + */ +void sph_bmw224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_bmw256_context) + */ +void sph_bmw256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_bmw384_context) + */ +void sph_bmw384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_bmw512_context) + */ +void sph_bmw512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 diff --git a/src/sph_cubehash.h b/src/sph_cubehash.h new file mode 100644 index 0000000..487a194 --- /dev/null +++ b/src/sph_cubehash.h @@ -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 + */ + +#ifndef SPH_CUBEHASH_H__ +#define SPH_CUBEHASH_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#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 + * memcpy()). + */ +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 + * sph_cubehash224_context) + */ +void sph_cubehash224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_cubehash256_context) + */ +void sph_cubehash256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_cubehash384_context) + */ +void sph_cubehash384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_cubehash512_context) + */ +void sph_cubehash512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 diff --git a/src/sph_echo.h b/src/sph_echo.h new file mode 100644 index 0000000..1ae1e3d --- /dev/null +++ b/src/sph_echo.h @@ -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 + */ + +#ifndef SPH_ECHO_H__ +#define SPH_ECHO_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#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 + * memcpy()). + */ +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 + * memcpy()). + */ +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 + * sph_echo224_context) + */ +void sph_echo224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_echo256_context) + */ +void sph_echo256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_echo384_context) + */ +void sph_echo384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_echo512_context) + */ +void sph_echo512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 diff --git a/src/sph_fugue.h b/src/sph_fugue.h new file mode 100644 index 0000000..c8ff395 --- /dev/null +++ b/src/sph_fugue.h @@ -0,0 +1,81 @@ +#ifndef SPH_FUGUE_H__ +#define SPH_FUGUE_H__ + +#include +#include "sph_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#define SPH_SIZE_fugue224 224 + +#define SPH_SIZE_fugue256 256 + +#define SPH_SIZE_fugue384 384 + +#define SPH_SIZE_fugue512 512 + +typedef struct { +#ifndef DOXYGEN_IGNORE + sph_u32 partial; + unsigned partial_len; + unsigned round_shift; + sph_u32 S[36]; +#if SPH_64 + sph_u64 bit_count; +#else + sph_u32 bit_count_high, bit_count_low; +#endif +#endif +} sph_fugue_context; + +typedef sph_fugue_context sph_fugue224_context; + +typedef sph_fugue_context sph_fugue256_context; + +typedef sph_fugue_context sph_fugue384_context; + +typedef sph_fugue_context sph_fugue512_context; + +void sph_fugue224_init(void *cc); + +void sph_fugue224(void *cc, const void *data, size_t len); + +void sph_fugue224_close(void *cc, void *dst); + +void sph_fugue224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +void sph_fugue256_init(void *cc); + +void sph_fugue256(void *cc, const void *data, size_t len); + +void sph_fugue256_close(void *cc, void *dst); + +void sph_fugue256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +void sph_fugue384_init(void *cc); + +void sph_fugue384(void *cc, const void *data, size_t len); + +void sph_fugue384_close(void *cc, void *dst); + +void sph_fugue384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +void sph_fugue512_init(void *cc); + +void sph_fugue512(void *cc, const void *data, size_t len); + +void sph_fugue512_close(void *cc, void *dst); + +void sph_fugue512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sph_groestl.h b/src/sph_groestl.h new file mode 100644 index 0000000..495f05e --- /dev/null +++ b/src/sph_groestl.h @@ -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 + */ + +#ifndef SPH_GROESTL_H__ +#define SPH_GROESTL_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#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 + * memcpy()). + */ +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 sph_groestl_small_context. + */ +typedef sph_groestl_small_context sph_groestl224_context; + +/** + * This structure is a context for Groestl-256 computations. It is + * identical to the common sph_groestl_small_context. + */ +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 + * memcpy()). + */ +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 sph_groestl_small_context. + */ +typedef sph_groestl_big_context sph_groestl384_context; + +/** + * This structure is a context for Groestl-512 computations. It is + * identical to the common sph_groestl_small_context. + */ +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 + * sph_groestl224_context) + */ +void sph_groestl224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_groestl256_context) + */ +void sph_groestl256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_groestl384_context) + */ +void sph_groestl384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_groestl512_context) + */ +void sph_groestl512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 diff --git a/src/sph_hamsi.h b/src/sph_hamsi.h new file mode 100644 index 0000000..56314de --- /dev/null +++ b/src/sph_hamsi.h @@ -0,0 +1,321 @@ +/* $Id: sph_hamsi.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * Hamsi interface. This code implements Hamsi 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_hamsi.h + * @author Thomas Pornin + */ + +#ifndef SPH_HAMSI_H__ +#define SPH_HAMSI_H__ + +#include +#include "sph_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/** + * Output size (in bits) for Hamsi-224. + */ +#define SPH_SIZE_hamsi224 224 + +/** + * Output size (in bits) for Hamsi-256. + */ +#define SPH_SIZE_hamsi256 256 + +/** + * Output size (in bits) for Hamsi-384. + */ +#define SPH_SIZE_hamsi384 384 + +/** + * Output size (in bits) for Hamsi-512. + */ +#define SPH_SIZE_hamsi512 512 + +/** + * This structure is a context for Hamsi-224 and Hamsi-256 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a Hamsi computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running Hamsi + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char partial[4]; + size_t partial_len; + sph_u32 h[8]; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_hamsi_small_context; + +/** + * This structure is a context for Hamsi-224 computations. It is + * identical to the common sph_hamsi_small_context. + */ +typedef sph_hamsi_small_context sph_hamsi224_context; + +/** + * This structure is a context for Hamsi-256 computations. It is + * identical to the common sph_hamsi_small_context. + */ +typedef sph_hamsi_small_context sph_hamsi256_context; + +/** + * This structure is a context for Hamsi-384 and Hamsi-512 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a Hamsi computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running Hamsi + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char partial[8]; + size_t partial_len; + sph_u32 h[16]; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_hamsi_big_context; + +/** + * This structure is a context for Hamsi-384 computations. It is + * identical to the common sph_hamsi_small_context. + */ +typedef sph_hamsi_big_context sph_hamsi384_context; + +/** + * This structure is a context for Hamsi-512 computations. It is + * identical to the common sph_hamsi_small_context. + */ +typedef sph_hamsi_big_context sph_hamsi512_context; + +/** + * Initialize a Hamsi-224 context. This process performs no memory allocation. + * + * @param cc the Hamsi-224 context (pointer to a + * sph_hamsi224_context) + */ +void sph_hamsi224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Hamsi-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_hamsi224(void *cc, const void *data, size_t len); + +/** + * Terminate the current Hamsi-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 Hamsi-224 context + * @param dst the destination buffer + */ +void sph_hamsi224_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 ub 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 Hamsi-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_hamsi224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Hamsi-256 context. This process performs no memory allocation. + * + * @param cc the Hamsi-256 context (pointer to a + * sph_hamsi256_context) + */ +void sph_hamsi256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Hamsi-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_hamsi256(void *cc, const void *data, size_t len); + +/** + * Terminate the current Hamsi-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 Hamsi-256 context + * @param dst the destination buffer + */ +void sph_hamsi256_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 ub 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 Hamsi-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_hamsi256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Hamsi-384 context. This process performs no memory allocation. + * + * @param cc the Hamsi-384 context (pointer to a + * sph_hamsi384_context) + */ +void sph_hamsi384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Hamsi-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_hamsi384(void *cc, const void *data, size_t len); + +/** + * Terminate the current Hamsi-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 Hamsi-384 context + * @param dst the destination buffer + */ +void sph_hamsi384_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 ub 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 Hamsi-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_hamsi384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Hamsi-512 context. This process performs no memory allocation. + * + * @param cc the Hamsi-512 context (pointer to a + * sph_hamsi512_context) + */ +void sph_hamsi512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Hamsi-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_hamsi512(void *cc, const void *data, size_t len); + +/** + * Terminate the current Hamsi-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 Hamsi-512 context + * @param dst the destination buffer + */ +void sph_hamsi512_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 ub 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 Hamsi-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_hamsi512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + + + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/sph_jh.h b/src/sph_jh.h new file mode 100644 index 0000000..82fae58 --- /dev/null +++ b/src/sph_jh.h @@ -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 + */ + +#ifndef SPH_JH_H__ +#define SPH_JH_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#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 + * memcpy()). + */ +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 + * sph_jh224_context) + */ +void sph_jh224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_jh256_context) + */ +void sph_jh256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_jh384_context) + */ +void sph_jh384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_jh512_context) + */ +void sph_jh512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 diff --git a/src/sph_keccak.h b/src/sph_keccak.h new file mode 100644 index 0000000..bdafdb8 --- /dev/null +++ b/src/sph_keccak.h @@ -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 + */ + +#ifndef SPH_KECCAK_H__ +#define SPH_KECCAK_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#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 + * memcpy()). + */ +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 + * sph_keccak224_context) + */ +void sph_keccak224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_keccak256_context) + */ +void sph_keccak256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_keccak384_context) + */ +void sph_keccak384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_keccak512_context) + */ +void sph_keccak512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 diff --git a/src/sph_luffa.h b/src/sph_luffa.h new file mode 100644 index 0000000..a32fd7b --- /dev/null +++ b/src/sph_luffa.h @@ -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 + */ + +#ifndef SPH_LUFFA_H__ +#define SPH_LUFFA_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#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 + * memcpy()). + */ +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 sph_luffa224_context. + */ +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 + * sph_luffa224_context) + */ +void sph_luffa224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_luffa256_context) + */ +void sph_luffa256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_luffa384_context) + */ +void sph_luffa384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_luffa512_context) + */ +void sph_luffa512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 diff --git a/src/sph_shabal.h b/src/sph_shabal.h new file mode 100644 index 0000000..9ee6c81 --- /dev/null +++ b/src/sph_shabal.h @@ -0,0 +1,344 @@ +/* $Id: sph_shabal.h 175 2010-05-07 16:03:20Z tp $ */ +/** + * Shabal interface. Shabal is a family of functions which differ by + * their output size; this implementation defines Shabal for output + * sizes 192, 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_shabal.h + * @author Thomas Pornin + */ + +#ifndef SPH_SHABAL_H__ +#define SPH_SHABAL_H__ + +#include +#include "sph_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/** + * Output size (in bits) for Shabal-192. + */ +#define SPH_SIZE_shabal192 192 + +/** + * Output size (in bits) for Shabal-224. + */ +#define SPH_SIZE_shabal224 224 + +/** + * Output size (in bits) for Shabal-256. + */ +#define SPH_SIZE_shabal256 256 + +/** + * Output size (in bits) for Shabal-384. + */ +#define SPH_SIZE_shabal384 384 + +/** + * Output size (in bits) for Shabal-512. + */ +#define SPH_SIZE_shabal512 512 + +/** + * This structure is a context for Shabal computations: it contains the + * intermediate values and some data from the last entered block. Once + * a Shabal computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running Shabal computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + sph_u32 A[12], B[16], C[16]; + sph_u32 Whigh, Wlow; +#endif +} sph_shabal_context; + +/** + * Type for a Shabal-192 context (identical to the common context). + */ +typedef sph_shabal_context sph_shabal192_context; + +/** + * Type for a Shabal-224 context (identical to the common context). + */ +typedef sph_shabal_context sph_shabal224_context; + +/** + * Type for a Shabal-256 context (identical to the common context). + */ +typedef sph_shabal_context sph_shabal256_context; + +/** + * Type for a Shabal-384 context (identical to the common context). + */ +typedef sph_shabal_context sph_shabal384_context; + +/** + * Type for a Shabal-512 context (identical to the common context). + */ +typedef sph_shabal_context sph_shabal512_context; + +/** + * Initialize a Shabal-192 context. This process performs no memory allocation. + * + * @param cc the Shabal-192 context (pointer to a + * sph_shabal192_context) + */ +void sph_shabal192_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Shabal-192 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_shabal192(void *cc, const void *data, size_t len); + +/** + * Terminate the current Shabal-192 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (24 bytes). The context is automatically + * reinitialized. + * + * @param cc the Shabal-192 context + * @param dst the destination buffer + */ +void sph_shabal192_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 (24 bytes). If bit number i + * in ub 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 Shabal-192 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_shabal192_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Shabal-224 context. This process performs no memory allocation. + * + * @param cc the Shabal-224 context (pointer to a + * sph_shabal224_context) + */ +void sph_shabal224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Shabal-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_shabal224(void *cc, const void *data, size_t len); + +/** + * Terminate the current Shabal-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 Shabal-224 context + * @param dst the destination buffer + */ +void sph_shabal224_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 ub 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 Shabal-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_shabal224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Shabal-256 context. This process performs no memory allocation. + * + * @param cc the Shabal-256 context (pointer to a + * sph_shabal256_context) + */ +void sph_shabal256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Shabal-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_shabal256(void *cc, const void *data, size_t len); + +/** + * Terminate the current Shabal-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 Shabal-256 context + * @param dst the destination buffer + */ +void sph_shabal256_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 ub 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 Shabal-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_shabal256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Shabal-384 context. This process performs no memory allocation. + * + * @param cc the Shabal-384 context (pointer to a + * sph_shabal384_context) + */ +void sph_shabal384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Shabal-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_shabal384(void *cc, const void *data, size_t len); + +/** + * Terminate the current Shabal-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 Shabal-384 context + * @param dst the destination buffer + */ +void sph_shabal384_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 ub 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 Shabal-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_shabal384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Shabal-512 context. This process performs no memory allocation. + * + * @param cc the Shabal-512 context (pointer to a + * sph_shabal512_context) + */ +void sph_shabal512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Shabal-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_shabal512(void *cc, const void *data, size_t len); + +/** + * Terminate the current Shabal-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 Shabal-512 context + * @param dst the destination buffer + */ +void sph_shabal512_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 ub 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 Shabal-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_shabal512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sph_shavite.h b/src/sph_shavite.h new file mode 100644 index 0000000..0957e42 --- /dev/null +++ b/src/sph_shavite.h @@ -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 + */ + +#ifndef SPH_SHAVITE_H__ +#define SPH_SHAVITE_H__ + +#include +#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 + * memcpy()). + */ +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 sph_shavite_small_context. + */ +typedef sph_shavite_small_context sph_shavite224_context; + +/** + * This structure is a context for SHAvite-256 computations. It is + * identical to the common sph_shavite_small_context. + */ +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 + * memcpy()). + */ +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 sph_shavite_small_context. + */ +typedef sph_shavite_big_context sph_shavite384_context; + +/** + * This structure is a context for SHAvite-512 computations. It is + * identical to the common sph_shavite_small_context. + */ +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 + * sph_shavite224_context) + */ +void sph_shavite224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_shavite256_context) + */ +void sph_shavite256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_shavite384_context) + */ +void sph_shavite384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 + * sph_shavite512_context) + */ +void sph_shavite512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len 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 ub 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 diff --git a/src/sph_simd.h b/src/sph_simd.h new file mode 100644 index 0000000..92ee1e7 --- /dev/null +++ b/src/sph_simd.h @@ -0,0 +1,309 @@ +/* $Id: sph_simd.h 154 2010-04-26 17:00:24Z tp $ */ +/** + * SIMD interface. SIMD is a family of functions which differ by + * their output size; this implementation defines SIMD 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_simd.h + * @author Thomas Pornin + */ + +#ifndef SPH_SIMD_H__ +#define SPH_SIMD_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for SIMD-224. + */ +#define SPH_SIZE_simd224 224 + +/** + * Output size (in bits) for SIMD-256. + */ +#define SPH_SIZE_simd256 256 + +/** + * Output size (in bits) for SIMD-384. + */ +#define SPH_SIZE_simd384 384 + +/** + * Output size (in bits) for SIMD-512. + */ +#define SPH_SIZE_simd512 512 + +/** + * This structure is a context for SIMD computations: it contains the + * intermediate values and some data from the last entered block. Once + * an SIMD computation has been performed, the context can be reused for + * another computation. This specific structure is used for SIMD-224 + * and SIMD-256. + * + * The contents of this structure are private. A running SIMD computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + sph_u32 state[16]; + sph_u32 count_low, count_high; +#endif +} sph_simd_small_context; + +/** + * This structure is a context for SIMD computations: it contains the + * intermediate values and some data from the last entered block. Once + * an SIMD computation has been performed, the context can be reused for + * another computation. This specific structure is used for SIMD-384 + * and SIMD-512. + * + * The contents of this structure are private. A running SIMD computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[128]; /* first field, for alignment */ + size_t ptr; + sph_u32 state[32]; + sph_u32 count_low, count_high; +#endif +} sph_simd_big_context; + +/** + * Type for a SIMD-224 context (identical to the common "small" context). + */ +typedef sph_simd_small_context sph_simd224_context; + +/** + * Type for a SIMD-256 context (identical to the common "small" context). + */ +typedef sph_simd_small_context sph_simd256_context; + +/** + * Type for a SIMD-384 context (identical to the common "big" context). + */ +typedef sph_simd_big_context sph_simd384_context; + +/** + * Type for a SIMD-512 context (identical to the common "big" context). + */ +typedef sph_simd_big_context sph_simd512_context; + +/** + * Initialize an SIMD-224 context. This process performs no memory allocation. + * + * @param cc the SIMD-224 context (pointer to a + * sph_simd224_context) + */ +void sph_simd224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the SIMD-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_simd224(void *cc, const void *data, size_t len); + +/** + * Terminate the current SIMD-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 SIMD-224 context + * @param dst the destination buffer + */ +void sph_simd224_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 ub 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 SIMD-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_simd224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize an SIMD-256 context. This process performs no memory allocation. + * + * @param cc the SIMD-256 context (pointer to a + * sph_simd256_context) + */ +void sph_simd256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the SIMD-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_simd256(void *cc, const void *data, size_t len); + +/** + * Terminate the current SIMD-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 SIMD-256 context + * @param dst the destination buffer + */ +void sph_simd256_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 ub 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 SIMD-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_simd256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize an SIMD-384 context. This process performs no memory allocation. + * + * @param cc the SIMD-384 context (pointer to a + * sph_simd384_context) + */ +void sph_simd384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the SIMD-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_simd384(void *cc, const void *data, size_t len); + +/** + * Terminate the current SIMD-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 SIMD-384 context + * @param dst the destination buffer + */ +void sph_simd384_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 ub 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 SIMD-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_simd384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize an SIMD-512 context. This process performs no memory allocation. + * + * @param cc the SIMD-512 context (pointer to a + * sph_simd512_context) + */ +void sph_simd512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the SIMD-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_simd512(void *cc, const void *data, size_t len); + +/** + * Terminate the current SIMD-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 SIMD-512 context + * @param dst the destination buffer + */ +void sph_simd512_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 ub 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 SIMD-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_simd512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sph_skein.h b/src/sph_skein.h new file mode 100644 index 0000000..bddbc86 --- /dev/null +++ b/src/sph_skein.h @@ -0,0 +1,298 @@ +/* $Id: sph_skein.h 253 2011-06-07 18:33:10Z tp $ */ +/** + * Skein interface. The Skein specification defines three main + * functions, called Skein-256, Skein-512 and Skein-1024, which can be + * further parameterized with an output length. For the SHA-3 + * competition, Skein-512 is used for output sizes of 224, 256, 384 and + * 512 bits; this is what this code implements. Thus, we hereafter call + * Skein-224, Skein-256, Skein-384 and Skein-512 what the Skein + * specification defines as Skein-512-224, Skein-512-256, Skein-512-384 + * and Skein-512-512, respectively. + * + * ==========================(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_skein.h + * @author Thomas Pornin + */ + +#ifndef SPH_SKEIN_H__ +#define SPH_SKEIN_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +#if SPH_64 + +/** + * Output size (in bits) for Skein-224. + */ +#define SPH_SIZE_skein224 224 + +/** + * Output size (in bits) for Skein-256. + */ +#define SPH_SIZE_skein256 256 + +/** + * Output size (in bits) for Skein-384. + */ +#define SPH_SIZE_skein384 384 + +/** + * Output size (in bits) for Skein-512. + */ +#define SPH_SIZE_skein512 512 + +/** + * This structure is a context for Skein computations (with a 384- or + * 512-bit output): it contains the intermediate values and some data + * from the last entered block. Once a Skein computation has been + * performed, the context can be reused for another computation. + * + * The contents of this structure are private. A running Skein computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + sph_u64 h0, h1, h2, h3, h4, h5, h6, h7; + sph_u64 bcount; +#endif +} sph_skein_big_context; + +/** + * Type for a Skein-224 context (identical to the common "big" context). + */ +typedef sph_skein_big_context sph_skein224_context; + +/** + * Type for a Skein-256 context (identical to the common "big" context). + */ +typedef sph_skein_big_context sph_skein256_context; + +/** + * Type for a Skein-384 context (identical to the common "big" context). + */ +typedef sph_skein_big_context sph_skein384_context; + +/** + * Type for a Skein-512 context (identical to the common "big" context). + */ +typedef sph_skein_big_context sph_skein512_context; + +/** + * Initialize a Skein-224 context. This process performs no memory allocation. + * + * @param cc the Skein-224 context (pointer to a + * sph_skein224_context) + */ +void sph_skein224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Skein-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_skein224(void *cc, const void *data, size_t len); + +/** + * Terminate the current Skein-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 Skein-224 context + * @param dst the destination buffer + */ +void sph_skein224_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 ub 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 Skein-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_skein224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Skein-256 context. This process performs no memory allocation. + * + * @param cc the Skein-256 context (pointer to a + * sph_skein256_context) + */ +void sph_skein256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Skein-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_skein256(void *cc, const void *data, size_t len); + +/** + * Terminate the current Skein-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 Skein-256 context + * @param dst the destination buffer + */ +void sph_skein256_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 ub 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 Skein-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_skein256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Skein-384 context. This process performs no memory allocation. + * + * @param cc the Skein-384 context (pointer to a + * sph_skein384_context) + */ +void sph_skein384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Skein-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_skein384(void *cc, const void *data, size_t len); + +/** + * Terminate the current Skein-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 Skein-384 context + * @param dst the destination buffer + */ +void sph_skein384_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 ub 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 Skein-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_skein384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Skein-512 context. This process performs no memory allocation. + * + * @param cc the Skein-512 context (pointer to a + * sph_skein512_context) + */ +void sph_skein512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Skein-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_skein512(void *cc, const void *data, size_t len); + +/** + * Terminate the current Skein-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 Skein-512 context + * @param dst the destination buffer + */ +void sph_skein512_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 ub 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 Skein-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_skein512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sph_types.h b/src/sph_types.h new file mode 100644 index 0000000..7295b0b --- /dev/null +++ b/src/sph_types.h @@ -0,0 +1,1976 @@ +/* $Id: sph_types.h 260 2011-07-21 01:02:38Z tp $ */ +/** + * Basic type definitions. + * + * This header file defines the generic integer types that will be used + * for the implementation of hash functions; it also contains helper + * functions which encode and decode multi-byte integer values, using + * either little-endian or big-endian conventions. + * + * This file contains a compile-time test on the size of a byte + * (the unsigned char C type). If bytes are not octets, + * i.e. if they do not have a size of exactly 8 bits, then compilation + * is aborted. Architectures where bytes are not octets are relatively + * rare, even in the embedded devices market. We forbid non-octet bytes + * because there is no clear convention on how octet streams are encoded + * on such systems. + * + * ==========================(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_types.h + * @author Thomas Pornin + */ + +#ifndef SPH_TYPES_H__ +#define SPH_TYPES_H__ + +#include + +/* + * All our I/O functions are defined over octet streams. We do not know + * how to handle input data if bytes are not octets. + */ +#if CHAR_BIT != 8 +#error This code requires 8-bit bytes +#endif + +/* ============= BEGIN documentation block for Doxygen ============ */ + +#ifdef DOXYGEN_IGNORE + +/** @mainpage sphlib C code documentation + * + * @section overview Overview + * + * sphlib is a library which contains implementations of + * various cryptographic hash functions. These pages have been generated + * with doxygen and + * document the API for the C implementations. + * + * The API is described in appropriate header files, which are available + * in the "Files" section. Each hash function family has its own header, + * whose name begins with "sph_" and contains the family + * name. For instance, the API for the RIPEMD hash functions is available + * in the header file sph_ripemd.h. + * + * @section principles API structure and conventions + * + * @subsection io Input/output conventions + * + * In all generality, hash functions operate over strings of bits. + * Individual bits are rarely encountered in C programming or actual + * communication protocols; most protocols converge on the ubiquitous + * "octet" which is a group of eight bits. Data is thus expressed as a + * stream of octets. The C programming language contains the notion of a + * "byte", which is a data unit managed under the type "unsigned + * char". The C standard prescribes that a byte should hold at + * least eight bits, but possibly more. Most modern architectures, even + * in the embedded world, feature eight-bit bytes, i.e. map bytes to + * octets. + * + * Nevertheless, for some of the implemented hash functions, an extra + * API has been added, which allows the input of arbitrary sequences of + * bits: when the computation is about to be closed, 1 to 7 extra bits + * can be added. The functions for which this API is implemented include + * the SHA-2 functions and all SHA-3 candidates. + * + * sphlib defines hash function which may hash octet streams, + * i.e. streams of bits where the number of bits is a multiple of eight. + * The data input functions in the sphlib API expect data + * as anonymous pointers ("const void *") with a length + * (of type "size_t") which gives the input data chunk length + * in bytes. A byte is assumed to be an octet; the sph_types.h + * header contains a compile-time test which prevents compilation on + * architectures where this property is not met. + * + * The hash function output is also converted into bytes. All currently + * implemented hash functions have an output width which is a multiple of + * eight, and this is likely to remain true for new designs. + * + * Most hash functions internally convert input data into 32-bit of 64-bit + * words, using either little-endian or big-endian conversion. The hash + * output also often consists of such words, which are encoded into output + * bytes with a similar endianness convention. Some hash functions have + * been only loosely specified on that subject; when necessary, + * sphlib has been tested against published "reference" + * implementations in order to use the same conventions. + * + * @subsection shortname Function short name + * + * Each implemented hash function has a "short name" which is used + * internally to derive the identifiers for the functions and context + * structures which the function uses. For instance, MD5 has the short + * name "md5". Short names are listed in the next section, + * for the implemented hash functions. In subsequent sections, the + * short name will be assumed to be "XXX": replace with the + * actual hash function name to get the C identifier. + * + * Note: some functions within the same family share the same core + * elements, such as update function or context structure. Correspondingly, + * some of the defined types or functions may actually be macros which + * transparently evaluate to another type or function name. + * + * @subsection context Context structure + * + * Each implemented hash fonction has its own context structure, available + * under the type name "sph_XXX_context" for the hash function + * with short name "XXX". This structure holds all needed + * state for a running hash computation. + * + * The contents of these structures are meant to be opaque, and private + * to the implementation. However, these contents are specified in the + * header files so that application code which uses sphlib + * may access the size of those structures. + * + * The caller is responsible for allocating the context structure, + * whether by dynamic allocation (malloc() or equivalent), + * static allocation (a global permanent variable), as an automatic + * variable ("on the stack"), or by any other mean which ensures proper + * structure alignment. sphlib code performs no dynamic + * allocation by itself. + * + * The context must be initialized before use, using the + * sph_XXX_init() function. This function sets the context + * state to proper initial values for hashing. + * + * Since all state data is contained within the context structure, + * sphlib is thread-safe and reentrant: several hash + * computations may be performed in parallel, provided that they do not + * operate on the same context. Moreover, a running computation can be + * cloned by copying the context (with a simple memcpy()): + * the context and its clone are then independant and may be updated + * with new data and/or closed without interfering with each other. + * Similarly, a context structure can be moved in memory at will: + * context structures contain no pointer, in particular no pointer to + * themselves. + * + * @subsection dataio Data input + * + * Hashed data is input with the sph_XXX() fonction, which + * takes as parameters a pointer to the context, a pointer to the data + * to hash, and the number of data bytes to hash. The context is updated + * with the new data. + * + * Data can be input in one or several calls, with arbitrary input lengths. + * However, it is best, performance wise, to input data by relatively big + * chunks (say a few kilobytes), because this allows sphlib to + * optimize things and avoid internal copying. + * + * When all data has been input, the context can be closed with + * sph_XXX_close(). The hash output is computed and written + * into the provided buffer. The caller must take care to provide a + * buffer of appropriate length; e.g., when using SHA-1, the output is + * a 20-byte word, therefore the output buffer must be at least 20-byte + * long. + * + * For some hash functions, the sph_XXX_addbits_and_close() + * function can be used instead of sph_XXX_close(). This + * function can take a few extra bits to be added at + * the end of the input message. This allows hashing messages with a + * bit length which is not a multiple of 8. The extra bits are provided + * as an unsigned integer value, and a bit count. The bit count must be + * between 0 and 7, inclusive. The extra bits are provided as bits 7 to + * 0 (bits of numerical value 128, 64, 32... downto 0), in that order. + * For instance, to add three bits of value 1, 1 and 0, the unsigned + * integer will have value 192 (1*128 + 1*64 + 0*32) and the bit count + * will be 3. + * + * The SPH_SIZE_XXX macro is defined for each hash function; + * it evaluates to the function output size, expressed in bits. For instance, + * SPH_SIZE_sha1 evaluates to 160. + * + * When closed, the context is automatically reinitialized and can be + * immediately used for another computation. It is not necessary to call + * sph_XXX_init() after a close. Note that + * sph_XXX_init() can still be called to "reset" a context, + * i.e. forget previously input data, and get back to the initial state. + * + * @subsection alignment Data alignment + * + * "Alignment" is a property of data, which is said to be "properly + * aligned" when its emplacement in memory is such that the data can + * be optimally read by full words. This depends on the type of access; + * basically, some hash functions will read data by 32-bit or 64-bit + * words. sphlib does not mandate such alignment for input + * data, but using aligned data can substantially improve performance. + * + * As a rule, it is best to input data by chunks whose length (in bytes) + * is a multiple of eight, and which begins at "generally aligned" + * addresses, such as the base address returned by a call to + * malloc(). + * + * @section functions Implemented functions + * + * We give here the list of implemented functions. They are grouped by + * family; to each family corresponds a specific header file. Each + * individual function has its associated "short name". Please refer to + * the documentation for that header file to get details on the hash + * function denomination and provenance. + * + * Note: the functions marked with a '(64)' in the list below are + * available only if the C compiler provides an integer type of length + * 64 bits or more. Such a type is mandatory in the latest C standard + * (ISO 9899:1999, aka "C99") and is present in several older compilers + * as well, so chances are that such a type is available. + * + * - HAVAL family: file sph_haval.h + * - HAVAL-128/3 (128-bit, 3 passes): short name: haval128_3 + * - HAVAL-128/4 (128-bit, 4 passes): short name: haval128_4 + * - HAVAL-128/5 (128-bit, 5 passes): short name: haval128_5 + * - HAVAL-160/3 (160-bit, 3 passes): short name: haval160_3 + * - HAVAL-160/4 (160-bit, 4 passes): short name: haval160_4 + * - HAVAL-160/5 (160-bit, 5 passes): short name: haval160_5 + * - HAVAL-192/3 (192-bit, 3 passes): short name: haval192_3 + * - HAVAL-192/4 (192-bit, 4 passes): short name: haval192_4 + * - HAVAL-192/5 (192-bit, 5 passes): short name: haval192_5 + * - HAVAL-224/3 (224-bit, 3 passes): short name: haval224_3 + * - HAVAL-224/4 (224-bit, 4 passes): short name: haval224_4 + * - HAVAL-224/5 (224-bit, 5 passes): short name: haval224_5 + * - HAVAL-256/3 (256-bit, 3 passes): short name: haval256_3 + * - HAVAL-256/4 (256-bit, 4 passes): short name: haval256_4 + * - HAVAL-256/5 (256-bit, 5 passes): short name: haval256_5 + * - MD2: file sph_md2.h, short name: md2 + * - MD4: file sph_md4.h, short name: md4 + * - MD5: file sph_md5.h, short name: md5 + * - PANAMA: file sph_panama.h, short name: panama + * - RadioGatun family: file sph_radiogatun.h + * - RadioGatun[32]: short name: radiogatun32 + * - RadioGatun[64]: short name: radiogatun64 (64) + * - RIPEMD family: file sph_ripemd.h + * - RIPEMD: short name: ripemd + * - RIPEMD-128: short name: ripemd128 + * - RIPEMD-160: short name: ripemd160 + * - SHA-0: file sph_sha0.h, short name: sha0 + * - SHA-1: file sph_sha1.h, short name: sha1 + * - SHA-2 family, 32-bit hashes: file sph_sha2.h + * - SHA-224: short name: sha224 + * - SHA-256: short name: sha256 + * - SHA-384: short name: sha384 (64) + * - SHA-512: short name: sha512 (64) + * - Tiger family: file sph_tiger.h + * - Tiger: short name: tiger (64) + * - Tiger2: short name: tiger2 (64) + * - WHIRLPOOL family: file sph_whirlpool.h + * - WHIRLPOOL-0: short name: whirlpool0 (64) + * - WHIRLPOOL-1: short name: whirlpool1 (64) + * - WHIRLPOOL: short name: whirlpool (64) + * + * The fourteen second-round SHA-3 candidates are also implemented; + * when applicable, the implementations follow the "final" specifications + * as published for the third round of the SHA-3 competition (BLAKE, + * Groestl, JH, Keccak and Skein have been tweaked for third round). + * + * - BLAKE family: file sph_blake.h + * - BLAKE-224: short name: blake224 + * - BLAKE-256: short name: blake256 + * - BLAKE-384: short name: blake384 + * - BLAKE-512: short name: blake512 + * - BMW (Blue Midnight Wish) family: file sph_bmw.h + * - BMW-224: short name: bmw224 + * - BMW-256: short name: bmw256 + * - BMW-384: short name: bmw384 (64) + * - BMW-512: short name: bmw512 (64) + * - CubeHash family: file sph_cubehash.h (specified as + * CubeHash16/32 in the CubeHash specification) + * - CubeHash-224: short name: cubehash224 + * - CubeHash-256: short name: cubehash256 + * - CubeHash-384: short name: cubehash384 + * - CubeHash-512: short name: cubehash512 + * - ECHO family: file sph_echo.h + * - ECHO-224: short name: echo224 + * - ECHO-256: short name: echo256 + * - ECHO-384: short name: echo384 + * - ECHO-512: short name: echo512 + * - Fugue family: file sph_fugue.h + * - Fugue-224: short name: fugue224 + * - Fugue-256: short name: fugue256 + * - Fugue-384: short name: fugue384 + * - Fugue-512: short name: fugue512 + * - Groestl family: file sph_groestl.h + * - Groestl-224: short name: groestl224 + * - Groestl-256: short name: groestl256 + * - Groestl-384: short name: groestl384 + * - Groestl-512: short name: groestl512 + * - Hamsi family: file sph_hamsi.h + * - Hamsi-224: short name: hamsi224 + * - Hamsi-256: short name: hamsi256 + * - Hamsi-384: short name: hamsi384 + * - Hamsi-512: short name: hamsi512 + * - JH family: file sph_jh.h + * - JH-224: short name: jh224 + * - JH-256: short name: jh256 + * - JH-384: short name: jh384 + * - JH-512: short name: jh512 + * - Keccak family: file sph_keccak.h + * - Keccak-224: short name: keccak224 + * - Keccak-256: short name: keccak256 + * - Keccak-384: short name: keccak384 + * - Keccak-512: short name: keccak512 + * - Luffa family: file sph_luffa.h + * - Luffa-224: short name: luffa224 + * - Luffa-256: short name: luffa256 + * - Luffa-384: short name: luffa384 + * - Luffa-512: short name: luffa512 + * - Shabal family: file sph_shabal.h + * - Shabal-192: short name: shabal192 + * - Shabal-224: short name: shabal224 + * - Shabal-256: short name: shabal256 + * - Shabal-384: short name: shabal384 + * - Shabal-512: short name: shabal512 + * - SHAvite-3 family: file sph_shavite.h + * - SHAvite-224 (nominally "SHAvite-3 with 224-bit output"): + * short name: shabal224 + * - SHAvite-256 (nominally "SHAvite-3 with 256-bit output"): + * short name: shabal256 + * - SHAvite-384 (nominally "SHAvite-3 with 384-bit output"): + * short name: shabal384 + * - SHAvite-512 (nominally "SHAvite-3 with 512-bit output"): + * short name: shabal512 + * - SIMD family: file sph_simd.h + * - SIMD-224: short name: simd224 + * - SIMD-256: short name: simd256 + * - SIMD-384: short name: simd384 + * - SIMD-512: short name: simd512 + * - Skein family: file sph_skein.h + * - Skein-224 (nominally specified as Skein-512-224): short name: + * skein224 (64) + * - Skein-256 (nominally specified as Skein-512-256): short name: + * skein256 (64) + * - Skein-384 (nominally specified as Skein-512-384): short name: + * skein384 (64) + * - Skein-512 (nominally specified as Skein-512-512): short name: + * skein512 (64) + * + * For the second-round SHA-3 candidates, the functions are as specified + * for round 2, i.e. with the "tweaks" that some candidates added + * between round 1 and round 2. Also, some of the submitted packages for + * round 2 contained errors, in the specification, reference code, or + * both. sphlib implements the corrected versions. + */ + +/** @hideinitializer + * Unsigned integer type whose length is at least 32 bits; on most + * architectures, it will have a width of exactly 32 bits. Unsigned C + * types implement arithmetics modulo a power of 2; use the + * SPH_T32() macro to ensure that the value is truncated + * to exactly 32 bits. Unless otherwise specified, all macros and + * functions which accept sph_u32 values assume that these + * values fit on 32 bits, i.e. do not exceed 2^32-1, even on architectures + * where sph_u32 is larger than that. + */ +typedef __arch_dependant__ sph_u32; + +/** @hideinitializer + * Signed integer type corresponding to sph_u32; it has + * width 32 bits or more. + */ +typedef __arch_dependant__ sph_s32; + +/** @hideinitializer + * Unsigned integer type whose length is at least 64 bits; on most + * architectures which feature such a type, it will have a width of + * exactly 64 bits. C99-compliant platform will have this type; it + * is also defined when the GNU compiler (gcc) is used, and on + * platforms where unsigned long is large enough. If this + * type is not available, then some hash functions which depends on + * a 64-bit type will not be available (most notably SHA-384, SHA-512, + * Tiger and WHIRLPOOL). + */ +typedef __arch_dependant__ sph_u64; + +/** @hideinitializer + * Signed integer type corresponding to sph_u64; it has + * width 64 bits or more. + */ +typedef __arch_dependant__ sph_s64; + +/** + * This macro expands the token x into a suitable + * constant expression of type sph_u32. Depending on + * how this type is defined, a suffix such as UL may + * be appended to the argument. + * + * @param x the token to expand into a suitable constant expression + */ +#define SPH_C32(x) + +/** + * Truncate a 32-bit value to exactly 32 bits. On most systems, this is + * a no-op, recognized as such by the compiler. + * + * @param x the value to truncate (of type sph_u32) + */ +#define SPH_T32(x) + +/** + * Rotate a 32-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 31. This macro assumes that its + * first argument fits in 32 bits (no extra bit allowed on machines where + * sph_u32 is wider); both arguments may be evaluated + * several times. + * + * @param x the value to rotate (of type sph_u32) + * @param n the rotation count (between 1 and 31, inclusive) + */ +#define SPH_ROTL32(x, n) + +/** + * Rotate a 32-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 31. This macro assumes that its + * first argument fits in 32 bits (no extra bit allowed on machines where + * sph_u32 is wider); both arguments may be evaluated + * several times. + * + * @param x the value to rotate (of type sph_u32) + * @param n the rotation count (between 1 and 31, inclusive) + */ +#define SPH_ROTR32(x, n) + +/** + * This macro is defined on systems for which a 64-bit type has been + * detected, and is used for sph_u64. + */ +#define SPH_64 + +/** + * This macro is defined on systems for the "native" integer size is + * 64 bits (64-bit values fit in one register). + */ +#define SPH_64_TRUE + +/** + * This macro expands the token x into a suitable + * constant expression of type sph_u64. Depending on + * how this type is defined, a suffix such as ULL may + * be appended to the argument. This macro is defined only if a + * 64-bit type was detected and used for sph_u64. + * + * @param x the token to expand into a suitable constant expression + */ +#define SPH_C64(x) + +/** + * Truncate a 64-bit value to exactly 64 bits. On most systems, this is + * a no-op, recognized as such by the compiler. This macro is defined only + * if a 64-bit type was detected and used for sph_u64. + * + * @param x the value to truncate (of type sph_u64) + */ +#define SPH_T64(x) + +/** + * Rotate a 64-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 63. This macro assumes that its + * first argument fits in 64 bits (no extra bit allowed on machines where + * sph_u64 is wider); both arguments may be evaluated + * several times. This macro is defined only if a 64-bit type was detected + * and used for sph_u64. + * + * @param x the value to rotate (of type sph_u64) + * @param n the rotation count (between 1 and 63, inclusive) + */ +#define SPH_ROTL64(x, n) + +/** + * Rotate a 64-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 63. This macro assumes that its + * first argument fits in 64 bits (no extra bit allowed on machines where + * sph_u64 is wider); both arguments may be evaluated + * several times. This macro is defined only if a 64-bit type was detected + * and used for sph_u64. + * + * @param x the value to rotate (of type sph_u64) + * @param n the rotation count (between 1 and 63, inclusive) + */ +#define SPH_ROTR64(x, n) + +/** + * This macro evaluates to inline or an equivalent construction, + * if available on the compilation platform, or to nothing otherwise. This + * is used to declare inline functions, for which the compiler should + * endeavour to include the code directly in the caller. Inline functions + * are typically defined in header files as replacement for macros. + */ +#define SPH_INLINE + +/** + * This macro is defined if the platform has been detected as using + * little-endian convention. This implies that the sph_u32 + * type (and the sph_u64 type also, if it is defined) has + * an exact width (i.e. exactly 32-bit, respectively 64-bit). + */ +#define SPH_LITTLE_ENDIAN + +/** + * This macro is defined if the platform has been detected as using + * big-endian convention. This implies that the sph_u32 + * type (and the sph_u64 type also, if it is defined) has + * an exact width (i.e. exactly 32-bit, respectively 64-bit). + */ +#define SPH_BIG_ENDIAN + +/** + * This macro is defined if 32-bit words (and 64-bit words, if defined) + * can be read from and written to memory efficiently in little-endian + * convention. This is the case for little-endian platforms, and also + * for the big-endian platforms which have special little-endian access + * opcodes (e.g. Ultrasparc). + */ +#define SPH_LITTLE_FAST + +/** + * This macro is defined if 32-bit words (and 64-bit words, if defined) + * can be read from and written to memory efficiently in big-endian + * convention. This is the case for little-endian platforms, and also + * for the little-endian platforms which have special big-endian access + * opcodes. + */ +#define SPH_BIG_FAST + +/** + * On some platforms, this macro is defined to an unsigned integer type + * into which pointer values may be cast. The resulting value can then + * be tested for being a multiple of 2, 4 or 8, indicating an aligned + * pointer for, respectively, 16-bit, 32-bit or 64-bit memory accesses. + */ +#define SPH_UPTR + +/** + * When defined, this macro indicates that unaligned memory accesses + * are possible with only a minor penalty, and thus should be prefered + * over strategies which first copy data to an aligned buffer. + */ +#define SPH_UNALIGNED + +/** + * Byte-swap a 32-bit word (i.e. 0x12345678 becomes + * 0x78563412). This is an inline function which resorts + * to inline assembly on some platforms, for better performance. + * + * @param x the 32-bit value to byte-swap + * @return the byte-swapped value + */ +static inline sph_u32 sph_bswap32(sph_u32 x); + +/** + * Byte-swap a 64-bit word. This is an inline function which resorts + * to inline assembly on some platforms, for better performance. This + * function is defined only if a suitable 64-bit type was found for + * sph_u64 + * + * @param x the 64-bit value to byte-swap + * @return the byte-swapped value + */ +static inline sph_u64 sph_bswap64(sph_u64 x); + +/** + * Decode a 16-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline unsigned sph_dec16le(const void *src); + +/** + * Encode a 16-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc16le(void *dst, unsigned val); + +/** + * Decode a 16-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline unsigned sph_dec16be(const void *src); + +/** + * Encode a 16-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc16be(void *dst, unsigned val); + +/** + * Decode a 32-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32le(const void *src); + +/** + * Decode a 32-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec32le() function. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32le_aligned(const void *src); + +/** + * Encode a 32-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32le(void *dst, sph_u32 val); + +/** + * Encode a 32-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc32le() function. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32le_aligned(void *dst, sph_u32 val); + +/** + * Decode a 32-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32be(const void *src); + +/** + * Decode a 32-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec32be() function. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32be_aligned(const void *src); + +/** + * Encode a 32-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32be(void *dst, sph_u32 val); + +/** + * Encode a 32-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc32be() function. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32be_aligned(void *dst, sph_u32 val); + +/** + * Decode a 64-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64le(const void *src); + +/** + * Decode a 64-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec64le() function. This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64le_aligned(const void *src); + +/** + * Encode a 64-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64le(void *dst, sph_u64 val); + +/** + * Encode a 64-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc64le() function. This function is defined + * only if a suitable 64-bit type was detected and used for + * sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64le_aligned(void *dst, sph_u64 val); + +/** + * Decode a 64-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64be(const void *src); + +/** + * Decode a 64-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec64be() function. This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64be_aligned(const void *src); + +/** + * Encode a 64-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64be(void *dst, sph_u64 val); + +/** + * Encode a 64-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc64be() function. This function is defined + * only if a suitable 64-bit type was detected and used for + * sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64be_aligned(void *dst, sph_u64 val); + +#endif + +/* ============== END documentation block for Doxygen ============= */ + +#ifndef DOXYGEN_IGNORE + +/* + * We want to define the types "sph_u32" and "sph_u64" which hold + * unsigned values of at least, respectively, 32 and 64 bits. These + * tests should select appropriate types for most platforms. The + * macro "SPH_64" is defined if the 64-bit is supported. + */ + +#undef SPH_64 +#undef SPH_64_TRUE + +#if defined __STDC__ && __STDC_VERSION__ >= 199901L + +/* + * On C99 implementations, we can use to get an exact 64-bit + * type, if any, or otherwise use a wider type (which must exist, for + * C99 conformance). + */ + +#include + +#ifdef UINT32_MAX +typedef uint32_t sph_u32; +typedef int32_t sph_s32; +#else +typedef uint_fast32_t sph_u32; +typedef int_fast32_t sph_s32; +#endif +#if !SPH_NO_64 +#ifdef UINT64_MAX +typedef uint64_t sph_u64; +typedef int64_t sph_s64; +#else +typedef uint_fast64_t sph_u64; +typedef int_fast64_t sph_s64; +#endif +#endif + +#define SPH_C32(x) ((sph_u32)(x)) +#if !SPH_NO_64 +#define SPH_C64(x) ((sph_u64)(x)) +#define SPH_64 1 +#endif + +#else + +/* + * On non-C99 systems, we use "unsigned int" if it is wide enough, + * "unsigned long" otherwise. This supports all "reasonable" architectures. + * We have to be cautious: pre-C99 preprocessors handle constants + * differently in '#if' expressions. Hence the shifts to test UINT_MAX. + */ + +#if ((UINT_MAX >> 11) >> 11) >= 0x3FF + +typedef unsigned int sph_u32; +typedef int sph_s32; + +#define SPH_C32(x) ((sph_u32)(x ## U)) + +#else + +typedef unsigned long sph_u32; +typedef long sph_s32; + +#define SPH_C32(x) ((sph_u32)(x ## UL)) + +#endif + +#if !SPH_NO_64 + +/* + * We want a 64-bit type. We use "unsigned long" if it is wide enough (as + * is common on 64-bit architectures such as AMD64, Alpha or Sparcv9), + * "unsigned long long" otherwise, if available. We use ULLONG_MAX to + * test whether "unsigned long long" is available; we also know that + * gcc features this type, even if the libc header do not know it. + */ + +#if ((ULONG_MAX >> 31) >> 31) >= 3 + +typedef unsigned long sph_u64; +typedef long sph_s64; + +#define SPH_C64(x) ((sph_u64)(x ## UL)) + +#define SPH_64 1 + +#elif ((ULLONG_MAX >> 31) >> 31) >= 3 || defined __GNUC__ + +typedef unsigned long long sph_u64; +typedef long long sph_s64; + +#define SPH_C64(x) ((sph_u64)(x ## ULL)) + +#define SPH_64 1 + +#else + +/* + * No 64-bit type... + */ + +#endif + +#endif + +#endif + +/* + * If the "unsigned long" type has length 64 bits or more, then this is + * a "true" 64-bit architectures. This is also true with Visual C on + * amd64, even though the "long" type is limited to 32 bits. + */ +#if SPH_64 && (((ULONG_MAX >> 31) >> 31) >= 3 || defined _M_X64) +#define SPH_64_TRUE 1 +#endif + +/* + * Implementation note: some processors have specific opcodes to perform + * a rotation. Recent versions of gcc recognize the expression above and + * use the relevant opcodes, when appropriate. + */ + +#define SPH_T32(x) ((x) & SPH_C32(0xFFFFFFFF)) +#define SPH_ROTL32(x, n) SPH_T32(((x) << (n)) | ((x) >> (32 - (n)))) +#define SPH_ROTR32(x, n) SPH_ROTL32(x, (32 - (n))) + +#if SPH_64 + +#define SPH_T64(x) ((x) & SPH_C64(0xFFFFFFFFFFFFFFFF)) +#define SPH_ROTL64(x, n) SPH_T64(((x) << (n)) | ((x) >> (64 - (n)))) +#define SPH_ROTR64(x, n) SPH_ROTL64(x, (64 - (n))) + +#endif + +#ifndef DOXYGEN_IGNORE +/* + * Define SPH_INLINE to be an "inline" qualifier, if available. We define + * some small macro-like functions which benefit greatly from being inlined. + */ +#if (defined __STDC__ && __STDC_VERSION__ >= 199901L) || defined __GNUC__ +#define SPH_INLINE inline +#elif defined _MSC_VER +#define SPH_INLINE __inline +#else +#define SPH_INLINE +#endif +#endif + +/* + * We define some macros which qualify the architecture. These macros + * may be explicit set externally (e.g. as compiler parameters). The + * code below sets those macros if they are not already defined. + * + * Most macros are boolean, thus evaluate to either zero or non-zero. + * The SPH_UPTR macro is special, in that it evaluates to a C type, + * or is not defined. + * + * SPH_UPTR if defined: unsigned type to cast pointers into + * + * SPH_UNALIGNED non-zero if unaligned accesses are efficient + * SPH_LITTLE_ENDIAN non-zero if architecture is known to be little-endian + * SPH_BIG_ENDIAN non-zero if architecture is known to be big-endian + * SPH_LITTLE_FAST non-zero if little-endian decoding is fast + * SPH_BIG_FAST non-zero if big-endian decoding is fast + * + * If SPH_UPTR is defined, then encoding and decoding of 32-bit and 64-bit + * values will try to be "smart". Either SPH_LITTLE_ENDIAN or SPH_BIG_ENDIAN + * _must_ be non-zero in those situations. The 32-bit and 64-bit types + * _must_ also have an exact width. + * + * SPH_SPARCV9_GCC_32 UltraSPARC-compatible with gcc, 32-bit mode + * SPH_SPARCV9_GCC_64 UltraSPARC-compatible with gcc, 64-bit mode + * SPH_SPARCV9_GCC UltraSPARC-compatible with gcc + * SPH_I386_GCC x86-compatible (32-bit) with gcc + * SPH_I386_MSVC x86-compatible (32-bit) with Microsoft Visual C + * SPH_AMD64_GCC x86-compatible (64-bit) with gcc + * SPH_AMD64_MSVC x86-compatible (64-bit) with Microsoft Visual C + * SPH_PPC32_GCC PowerPC, 32-bit, with gcc + * SPH_PPC64_GCC PowerPC, 64-bit, with gcc + * + * TODO: enhance automatic detection, for more architectures and compilers. + * Endianness is the most important. SPH_UNALIGNED and SPH_UPTR help with + * some very fast functions (e.g. MD4) when using unaligned input data. + * The CPU-specific-with-GCC macros are useful only for inline assembly, + * normally restrained to this header file. + */ + +/* + * 32-bit x86, aka "i386 compatible". + */ +#if defined __i386__ || defined _M_IX86 + +#define SPH_DETECT_UNALIGNED 1 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u32 +#ifdef __GNUC__ +#define SPH_DETECT_I386_GCC 1 +#endif +#ifdef _MSC_VER +#define SPH_DETECT_I386_MSVC 1 +#endif + +/* + * 64-bit x86, hereafter known as "amd64". + */ +#elif defined __x86_64 || defined _M_X64 + +#define SPH_DETECT_UNALIGNED 1 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u64 +#ifdef __GNUC__ +#define SPH_DETECT_AMD64_GCC 1 +#endif +#ifdef _MSC_VER +#define SPH_DETECT_AMD64_MSVC 1 +#endif + +/* + * 64-bit Sparc architecture (implies v9). + */ +#elif ((defined __sparc__ || defined __sparc) && defined __arch64__) \ + || defined __sparcv9 + +#define SPH_DETECT_BIG_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u64 +#ifdef __GNUC__ +#define SPH_DETECT_SPARCV9_GCC_64 1 +#define SPH_DETECT_LITTLE_FAST 1 +#endif + +/* + * 32-bit Sparc. + */ +#elif (defined __sparc__ || defined __sparc) \ + && !(defined __sparcv9 || defined __arch64__) + +#define SPH_DETECT_BIG_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u32 +#if defined __GNUC__ && defined __sparc_v9__ +#define SPH_DETECT_SPARCV9_GCC_32 1 +#define SPH_DETECT_LITTLE_FAST 1 +#endif + +/* + * ARM, little-endian. + */ +#elif defined __arm__ && __ARMEL__ + +#define SPH_DETECT_LITTLE_ENDIAN 1 + +/* + * MIPS, little-endian. + */ +#elif MIPSEL || _MIPSEL || __MIPSEL || __MIPSEL__ + +#define SPH_DETECT_LITTLE_ENDIAN 1 + +/* + * MIPS, big-endian. + */ +#elif MIPSEB || _MIPSEB || __MIPSEB || __MIPSEB__ + +#define SPH_DETECT_BIG_ENDIAN 1 + +/* + * PowerPC. + */ +#elif defined __powerpc__ || defined __POWERPC__ || defined __ppc__ \ + || defined _ARCH_PPC + +/* + * Note: we do not declare cross-endian access to be "fast": even if + * using inline assembly, implementation should still assume that + * keeping the decoded word in a temporary is faster than decoding + * it again. + */ +#if defined __GNUC__ +#if SPH_64_TRUE +#define SPH_DETECT_PPC64_GCC 1 +#else +#define SPH_DETECT_PPC32_GCC 1 +#endif +#endif + +#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN +#define SPH_DETECT_BIG_ENDIAN 1 +#elif defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN +#define SPH_DETECT_LITTLE_ENDIAN 1 +#endif + +/* + * Itanium, 64-bit. + */ +#elif defined __ia64 || defined __ia64__ \ + || defined __itanium__ || defined _M_IA64 + +#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN +#define SPH_DETECT_BIG_ENDIAN 1 +#else +#define SPH_DETECT_LITTLE_ENDIAN 1 +#endif +#if defined __LP64__ || defined _LP64 +#define SPH_DETECT_UPTR sph_u64 +#else +#define SPH_DETECT_UPTR sph_u32 +#endif + +#endif + +#if defined SPH_DETECT_SPARCV9_GCC_32 || defined SPH_DETECT_SPARCV9_GCC_64 +#define SPH_DETECT_SPARCV9_GCC 1 +#endif + +#if defined SPH_DETECT_UNALIGNED && !defined SPH_UNALIGNED +#define SPH_UNALIGNED SPH_DETECT_UNALIGNED +#endif +#if defined SPH_DETECT_UPTR && !defined SPH_UPTR +#define SPH_UPTR SPH_DETECT_UPTR +#endif +#if defined SPH_DETECT_LITTLE_ENDIAN && !defined SPH_LITTLE_ENDIAN +#define SPH_LITTLE_ENDIAN SPH_DETECT_LITTLE_ENDIAN +#endif +#if defined SPH_DETECT_BIG_ENDIAN && !defined SPH_BIG_ENDIAN +#define SPH_BIG_ENDIAN SPH_DETECT_BIG_ENDIAN +#endif +#if defined SPH_DETECT_LITTLE_FAST && !defined SPH_LITTLE_FAST +#define SPH_LITTLE_FAST SPH_DETECT_LITTLE_FAST +#endif +#if defined SPH_DETECT_BIG_FAST && !defined SPH_BIG_FAST +#define SPH_BIG_FAST SPH_DETECT_BIG_FAST +#endif +#if defined SPH_DETECT_SPARCV9_GCC_32 && !defined SPH_SPARCV9_GCC_32 +#define SPH_SPARCV9_GCC_32 SPH_DETECT_SPARCV9_GCC_32 +#endif +#if defined SPH_DETECT_SPARCV9_GCC_64 && !defined SPH_SPARCV9_GCC_64 +#define SPH_SPARCV9_GCC_64 SPH_DETECT_SPARCV9_GCC_64 +#endif +#if defined SPH_DETECT_SPARCV9_GCC && !defined SPH_SPARCV9_GCC +#define SPH_SPARCV9_GCC SPH_DETECT_SPARCV9_GCC +#endif +#if defined SPH_DETECT_I386_GCC && !defined SPH_I386_GCC +#define SPH_I386_GCC SPH_DETECT_I386_GCC +#endif +#if defined SPH_DETECT_I386_MSVC && !defined SPH_I386_MSVC +#define SPH_I386_MSVC SPH_DETECT_I386_MSVC +#endif +#if defined SPH_DETECT_AMD64_GCC && !defined SPH_AMD64_GCC +#define SPH_AMD64_GCC SPH_DETECT_AMD64_GCC +#endif +#if defined SPH_DETECT_AMD64_MSVC && !defined SPH_AMD64_MSVC +#define SPH_AMD64_MSVC SPH_DETECT_AMD64_MSVC +#endif +#if defined SPH_DETECT_PPC32_GCC && !defined SPH_PPC32_GCC +#define SPH_PPC32_GCC SPH_DETECT_PPC32_GCC +#endif +#if defined SPH_DETECT_PPC64_GCC && !defined SPH_PPC64_GCC +#define SPH_PPC64_GCC SPH_DETECT_PPC64_GCC +#endif + +#if SPH_LITTLE_ENDIAN && !defined SPH_LITTLE_FAST +#define SPH_LITTLE_FAST 1 +#endif +#if SPH_BIG_ENDIAN && !defined SPH_BIG_FAST +#define SPH_BIG_FAST 1 +#endif + +#if defined SPH_UPTR && !(SPH_LITTLE_ENDIAN || SPH_BIG_ENDIAN) +#error SPH_UPTR defined, but endianness is not known. +#endif + +#if SPH_I386_GCC && !SPH_NO_ASM + +/* + * On x86 32-bit, with gcc, we use the bswapl opcode to byte-swap 32-bit + * values. + */ + +static SPH_INLINE sph_u32 +sph_bswap32(sph_u32 x) +{ + __asm__ __volatile__ ("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} + +#if SPH_64 + +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + return ((sph_u64)sph_bswap32((sph_u32)x) << 32) + | (sph_u64)sph_bswap32((sph_u32)(x >> 32)); +} + +#endif + +#elif SPH_AMD64_GCC && !SPH_NO_ASM + +/* + * On x86 64-bit, with gcc, we use the bswapl opcode to byte-swap 32-bit + * and 64-bit values. + */ + +static SPH_INLINE sph_u32 +sph_bswap32(sph_u32 x) +{ + __asm__ __volatile__ ("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} + +#if SPH_64 + +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + __asm__ __volatile__ ("bswapq %0" : "=r" (x) : "0" (x)); + return x; +} + +#endif + +/* + * Disabled code. Apparently, Microsoft Visual C 2005 is smart enough + * to generate proper opcodes for endianness swapping with the pure C + * implementation below. + * + +#elif SPH_I386_MSVC && !SPH_NO_ASM + +static __inline sph_u32 __declspec(naked) __fastcall +sph_bswap32(sph_u32 x) +{ + __asm { + bswap ecx + mov eax,ecx + ret + } +} + +#if SPH_64 + +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + return ((sph_u64)sph_bswap32((sph_u32)x) << 32) + | (sph_u64)sph_bswap32((sph_u32)(x >> 32)); +} + +#endif + + * + * [end of disabled code] + */ + +#else + +static SPH_INLINE sph_u32 +sph_bswap32(sph_u32 x) +{ + x = SPH_T32((x << 16) | (x >> 16)); + x = ((x & SPH_C32(0xFF00FF00)) >> 8) + | ((x & SPH_C32(0x00FF00FF)) << 8); + return x; +} + +#if SPH_64 + +/** + * Byte-swap a 64-bit value. + * + * @param x the input value + * @return the byte-swapped value + */ +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + x = SPH_T64((x << 32) | (x >> 32)); + x = ((x & SPH_C64(0xFFFF0000FFFF0000)) >> 16) + | ((x & SPH_C64(0x0000FFFF0000FFFF)) << 16); + x = ((x & SPH_C64(0xFF00FF00FF00FF00)) >> 8) + | ((x & SPH_C64(0x00FF00FF00FF00FF)) << 8); + return x; +} + +#endif + +#endif + +#if SPH_SPARCV9_GCC && !SPH_NO_ASM + +/* + * On UltraSPARC systems, native ordering is big-endian, but it is + * possible to perform little-endian read accesses by specifying the + * address space 0x88 (ASI_PRIMARY_LITTLE). Basically, either we use + * the opcode "lda [%reg]0x88,%dst", where %reg is the register which + * contains the source address and %dst is the destination register, + * or we use "lda [%reg+imm]%asi,%dst", which uses the %asi register + * to get the address space name. The latter format is better since it + * combines an addition and the actual access in a single opcode; but + * it requires the setting (and subsequent resetting) of %asi, which is + * slow. Some operations (i.e. MD5 compression function) combine many + * successive little-endian read accesses, which may share the same + * %asi setting. The macros below contain the appropriate inline + * assembly. + */ + +#define SPH_SPARCV9_SET_ASI \ + sph_u32 sph_sparcv9_asi; \ + __asm__ __volatile__ ( \ + "rd %%asi,%0\n\twr %%g0,0x88,%%asi" : "=r" (sph_sparcv9_asi)); + +#define SPH_SPARCV9_RESET_ASI \ + __asm__ __volatile__ ("wr %%g0,%0,%%asi" : : "r" (sph_sparcv9_asi)); + +#define SPH_SPARCV9_DEC32LE(base, idx) ({ \ + sph_u32 sph_sparcv9_tmp; \ + __asm__ __volatile__ ("lda [%1+" #idx "*4]%%asi,%0" \ + : "=r" (sph_sparcv9_tmp) : "r" (base)); \ + sph_sparcv9_tmp; \ + }) + +#endif + +static SPH_INLINE void +sph_enc16be(void *dst, unsigned val) +{ + ((unsigned char *)dst)[0] = (val >> 8); + ((unsigned char *)dst)[1] = val; +} + +static SPH_INLINE unsigned +sph_dec16be(const void *src) +{ + return ((unsigned)(((const unsigned char *)src)[0]) << 8) + | (unsigned)(((const unsigned char *)src)[1]); +} + +static SPH_INLINE void +sph_enc16le(void *dst, unsigned val) +{ + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = val >> 8; +} + +static SPH_INLINE unsigned +sph_dec16le(const void *src) +{ + return (unsigned)(((const unsigned char *)src)[0]) + | ((unsigned)(((const unsigned char *)src)[1]) << 8); +} + +/** + * Encode a 32-bit value into the provided buffer (big endian convention). + * + * @param dst the destination buffer + * @param val the 32-bit value to encode + */ +static SPH_INLINE void +sph_enc32be(void *dst, sph_u32 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; +#else + if (((SPH_UPTR)dst & 3) == 0) { +#if SPH_LITTLE_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; + } else { + ((unsigned char *)dst)[0] = (val >> 24); + ((unsigned char *)dst)[1] = (val >> 16); + ((unsigned char *)dst)[2] = (val >> 8); + ((unsigned char *)dst)[3] = val; + } +#endif +#else + ((unsigned char *)dst)[0] = (val >> 24); + ((unsigned char *)dst)[1] = (val >> 16); + ((unsigned char *)dst)[2] = (val >> 8); + ((unsigned char *)dst)[3] = val; +#endif +} + +/** + * Encode a 32-bit value into the provided buffer (big endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (32-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc32be_aligned(void *dst, sph_u32 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u32 *)dst = sph_bswap32(val); +#elif SPH_BIG_ENDIAN + *(sph_u32 *)dst = val; +#else + ((unsigned char *)dst)[0] = (val >> 24); + ((unsigned char *)dst)[1] = (val >> 16); + ((unsigned char *)dst)[2] = (val >> 8); + ((unsigned char *)dst)[3] = val; +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (big endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32be(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#else + return *(const sph_u32 *)src; +#endif +#else + if (((SPH_UPTR)src & 3) == 0) { +#if SPH_LITTLE_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#else + return *(const sph_u32 *)src; +#endif + } else { + return ((sph_u32)(((const unsigned char *)src)[0]) << 24) + | ((sph_u32)(((const unsigned char *)src)[1]) << 16) + | ((sph_u32)(((const unsigned char *)src)[2]) << 8) + | (sph_u32)(((const unsigned char *)src)[3]); + } +#endif +#else + return ((sph_u32)(((const unsigned char *)src)[0]) << 24) + | ((sph_u32)(((const unsigned char *)src)[1]) << 16) + | ((sph_u32)(((const unsigned char *)src)[2]) << 8) + | (sph_u32)(((const unsigned char *)src)[3]); +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (big endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (32-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32be_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#elif SPH_BIG_ENDIAN + return *(const sph_u32 *)src; +#else + return ((sph_u32)(((const unsigned char *)src)[0]) << 24) + | ((sph_u32)(((const unsigned char *)src)[1]) << 16) + | ((sph_u32)(((const unsigned char *)src)[2]) << 8) + | (sph_u32)(((const unsigned char *)src)[3]); +#endif +} + +/** + * Encode a 32-bit value into the provided buffer (little endian convention). + * + * @param dst the destination buffer + * @param val the 32-bit value to encode + */ +static SPH_INLINE void +sph_enc32le(void *dst, sph_u32 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; +#else + if (((SPH_UPTR)dst & 3) == 0) { +#if SPH_BIG_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; + } else { + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + } +#endif +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); +#endif +} + +/** + * Encode a 32-bit value into the provided buffer (little endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (32-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc32le_aligned(void *dst, sph_u32 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u32 *)dst = val; +#elif SPH_BIG_ENDIAN + *(sph_u32 *)dst = sph_bswap32(val); +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (little endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32le(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#else + return *(const sph_u32 *)src; +#endif +#else + if (((SPH_UPTR)src & 3) == 0) { +#if SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC && !SPH_NO_ASM + sph_u32 tmp; + + /* + * "__volatile__" is needed here because without it, + * gcc-3.4.3 miscompiles the code and performs the + * access before the test on the address, thus triggering + * a bus error... + */ + __asm__ __volatile__ ( + "lda [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * On PowerPC, this turns out not to be worth the effort: the inline + * assembly makes GCC optimizer uncomfortable, which tends to nullify + * the decoding gains. + * + * For most hash functions, using this inline assembly trick changes + * hashing speed by less than 5% and often _reduces_ it. The biggest + * gains are for MD4 (+11%) and CubeHash (+30%). For all others, it is + * less then 10%. The speed gain on CubeHash is probably due to the + * chronic shortage of registers that CubeHash endures; for the other + * functions, the generic code appears to be efficient enough already. + * +#elif (SPH_PPC32_GCC || SPH_PPC64_GCC) && !SPH_NO_ASM + sph_u32 tmp; + + __asm__ __volatile__ ( + "lwbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap32(*(const sph_u32 *)src); +#endif +#else + return *(const sph_u32 *)src; +#endif + } else { + return (sph_u32)(((const unsigned char *)src)[0]) + | ((sph_u32)(((const unsigned char *)src)[1]) << 8) + | ((sph_u32)(((const unsigned char *)src)[2]) << 16) + | ((sph_u32)(((const unsigned char *)src)[3]) << 24); + } +#endif +#else + return (sph_u32)(((const unsigned char *)src)[0]) + | ((sph_u32)(((const unsigned char *)src)[1]) << 8) + | ((sph_u32)(((const unsigned char *)src)[2]) << 16) + | ((sph_u32)(((const unsigned char *)src)[3]) << 24); +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (little endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (32-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32le_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return *(const sph_u32 *)src; +#elif SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC && !SPH_NO_ASM + sph_u32 tmp; + + __asm__ __volatile__ ("lda [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * Not worth it generally. + * +#elif (SPH_PPC32_GCC || SPH_PPC64_GCC) && !SPH_NO_ASM + sph_u32 tmp; + + __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap32(*(const sph_u32 *)src); +#endif +#else + return (sph_u32)(((const unsigned char *)src)[0]) + | ((sph_u32)(((const unsigned char *)src)[1]) << 8) + | ((sph_u32)(((const unsigned char *)src)[2]) << 16) + | ((sph_u32)(((const unsigned char *)src)[3]) << 24); +#endif +} + +#if SPH_64 + +/** + * Encode a 64-bit value into the provided buffer (big endian convention). + * + * @param dst the destination buffer + * @param val the 64-bit value to encode + */ +static SPH_INLINE void +sph_enc64be(void *dst, sph_u64 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; +#else + if (((SPH_UPTR)dst & 7) == 0) { +#if SPH_LITTLE_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; + } else { + ((unsigned char *)dst)[0] = (val >> 56); + ((unsigned char *)dst)[1] = (val >> 48); + ((unsigned char *)dst)[2] = (val >> 40); + ((unsigned char *)dst)[3] = (val >> 32); + ((unsigned char *)dst)[4] = (val >> 24); + ((unsigned char *)dst)[5] = (val >> 16); + ((unsigned char *)dst)[6] = (val >> 8); + ((unsigned char *)dst)[7] = val; + } +#endif +#else + ((unsigned char *)dst)[0] = (val >> 56); + ((unsigned char *)dst)[1] = (val >> 48); + ((unsigned char *)dst)[2] = (val >> 40); + ((unsigned char *)dst)[3] = (val >> 32); + ((unsigned char *)dst)[4] = (val >> 24); + ((unsigned char *)dst)[5] = (val >> 16); + ((unsigned char *)dst)[6] = (val >> 8); + ((unsigned char *)dst)[7] = val; +#endif +} + +/** + * Encode a 64-bit value into the provided buffer (big endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (64-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc64be_aligned(void *dst, sph_u64 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u64 *)dst = sph_bswap64(val); +#elif SPH_BIG_ENDIAN + *(sph_u64 *)dst = val; +#else + ((unsigned char *)dst)[0] = (val >> 56); + ((unsigned char *)dst)[1] = (val >> 48); + ((unsigned char *)dst)[2] = (val >> 40); + ((unsigned char *)dst)[3] = (val >> 32); + ((unsigned char *)dst)[4] = (val >> 24); + ((unsigned char *)dst)[5] = (val >> 16); + ((unsigned char *)dst)[6] = (val >> 8); + ((unsigned char *)dst)[7] = val; +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (big endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64be(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#else + return *(const sph_u64 *)src; +#endif +#else + if (((SPH_UPTR)src & 7) == 0) { +#if SPH_LITTLE_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#else + return *(const sph_u64 *)src; +#endif + } else { + return ((sph_u64)(((const unsigned char *)src)[0]) << 56) + | ((sph_u64)(((const unsigned char *)src)[1]) << 48) + | ((sph_u64)(((const unsigned char *)src)[2]) << 40) + | ((sph_u64)(((const unsigned char *)src)[3]) << 32) + | ((sph_u64)(((const unsigned char *)src)[4]) << 24) + | ((sph_u64)(((const unsigned char *)src)[5]) << 16) + | ((sph_u64)(((const unsigned char *)src)[6]) << 8) + | (sph_u64)(((const unsigned char *)src)[7]); + } +#endif +#else + return ((sph_u64)(((const unsigned char *)src)[0]) << 56) + | ((sph_u64)(((const unsigned char *)src)[1]) << 48) + | ((sph_u64)(((const unsigned char *)src)[2]) << 40) + | ((sph_u64)(((const unsigned char *)src)[3]) << 32) + | ((sph_u64)(((const unsigned char *)src)[4]) << 24) + | ((sph_u64)(((const unsigned char *)src)[5]) << 16) + | ((sph_u64)(((const unsigned char *)src)[6]) << 8) + | (sph_u64)(((const unsigned char *)src)[7]); +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (big endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (64-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64be_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#elif SPH_BIG_ENDIAN + return *(const sph_u64 *)src; +#else + return ((sph_u64)(((const unsigned char *)src)[0]) << 56) + | ((sph_u64)(((const unsigned char *)src)[1]) << 48) + | ((sph_u64)(((const unsigned char *)src)[2]) << 40) + | ((sph_u64)(((const unsigned char *)src)[3]) << 32) + | ((sph_u64)(((const unsigned char *)src)[4]) << 24) + | ((sph_u64)(((const unsigned char *)src)[5]) << 16) + | ((sph_u64)(((const unsigned char *)src)[6]) << 8) + | (sph_u64)(((const unsigned char *)src)[7]); +#endif +} + +/** + * Encode a 64-bit value into the provided buffer (little endian convention). + * + * @param dst the destination buffer + * @param val the 64-bit value to encode + */ +static SPH_INLINE void +sph_enc64le(void *dst, sph_u64 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; +#else + if (((SPH_UPTR)dst & 7) == 0) { +#if SPH_BIG_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; + } else { + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char *)dst)[4] = (val >> 32); + ((unsigned char *)dst)[5] = (val >> 40); + ((unsigned char *)dst)[6] = (val >> 48); + ((unsigned char *)dst)[7] = (val >> 56); + } +#endif +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char *)dst)[4] = (val >> 32); + ((unsigned char *)dst)[5] = (val >> 40); + ((unsigned char *)dst)[6] = (val >> 48); + ((unsigned char *)dst)[7] = (val >> 56); +#endif +} + +/** + * Encode a 64-bit value into the provided buffer (little endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (64-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc64le_aligned(void *dst, sph_u64 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u64 *)dst = val; +#elif SPH_BIG_ENDIAN + *(sph_u64 *)dst = sph_bswap64(val); +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char *)dst)[4] = (val >> 32); + ((unsigned char *)dst)[5] = (val >> 40); + ((unsigned char *)dst)[6] = (val >> 48); + ((unsigned char *)dst)[7] = (val >> 56); +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (little endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64le(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#else + return *(const sph_u64 *)src; +#endif +#else + if (((SPH_UPTR)src & 7) == 0) { +#if SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC_64 && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ( + "ldxa [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * Not worth it generally. + * +#elif SPH_PPC32_GCC && !SPH_NO_ASM + return (sph_u64)sph_dec32le_aligned(src) + | ((sph_u64)sph_dec32le_aligned( + (const char *)src + 4) << 32); +#elif SPH_PPC64_GCC && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ( + "ldbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap64(*(const sph_u64 *)src); +#endif +#else + return *(const sph_u64 *)src; +#endif + } else { + return (sph_u64)(((const unsigned char *)src)[0]) + | ((sph_u64)(((const unsigned char *)src)[1]) << 8) + | ((sph_u64)(((const unsigned char *)src)[2]) << 16) + | ((sph_u64)(((const unsigned char *)src)[3]) << 24) + | ((sph_u64)(((const unsigned char *)src)[4]) << 32) + | ((sph_u64)(((const unsigned char *)src)[5]) << 40) + | ((sph_u64)(((const unsigned char *)src)[6]) << 48) + | ((sph_u64)(((const unsigned char *)src)[7]) << 56); + } +#endif +#else + return (sph_u64)(((const unsigned char *)src)[0]) + | ((sph_u64)(((const unsigned char *)src)[1]) << 8) + | ((sph_u64)(((const unsigned char *)src)[2]) << 16) + | ((sph_u64)(((const unsigned char *)src)[3]) << 24) + | ((sph_u64)(((const unsigned char *)src)[4]) << 32) + | ((sph_u64)(((const unsigned char *)src)[5]) << 40) + | ((sph_u64)(((const unsigned char *)src)[6]) << 48) + | ((sph_u64)(((const unsigned char *)src)[7]) << 56); +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (little endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (64-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64le_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return *(const sph_u64 *)src; +#elif SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC_64 && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ("ldxa [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * Not worth it generally. + * +#elif SPH_PPC32_GCC && !SPH_NO_ASM + return (sph_u64)sph_dec32le_aligned(src) + | ((sph_u64)sph_dec32le_aligned((const char *)src + 4) << 32); +#elif SPH_PPC64_GCC && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ("ldbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap64(*(const sph_u64 *)src); +#endif +#else + return (sph_u64)(((const unsigned char *)src)[0]) + | ((sph_u64)(((const unsigned char *)src)[1]) << 8) + | ((sph_u64)(((const unsigned char *)src)[2]) << 16) + | ((sph_u64)(((const unsigned char *)src)[3]) << 24) + | ((sph_u64)(((const unsigned char *)src)[4]) << 32) + | ((sph_u64)(((const unsigned char *)src)[5]) << 40) + | ((sph_u64)(((const unsigned char *)src)[6]) << 48) + | ((sph_u64)(((const unsigned char *)src)[7]) << 56); +#endif +} + +#endif + +#endif /* Doxygen excluded block */ + +#endif diff --git a/src/strlcpy.h b/src/strlcpy.h new file mode 100644 index 0000000..2cc786e --- /dev/null +++ b/src/strlcpy.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef BITCOIN_STRLCPY_H +#define BITCOIN_STRLCPY_H + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +inline size_t strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) + { + while (--n != 0) + { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) + { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +inline size_t strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') + { + if (n != 1) + { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} +#endif diff --git a/src/sync.cpp b/src/sync.cpp new file mode 100644 index 0000000..1ac4403 --- /dev/null +++ b/src/sync.cpp @@ -0,0 +1,128 @@ +// Copyright (c) 2011-2012 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 "sync.h" +#include "util.h" + +#include + +#ifdef DEBUG_LOCKCONTENTION +void PrintLockContention(const char* pszName, const char* pszFile, int nLine) +{ + printf("LOCKCONTENTION: %s\n", pszName); + printf("Locker: %s:%d\n", pszFile, nLine); +} +#endif /* DEBUG_LOCKCONTENTION */ + +#ifdef DEBUG_LOCKORDER +// +// Early deadlock detection. +// Problem being solved: +// Thread 1 locks A, then B, then C +// Thread 2 locks D, then C, then A +// --> may result in deadlock between the two threads, depending on when they run. +// Solution implemented here: +// Keep track of pairs of locks: (A before B), (A before C), etc. +// Complain if any thread tries to lock in a different order. +// + +struct CLockLocation +{ + CLockLocation(const char* pszName, const char* pszFile, int nLine) + { + mutexName = pszName; + sourceFile = pszFile; + sourceLine = nLine; + } + + std::string ToString() const + { + return mutexName+" "+sourceFile+":"+itostr(sourceLine); + } + +private: + std::string mutexName; + std::string sourceFile; + int sourceLine; +}; + +typedef std::vector< std::pair > LockStack; + +static boost::mutex dd_mutex; +static std::map, LockStack> lockorders; +static boost::thread_specific_ptr lockstack; + + +static void potential_deadlock_detected(const std::pair& mismatch, const LockStack& s1, const LockStack& s2) +{ + printf("POTENTIAL DEADLOCK DETECTED\n"); + printf("Previous lock order was:\n"); + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2) + { + if (i.first == mismatch.first) printf(" (1)"); + if (i.first == mismatch.second) printf(" (2)"); + printf(" %s\n", i.second.ToString().c_str()); + } + printf("Current lock order is:\n"); + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1) + { + if (i.first == mismatch.first) printf(" (1)"); + if (i.first == mismatch.second) printf(" (2)"); + printf(" %s\n", i.second.ToString().c_str()); + } +} + +static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) +{ + if (lockstack.get() == NULL) + lockstack.reset(new LockStack); + + if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str()); + dd_mutex.lock(); + + (*lockstack).push_back(std::make_pair(c, locklocation)); + + if (!fTry) { + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack)) { + if (i.first == c) break; + + std::pair p1 = std::make_pair(i.first, c); + if (lockorders.count(p1)) + continue; + lockorders[p1] = (*lockstack); + + std::pair p2 = std::make_pair(c, i.first); + if (lockorders.count(p2)) + { + potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]); + break; + } + } + } + dd_mutex.unlock(); +} + +static void pop_lock() +{ + if (fDebug) + { + const CLockLocation& locklocation = (*lockstack).rbegin()->second; + printf("Unlocked: %s\n", locklocation.ToString().c_str()); + } + dd_mutex.lock(); + (*lockstack).pop_back(); + dd_mutex.unlock(); +} + +void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry) +{ + push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry); +} + +void LeaveCritical() +{ + pop_lock(); +} + +#endif /* DEBUG_LOCKORDER */ diff --git a/src/sync.h b/src/sync.h new file mode 100644 index 0000000..e80efbe --- /dev/null +++ b/src/sync.h @@ -0,0 +1,212 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_SYNC_H +#define BITCOIN_SYNC_H + +#include +#include +#include +#include + + + + +/** Wrapped boost mutex: supports recursive locking, but no waiting */ +typedef boost::recursive_mutex CCriticalSection; + +/** Wrapped boost mutex: supports waiting but not recursive locking */ +typedef boost::mutex CWaitableCriticalSection; + +#ifdef DEBUG_LOCKORDER +void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false); +void LeaveCritical(); +#else +void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {} +void static inline LeaveCritical() {} +#endif + +#ifdef DEBUG_LOCKCONTENTION +void PrintLockContention(const char* pszName, const char* pszFile, int nLine); +#endif + +/** Wrapper around boost::unique_lock */ +template +class CMutexLock +{ +private: + boost::unique_lock lock; +public: + + void Enter(const char* pszName, const char* pszFile, int nLine) + { + if (!lock.owns_lock()) + { + EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex())); +#ifdef DEBUG_LOCKCONTENTION + if (!lock.try_lock()) + { + PrintLockContention(pszName, pszFile, nLine); +#endif + lock.lock(); +#ifdef DEBUG_LOCKCONTENTION + } +#endif + } + } + + void Leave() + { + if (lock.owns_lock()) + { + lock.unlock(); + LeaveCritical(); + } + } + + bool TryEnter(const char* pszName, const char* pszFile, int nLine) + { + if (!lock.owns_lock()) + { + EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true); + lock.try_lock(); + if (!lock.owns_lock()) + LeaveCritical(); + } + return lock.owns_lock(); + } + + CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) : lock(mutexIn, boost::defer_lock) + { + if (fTry) + TryEnter(pszName, pszFile, nLine); + else + Enter(pszName, pszFile, nLine); + } + + ~CMutexLock() + { + if (lock.owns_lock()) + LeaveCritical(); + } + + operator bool() + { + return lock.owns_lock(); + } + + boost::unique_lock &GetLock() + { + return lock; + } +}; + +typedef CMutexLock CCriticalBlock; + +#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__) +#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__) +#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true) + +#define ENTER_CRITICAL_SECTION(cs) \ + { \ + EnterCritical(#cs, __FILE__, __LINE__, (void*)(&cs)); \ + (cs).lock(); \ + } + +#define LEAVE_CRITICAL_SECTION(cs) \ + { \ + (cs).unlock(); \ + LeaveCritical(); \ + } + +class CSemaphore +{ +private: + boost::condition_variable condition; + boost::mutex mutex; + int value; + +public: + CSemaphore(int init) : value(init) {} + + void wait() { + boost::unique_lock lock(mutex); + while (value < 1) { + condition.wait(lock); + } + value--; + } + + bool try_wait() { + boost::unique_lock lock(mutex); + if (value < 1) + return false; + value--; + return true; + } + + void post() { + { + boost::unique_lock lock(mutex); + value++; + } + condition.notify_one(); + } +}; + +/** RAII-style semaphore lock */ +class CSemaphoreGrant +{ +private: + CSemaphore *sem; + bool fHaveGrant; + +public: + void Acquire() { + if (fHaveGrant) + return; + sem->wait(); + fHaveGrant = true; + } + + void Release() { + if (!fHaveGrant) + return; + sem->post(); + fHaveGrant = false; + } + + bool TryAcquire() { + if (!fHaveGrant && sem->try_wait()) + fHaveGrant = true; + return fHaveGrant; + } + + void MoveTo(CSemaphoreGrant &grant) { + grant.Release(); + grant.sem = sem; + grant.fHaveGrant = fHaveGrant; + sem = NULL; + fHaveGrant = false; + } + + CSemaphoreGrant() : sem(NULL), fHaveGrant(false) {} + + CSemaphoreGrant(CSemaphore &sema, bool fTry = false) : sem(&sema), fHaveGrant(false) { + if (fTry) + TryAcquire(); + else + Acquire(); + } + + ~CSemaphoreGrant() { + Release(); + } + + operator bool() { + return fHaveGrant; + } +}; +#endif + diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp new file mode 100644 index 0000000..b14e9f7 --- /dev/null +++ b/src/test/Checkpoints_tests.cpp @@ -0,0 +1,34 @@ +// +// Unit tests for block-chain checkpoints +// +#include // for 'map_list_of()' +#include +#include + +#include "../checkpoints.h" +#include "../util.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(Checkpoints_tests) + +BOOST_AUTO_TEST_CASE(sanity) +{ + uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"); + uint256 p134444 = uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"); + BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111)); + BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444)); + + + // Wrong hashes at checkpoints should fail: + BOOST_CHECK(!Checkpoints::CheckBlock(11111, p134444)); + BOOST_CHECK(!Checkpoints::CheckBlock(134444, p11111)); + + // ... but any hash not at a checkpoint should succeed: + BOOST_CHECK(Checkpoints::CheckBlock(11111+1, p134444)); + BOOST_CHECK(Checkpoints::CheckBlock(134444+1, p11111)); + + BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 134444); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp new file mode 100644 index 0000000..7f08dd5 --- /dev/null +++ b/src/test/DoS_tests.cpp @@ -0,0 +1,314 @@ +// +// Unit tests for denial-of-service detection/prevention code +// +#include + +#include // for 'map_list_of()' +#include +#include +#include + +#include "main.h" +#include "wallet.h" +#include "net.h" +#include "util.h" + +#include + +// Tests this internal-to-main.cpp method: +extern bool AddOrphanTx(const CDataStream& vMsg); +extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans); +extern std::map mapOrphanTransactions; +extern std::map > mapOrphanTransactionsByPrev; + +CService ip(uint32_t i) +{ + struct in_addr s; + s.s_addr = i; + return CService(CNetAddr(s), GetDefaultPort()); +} + +BOOST_AUTO_TEST_SUITE(DoS_tests) + +BOOST_AUTO_TEST_CASE(DoS_banning) +{ + CNode::ClearBanned(); + CAddress addr1(ip(0xa0b0c001)); + CNode dummyNode1(INVALID_SOCKET, addr1, "", true); + dummyNode1.Misbehaving(100); // Should get banned + BOOST_CHECK(CNode::IsBanned(addr1)); + BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned + + CAddress addr2(ip(0xa0b0c002)); + CNode dummyNode2(INVALID_SOCKET, addr2, "", true); + dummyNode2.Misbehaving(50); + BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet... + BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be + dummyNode2.Misbehaving(50); + BOOST_CHECK(CNode::IsBanned(addr2)); +} + +BOOST_AUTO_TEST_CASE(DoS_banscore) +{ + CNode::ClearBanned(); + mapArgs["-banscore"] = "111"; // because 11 is my favorite number + CAddress addr1(ip(0xa0b0c001)); + CNode dummyNode1(INVALID_SOCKET, addr1, "", true); + dummyNode1.Misbehaving(100); + BOOST_CHECK(!CNode::IsBanned(addr1)); + dummyNode1.Misbehaving(10); + BOOST_CHECK(!CNode::IsBanned(addr1)); + dummyNode1.Misbehaving(1); + BOOST_CHECK(CNode::IsBanned(addr1)); + mapArgs.erase("-banscore"); +} + +BOOST_AUTO_TEST_CASE(DoS_bantime) +{ + CNode::ClearBanned(); + int64 nStartTime = GetTime(); + SetMockTime(nStartTime); // Overrides future calls to GetTime() + + CAddress addr(ip(0xa0b0c001)); + CNode dummyNode(INVALID_SOCKET, addr, "", true); + + dummyNode.Misbehaving(100); + BOOST_CHECK(CNode::IsBanned(addr)); + + SetMockTime(nStartTime+60*60); + BOOST_CHECK(CNode::IsBanned(addr)); + + SetMockTime(nStartTime+60*60*24+1); + BOOST_CHECK(!CNode::IsBanned(addr)); +} + +static bool CheckNBits(unsigned int nbits1, int64 time1, unsigned int nbits2, int64 time2)\ +{ + if (time1 > time2) + return CheckNBits(nbits2, time2, nbits1, time1); + int64 deltaTime = time2-time1; + + CBigNum required; + required.SetCompact(ComputeMinWork(nbits1, deltaTime)); + CBigNum have; + have.SetCompact(nbits2); + return (have <= required); +} + +BOOST_AUTO_TEST_CASE(DoS_checknbits) +{ + using namespace boost::assign; // for 'map_list_of()' + + // Timestamps,nBits from the bitcoin blockchain. + // These are the block-chain checkpoint blocks + typedef std::map BlockData; + BlockData chainData = + map_list_of(1239852051,486604799)(1262749024,486594666) + (1279305360,469854461)(1280200847,469830746)(1281678674,469809688) + (1296207707,453179945)(1302624061,453036989)(1309640330,437004818) + (1313172719,436789733); + + // Make sure CheckNBits considers every combination of block-chain-lock-in-points + // "sane": + BOOST_FOREACH(const BlockData::value_type& i, chainData) + { + BOOST_FOREACH(const BlockData::value_type& j, chainData) + { + BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first)); + } + } + + // Test a couple of insane combinations: + BlockData::value_type firstcheck = *(chainData.begin()); + BlockData::value_type lastcheck = *(chainData.rbegin()); + + // First checkpoint difficulty at or a while after the last checkpoint time should fail when + // compared to last checkpoint + BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*10, lastcheck.second, lastcheck.first)); + BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*60*24*14, lastcheck.second, lastcheck.first)); + + // ... but OK if enough time passed for difficulty to adjust downward: + BOOST_CHECK(CheckNBits(firstcheck.second, lastcheck.first+60*60*24*365*4, lastcheck.second, lastcheck.first)); + +} + +CTransaction RandomOrphan() +{ + std::map::iterator it; + it = mapOrphanTransactions.lower_bound(GetRandHash()); + if (it == mapOrphanTransactions.end()) + it = mapOrphanTransactions.begin(); + const CDataStream* pvMsg = it->second; + CTransaction tx; + CDataStream(*pvMsg) >> tx; + return tx; +} + +BOOST_AUTO_TEST_CASE(DoS_mapOrphans) +{ + CKey key; + key.MakeNewKey(true); + CBasicKeyStore keystore; + keystore.AddKey(key); + + // 50 orphan transactions: + for (int i = 0; i < 50; i++) + { + CTransaction tx; + tx.vin.resize(1); + tx.vin[0].prevout.n = 0; + tx.vin[0].prevout.hash = GetRandHash(); + tx.vin[0].scriptSig << OP_1; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + + CDataStream ds(SER_DISK, CLIENT_VERSION); + ds << tx; + AddOrphanTx(ds); + } + + // ... and 50 that depend on other orphans: + for (int i = 0; i < 50; i++) + { + CTransaction txPrev = RandomOrphan(); + + CTransaction tx; + tx.vin.resize(1); + tx.vin[0].prevout.n = 0; + tx.vin[0].prevout.hash = txPrev.GetHash(); + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + SignSignature(keystore, txPrev, tx, 0); + + CDataStream ds(SER_DISK, CLIENT_VERSION); + ds << tx; + AddOrphanTx(ds); + } + + // This really-big orphan should be ignored: + for (int i = 0; i < 10; i++) + { + CTransaction txPrev = RandomOrphan(); + + CTransaction tx; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + tx.vin.resize(500); + for (unsigned int j = 0; j < tx.vin.size(); j++) + { + tx.vin[j].prevout.n = j; + tx.vin[j].prevout.hash = txPrev.GetHash(); + } + SignSignature(keystore, txPrev, tx, 0); + // Re-use same signature for other inputs + // (they don't have to be valid for this test) + for (unsigned int j = 1; j < tx.vin.size(); j++) + tx.vin[j].scriptSig = tx.vin[0].scriptSig; + + CDataStream ds(SER_DISK, CLIENT_VERSION); + ds << tx; + BOOST_CHECK(!AddOrphanTx(ds)); + } + + // Test LimitOrphanTxSize() function: + LimitOrphanTxSize(40); + BOOST_CHECK(mapOrphanTransactions.size() <= 40); + LimitOrphanTxSize(10); + BOOST_CHECK(mapOrphanTransactions.size() <= 10); + LimitOrphanTxSize(0); + BOOST_CHECK(mapOrphanTransactions.empty()); + BOOST_CHECK(mapOrphanTransactionsByPrev.empty()); +} + +BOOST_AUTO_TEST_CASE(DoS_checkSig) +{ + // Test signature caching code (see key.cpp Verify() methods) + + CKey key; + key.MakeNewKey(true); + CBasicKeyStore keystore; + keystore.AddKey(key); + + // 100 orphan transactions: + static const int NPREV=100; + CTransaction orphans[NPREV]; + for (int i = 0; i < NPREV; i++) + { + CTransaction& tx = orphans[i]; + tx.vin.resize(1); + tx.vin[0].prevout.n = 0; + tx.vin[0].prevout.hash = GetRandHash(); + tx.vin[0].scriptSig << OP_1; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + + CDataStream ds(SER_DISK, CLIENT_VERSION); + ds << tx; + AddOrphanTx(ds); + } + + // Create a transaction that depends on orphans: + CTransaction tx; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + tx.vin.resize(NPREV); + for (unsigned int j = 0; j < tx.vin.size(); j++) + { + tx.vin[j].prevout.n = 0; + tx.vin[j].prevout.hash = orphans[j].GetHash(); + } + // Creating signatures primes the cache: + boost::posix_time::ptime mst1 = boost::posix_time::microsec_clock::local_time(); + for (unsigned int j = 0; j < tx.vin.size(); j++) + BOOST_CHECK(SignSignature(keystore, orphans[j], tx, j)); + boost::posix_time::ptime mst2 = boost::posix_time::microsec_clock::local_time(); + boost::posix_time::time_duration msdiff = mst2 - mst1; + long nOneValidate = msdiff.total_milliseconds(); + if (fDebug) printf("DoS_Checksig sign: %ld\n", nOneValidate); + + // ... now validating repeatedly should be quick: + // 2.8GHz machine, -g build: Sign takes ~760ms, + // uncached Verify takes ~250ms, cached Verify takes ~50ms + // (for 100 single-signature inputs) + mst1 = boost::posix_time::microsec_clock::local_time(); + for (unsigned int i = 0; i < 5; i++) + for (unsigned int j = 0; j < tx.vin.size(); j++) + BOOST_CHECK(VerifySignature(orphans[j], tx, j, true, SIGHASH_ALL)); + mst2 = boost::posix_time::microsec_clock::local_time(); + msdiff = mst2 - mst1; + long nManyValidate = msdiff.total_milliseconds(); + if (fDebug) printf("DoS_Checksig five: %ld\n", nManyValidate); + + BOOST_CHECK_MESSAGE(nManyValidate < nOneValidate, "Signature cache timing failed"); + + // Empty a signature, validation should fail: + CScript save = tx.vin[0].scriptSig; + tx.vin[0].scriptSig = CScript(); + BOOST_CHECK(!VerifySignature(orphans[0], tx, 0, true, SIGHASH_ALL)); + tx.vin[0].scriptSig = save; + + // Swap signatures, validation should fail: + std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig); + BOOST_CHECK(!VerifySignature(orphans[0], tx, 0, true, SIGHASH_ALL)); + BOOST_CHECK(!VerifySignature(orphans[1], tx, 1, true, SIGHASH_ALL)); + std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig); + + // Exercise -maxsigcachesize code: + mapArgs["-maxsigcachesize"] = "10"; + // Generate a new, different signature for vin[0] to trigger cache clear: + CScript oldSig = tx.vin[0].scriptSig; + BOOST_CHECK(SignSignature(keystore, orphans[0], tx, 0)); + BOOST_CHECK(tx.vin[0].scriptSig != oldSig); + for (unsigned int j = 0; j < tx.vin.size(); j++) + BOOST_CHECK(VerifySignature(orphans[j], tx, j, true, SIGHASH_ALL)); + mapArgs.erase("-maxsigcachesize"); + + LimitOrphanTxSize(0); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/README b/src/test/README new file mode 100644 index 0000000..77f7faa --- /dev/null +++ b/src/test/README @@ -0,0 +1,21 @@ +The sources in this directory are unit test cases. Boost includes a +unit testing framework, and since bitcoin already uses boost, it makes +sense to simply use this framework rather than require developers to +configure some other framework (we want as few impediments to creating +unit tests as possible). + +The build system is setup to compile an executable called "test_bitcoin" +that runs all of the unit tests. The main source file is called +test_bitcoin.cpp, which simply includes other files that contain the +actual unit tests (outside of a couple required preprocessor +directives). The pattern is to create one test file for each class or +source file for which you want to create unit tests. The file naming +convention is "_tests.cpp" and such files should wrap +their tests in a test suite called "_tests". For an +examples of this pattern, examine uint160_tests.cpp and +uint256_tests.cpp. + +For further reading, I found the following website to be helpful in +explaining how the boost unit test framework works: + +http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/ diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp new file mode 100644 index 0000000..8ac6572 --- /dev/null +++ b/src/test/accounting_tests.cpp @@ -0,0 +1,123 @@ +#include + +#include + +#include "init.h" +#include "wallet.h" +#include "walletdb.h" + +BOOST_AUTO_TEST_SUITE(accounting_tests) + +static void +GetResults(CWalletDB& walletdb, std::map& results) +{ + std::list aes; + + results.clear(); + BOOST_CHECK(walletdb.ReorderTransactions(pwalletMain) == DB_LOAD_OK); + walletdb.ListAccountCreditDebit("", aes); + BOOST_FOREACH(CAccountingEntry& ae, aes) + { + results[ae.nOrderPos] = ae; + } +} + +BOOST_AUTO_TEST_CASE(acc_orderupgrade) +{ + CWalletDB walletdb(pwalletMain->strWalletFile); + std::vector vpwtx; + CWalletTx wtx; + CAccountingEntry ae; + std::map results; + + ae.strAccount = ""; + ae.nCreditDebit = 1; + ae.nTime = 1333333333; + ae.strOtherAccount = "b"; + ae.strComment = ""; + walletdb.WriteAccountingEntry(ae); + + wtx.mapValue["comment"] = "z"; + pwalletMain->AddToWallet(wtx); + vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); + vpwtx[0]->nTimeReceived = (unsigned int)1333333335; + vpwtx[0]->nOrderPos = -1; + + ae.nTime = 1333333336; + ae.strOtherAccount = "c"; + walletdb.WriteAccountingEntry(ae); + + GetResults(walletdb, results); + + BOOST_CHECK(pwalletMain->nOrderPosNext == 3); + BOOST_CHECK(2 == results.size()); + BOOST_CHECK(results[0].nTime == 1333333333); + BOOST_CHECK(results[0].strComment.empty()); + BOOST_CHECK(1 == vpwtx[0]->nOrderPos); + BOOST_CHECK(results[2].nTime == 1333333336); + BOOST_CHECK(results[2].strOtherAccount == "c"); + + + ae.nTime = 1333333330; + ae.strOtherAccount = "d"; + ae.nOrderPos = pwalletMain->IncOrderPosNext(); + walletdb.WriteAccountingEntry(ae); + + GetResults(walletdb, results); + + BOOST_CHECK(results.size() == 3); + BOOST_CHECK(pwalletMain->nOrderPosNext == 4); + BOOST_CHECK(results[0].nTime == 1333333333); + BOOST_CHECK(1 == vpwtx[0]->nOrderPos); + BOOST_CHECK(results[2].nTime == 1333333336); + BOOST_CHECK(results[3].nTime == 1333333330); + BOOST_CHECK(results[3].strComment.empty()); + + + wtx.mapValue["comment"] = "y"; + --wtx.nLockTime; // Just to change the hash :) + pwalletMain->AddToWallet(wtx); + vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); + vpwtx[1]->nTimeReceived = (unsigned int)1333333336; + + wtx.mapValue["comment"] = "x"; + --wtx.nLockTime; // Just to change the hash :) + pwalletMain->AddToWallet(wtx); + vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); + vpwtx[2]->nTimeReceived = (unsigned int)1333333329; + vpwtx[2]->nOrderPos = -1; + + GetResults(walletdb, results); + + BOOST_CHECK(results.size() == 3); + BOOST_CHECK(pwalletMain->nOrderPosNext == 6); + BOOST_CHECK(0 == vpwtx[2]->nOrderPos); + BOOST_CHECK(results[1].nTime == 1333333333); + BOOST_CHECK(2 == vpwtx[0]->nOrderPos); + BOOST_CHECK(results[3].nTime == 1333333336); + BOOST_CHECK(results[4].nTime == 1333333330); + BOOST_CHECK(results[4].strComment.empty()); + BOOST_CHECK(5 == vpwtx[1]->nOrderPos); + + + ae.nTime = 1333333334; + ae.strOtherAccount = "e"; + ae.nOrderPos = -1; + walletdb.WriteAccountingEntry(ae); + + GetResults(walletdb, results); + + BOOST_CHECK(results.size() == 4); + BOOST_CHECK(pwalletMain->nOrderPosNext == 7); + BOOST_CHECK(0 == vpwtx[2]->nOrderPos); + BOOST_CHECK(results[1].nTime == 1333333333); + BOOST_CHECK(2 == vpwtx[0]->nOrderPos); + BOOST_CHECK(results[3].nTime == 1333333336); + BOOST_CHECK(results[3].strComment.empty()); + BOOST_CHECK(results[4].nTime == 1333333330); + BOOST_CHECK(results[4].strComment.empty()); + BOOST_CHECK(results[5].nTime == 1333333334); + BOOST_CHECK(6 == vpwtx[1]->nOrderPos); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp new file mode 100644 index 0000000..d5cb8e8 --- /dev/null +++ b/src/test/allocator_tests.cpp @@ -0,0 +1,115 @@ +#include + +#include "init.h" +#include "main.h" +#include "util.h" + +BOOST_AUTO_TEST_SUITE(allocator_tests) + +// Dummy memory page locker for platform independent tests +static const void *last_lock_addr, *last_unlock_addr; +static size_t last_lock_len, last_unlock_len; +class TestLocker +{ +public: + bool Lock(const void *addr, size_t len) + { + last_lock_addr = addr; + last_lock_len = len; + return true; + } + bool Unlock(const void *addr, size_t len) + { + last_unlock_addr = addr; + last_unlock_len = len; + return true; + } +}; + +BOOST_AUTO_TEST_CASE(test_LockedPageManagerBase) +{ + const size_t test_page_size = 4096; + LockedPageManagerBase lpm(test_page_size); + size_t addr; + last_lock_addr = last_unlock_addr = 0; + last_lock_len = last_unlock_len = 0; + + /* Try large number of small objects */ + addr = 0; + for(int i=0; i<1000; ++i) + { + lpm.LockRange(reinterpret_cast(addr), 33); + addr += 33; + } + /* Try small number of page-sized objects, straddling two pages */ + addr = test_page_size*100 + 53; + for(int i=0; i<100; ++i) + { + lpm.LockRange(reinterpret_cast(addr), test_page_size); + addr += test_page_size; + } + /* Try small number of page-sized objects aligned to exactly one page */ + addr = test_page_size*300; + for(int i=0; i<100; ++i) + { + lpm.LockRange(reinterpret_cast(addr), test_page_size); + addr += test_page_size; + } + /* one very large object, straddling pages */ + lpm.LockRange(reinterpret_cast(test_page_size*600+1), test_page_size*500); + BOOST_CHECK(last_lock_addr == reinterpret_cast(test_page_size*(600+500))); + /* one very large object, page aligned */ + lpm.LockRange(reinterpret_cast(test_page_size*1200), test_page_size*500-1); + BOOST_CHECK(last_lock_addr == reinterpret_cast(test_page_size*(1200+500-1))); + + BOOST_CHECK(lpm.GetLockedPageCount() == ( + (1000*33+test_page_size-1)/test_page_size + // small objects + 101 + 100 + // page-sized objects + 501 + 500)); // large objects + BOOST_CHECK((last_lock_len & (test_page_size-1)) == 0); // always lock entire pages + BOOST_CHECK(last_unlock_len == 0); // nothing unlocked yet + + /* And unlock again */ + addr = 0; + for(int i=0; i<1000; ++i) + { + lpm.UnlockRange(reinterpret_cast(addr), 33); + addr += 33; + } + addr = test_page_size*100 + 53; + for(int i=0; i<100; ++i) + { + lpm.UnlockRange(reinterpret_cast(addr), test_page_size); + addr += test_page_size; + } + addr = test_page_size*300; + for(int i=0; i<100; ++i) + { + lpm.UnlockRange(reinterpret_cast(addr), test_page_size); + addr += test_page_size; + } + lpm.UnlockRange(reinterpret_cast(test_page_size*600+1), test_page_size*500); + lpm.UnlockRange(reinterpret_cast(test_page_size*1200), test_page_size*500-1); + + /* Check that everything is released */ + BOOST_CHECK(lpm.GetLockedPageCount() == 0); + + /* A few and unlocks of size zero (should have no effect) */ + addr = 0; + for(int i=0; i<1000; ++i) + { + lpm.LockRange(reinterpret_cast(addr), 0); + addr += 1; + } + BOOST_CHECK(lpm.GetLockedPageCount() == 0); + addr = 0; + for(int i=0; i<1000; ++i) + { + lpm.UnlockRange(reinterpret_cast(addr), 0); + addr += 1; + } + BOOST_CHECK(lpm.GetLockedPageCount() == 0); + BOOST_CHECK((last_unlock_len & (test_page_size-1)) == 0); // always unlock entire pages +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp new file mode 100644 index 0000000..fdf3285 --- /dev/null +++ b/src/test/base32_tests.cpp @@ -0,0 +1,20 @@ +#include + +#include "util.h" + +BOOST_AUTO_TEST_SUITE(base32_tests) + +BOOST_AUTO_TEST_CASE(base32_testvectors) +{ + static const std::string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"}; + static const std::string vstrOut[] = {"","my======","mzxq====","mzxw6===","mzxw6yq=","mzxw6ytb","mzxw6ytboi======"}; + for (unsigned int i=0; i +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" + +#include "base58.h" +#include "util.h" + +using namespace json_spirit; +extern Array read_json(const std::string& filename); + +BOOST_AUTO_TEST_SUITE(base58_tests) + +// Goal: test low-level base58 encoding functionality +BOOST_AUTO_TEST_CASE(base58_EncodeBase58) +{ + Array tests = read_json("base58_encode_decode.json"); + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + std::string strTest = write_string(tv, false); + if (test.size() < 2) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + std::vector sourcedata = ParseHex(test[0].get_str()); + std::string base58string = test[1].get_str(); + BOOST_CHECK_MESSAGE( + EncodeBase58(&sourcedata[0], &sourcedata[sourcedata.size()]) == base58string, + strTest); + } +} + +// Goal: test low-level base58 decoding functionality +BOOST_AUTO_TEST_CASE(base58_DecodeBase58) +{ + Array tests = read_json("base58_encode_decode.json"); + std::vector result; + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + std::string strTest = write_string(tv, false); + if (test.size() < 2) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + std::vector expected = ParseHex(test[0].get_str()); + std::string base58string = test[1].get_str(); + BOOST_CHECK_MESSAGE(DecodeBase58(base58string, result), strTest); + BOOST_CHECK_MESSAGE(result.size() == expected.size() && std::equal(result.begin(), result.end(), expected.begin()), strTest); + } + + BOOST_CHECK(!DecodeBase58("invalid", result)); +} + +// Visitor to check address type +class TestAddrTypeVisitor : public boost::static_visitor +{ +private: + std::string exp_addrType; +public: + TestAddrTypeVisitor(const std::string &exp_addrType) : exp_addrType(exp_addrType) { } + bool operator()(const CKeyID &id) const + { + return (exp_addrType == "pubkey"); + } + bool operator()(const CScriptID &id) const + { + return (exp_addrType == "script"); + } + bool operator()(const CNoDestination &no) const + { + return (exp_addrType == "none"); + } +}; + +// Visitor to check address payload +class TestPayloadVisitor : public boost::static_visitor +{ +private: + std::vector exp_payload; +public: + TestPayloadVisitor(std::vector &exp_payload) : exp_payload(exp_payload) { } + bool operator()(const CKeyID &id) const + { + uint160 exp_key(exp_payload); + return exp_key == id; + } + bool operator()(const CScriptID &id) const + { + uint160 exp_key(exp_payload); + return exp_key == id; + } + bool operator()(const CNoDestination &no) const + { + return exp_payload.size() == 0; + } +}; + +// Goal: check that parsed keys match test payload +BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) +{ + Array tests = read_json("base58_keys_valid.json"); + std::vector result; + CBitcoinSecret secret; + CBitcoinAddress addr; + // Save global state + bool fTestNet_stored = fTestNet; + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + std::string strTest = write_string(tv, false); + if (test.size() < 3) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + std::string exp_base58string = test[0].get_str(); + std::vector exp_payload = ParseHex(test[1].get_str()); + const Object &metadata = test[2].get_obj(); + bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); + bool isTestnet = find_value(metadata, "isTestnet").get_bool(); + fTestNet = isTestnet; // Override testnet flag + if(isPrivkey) + { + bool isCompressed = find_value(metadata, "isCompressed").get_bool(); + // Must be valid private key + // Note: CBitcoinSecret::SetString tests isValid, whereas CBitcoinAddress does not! + BOOST_CHECK_MESSAGE(secret.SetString(exp_base58string), "!SetString:"+ strTest); + BOOST_CHECK_MESSAGE(secret.IsValid(), "!IsValid:" + strTest); + bool fCompressedOut = false; + CSecret privkey = secret.GetSecret(fCompressedOut); + BOOST_CHECK_MESSAGE(fCompressedOut == isCompressed, "compressed mismatch:" + strTest); + BOOST_CHECK_MESSAGE(privkey.size() == exp_payload.size() && std::equal(privkey.begin(), privkey.end(), exp_payload.begin()), "key mismatch:" + strTest); + + // Private key must be invalid public key + addr.SetString(exp_base58string); + BOOST_CHECK_MESSAGE(!addr.IsValid(), "IsValid privkey as pubkey:" + strTest); + } + else + { + std::string exp_addrType = find_value(metadata, "addrType").get_str(); // "script" or "pubkey" + // Must be valid public key + BOOST_CHECK_MESSAGE(addr.SetString(exp_base58string), "SetString:" + strTest); + BOOST_CHECK_MESSAGE(addr.IsValid(), "!IsValid:" + strTest); + BOOST_CHECK_MESSAGE(addr.IsScript() == (exp_addrType == "script"), "isScript mismatch" + strTest); + CTxDestination dest = addr.Get(); + BOOST_CHECK_MESSAGE(boost::apply_visitor(TestAddrTypeVisitor(exp_addrType), dest), "addrType mismatch" + strTest); + + // Public key must be invalid private key + secret.SetString(exp_base58string); + BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest); + } + } + // Restore global state + fTestNet = fTestNet_stored; +} + +// Goal: check that generated keys match test vectors +BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) +{ + Array tests = read_json("base58_keys_valid.json"); + std::vector result; + // Save global state + bool fTestNet_stored = fTestNet; + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + std::string strTest = write_string(tv, false); + if (test.size() < 3) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + std::string exp_base58string = test[0].get_str(); + std::vector exp_payload = ParseHex(test[1].get_str()); + const Object &metadata = test[2].get_obj(); + bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); + bool isTestnet = find_value(metadata, "isTestnet").get_bool(); + fTestNet = isTestnet; // Override testnet flag + if(isPrivkey) + { + bool isCompressed = find_value(metadata, "isCompressed").get_bool(); + CBitcoinSecret secret; + secret.SetSecret(CSecret(exp_payload.begin(), exp_payload.end()), isCompressed); + BOOST_CHECK_MESSAGE(secret.ToString() == exp_base58string, "result mismatch: " + strTest); + } + else + { + std::string exp_addrType = find_value(metadata, "addrType").get_str(); + CTxDestination dest; + if(exp_addrType == "pubkey") + { + dest = CKeyID(uint160(exp_payload)); + } + else if(exp_addrType == "script") + { + dest = CScriptID(uint160(exp_payload)); + } + else if(exp_addrType == "none") + { + dest = CNoDestination(); + } + else + { + BOOST_ERROR("Bad addrtype: " << strTest); + continue; + } + CBitcoinAddress addrOut; + BOOST_CHECK_MESSAGE(boost::apply_visitor(CBitcoinAddressVisitor(&addrOut), dest), "encode dest: " + strTest); + BOOST_CHECK_MESSAGE(addrOut.ToString() == exp_base58string, "mismatch: " + strTest); + } + } + + // Visiting a CNoDestination must fail + CBitcoinAddress dummyAddr; + CTxDestination nodest = CNoDestination(); + BOOST_CHECK(!boost::apply_visitor(CBitcoinAddressVisitor(&dummyAddr), nodest)); + + // Restore global state + fTestNet = fTestNet_stored; +} + +// Goal: check that base58 parsing code is robust against a variety of corrupted data +BOOST_AUTO_TEST_CASE(base58_keys_invalid) +{ + Array tests = read_json("base58_keys_invalid.json"); // Negative testcases + std::vector result; + CBitcoinSecret secret; + CBitcoinAddress addr; + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + std::string strTest = write_string(tv, false); + if (test.size() < 1) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + std::string exp_base58string = test[0].get_str(); + + // must be invalid as public and as private key + addr.SetString(exp_base58string); + BOOST_CHECK_MESSAGE(!addr.IsValid(), "IsValid pubkey:" + strTest); + secret.SetString(exp_base58string); + BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid privkey:" + strTest); + } +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp new file mode 100644 index 0000000..c5a053e --- /dev/null +++ b/src/test/base64_tests.cpp @@ -0,0 +1,22 @@ +#include + +#include "main.h" +#include "wallet.h" +#include "util.h" + +BOOST_AUTO_TEST_SUITE(base64_tests) + +BOOST_AUTO_TEST_CASE(base64_testvectors) +{ + static const std::string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"}; + static const std::string vstrOut[] = {"","Zg==","Zm8=","Zm9v","Zm9vYg==","Zm9vYmE=","Zm9vYmFy"}; + for (unsigned int i=0; i +#include + +#include "bignum.h" +#include "util.h" + +BOOST_AUTO_TEST_SUITE(bignum_tests) + +// Unfortunately there's no standard way of preventing a function from being +// inlined, so we define a macro for it. +// +// You should use it like this: +// NOINLINE void function() {...} +#if defined(__GNUC__) +// This also works and will be defined for any compiler implementing GCC +// extensions, such as Clang and ICC. +#define NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define NOINLINE __declspec(noinline) +#else +// We give out a warning because it impacts the correctness of one bignum test. +#warning You should define NOINLINE for your compiler. +#define NOINLINE +#endif + +// For the following test case, it is useful to use additional tools. +// +// The simplest one to use is the compiler flag -ftrapv, which detects integer +// overflows and similar errors. However, due to optimizations and compilers +// taking advantage of undefined behavior sometimes it may not actually detect +// anything. +// +// You can also use compiler-based stack protection to possibly detect possible +// stack buffer overruns. +// +// For more accurate diagnostics, you can use an undefined arithmetic operation +// detector such as the clang-based tool: +// +// "IOC: An Integer Overflow Checker for C/C++" +// +// Available at: http://embed.cs.utah.edu/ioc/ +// +// It might also be useful to use Google's AddressSanitizer to detect +// stack buffer overruns, which valgrind can't currently detect. + +// Let's force this code not to be inlined, in order to actually +// test a generic version of the function. This increases the chance +// that -ftrapv will detect overflows. +NOINLINE void mysetint64(CBigNum& num, int64 n) +{ + num.setint64(n); +} + +// For each number, we do 2 tests: one with inline code, then we reset the +// value to 0, then the second one with a non-inlined function. +BOOST_AUTO_TEST_CASE(bignum_setint64) +{ + int64 n; + + { + n = 0; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "0"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "0"); + } + { + n = 1; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "1"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "1"); + } + { + n = -1; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "-1"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "-1"); + } + { + n = 5; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "5"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "5"); + } + { + n = -5; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "-5"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "-5"); + } + { + n = std::numeric_limits::min(); + CBigNum num(n); + BOOST_CHECK(num.ToString() == "-9223372036854775808"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "-9223372036854775808"); + } + { + n = std::numeric_limits::max(); + CBigNum num(n); + BOOST_CHECK(num.ToString() == "9223372036854775807"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "9223372036854775807"); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/data/base58_encode_decode.json b/src/test/data/base58_encode_decode.json new file mode 100644 index 0000000..9448f25 --- /dev/null +++ b/src/test/data/base58_encode_decode.json @@ -0,0 +1,14 @@ +[ +["", ""], +["61", "2g"], +["626262", "a3gV"], +["636363", "aPEr"], +["73696d706c792061206c6f6e6720737472696e67", "2cFupjhnEsSn59qHXstmK2ffpLv2"], +["00eb15231dfceb60925886b67d065299925915aeb172c06647", "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"], +["516b6fcd0f", "ABnLTmg"], +["bf4f89001e670274dd", "3SEo3LWLoPntC"], +["572e4794", "3EFU7m"], +["ecac89cad93923c02321", "EJDM8drfXA6uyA"], +["10c8511e", "Rt5zm"], +["00000000000000000000", "1111111111"] +] diff --git a/src/test/data/base58_keys_invalid.json b/src/test/data/base58_keys_invalid.json new file mode 100644 index 0000000..a088620 --- /dev/null +++ b/src/test/data/base58_keys_invalid.json @@ -0,0 +1,152 @@ +[ + [ + "" + ], + [ + "x" + ], + [ + "37qgekLpCCHrQuSjvX3fs496FWTGsHFHizjJAs6NPcR47aefnnCWECAhHV6E3g4YN7u7Yuwod5Y" + ], + [ + "dzb7VV1Ui55BARxv7ATxAtCUeJsANKovDGWFVgpTbhq9gvPqP3yv" + ], + [ + "MuNu7ZAEDFiHthiunm7dPjwKqrVNCM3mAz6rP9zFveQu14YA8CxExSJTHcVP9DErn6u84E6Ej7S" + ], + [ + "rPpQpYknyNQ5AEHuY6H8ijJJrYc2nDKKk9jjmKEXsWzyAQcFGpDLU2Zvsmoi8JLR7hAwoy3RQWf" + ], + [ + "4Uc3FmN6NQ6zLBK5QQBXRBUREaaHwCZYsGCueHauuDmJpZKn6jkEskMB2Zi2CNgtb5r6epWEFfUJq" + ], + [ + "7aQgR5DFQ25vyXmqZAWmnVCjL3PkBcdVkBUpjrjMTcghHx3E8wb" + ], + [ + "17QpPprjeg69fW1DV8DcYYCKvWjYhXvWkov6MJ1iTTvMFj6weAqW7wybZeH57WTNxXVCRH4veVs" + ], + [ + "KxuACDviz8Xvpn1xAh9MfopySZNuyajYMZWz16Dv2mHHryznWUp3" + ], + [ + "7nK3GSmqdXJQtdohvGfJ7KsSmn3TmGqExug49583bDAL91pVSGq5xS9SHoAYL3Wv3ijKTit65th" + ], + [ + "cTivdBmq7bay3RFGEBBuNfMh2P1pDCgRYN2Wbxmgwr4ki3jNUL2va" + ], + [ + "gjMV4vjNjyMrna4fsAr8bWxAbwtmMUBXJS3zL4NJt5qjozpbQLmAfK1uA3CquSqsZQMpoD1g2nk" + ], + [ + "emXm1naBMoVzPjbk7xpeTVMFy4oDEe25UmoyGgKEB1gGWsK8kRGs" + ], + [ + "7VThQnNRj1o3Zyvc7XHPRrjDf8j2oivPTeDXnRPYWeYGE4pXeRJDZgf28ppti5hsHWXS2GSobdqyo" + ], + [ + "1G9u6oCVCPh2o8m3t55ACiYvG1y5BHewUkDSdiQarDcYXXhFHYdzMdYfUAhfxn5vNZBwpgUNpso" + ], + [ + "31QQ7ZMLkScDiB4VyZjuptr7AEc9j1SjstF7pRoLhHTGkW4Q2y9XELobQmhhWxeRvqcukGd1XCq" + ], + [ + "DHqKSnpxa8ZdQyH8keAhvLTrfkyBMQxqngcQA5N8LQ9KVt25kmGN" + ], + [ + "2LUHcJPbwLCy9GLH1qXmfmAwvadWw4bp4PCpDfduLqV17s6iDcy1imUwhQJhAoNoN1XNmweiJP4i" + ], + [ + "7USRzBXAnmck8fX9HmW7RAb4qt92VFX6soCnts9s74wxm4gguVhtG5of8fZGbNPJA83irHVY6bCos" + ], + [ + "1DGezo7BfVebZxAbNT3XGujdeHyNNBF3vnficYoTSp4PfK2QaML9bHzAMxke3wdKdHYWmsMTJVu" + ], + [ + "2D12DqDZKwCxxkzs1ZATJWvgJGhQ4cFi3WrizQ5zLAyhN5HxuAJ1yMYaJp8GuYsTLLxTAz6otCfb" + ], + [ + "8AFJzuTujXjw1Z6M3fWhQ1ujDW7zsV4ePeVjVo7D1egERqSW9nZ" + ], + [ + "163Q17qLbTCue8YY3AvjpUhotuaodLm2uqMhpYirsKjVqnxJRWTEoywMVY3NbBAHuhAJ2cF9GAZ" + ], + [ + "2MnmgiRH4eGLyLc9eAqStzk7dFgBjFtUCtu" + ], + [ + "461QQ2sYWxU7H2PV4oBwJGNch8XVTYYbZxU" + ], + [ + "2UCtv53VttmQYkVU4VMtXB31REvQg4ABzs41AEKZ8UcB7DAfVzdkV9JDErwGwyj5AUHLkmgZeobs" + ], + [ + "cSNjAsnhgtiFMi6MtfvgscMB2Cbhn2v1FUYfviJ1CdjfidvmeW6mn" + ], + [ + "gmsow2Y6EWAFDFE1CE4Hd3Tpu2BvfmBfG1SXsuRARbnt1WjkZnFh1qGTiptWWbjsq2Q6qvpgJVj" + ], + [ + "nksUKSkzS76v8EsSgozXGMoQFiCoCHzCVajFKAXqzK5on9ZJYVHMD5CKwgmX3S3c7M1U3xabUny" + ], + [ + "L3favK1UzFGgdzYBF2oBT5tbayCo4vtVBLJhg2iYuMeePxWG8SQc" + ], + [ + "7VxLxGGtYT6N99GdEfi6xz56xdQ8nP2dG1CavuXx7Rf2PrvNMTBNevjkfgs9JmkcGm6EXpj8ipyPZ" + ], + [ + "2mbZwFXF6cxShaCo2czTRB62WTx9LxhTtpP" + ], + [ + "dB7cwYdcPSgiyAwKWL3JwCVwSk6epU2txw" + ], + [ + "HPhFUhUAh8ZQQisH8QQWafAxtQYju3SFTX" + ], + [ + "4ctAH6AkHzq5ioiM1m9T3E2hiYEev5mTsB" + ], + [ + "Hn1uFi4dNexWrqARpjMqgT6cX1UsNPuV3cHdGg9ExyXw8HTKadbktRDtdeVmY3M1BxJStiL4vjJ" + ], + [ + "Sq3fDbvutABmnAHHExJDgPLQn44KnNC7UsXuT7KZecpaYDMU9Txs" + ], + [ + "6TqWyrqdgUEYDQU1aChMuFMMEimHX44qHFzCUgGfqxGgZNMUVWJ" + ], + [ + "giqJo7oWqFxNKWyrgcBxAVHXnjJ1t6cGoEffce5Y1y7u649Noj5wJ4mmiUAKEVVrYAGg2KPB3Y4" + ], + [ + "cNzHY5e8vcmM3QVJUcjCyiKMYfeYvyueq5qCMV3kqcySoLyGLYUK" + ], + [ + "37uTe568EYc9WLoHEd9jXEvUiWbq5LFLscNyqvAzLU5vBArUJA6eydkLmnMwJDjkL5kXc2VK7ig" + ], + [ + "EsYbG4tWWWY45G31nox838qNdzksbPySWc" + ], + [ + "nbuzhfwMoNzA3PaFnyLcRxE9bTJPDkjZ6Rf6Y6o2ckXZfzZzXBT" + ], + [ + "cQN9PoxZeCWK1x56xnz6QYAsvR11XAce3Ehp3gMUdfSQ53Y2mPzx" + ], + [ + "1Gm3N3rkef6iMbx4voBzaxtXcmmiMTqZPhcuAepRzYUJQW4qRpEnHvMojzof42hjFRf8PE2jPde" + ], + [ + "2TAq2tuN6x6m233bpT7yqdYQPELdTDJn1eU" + ], + [ + "ntEtnnGhqPii4joABvBtSEJG6BxjT2tUZqE8PcVYgk3RHpgxgHDCQxNbLJf7ardf1dDk2oCQ7Cf" + ], + [ + "Ky1YjoZNgQ196HJV3HpdkecfhRBmRZdMJk89Hi5KGfpfPwS2bUbfd" + ], + [ + "2A1q1YsMZowabbvta7kTy2Fd6qN4r5ZCeG3qLpvZBMzCixMUdkN2Y4dHB1wPsZAeVXUGD83MfRED" + ] +] diff --git a/src/test/data/base58_keys_valid.json b/src/test/data/base58_keys_valid.json new file mode 100644 index 0000000..e1e252e --- /dev/null +++ b/src/test/data/base58_keys_valid.json @@ -0,0 +1,452 @@ +[ + [ + "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", + "65a16059864a2fdbc7c99a4723a8395bc6f188eb", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", + "74f209f6ea907e2ea48f74fae05782ae8a665257", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", + "53c0307d6851aa0ce7825ba883c6bd9ad242b486", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", + "6349a418fc4578d10a372b54b45c280cc8c4382f", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "5Kd3NBUAdUnhyzenEwVLy9pBKxSwXvE9FMPyR4UKZvpe6E3AgLr", + "eddbdc1168f1daeadbd3e44c1e3f8f5a284c2029f78ad26af98583a499de5b19", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "Kz6UJmQACJmLtaQj5A3JAge4kVTNQ8gbvXuwbmCj7bsaabudb3RD", + "55c9bccb9ed68446d1b75273bbce89d7fe013a8acd1625514420fb2aca1a21c4", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "9213qJab2HNEpMpYNBa7wHGFKKbkDn24jpANDs2huN3yi4J11ko", + "36cb93b9ab1bdabf7fb9f2c04f1b9cc879933530ae7842398eef5a63a56800c2", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "cTpB4YiyKiBcPxnefsDpbnDxFDffjqJob8wGCEDXxgQ7zQoMXJdH", + "b9f4892c9e8282028fea1d2667c4dc5213564d41fc5783896a0d843fc15089f3", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", + "6d23156cbbdcc82a5a47eee4c2c7c583c18b6bf4", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", + "fcc5460dd6e2487c7d75b1963625da0e8f4c5975", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "n3ZddxzLvAY9o7184TB4c6FJasAybsw4HZ", + "f1d470f9b02370fdec2e6b708b08ac431bf7a5f7", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", + "c579342c2c4c9220205e2cdc285617040c924a0a", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "5K494XZwps2bGyeL71pWid4noiSNA2cfCibrvRWqcHSptoFn7rc", + "a326b95ebae30164217d7a7f57d72ab2b54e3be64928a19da0210b9568d4015e", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi", + "7d998b45c219a1e38e99e7cbd312ef67f77a455a9b50c730c27f02c6f730dfb4", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "93DVKyFYwSN6wEo3E2fCrFPUp17FtrtNi2Lf7n4G3garFb16CRj", + "d6bca256b5abc5602ec2e1c121a08b0da2556587430bcf7e1898af2224885203", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "cTDVKtMGVYWTHCb1AFjmVbEbWjvKpKqKgMaR3QJxToMSQAhmCeTN", + "a81ca4e8f90181ec4b61b6a7eb998af17b2cb04de8a03b504b9e34c4c61db7d9", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", + "7987ccaa53d02c8873487ef919677cd3db7a6912", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", + "63bcc565f9e68ee0189dd5cc67f1b0e5f02f45cb", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "n3LnJXCqbPjghuVs8ph9CYsAe4Sh4j97wk", + "ef66444b5b17f14e8fae6e7e19b045a78c54fd79", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "2NB72XtkjpnATMggui83aEtPawyyKvnbX2o", + "c3e55fceceaa4391ed2a9677f4a4d34eacd021a0", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "5KaBW9vNtWNhc3ZEDyNCiXLPdVPHCikRxSBWwV9NrpLLa4LsXi9", + "e75d936d56377f432f404aabb406601f892fd49da90eb6ac558a733c93b47252", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "L1axzbSyynNYA8mCAhzxkipKkfHtAXYF4YQnhSKcLV8YXA874fgT", + "8248bd0375f2f75d7e274ae544fb920f51784480866b102384190b1addfbaa5c", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "927CnUkUbasYtDwYwVn2j8GdTuACNnKkjZ1rpZd2yBB1CLcnXpo", + "44c4f6a096eac5238291a94cc24c01e3b19b8d8cef72874a079e00a242237a52", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "cUcfCMRjiQf85YMzzQEk9d1s5A4K7xL5SmBCLrezqXFuTVefyhY7", + "d1de707020a9059d6d3abaf85e17967c6555151143db13dbb06db78df0f15c69", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", + "adc1cc2081a27206fae25792f28bbc55b831549d", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", + "188f91a931947eddd7432d6e614387e32b244709", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "mhaMcBxNh5cqXm4aTQ6EcVbKtfL6LGyK2H", + "1694f5bc1a7295b600f40018a618a6ea48eeb498", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "2MxgPqX1iThW3oZVk9KoFcE5M4JpiETssVN", + "3b9b3fd7a50d4f08d1a5b0f62f644fa7115ae2f3", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "5HtH6GdcwCJA4ggWEL1B3jzBBUB8HPiBi9SBc5h9i4Wk4PSeApR", + "091035445ef105fa1bb125eccfb1882f3fe69592265956ade751fd095033d8d0", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "L2xSYmMeVo3Zek3ZTsv9xUrXVAmrWxJ8Ua4cw8pkfbQhcEFhkXT8", + "ab2b4bcdfc91d34dee0ae2a8c6b6668dadaeb3a88b9859743156f462325187af", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "92xFEve1Z9N8Z641KQQS7ByCSb8kGjsDzw6fAmjHN1LZGKQXyMq", + "b4204389cef18bbe2b353623cbf93e8678fbc92a475b664ae98ed594e6cf0856", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "cVM65tdYu1YK37tNoAyGoJTR13VBYFva1vg9FLuPAsJijGvG6NEA", + "e7b230133f1b5489843260236b06edca25f66adb1be455fbd38d4010d48faeef", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", + "c4c1b72491ede1eedaca00618407ee0b772cad0d", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", + "f6fe69bcb548a829cce4c57bf6fff8af3a5981f9", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "mizXiucXRCsEriQCHUkCqef9ph9qtPbZZ6", + "261f83568a098a8638844bd7aeca039d5f2352c0", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "2NEWDzHWwY5ZZp8CQWbB7ouNMLqCia6YRda", + "e930e1834a4d234702773951d627cce82fbb5d2e", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "5KQmDryMNDcisTzRp3zEq9e4awRmJrEVU1j5vFRTKpRNYPqYrMg", + "d1fab7ab7385ad26872237f1eb9789aa25cc986bacc695e07ac571d6cdac8bc0", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "L39Fy7AC2Hhj95gh3Yb2AU5YHh1mQSAHgpNixvm27poizcJyLtUi", + "b0bbede33ef254e8376aceb1510253fc3550efd0fcf84dcd0c9998b288f166b3", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "91cTVUcgydqyZLgaANpf1fvL55FH53QMm4BsnCADVNYuWuqdVys", + "037f4192c630f399d9271e26c575269b1d15be553ea1a7217f0cb8513cef41cb", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "cQspfSzsgLeiJGB2u8vrAiWpCU4MxUT6JseWo2SjXy4Qbzn2fwDw", + "6251e205e8ad508bab5596bee086ef16cd4b239e0cc0c5d7c4e6035441e7d5de", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", + "5eadaf9bb7121f0f192561a5a62f5e5f54210292", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", + "3f210e7277c899c3a155cc1c90f4106cbddeec6e", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "myoqcgYiehufrsnnkqdqbp69dddVDMopJu", + "c8a3c2a09a298592c3e180f02487cd91ba3400b5", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "2N7FuwuUuoTBrDFdrAZ9KxBmtqMLxce9i1C", + "99b31df7c9068d1481b596578ddbb4d3bd90baeb", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": true + } + ], + [ + "5KL6zEaMtPRXZKo1bbMq7JDjjo1bJuQcsgL33je3oY8uSJCR5b4", + "c7666842503db6dc6ea061f092cfb9c388448629a6fe868d068c42a488b478ae", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "KwV9KAfwbwt51veZWNscRTeZs9CKpojyu1MsPnaKTF5kz69H1UN2", + "07f0803fc5399e773555ab1e8939907e9badacc17ca129e67a2f5f2ff84351dd", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": false + } + ], + [ + "93N87D6uxSBzwXvpokpzg8FFmfQPmvX4xHoWQe3pLdYpbiwT5YV", + "ea577acfb5d1d14d3b7b195c321566f12f87d2b77ea3a53f68df7ebf8604a801", + { + "isCompressed": false, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "cMxXusSihaX58wpJ3tNuuUcZEQGt6DKJ1wEpxys88FFaQCYjku9h", + "0b3b34f0958d8a268193a9814da92c3e8b58b4a4378a542863e34ac289cd830c", + { + "isCompressed": true, + "isPrivkey": true, + "isTestnet": true + } + ], + [ + "13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", + "1ed467017f043e91ed4c44b4e8dd674db211c4e6", + { + "addrType": "pubkey", + "isPrivkey": false, + "isTestnet": false + } + ], + [ + "3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", + "5ece0cadddc415b1980f001785947120acdb36fc", + { + "addrType": "script", + "isPrivkey": false, + "isTestnet": false + } + ] +] diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json new file mode 100644 index 0000000..d413eae --- /dev/null +++ b/src/test/data/script_invalid.json @@ -0,0 +1,245 @@ +[ +["", ""], +["", "NOP"], +["NOP", ""], +["NOP","NOP"], + +["0x4c01","0x01 NOP", "PUSHDATA1 with not enough bytes"], +["0x4d0200ff","0x01 NOP", "PUSHDATA2 with not enough bytes"], +["0x4e03000000ffff","0x01 NOP", "PUSHDATA4 with not enough bytes"], + +["1", "IF 0x50 ENDIF 1", "0x50 is reserved"], +["0x52", "0x5f ADD 0x60 EQUAL", "0x51 through 0x60 push 1 through 16 onto stack"], +["0","NOP"], +["1", "IF VER ELSE 1 ENDIF", "VER non-functional"], +["0", "IF VERIF ELSE 1 ENDIF", "VERIF illegal everywhere"], +["0", "IF VERNOTIF ELSE 1 ENDIF", "VERNOT illegal everywhere"], + +["1 IF", "1 ENDIF", "IF/ENDIF can't span scriptSig/scriptPubKey"], +["1 IF 0 ENDIF", "1 ENDIF"], +["1 ELSE 0 ENDIF", "1"], +["0 NOTIF", "123"], + +["0", "DUP IF ENDIF"], +["0", "IF 1 ENDIF"], +["0", "DUP IF ELSE ENDIF"], +["0", "IF 1 ELSE ENDIF"], +["0", "NOTIF ELSE 1 ENDIF"], + +["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF"], +["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF"], +["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], + +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF"], +["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF"], +["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], + +["1", "RETURN"], +["1", "DUP IF RETURN ENDIF"], + +["0", "VERIFY 1"], +["1", "VERIFY"], +["1", "VERIFY 0"], + +["1 TOALTSTACK", "FROMALTSTACK 1", "alt stack not shared between sig/pubkey"], + +["IFDUP", "DEPTH 0 EQUAL"], +["DROP", "DEPTH 0 EQUAL"], +["DUP", "DEPTH 0 EQUAL"], +["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL"], +["NOP", "NIP"], +["NOP", "1 NIP"], +["NOP", "1 0 NIP"], +["NOP", "OVER 1"], +["1", "OVER"], +["0 1", "OVER DEPTH 3 EQUALVERIFY"], +["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL"], +["NOP", "0 PICK"], +["1", "-1 PICK"], +["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL"], +["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL"], +["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL"], +["NOP", "0 ROLL"], +["1", "-1 ROLL"], +["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL"], +["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL"], +["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL"], +["NOP", "ROT 1"], +["NOP", "1 ROT 1"], +["NOP", "1 2 ROT 1"], +["NOP", "0 1 2 ROT"], +["NOP", "SWAP 1"], +["1", "SWAP 1"], +["0 1", "SWAP 1 EQUALVERIFY"], +["NOP", "TUCK 1"], +["1", "TUCK 1"], +["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP"], +["NOP", "2DUP 1"], +["1", "2DUP 1"], +["NOP", "3DUP 1"], +["1", "3DUP 1"], +["1 2", "3DUP 1"], +["NOP", "2OVER 1"], +["1", "2 3 2OVER 1"], +["NOP", "2SWAP 1"], +["1", "2 3 2SWAP 1"], + +["'a' 'b'", "CAT", "CAT disabled"], +["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "CAT disabled"], +["'abc' 1 1", "SUBSTR", "SUBSTR disabled"], +["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "SUBSTR disabled"], +["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "LEFT disabled"], +["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "RIGHT disabled"], + +["NOP", "SIZE 1"], + +["'abc'", "IF INVERT ELSE 1 ENDIF", "INVERT disabled"], +["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "AND disabled"], +["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "OR disabled"], +["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "XOR disabled"], +["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "2MUL disabled"], +["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "2DIV disabled"], +["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "MUL disabled"], +["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "DIV disabled"], +["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "MOD disabled"], +["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "LSHIFT disabled"], +["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "RSHIFT disabled"], + +["0 1","EQUAL"], +["1 1 ADD", "0 EQUAL"], +["11 1 ADD 12 SUB", "11 EQUAL"], + +["2147483648 0 ADD", "NOP", "arithmetic operands must be in range [-2^31...2^31] "], +["-2147483648 0 ADD", "NOP", "arithmetic operands must be in range [-2^31...2^31] "], +["2147483647 DUP ADD", "4294967294 NUMEQUAL", "NUMEQUAL must be in numeric range"], +["'abcdef' NOT", "0 EQUAL", "NOT is an arithmetic operand"], + +["2 DUP MUL", "4 EQUAL", "disabled"], +["2 DUP DIV", "1 EQUAL", "disabled"], +["2 2MUL", "4 EQUAL", "disabled"], +["2 2DIV", "1 EQUAL", "disabled"], +["7 3 MOD", "1 EQUAL", "disabled"], +["2 2 LSHIFT", "8 EQUAL", "disabled"], +["2 1 RSHIFT", "1 EQUAL", "disabled"], + +["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL"], +["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL"], + +["0x50","1", "opcode 0x50 is reserved"], +["1", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid"], +["1", "IF 0xc0 ELSE 1 ENDIF"], +["1", "IF 0xd1 ELSE 1 ENDIF"], +["1", "IF 0xee ELSE 1 ENDIF"], +["1", "IF 0xfd ELSE 1 ENDIF"], +["1", "IF 0xff ELSE 1 ENDIF"], + +["NOP", "RIPEMD160"], +["NOP", "SHA1"], +["NOP", "SHA256"], +["NOP", "HASH160"], +["NOP", "HASH256"], + +["NOP", +"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", +">520 byte push"], +["0", +"IF 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ENDIF 1", +">520 byte push in non-executed IF branch"], +["1", +"0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +">201 opcodes executed. 0x61 is NOP"], +["0", +"IF 0x6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 ENDIF 1", +">201 opcodes including non-executed IF branch. 0x61 is NOP"], +["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 2 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +">1,000 stack size (0x6f is 3DUP)"], +["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 TOALTSTACK 2 TOALTSTACK 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +">1,000 stack+altstack size"], +["NOP", +"0 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +"10,001-byte scriptPubKey"], + +["NOP1","NOP10"], + +["1","VER", "OP_VER is reserved"], +["1","VERIF", "OP_VERIF is reserved"], +["1","VERNOTIF", "OP_VERNOTIF is reserved"], +["1","RESERVED1", "OP_RESERVED1 is reserved"], +["1","RESERVED2", "OP_RESERVED2 is reserved"], +["1","0xba", "0xba == OP_NOP10 + 1"], + +["2147483648", "1ADD 1", "We cannot do math on 5-byte integers"], +["-2147483648", "1ADD 1", "Because we use a sign bit, -2147483648 is also 5 bytes"], + +["1", "1 ENDIF", "ENDIF without IF"], +["1", "IF 1", "IF without ENDIF"], +["1 IF 1", "ENDIF", "IFs don't carry over"], + +["NOP", "IF 1 ENDIF", "The following tests check the if(stack.size() < N) tests in each opcode"], +["NOP", "NOTIF 1 ENDIF", "They are here to catch copy-and-paste errors"], +["NOP", "VERIFY 1", "Most of them are duplicated elsewhere,"], + +["NOP", "TOALTSTACK 1", "but, hey, more is always better, right?"], +["1", "FROMALTSTACK"], +["1", "2DROP 1"], +["1", "2DUP"], +["1 1", "3DUP"], +["1 1 1", "2OVER"], +["1 1 1 1 1", "2ROT"], +["1 1 1", "2SWAP"], +["NOP", "IFDUP 1"], +["NOP", "DROP 1"], +["NOP", "DUP 1"], +["1", "NIP"], +["1", "OVER"], +["1 1 1 3", "PICK"], +["0", "PICK 1"], +["1 1 1 3", "ROLL"], +["0", "ROLL 1"], +["1 1", "ROT"], +["1", "SWAP"], +["1", "TUCK"], + +["NOP", "SIZE 1"], + +["1", "EQUAL 1"], +["1", "EQUALVERIFY 1"], + +["NOP", "1ADD 1"], +["NOP", "1SUB 1"], +["NOP", "NEGATE 1"], +["NOP", "ABS 1"], +["NOP", "NOT 1"], +["NOP", "0NOTEQUAL 1"], + +["1", "ADD"], +["1", "SUB"], +["1", "BOOLAND"], +["1", "BOOLOR"], +["1", "NUMEQUAL"], +["1", "NUMEQUALVERIFY 1"], +["1", "NUMNOTEQUAL"], +["1", "LESSTHAN"], +["1", "GREATERTHAN"], +["1", "LESSTHANOREQUAL"], +["1", "GREATERTHANOREQUAL"], +["1", "MIN"], +["1", "MAX"], +["1 1", "WITHIN"], + +["NOP", "RIPEMD160 1"], +["NOP", "SHA1 1"], +["NOP", "SHA256 1"], +["NOP", "HASH160 1"], +["NOP", "HASH256 1"], + +["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "Tests for Script.IsPushOnly()"], +["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL"], + +["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "OP_RESERVED in P2SH should fail"], +["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "OP_VER in P2SH should fail"] +] diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json new file mode 100644 index 0000000..c33a3c7 --- /dev/null +++ b/src/test/data/script_valid.json @@ -0,0 +1,313 @@ +[ +["0x01 0x0b", "11 EQUAL", "push 1 byte"], +["0x02 0x417a", "'Az' EQUAL"], +["0x4b 0x417a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a", + "'Azzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' EQUAL", "push 75 bytes"], + +["0x4c 0x01 0x07","7 EQUAL", "0x4c is OP_PUSHDATA1"], +["0x4d 0x0100 0x08","8 EQUAL", "0x4d is OP_PUSHDATA2"], +["0x4e 0x01000000 0x09","9 EQUAL", "0x4e is OP_PUSHDATA4"], + +["0x4c 0x00","0 EQUAL"], +["0x4d 0x0000","0 EQUAL"], +["0x4e 0x00000000","0 EQUAL"], +["0x4f 1000 ADD","999 EQUAL"], +["0", "IF 0x50 ENDIF 1", "0x50 is reserved (ok if not executed)"], +["0x51", "0x5f ADD 0x60 EQUAL", "0x51 through 0x60 push 1 through 16 onto stack"], +["1","NOP"], +["0", "IF VER ELSE 1 ENDIF", "VER non-functional (ok if not executed)"], +["0", "IF RESERVED1 RESERVED2 ELSE 1 ENDIF", "RESERVED ok in un-executed IF"], + +["1", "DUP IF ENDIF"], +["1", "IF 1 ENDIF"], +["1", "DUP IF ELSE ENDIF"], +["1", "IF 1 ELSE ENDIF"], +["0", "IF ELSE 1 ENDIF"], + +["1 1", "IF IF 1 ELSE 0 ENDIF ENDIF"], +["1 0", "IF IF 1 ELSE 0 ENDIF ENDIF"], +["1 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], + +["1 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF"], +["1 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF"], +["1 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], + +["1 1", "VERIFY"], + +["10 0 11 TOALTSTACK DROP FROMALTSTACK", "ADD 21 EQUAL"], +["'gavin_was_here' TOALTSTACK 11 FROMALTSTACK", "'gavin_was_here' EQUALVERIFY 11 EQUAL"], + +["0 IFDUP", "DEPTH 1 EQUALVERIFY 0 EQUAL"], +["1 IFDUP", "DEPTH 2 EQUALVERIFY 1 EQUALVERIFY 1 EQUAL"], +["0 DROP", "DEPTH 0 EQUAL"], +["0", "DUP 1 ADD 1 EQUALVERIFY 0 EQUAL"], +["0 1", "NIP"], +["1 0", "OVER DEPTH 3 EQUALVERIFY"], +["22 21 20", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL"], +["22 21 20", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL"], +["22 21 20", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL"], +["22 21 20", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL"], +["22 21 20", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL"], +["22 21 20", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL"], +["22 21 20", "ROT 22 EQUAL"], +["22 21 20", "ROT DROP 20 EQUAL"], +["22 21 20", "ROT DROP DROP 21 EQUAL"], +["22 21 20", "ROT ROT 21 EQUAL"], +["22 21 20", "ROT ROT ROT 20 EQUAL"], +["25 24 23 22 21 20", "2ROT 24 EQUAL"], +["25 24 23 22 21 20", "2ROT DROP 25 EQUAL"], +["25 24 23 22 21 20", "2ROT 2DROP 20 EQUAL"], +["25 24 23 22 21 20", "2ROT 2DROP DROP 21 EQUAL"], +["25 24 23 22 21 20", "2ROT 2DROP 2DROP 22 EQUAL"], +["25 24 23 22 21 20", "2ROT 2DROP 2DROP DROP 23 EQUAL"], +["25 24 23 22 21 20", "2ROT 2ROT 22 EQUAL"], +["25 24 23 22 21 20", "2ROT 2ROT 2ROT 20 EQUAL"], +["1 0", "SWAP 1 EQUALVERIFY 0 EQUAL"], +["0 1", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP"], +["13 14", "2DUP ROT EQUALVERIFY EQUAL"], +["-1 0 1 2", "3DUP DEPTH 7 EQUALVERIFY ADD ADD 3 EQUALVERIFY 2DROP 0 EQUALVERIFY"], +["1 2 3 5", "2OVER ADD ADD 8 EQUALVERIFY ADD ADD 6 EQUAL"], +["1 3 5 7", "2SWAP ADD 4 EQUALVERIFY ADD 12 EQUAL"], +["0", "SIZE 0 EQUAL"], +["1", "SIZE 1 EQUAL"], +["127", "SIZE 1 EQUAL"], +["128", "SIZE 2 EQUAL"], +["32767", "SIZE 2 EQUAL"], +["32768", "SIZE 3 EQUAL"], +["8388607", "SIZE 3 EQUAL"], +["8388608", "SIZE 4 EQUAL"], +["2147483647", "SIZE 4 EQUAL"], +["2147483648", "SIZE 5 EQUAL"], +["-1", "SIZE 1 EQUAL"], +["-127", "SIZE 1 EQUAL"], +["-128", "SIZE 2 EQUAL"], +["-32767", "SIZE 2 EQUAL"], +["-32768", "SIZE 3 EQUAL"], +["-8388607", "SIZE 3 EQUAL"], +["-8388608", "SIZE 4 EQUAL"], +["-2147483647", "SIZE 4 EQUAL"], +["-2147483648", "SIZE 5 EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "SIZE 26 EQUAL"], + + +["2 -2 ADD", "0 EQUAL"], +["2147483647 -2147483647 ADD", "0 EQUAL"], +["-1 -1 ADD", "-2 EQUAL"], + +["0 0","EQUAL"], +["1 1 ADD", "2 EQUAL"], +["1 1ADD", "2 EQUAL"], +["111 1SUB", "110 EQUAL"], +["111 1 ADD 12 SUB", "100 EQUAL"], +["0 ABS", "0 EQUAL"], +["16 ABS", "16 EQUAL"], +["-16 ABS", "-16 NEGATE EQUAL"], +["0 NOT", "NOP"], +["1 NOT", "0 EQUAL"], +["11 NOT", "0 EQUAL"], +["0 0NOTEQUAL", "0 EQUAL"], +["1 0NOTEQUAL", "1 EQUAL"], +["111 0NOTEQUAL", "1 EQUAL"], +["-111 0NOTEQUAL", "1 EQUAL"], +["1 1 BOOLAND", "NOP"], +["1 0 BOOLAND", "NOT"], +["0 1 BOOLAND", "NOT"], +["0 0 BOOLAND", "NOT"], +["16 17 BOOLAND", "NOP"], +["1 1 BOOLOR", "NOP"], +["1 0 BOOLOR", "NOP"], +["0 1 BOOLOR", "NOP"], +["0 0 BOOLOR", "NOT"], +["16 17 BOOLOR", "NOP"], +["11 10 1 ADD", "NUMEQUAL"], +["11 10 1 ADD", "NUMEQUALVERIFY 1"], +["11 10 1 ADD", "NUMNOTEQUAL NOT"], +["111 10 1 ADD", "NUMNOTEQUAL"], +["11 10", "LESSTHAN NOT"], +["4 4", "LESSTHAN NOT"], +["10 11", "LESSTHAN"], +["-11 11", "LESSTHAN"], +["-11 -10", "LESSTHAN"], +["11 10", "GREATERTHAN"], +["4 4", "GREATERTHAN NOT"], +["10 11", "GREATERTHAN NOT"], +["-11 11", "GREATERTHAN NOT"], +["-11 -10", "GREATERTHAN NOT"], +["11 10", "LESSTHANOREQUAL NOT"], +["4 4", "LESSTHANOREQUAL"], +["10 11", "LESSTHANOREQUAL"], +["-11 11", "LESSTHANOREQUAL"], +["-11 -10", "LESSTHANOREQUAL"], +["11 10", "GREATERTHANOREQUAL"], +["4 4", "GREATERTHANOREQUAL"], +["10 11", "GREATERTHANOREQUAL NOT"], +["-11 11", "GREATERTHANOREQUAL NOT"], +["-11 -10", "GREATERTHANOREQUAL NOT"], +["1 0 MIN", "0 NUMEQUAL"], +["0 1 MIN", "0 NUMEQUAL"], +["-1 0 MIN", "-1 NUMEQUAL"], +["0 -2147483647 MIN", "-2147483647 NUMEQUAL"], +["2147483647 0 MAX", "2147483647 NUMEQUAL"], +["0 100 MAX", "100 NUMEQUAL"], +["-100 0 MAX", "0 NUMEQUAL"], +["0 -2147483647 MAX", "0 NUMEQUAL"], +["0 0 1", "WITHIN"], +["1 0 1", "WITHIN NOT"], +["0 -2147483647 2147483647", "WITHIN"], +["-1 -100 100", "WITHIN"], +["11 -100 100", "WITHIN"], +["-2147483647 -100 100", "WITHIN NOT"], +["2147483647 -100 100", "WITHIN NOT"], + +["2147483647 2147483647 SUB", "0 EQUAL"], +["2147483647 DUP ADD", "4294967294 EQUAL", ">32 bit EQUAL is valid"], +["2147483647 NEGATE DUP ADD", "-4294967294 EQUAL"], + +["''", "RIPEMD160 0x14 0x9c1185a5c5e9fc54612808977ee8f548b2258d31 EQUAL"], +["'a'", "RIPEMD160 0x14 0x0bdc9d2d256b3ee9daae347be6f4dc835a467ffe EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "RIPEMD160 0x14 0xf71c27109c692c1b56bbdceb5b9d2865b3708dbc EQUAL"], +["''", "SHA1 0x14 0xda39a3ee5e6b4b0d3255bfef95601890afd80709 EQUAL"], +["'a'", "SHA1 0x14 0x86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "SHA1 0x14 0x32d10c7b8cf96570ca04ce37f2a19d84240d3a89 EQUAL"], +["''", "SHA256 0x20 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 EQUAL"], +["'a'", "SHA256 0x20 0xca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "SHA256 0x20 0x71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73 EQUAL"], +["''", "DUP HASH160 SWAP SHA256 RIPEMD160 EQUAL"], +["''", "DUP HASH256 SWAP SHA256 SHA256 EQUAL"], +["''", "NOP HASH160 0x14 0xb472a266d0bd89c13706a4132ccfb16f7c3b9fcb EQUAL"], +["'a'", "HASH160 NOP 0x14 0x994355199e516ff76c4fa4aab39337b9d84cf12b EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "HASH160 0x4c 0x14 0xc286a1af0947f58d1ad787385b1c2c4a976f9e71 EQUAL"], +["''", "HASH256 0x20 0x5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456 EQUAL"], +["'a'", "HASH256 0x20 0xbf5d3affb73efd2ec6c36ad3112dd933efed63c4e1cbffcfa88e2759c144f2d8 EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL"], + + +["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL"], +["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL"], + +["0", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid if executed"], +["0", "IF 0xc0 ELSE 1 ENDIF"], +["0", "IF 0xd1 ELSE 1 ENDIF"], +["0", "IF 0xee ELSE 1 ENDIF"], +["0", "IF 0xfd ELSE 1 ENDIF"], +["0", "IF 0xff ELSE 1 ENDIF"], + +["NOP", +"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", +"520 byte push"], +["1", +"0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +"201 opcodes executed. 0x61 is NOP"], +["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1,000 stack size (0x6f is 3DUP)"], +["1 TOALTSTACK 2 TOALTSTACK 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 2 3 4 5 6 7 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1,000 stack size (altstack cleared between scriptSig/scriptPubKey)"], +["'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +"Max-size (10,000-byte), max-push(520 bytes), max-opcodes(201), max stack size(1,000 items). 0x6f is 3DUP, 0x61 is NOP"], + +["NOP","1"], + +["1", "0x01 0x01 EQUAL", "The following is useful for checking implementations of BN_bn2mpi"], +["127", "0x01 0x7F EQUAL"], +["128", "0x02 0x8000 EQUAL", "Leave room for the sign bit"], +["32767", "0x02 0xFF7F EQUAL"], +["32768", "0x03 0x008000 EQUAL"], +["8388607", "0x03 0xFFFF7F EQUAL"], +["8388608", "0x04 0x00008000 EQUAL"], +["2147483647", "0x04 0xFFFFFF7F EQUAL"], +["2147483648", "0x05 0x0000008000 EQUAL"], +["-1", "0x01 0x81 EQUAL", "Numbers are little-endian with the MSB being a sign bit"], +["-127", "0x01 0xFF EQUAL"], +["-128", "0x02 0x8080 EQUAL"], +["-32767", "0x02 0xFFFF EQUAL"], +["-32768", "0x03 0x008080 EQUAL"], +["-8388607", "0x03 0xFFFFFF EQUAL"], +["-8388608", "0x04 0x00008080 EQUAL"], +["-2147483647", "0x04 0xFFFFFFFF EQUAL"], +["-2147483648", "0x05 0x0000008080 EQUAL"], + +["2147483647", "1ADD 2147483648 EQUAL", "We can do math on 4-byte integers, and compare 5-byte ones"], +["2147483647", "1ADD 1"], +["-2147483647", "1ADD 1"], + + +["NOP", "NOP 1", "The following tests check the if(stack.size() < N) tests in each opcode"], +["1", "IF 1 ENDIF", "They are here to catch copy-and-paste errors"], +["0", "NOTIF 1 ENDIF", "Most of them are duplicated elsewhere,"], +["1", "VERIFY 1", "but, hey, more is always better, right?"], + +["0", "TOALTSTACK 1"], +["1", "TOALTSTACK FROMALTSTACK"], +["0 0", "2DROP 1"], +["0 1", "2DUP"], +["0 0 1", "3DUP"], +["0 1 0 0", "2OVER"], +["0 1 0 0 0 0", "2ROT"], +["0 1 0 0", "2SWAP"], +["1", "IFDUP"], +["NOP", "DEPTH 1"], +["0", "DROP 1"], +["1", "DUP"], +["0 1", "NIP"], +["1 0", "OVER"], +["1 0 0 0 3", "PICK"], +["1 0", "PICK"], +["1 0 0 0 3", "ROLL"], +["1 0", "ROLL"], +["1 0 0", "ROT"], +["1 0", "SWAP"], +["0 1", "TUCK"], + +["1", "SIZE"], + +["0 0", "EQUAL"], +["0 0", "EQUALVERIFY 1"], + +["0", "1ADD"], +["2", "1SUB"], +["-1", "NEGATE"], +["-1", "ABS"], +["0", "NOT"], +["-1", "0NOTEQUAL"], + +["1 0", "ADD"], +["1 0", "SUB"], +["-1 -1", "BOOLAND"], +["-1 0", "BOOLOR"], +["0 0", "NUMEQUAL"], +["0 0", "NUMEQUALVERIFY 1"], +["-1 0", "NUMNOTEQUAL"], +["-1 0", "LESSTHAN"], +["1 0", "GREATERTHAN"], +["0 0", "LESSTHANOREQUAL"], +["0 0", "GREATERTHANOREQUAL"], +["-1 0", "MIN"], +["1 0", "MAX"], +["-1 -1 0", "WITHIN"], + +["0", "RIPEMD160"], +["0", "SHA1"], +["0", "SHA256"], +["0", "HASH160"], +["0", "HASH256"], +["NOP", "CODESEPARATOR 1"], + +["NOP", "NOP1 1"], +["NOP", "NOP2 1"], +["NOP", "NOP3 1"], +["NOP", "NOP4 1"], +["NOP", "NOP5 1"], +["NOP", "NOP6 1"], +["NOP", "NOP7 1"], +["NOP", "NOP8 1"], +["NOP", "NOP9 1"], +["NOP", "NOP10 1"], + +["0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "Very basic P2SH"], +["0x4c 0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL"] +] diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json new file mode 100644 index 0000000..f01ee06 --- /dev/null +++ b/src/test/data/tx_invalid.json @@ -0,0 +1,64 @@ +[ +["The following are deserialized transactions which are invalid."], +["They are in the form"], +["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], +["serializedTransaction, enforceP2SH]"], +["Objects that are only a single string (like this one) are ignored"], + +["0e1b5688cf179cd9f7cbda1fac0090f6e684bbf8cd946660120197c3f3681809 but with extra junk appended to the end of the scriptPubKey"], +[[["6ca7ec7b1847f6bdbd737176050e6a08d66ccd55bb94ad24f4018024107a5827", 0, "0x41 0x043b640e983c9690a14c039a2037ecc3467b27a0dcd58f19d76c7bc118d09fec45adc5370a1c5bf8067ca9f5557a4cf885fdb0fe0dcc9c3a7137226106fbc779a5 CHECKSIG VERIFY 1"]], +"010000000127587a10248001f424ad94bb55cd6cd6086a0e05767173bdbdf647187beca76c000000004948304502201b822ad10d6adc1a341ae8835be3f70a25201bbff31f59cbb9c5353a5f0eca18022100ea7b2f7074e9aa9cf70aa8d0ffee13e6b45dddabf1ab961bda378bcdb778fa4701ffffffff0100f2052a010000001976a914fc50c5907d86fed474ba5ce8b12a66e0a4c139d888ac00000000", true], + +["This is the nearly-standard transaction with CHECKSIGVERIFY 1 instead of CHECKSIG from tx_valid.json"], +["but with the signature duplicated in the scriptPubKey with a non-standard pushdata prefix"], +["See FindAndDelete, which will only remove if it uses the same pushdata prefix as is standard"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x4c 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", true], + +["Same as above, but with the sig in the scriptSig also pushed with the same non-standard OP_PUSHDATA"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x4c 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006b4c473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", true], + +["An invalid P2SH Transaction"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", true], + +["Tests for CTransaction::CheckTransaction()"], +["No inputs"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], +"0100000000010000000000000000015100000000", true], + +["No outputs"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x05ab9e14d983742513f0f451e105ffb4198d1dd4 EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022100f16703104aab4e4088317c862daec83440242411b039d14280e03dd33b487ab802201318a7be236672c5c56083eb7a5a195bc57a40af7923ff8545016cd3b571e2a601232103c40e5d339df3f30bf753e7e04450ae4ef76c9e45587d1d993bdc4cd06f0651c7acffffffff0000000000", true], + +["Negative output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xae609aca8061d77c5e111f6bb62501a6bbe2bfdb EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d4830450220063222cbb128731fc09de0d7323746539166544d6c1df84d867ccea84bcc8903022100bf568e8552844de664cd41648a031554327aa8844af34b4f27397c65b92c04de0123210243ec37dee0e2e053a9c976f43147e79bc7d9dc606ea51010af1ac80db6b069e1acffffffff01ffffffffffffffff015100000000", true], + +["MAX_MONEY + 1 output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010140075af0750700015100000000", true], + +["MAX_MONEY output + 1 output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xb558cbf4930954aa6a344363a15668d7477ae716 EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020040075af075070001510001000000000000015100000000", true], + +["Duplicate inputs"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x236d0639db62b0773fd8ac34dc85ae19e9aba80a EQUAL"]], +"01000000020001000000000000000000000000000000000000000000000000000000000000000000006c47304402204bb1197053d0d7799bf1b30cd503c44b58d6240cccbdc85b6fe76d087980208f02204beeed78200178ffc6c74237bb74b3f276bbb4098b5605d814304fe128bf1431012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff0001000000000000000000000000000000000000000000000000000000000000000000006c47304402202306489afef52a6f62e90bf750bbcdf40c06f5c6b138286e6b6b86176bb9341802200dba98486ea68380f47ebb19a7df173b99e6bc9c681d6ccf3bde31465d1f16b3012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff010000000000000000015100000000", true], + +["Coinbase of size 1"], +["Note the input is just required to make the tester happy"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0151ffffffff010000000000000000015100000000", true], + +["Coinbase of size 101"], +["Note the input is just required to make the tester happy"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff655151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", true], + +["Null txin"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "HASH160 0x14 0x02dae7dbbda56097959cba59b1989dd3e47937bf EQUAL"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6e49304602210086f39e028e46dafa8e1e3be63906465f4cf038fbe5ed6403dc3e74ae876e6431022100c4625c675cfc5c7e3a0e0d7eaec92ac24da20c73a88eb40d09253e51ac6def5201232103a183ddc41e84753aca47723c965d1b5c8b0e2b537963518355e6dd6cf8415e50acffffffff010000000000000000015100000000", true] +] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json new file mode 100644 index 0000000..5528ae7 --- /dev/null +++ b/src/test/data/tx_valid.json @@ -0,0 +1,71 @@ +[ +["The following are deserialized transactions which are valid."], +["They are in the form"], +["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], +["serializedTransaction, enforceP2SH]"], +["Objects that are only a single string (like this one) are ignored"], + +["The following is 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], +["It is of particular interest because it contains an invalidly-encoded signature which OpenSSL accepts"], +["See http://r6.ca/blog/20111119T211504Z.html"], +["It is also the first OP_CHECKMULTISIG transaction in standard form"], +[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], +"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000490047304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", true], + +["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], +["It has an arbitrary extra byte stuffed into the signature at pos length - 2"], +[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], +"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004A0048304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2bab01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", true], + +["The following is c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73"], +["It is of interest because it contains a 0-sequence as well as a signature of SIGHASH type 0 (which is not a real type)"], +[[["406b2b06bcd34d3c8733e6b79f7a394c8a431fbf4ff5ac705c93f4076bb77602", 0, "DUP HASH160 0x14 0xdc44b1164188067c3a32d4780f5996fa14a4f2d9 EQUALVERIFY CHECKSIG"]], +"01000000010276b76b07f4935c70acf54fbf1f438a4c397a9fb7e633873c4dd3bc062b6b40000000008c493046022100d23459d03ed7e9511a47d13292d3430a04627de6235b6e51a40f9cd386f2abe3022100e7d25b080f0bb8d8d5f878bba7d54ad2fda650ea8d158a33ee3cbd11768191fd004104b0e2c879e4daf7b9ab68350228c159766676a14f5815084ba166432aab46198d4cca98fa3e9981d0a90b2effc514b76279476550ba3663fdcaff94c38420e9d5000000000100093d00000000001976a9149a7b0f3b80c6baaeedce0a0842553800f832ba1f88ac00000000", true], + +["A nearly-standard transaction with CHECKSIGVERIFY 1 instead of CHECKSIG"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", true], + +["Same as above, but with the signature duplicated in the scriptPubKey with the proper pushdata prefix"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", true], + +["The following is f7fdd091fa6d8f5e7a8c2458f5c38faffff2d3f1406b6e4fe2c99dcc0d2d1cbb"], +["It caught a bug in the workaround for 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63 in an overly simple implementation"], +[[["b464e85df2a238416f8bdae11d120add610380ea07f4ef19c5f9dfd472f96c3d", 0, "DUP HASH160 0x14 0xbef80ecf3a44500fda1bc92176e442891662aed2 EQUALVERIFY CHECKSIG"], +["b7978cc96e59a8b13e0865d3f95657561a7f725be952438637475920bac9eb21", 1, "DUP HASH160 0x14 0xbef80ecf3a44500fda1bc92176e442891662aed2 EQUALVERIFY CHECKSIG"]], +"01000000023d6cf972d4dff9c519eff407ea800361dd0a121de1da8b6f4138a2f25de864b4000000008a4730440220ffda47bfc776bcd269da4832626ac332adfca6dd835e8ecd83cd1ebe7d709b0e022049cffa1cdc102a0b56e0e04913606c70af702a1149dc3b305ab9439288fee090014104266abb36d66eb4218a6dd31f09bb92cf3cfa803c7ea72c1fc80a50f919273e613f895b855fb7465ccbc8919ad1bd4a306c783f22cd3227327694c4fa4c1c439affffffff21ebc9ba20594737864352e95b727f1a565756f9d365083eb1a8596ec98c97b7010000008a4730440220503ff10e9f1e0de731407a4a245531c9ff17676eda461f8ceeb8c06049fa2c810220c008ac34694510298fa60b3f000df01caa244f165b727d4896eb84f81e46bcc4014104266abb36d66eb4218a6dd31f09bb92cf3cfa803c7ea72c1fc80a50f919273e613f895b855fb7465ccbc8919ad1bd4a306c783f22cd3227327694c4fa4c1c439affffffff01f0da5200000000001976a914857ccd42dded6df32949d4646dfa10a92458cfaa88ac00000000", true], + +["The following tests for the presence of a bug in the handling of SIGHASH_SINGLE"], +["It results in signing the constant 1, instead of something generated based on the transaction,"], +["when the input doing the signing has an index greater than the maximum output index"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0xe52b482f2faa8ecbf0db344f93c84ac908557f33 EQUALVERIFY CHECKSIG"], ["0000000000000000000000000000000000000000000000000000000000000200", 0, "1"]], +"01000000020002000000000000000000000000000000000000000000000000000000000000000000000151ffffffff0001000000000000000000000000000000000000000000000000000000000000000000006b483045022100c9cdd08798a28af9d1baf44a6c77bcc7e279f47dc487c8c899911bc48feaffcc0220503c5c50ae3998a733263c5c0f7061b483e2b56c4c41b456e7d2f5a78a74c077032102d5c25adb51b61339d2b05315791e21bbe80ea470a49db0135720983c905aace0ffffffff010000000000000000015100000000", true], + +["An invalid P2SH Transaction"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", false], + +["A valid P2SH Transaction using the standard transaction type put forth in BIP 16"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x8febbed40483661de6958d957412f82deed8e2f7 EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100c66c9cdf4c43609586d15424c54707156e316d88b0a1534c9e6b0d4f311406310221009c0fe51dbc9c4ab7cc25d3fdbeccf6679fe6827f08edf2b4a9f16ee3eb0e438a0123210338e8034509af564c62644c07691942e0c056752008a173c89f60ab2a88ac2ebfacffffffff010000000000000000015100000000", true], + +["Tests for CTransaction::CheckTransaction()"], +["MAX_MONEY output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010040075af0750700015100000000", true], + +["MAX_MONEY output + 0 output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xb558cbf4930954aa6a344363a15668d7477ae716 EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020040075af075070001510000000000000000015100000000", true], + +["Coinbase of size 2"], +["Note the input is just required to make the tester happy"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025151ffffffff010000000000000000015100000000", true], + +["Coinbase of size 100"], +["Note the input is just required to make the tester happy"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6451515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", true] +] diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp new file mode 100644 index 0000000..78953d2 --- /dev/null +++ b/src/test/getarg_tests.cpp @@ -0,0 +1,167 @@ +#include +#include +#include + +#include "util.h" + +BOOST_AUTO_TEST_SUITE(getarg_tests) + +static void +ResetArgs(const std::string& strArg) +{ + std::vector vecArg; + boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on); + + // Insert dummy executable name: + vecArg.insert(vecArg.begin(), "testbitcoin"); + + // Convert to char*: + std::vector vecChar; + BOOST_FOREACH(std::string& s, vecArg) + vecChar.push_back(s.c_str()); + + ParseParameters(vecChar.size(), &vecChar[0]); +} + +BOOST_AUTO_TEST_CASE(boolarg) +{ + ResetArgs("-foo"); + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + BOOST_CHECK(!GetBoolArg("-fo")); + BOOST_CHECK(!GetBoolArg("-fo", false)); + BOOST_CHECK(GetBoolArg("-fo", true)); + + BOOST_CHECK(!GetBoolArg("-fooo")); + BOOST_CHECK(!GetBoolArg("-fooo", false)); + BOOST_CHECK(GetBoolArg("-fooo", true)); + + ResetArgs("-foo=0"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + + ResetArgs("-foo=1"); + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + // New 0.6 feature: auto-map -nosomething to !-something: + ResetArgs("-nofoo"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + + ResetArgs("-nofoo=1"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + + ResetArgs("-foo -nofoo"); // -foo should win + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + ResetArgs("-foo=1 -nofoo=1"); // -foo should win + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + ResetArgs("-foo=0 -nofoo=0"); // -foo should win + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + + // New 0.6 feature: treat -- same as -: + ResetArgs("--foo=1"); + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + ResetArgs("--nofoo=1"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + +} + +BOOST_AUTO_TEST_CASE(stringarg) +{ + ResetArgs(""); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), "eleven"); + + ResetArgs("-foo -bar"); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), ""); + + ResetArgs("-foo="); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), ""); + + ResetArgs("-foo=11"); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), "11"); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), "11"); + + ResetArgs("-foo=eleven"); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), "eleven"); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), "eleven"); + +} + +BOOST_AUTO_TEST_CASE(intarg) +{ + ResetArgs(""); + BOOST_CHECK_EQUAL(GetArg("-foo", 11), 11); + BOOST_CHECK_EQUAL(GetArg("-foo", 0), 0); + + ResetArgs("-foo -bar"); + BOOST_CHECK_EQUAL(GetArg("-foo", 11), 0); + BOOST_CHECK_EQUAL(GetArg("-bar", 11), 0); + + ResetArgs("-foo=11 -bar=12"); + BOOST_CHECK_EQUAL(GetArg("-foo", 0), 11); + BOOST_CHECK_EQUAL(GetArg("-bar", 11), 12); + + ResetArgs("-foo=NaN -bar=NotANumber"); + BOOST_CHECK_EQUAL(GetArg("-foo", 1), 0); + BOOST_CHECK_EQUAL(GetArg("-bar", 11), 0); +} + +BOOST_AUTO_TEST_CASE(doubledash) +{ + ResetArgs("--foo"); + BOOST_CHECK_EQUAL(GetBoolArg("-foo"), true); + + ResetArgs("--foo=verbose --bar=1"); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), "verbose"); + BOOST_CHECK_EQUAL(GetArg("-bar", 0), 1); +} + +BOOST_AUTO_TEST_CASE(boolargno) +{ + ResetArgs("-nofoo"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!GetBoolArg("-foo", false)); + + ResetArgs("-nofoo=1"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!GetBoolArg("-foo", false)); + + ResetArgs("-nofoo=0"); + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", true)); + BOOST_CHECK(GetBoolArg("-foo", false)); + + ResetArgs("-foo --nofoo"); + BOOST_CHECK(GetBoolArg("-foo")); + + ResetArgs("-nofoo -foo"); // foo always wins: + BOOST_CHECK(GetBoolArg("-foo")); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp new file mode 100644 index 0000000..0a6df88 --- /dev/null +++ b/src/test/key_tests.cpp @@ -0,0 +1,147 @@ +#include + +#include +#include + +#include "key.h" +#include "base58.h" +#include "uint256.h" +#include "util.h" + +using namespace std; + +static const string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj"); +static const string strSecret2 ("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3"); +static const string strSecret1C ("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw"); +static const string strSecret2C ("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g"); +static const CBitcoinAddress addr1 ("1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ"); +static const CBitcoinAddress addr2 ("1F5y5E5FMc5YzdJtB9hLaUe43GDxEKXENJ"); +static const CBitcoinAddress addr1C("1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs"); +static const CBitcoinAddress addr2C("1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs"); + + +static const string strAddressBad("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF"); + + +#ifdef KEY_TESTS_DUMPINFO +void dumpKeyInfo(uint256 privkey) +{ + CSecret secret; + secret.resize(32); + memcpy(&secret[0], &privkey, 32); + vector sec; + sec.resize(32); + memcpy(&sec[0], &secret[0], 32); + printf(" * secret (hex): %s\n", HexStr(sec).c_str()); + + for (int nCompressed=0; nCompressed<2; nCompressed++) + { + bool fCompressed = nCompressed == 1; + printf(" * %s:\n", fCompressed ? "compressed" : "uncompressed"); + CBitcoinSecret bsecret; + bsecret.SetSecret(secret, fCompressed); + printf(" * secret (base58): %s\n", bsecret.ToString().c_str()); + CKey key; + key.SetSecret(secret, fCompressed); + vector vchPubKey = key.GetPubKey(); + printf(" * pubkey (hex): %s\n", HexStr(vchPubKey).c_str()); + printf(" * address (base58): %s\n", CBitcoinAddress(vchPubKey).ToString().c_str()); + } +} +#endif + + +BOOST_AUTO_TEST_SUITE(key_tests) + +BOOST_AUTO_TEST_CASE(key_test1) +{ + CBitcoinSecret bsecret1, bsecret2, bsecret1C, bsecret2C, baddress1; + BOOST_CHECK( bsecret1.SetString (strSecret1)); + BOOST_CHECK( bsecret2.SetString (strSecret2)); + BOOST_CHECK( bsecret1C.SetString(strSecret1C)); + BOOST_CHECK( bsecret2C.SetString(strSecret2C)); + BOOST_CHECK(!baddress1.SetString(strAddressBad)); + + bool fCompressed; + CSecret secret1 = bsecret1.GetSecret (fCompressed); + BOOST_CHECK(fCompressed == false); + CSecret secret2 = bsecret2.GetSecret (fCompressed); + BOOST_CHECK(fCompressed == false); + CSecret secret1C = bsecret1C.GetSecret(fCompressed); + BOOST_CHECK(fCompressed == true); + CSecret secret2C = bsecret2C.GetSecret(fCompressed); + BOOST_CHECK(fCompressed == true); + + BOOST_CHECK(secret1 == secret1C); + BOOST_CHECK(secret2 == secret2C); + + CKey key1, key2, key1C, key2C; + key1.SetSecret(secret1, false); + key2.SetSecret(secret2, false); + key1C.SetSecret(secret1, true); + key2C.SetSecret(secret2, true); + + BOOST_CHECK(addr1.Get() == CTxDestination(key1.GetPubKey().GetID())); + BOOST_CHECK(addr2.Get() == CTxDestination(key2.GetPubKey().GetID())); + BOOST_CHECK(addr1C.Get() == CTxDestination(key1C.GetPubKey().GetID())); + BOOST_CHECK(addr2C.Get() == CTxDestination(key2C.GetPubKey().GetID())); + + for (int n=0; n<16; n++) + { + string strMsg = strprintf("Very secret message %i: 11", n); + uint256 hashMsg = Hash(strMsg.begin(), strMsg.end()); + + // normal signatures + + vector sign1, sign2, sign1C, sign2C; + + BOOST_CHECK(key1.Sign (hashMsg, sign1)); + BOOST_CHECK(key2.Sign (hashMsg, sign2)); + BOOST_CHECK(key1C.Sign(hashMsg, sign1C)); + BOOST_CHECK(key2C.Sign(hashMsg, sign2C)); + + BOOST_CHECK( key1.Verify(hashMsg, sign1)); + BOOST_CHECK(!key1.Verify(hashMsg, sign2)); + BOOST_CHECK( key1.Verify(hashMsg, sign1C)); + BOOST_CHECK(!key1.Verify(hashMsg, sign2C)); + + BOOST_CHECK(!key2.Verify(hashMsg, sign1)); + BOOST_CHECK( key2.Verify(hashMsg, sign2)); + BOOST_CHECK(!key2.Verify(hashMsg, sign1C)); + BOOST_CHECK( key2.Verify(hashMsg, sign2C)); + + BOOST_CHECK( key1C.Verify(hashMsg, sign1)); + BOOST_CHECK(!key1C.Verify(hashMsg, sign2)); + BOOST_CHECK( key1C.Verify(hashMsg, sign1C)); + BOOST_CHECK(!key1C.Verify(hashMsg, sign2C)); + + BOOST_CHECK(!key2C.Verify(hashMsg, sign1)); + BOOST_CHECK( key2C.Verify(hashMsg, sign2)); + BOOST_CHECK(!key2C.Verify(hashMsg, sign1C)); + BOOST_CHECK( key2C.Verify(hashMsg, sign2C)); + + // compact signatures (with key recovery) + + vector csign1, csign2, csign1C, csign2C; + + BOOST_CHECK(key1.SignCompact (hashMsg, csign1)); + BOOST_CHECK(key2.SignCompact (hashMsg, csign2)); + BOOST_CHECK(key1C.SignCompact(hashMsg, csign1C)); + BOOST_CHECK(key2C.SignCompact(hashMsg, csign2C)); + + CKey rkey1, rkey2, rkey1C, rkey2C; + + BOOST_CHECK(rkey1.SetCompactSignature (hashMsg, csign1)); + BOOST_CHECK(rkey2.SetCompactSignature (hashMsg, csign2)); + BOOST_CHECK(rkey1C.SetCompactSignature(hashMsg, csign1C)); + BOOST_CHECK(rkey2C.SetCompactSignature(hashMsg, csign2C)); + + + BOOST_CHECK(rkey1.GetPubKey() == key1.GetPubKey()); + BOOST_CHECK(rkey2.GetPubKey() == key2.GetPubKey()); + BOOST_CHECK(rkey1C.GetPubKey() == key1C.GetPubKey()); + BOOST_CHECK(rkey2C.GetPubKey() == key2C.GetPubKey()); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp new file mode 100644 index 0000000..4558a76 --- /dev/null +++ b/src/test/miner_tests.cpp @@ -0,0 +1,227 @@ +#include + +#include "init.h" +#include "main.h" +#include "uint256.h" +#include "util.h" +#include "wallet.h" + +extern void SHA256Transform(void* pstate, void* pinput, const void* pinit); + +BOOST_AUTO_TEST_SUITE(miner_tests) + +static +struct { + unsigned char extranonce; + unsigned int nonce; +} blockinfo[] = { + {4, 0xa4a3e223}, {2, 0x15c32f9e}, {1, 0x0375b547}, {1, 0x7004a8a5}, + {2, 0xce440296}, {2, 0x52cfe198}, {1, 0x77a72cd0}, {2, 0xbb5d6f84}, + {2, 0x83f30c2c}, {1, 0x48a73d5b}, {1, 0xef7dcd01}, {2, 0x6809c6c4}, + {2, 0x0883ab3c}, {1, 0x087bbbe2}, {2, 0x2104a814}, {2, 0xdffb6daa}, + {1, 0xee8a0a08}, {2, 0xba4237c1}, {1, 0xa70349dc}, {1, 0x344722bb}, + {3, 0xd6294733}, {2, 0xec9f5c94}, {2, 0xca2fbc28}, {1, 0x6ba4f406}, + {2, 0x015d4532}, {1, 0x6e119b7c}, {2, 0x43e8f314}, {2, 0x27962f38}, + {2, 0xb571b51b}, {2, 0xb36bee23}, {2, 0xd17924a8}, {2, 0x6bc212d9}, + {1, 0x630d4948}, {2, 0x9a4c4ebb}, {2, 0x554be537}, {1, 0xd63ddfc7}, + {2, 0xa10acc11}, {1, 0x759a8363}, {2, 0xfb73090d}, {1, 0xe82c6a34}, + {1, 0xe33e92d7}, {3, 0x658ef5cb}, {2, 0xba32ff22}, {5, 0x0227a10c}, + {1, 0xa9a70155}, {5, 0xd096d809}, {1, 0x37176174}, {1, 0x830b8d0f}, + {1, 0xc6e3910e}, {2, 0x823f3ca8}, {1, 0x99850849}, {1, 0x7521fb81}, + {1, 0xaacaabab}, {1, 0xd645a2eb}, {5, 0x7aea1781}, {5, 0x9d6e4b78}, + {1, 0x4ce90fd8}, {1, 0xabdc832d}, {6, 0x4a34f32a}, {2, 0xf2524c1c}, + {2, 0x1bbeb08a}, {1, 0xad47f480}, {1, 0x9f026aeb}, {1, 0x15a95049}, + {2, 0xd1cb95b2}, {2, 0xf84bbda5}, {1, 0x0fa62cd1}, {1, 0xe05f9169}, + {1, 0x78d194a9}, {5, 0x3e38147b}, {5, 0x737ba0d4}, {1, 0x63378e10}, + {1, 0x6d5f91cf}, {2, 0x88612eb8}, {2, 0xe9639484}, {1, 0xb7fabc9d}, + {2, 0x19b01592}, {1, 0x5a90dd31}, {2, 0x5bd7e028}, {2, 0x94d00323}, + {1, 0xa9b9c01a}, {1, 0x3a40de61}, {1, 0x56e7eec7}, {5, 0x859f7ef6}, + {1, 0xfd8e5630}, {1, 0x2b0c9f7f}, {1, 0xba700e26}, {1, 0x7170a408}, + {1, 0x70de86a8}, {1, 0x74d64cd5}, {1, 0x49e738a1}, {2, 0x6910b602}, + {0, 0x643c565f}, {1, 0x54264b3f}, {2, 0x97ea6396}, {2, 0x55174459}, + {2, 0x03e8779a}, {1, 0x98f34d8f}, {1, 0xc07b2b07}, {1, 0xdfe29668}, + {1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce}, + {2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e}, + {2, 0xbbbeb305}, {2, 0xfe1c810a}, +}; + +// NOTE: These tests rely on CreateNewBlock doing its own self-validation! +BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) +{ + CReserveKey reservekey(pwalletMain); + CBlock *pblock; + CTransaction tx; + CScript script; + uint256 hash; + + // Simple block creation, nothing special yet: + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + + // We can't make transactions until we have inputs + // Therefore, load 100 blocks :) + std::vectortxFirst; + for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i) + { + pblock->nVersion = 1; + pblock->nTime = pindexBest->GetMedianTimePast()+1; + pblock->vtx[0].vin[0].scriptSig = CScript(); + pblock->vtx[0].vin[0].scriptSig.push_back(blockinfo[i].extranonce); + pblock->vtx[0].vin[0].scriptSig.push_back(pindexBest->nHeight); + pblock->vtx[0].vout[0].scriptPubKey = CScript(); + if (txFirst.size() < 2) + txFirst.push_back(new CTransaction(pblock->vtx[0])); + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + pblock->nNonce = blockinfo[i].nonce; + assert(ProcessBlock(NULL, pblock)); + pblock->hashPrevBlock = pblock->GetHash(); + } + delete pblock; + + // Just to make sure we can still make simple blocks + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + + // block sigops > limit: 1000 CHECKMULTISIG + 1 + tx.vin.resize(1); + // NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG + tx.vin[0].scriptSig = CScript() << OP_0 << OP_0 << OP_0 << OP_NOP << OP_CHECKMULTISIG << OP_1; + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vin[0].prevout.n = 0; + tx.vout.resize(1); + tx.vout[0].nValue = 5000000000LL; + for (unsigned int i = 0; i < 1001; ++i) + { + tx.vout[0].nValue -= 1000000; + hash = tx.GetHash(); + mempool.addUnchecked(hash, tx); + tx.vin[0].prevout.hash = hash; + } + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + delete pblock; + mempool.clear(); + + // block size > limit + tx.vin[0].scriptSig = CScript(); + // 18 * (520char + DROP) + OP_1 = 9433 bytes + std::vector vchData(520); + for (unsigned int i = 0; i < 18; ++i) + tx.vin[0].scriptSig << vchData << OP_DROP; + tx.vin[0].scriptSig << OP_1; + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vout[0].nValue = 5000000000LL; + for (unsigned int i = 0; i < 128; ++i) + { + tx.vout[0].nValue -= 10000000; + hash = tx.GetHash(); + mempool.addUnchecked(hash, tx); + tx.vin[0].prevout.hash = hash; + } + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + delete pblock; + mempool.clear(); + + // orphan in mempool + hash = tx.GetHash(); + mempool.addUnchecked(hash, tx); + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + delete pblock; + mempool.clear(); + + // child with higher priority than parent + tx.vin[0].scriptSig = CScript() << OP_1; + tx.vin[0].prevout.hash = txFirst[1]->GetHash(); + tx.vout[0].nValue = 4900000000LL; + hash = tx.GetHash(); + mempool.addUnchecked(hash, tx); + tx.vin[0].prevout.hash = hash; + tx.vin.resize(2); + tx.vin[1].scriptSig = CScript() << OP_1; + tx.vin[1].prevout.hash = txFirst[0]->GetHash(); + tx.vin[1].prevout.n = 0; + tx.vout[0].nValue = 5900000000LL; + hash = tx.GetHash(); + mempool.addUnchecked(hash, tx); + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + delete pblock; + mempool.clear(); + + // coinbase in mempool + tx.vin.resize(1); + tx.vin[0].prevout.SetNull(); + tx.vin[0].scriptSig = CScript() << OP_0 << OP_1; + tx.vout[0].nValue = 0; + hash = tx.GetHash(); + mempool.addUnchecked(hash, tx); + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + delete pblock; + mempool.clear(); + + // invalid (pre-p2sh) txn in mempool + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vin[0].prevout.n = 0; + tx.vin[0].scriptSig = CScript() << OP_1; + tx.vout[0].nValue = 4900000000LL; + script = CScript() << OP_0; + tx.vout[0].scriptPubKey.SetDestination(script.GetID()); + hash = tx.GetHash(); + mempool.addUnchecked(hash, tx); + tx.vin[0].prevout.hash = hash; + tx.vin[0].scriptSig = CScript() << (std::vector)script; + tx.vout[0].nValue -= 1000000; + hash = tx.GetHash(); + mempool.addUnchecked(hash,tx); + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + delete pblock; + mempool.clear(); + + // double spend txn pair in mempool + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vin[0].scriptSig = CScript() << OP_1; + tx.vout[0].nValue = 4900000000LL; + tx.vout[0].scriptPubKey = CScript() << OP_1; + hash = tx.GetHash(); + mempool.addUnchecked(hash, tx); + tx.vout[0].scriptPubKey = CScript() << OP_2; + hash = tx.GetHash(); + mempool.addUnchecked(hash, tx); + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + delete pblock; + mempool.clear(); + + // subsidy changing + int nHeight = pindexBest->nHeight; + pindexBest->nHeight = 209999; + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + delete pblock; + pindexBest->nHeight = 210000; + BOOST_CHECK(pblock = CreateNewBlock(reservekey)); + delete pblock; + pindexBest->nHeight = nHeight; +} + +BOOST_AUTO_TEST_CASE(sha256transform_equality) +{ + unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + + + // unsigned char pstate[32]; + unsigned char pinput[64]; + + int i; + + for (i = 0; i < 32; i++) { + pinput[i] = i; + pinput[i+32] = 0; + } + + uint256 hash; + + SHA256Transform(&hash, pinput, pSHA256InitState); + + BOOST_TEST_MESSAGE(hash.GetHex()); + + uint256 hash_reference("0x2df5e1c65ef9f8cde240d23cae2ec036d31a15ec64bc68f64be242b1da6631f3"); + + BOOST_CHECK(hash == hash_reference); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp new file mode 100644 index 0000000..64a6678 --- /dev/null +++ b/src/test/mruset_tests.cpp @@ -0,0 +1,90 @@ +#include + +using namespace std; + +#include "mruset.h" +#include "util.h" + +#define NUM_TESTS 16 +#define MAX_SIZE 100 + +class mrutester +{ +private: + mruset mru; + std::set set; + +public: + mrutester() { mru.max_size(MAX_SIZE); } + int size() const { return set.size(); } + + void insert(int n) + { + mru.insert(n); + set.insert(n); + BOOST_CHECK(mru == set); + } +}; + +BOOST_AUTO_TEST_SUITE(mruset_tests) + +// Test that an mruset behaves like a set, as long as no more than MAX_SIZE elements are in it +BOOST_AUTO_TEST_CASE(mruset_like_set) +{ + + for (int nTest=0; nTest mru(MAX_SIZE); + for (int nAction=0; nAction<3*MAX_SIZE; nAction++) + { + int n = GetRandInt(2 * MAX_SIZE); + mru.insert(n); + BOOST_CHECK(mru.size() <= MAX_SIZE); + } + } +} + +// 16-bit permutation function +int static permute(int n) +{ + // hexadecimals of pi; verified to be linearly independent + static const int table[16] = {0x243F, 0x6A88, 0x85A3, 0x08D3, 0x1319, 0x8A2E, 0x0370, 0x7344, + 0xA409, 0x3822, 0x299F, 0x31D0, 0x082E, 0xFA98, 0xEC4E, 0x6C89}; + + int ret = 0; + for (int bit=0; bit<16; bit++) + if (n & (1< mru(MAX_SIZE); + for (int n=0; n<10*MAX_SIZE; n++) + { + mru.insert(permute(n)); + + set tester; + for (int m=max(0,n-MAX_SIZE+1); m<=n; m++) + tester.insert(permute(m)); + + BOOST_CHECK(mru == tester); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp new file mode 100644 index 0000000..6bc5e3b --- /dev/null +++ b/src/test/multisig_tests.cpp @@ -0,0 +1,296 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "keystore.h" +#include "main.h" +#include "script.h" +#include "wallet.h" + +using namespace std; +using namespace boost::assign; + +typedef vector valtype; + +extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType); + +BOOST_AUTO_TEST_SUITE(multisig_tests) + +CScript +sign_multisig(CScript scriptPubKey, vector keys, CTransaction transaction, int whichIn) +{ + uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL); + + CScript result; + result << OP_0; // CHECKMULTISIG bug workaround + BOOST_FOREACH(CKey key, keys) + { + vector vchSig; + BOOST_CHECK(key.Sign(hash, vchSig)); + vchSig.push_back((unsigned char)SIGHASH_ALL); + result << vchSig; + } + return result; +} + +BOOST_AUTO_TEST_CASE(multisig_verify) +{ + CKey key[4]; + for (int i = 0; i < 4; i++) + key[i].MakeNewKey(true); + + CScript a_and_b; + a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CScript a_or_b; + a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CScript escrow; + escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + + CTransaction txFrom; // Funding transaction + txFrom.vout.resize(3); + txFrom.vout[0].scriptPubKey = a_and_b; + txFrom.vout[1].scriptPubKey = a_or_b; + txFrom.vout[2].scriptPubKey = escrow; + + CTransaction txTo[3]; // Spending transaction + for (int i = 0; i < 3; i++) + { + txTo[i].vin.resize(1); + txTo[i].vout.resize(1); + txTo[i].vin[0].prevout.n = i; + txTo[i].vin[0].prevout.hash = txFrom.GetHash(); + txTo[i].vout[0].nValue = 1; + } + + vector keys; + CScript s; + + // Test a AND b: + keys.clear(); + keys += key[0],key[1]; // magic operator+= from boost.assign + s = sign_multisig(a_and_b, keys, txTo[0], 0); + BOOST_CHECK(VerifyScript(s, a_and_b, txTo[0], 0, true, 0)); + + for (int i = 0; i < 4; i++) + { + keys.clear(); + keys += key[i]; + s = sign_multisig(a_and_b, keys, txTo[0], 0); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, true, 0), strprintf("a&b 1: %d", i)); + + keys.clear(); + keys += key[1],key[i]; + s = sign_multisig(a_and_b, keys, txTo[0], 0); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, true, 0), strprintf("a&b 2: %d", i)); + } + + // Test a OR b: + for (int i = 0; i < 4; i++) + { + keys.clear(); + keys += key[i]; + s = sign_multisig(a_or_b, keys, txTo[1], 0); + if (i == 0 || i == 1) + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, txTo[1], 0, true, 0), strprintf("a|b: %d", i)); + else + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, txTo[1], 0, true, 0), strprintf("a|b: %d", i)); + } + s.clear(); + s << OP_0 << OP_0; + BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, true, 0)); + s.clear(); + s << OP_0 << OP_1; + BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, true, 0)); + + + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + { + keys.clear(); + keys += key[i],key[j]; + s = sign_multisig(escrow, keys, txTo[2], 0); + if (i < j && i < 3 && j < 3) + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, txTo[2], 0, true, 0), strprintf("escrow 1: %d %d", i, j)); + else + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, txTo[2], 0, true, 0), strprintf("escrow 2: %d %d", i, j)); + } +} + +BOOST_AUTO_TEST_CASE(multisig_IsStandard) +{ + CKey key[4]; + for (int i = 0; i < 4; i++) + key[i].MakeNewKey(true); + + CScript a_and_b; + a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK(::IsStandard(a_and_b)); + + CScript a_or_b; + a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK(::IsStandard(a_or_b)); + + CScript escrow; + escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + BOOST_CHECK(::IsStandard(escrow)); + + CScript one_of_four; + one_of_four << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << key[3].GetPubKey() << OP_4 << OP_CHECKMULTISIG; + BOOST_CHECK(!::IsStandard(one_of_four)); + + CScript malformed[6]; + malformed[0] << OP_3 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + malformed[1] << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + malformed[2] << OP_0 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + malformed[3] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_0 << OP_CHECKMULTISIG; + malformed[4] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_CHECKMULTISIG; + malformed[5] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey(); + + for (int i = 0; i < 6; i++) + BOOST_CHECK(!::IsStandard(malformed[i])); +} + +BOOST_AUTO_TEST_CASE(multisig_Solver1) +{ + // Tests Solver() that returns lists of keys that are + // required to satisfy a ScriptPubKey + // + // Also tests IsMine() and ExtractAddress() + // + // Note: ExtractAddress for the multisignature transactions + // always returns false for this release, even if you have + // one key that would satisfy an (a|b) or 2-of-3 keys needed + // to spend an escrow transaction. + // + CBasicKeyStore keystore, emptykeystore, partialkeystore; + CKey key[3]; + CTxDestination keyaddr[3]; + for (int i = 0; i < 3; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + keyaddr[i] = key[i].GetPubKey().GetID(); + } + partialkeystore.AddKey(key[0]); + + { + vector solutions; + txnouttype whichType; + CScript s; + s << key[0].GetPubKey() << OP_CHECKSIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK(solutions.size() == 1); + CTxDestination addr; + BOOST_CHECK(ExtractDestination(s, addr)); + BOOST_CHECK(addr == keyaddr[0]); + BOOST_CHECK(IsMine(keystore, s)); + BOOST_CHECK(!IsMine(emptykeystore, s)); + } + { + vector solutions; + txnouttype whichType; + CScript s; + s << OP_DUP << OP_HASH160 << key[0].GetPubKey().GetID() << OP_EQUALVERIFY << OP_CHECKSIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK(solutions.size() == 1); + CTxDestination addr; + BOOST_CHECK(ExtractDestination(s, addr)); + BOOST_CHECK(addr == keyaddr[0]); + BOOST_CHECK(IsMine(keystore, s)); + BOOST_CHECK(!IsMine(emptykeystore, s)); + } + { + vector solutions; + txnouttype whichType; + CScript s; + s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(solutions.size(), 4); + CTxDestination addr; + BOOST_CHECK(!ExtractDestination(s, addr)); + BOOST_CHECK(IsMine(keystore, s)); + BOOST_CHECK(!IsMine(emptykeystore, s)); + BOOST_CHECK(!IsMine(partialkeystore, s)); + } + { + vector solutions; + txnouttype whichType; + CScript s; + s << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(solutions.size(), 4); + vector addrs; + int nRequired; + BOOST_CHECK(ExtractDestinations(s, whichType, addrs, nRequired)); + BOOST_CHECK(addrs[0] == keyaddr[0]); + BOOST_CHECK(addrs[1] == keyaddr[1]); + BOOST_CHECK(nRequired == 1); + BOOST_CHECK(IsMine(keystore, s)); + BOOST_CHECK(!IsMine(emptykeystore, s)); + BOOST_CHECK(!IsMine(partialkeystore, s)); + } + { + vector solutions; + txnouttype whichType; + CScript s; + s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK(solutions.size() == 5); + } +} + +BOOST_AUTO_TEST_CASE(multisig_Sign) +{ + // Test SignSignature() (and therefore the version of Solver() that signs transactions) + CBasicKeyStore keystore; + CKey key[4]; + for (int i = 0; i < 4; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + } + + CScript a_and_b; + a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CScript a_or_b; + a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CScript escrow; + escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + + CTransaction txFrom; // Funding transaction + txFrom.vout.resize(3); + txFrom.vout[0].scriptPubKey = a_and_b; + txFrom.vout[1].scriptPubKey = a_or_b; + txFrom.vout[2].scriptPubKey = escrow; + + CTransaction txTo[3]; // Spending transaction + for (int i = 0; i < 3; i++) + { + txTo[i].vin.resize(1); + txTo[i].vout.resize(1); + txTo[i].vin[0].prevout.n = i; + txTo[i].vin[0].prevout.hash = txFrom.GetHash(); + txTo[i].vout[0].nValue = 1; + } + + for (int i = 0; i < 3; i++) + { + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + } +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp new file mode 100644 index 0000000..e5a7562 --- /dev/null +++ b/src/test/netbase_tests.cpp @@ -0,0 +1,102 @@ +#include + +#include +#include + +#include "netbase.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(netbase_tests) + +BOOST_AUTO_TEST_CASE(netbase_networks) +{ + BOOST_CHECK(CNetAddr("127.0.0.1").GetNetwork() == NET_UNROUTABLE); + BOOST_CHECK(CNetAddr("::1").GetNetwork() == NET_UNROUTABLE); + BOOST_CHECK(CNetAddr("8.8.8.8").GetNetwork() == NET_IPV4); + BOOST_CHECK(CNetAddr("2001::8888").GetNetwork() == NET_IPV6); + BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_TOR); +} + +BOOST_AUTO_TEST_CASE(netbase_properties) +{ + BOOST_CHECK(CNetAddr("127.0.0.1").IsIPv4()); + BOOST_CHECK(CNetAddr("::FFFF:192.168.1.1").IsIPv4()); + BOOST_CHECK(CNetAddr("::1").IsIPv6()); + BOOST_CHECK(CNetAddr("10.0.0.1").IsRFC1918()); + BOOST_CHECK(CNetAddr("192.168.1.1").IsRFC1918()); + BOOST_CHECK(CNetAddr("172.31.255.255").IsRFC1918()); + BOOST_CHECK(CNetAddr("2001:0DB8::").IsRFC3849()); + BOOST_CHECK(CNetAddr("169.254.1.1").IsRFC3927()); + BOOST_CHECK(CNetAddr("2002::1").IsRFC3964()); + BOOST_CHECK(CNetAddr("FC00::").IsRFC4193()); + BOOST_CHECK(CNetAddr("2001::2").IsRFC4380()); + BOOST_CHECK(CNetAddr("2001:10::").IsRFC4843()); + BOOST_CHECK(CNetAddr("FE80::").IsRFC4862()); + BOOST_CHECK(CNetAddr("64:FF9B::").IsRFC6052()); + BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor()); + BOOST_CHECK(CNetAddr("127.0.0.1").IsLocal()); + BOOST_CHECK(CNetAddr("::1").IsLocal()); + BOOST_CHECK(CNetAddr("8.8.8.8").IsRoutable()); + BOOST_CHECK(CNetAddr("2001::1").IsRoutable()); + BOOST_CHECK(CNetAddr("127.0.0.1").IsValid()); +} + +bool static TestSplitHost(string test, string host, int port) +{ + string hostOut; + int portOut = -1; + SplitHostPort(test, portOut, hostOut); + return hostOut == host && port == portOut; +} + +BOOST_AUTO_TEST_CASE(netbase_splithost) +{ + BOOST_CHECK(TestSplitHost("www.bitcoin.org", "www.bitcoin.org", -1)); + BOOST_CHECK(TestSplitHost("[www.bitcoin.org]", "www.bitcoin.org", -1)); + BOOST_CHECK(TestSplitHost("www.bitcoin.org:80", "www.bitcoin.org", 80)); + BOOST_CHECK(TestSplitHost("[www.bitcoin.org]:80", "www.bitcoin.org", 80)); + BOOST_CHECK(TestSplitHost("127.0.0.1", "127.0.0.1", -1)); + BOOST_CHECK(TestSplitHost("127.0.0.1:8333", "127.0.0.1", 8333)); + BOOST_CHECK(TestSplitHost("[127.0.0.1]", "127.0.0.1", -1)); + BOOST_CHECK(TestSplitHost("[127.0.0.1]:8333", "127.0.0.1", 8333)); + BOOST_CHECK(TestSplitHost("::ffff:127.0.0.1", "::ffff:127.0.0.1", -1)); + BOOST_CHECK(TestSplitHost("[::ffff:127.0.0.1]:8333", "::ffff:127.0.0.1", 8333)); + BOOST_CHECK(TestSplitHost("[::]:8333", "::", 8333)); + BOOST_CHECK(TestSplitHost("::8333", "::8333", -1)); + BOOST_CHECK(TestSplitHost(":8333", "", 8333)); + BOOST_CHECK(TestSplitHost("[]:8333", "", 8333)); + BOOST_CHECK(TestSplitHost("", "", -1)); +} + +bool static TestParse(string src, string canon) +{ + CService addr; + if (!LookupNumeric(src.c_str(), addr, 65535)) + return canon == ""; + return canon == addr.ToString(); +} + +BOOST_AUTO_TEST_CASE(netbase_lookupnumeric) +{ + BOOST_CHECK(TestParse("127.0.0.1", "127.0.0.1:65535")); + BOOST_CHECK(TestParse("127.0.0.1:8333", "127.0.0.1:8333")); + BOOST_CHECK(TestParse("::ffff:127.0.0.1", "127.0.0.1:65535")); + BOOST_CHECK(TestParse("::", "[::]:65535")); + BOOST_CHECK(TestParse("[::]:8333", "[::]:8333")); + BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535")); + BOOST_CHECK(TestParse(":::", "")); +} + +BOOST_AUTO_TEST_CASE(onioncat_test) +{ + // values from http://www.cypherpunk.at/onioncat/wiki/OnionCat + CNetAddr addr1("5wyqrzbvrdsumnok.onion"); + CNetAddr addr2("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca"); + BOOST_CHECK(addr1 == addr2); + BOOST_CHECK(addr1.IsTor()); + BOOST_CHECK(addr1.ToStringIP() == "5wyqrzbvrdsumnok.onion"); + BOOST_CHECK(addr1.IsRoutable()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp new file mode 100644 index 0000000..505ec8f --- /dev/null +++ b/src/test/rpc_tests.cpp @@ -0,0 +1,62 @@ +#include +#include + +#include "base58.h" +#include "util.h" +#include "bitcoinrpc.h" + +using namespace std; +using namespace json_spirit; + +BOOST_AUTO_TEST_SUITE(rpc_tests) + +static Array +createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) +{ + Array result; + result.push_back(nRequired); + Array addresses; + if (address1) addresses.push_back(address1); + if (address2) addresses.push_back(address2); + result.push_back(addresses); + return result; +} + +BOOST_AUTO_TEST_CASE(rpc_addmultisig) +{ + rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor; + + // old, 65-byte-long: + const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8"; + // new, compressed: + const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; + + Value v; + CBitcoinAddress address; + BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); + address.SetString(v.get_str()); + BOOST_CHECK(address.IsValid() && address.IsScript()); + + BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false)); + address.SetString(v.get_str()); + BOOST_CHECK(address.IsValid() && address.IsScript()); + + BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false)); + address.SetString(v.get_str()); + BOOST_CHECK(address.IsValid() && address.IsScript()); + + BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error); + BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error); + BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error); + + BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error); + BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error); + + string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing + BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error); + + string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing + BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp new file mode 100644 index 0000000..eabfcd0 --- /dev/null +++ b/src/test/script_P2SH_tests.cpp @@ -0,0 +1,330 @@ +#include +#include +#include +#include +#include +#include + +#include "../main.h" +#include "../script.h" +#include "../wallet.h" + +using namespace std; + +// Test routines internal to script.cpp: +extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType); + +// Helpers: +static std::vector +Serialize(const CScript& s) +{ + std::vector sSerialized(s); + return sSerialized; +} + +static bool +Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict) +{ + // Create dummy to/from transactions: + CTransaction txFrom; + txFrom.vout.resize(1); + txFrom.vout[0].scriptPubKey = scriptPubKey; + + CTransaction txTo; + txTo.vin.resize(1); + txTo.vout.resize(1); + txTo.vin[0].prevout.n = 0; + txTo.vin[0].prevout.hash = txFrom.GetHash(); + txTo.vin[0].scriptSig = scriptSig; + txTo.vout[0].nValue = 1; + + return VerifyScript(scriptSig, scriptPubKey, txTo, 0, fStrict, 0); +} + + +BOOST_AUTO_TEST_SUITE(script_P2SH_tests) + +BOOST_AUTO_TEST_CASE(sign) +{ + // Pay-to-script-hash looks like this: + // scriptSig: + // scriptPubKey: HASH160 EQUAL + + // Test SignSignature() (and therefore the version of Solver() that signs transactions) + CBasicKeyStore keystore; + CKey key[4]; + for (int i = 0; i < 4; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + } + + // 8 Scripts: checking all combinations of + // different keys, straight/P2SH, pubkey/pubkeyhash + CScript standardScripts[4]; + standardScripts[0] << key[0].GetPubKey() << OP_CHECKSIG; + standardScripts[1].SetDestination(key[1].GetPubKey().GetID()); + standardScripts[2] << key[1].GetPubKey() << OP_CHECKSIG; + standardScripts[3].SetDestination(key[2].GetPubKey().GetID()); + CScript evalScripts[4]; + for (int i = 0; i < 4; i++) + { + keystore.AddCScript(standardScripts[i]); + evalScripts[i].SetDestination(standardScripts[i].GetID()); + } + + CTransaction txFrom; // Funding transaction: + txFrom.vout.resize(8); + for (int i = 0; i < 4; i++) + { + txFrom.vout[i].scriptPubKey = evalScripts[i]; + txFrom.vout[i+4].scriptPubKey = standardScripts[i]; + } + BOOST_CHECK(txFrom.IsStandard()); + + CTransaction txTo[8]; // Spending transactions + for (int i = 0; i < 8; i++) + { + txTo[i].vin.resize(1); + txTo[i].vout.resize(1); + txTo[i].vin[0].prevout.n = i; + txTo[i].vin[0].prevout.hash = txFrom.GetHash(); + txTo[i].vout[0].nValue = 1; + BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); + } + for (int i = 0; i < 8; i++) + { + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + } + // All of the above should be OK, and the txTos have valid signatures + // Check to make sure signature verification fails if we use the wrong ScriptSig: + for (int i = 0; i < 8; i++) + for (int j = 0; j < 8; j++) + { + CScript sigSave = txTo[i].vin[0].scriptSig; + txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; + bool sigOK = VerifySignature(txFrom, txTo[i], 0, true, 0); + if (i == j) + BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); + else + BOOST_CHECK_MESSAGE(!sigOK, strprintf("VerifySignature %d %d", i, j)); + txTo[i].vin[0].scriptSig = sigSave; + } +} + +BOOST_AUTO_TEST_CASE(norecurse) +{ + // Make sure only the outer pay-to-script-hash does the + // extra-validation thing: + CScript invalidAsScript; + invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE; + + CScript p2sh; + p2sh.SetDestination(invalidAsScript.GetID()); + + CScript scriptSig; + scriptSig << Serialize(invalidAsScript); + + // Should not verify, because it will try to execute OP_INVALIDOPCODE + BOOST_CHECK(!Verify(scriptSig, p2sh, true)); + + // Try to recur, and verification should succeed because + // the inner HASH160 <> EQUAL should only check the hash: + CScript p2sh2; + p2sh2.SetDestination(p2sh.GetID()); + CScript scriptSig2; + scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh); + + BOOST_CHECK(Verify(scriptSig2, p2sh2, true)); +} + +BOOST_AUTO_TEST_CASE(set) +{ + // Test the CScript::Set* methods + CBasicKeyStore keystore; + CKey key[4]; + std::vector keys; + for (int i = 0; i < 4; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + keys.push_back(key[i]); + } + + CScript inner[4]; + inner[0].SetDestination(key[0].GetPubKey().GetID()); + inner[1].SetMultisig(2, std::vector(keys.begin(), keys.begin()+2)); + inner[2].SetMultisig(1, std::vector(keys.begin(), keys.begin()+2)); + inner[3].SetMultisig(2, std::vector(keys.begin(), keys.begin()+3)); + + CScript outer[4]; + for (int i = 0; i < 4; i++) + { + outer[i].SetDestination(inner[i].GetID()); + keystore.AddCScript(inner[i]); + } + + CTransaction txFrom; // Funding transaction: + txFrom.vout.resize(4); + for (int i = 0; i < 4; i++) + { + txFrom.vout[i].scriptPubKey = outer[i]; + } + BOOST_CHECK(txFrom.IsStandard()); + + CTransaction txTo[4]; // Spending transactions + for (int i = 0; i < 4; i++) + { + txTo[i].vin.resize(1); + txTo[i].vout.resize(1); + txTo[i].vin[0].prevout.n = i; + txTo[i].vin[0].prevout.hash = txFrom.GetHash(); + txTo[i].vout[0].nValue = 1; + txTo[i].vout[0].scriptPubKey = inner[i]; + BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); + } + for (int i = 0; i < 4; i++) + { + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + BOOST_CHECK_MESSAGE(txTo[i].IsStandard(), strprintf("txTo[%d].IsStandard", i)); + } +} + +BOOST_AUTO_TEST_CASE(is) +{ + // Test CScript::IsPayToScriptHash() + uint160 dummy; + CScript p2sh; + p2sh << OP_HASH160 << dummy << OP_EQUAL; + BOOST_CHECK(p2sh.IsPayToScriptHash()); + + // Not considered pay-to-script-hash if using one of the OP_PUSHDATA opcodes: + static const unsigned char direct[] = { OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL }; + BOOST_CHECK(CScript(direct, direct+sizeof(direct)).IsPayToScriptHash()); + static const unsigned char pushdata1[] = { OP_HASH160, OP_PUSHDATA1, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL }; + BOOST_CHECK(!CScript(pushdata1, pushdata1+sizeof(pushdata1)).IsPayToScriptHash()); + static const unsigned char pushdata2[] = { OP_HASH160, OP_PUSHDATA2, 20,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL }; + BOOST_CHECK(!CScript(pushdata2, pushdata2+sizeof(pushdata2)).IsPayToScriptHash()); + static const unsigned char pushdata4[] = { OP_HASH160, OP_PUSHDATA4, 20,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL }; + BOOST_CHECK(!CScript(pushdata4, pushdata4+sizeof(pushdata4)).IsPayToScriptHash()); + + CScript not_p2sh; + BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); + + not_p2sh.clear(); not_p2sh << OP_HASH160 << dummy << dummy << OP_EQUAL; + BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); + + not_p2sh.clear(); not_p2sh << OP_NOP << dummy << OP_EQUAL; + BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); + + not_p2sh.clear(); not_p2sh << OP_HASH160 << dummy << OP_CHECKSIG; + BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); +} + +BOOST_AUTO_TEST_CASE(switchover) +{ + // Test switch over code + CScript notValid; + notValid << OP_11 << OP_12 << OP_EQUALVERIFY; + CScript scriptSig; + scriptSig << Serialize(notValid); + + CScript fund; + fund.SetDestination(notValid.GetID()); + + + // Validation should succeed under old rules (hash is correct): + BOOST_CHECK(Verify(scriptSig, fund, false)); + // Fail under new: + BOOST_CHECK(!Verify(scriptSig, fund, true)); +} + +BOOST_AUTO_TEST_CASE(AreInputsStandard) +{ + std::map > mapInputs; + CBasicKeyStore keystore; + CKey key[3]; + vector keys; + for (int i = 0; i < 3; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + keys.push_back(key[i]); + } + + CTransaction txFrom; + txFrom.vout.resize(6); + + // First three are standard: + CScript pay1; pay1.SetDestination(key[0].GetPubKey().GetID()); + keystore.AddCScript(pay1); + CScript payScriptHash1; payScriptHash1.SetDestination(pay1.GetID()); + CScript pay1of3; pay1of3.SetMultisig(1, keys); + + txFrom.vout[0].scriptPubKey = payScriptHash1; + txFrom.vout[1].scriptPubKey = pay1; + txFrom.vout[2].scriptPubKey = pay1of3; + + // Last three non-standard: + CScript empty; + keystore.AddCScript(empty); + txFrom.vout[3].scriptPubKey = empty; + // Can't use SetPayToScriptHash, it checks for the empty Script. So: + txFrom.vout[4].scriptPubKey << OP_HASH160 << Hash160(empty) << OP_EQUAL; + CScript oneOfEleven; + oneOfEleven << OP_1; + for (int i = 0; i < 11; i++) + oneOfEleven << key[0].GetPubKey(); + oneOfEleven << OP_11 << OP_CHECKMULTISIG; + txFrom.vout[5].scriptPubKey.SetDestination(oneOfEleven.GetID()); + + mapInputs[txFrom.GetHash()] = make_pair(CTxIndex(), txFrom); + + CTransaction txTo; + txTo.vout.resize(1); + txTo.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID()); + + txTo.vin.resize(3); + txTo.vin[0].prevout.n = 0; + txTo.vin[0].prevout.hash = txFrom.GetHash(); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0)); + txTo.vin[1].prevout.n = 1; + txTo.vin[1].prevout.hash = txFrom.GetHash(); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1)); + txTo.vin[2].prevout.n = 2; + txTo.vin[2].prevout.hash = txFrom.GetHash(); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2)); + + BOOST_CHECK(txTo.AreInputsStandard(mapInputs)); + BOOST_CHECK_EQUAL(txTo.GetP2SHSigOpCount(mapInputs), 1); + + // Make sure adding crap to the scriptSigs makes them non-standard: + for (int i = 0; i < 3; i++) + { + CScript t = txTo.vin[i].scriptSig; + txTo.vin[i].scriptSig = (CScript() << 11) + t; + BOOST_CHECK(!txTo.AreInputsStandard(mapInputs)); + txTo.vin[i].scriptSig = t; + } + + CTransaction txToNonStd; + txToNonStd.vout.resize(1); + txToNonStd.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID()); + txToNonStd.vin.resize(2); + txToNonStd.vin[0].prevout.n = 4; + txToNonStd.vin[0].prevout.hash = txFrom.GetHash(); + txToNonStd.vin[0].scriptSig << Serialize(empty); + txToNonStd.vin[1].prevout.n = 5; + txToNonStd.vin[1].prevout.hash = txFrom.GetHash(); + txToNonStd.vin[1].scriptSig << OP_0 << Serialize(oneOfEleven); + + BOOST_CHECK(!txToNonStd.AreInputsStandard(mapInputs)); + BOOST_CHECK_EQUAL(txToNonStd.GetP2SHSigOpCount(mapInputs), 11); + + txToNonStd.vin[0].scriptSig.clear(); + BOOST_CHECK(!txToNonStd.AreInputsStandard(mapInputs)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp new file mode 100644 index 0000000..61d9a64 --- /dev/null +++ b/src/test/script_tests.cpp @@ -0,0 +1,445 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" + +#include "main.h" +#include "wallet.h" + +using namespace std; +using namespace json_spirit; +using namespace boost::algorithm; + +extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType); + +CScript +ParseScript(string s) +{ + CScript result; + + static map mapOpNames; + + if (mapOpNames.size() == 0) + { + for (int op = OP_NOP; op <= OP_NOP10; op++) + { + 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 words; + split(words, s, is_any_of(" \t\n"), token_compress_on); + + BOOST_FOREACH(string w, words) + { + if (all(w, is_digit()) || + (starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit()))) + { + // Number + int64 n = atoi64(w); + result << n; + } + else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end()))) + { + // Raw hex data, inserted NOT pushed onto stack: + std::vector 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 value(w.begin()+1, w.end()-1); + result << value; + } + else if (mapOpNames.count(w)) + { + // opcode, e.g. OP_ADD or OP_1: + result << mapOpNames[w]; + } + else + { + BOOST_ERROR("Parse error: " << s); + return CScript(); + } + } + + return result; +} + +Array +read_json(const std::string& filename) +{ + namespace fs = boost::filesystem; + fs::path testFile = fs::current_path() / "test" / "data" / filename; + +#ifdef TEST_DATA_DIR + if (!fs::exists(testFile)) + { + testFile = fs::path(BOOST_PP_STRINGIZE(TEST_DATA_DIR)) / filename; + } +#endif + + ifstream ifs(testFile.string().c_str(), ifstream::in); + Value v; + if (!read_stream(ifs, v)) + { + if (ifs.fail()) + BOOST_ERROR("Cound not find/open " << filename); + else + BOOST_ERROR("JSON syntax error in " << filename); + return Array(); + } + if (v.type() != array_type) + { + BOOST_ERROR(filename << " does not contain a json array"); + return Array(); + } + + return v.get_array(); +} + +BOOST_AUTO_TEST_SUITE(script_tests) + +BOOST_AUTO_TEST_CASE(script_valid) +{ + // Read tests from test/data/script_valid.json + // Format is an array of arrays + // Inner arrays are [ "scriptSig", "scriptPubKey" ] + // ... where scriptSig and scriptPubKey are stringified + // scripts. + Array tests = read_json("script_valid.json"); + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + string strTest = write_string(tv, false); + if (test.size() < 2) // Allow size > 2; extra stuff ignored (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + string scriptSigString = test[0].get_str(); + CScript scriptSig = ParseScript(scriptSigString); + string scriptPubKeyString = test[1].get_str(); + CScript scriptPubKey = ParseScript(scriptPubKeyString); + + CTransaction tx; + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, tx, 0, true, SIGHASH_NONE), strTest); + } +} + +BOOST_AUTO_TEST_CASE(script_invalid) +{ + // Scripts that should evaluate as invalid + Array tests = read_json("script_invalid.json"); + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + string strTest = write_string(tv, false); + if (test.size() < 2) // Allow size > 2; extra stuff ignored (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + string scriptSigString = test[0].get_str(); + CScript scriptSig = ParseScript(scriptSigString); + string scriptPubKeyString = test[1].get_str(); + CScript scriptPubKey = ParseScript(scriptPubKeyString); + + CTransaction tx; + BOOST_CHECK_MESSAGE(!VerifyScript(scriptSig, scriptPubKey, tx, 0, true, SIGHASH_NONE), strTest); + } +} + +BOOST_AUTO_TEST_CASE(script_PushData) +{ + // Check that PUSHDATA1, PUSHDATA2, and PUSHDATA4 create the same value on + // the stack as the 1-75 opcodes do. + static const unsigned char direct[] = { 1, 0x5a }; + static const unsigned char pushdata1[] = { OP_PUSHDATA1, 1, 0x5a }; + static const unsigned char pushdata2[] = { OP_PUSHDATA2, 1, 0, 0x5a }; + static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a }; + + vector > directStack; + BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), CTransaction(), 0, 0)); + + vector > pushdata1Stack; + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), CTransaction(), 0, 0)); + BOOST_CHECK(pushdata1Stack == directStack); + + vector > pushdata2Stack; + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), CTransaction(), 0, 0)); + BOOST_CHECK(pushdata2Stack == directStack); + + vector > pushdata4Stack; + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), CTransaction(), 0, 0)); + BOOST_CHECK(pushdata4Stack == directStack); +} + +CScript +sign_multisig(CScript scriptPubKey, std::vector keys, CTransaction transaction) +{ + uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL); + + CScript result; + // + // NOTE: CHECKMULTISIG has an unfortunate bug; it requires + // one extra item on the stack, before the signatures. + // Putting OP_0 on the stack is the workaround; + // fixing the bug would mean splitting the blockchain (old + // clients would not accept new CHECKMULTISIG transactions, + // and vice-versa) + // + result << OP_0; + BOOST_FOREACH(CKey key, keys) + { + vector vchSig; + BOOST_CHECK(key.Sign(hash, vchSig)); + vchSig.push_back((unsigned char)SIGHASH_ALL); + result << vchSig; + } + return result; +} +CScript +sign_multisig(CScript scriptPubKey, CKey key, CTransaction transaction) +{ + std::vector keys; + keys.push_back(key); + return sign_multisig(scriptPubKey, keys, transaction); +} + +BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) +{ + CKey key1, key2, key3; + key1.MakeNewKey(true); + key2.MakeNewKey(false); + key3.MakeNewKey(true); + + CScript scriptPubKey12; + scriptPubKey12 << OP_1 << key1.GetPubKey() << key2.GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CTransaction txFrom12; + txFrom12.vout.resize(1); + txFrom12.vout[0].scriptPubKey = scriptPubKey12; + + CTransaction txTo12; + txTo12.vin.resize(1); + txTo12.vout.resize(1); + txTo12.vin[0].prevout.n = 0; + txTo12.vin[0].prevout.hash = txFrom12.GetHash(); + txTo12.vout[0].nValue = 1; + + CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, true, 0)); + txTo12.vout[0].nValue = 2; + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, true, 0)); + + CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, true, 0)); + + CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, true, 0)); +} + +BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) +{ + CKey key1, key2, key3, key4; + key1.MakeNewKey(true); + key2.MakeNewKey(false); + key3.MakeNewKey(true); + key4.MakeNewKey(false); + + CScript scriptPubKey23; + scriptPubKey23 << OP_2 << key1.GetPubKey() << key2.GetPubKey() << key3.GetPubKey() << OP_3 << OP_CHECKMULTISIG; + + CTransaction txFrom23; + txFrom23.vout.resize(1); + txFrom23.vout[0].scriptPubKey = scriptPubKey23; + + CTransaction txTo23; + txTo23.vin.resize(1); + txTo23.vout.resize(1); + txTo23.vin[0].prevout.n = 0; + txTo23.vin[0].prevout.hash = txFrom23.GetHash(); + txTo23.vout[0].nValue = 1; + + std::vector keys; + keys.push_back(key1); keys.push_back(key2); + CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key1); keys.push_back(key3); + CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key2); keys.push_back(key3); + CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key2); keys.push_back(key2); // Can't re-use sig + CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order + CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order + CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys + CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys + CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); // Must have signatures + CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, true, 0)); +} + +BOOST_AUTO_TEST_CASE(script_combineSigs) +{ + // Test the CombineSignatures function + CBasicKeyStore keystore; + vector keys; + for (int i = 0; i < 3; i++) + { + CKey key; + key.MakeNewKey(i%2 == 1); + keys.push_back(key); + keystore.AddKey(key); + } + + CTransaction txFrom; + txFrom.vout.resize(1); + txFrom.vout[0].scriptPubKey.SetDestination(keys[0].GetPubKey().GetID()); + CScript& scriptPubKey = txFrom.vout[0].scriptPubKey; + CTransaction txTo; + txTo.vin.resize(1); + txTo.vout.resize(1); + txTo.vin[0].prevout.n = 0; + txTo.vin[0].prevout.hash = txFrom.GetHash(); + CScript& scriptSig = txTo.vin[0].scriptSig; + txTo.vout[0].nValue = 1; + + CScript empty; + CScript combined = CombineSignatures(scriptPubKey, txTo, 0, empty, empty); + BOOST_CHECK(combined.empty()); + + // Single signature case: + SignSignature(keystore, txFrom, txTo, 0); // changes scriptSig + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); + BOOST_CHECK(combined == scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); + BOOST_CHECK(combined == scriptSig); + CScript scriptSigCopy = scriptSig; + // Signing again will give a different, valid signature: + SignSignature(keystore, txFrom, txTo, 0); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); + BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); + + // P2SH, single-signature case: + CScript pkSingle; pkSingle << keys[0].GetPubKey() << OP_CHECKSIG; + keystore.AddCScript(pkSingle); + scriptPubKey.SetDestination(pkSingle.GetID()); + SignSignature(keystore, txFrom, txTo, 0); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); + BOOST_CHECK(combined == scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); + BOOST_CHECK(combined == scriptSig); + scriptSigCopy = scriptSig; + SignSignature(keystore, txFrom, txTo, 0); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); + BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); + // dummy scriptSigCopy with placeholder, should always choose non-placeholder: + scriptSigCopy = CScript() << OP_0 << static_cast >(pkSingle); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); + BOOST_CHECK(combined == scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy); + BOOST_CHECK(combined == scriptSig); + + // Hardest case: Multisig 2-of-3 + scriptPubKey.SetMultisig(2, keys); + keystore.AddCScript(scriptPubKey); + SignSignature(keystore, txFrom, txTo, 0); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); + BOOST_CHECK(combined == scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); + BOOST_CHECK(combined == scriptSig); + + // A couple of partially-signed versions: + vector sig1; + uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL); + BOOST_CHECK(keys[0].Sign(hash1, sig1)); + sig1.push_back(SIGHASH_ALL); + vector sig2; + uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE); + BOOST_CHECK(keys[1].Sign(hash2, sig2)); + sig2.push_back(SIGHASH_NONE); + vector sig3; + uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE); + BOOST_CHECK(keys[2].Sign(hash3, sig3)); + sig3.push_back(SIGHASH_SINGLE); + + // Not fussy about order (or even existence) of placeholders or signatures: + CScript partial1a = CScript() << OP_0 << sig1 << OP_0; + CScript partial1b = CScript() << OP_0 << OP_0 << sig1; + CScript partial2a = CScript() << OP_0 << sig2; + CScript partial2b = CScript() << sig2 << OP_0; + CScript partial3a = CScript() << sig3; + CScript partial3b = CScript() << OP_0 << OP_0 << sig3; + CScript partial3c = CScript() << OP_0 << sig3 << OP_0; + CScript complete12 = CScript() << OP_0 << sig1 << sig2; + CScript complete13 = CScript() << OP_0 << sig1 << sig3; + CScript complete23 = CScript() << OP_0 << sig2 << sig3; + + combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b); + BOOST_CHECK(combined == partial1a); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a); + BOOST_CHECK(combined == complete12); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial1a); + BOOST_CHECK(combined == complete12); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial1b, partial2b); + BOOST_CHECK(combined == complete12); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial1b); + BOOST_CHECK(combined == complete13); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial3a); + BOOST_CHECK(combined == complete23); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial2b); + BOOST_CHECK(combined == complete23); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial3a); + BOOST_CHECK(combined == partial3c); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp new file mode 100644 index 0000000..59673f9 --- /dev/null +++ b/src/test/sigopcount_tests.cpp @@ -0,0 +1,60 @@ +#include +#include +#include + +#include "script.h" +#include "key.h" + +using namespace std; + +// Helpers: +static std::vector +Serialize(const CScript& s) +{ + std::vector sSerialized(s); + return sSerialized; +} + +BOOST_AUTO_TEST_SUITE(sigopcount_tests) + +BOOST_AUTO_TEST_CASE(GetSigOpCount) +{ + // Test CScript::GetSigOpCount() + CScript s1; + BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0); + BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0); + + uint160 dummy; + s1 << OP_1 << dummy << dummy << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2); + s1 << OP_IF << OP_CHECKSIG << OP_ENDIF; + BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3); + BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21); + + CScript p2sh; + p2sh.SetDestination(s1.GetID()); + CScript scriptSig; + scriptSig << OP_0 << Serialize(s1); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3); + + std::vector keys; + for (int i = 0; i < 3; i++) + { + CKey k; + k.MakeNewKey(true); + keys.push_back(k); + } + CScript s2; + s2.SetMultisig(1, keys); + BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3); + BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20); + + p2sh.SetDestination(s2.GetID()); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0); + CScript scriptSig2; + scriptSig2 << OP_1 << dummy << dummy << Serialize(s2); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp new file mode 100644 index 0000000..bcf0907 --- /dev/null +++ b/src/test/test_bitcoin.cpp @@ -0,0 +1,44 @@ +#define BOOST_TEST_MODULE Bitcoin Test Suite +#include + +#include "db.h" +#include "main.h" +#include "wallet.h" + +CWallet* pwalletMain; +CClientUIInterface uiInterface; + +extern bool fPrintToConsole; +extern void noui_connect(); + +struct TestingSetup { + TestingSetup() { + fPrintToDebugger = true; // don't want to write to debug.log file + noui_connect(); + bitdb.MakeMock(); + LoadBlockIndex(true); + bool fFirstRun; + pwalletMain = new CWallet("wallet.dat"); + pwalletMain->LoadWallet(fFirstRun); + RegisterWallet(pwalletMain); + } + ~TestingSetup() + { + delete pwalletMain; + pwalletMain = NULL; + bitdb.Flush(true); + } +}; + +BOOST_GLOBAL_FIXTURE(TestingSetup); + +void Shutdown(void* parg) +{ + exit(0); +} + +void StartShutdown() +{ + exit(0); +} + diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp new file mode 100644 index 0000000..c230458 --- /dev/null +++ b/src/test/transaction_tests.cpp @@ -0,0 +1,264 @@ +#include +#include +#include +#include "json/json_spirit_writer_template.h" + +#include "main.h" +#include "wallet.h" + +using namespace std; +using namespace json_spirit; + +// In script_tests.cpp +extern Array read_json(const std::string& filename); +extern CScript ParseScript(string s); + +BOOST_AUTO_TEST_SUITE(transaction_tests) + +BOOST_AUTO_TEST_CASE(tx_valid) +{ + // Read tests from test/data/tx_valid.json + // Format is an array of arrays + // Inner arrays are either [ "comment" ] + // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, enforceP2SH + // ... where all scripts are stringified scripts. + Array tests = read_json("tx_valid.json"); + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + string strTest = write_string(tv, false); + if (test[0].type() == array_type) + { + if (test.size() != 3 || test[1].type() != str_type || test[2].type() != bool_type) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + + map mapprevOutScriptPubKeys; + Array inputs = test[0].get_array(); + bool fValid = true; + BOOST_FOREACH(Value& input, inputs) + { + if (input.type() != array_type) + { + fValid = false; + break; + } + Array vinput = input.get_array(); + if (vinput.size() != 3) + { + fValid = false; + break; + } + + mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); + } + if (!fValid) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + + string transaction = test[1].get_str(); + CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + + BOOST_CHECK_MESSAGE(tx.CheckTransaction(), strTest); + + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) + { + BOOST_ERROR("Bad test: " << strTest); + break; + } + + BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], tx, i, test[2].get_bool(), 0), strTest); + } + } + } +} + +BOOST_AUTO_TEST_CASE(tx_invalid) +{ + // Read tests from test/data/tx_invalid.json + // Format is an array of arrays + // Inner arrays are either [ "comment" ] + // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, enforceP2SH + // ... where all scripts are stringified scripts. + Array tests = read_json("tx_invalid.json"); + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + string strTest = write_string(tv, false); + if (test[0].type() == array_type) + { + if (test.size() != 3 || test[1].type() != str_type || test[2].type() != bool_type) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + + map mapprevOutScriptPubKeys; + Array inputs = test[0].get_array(); + bool fValid = true; + BOOST_FOREACH(Value& input, inputs) + { + if (input.type() != array_type) + { + fValid = false; + break; + } + Array vinput = input.get_array(); + if (vinput.size() != 3) + { + fValid = false; + break; + } + + mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); + } + if (!fValid) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + + string transaction = test[1].get_str(); + CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + + fValid = tx.CheckTransaction(); + + for (unsigned int i = 0; i < tx.vin.size() && fValid; i++) + { + if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) + { + BOOST_ERROR("Bad test: " << strTest); + break; + } + + fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], tx, i, test[2].get_bool(), 0); + } + + BOOST_CHECK_MESSAGE(!fValid, strTest); + } + } +} + +BOOST_AUTO_TEST_CASE(basic_transaction_tests) +{ + // Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436) + unsigned char ch[] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00}; + vector vch(ch, ch + sizeof(ch) -1); + CDataStream stream(vch, SER_DISK, CLIENT_VERSION); + CTransaction tx; + stream >> tx; + BOOST_CHECK_MESSAGE(tx.CheckTransaction(), "Simple deserialized transaction should be valid."); + + // Check that duplicate txins fail + tx.vin.push_back(tx.vin[0]); + BOOST_CHECK_MESSAGE(!tx.CheckTransaction(), "Transaction with duplicate txins should be invalid."); +} + +// +// Helper: create two dummy transactions, each with +// two outputs. The first has 11 and 50 CENT outputs +// paid to a TX_PUBKEY, the second 21 and 22 CENT outputs +// paid to a TX_PUBKEYHASH. +// +static std::vector +SetupDummyInputs(CBasicKeyStore& keystoreRet, MapPrevTx& inputsRet) +{ + std::vector dummyTransactions; + dummyTransactions.resize(2); + + // Add some keys to the keystore: + CKey key[4]; + for (int i = 0; i < 4; i++) + { + key[i].MakeNewKey(i % 2); + keystoreRet.AddKey(key[i]); + } + + // Create some dummy input transactions + dummyTransactions[0].vout.resize(2); + dummyTransactions[0].vout[0].nValue = 11*CENT; + dummyTransactions[0].vout[0].scriptPubKey << key[0].GetPubKey() << OP_CHECKSIG; + dummyTransactions[0].vout[1].nValue = 50*CENT; + dummyTransactions[0].vout[1].scriptPubKey << key[1].GetPubKey() << OP_CHECKSIG; + inputsRet[dummyTransactions[0].GetHash()] = make_pair(CTxIndex(), dummyTransactions[0]); + + dummyTransactions[1].vout.resize(2); + dummyTransactions[1].vout[0].nValue = 21*CENT; + dummyTransactions[1].vout[0].scriptPubKey.SetDestination(key[2].GetPubKey().GetID()); + dummyTransactions[1].vout[1].nValue = 22*CENT; + dummyTransactions[1].vout[1].scriptPubKey.SetDestination(key[3].GetPubKey().GetID()); + inputsRet[dummyTransactions[1].GetHash()] = make_pair(CTxIndex(), dummyTransactions[1]); + + return dummyTransactions; +} + +BOOST_AUTO_TEST_CASE(test_Get) +{ + CBasicKeyStore keystore; + MapPrevTx dummyInputs; + std::vector dummyTransactions = SetupDummyInputs(keystore, dummyInputs); + + CTransaction t1; + t1.vin.resize(3); + t1.vin[0].prevout.hash = dummyTransactions[0].GetHash(); + t1.vin[0].prevout.n = 1; + t1.vin[0].scriptSig << std::vector(65, 0); + t1.vin[1].prevout.hash = dummyTransactions[1].GetHash(); + t1.vin[1].prevout.n = 0; + t1.vin[1].scriptSig << std::vector(65, 0) << std::vector(33, 4); + t1.vin[2].prevout.hash = dummyTransactions[1].GetHash(); + t1.vin[2].prevout.n = 1; + t1.vin[2].scriptSig << std::vector(65, 0) << std::vector(33, 4); + t1.vout.resize(2); + t1.vout[0].nValue = 90*CENT; + t1.vout[0].scriptPubKey << OP_1; + + BOOST_CHECK(t1.AreInputsStandard(dummyInputs)); + BOOST_CHECK_EQUAL(t1.GetValueIn(dummyInputs), (50+21+22)*CENT); + + // Adding extra junk to the scriptSig should make it non-standard: + t1.vin[0].scriptSig << OP_11; + BOOST_CHECK(!t1.AreInputsStandard(dummyInputs)); + + // ... as should not having enough: + t1.vin[0].scriptSig = CScript(); + BOOST_CHECK(!t1.AreInputsStandard(dummyInputs)); +} + +BOOST_AUTO_TEST_CASE(test_GetThrow) +{ + CBasicKeyStore keystore; + MapPrevTx dummyInputs; + std::vector dummyTransactions = SetupDummyInputs(keystore, dummyInputs); + + MapPrevTx missingInputs; + + CTransaction t1; + t1.vin.resize(3); + t1.vin[0].prevout.hash = dummyTransactions[0].GetHash(); + t1.vin[0].prevout.n = 0; + t1.vin[1].prevout.hash = dummyTransactions[1].GetHash();; + t1.vin[1].prevout.n = 0; + t1.vin[2].prevout.hash = dummyTransactions[1].GetHash();; + t1.vin[2].prevout.n = 1; + t1.vout.resize(2); + t1.vout[0].nValue = 90*CENT; + t1.vout[0].scriptPubKey << OP_1; + + BOOST_CHECK_THROW(t1.AreInputsStandard(missingInputs), runtime_error); + BOOST_CHECK_THROW(t1.GetValueIn(missingInputs), runtime_error); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/uint160_tests.cpp b/src/test/uint160_tests.cpp new file mode 100644 index 0000000..35cb35b --- /dev/null +++ b/src/test/uint160_tests.cpp @@ -0,0 +1,18 @@ +#include + +#include "uint256.h" + +BOOST_AUTO_TEST_SUITE(uint160_tests) + +BOOST_AUTO_TEST_CASE(uint160_equality) +{ + uint160 num1 = 10; + uint160 num2 = 11; + BOOST_CHECK(num1+1 == num2); + + uint64 num3 = 10; + BOOST_CHECK(num1 == num3); + BOOST_CHECK(num1+num2 == num3+num2); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp new file mode 100644 index 0000000..efdc8a6 --- /dev/null +++ b/src/test/uint256_tests.cpp @@ -0,0 +1,18 @@ +#include + +#include "uint256.h" + +BOOST_AUTO_TEST_SUITE(uint256_tests) + +BOOST_AUTO_TEST_CASE(uint256_equality) +{ + uint256 num1 = 10; + uint256 num2 = 11; + BOOST_CHECK(num1+1 == num2); + + uint64 num3 = 10; + BOOST_CHECK(num1 == num3); + BOOST_CHECK(num1+num2 == num3+num2); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp new file mode 100644 index 0000000..3a4c035 --- /dev/null +++ b/src/test/util_tests.cpp @@ -0,0 +1,264 @@ +#include +#include +#include + +#include "main.h" +#include "wallet.h" +#include "util.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(util_tests) + +BOOST_AUTO_TEST_CASE(util_criticalsection) +{ + CCriticalSection cs; + + do { + LOCK(cs); + break; + + BOOST_ERROR("break was swallowed!"); + } while(0); + + do { + TRY_LOCK(cs, lockTest); + if (lockTest) + break; + + BOOST_ERROR("break was swallowed!"); + } while(0); +} + +BOOST_AUTO_TEST_CASE(util_MedianFilter) +{ + CMedianFilter filter(5, 15); + + BOOST_CHECK_EQUAL(filter.median(), 15); + + filter.input(20); // [15 20] + BOOST_CHECK_EQUAL(filter.median(), 17); + + filter.input(30); // [15 20 30] + BOOST_CHECK_EQUAL(filter.median(), 20); + + filter.input(3); // [3 15 20 30] + BOOST_CHECK_EQUAL(filter.median(), 17); + + filter.input(7); // [3 7 15 20 30] + BOOST_CHECK_EQUAL(filter.median(), 15); + + filter.input(18); // [3 7 18 20 30] + BOOST_CHECK_EQUAL(filter.median(), 18); + + filter.input(0); // [0 3 7 18 30] + BOOST_CHECK_EQUAL(filter.median(), 7); +} + +static const unsigned char ParseHex_expected[65] = { + 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, + 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, + 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, + 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, + 0x5f +}; +BOOST_AUTO_TEST_CASE(util_ParseHex) +{ + std::vector result; + std::vector expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)); + // Basic test vector + result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); + BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); + + // Spaces between bytes must be supported + result = ParseHex("12 34 56 78"); + BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78); + + // Stop parsing at invalid value + result = ParseHex("1234 invalid 1234"); + BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34); +} + +BOOST_AUTO_TEST_CASE(util_HexStr) +{ + BOOST_CHECK_EQUAL( + HexStr(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)), + "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); + + BOOST_CHECK_EQUAL( + HexStr(ParseHex_expected, ParseHex_expected + 5, true), + "04 67 8a fd b0"); + + BOOST_CHECK_EQUAL( + HexStr(ParseHex_expected, ParseHex_expected, true), + ""); + + std::vector ParseHex_vec(ParseHex_expected, ParseHex_expected + 5); + + BOOST_CHECK_EQUAL( + HexStr(ParseHex_vec, true), + "04 67 8a fd b0"); +} + + +BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat) +{ +/*These are platform-dependant and thus removed to avoid useless test failures + BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0), "01/01/70 00:00:00"); + BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0x7FFFFFFF), "01/19/38 03:14:07"); + // Formats used within Bitcoin + BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 1317425777), "09/30/11 23:36:17"); + BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M", 1317425777), "09/30/11 23:36"); +*/ +} + +BOOST_AUTO_TEST_CASE(util_ParseParameters) +{ + const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"}; + + ParseParameters(0, (char**)argv_test); + BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + + ParseParameters(1, (char**)argv_test); + BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + + ParseParameters(5, (char**)argv_test); + // expectation: -ignored is ignored (program name argument), + // -a, -b and -ccc end up in map, -d ignored because it is after + // a non-option argument (non-GNU option parsing) + BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3); + BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc") + && !mapArgs.count("f") && !mapArgs.count("-d")); + BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc") + && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d")); + + BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple"); + BOOST_CHECK(mapMultiArgs["-ccc"].size() == 2); +} + +BOOST_AUTO_TEST_CASE(util_GetArg) +{ + mapArgs.clear(); + mapArgs["strtest1"] = "string..."; + // strtest2 undefined on purpose + mapArgs["inttest1"] = "12345"; + mapArgs["inttest2"] = "81985529216486895"; + // inttest3 undefined on purpose + mapArgs["booltest1"] = ""; + // booltest2 undefined on purpose + mapArgs["booltest3"] = "0"; + mapArgs["booltest4"] = "1"; + + BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string..."); + BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default"); + BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345); + BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL); + BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1); + BOOST_CHECK_EQUAL(GetBoolArg("booltest1"), true); + BOOST_CHECK_EQUAL(GetBoolArg("booltest2"), false); + BOOST_CHECK_EQUAL(GetBoolArg("booltest3"), false); + BOOST_CHECK_EQUAL(GetBoolArg("booltest4"), true); +} + +BOOST_AUTO_TEST_CASE(util_WildcardMatch) +{ + BOOST_CHECK(WildcardMatch("127.0.0.1", "*")); + BOOST_CHECK(WildcardMatch("127.0.0.1", "127.*")); + BOOST_CHECK(WildcardMatch("abcdef", "a?cde?")); + BOOST_CHECK(!WildcardMatch("abcdef", "a?cde??")); + BOOST_CHECK(WildcardMatch("abcdef", "a*f")); + BOOST_CHECK(!WildcardMatch("abcdef", "a*x")); + BOOST_CHECK(WildcardMatch("", "*")); +} + +BOOST_AUTO_TEST_CASE(util_FormatMoney) +{ + BOOST_CHECK_EQUAL(FormatMoney(0, false), "0.00"); + BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789, false), "12345.6789"); + BOOST_CHECK_EQUAL(FormatMoney(COIN, true), "+1.00"); + BOOST_CHECK_EQUAL(FormatMoney(-COIN, false), "-1.00"); + BOOST_CHECK_EQUAL(FormatMoney(-COIN, true), "-1.00"); + + BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000, false), "100000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000, false), "10000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000, false), "1000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*100000, false), "100000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10000, false), "10000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*1000, false), "1000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*100, false), "100.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10, false), "10.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN, false), "1.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10, false), "0.10"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100, false), "0.01"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/1000, false), "0.001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10000, false), "0.0001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100000, false), "0.00001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000, false), "0.000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000, false), "0.0000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000, false), "0.00000001"); +} + +BOOST_AUTO_TEST_CASE(util_ParseMoney) +{ + int64 ret = 0; + BOOST_CHECK(ParseMoney("0.0", ret)); + BOOST_CHECK_EQUAL(ret, 0); + + BOOST_CHECK(ParseMoney("12345.6789", ret)); + BOOST_CHECK_EQUAL(ret, (COIN/10000)*123456789); + + BOOST_CHECK(ParseMoney("100000000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*100000000); + BOOST_CHECK(ParseMoney("10000000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*10000000); + BOOST_CHECK(ParseMoney("1000000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*1000000); + BOOST_CHECK(ParseMoney("100000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*100000); + BOOST_CHECK(ParseMoney("10000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*10000); + BOOST_CHECK(ParseMoney("1000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*1000); + BOOST_CHECK(ParseMoney("100.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*100); + BOOST_CHECK(ParseMoney("10.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*10); + BOOST_CHECK(ParseMoney("1.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN); + BOOST_CHECK(ParseMoney("0.1", ret)); + BOOST_CHECK_EQUAL(ret, COIN/10); + BOOST_CHECK(ParseMoney("0.01", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100); + BOOST_CHECK(ParseMoney("0.001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/1000); + BOOST_CHECK(ParseMoney("0.0001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/10000); + BOOST_CHECK(ParseMoney("0.00001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100000); + BOOST_CHECK(ParseMoney("0.000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/1000000); + BOOST_CHECK(ParseMoney("0.0000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/10000000); + BOOST_CHECK(ParseMoney("0.00000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100000000); + + // Attempted 63 bit overflow should fail + BOOST_CHECK(!ParseMoney("92233720368.54775808", ret)); +} + +BOOST_AUTO_TEST_CASE(util_IsHex) +{ + BOOST_CHECK(IsHex("00")); + BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF")); + BOOST_CHECK(IsHex("ff")); + BOOST_CHECK(IsHex("FF")); + + BOOST_CHECK(!IsHex("")); + BOOST_CHECK(!IsHex("0")); + BOOST_CHECK(!IsHex("a")); + BOOST_CHECK(!IsHex("eleven")); + BOOST_CHECK(!IsHex("00xx00")); + BOOST_CHECK(!IsHex("0x0000")); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp new file mode 100644 index 0000000..b0b3c47 --- /dev/null +++ b/src/test/wallet_tests.cpp @@ -0,0 +1,295 @@ +#include + +#include "main.h" +#include "wallet.h" + +// how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles +#define RUN_TESTS 100 + +// some tests fail 1% of the time due to bad luck. +// we repeat those tests this many times and only complain if all iterations of the test fail +#define RANDOM_REPEATS 5 + +using namespace std; + +typedef set > CoinSet; + +BOOST_AUTO_TEST_SUITE(wallet_tests) + +static CWallet wallet; +static vector vCoins; + +static void add_coin(int64 nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) +{ + static int i; + CTransaction* tx = new CTransaction; + tx->nLockTime = i++; // so all transactions get different hashes + tx->vout.resize(nInput+1); + tx->vout[nInput].nValue = nValue; + CWalletTx* wtx = new CWalletTx(&wallet, *tx); + delete tx; + if (fIsFromMe) + { + // IsFromMe() returns (GetDebit() > 0), and GetDebit() is 0 if vin.empty(), + // so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe() + wtx->vin.resize(1); + wtx->fDebitCached = true; + wtx->nDebitCached = 1; + } + COutput output(wtx, nInput, nAge); + vCoins.push_back(output); +} + +static void empty_wallet(void) +{ + BOOST_FOREACH(COutput output, vCoins) + delete output.tx; + vCoins.clear(); +} + +static bool equal_sets(CoinSet a, CoinSet b) +{ + pair ret = mismatch(a.begin(), a.end(), b.begin()); + return ret.first == a.end() && ret.second == b.end(); +} + +BOOST_AUTO_TEST_CASE(coin_selection_tests) +{ + static CoinSet setCoinsRet, setCoinsRet2; + static int64 nValueRet; + + // test multiple times to allow for differences in the shuffle order + for (int i = 0; i < RUN_TESTS; i++) + { + empty_wallet(); + + // with an empty wallet we can't even pay one cent + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + + add_coin(1*CENT, 4); // add a new 1 cent coin + + // with a new 1 cent coin, we still can't find a mature 1 cent + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + + // but we can find a new 1 cent + BOOST_CHECK( wallet.SelectCoinsMinConf( 1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); + + add_coin(2*CENT); // add a mature 2 cent coin + + // we can't make 3 cents of mature coins + BOOST_CHECK(!wallet.SelectCoinsMinConf( 3 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + + // we can make 3 cents of new coins + BOOST_CHECK( wallet.SelectCoinsMinConf( 3 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); + + add_coin(5*CENT); // add a mature 5 cent coin, + add_coin(10*CENT, 3, true); // a new 10 cent coin sent from one of our own addresses + add_coin(20*CENT); // and a mature 20 cent coin + + // now we have new: 1+10=11 (of which 10 was self-sent), and mature: 2+5+20=27. total = 38 + + // we can't make 38 cents only if we disallow new coins: + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + // we can't even make 37 cents if we don't allow new coins even if they're from us + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 6, 6, vCoins, setCoinsRet, nValueRet)); + // but we can make 37 cents if we accept new coins from ourself + BOOST_CHECK( wallet.SelectCoinsMinConf(37 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 37 * CENT); + // and we can make 38 cents if we accept all new coins + BOOST_CHECK( wallet.SelectCoinsMinConf(38 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 38 * CENT); + + // try making 34 cents from 1,2,5,10,20 - we can't do it exactly + BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_GT(nValueRet, 34 * CENT); // but should get more than 34 cents + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) + + // when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5 + BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 7 * CENT); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); + + // when we try making 8 cents, the smaller coins (1,2,5) are exactly enough. + BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(nValueRet == 8 * CENT); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); + + // when we try making 9 cents, no subset of smaller coins is enough, and we get the next bigger coin (10) + BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 10 * CENT); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + // now clear out the wallet and start again to test choosing between subsets of smaller coins and the next biggest coin + empty_wallet(); + + add_coin( 6*CENT); + add_coin( 7*CENT); + add_coin( 8*CENT); + add_coin(20*CENT); + add_coin(30*CENT); // now we have 6+7+8+20+30 = 71 cents total + + // check that we have 71 and not 72 + BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + + // now try making 16 cents. the best smaller coins can do is 6+7+8 = 21; not as good at the next biggest coin, 20 + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + add_coin( 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total + + // now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, better than the next biggest coin, 20 + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); + + add_coin( 18*CENT); // now we have 5+6+7+8+18+20+30 + + // and now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, the same as the next biggest coin, 18 + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 1 coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); // because in the event of a tie, the biggest coin wins + + // now try making 11 cents. we should get 5+6 + BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 11 * CENT); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); + + // check that the smallest bigger coin is used + add_coin( 1*COIN); + add_coin( 2*COIN); + add_coin( 3*COIN); + add_coin( 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents + BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 BTC in 1 coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + // empty the wallet and start again, now with fractions of a cent, to test sub-cent change avoidance + empty_wallet(); + add_coin(0.1*CENT); + add_coin(0.2*CENT); + add_coin(0.3*CENT); + add_coin(0.4*CENT); + add_coin(0.5*CENT); + + // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 = 1.5 cents + // we'll get sub-cent change whatever happens, so can expect 1.0 exactly + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); + + // but if we add a bigger coin, making it possible to avoid sub-cent change, things change: + add_coin(1111*CENT); + + // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 cents + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + + // if we add more sub-cent coins: + add_coin(0.6*CENT); + add_coin(0.7*CENT); + + // and try again to make 1.0 cents, we can still make 1.0 cents + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + + // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) + // they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change + empty_wallet(); + for (int i = 0; i < 20; i++) + add_coin(50000 * COIN); + + BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount + BOOST_CHECK_EQUAL(setCoinsRet.size(), 10); // in ten coins + + // if there's not enough in the smaller coins to make at least 1 cent change (0.5+0.6+0.7 < 1.0+1.0), + // we need to try finding an exact subset anyway + + // sometimes it will fail, and so we use the next biggest coin: + empty_wallet(); + add_coin(0.5 * CENT); + add_coin(0.6 * CENT); + add_coin(0.7 * CENT); + add_coin(1111 * CENT); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // we get the bigger coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) + empty_wallet(); + add_coin(0.4 * CENT); + add_coin(0.6 * CENT); + add_coin(0.8 * CENT); + add_coin(1111 * CENT); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); // in two coins 0.4+0.6 + + // test avoiding sub-cent change + empty_wallet(); + add_coin(0.0005 * COIN); + add_coin(0.01 * COIN); + add_coin(1 * COIN); + + // trying to make 1.0001 from these three coins + BOOST_CHECK( wallet.SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1.0105 * COIN); // we should get all coins + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); + + // but if we try to make 0.999, we should take the bigger of the two small coins to avoid sub-cent change + BOOST_CHECK( wallet.SelectCoinsMinConf(0.999 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1.01 * COIN); // we should get 1 + 0.01 + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); + + // test randomness + { + empty_wallet(); + for (int i2 = 0; i2 < 100; i2++) + add_coin(COIN); + + // picking 50 from 100 coins doesn't depend on the shuffle, + // but does depend on randomness in the stochastic approximation code + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); + + int fails = 0; + for (int i = 0; i < RANDOM_REPEATS; i++) + { + // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time + // run the test RANDOM_REPEATS times and only complain if all of them fail + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + if (equal_sets(setCoinsRet, setCoinsRet2)) + fails++; + } + BOOST_CHECK_NE(fails, RANDOM_REPEATS); + + // add 75 cents in small change. not enough to make 90 cents, + // then try making 90 cents. there are multiple competing "smallest bigger" coins, + // one of which should be picked at random + add_coin( 5*CENT); add_coin(10*CENT); add_coin(15*CENT); add_coin(20*CENT); add_coin(25*CENT); + + fails = 0; + for (int i = 0; i < RANDOM_REPEATS; i++) + { + // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time + // run the test RANDOM_REPEATS times and only complain if all of them fail + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet2, nValueRet)); + if (equal_sets(setCoinsRet, setCoinsRet2)) + fails++; + } + BOOST_CHECK_NE(fails, RANDOM_REPEATS); + } + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/ui_interface.h b/src/ui_interface.h new file mode 100644 index 0000000..0f7fdef --- /dev/null +++ b/src/ui_interface.h @@ -0,0 +1,105 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2012 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_UI_INTERFACE_H +#define BITCOIN_UI_INTERFACE_H + +#include +#include "util.h" // for int64 +#include +#include + +class CBasicKeyStore; +class CWallet; +class uint256; + +/** General change type (added, updated, removed). */ +enum ChangeType +{ + CT_NEW, + CT_UPDATED, + CT_DELETED +}; + +/** Signals for UI communication. */ +class CClientUIInterface +{ +public: + /** Flags for CClientUIInterface::ThreadSafeMessageBox */ + enum MessageBoxFlags + { + YES = 0x00000002, + OK = 0x00000004, + NO = 0x00000008, + YES_NO = (YES|NO), + CANCEL = 0x00000010, + APPLY = 0x00000020, + CLOSE = 0x00000040, + OK_DEFAULT = 0x00000000, + YES_DEFAULT = 0x00000000, + NO_DEFAULT = 0x00000080, + CANCEL_DEFAULT = 0x80000000, + ICON_EXCLAMATION = 0x00000100, + ICON_HAND = 0x00000200, + ICON_WARNING = ICON_EXCLAMATION, + ICON_ERROR = ICON_HAND, + ICON_QUESTION = 0x00000400, + ICON_INFORMATION = 0x00000800, + ICON_STOP = ICON_HAND, + ICON_ASTERISK = ICON_INFORMATION, + ICON_MASK = (0x00000100|0x00000200|0x00000400|0x00000800), + FORWARD = 0x00001000, + BACKWARD = 0x00002000, + RESET = 0x00004000, + HELP = 0x00008000, + MORE = 0x00010000, + SETUP = 0x00020000, + // Force blocking, modal message box dialog (not just OS notification) + MODAL = 0x00040000 + }; + + /** Show message box. */ + boost::signals2::signal ThreadSafeMessageBox; + + /** Ask the user whether they want to pay a fee or not. */ + boost::signals2::signal > ThreadSafeAskFee; + + /** Handle a URL passed at the command line. */ + boost::signals2::signal ThreadSafeHandleURI; + + /** Progress message during initialization. */ + boost::signals2::signal InitMessage; + + /** Initiate client shutdown. */ + boost::signals2::signal QueueShutdown; + + /** Translate a message to the native language of the user. */ + boost::signals2::signal Translate; + + /** Block chain changed. */ + boost::signals2::signal NotifyBlocksChanged; + + /** Number of network connections changed. */ + boost::signals2::signal NotifyNumConnectionsChanged; + + /** + * New, updated or cancelled alert. + * @note called with lock cs_mapAlerts held. + */ + boost::signals2::signal NotifyAlertChanged; +}; + +extern CClientUIInterface uiInterface; + +/** + * Translation function: Call Translate signal on UI interface, which returns a boost::optional result. + * If no translation slot is registered, nothing is returned, and simply return the input. + */ +inline std::string _(const char* psz) +{ + boost::optional rv = uiInterface.Translate(psz); + return rv ? (*rv) : psz; +} + +#endif diff --git a/src/uint256.h b/src/uint256.h new file mode 100644 index 0000000..268500e --- /dev/null +++ b/src/uint256.h @@ -0,0 +1,883 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_UINT256_H +#define BITCOIN_UINT256_H + +#include +#include +#include +#include +#include + +typedef long long int64; +typedef unsigned long long uint64; + + +inline int Testuint256AdHoc(std::vector vArg); + + + +/** Base class without constructors for uint256 and uint160. + * This makes the compiler let u use it in a union. + */ +template +class base_uint +{ +protected: + enum { WIDTH=BITS/32 }; + unsigned int pn[WIDTH]; +public: + + bool operator!() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } + + const base_uint operator~() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + return ret; + } + + const base_uint operator-() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + ret++; + return ret; + } + + + base_uint& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + base_uint& operator^=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] ^= b.pn[i]; + return *this; + } + + base_uint& operator&=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] &= b.pn[i]; + return *this; + } + + base_uint& operator|=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] |= b.pn[i]; + return *this; + } + + base_uint& operator^=(uint64 b) + { + pn[0] ^= (unsigned int)b; + pn[1] ^= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator|=(uint64 b) + { + pn[0] |= (unsigned int)b; + pn[1] |= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator<<=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i+k+1 < WIDTH && shift != 0) + pn[i+k+1] |= (a.pn[i] >> (32-shift)); + if (i+k < WIDTH) + pn[i+k] |= (a.pn[i] << shift); + } + return *this; + } + + base_uint& operator>>=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i-k-1 >= 0 && shift != 0) + pn[i-k-1] |= (a.pn[i] << (32-shift)); + if (i-k >= 0) + pn[i-k] |= (a.pn[i] >> shift); + } + return *this; + } + + base_uint& operator+=(const base_uint& b) + { + uint64 carry = 0; + for (int i = 0; i < WIDTH; i++) + { + uint64 n = carry + pn[i] + b.pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; + } + + base_uint& operator-=(const base_uint& b) + { + *this += -b; + return *this; + } + + base_uint& operator+=(uint64 b64) + { + base_uint b; + b = b64; + *this += b; + return *this; + } + + base_uint& operator-=(uint64 b64) + { + base_uint b; + b = b64; + *this += -b; + return *this; + } + + + base_uint& operator++() + { + // prefix operator + int i = 0; + while (++pn[i] == 0 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator++(int) + { + // postfix operator + const base_uint ret = *this; + ++(*this); + return ret; + } + + base_uint& operator--() + { + // prefix operator + int i = 0; + while (--pn[i] == -1 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator--(int) + { + // postfix operator + const base_uint ret = *this; + --(*this); + return ret; + } + + + friend inline bool operator<(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator<=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator>(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator>=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator==(const base_uint& a, const base_uint& b) + { + for (int i = 0; i < base_uint::WIDTH; i++) + if (a.pn[i] != b.pn[i]) + return false; + return true; + } + + friend inline bool operator==(const base_uint& a, uint64 b) + { + if (a.pn[0] != (unsigned int)b) + return false; + if (a.pn[1] != (unsigned int)(b >> 32)) + return false; + for (int i = 2; i < base_uint::WIDTH; i++) + if (a.pn[i] != 0) + return false; + return true; + } + + friend inline bool operator!=(const base_uint& a, const base_uint& b) + { + return (!(a == b)); + } + + friend inline bool operator!=(const base_uint& a, uint64 b) + { + return (!(a == b)); + } + + + + std::string GetHex() const + { + char psz[sizeof(pn)*2 + 1]; + for (unsigned int i = 0; i < sizeof(pn); i++) + sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); + return std::string(psz, psz + sizeof(pn)*2); + } + + void SetHex(const char* psz) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + + // skip leading spaces + while (isspace(*psz)) + psz++; + + // skip 0x + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + + // hex string to uint + static const unsigned char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + const char* pbegin = psz; + while (phexdigit[(unsigned char)*psz] || *psz == '0') + psz++; + psz--; + unsigned char* p1 = (unsigned char*)pn; + unsigned char* pend = p1 + WIDTH * 4; + while (psz >= pbegin && p1 < pend) + { + *p1 = phexdigit[(unsigned char)*psz--]; + if (psz >= pbegin) + { + *p1 |= (phexdigit[(unsigned char)*psz--] << 4); + p1++; + } + } + } + + void SetHex(const std::string& str) + { + SetHex(str.c_str()); + } + + std::string ToString() const + { + return (GetHex()); + } + + unsigned char* begin() + { + return (unsigned char*)&pn[0]; + } + + unsigned char* end() + { + return (unsigned char*)&pn[WIDTH]; + } + + unsigned int size() + { + return sizeof(pn); + } + + uint64 Get64(int n=0) const + { + return pn[2*n] | (uint64)pn[2*n+1] << 32; + } + +// unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const + unsigned int GetSerializeSize(int nType, int nVersion) const + { + return sizeof(pn); + } + + template +// void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const + void Serialize(Stream& s, int nType, int nVersion) const + { + s.write((char*)pn, sizeof(pn)); + } + + template +// void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) + void Unserialize(Stream& s, int nType, int nVersion) + { + s.read((char*)pn, sizeof(pn)); + } + + + friend class uint160; + friend class uint256; + friend class uint512; + friend inline int Testuint256AdHoc(std::vector vArg); +}; + +typedef base_uint<160> base_uint160; +typedef base_uint<256> base_uint256; +typedef base_uint<512> base_uint512; + + +// +// uint160 and uint256 could be implemented as templates, but to keep +// compile errors and debugging cleaner, they're copy and pasted. +// + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint160 +// + +/** 160-bit unsigned integer */ +class uint160 : public base_uint160 +{ +public: + typedef base_uint160 basetype; + + uint160() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint160(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint160& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint160(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint160& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint160(const std::string& str) + { + SetHex(str); + } + + explicit uint160(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; } +inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; } +inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; } +inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; } + +inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; } +inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; } +inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; } +inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; } +inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; } + +inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint256 +// + +/** 256-bit unsigned integer */ +class uint256 : public base_uint256 +{ +public: + typedef base_uint256 basetype; + + uint256() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint256(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint256& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint256(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint256& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint256(const std::string& str) + { + SetHex(str); + } + + explicit uint256(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint256& a, uint64 b) { return (base_uint256)a == b; } +inline bool operator!=(const uint256& a, uint64 b) { return (base_uint256)a != b; } +inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; } +inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; } + +inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; } +inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; } +inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; } +inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; } +inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; } + +inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint512 +// + +/** 512-bit unsigned integer */ +class uint512 : public base_uint512 +{ +public: + typedef base_uint512 basetype; + + uint512() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint512(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint512& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint512(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint512& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint512(const std::string& str) + { + SetHex(str); + } + + explicit uint512(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } + + uint256 trim256() const + { + uint256 ret; + for (unsigned int i = 0; i < uint256::WIDTH; i++){ + ret.pn[i] = pn[i]; + } + return ret; + } +}; + +inline bool operator==(const uint512& a, uint64 b) { return (base_uint512)a == b; } +inline bool operator!=(const uint512& a, uint64 b) { return (base_uint512)a != b; } +inline const uint512 operator<<(const base_uint512& a, unsigned int shift) { return uint512(a) <<= shift; } +inline const uint512 operator>>(const base_uint512& a, unsigned int shift) { return uint512(a) >>= shift; } +inline const uint512 operator<<(const uint512& a, unsigned int shift) { return uint512(a) <<= shift; } +inline const uint512 operator>>(const uint512& a, unsigned int shift) { return uint512(a) >>= shift; } + +inline const uint512 operator^(const base_uint512& a, const base_uint512& b) { return uint512(a) ^= b; } +inline const uint512 operator&(const base_uint512& a, const base_uint512& b) { return uint512(a) &= b; } +inline const uint512 operator|(const base_uint512& a, const base_uint512& b) { return uint512(a) |= b; } +inline const uint512 operator+(const base_uint512& a, const base_uint512& b) { return uint512(a) += b; } +inline const uint512 operator-(const base_uint512& a, const base_uint512& b) { return uint512(a) -= b; } + +inline bool operator<(const base_uint512& a, const uint512& b) { return (base_uint512)a < (base_uint512)b; } +inline bool operator<=(const base_uint512& a, const uint512& b) { return (base_uint512)a <= (base_uint512)b; } +inline bool operator>(const base_uint512& a, const uint512& b) { return (base_uint512)a > (base_uint512)b; } +inline bool operator>=(const base_uint512& a, const uint512& b) { return (base_uint512)a >= (base_uint512)b; } +inline bool operator==(const base_uint512& a, const uint512& b) { return (base_uint512)a == (base_uint512)b; } +inline bool operator!=(const base_uint512& a, const uint512& b) { return (base_uint512)a != (base_uint512)b; } +inline const uint512 operator^(const base_uint512& a, const uint512& b) { return (base_uint512)a ^ (base_uint512)b; } +inline const uint512 operator&(const base_uint512& a, const uint512& b) { return (base_uint512)a & (base_uint512)b; } +inline const uint512 operator|(const base_uint512& a, const uint512& b) { return (base_uint512)a | (base_uint512)b; } +inline const uint512 operator+(const base_uint512& a, const uint512& b) { return (base_uint512)a + (base_uint512)b; } +inline const uint512 operator-(const base_uint512& a, const uint512& b) { return (base_uint512)a - (base_uint512)b; } + +inline bool operator<(const uint512& a, const base_uint512& b) { return (base_uint512)a < (base_uint512)b; } +inline bool operator<=(const uint512& a, const base_uint512& b) { return (base_uint512)a <= (base_uint512)b; } +inline bool operator>(const uint512& a, const base_uint512& b) { return (base_uint512)a > (base_uint512)b; } +inline bool operator>=(const uint512& a, const base_uint512& b) { return (base_uint512)a >= (base_uint512)b; } +inline bool operator==(const uint512& a, const base_uint512& b) { return (base_uint512)a == (base_uint512)b; } +inline bool operator!=(const uint512& a, const base_uint512& b) { return (base_uint512)a != (base_uint512)b; } +inline const uint512 operator^(const uint512& a, const base_uint512& b) { return (base_uint512)a ^ (base_uint512)b; } +inline const uint512 operator&(const uint512& a, const base_uint512& b) { return (base_uint512)a & (base_uint512)b; } +inline const uint512 operator|(const uint512& a, const base_uint512& b) { return (base_uint512)a | (base_uint512)b; } +inline const uint512 operator+(const uint512& a, const base_uint512& b) { return (base_uint512)a + (base_uint512)b; } +inline const uint512 operator-(const uint512& a, const base_uint512& b) { return (base_uint512)a - (base_uint512)b; } + +inline bool operator<(const uint512& a, const uint512& b) { return (base_uint512)a < (base_uint512)b; } +inline bool operator<=(const uint512& a, const uint512& b) { return (base_uint512)a <= (base_uint512)b; } +inline bool operator>(const uint512& a, const uint512& b) { return (base_uint512)a > (base_uint512)b; } +inline bool operator>=(const uint512& a, const uint512& b) { return (base_uint512)a >= (base_uint512)b; } +inline bool operator==(const uint512& a, const uint512& b) { return (base_uint512)a == (base_uint512)b; } +inline bool operator!=(const uint512& a, const uint512& b) { return (base_uint512)a != (base_uint512)b; } +inline const uint512 operator^(const uint512& a, const uint512& b) { return (base_uint512)a ^ (base_uint512)b; } +inline const uint512 operator&(const uint512& a, const uint512& b) { return (base_uint512)a & (base_uint512)b; } +inline const uint512 operator|(const uint512& a, const uint512& b) { return (base_uint512)a | (base_uint512)b; } +inline const uint512 operator+(const uint512& a, const uint512& b) { return (base_uint512)a + (base_uint512)b; } +inline const uint512 operator-(const uint512& a, const uint512& b) { return (base_uint512)a - (base_uint512)b; } + + + + + + +#ifdef TEST_UINT256 + +inline int Testuint256AdHoc(std::vector vArg) +{ + uint256 g(0); + + + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + + + + uint256 a(7); + printf("a=7\n"); + printf("%s\n", a.ToString().c_str()); + + uint256 b; + printf("b undefined\n"); + printf("%s\n", b.ToString().c_str()); + int c = 3; + + a = c; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + uint256 k(c); + + a = 5; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + b = 1; + b <<= 52; + + a |= b; + + a ^= 0x500; + + printf("a %s\n", a.ToString().c_str()); + + a = a | b | (uint256)0x1000; + + + printf("a %s\n", a.ToString().c_str()); + printf("b %s\n", b.ToString().c_str()); + + a = 0xfffffffe; + a.pn[4] = 9; + + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + uint256 d = a--; + printf("%s\n", d.ToString().c_str()); + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + + d = a; + + printf("%s\n", d.ToString().c_str()); + for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n"); + + uint256 neg = d; + neg = ~neg; + printf("%s\n", neg.ToString().c_str()); + + + uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + printf("\n"); + printf("%s\n", e.ToString().c_str()); + + + printf("\n"); + uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + uint256 x2; + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1 << i; + printf("%s\n", x2.ToString().c_str()); + } + + printf("\n"); + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1; + x2 >>= i; + printf("%s\n", x2.ToString().c_str()); + } + + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) >> i); + printf("%s\n", k.ToString().c_str()); + } + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) << i); + printf("%s\n", k.ToString().c_str()); + } + + return (0); +} + +#endif + +#endif diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..c271c64 --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,1397 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "util.h" +#include "sync.h" +#include "strlcpy.h" +#include "version.h" +#include "ui_interface.h" +#include + +// Work around clang compilation problem in Boost 1.46: +// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup +// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options +// http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION +namespace boost { + namespace program_options { + std::string to_internal(const std::string&); + } +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4804) +#pragma warning(disable:4805) +#pragma warning(disable:4717) +#endif +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include /* for _commit */ +#include "shlobj.h" +#elif defined(__linux__) +# include +#endif + +#ifndef WIN32 +#include +#endif + + +using namespace std; + +map mapArgs; +map > mapMultiArgs; +bool fStaking = true; +bool fDebug = false; +bool fDebugNet = false; +bool fPrintToConsole = false; +bool fPrintToDebugger = false; +bool fRequestShutdown = false; +bool fShutdown = false; +bool fDaemon = false; +bool fServer = false; +bool fCommandLine = false; +string strMiscWarning; +bool fTestNet = false; +bool fNoListen = false; +bool fLogTimestamps = false; +CMedianFilter vTimeOffsets(200,0); +bool fReopenDebugLog = false; + +// Init OpenSSL library multithreading support +static CCriticalSection** ppmutexOpenSSL; +void locking_callback(int mode, int i, const char* file, int line) +{ + if (mode & CRYPTO_LOCK) { + ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]); + } else { + LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]); + } +} + +LockedPageManager LockedPageManager::instance; + +// Init +class CInit +{ +public: + CInit() + { + // Init OpenSSL library multithreading support + ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*)); + for (int i = 0; i < CRYPTO_num_locks(); i++) + ppmutexOpenSSL[i] = new CCriticalSection(); + CRYPTO_set_locking_callback(locking_callback); + +#ifdef WIN32 + // Seed random number generator with screen scrape and other hardware sources + RAND_screen(); +#endif + + // Seed random number generator with performance counter + RandAddSeed(); + } + ~CInit() + { + // Shutdown OpenSSL library multithreading support + CRYPTO_set_locking_callback(NULL); + for (int i = 0; i < CRYPTO_num_locks(); i++) + delete ppmutexOpenSSL[i]; + OPENSSL_free(ppmutexOpenSSL); + } +} +instance_of_cinit; + + + + + + + + +void RandAddSeed() +{ + // Seed with CPU performance counter + int64 nCounter = GetPerformanceCounter(); + RAND_add(&nCounter, sizeof(nCounter), 1.5); + memset(&nCounter, 0, sizeof(nCounter)); +} + +void RandAddSeedPerfmon() +{ + RandAddSeed(); + + // This can take up to 2 seconds, so only do it every 10 minutes + static int64 nLastPerfmon; + if (GetTime() < nLastPerfmon + 10 * 60) + return; + nLastPerfmon = GetTime(); + +#ifdef WIN32 + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom + // Seed with the entire set of perfmon data + unsigned char pdata[250000]; + memset(pdata, 0, sizeof(pdata)); + unsigned long nSize = sizeof(pdata); + long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + RegCloseKey(HKEY_PERFORMANCE_DATA); + if (ret == ERROR_SUCCESS) + { + RAND_add(pdata, nSize, nSize/100.0); + memset(pdata, 0, nSize); + printf("RandAddSeed() %lu bytes\n", nSize); + } +#endif +} + +uint64 GetRand(uint64 nMax) +{ + if (nMax == 0) + return 0; + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64 nRange = (std::numeric_limits::max() / nMax) * nMax; + uint64 nRand = 0; + do + RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); + while (nRand >= nRange); + return (nRand % nMax); +} + +int GetRandInt(int nMax) +{ + return GetRand(nMax); +} + +uint256 GetRandHash() +{ + uint256 hash; + RAND_bytes((unsigned char*)&hash, sizeof(hash)); + return hash; +} + + + + + + +static FILE* fileout = NULL; + +inline int OutputDebugStringF(const char* pszFormat, ...) +{ + int ret = 0; + if (fPrintToConsole) + { + // print to console + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + } + else if (!fPrintToDebugger) + { + // print to debug.log + + if (!fileout) + { + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + fileout = fopen(pathDebug.string().c_str(), "a"); + if (fileout) setbuf(fileout, NULL); // unbuffered + } + if (fileout) + { + static bool fStartedNewLine = true; + + // This routine may be called by global destructors during shutdown. + // Since the order of destruction of static/global objects is undefined, + // allocate mutexDebugLog on the heap the first time this routine + // is called to avoid crashes during shutdown. + static boost::mutex* mutexDebugLog = NULL; + if (mutexDebugLog == NULL) mutexDebugLog = new boost::mutex(); + boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); + + // reopen the log file, if requested + if (fReopenDebugLog) { + fReopenDebugLog = false; + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL) + setbuf(fileout, NULL); // unbuffered + } + + // Debug print useful for profiling + if (fLogTimestamps && fStartedNewLine) + fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + if (pszFormat[strlen(pszFormat) - 1] == '\n') + fStartedNewLine = true; + else + fStartedNewLine = false; + + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vfprintf(fileout, pszFormat, arg_ptr); + va_end(arg_ptr); + } + } + +#ifdef WIN32 + if (fPrintToDebugger) + { + static CCriticalSection cs_OutputDebugStringF; + + // accumulate and output a line at a time + { + LOCK(cs_OutputDebugStringF); + static std::string buffer; + + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + buffer += vstrprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + + int line_start = 0, line_end; + while((line_end = buffer.find('\n', line_start)) != -1) + { + OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str()); + line_start = line_end + 1; + } + buffer.erase(0, line_start); + } + } +#endif + return ret; +} + +string vstrprintf(const char *format, va_list ap) +{ + char buffer[50000]; + char* p = buffer; + int limit = sizeof(buffer); + int ret; + while (true) + { + va_list arg_ptr; + va_copy(arg_ptr, ap); +#ifdef WIN32 + ret = _vsnprintf(p, limit, format, arg_ptr); +#else + ret = vsnprintf(p, limit, format, arg_ptr); +#endif + va_end(arg_ptr); + if (ret >= 0 && ret < limit) + break; + if (p != buffer) + delete[] p; + limit *= 2; + p = new char[limit]; + if (p == NULL) + throw std::bad_alloc(); + } + string str(p, p+ret); + if (p != buffer) + delete[] p; + return str; +} + +string real_strprintf(const char *format, int dummy, ...) +{ + va_list arg_ptr; + va_start(arg_ptr, dummy); + string str = vstrprintf(format, arg_ptr); + va_end(arg_ptr); + return str; +} + +string real_strprintf(const std::string &format, int dummy, ...) +{ + va_list arg_ptr; + va_start(arg_ptr, dummy); + string str = vstrprintf(format.c_str(), arg_ptr); + va_end(arg_ptr); + return str; +} + +bool error(const char *format, ...) +{ + va_list arg_ptr; + va_start(arg_ptr, format); + std::string str = vstrprintf(format, arg_ptr); + va_end(arg_ptr); + printf("ERROR: %s\n", str.c_str()); + return false; +} + + +void ParseString(const string& str, char c, vector& v) +{ + if (str.empty()) + return; + string::size_type i1 = 0; + string::size_type i2; + while (true) + { + i2 = str.find(c, i1); + if (i2 == str.npos) + { + v.push_back(str.substr(i1)); + return; + } + v.push_back(str.substr(i1, i2-i1)); + i1 = i2+1; + } +} + + +string FormatMoney(int64 n, bool fPlus) +{ + // Note: not using straight sprintf here because we do NOT want + // localized number formatting. + int64 n_abs = (n > 0 ? n : -n); + int64 quotient = n_abs/COIN; + int64 remainder = n_abs%COIN; + string str = strprintf("%"PRI64d".%06"PRI64d, quotient, remainder); + + // Right-trim excess zeros before the decimal point: + int nTrim = 0; + for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i) + ++nTrim; + if (nTrim) + str.erase(str.size()-nTrim, nTrim); + + if (n < 0) + str.insert((unsigned int)0, 1, '-'); + else if (fPlus && n > 0) + str.insert((unsigned int)0, 1, '+'); + return str; +} + + +bool ParseMoney(const string& str, int64& nRet) +{ + return ParseMoney(str.c_str(), nRet); +} + +bool ParseMoney(const char* pszIn, int64& nRet) +{ + string strWhole; + int64 nUnits = 0; + const char* p = pszIn; + while (isspace(*p)) + p++; + for (; *p; p++) + { + if (*p == '.') + { + p++; + int64 nMult = CENT*10; + while (isdigit(*p) && (nMult > 0)) + { + nUnits += nMult * (*p++ - '0'); + nMult /= 10; + } + break; + } + if (isspace(*p)) + break; + if (!isdigit(*p)) + return false; + strWhole.insert(strWhole.end(), *p); + } + for (; *p; p++) + if (!isspace(*p)) + return false; + if (strWhole.size() > 10) // guard against 63 bit overflow + return false; + if (nUnits < 0 || nUnits > COIN) + return false; + int64 nWhole = atoi64(strWhole); + int64 nValue = nWhole*COIN + nUnits; + + nRet = nValue; + return true; +} + + +static const signed char phexdigit[256] = +{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; + + +static const long hextable[] = +{ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-19 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 30-39 + -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, // 50-59 + -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, + 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 70-79 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, // 90-99 + 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 110-109 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 130-139 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 150-159 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 170-179 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 190-199 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 210-219 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 230-239 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1 +}; + + +long hex2long(const char* hexString) +{ + long ret = 0; + + while (*hexString && ret >= 0) + { + ret = (ret << 4) | hextable[*hexString++]; + } + + return ret; +} + + + +bool IsHex(const string& str) +{ + BOOST_FOREACH(unsigned char c, str) + { + if (phexdigit[c] < 0) + return false; + } + return (str.size() > 0) && (str.size()%2 == 0); +} + +vector ParseHex(const char* psz) +{ + // convert hex dump to vector + vector vch; + while (true) + { + while (isspace(*psz)) + psz++; + signed char c = phexdigit[(unsigned char)*psz++]; + if (c == (signed char)-1) + break; + unsigned char n = (c << 4); + c = phexdigit[(unsigned char)*psz++]; + if (c == (signed char)-1) + break; + n |= c; + vch.push_back(n); + } + return vch; +} + +vector ParseHex(const string& str) +{ + return ParseHex(str.c_str()); +} + +static void InterpretNegativeSetting(string name, map& mapSettingsRet) +{ + // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set + if (name.find("-no") == 0) + { + std::string positive("-"); + positive.append(name.begin()+3, name.end()); + if (mapSettingsRet.count(positive) == 0) + { + bool value = !GetBoolArg(name); + mapSettingsRet[positive] = (value ? "1" : "0"); + } + } +} + +void ParseParameters(int argc, const char* const argv[]) +{ + mapArgs.clear(); + mapMultiArgs.clear(); + for (int i = 1; i < argc; i++) + { + char psz[10000]; + strlcpy(psz, argv[i], sizeof(psz)); + char* pszValue = (char*)""; + if (strchr(psz, '=')) + { + pszValue = strchr(psz, '='); + *pszValue++ = '\0'; + } + #ifdef WIN32 + _strlwr(psz); + if (psz[0] == '/') + psz[0] = '-'; + #endif + if (psz[0] != '-') + break; + + mapArgs[psz] = pszValue; + mapMultiArgs[psz].push_back(pszValue); + } + + // New 0.6 features: + BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs) + { + string name = entry.first; + + // interpret --foo as -foo (as long as both are not set) + if (name.find("--") == 0) + { + std::string singleDash(name.begin()+1, name.end()); + if (mapArgs.count(singleDash) == 0) + mapArgs[singleDash] = entry.second; + name = singleDash; + } + + // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set + InterpretNegativeSetting(name, mapArgs); + } +} + +std::string GetArg(const std::string& strArg, const std::string& strDefault) +{ + if (mapArgs.count(strArg)) + return mapArgs[strArg]; + return strDefault; +} + +int64 GetArg(const std::string& strArg, int64 nDefault) +{ + if (mapArgs.count(strArg)) + return atoi64(mapArgs[strArg]); + return nDefault; +} + +bool GetBoolArg(const std::string& strArg, bool fDefault) +{ + if (mapArgs.count(strArg)) + { + if (mapArgs[strArg].empty()) + return true; + return (atoi(mapArgs[strArg]) != 0); + } + return fDefault; +} + +bool SoftSetArg(const std::string& strArg, const std::string& strValue) +{ + if (mapArgs.count(strArg)) + return false; + mapArgs[strArg] = strValue; + return true; +} + +bool SoftSetBoolArg(const std::string& strArg, bool fValue) +{ + if (fValue) + return SoftSetArg(strArg, std::string("1")); + else + return SoftSetArg(strArg, std::string("0")); +} + + +string EncodeBase64(const unsigned char* pch, size_t len) +{ + static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + string strRet=""; + strRet.reserve((len+2)/3*4); + + int mode=0, left=0; + const unsigned char *pchEnd = pch+len; + + while (pch> 2]; + left = (enc & 3) << 4; + mode = 1; + break; + + case 1: // we have two bits + strRet += pbase64[left | (enc >> 4)]; + left = (enc & 15) << 2; + mode = 2; + break; + + case 2: // we have four bits + strRet += pbase64[left | (enc >> 6)]; + strRet += pbase64[enc & 63]; + mode = 0; + break; + } + } + + if (mode) + { + strRet += pbase64[left]; + strRet += '='; + if (mode == 1) + strRet += '='; + } + + return strRet; +} + +string EncodeBase64(const string& str) +{ + return EncodeBase64((const unsigned char*)str.c_str(), str.size()); +} + +vector DecodeBase64(const char* p, bool* pfInvalid) +{ + static const int decode64_table[256] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, + -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + if (pfInvalid) + *pfInvalid = false; + + vector vchRet; + vchRet.reserve(strlen(p)*3/4); + + int mode = 0; + int left = 0; + + while (1) + { + int dec = decode64_table[(unsigned char)*p]; + if (dec == -1) break; + p++; + switch (mode) + { + case 0: // we have no bits and get 6 + left = dec; + mode = 1; + break; + + case 1: // we have 6 bits and keep 4 + vchRet.push_back((left<<2) | (dec>>4)); + left = dec & 15; + mode = 2; + break; + + case 2: // we have 4 bits and get 6, we keep 2 + vchRet.push_back((left<<4) | (dec>>2)); + left = dec & 3; + mode = 3; + break; + + case 3: // we have 2 bits and get 6 + vchRet.push_back((left<<6) | dec); + mode = 0; + break; + } + } + + if (pfInvalid) + switch (mode) + { + case 0: // 4n base64 characters processed: ok + break; + + case 1: // 4n+1 base64 character processed: impossible + *pfInvalid = true; + break; + + case 2: // 4n+2 base64 characters processed: require '==' + if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1) + *pfInvalid = true; + break; + + case 3: // 4n+3 base64 characters processed: require '=' + if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1) + *pfInvalid = true; + break; + } + + return vchRet; +} + +string DecodeBase64(const string& str) +{ + vector vchRet = DecodeBase64(str.c_str()); + return string((const char*)&vchRet[0], vchRet.size()); +} + +string EncodeBase32(const unsigned char* pch, size_t len) +{ + static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567"; + + string strRet=""; + strRet.reserve((len+4)/5*8); + + int mode=0, left=0; + const unsigned char *pchEnd = pch+len; + + while (pch> 3]; + left = (enc & 7) << 2; + mode = 1; + break; + + case 1: // we have three bits + strRet += pbase32[left | (enc >> 6)]; + strRet += pbase32[(enc >> 1) & 31]; + left = (enc & 1) << 4; + mode = 2; + break; + + case 2: // we have one bit + strRet += pbase32[left | (enc >> 4)]; + left = (enc & 15) << 1; + mode = 3; + break; + + case 3: // we have four bits + strRet += pbase32[left | (enc >> 7)]; + strRet += pbase32[(enc >> 2) & 31]; + left = (enc & 3) << 3; + mode = 4; + break; + + case 4: // we have two bits + strRet += pbase32[left | (enc >> 5)]; + strRet += pbase32[enc & 31]; + mode = 0; + } + } + + static const int nPadding[5] = {0, 6, 4, 3, 1}; + if (mode) + { + strRet += pbase32[left]; + for (int n=0; n DecodeBase32(const char* p, bool* pfInvalid) +{ + static const int decode32_table[256] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + if (pfInvalid) + *pfInvalid = false; + + vector vchRet; + vchRet.reserve((strlen(p))*5/8); + + int mode = 0; + int left = 0; + + while (1) + { + int dec = decode32_table[(unsigned char)*p]; + if (dec == -1) break; + p++; + switch (mode) + { + case 0: // we have no bits and get 5 + left = dec; + mode = 1; + break; + + case 1: // we have 5 bits and keep 2 + vchRet.push_back((left<<3) | (dec>>2)); + left = dec & 3; + mode = 2; + break; + + case 2: // we have 2 bits and keep 7 + left = left << 5 | dec; + mode = 3; + break; + + case 3: // we have 7 bits and keep 4 + vchRet.push_back((left<<1) | (dec>>4)); + left = dec & 15; + mode = 4; + break; + + case 4: // we have 4 bits, and keep 1 + vchRet.push_back((left<<4) | (dec>>1)); + left = dec & 1; + mode = 5; + break; + + case 5: // we have 1 bit, and keep 6 + left = left << 5 | dec; + mode = 6; + break; + + case 6: // we have 6 bits, and keep 3 + vchRet.push_back((left<<2) | (dec>>3)); + left = dec & 7; + mode = 7; + break; + + case 7: // we have 3 bits, and keep 0 + vchRet.push_back((left<<5) | dec); + mode = 0; + break; + } + } + + if (pfInvalid) + switch (mode) + { + case 0: // 8n base32 characters processed: ok + break; + + case 1: // 8n+1 base32 characters processed: impossible + case 3: // +3 + case 6: // +6 + *pfInvalid = true; + break; + + case 2: // 8n+2 base32 characters processed: require '======' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1) + *pfInvalid = true; + break; + + case 4: // 8n+4 base32 characters processed: require '====' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1) + *pfInvalid = true; + break; + + case 5: // 8n+5 base32 characters processed: require '===' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1) + *pfInvalid = true; + break; + + case 7: // 8n+7 base32 characters processed: require '=' + if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1) + *pfInvalid = true; + break; + } + + return vchRet; +} + +string DecodeBase32(const string& str) +{ + vector vchRet = DecodeBase32(str.c_str()); + return string((const char*)&vchRet[0], vchRet.size()); +} + + +bool WildcardMatch(const char* psz, const char* mask) +{ + while (true) + { + switch (*mask) + { + case '\0': + return (*psz == '\0'); + case '*': + return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask)); + case '?': + if (*psz == '\0') + return false; + break; + default: + if (*psz != *mask) + return false; + break; + } + psz++; + mask++; + } +} + +bool WildcardMatch(const string& str, const string& mask) +{ + return WildcardMatch(str.c_str(), mask.c_str()); +} + + + + + + + + +static std::string FormatException(std::exception* pex, const char* pszThread) +{ +#ifdef WIN32 + char pszModule[MAX_PATH] = ""; + GetModuleFileNameA(NULL, pszModule, sizeof(pszModule)); +#else + const char* pszModule = "BERN"; +#endif + if (pex) + return strprintf( + "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); + else + return strprintf( + "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); +} + +void LogException(std::exception* pex, const char* pszThread) +{ + std::string message = FormatException(pex, pszThread); + printf("\n%s", message.c_str()); +} + +void PrintException(std::exception* pex, const char* pszThread) +{ + std::string message = FormatException(pex, pszThread); + printf("\n\n************************\n%s\n", message.c_str()); + fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); + strMiscWarning = message; + throw; +} + +void LogStackTrace() { + printf("\n\n******* exception encountered *******\n"); + if (fileout) + { +#ifndef WIN32 + void* pszBuffer[32]; + size_t size; + size = backtrace(pszBuffer, 32); + backtrace_symbols_fd(pszBuffer, size, fileno(fileout)); +#endif + } +} + +void PrintExceptionContinue(std::exception* pex, const char* pszThread) +{ + std::string message = FormatException(pex, pszThread); + printf("\n\n************************\n%s\n", message.c_str()); + fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); + strMiscWarning = message; +} + +boost::filesystem::path GetDefaultDataDir() +{ + namespace fs = boost::filesystem; + // retaining the BERNcash directory for upgrade ease. STS + // Windows < Vista: C:\Documents and Settings\Username\Application Data\BERNcash + // Windows >= Vista: C:\Users\Username\AppData\Roaming\BERNcash + // Mac: ~/Library/Application Support/BERNcash + // Unix: ~/.BERNcash +#ifdef WIN32 + // Windows + return GetSpecialFolderPath(CSIDL_APPDATA) / "BERNcash"; +#else + fs::path pathRet; + char* pszHome = getenv("HOME"); + if (pszHome == NULL || strlen(pszHome) == 0) + pathRet = fs::path("/"); + else + pathRet = fs::path(pszHome); +#ifdef MAC_OSX + // Mac + pathRet /= "Library/Application Support"; + fs::create_directory(pathRet); + return pathRet / "BERNcash"; +#else + // Unix + return pathRet / ".BERNcash"; +#endif +#endif +} + +const boost::filesystem::path &GetDataDir(bool fNetSpecific) +{ + namespace fs = boost::filesystem; + + static fs::path pathCached[2]; + static CCriticalSection csPathCached; + static bool cachedPath[2] = {false, false}; + + fs::path &path = pathCached[fNetSpecific]; + + // This can be called during exceptions by printf, so we cache the + // value so we don't have to do memory allocations after that. + if (cachedPath[fNetSpecific]) + return path; + + LOCK(csPathCached); + + if (mapArgs.count("-datadir")) { + path = fs::system_complete(mapArgs["-datadir"]); + if (!fs::is_directory(path)) { + path = ""; + return path; + } + } else { + path = GetDefaultDataDir(); + } + if (fNetSpecific && GetBoolArg("-testnet", false)) + path /= "testnet"; + + fs::create_directory(path); + + cachedPath[fNetSpecific]=true; + return path; +} + +boost::filesystem::path GetConfigFile() +{ + boost::filesystem::path pathConfigFile(GetArg("-conf", "BERNcash.conf")); + if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile; + return pathConfigFile; +} + +void ReadConfigFile(map& mapSettingsRet, + map >& mapMultiSettingsRet) +{ + boost::filesystem::ifstream streamConfig(GetConfigFile()); + if (!streamConfig.good()) + return; // No bitcoin.conf file is OK + + set setOptions; + setOptions.insert("*"); + + for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it) + { + // Don't overwrite existing settings so command line settings override bitcoin.conf + string strKey = string("-") + it->string_key; + if (mapSettingsRet.count(strKey) == 0) + { + mapSettingsRet[strKey] = it->value[0]; + // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set) + InterpretNegativeSetting(strKey, mapSettingsRet); + } + mapMultiSettingsRet[strKey].push_back(it->value[0]); + } +} + +boost::filesystem::path GetPidFile() +{ + boost::filesystem::path pathPidFile(GetArg("-pid", "BERNd.pid")); + if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile; + return pathPidFile; +} + +void CreatePidFile(const boost::filesystem::path &path, pid_t pid) +{ + FILE* file = fopen(path.string().c_str(), "w"); + if (file) + { + fprintf(file, "%d\n", pid); + fclose(file); + } +} + +bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest) +{ +#ifdef WIN32 + return MoveFileExA(src.string().c_str(), dest.string().c_str(), + MOVEFILE_REPLACE_EXISTING); +#else + int rc = std::rename(src.string().c_str(), dest.string().c_str()); + return (rc == 0); +#endif /* WIN32 */ +} + +void FileCommit(FILE *fileout) +{ + fflush(fileout); // harmless if redundantly called +#ifdef WIN32 + _commit(_fileno(fileout)); +#else + fsync(fileno(fileout)); +#endif +} + +int GetFilesize(FILE* file) +{ + int nSavePos = ftell(file); + int nFilesize = -1; + if (fseek(file, 0, SEEK_END) == 0) + nFilesize = ftell(file); + fseek(file, nSavePos, SEEK_SET); + return nFilesize; +} + +void ShrinkDebugFile() +{ + // Scroll debug.log if it's getting too big + boost::filesystem::path pathLog = GetDataDir() / "debug.log"; + FILE* file = fopen(pathLog.string().c_str(), "r"); + if (file && GetFilesize(file) > 10 * 1000000) + { + // Restart the file with some of the end + char pch[200000]; + fseek(file, -sizeof(pch), SEEK_END); + int nBytes = fread(pch, 1, sizeof(pch), file); + fclose(file); + + file = fopen(pathLog.string().c_str(), "w"); + if (file) + { + fwrite(pch, 1, nBytes, file); + fclose(file); + } + } +} + + + + + + + + +// +// "Never go to sea with two chronometers; take one or three." +// Our three time sources are: +// - System clock +// - Median of other nodes clocks +// - The user (asking the user to fix the system clock if the first two disagree) +// +static int64 nMockTime = 0; // For unit testing + +int64 GetTime() +{ + if (nMockTime) return nMockTime; + + return time(NULL); +} + +void SetMockTime(int64 nMockTimeIn) +{ + nMockTime = nMockTimeIn; +} + +static int64 nTimeOffset = 0; + +int64 GetAdjustedTime() +{ + return GetTime() + nTimeOffset; +} + +void AddTimeData(const CNetAddr& ip, int64 nTime) +{ + int64 nOffsetSample = nTime - GetTime(); + + // Ignore duplicates + static set setKnown; + if (!setKnown.insert(ip).second) + return; + + // Add data + vTimeOffsets.input(nOffsetSample); + printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); + if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) + { + int64 nMedian = vTimeOffsets.median(); + std::vector vSorted = vTimeOffsets.sorted(); + // Only let other nodes change our time by so much + if (abs64(nMedian) < 70 * 60) + { + nTimeOffset = nMedian; + } + else + { + nTimeOffset = 0; + + static bool fDone; + if (!fDone) + { + // If nobody has a time different than ours but within 5 minutes of ours, give a warning + bool fMatch = false; + BOOST_FOREACH(int64 nOffset, vSorted) + if (nOffset != 0 && abs64(nOffset) < 5 * 60) + fMatch = true; + + if (!fMatch) + { + fDone = true; + string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong BERN will not work properly."); + strMiscWarning = strMessage; + printf("*** %s\n", strMessage.c_str()); + uiInterface.ThreadSafeMessageBox(strMessage+" ", string("BERN"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION); + } + } + } + if (fDebug) { + BOOST_FOREACH(int64 n, vSorted) + printf("%+"PRI64d" ", n); + printf("| "); + } + printf("nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60); + } +} + + + + + + + + +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); +} + +string FormatFullVersion() +{ + return CLIENT_BUILD; +} + +// Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014) +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments) +{ + std::ostringstream ss; + ss << "/"; + ss << name << ":" << FormatVersion(nClientVersion); + if (!comments.empty()) + ss << "(" << boost::algorithm::join(comments, "; ") << ")"; + ss << "/"; + return ss.str(); +} + +#ifdef WIN32 +boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate) +{ + namespace fs = boost::filesystem; + + char pszPath[MAX_PATH] = ""; + + if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate)) + { + return fs::path(pszPath); + } + + printf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n"); + return fs::path(""); +} +#endif + +void runCommand(std::string strCommand) +{ + int nErr = ::system(strCommand.c_str()); + if (nErr) + printf("runCommand error: system(%s) returned %d\n", strCommand.c_str(), nErr); +} + +void RenameThread(const char* name) +{ +#if defined(PR_SET_NAME) + // Only the first 15 characters are used (16 - NUL terminator) + ::prctl(PR_SET_NAME, name, 0, 0, 0); +#elif 0 && (defined(__FreeBSD__) || defined(__OpenBSD__)) + // TODO: This is currently disabled because it needs to be verified to work + // on FreeBSD or OpenBSD first. When verified the '0 &&' part can be + // removed. + pthread_set_name_np(pthread_self(), name); + +// This is XCode 10.6-and-later; bring back if we drop 10.5 support: +// #elif defined(MAC_OSX) +// pthread_setname_np(name); + +#else + // Prevent warnings for unused parameters... + (void)name; +#endif +} + +bool NewThread(void(*pfn)(void*), void* parg) +{ + try + { + boost::thread(pfn, parg); // thread detaches when out of scope + } catch(boost::thread_resource_error &e) { + printf("Error creating thread: %s\n", e.what()); + return false; + } + return true; +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..dc7e80c --- /dev/null +++ b/src/util.h @@ -0,0 +1,655 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_UTIL_H +#define BITCOIN_UTIL_H + +#include "uint256.h" + +#ifndef WIN32 +#include +#include +#include +#else +typedef int pid_t; /* define for Windows compatibility */ +#endif +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "netbase.h" // for AddTimeData + +typedef long long int64; +typedef unsigned long long uint64; + +static const int64 COIN = 1000000; +static const int64 CENT = 10000; + + +#define BEGIN(a) ((char*)&(a)) +#define END(a) ((char*)&((&(a))[1])) +#define UBEGIN(a) ((unsigned char*)&(a)) +#define UEND(a) ((unsigned char*)&((&(a))[1])) +#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) + +#define UVOIDBEGIN(a) ((void*)&(a)) +#define CVOIDBEGIN(a) ((const void*)&(a)) +#define UINTBEGIN(a) ((uint32_t*)&(a)) +#define CUINTBEGIN(a) ((const uint32_t*)&(a)) + +#ifndef PRI64d +#if defined(_MSC_VER) || defined(__MSVCRT__) +#define PRI64d "I64d" +#define PRI64u "I64u" +#define PRI64x "I64x" +#else +#define PRI64d "lld" +#define PRI64u "llu" +#define PRI64x "llx" +#endif +#endif + +#ifndef THROW_WITH_STACKTRACE +#define THROW_WITH_STACKTRACE(exception) \ +{ \ + LogStackTrace(); \ + throw (exception); \ +} +void LogStackTrace(); +#endif + + +/* Format characters for (s)size_t and ptrdiff_t */ +#if defined(_MSC_VER) || defined(__MSVCRT__) + /* (s)size_t and ptrdiff_t have the same size specifier in MSVC: + http://msdn.microsoft.com/en-us/library/tcxf1dw6%28v=vs.100%29.aspx + */ + #define PRIszx "Ix" + #define PRIszu "Iu" + #define PRIszd "Id" + #define PRIpdx "Ix" + #define PRIpdu "Iu" + #define PRIpdd "Id" +#else /* C99 standard */ + #define PRIszx "zx" + #define PRIszu "zu" + #define PRIszd "zd" + #define PRIpdx "tx" + #define PRIpdu "tu" + #define PRIpdd "td" +#endif + +// This is needed because the foreach macro can't get over the comma in pair +#define PAIRTYPE(t1, t2) std::pair + +// Align by increasing pointer, must have extra space at end of buffer +template +T* alignup(T* p) +{ + union + { + T* ptr; + size_t n; + } u; + u.ptr = p; + u.n = (u.n + (nBytes-1)) & ~(nBytes-1); + return u.ptr; +} + +#ifdef WIN32 +#define MSG_NOSIGNAL 0 +#define MSG_DONTWAIT 0 + +#ifndef S_IRUSR +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#endif +#else +#define MAX_PATH 1024 +inline void Sleep(int64 n) +{ + /*Boost has a year 2038 problem— if the request sleep time is past epoch+2^31 seconds the sleep returns instantly. + So we clamp our sleeps here to 10 years and hope that boost is fixed by 2028.*/ + boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n>315576000000LL?315576000000LL:n)); +} +#endif + +/* This GNU C extension enables the compiler to check the format string against the parameters provided. + * X is the number of the "format string" parameter, and Y is the number of the first variadic parameter. + * Parameters count from 1. + */ +#ifdef __GNUC__ +#define ATTR_WARN_PRINTF(X,Y) __attribute__((format(printf,X,Y))) +#else +#define ATTR_WARN_PRINTF(X,Y) +#endif + + + + + + + + +extern std::map mapArgs; +extern std::map > mapMultiArgs; +extern bool fDebug; +extern bool fStaking; +extern bool fDebugNet; +extern bool fPrintToConsole; +extern bool fPrintToDebugger; +extern bool fRequestShutdown; +extern bool fShutdown; +extern bool fDaemon; +extern bool fServer; +extern bool fCommandLine; +extern std::string strMiscWarning; +extern bool fTestNet; +extern bool fNoListen; +extern bool fLogTimestamps; +extern bool fReopenDebugLog; + +void RandAddSeed(); +void RandAddSeedPerfmon(); +int ATTR_WARN_PRINTF(1,2) OutputDebugStringF(const char* pszFormat, ...); + +/* + Rationale for the real_strprintf / strprintf construction: + It is not allowed to use va_start with a pass-by-reference argument. + (C++ standard, 18.7, paragraph 3). Use a dummy argument to work around this, and use a + macro to keep similar semantics. +*/ + +/** Overload strprintf for char*, so that GCC format type warnings can be given */ +std::string ATTR_WARN_PRINTF(1,3) real_strprintf(const char *format, int dummy, ...); +/** Overload strprintf for std::string, to be able to use it with _ (translation). + * This will not support GCC format type warnings (-Wformat) so be careful. + */ +std::string real_strprintf(const std::string &format, int dummy, ...); +#define strprintf(format, ...) real_strprintf(format, 0, __VA_ARGS__) +std::string vstrprintf(const char *format, va_list ap); + +bool ATTR_WARN_PRINTF(1,2) error(const char *format, ...); + +/* Redefine printf so that it directs output to debug.log + * + * Do this *after* defining the other printf-like functions, because otherwise the + * __attribute__((format(printf,X,Y))) gets expanded to __attribute__((format(OutputDebugStringF,X,Y))) + * which confuses gcc. + */ +#define printf OutputDebugStringF + +void LogException(std::exception* pex, const char* pszThread); +void PrintException(std::exception* pex, const char* pszThread); +void PrintExceptionContinue(std::exception* pex, const char* pszThread); +void ParseString(const std::string& str, char c, std::vector& v); +std::string FormatMoney(int64 n, bool fPlus=false); +bool ParseMoney(const std::string& str, int64& nRet); +bool ParseMoney(const char* pszIn, int64& nRet); +std::vector ParseHex(const char* psz); +std::vector ParseHex(const std::string& str); +bool IsHex(const std::string& str); +std::vector DecodeBase64(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase64(const std::string& str); +std::string EncodeBase64(const unsigned char* pch, size_t len); +std::string EncodeBase64(const std::string& str); +std::vector DecodeBase32(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase32(const std::string& str); +std::string EncodeBase32(const unsigned char* pch, size_t len); +std::string EncodeBase32(const std::string& str); +void ParseParameters(int argc, const char*const argv[]); +bool WildcardMatch(const char* psz, const char* mask); +bool WildcardMatch(const std::string& str, const std::string& mask); +void FileCommit(FILE *fileout); +int GetFilesize(FILE* file); +bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest); +boost::filesystem::path GetDefaultDataDir(); +const boost::filesystem::path &GetDataDir(bool fNetSpecific = true); +boost::filesystem::path GetConfigFile(); +boost::filesystem::path GetPidFile(); +void CreatePidFile(const boost::filesystem::path &path, pid_t pid); +void ReadConfigFile(std::map& mapSettingsRet, std::map >& mapMultiSettingsRet); +#ifdef WIN32 +boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); +#endif +void ShrinkDebugFile(); +int GetRandInt(int nMax); +uint64 GetRand(uint64 nMax); +uint256 GetRandHash(); +int64 GetTime(); +void SetMockTime(int64 nMockTimeIn); +int64 GetAdjustedTime(); +long hex2long(const char* hexString); +std::string FormatFullVersion(); +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); +void AddTimeData(const CNetAddr& ip, int64 nTime); +void runCommand(std::string strCommand); + + + + + + + + + +inline std::string i64tostr(int64 n) +{ + return strprintf("%"PRI64d, n); +} + +inline std::string itostr(int n) +{ + return strprintf("%d", n); +} + +inline int64 atoi64(const char* psz) +{ +#ifdef _MSC_VER + return _atoi64(psz); +#else + return strtoll(psz, NULL, 10); +#endif +} + +inline int64 atoi64(const std::string& str) +{ +#ifdef _MSC_VER + return _atoi64(str.c_str()); +#else + return strtoll(str.c_str(), NULL, 10); +#endif +} + +inline int atoi(const std::string& str) +{ + return atoi(str.c_str()); +} + +inline int roundint(double d) +{ + return (int)(d > 0 ? d + 0.5 : d - 0.5); +} + +inline int64 roundint64(double d) +{ + return (int64)(d > 0 ? d + 0.5 : d - 0.5); +} + +inline int64 abs64(int64 n) +{ + return (n >= 0 ? n : -n); +} + +template +std::string HexStr(const T itbegin, const T itend, bool fSpaces=false) +{ + std::string rv; + static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + rv.reserve((itend-itbegin)*3); + for(T it = itbegin; it < itend; ++it) + { + unsigned char val = (unsigned char)(*it); + if(fSpaces && it != itbegin) + rv.push_back(' '); + rv.push_back(hexmap[val>>4]); + rv.push_back(hexmap[val&15]); + } + + return rv; +} + +inline std::string HexStr(const std::vector& vch, bool fSpaces=false) +{ + return HexStr(vch.begin(), vch.end(), fSpaces); +} + +template +void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true) +{ + printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); +} + +inline void PrintHex(const std::vector& vch, const char* pszFormat="%s", bool fSpaces=true) +{ + printf(pszFormat, HexStr(vch, fSpaces).c_str()); +} + +inline int64 GetPerformanceCounter() +{ + int64 nCounter = 0; +#ifdef WIN32 + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); +#else + timeval t; + gettimeofday(&t, NULL); + nCounter = (int64) t.tv_sec * 1000000 + t.tv_usec; +#endif + return nCounter; +} + +inline int64 GetTimeMillis() +{ + return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - + boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); +} + +inline std::string DateTimeStrFormat(const char* pszFormat, int64 nTime) +{ + time_t n = nTime; + struct tm* ptmTime = gmtime(&n); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime); + return pszTime; +} + +static const std::string strTimestampFormat = "%Y-%m-%d %H:%M:%S UTC"; +inline std::string DateTimeStrFormat(int64 nTime) +{ + return DateTimeStrFormat(strTimestampFormat.c_str(), nTime); +} + + +template +void skipspaces(T& it) +{ + while (isspace(*it)) + ++it; +} + +inline bool IsSwitchChar(char c) +{ +#ifdef WIN32 + return c == '-' || c == '/'; +#else + return c == '-'; +#endif +} + +/** + * Return string argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. "1") + * @return command-line argument or default value + */ +std::string GetArg(const std::string& strArg, const std::string& strDefault); + +/** + * Return integer argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. 1) + * @return command-line argument (0 if invalid number) or default value + */ +int64 GetArg(const std::string& strArg, int64 nDefault); + +/** + * Return boolean argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (true or false) + * @return command-line argument or default value + */ +bool GetBoolArg(const std::string& strArg, bool fDefault=false); + +/** + * Set an argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param strValue Value (e.g. "1") + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetArg(const std::string& strArg, const std::string& strValue); + +/** + * Set a boolean argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param fValue Value (e.g. false) + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetBoolArg(const std::string& strArg, bool fValue); + + + + + + + + + +template +inline uint256 Hash(const T1 pbegin, const T1 pend) +{ + static unsigned char pblank[1]; + uint256 hash1; + SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +class CHashWriter +{ +private: + SHA256_CTX ctx; + +public: + int nType; + int nVersion; + + void Init() { + SHA256_Init(&ctx); + } + + CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) { + Init(); + } + + CHashWriter& write(const char *pch, size_t size) { + SHA256_Update(&ctx, pch, size); + return (*this); + } + + // invalidates the object + uint256 GetHash() { + uint256 hash1; + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; + } + + template + CHashWriter& operator<<(const T& obj) { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } +}; + + +template +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end) +{ + static unsigned char pblank[1]; + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end, + const T3 p3begin, const T3 p3end) +{ + static unsigned char pblank[1]; + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) +{ + CHashWriter ss(nType, nVersion); + ss << obj; + return ss.GetHash(); +} + +inline uint160 Hash160(const std::vector& vch) +{ + uint256 hash1; + SHA256(&vch[0], vch.size(), (unsigned char*)&hash1); + uint160 hash2; + RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + + +/** Median filter over a stream of values. + * Returns the median of the last N numbers + */ +template class CMedianFilter +{ +private: + std::vector vValues; + std::vector vSorted; + unsigned int nSize; + T tInitial; +public: + CMedianFilter(unsigned int size, T initial_value): + nSize(size) + { + vValues.reserve(size); + vValues.push_back(initial_value); + vSorted = vValues; + tInitial = initial_value; + } + + void input(T value) + { + if(vValues.size() == nSize) + { + vValues.erase(vValues.begin()); + } + vValues.push_back(value); + + vSorted.resize(vValues.size()); + std::copy(vValues.begin(), vValues.end(), vSorted.begin()); + std::sort(vSorted.begin(), vSorted.end()); + } + + // remove last instance of a value + void removeLast(T value) + { + for (int i = vValues.size()-1; i >= 0; --i) + { + if (vValues[i] == value) + { + vValues.erase(vValues.begin()+i); + break; + } + } + if (vValues.empty()) + { + vValues.push_back(tInitial); + } + + vSorted.resize(vValues.size()); + std::copy(vValues.begin(), vValues.end(), vSorted.begin()); + std::sort(vSorted.begin(), vSorted.end()); + } + + T median() const + { + int size = vSorted.size(); + assert(size>0); + if(size & 1) // Odd number of elements + { + return vSorted[size/2]; + } + else // Even number of elements + { + return (vSorted[size/2-1] + vSorted[size/2]) / 2; + } + } + + int size() const + { + return vValues.size(); + } + + std::vector sorted () const + { + return vSorted; + } +}; + +bool NewThread(void(*pfn)(void*), void* parg); + +#ifdef WIN32 +inline void SetThreadPriority(int nPriority) +{ + SetThreadPriority(GetCurrentThread(), nPriority); +} +#else + +#define THREAD_PRIORITY_LOWEST PRIO_MAX +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 + +inline void SetThreadPriority(int nPriority) +{ + // It's unclear if it's even possible to change thread priorities on Linux, + // but we really and truly need it for the generation threads. +#ifdef PRIO_THREAD + setpriority(PRIO_THREAD, 0, nPriority); +#else + setpriority(PRIO_PROCESS, 0, nPriority); +#endif +} + +inline void ExitThread(size_t nExitCode) +{ + pthread_exit((void*)nExitCode); +} +#endif + +void RenameThread(const char* name); + +inline uint32_t ByteReverse(uint32_t value) +{ + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return (value<<16) | (value>>16); +} + +#endif + diff --git a/src/version.cpp b/src/version.cpp new file mode 100644 index 0000000..116540d --- /dev/null +++ b/src/version.cpp @@ -0,0 +1,66 @@ +// Copyright (c) 2012 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 + +#include "version.h" + +// Name of client reported in the 'version' message. Report the same name +// for both bitcoind and bitcoin-qt, to make it harder for attackers to +// target servers or GUI users specifically. +const std::string CLIENT_NAME("BERN"); + +// 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 "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 "$Format:%cD" +#endif + +#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \ + "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "" commit + +#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \ + "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "" + +#ifndef BUILD_DESC +# ifdef GIT_COMMIT_ID +# define BUILD_DESC BUILD_DESC_FROM_COMMIT(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD, GIT_COMMIT_ID) +# else +# define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_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); diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..0a995bf --- /dev/null +++ b/src/version.h @@ -0,0 +1,52 @@ +// Copyright (c) 2012 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_VERSION_H +#define BITCOIN_VERSION_H + +#include "clientversion.h" +#include + +// +// client versioning +// + +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; + +// +// network protocol versioning +// + +static const int PROTOCOL_VERSION = 60016; + +// earlier versions not supported as of Feb 2012, and are disconnected +static const int MIN_PROTO_VERSION = 60016; + +// nTime field added to CAddress, starting with this version; +// if possible, avoid requesting addresses nodes older than this +static const int CADDR_TIME_VERSION = 60016; + +// only request blocks from nodes outside this range of versions +static const int NOBLKS_VERSION_START = 0; +static const int NOBLKS_VERSION_END = 60016; + +// BIP 0031, pong message, is enabled for all versions AFTER this one +static const int BIP0031_VERSION = 60000; + +// "mempool" command, enhanced "getdata" behavior starts with this version: +static const int MEMPOOL_GD_VERSION = 60016; + +#define DISPLAY_VERSION_MAJOR 1 +#define DISPLAY_VERSION_MINOR 1 +#define DISPLAY_VERSION_REVISION 0 +#define DISPLAY_VERSION_BUILD 0 + +#endif diff --git a/src/wallet.cpp b/src/wallet.cpp new file mode 100644 index 0000000..70ff40a --- /dev/null +++ b/src/wallet.cpp @@ -0,0 +1,2269 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "main.h" +#include "wallet.h" +#include "walletdb.h" +#include "crypter.h" +#include "ui_interface.h" +#include "base58.h" +#include "kernel.h" +#include "coincontrol.h" + +#include + +using namespace std; +extern int nStakeMaxAge; + + +////////////////////////////////////////////////////////////////////////////// +// +// mapWallet +// + +struct CompareValueOnly +{ + bool operator()(const pair >& t1, + const pair >& t2) const + { + return t1.first < t2.first; + } +}; + +CPubKey CWallet::GenerateNewKey() +{ + bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets + + RandAddSeedPerfmon(); + CKey key; + key.MakeNewKey(fCompressed); + + // Compressed public keys were introduced in version 0.6.0 + if (fCompressed) + SetMinVersion(FEATURE_COMPRPUBKEY); + + if (!AddKey(key)) + throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed"); + return key.GetPubKey(); +} + +bool CWallet::AddKey(const CKey& key) +{ + if (!CCryptoKeyStore::AddKey(key)) + return false; + if (!fFileBacked) + return true; + if (!IsCrypted()) + return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey()); + return true; +} + +bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector &vchCryptedSecret) +{ + if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) + return false; + if (!fFileBacked) + return true; + { + LOCK(cs_wallet); + if (pwalletdbEncryption) + return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret); + else + return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret); + } + return false; +} + +bool CWallet::AddCScript(const CScript& redeemScript) +{ + if (!CCryptoKeyStore::AddCScript(redeemScript)) + return false; + if (!fFileBacked) + return true; + return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript); +} + +// ppcoin: optional setting to unlock wallet for block minting only; +// serves to disable the trivial sendmoney when OS account compromised +bool fWalletUnlockMintOnly = false; + +bool CWallet::Unlock(const SecureString& strWalletPassphrase) +{ + if (!IsLocked()) + return false; + + CCrypter crypter; + CKeyingMaterial vMasterKey; + + { + LOCK(cs_wallet); + BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (CCryptoKeyStore::Unlock(vMasterKey)) + return true; + } + } + return false; +} + +bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase) +{ + bool fWasLocked = IsLocked(); + + { + LOCK(cs_wallet); + Lock(); + + CCrypter crypter; + CKeyingMaterial vMasterKey; + BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (CCryptoKeyStore::Unlock(vMasterKey)) + { + int64 nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (pMasterKey.second.nDeriveIterations < 25000) + pMasterKey.second.nDeriveIterations = 25000; + + printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey)) + return false; + CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second); + if (fWasLocked) + Lock(); + return true; + } + } + } + + return false; +} + +void CWallet::SetBestChain(const CBlockLocator& loc) +{ + CWalletDB walletdb(strWalletFile); + walletdb.WriteBestBlock(loc); +} + +// This class implements an addrIncoming entry that causes pre-0.4 +// clients to crash on startup if reading a private-key-encrypted wallet. +class CCorruptAddress +{ +public: + IMPLEMENT_SERIALIZE + ( + if (nType & SER_DISK) + READWRITE(nVersion); + ) +}; + +bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit) +{ + if (nWalletVersion >= nVersion) + return true; + + // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way + if (fExplicit && nVersion > nWalletMaxVersion) + nVersion = FEATURE_LATEST; + + nWalletVersion = nVersion; + + if (nVersion > nWalletMaxVersion) + nWalletMaxVersion = nVersion; + + if (fFileBacked) + { + CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile); + if (nWalletVersion >= 40000) + { + // Versions prior to 0.4.0 did not support the "minversion" record. + // Use a CCorruptAddress to make them crash instead. + CCorruptAddress corruptAddress; + pwalletdb->WriteSetting("addrIncoming", corruptAddress); + } + if (nWalletVersion > 40000) + pwalletdb->WriteMinVersion(nWalletVersion); + if (!pwalletdbIn) + delete pwalletdb; + } + + return true; +} + +bool CWallet::SetMaxVersion(int nVersion) +{ + // cannot downgrade below current version + if (nWalletVersion > nVersion) + return false; + + nWalletMaxVersion = nVersion; + + return true; +} + +bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) +{ + if (IsCrypted()) + return false; + + CKeyingMaterial vMasterKey; + RandAddSeedPerfmon(); + + vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); + RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); + + CMasterKey kMasterKey; + + RandAddSeedPerfmon(); + kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); + RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); + + CCrypter crypter; + int64 nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime)); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (kMasterKey.nDeriveIterations < 25000) + kMasterKey.nDeriveIterations = 25000; + + printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) + return false; + + { + LOCK(cs_wallet); + mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; + if (fFileBacked) + { + pwalletdbEncryption = new CWalletDB(strWalletFile); + if (!pwalletdbEncryption->TxnBegin()) + return false; + pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); + } + + if (!EncryptKeys(vMasterKey)) + { + if (fFileBacked) + pwalletdbEncryption->TxnAbort(); + exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet. + } + + // Encryption was introduced in version 0.4.0 + SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true); + + if (fFileBacked) + { + if (!pwalletdbEncryption->TxnCommit()) + exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet. + + delete pwalletdbEncryption; + pwalletdbEncryption = NULL; + } + + Lock(); + Unlock(strWalletPassphrase); + NewKeyPool(); + Lock(); + + // Need to completely rewrite the wallet file; if we don't, bdb might keep + // bits of the unencrypted private key in slack space in the database file. + CDB::Rewrite(strWalletFile); + + } + NotifyStatusChanged(this); + + return true; +} + +int64 CWallet::IncOrderPosNext(CWalletDB *pwalletdb) +{ + int64 nRet = nOrderPosNext++; + if (pwalletdb) { + pwalletdb->WriteOrderPosNext(nOrderPosNext); + } else { + CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext); + } + return nRet; +} + +CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, std::string strAccount) +{ + CWalletDB walletdb(strWalletFile); + + // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap. + TxItems txOrdered; + + // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry + // would make this much faster for applications that do this a lot. + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx* wtx = &((*it).second); + txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); + } + acentries.clear(); + walletdb.ListAccountCreditDebit(strAccount, acentries); + BOOST_FOREACH(CAccountingEntry& entry, acentries) + { + txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry))); + } + + return txOrdered; +} + +void CWallet::WalletUpdateSpent(const CTransaction &tx) +{ + // Anytime a signature is successfully verified, it's proof the outpoint is spent. + // Update the wallet spent flag if it doesn't know due to wallet.dat being + // restored from backup or the user making copies of wallet.dat. + { + LOCK(cs_wallet); + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + map::iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + CWalletTx& wtx = (*mi).second; + if (txin.prevout.n >= wtx.vout.size()) + printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str()); + else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n])) + { + printf("WalletUpdateSpent found spent coin %sMNT %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.MarkSpent(txin.prevout.n); + wtx.WriteToDisk(); + NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED); + } + } + } + } +} + +void CWallet::MarkDirty() +{ + { + LOCK(cs_wallet); + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + item.second.MarkDirty(); + } +} + +bool CWallet::AddToWallet(const CWalletTx& wtxIn) +{ + uint256 hash = wtxIn.GetHash(); + { + LOCK(cs_wallet); + // Inserts only if not already there, returns tx inserted or tx found + pair::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); + CWalletTx& wtx = (*ret.first).second; + wtx.BindWallet(this); + bool fInsertedNew = ret.second; + if (fInsertedNew) + { + wtx.nTimeReceived = GetAdjustedTime(); + wtx.nOrderPos = IncOrderPosNext(); + + wtx.nTimeSmart = wtx.nTimeReceived; + if (wtxIn.hashBlock != 0) + { + if (mapBlockIndex.count(wtxIn.hashBlock)) + { + unsigned int latestNow = wtx.nTimeReceived; + unsigned int latestEntry = 0; + { + // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future + int64 latestTolerated = latestNow + 300; + std::list acentries; + TxItems txOrdered = OrderedTxItems(acentries); + for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx == &wtx) + continue; + CAccountingEntry *const pacentry = (*it).second.second; + int64 nSmartTime; + if (pwtx) + { + nSmartTime = pwtx->nTimeSmart; + if (!nSmartTime) + nSmartTime = pwtx->nTimeReceived; + } + else + nSmartTime = pacentry->nTime; + if (nSmartTime <= latestTolerated) + { + latestEntry = nSmartTime; + if (nSmartTime > latestNow) + latestNow = nSmartTime; + break; + } + } + } + + unsigned int& blocktime = mapBlockIndex[wtxIn.hashBlock]->nTime; + wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow)); + } + else + printf("AddToWallet() : found %s in block %s not in index\n", + wtxIn.GetHash().ToString().substr(0,10).c_str(), + wtxIn.hashBlock.ToString().c_str()); + } + } + + bool fUpdated = false; + if (!fInsertedNew) + { + // Merge + if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) + { + wtx.hashBlock = wtxIn.hashBlock; + fUpdated = true; + } + if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex)) + { + wtx.vMerkleBranch = wtxIn.vMerkleBranch; + wtx.nIndex = wtxIn.nIndex; + fUpdated = true; + } + if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe) + { + wtx.fFromMe = wtxIn.fFromMe; + fUpdated = true; + } + fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent); + } + + //// debug print + printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); + + // Write to disk + if (fInsertedNew || fUpdated) + if (!wtx.WriteToDisk()) + return false; +#ifndef QT_GUI + // If default receiving address gets used, replace it with a new one + CScript scriptDefaultKey; + scriptDefaultKey.SetDestination(vchDefaultKey.GetID()); + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if (txout.scriptPubKey == scriptDefaultKey) + { + CPubKey newDefaultKey; + if (GetKeyFromPool(newDefaultKey, false)) + { + SetDefaultKey(newDefaultKey); + SetAddressBookName(vchDefaultKey.GetID(), ""); + } + } + } +#endif + // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins + WalletUpdateSpent(wtx); + + // Notify UI of new or updated transaction + NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED); + + // notify an external script when a wallet transaction comes in or is updated + std::string strCmd = GetArg("-walletnotify", ""); + + if ( !strCmd.empty()) + { + boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex()); + boost::thread t(runCommand, strCmd); // thread runs free + } + } + return true; +} + +// Add a transaction to the wallet, or update it. +// pblock is optional, but should be provided if the transaction is known to be in a block. +// If fUpdate is true, existing transactions will be updated. +bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock) +{ + uint256 hash = tx.GetHash(); + { + LOCK(cs_wallet); + bool fExisted = mapWallet.count(hash); + if (fExisted && !fUpdate) return false; + if (fExisted || IsMine(tx) || IsFromMe(tx)) + { + CWalletTx wtx(this,tx); + // Get merkle branch if transaction was found in a block + if (pblock) + wtx.SetMerkleBranch(pblock); + return AddToWallet(wtx); + } + else + WalletUpdateSpent(tx); + } + return false; +} + +bool CWallet::EraseFromWallet(uint256 hash) +{ + if (!fFileBacked) + return false; + { + LOCK(cs_wallet); + if (mapWallet.erase(hash)) + CWalletDB(strWalletFile).EraseTx(hash); + } + return true; +} + + +bool CWallet::IsMine(const CTxIn &txin) const +{ + { + LOCK(cs_wallet); + map::const_iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (txin.prevout.n < prev.vout.size()) + if (IsMine(prev.vout[txin.prevout.n])) + return true; + } + } + return false; +} + +int64 CWallet::GetDebit(const CTxIn &txin) const +{ + { + LOCK(cs_wallet); + map::const_iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (txin.prevout.n < prev.vout.size()) + if (IsMine(prev.vout[txin.prevout.n])) + return prev.vout[txin.prevout.n].nValue; + } + } + return 0; +} + +bool CWallet::IsChange(const CTxOut& txout) const +{ + CTxDestination address; + + // TODO: fix handling of 'change' outputs. The assumption is that any + // payment to a TX_PUBKEYHASH that is mine but isn't in the address book + // is change. That assumption is likely to break when we implement multisignature + // wallets that return change back into a multi-signature-protected address; + // a better way of identifying which outputs are 'the send' and which are + // 'the change' will need to be implemented (maybe extend CWalletTx to remember + // which output, if any, was change). + if (ExtractDestination(txout.scriptPubKey, address) && ::IsMine(*this, address)) + { + LOCK(cs_wallet); + if (!mapAddressBook.count(address)) + return true; + } + return false; +} + +int64 CWalletTx::GetTxTime() const +{ + int64 n = nTimeSmart; + return n ? n : nTimeReceived; +} + +int CWalletTx::GetRequestCount() const +{ + // Returns -1 if it wasn't being tracked + int nRequests = -1; + { + LOCK(pwallet->cs_wallet); + if (IsCoinBase() || IsCoinStake()) + { + // Generated block + if (hashBlock != 0) + { + map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); + if (mi != pwallet->mapRequestCount.end()) + nRequests = (*mi).second; + } + } + else + { + // Did anyone request this transaction? + map::const_iterator mi = pwallet->mapRequestCount.find(GetHash()); + if (mi != pwallet->mapRequestCount.end()) + { + nRequests = (*mi).second; + + // How about the block it's in? + if (nRequests == 0 && hashBlock != 0) + { + map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); + if (mi != pwallet->mapRequestCount.end()) + nRequests = (*mi).second; + else + nRequests = 1; // If it's in someone else's block it must have got out + } + } + } + } + return nRequests; +} + +void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list >& listReceived, + list >& listSent, int64& nFee, string& strSentAccount) const +{ + nGeneratedImmature = nGeneratedMature = nFee = 0; + listReceived.clear(); + listSent.clear(); + strSentAccount = strFromAccount; + + // Compute fee: + int64 nDebit = GetDebit(); + if (nDebit > 0) // debit>0 means we signed/sent this transaction + { + int64 nValueOut = GetValueOut(); + nFee = nDebit - nValueOut; + } + + // Sent/received. + BOOST_FOREACH(const CTxOut& txout, vout) + { + CTxDestination address; + vector vchPubKey; + if (!ExtractDestination(txout.scriptPubKey, address)) + { + if(!IsCoinBaseOrStake()) + { + printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", + this->GetHash().ToString().c_str()); + } + continue; + } + + // Don't report 'change' txouts + if (nDebit > 0 && pwallet->IsChange(txout)) + continue; + + if (nDebit > 0) + listSent.push_back(make_pair(address, txout.nValue)); + + if (pwallet->IsMine(txout)) + { + if(IsCoinBaseOrStake()) + { + if(GetBlocksToMaturity() > 0) + nGeneratedImmature += txout.nValue; + else + nGeneratedMature += txout.nValue; + } + else + listReceived.push_back(make_pair(address, txout.nValue)); + } + } + +} + +void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGeneratedImmature, int64& nGeneratedMature, int64& nReceived, + int64& nSent, int64& nFee) const +{ + nGeneratedImmature = nGeneratedMature = nReceived = nSent = nFee = 0; + + int64 allGeneratedImmature, allGeneratedMature, allFee; + string strSentAccount; + list > listReceived; + list > listSent; + GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); + + if (strAccount == strSentAccount) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& s, listSent) + nSent += s.second; + nFee = allFee; + nGeneratedImmature = allGeneratedImmature; + nGeneratedMature = allGeneratedMature; + } + { + LOCK(pwallet->cs_wallet); + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived) + { + if (pwallet->mapAddressBook.count(r.first)) + { + map::const_iterator mi = pwallet->mapAddressBook.find(r.first); + if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount) + nReceived += r.second; + } + else if (strAccount.empty()) + { + nReceived += r.second; + } + } + } +} + +void CWalletTx::AddSupportingTransactions(CTxDB& txdb) +{ + vtxPrev.clear(); + + const int COPY_DEPTH = 3; + if (SetMerkleBranch() < COPY_DEPTH) + { + vector vWorkQueue; + BOOST_FOREACH(const CTxIn& txin, vin) + vWorkQueue.push_back(txin.prevout.hash); + + // This critsect is OK because txdb is already open + { + LOCK(pwallet->cs_wallet); + map mapWalletPrev; + set setAlreadyDone; + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hash = vWorkQueue[i]; + if (setAlreadyDone.count(hash)) + continue; + setAlreadyDone.insert(hash); + + CMerkleTx tx; + map::const_iterator mi = pwallet->mapWallet.find(hash); + if (mi != pwallet->mapWallet.end()) + { + tx = (*mi).second; + BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev) + mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev; + } + else if (mapWalletPrev.count(hash)) + { + tx = *mapWalletPrev[hash]; + } + else if (!fClient && txdb.ReadDiskTx(hash, tx)) + { + ; + } + else + { + printf("ERROR: AddSupportingTransactions() : unsupported transaction\n"); + continue; + } + + int nDepth = tx.SetMerkleBranch(); + vtxPrev.push_back(tx); + + if (nDepth < COPY_DEPTH) + { + BOOST_FOREACH(const CTxIn& txin, tx.vin) + vWorkQueue.push_back(txin.prevout.hash); + } + } + } + } + + reverse(vtxPrev.begin(), vtxPrev.end()); +} + +bool CWalletTx::WriteToDisk() +{ + return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); +} + +// Scan the block chain (starting in pindexStart) for transactions +// from or to us. If fUpdate is true, found transactions that already +// exist in the wallet will be updated. +int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) +{ + int ret = 0; + + CBlockIndex* pindex = pindexStart; + { + LOCK(cs_wallet); + while (pindex) + { + CBlock block; + block.ReadFromDisk(pindex, true); + BOOST_FOREACH(CTransaction& tx, block.vtx) + { + if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) + ret++; + } + pindex = pindex->pnext; + } + } + return ret; +} + +int CWallet::ScanForWalletTransaction(const uint256& hashTx) +{ + CTransaction tx; + tx.ReadFromDisk(COutPoint(hashTx, 0)); + if (AddToWalletIfInvolvingMe(tx, NULL, true, true)) + return 1; + return 0; +} + +void CWallet::ReacceptWalletTransactions() +{ + CTxDB txdb("r"); + bool fRepeat = true; + while (fRepeat) + { + LOCK(cs_wallet); + fRepeat = false; + vector vMissingTx; + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + if ((wtx.IsCoinBase() && wtx.IsSpent(0)) || (wtx.IsCoinStake() && wtx.IsSpent(1))) + continue; + + CTxIndex txindex; + bool fUpdated = false; + if (txdb.ReadTxIndex(wtx.GetHash(), txindex)) + { + // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat + if (txindex.vSpent.size() != wtx.vout.size()) + { + printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %"PRIszu" != wtx.vout.size() %"PRIszu"\n", txindex.vSpent.size(), wtx.vout.size()); + continue; + } + for (unsigned int i = 0; i < txindex.vSpent.size(); i++) + { + if (wtx.IsSpent(i)) + continue; + if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i])) + { + wtx.MarkSpent(i); + fUpdated = true; + vMissingTx.push_back(txindex.vSpent[i]); + } + } + if (fUpdated) + { + printf("ReacceptWalletTransactions found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.MarkDirty(); + wtx.WriteToDisk(); + } + } + else + { + // Re-accept any txes of ours that aren't already in a block + if (!(wtx.IsCoinBase() || wtx.IsCoinStake())) + wtx.AcceptWalletTransaction(txdb, false); + } + } + if (!vMissingTx.empty()) + { + // TODO: optimize this to scan just part of the block chain? + if (ScanForWalletTransactions(pindexGenesisBlock)) + fRepeat = true; // Found missing transactions: re-do re-accept. + } + } +} + +void CWalletTx::RelayWalletTransaction(CTxDB& txdb) +{ + BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) + { + if (!(tx.IsCoinBase() || tx.IsCoinStake())) + { + uint256 hash = tx.GetHash(); + if (!txdb.ContainsTx(hash)) + RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx); + } + } + if (!(IsCoinBase() || IsCoinStake())) + { + uint256 hash = GetHash(); + if (!txdb.ContainsTx(hash)) + { + printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str()); + RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); + } + } +} + +void CWalletTx::RelayWalletTransaction() +{ + CTxDB txdb("r"); + RelayWalletTransaction(txdb); +} + +void CWallet::ResendWalletTransactions() +{ + // Do this infrequently and randomly to avoid giving away + // that these are our transactions. + static int64 nNextTime; + if (GetTime() < nNextTime) + return; + bool fFirst = (nNextTime == 0); + nNextTime = GetTime() + GetRand(30 * 60); + if (fFirst) + return; + + // Only do it if there's been a new block since last time + static int64 nLastTime; + if (nTimeBestReceived < nLastTime) + return; + nLastTime = GetTime(); + + // Rebroadcast any of our txes that aren't in a block yet + printf("ResendWalletTransactions()\n"); + CTxDB txdb("r"); + { + LOCK(cs_wallet); + // Sort them in chronological order + multimap mapSorted; + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + // Don't rebroadcast until it's had plenty of time that + // it should have gotten in already by now. + if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60) + mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + } + BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) + { + CWalletTx& wtx = *item.second; + if (wtx.CheckTransaction()) + wtx.RelayWalletTransaction(txdb); + else + printf("ResendWalletTransactions() : CheckTransaction failed for transaction %s\n", wtx.GetHash().ToString().c_str()); + } + } +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Actions +// + + +int64 CWallet::GetBalance() const +{ + int64 nTotal = 0; + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsFinal() && pcoin->IsConfirmed()) + nTotal += pcoin->GetAvailableCredit(); + } + } + + return nTotal; +} + +int64 CWallet::GetUnconfirmedBalance() const +{ + int64 nTotal = 0; + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (!pcoin->IsFinal() || !pcoin->IsConfirmed()) + nTotal += pcoin->GetAvailableCredit(); + } + } + return nTotal; +} + +int64 CWallet::GetImmatureBalance() const +{ + int64 nTotal = 0; + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& pcoin = (*it).second; + if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.IsInMainChain()) + nTotal += GetCredit(pcoin); + } + } + return nTotal; +} + +// populate vCoins with vector of spendable COutputs +void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const +{ + vCoins.clear(); + + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + if (!pcoin->IsFinal()) + continue; + + if (fOnlyConfirmed && !pcoin->IsConfirmed()) + continue; + + if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) + continue; + + if(pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0) + continue; + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) + if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue > 0 && + (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) + vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); + } + } +} + +static void ApproximateBestSubset(vector > >vValue, int64 nTotalLower, int64 nTargetValue, + vector& vfBest, int64& nBest, int iterations = 1000) +{ + vector vfIncluded; + + vfBest.assign(vValue.size(), true); + nBest = nTotalLower; + + for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++) + { + vfIncluded.assign(vValue.size(), false); + int64 nTotal = 0; + bool fReachedTarget = false; + for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) + { + for (unsigned int i = 0; i < vValue.size(); i++) + { + if (nPass == 0 ? rand() % 2 : !vfIncluded[i]) + { + nTotal += vValue[i].first; + vfIncluded[i] = true; + if (nTotal >= nTargetValue) + { + fReachedTarget = true; + if (nTotal < nBest) + { + nBest = nTotal; + vfBest = vfIncluded; + } + nTotal -= vValue[i].first; + vfIncluded[i] = false; + } + } + } + } + } +} + +// ppcoin: total coins staked (non-spendable until maturity) +int64 CWallet::GetStake() const +{ + int64 nTotal = 0; + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0) + nTotal += CWallet::GetCredit(*pcoin); + } + return nTotal; +} + +int64 CWallet::GetNewMint() const +{ + int64 nTotal = 0; + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0) + nTotal += CWallet::GetCredit(*pcoin); + } + return nTotal; +} + +bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, vector vCoins, set >& setCoinsRet, int64& nValueRet) const +{ + setCoinsRet.clear(); + nValueRet = 0; + + // List of values less than target + pair > coinLowestLarger; + coinLowestLarger.first = std::numeric_limits::max(); + coinLowestLarger.second.first = NULL; + vector > > vValue; + int64 nTotalLower = 0; + + random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); + + BOOST_FOREACH(COutput output, vCoins) + { + const CWalletTx *pcoin = output.tx; + + if (output.nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs)) + continue; + + int i = output.i; + + if (pcoin->nTime > nSpendTime) + continue; // ppcoin: timestamp must not exceed spend time + + int64 n = pcoin->vout[i].nValue; + + pair > coin = make_pair(n,make_pair(pcoin, i)); + + if (n == nTargetValue) + { + setCoinsRet.insert(coin.second); + nValueRet += coin.first; + return true; + } + else if (n < nTargetValue + CENT) + { + vValue.push_back(coin); + nTotalLower += n; + } + else if (n < coinLowestLarger.first) + { + coinLowestLarger = coin; + } + } + + if (nTotalLower == nTargetValue) + { + for (unsigned int i = 0; i < vValue.size(); ++i) + { + setCoinsRet.insert(vValue[i].second); + nValueRet += vValue[i].first; + } + return true; + } + + if (nTotalLower < nTargetValue) + { + if (coinLowestLarger.second.first == NULL) + return false; + setCoinsRet.insert(coinLowestLarger.second); + nValueRet += coinLowestLarger.first; + return true; + } + + // Solve subset sum by stochastic approximation + sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); + vector vfBest; + int64 nBest; + + ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000); + if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT) + ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000); + + // If we have a bigger coin and (either the stochastic approximation didn't find a good solution, + // or the next bigger coin is closer), return the bigger coin + if (coinLowestLarger.second.first && + ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest)) + { + setCoinsRet.insert(coinLowestLarger.second); + nValueRet += coinLowestLarger.first; + } + else { + for (unsigned int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + { + setCoinsRet.insert(vValue[i].second); + nValueRet += vValue[i].first; + } + + if (fDebug && GetBoolArg("-printpriority")) + { + //// debug print + printf("SelectCoins() best subset: "); + for (unsigned int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + printf("%s ", FormatMoney(vValue[i].first).c_str()); + printf("total %s\n", FormatMoney(nBest).c_str()); + } + } + + return true; +} + +bool CWallet::SelectCoins(int64 nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64& nValueRet, const CCoinControl* coinControl) const +{ + vector vCoins; + AvailableCoins(vCoins, true, coinControl); + + // coin control -> return all selected outputs (we want all selected to go into the transaction for sure) + if (coinControl && coinControl->HasSelected()) + { + BOOST_FOREACH(const COutput& out, vCoins) + { + nValueRet += out.tx->vout[out.i].nValue; + setCoinsRet.insert(make_pair(out.tx, out.i)); + } + return (nValueRet >= nTargetValue); + } + + return (SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 6, vCoins, setCoinsRet, nValueRet) || + SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 1, vCoins, setCoinsRet, nValueRet) || + SelectCoinsMinConf(nTargetValue, nSpendTime, 0, 1, vCoins, setCoinsRet, nValueRet)); +} + +bool CWallet::CreateTransaction(const vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl* coinControl) +{ + int64 nValue = 0; + BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend) + { + if (nValue < 0) + return false; + nValue += s.second; + } + if (vecSend.empty() || nValue < 0) + return false; + + wtxNew.BindWallet(this); + + { + LOCK2(cs_main, cs_wallet); + // txdb must be opened before the mapWallet lock + CTxDB txdb("r"); + { + nFeeRet = nTransactionFee; + while (true) + { + wtxNew.vin.clear(); + wtxNew.vout.clear(); + wtxNew.fFromMe = true; + + int64 nTotalValue = nValue + nFeeRet; + double dPriority = 0; + // vouts to the payees + BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend) + wtxNew.vout.push_back(CTxOut(s.second, s.first)); + + // Choose coins to use + set > setCoins; + int64 nValueIn = 0; + if (!SelectCoins(nTotalValue, wtxNew.nTime, setCoins, nValueIn, coinControl)) + return false; + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + int64 nCredit = pcoin.first->vout[pcoin.second].nValue; + dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain(); + } + + int64 nChange = nValueIn - nValue - nFeeRet; + // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE + // or until nChange becomes zero + // NOTE: this depends on the exact behaviour of GetMinFee + if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT) + { + int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet); + nChange -= nMoveToFee; + nFeeRet += nMoveToFee; + } + + // ppcoin: sub-cent change is moved to fee + if (nChange > 0 && nChange < MIN_TXOUT_AMOUNT) + { + nFeeRet += nChange; + nChange = 0; + } + + if (nChange > 0) + { + + // Fill a vout to ourself + // TODO: pass in scriptChange instead of reservekey so + // change transaction isn't always pay-to-bitcoin-address + CScript scriptChange; + + // coin control: send change to custom address + if (coinControl && !boost::get(&coinControl->destChange)) + scriptChange.SetDestination(coinControl->destChange); + + // no coin control: send change to newly generated address + else + { + // Note: We use a new key here to keep it from being obvious which side is the change. + // The drawback is that by not reusing a previous key, the change may be lost if a + // backup is restored, if the backup doesn't have the new private key for the change. + // If we reused the old key, it would be possible to add code to look for and + // rediscover unknown transactions that were written with keys of ours to recover + // post-backup change. + + // Reserve a new key pair from key pool + CPubKey vchPubKey = reservekey.GetReservedKey(); + + scriptChange.SetDestination(vchPubKey.GetID()); + } + + // Insert change txn at random position: + vector::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()); + wtxNew.vout.insert(position, CTxOut(nChange, scriptChange)); + } + else + reservekey.ReturnKey(); + + // Fill vin + BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) + wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second)); + + // Sign + int nIn = 0; + BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) + if (!SignSignature(*this, *coin.first, wtxNew, nIn++)) + return false; + + // Limit size + unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION); + if (nBytes >= MAX_BLOCK_SIZE_GEN/5) + return false; + dPriority /= nBytes; + + // Check that enough fee is included + int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000); + int64 nMinFee = wtxNew.GetMinFee(1, false, GMF_SEND, nBytes); + + if (nFeeRet < max(nPayFee, nMinFee)) + { + nFeeRet = max(nPayFee, nMinFee); + continue; + } + + // Fill vtxPrev by copying from previous transactions vtxPrev + wtxNew.AddSupportingTransactions(txdb); + wtxNew.fTimeReceivedIsTxTime = true; + + break; + } + } + } + return true; +} + +bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl* coinControl) +{ + vector< pair > vecSend; + vecSend.push_back(make_pair(scriptPubKey, nValue)); + return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, coinControl); +} + +bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight) +{ + // Choose coins to use + int64 nBalance = GetBalance(); + + int64 nReserveBalance = 0; + if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) + return error("CreateCoinStake : invalid reserve balance amount"); + if (nBalance <= nReserveBalance) + return false; + + set > setCoins; + vector vwtxPrev; + int64 nValueIn = 0; + + if (!SelectCoins(nBalance - nReserveBalance, GetTime(), setCoins, nValueIn)) + return false; + + if (setCoins.empty()) + return false; + + CTxDB txdb("r"); + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + CTxIndex txindex; + { + LOCK2(cs_main, cs_wallet); + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + } + + int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)GetTime()); + CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60); + + // Weight is greater than zero + if (nTimeWeight > 0) + { + nWeight += bnCoinDayWeight.getuint64(); + } + + // Weight is greater than zero, but the maximum value isn't reached yet + if (nTimeWeight > 0 && nTimeWeight < nStakeMaxAge) + { + nMinWeight += bnCoinDayWeight.getuint64(); + } + + // Maximum weight was reached + if (nTimeWeight == nStakeMaxAge) + { + nMaxWeight += bnCoinDayWeight.getuint64(); + } + } + + return true; +} + +// ppcoin: create coin stake transaction +bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew) +{ + // The following split & combine thresholds are important to security + // Should not be adjusted if you don't understand the consequences + static unsigned int nStakeSplitAge = (60 * 60 * 24 * 30); + const CBlockIndex* pIndex0 = GetLastBlockIndex(pindexBest, false); + int64 nCombineThreshold = 0; + if(pIndex0->pprev) + nCombineThreshold = GetProofOfWorkReward(pIndex0->nHeight, MIN_TX_FEE, pIndex0->pprev->GetBlockHash()) / 3; + + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(nBits); + + txNew.vin.clear(); + txNew.vout.clear(); + // Mark coin stake transaction + CScript scriptEmpty; + scriptEmpty.clear(); + txNew.vout.push_back(CTxOut(0, scriptEmpty)); + // Choose coins to use + int64 nBalance = GetBalance(); + int64 nReserveBalance = 0; + if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) + return error("CreateCoinStake : invalid reserve balance amount"); + if (nBalance <= nReserveBalance) + return false; + + set > setCoins; + vector vwtxPrev; + int64 nValueIn = 0; + if (!SelectCoins(nBalance - nReserveBalance, txNew.nTime, setCoins, nValueIn)) + return false; + + if (setCoins.empty()) + return false; + + int64 nCredit = 0; + CScript scriptPubKeyKernel; + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + CTxDB txdb("r"); + CTxIndex txindex; + { + LOCK2(cs_main, cs_wallet); + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + } + + // Read block header + CBlock block; + { + LOCK2(cs_main, cs_wallet); + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + continue; + } + + static int nMaxStakeSearchInterval = 60; + + // printf(">> block.GetBlockTime() = %"PRI64d", nStakeMinAge = %d, txNew.nTime = %d\n", block.GetBlockTime(), nStakeMinAge,txNew.nTime); + if (block.GetBlockTime() + nStakeMinAge > txNew.nTime - nMaxStakeSearchInterval) + continue; // only count coins meeting min age requirement + + bool fKernelFound = false; + for (unsigned int n=0; n> In.....\n"); + // Search backward in time from the given txNew timestamp + // Search nSearchInterval seconds back up to nMaxStakeSearchInterval + uint256 hashProofOfStake = 0; + COutPoint prevoutStake = COutPoint(pcoin.first->GetHash(), pcoin.second); + if (CheckStakeKernelHash(nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, *pcoin.first, prevoutStake, txNew.nTime - n, hashProofOfStake)) + { + // Found a kernel + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : kernel found\n"); + vector vSolutions; + txnouttype whichType; + CScript scriptPubKeyOut; + scriptPubKeyKernel = pcoin.first->vout[pcoin.second].scriptPubKey; + if (!Solver(scriptPubKeyKernel, whichType, vSolutions)) + { + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : failed to parse kernel\n"); + break; + } + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : parsed kernel type=%d\n", whichType); + if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH) + { + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : no support for kernel type=%d\n", whichType); + break; // only support pay to public key and pay to address + } + if (whichType == TX_PUBKEYHASH) // pay to address type + { + // convert to pay to public key type + CKey key; + if (!keystore.GetKey(uint160(vSolutions[0]), key)) + { + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType); + break; // unable to find corresponding public key + } + scriptPubKeyOut << key.GetPubKey() << OP_CHECKSIG; + } + else + scriptPubKeyOut = scriptPubKeyKernel; + + txNew.nTime -= n; + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); + nCredit += pcoin.first->vout[pcoin.second].nValue; + + // printf(">> Wallet: CreateCoinStake: nCredit = %"PRI64d"\n", nCredit); + + vwtxPrev.push_back(pcoin.first); + txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); + if (block.GetBlockTime() + nStakeSplitAge > txNew.nTime) + txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); //split stake + + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : added kernel type=%d\n", whichType); + fKernelFound = true; + break; + } + } + if (fKernelFound || fShutdown) + break; // if kernel is found stop searching + } + if (nCredit == 0 || nCredit > nBalance - nReserveBalance) + { + // printf(">> Wallet: CreateCoinStake: nCredit = %"PRI64d", nBalance = %"PRI64d", nReserveBalance = %"PRI64d"\n", nCredit, nBalance, nReserveBalance); + return false; + } + + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + // Attempt to add more inputs + // Only add coins of the same key/address as kernel + if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey)) + && pcoin.first->GetHash() != txNew.vin[0].prevout.hash) + { + // Stop adding more inputs if already too many inputs + if (txNew.vin.size() >= 100) + break; + // Stop adding more inputs if value is already pretty significant + if (nCredit > nCombineThreshold) + break; + // Stop adding inputs if reached reserve limit + if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance) + break; + // Do not add additional significant input + if (pcoin.first->vout[pcoin.second].nValue > nCombineThreshold) + continue; + // Do not add input that is still too young + if (pcoin.first->nTime + nStakeMaxAge > txNew.nTime) + continue; + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); + nCredit += pcoin.first->vout[pcoin.second].nValue; + vwtxPrev.push_back(pcoin.first); + } + } + // Calculate coin age reward + { + uint64 nCoinAge; + CTxDB txdb("r"); + const CBlockIndex* pIndex0 = GetLastBlockIndex(pindexBest, false); + + if (!txNew.GetCoinAge(txdb, nCoinAge)) + return error("CreateCoinStake : failed to calculate coin age"); + nCredit += GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime, pIndex0->nHeight); + } + + int64 nMinFee = 0; + while (true) + { + // Set output amount + if (txNew.vout.size() == 3) + { + txNew.vout[1].nValue = ((nCredit - nMinFee) / 2 / CENT) * CENT; + txNew.vout[2].nValue = nCredit - nMinFee - txNew.vout[1].nValue; + } + else + txNew.vout[1].nValue = nCredit - nMinFee; + + // Sign + int nIn = 0; + BOOST_FOREACH(const CWalletTx* pcoin, vwtxPrev) + { + if (!SignSignature(*this, *pcoin, txNew, nIn++)) + return error("CreateCoinStake : failed to sign coinstake"); + } + + // Limit size + unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); + if (nBytes >= MAX_BLOCK_SIZE_GEN/5) + return error("CreateCoinStake : exceeded coinstake size limit"); + + // Check enough fee is paid + if (nMinFee < txNew.GetMinFee() - MIN_TX_FEE) + { + nMinFee = txNew.GetMinFee() - MIN_TX_FEE; + continue; // try signing again + } + else + { + if (fDebug && GetBoolArg("-printfee")) + printf("CreateCoinStake : fee for coinstake %s\n", FormatMoney(nMinFee).c_str()); + break; + } + } + + // Successfully generated coinstake + return true; +} + + +// Call after CreateTransaction unless you want to abort +bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) +{ + { + LOCK2(cs_main, cs_wallet); + printf("CommitTransaction:\n%s", wtxNew.ToString().c_str()); + { + // This is only to keep the database open to defeat the auto-flush for the + // duration of this scope. This is the only place where this optimization + // maybe makes sense; please don't do it anywhere else. + CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL; + + // Take key pair from key pool so it won't be used again + reservekey.KeepKey(); + + // Add tx to wallet, because if it has change it's also ours, + // otherwise just for transaction history. + AddToWallet(wtxNew); + + // Mark old coins as spent + set setCoins; + BOOST_FOREACH(const CTxIn& txin, wtxNew.vin) + { + CWalletTx &coin = mapWallet[txin.prevout.hash]; + coin.BindWallet(this); + coin.MarkSpent(txin.prevout.n); + coin.WriteToDisk(); + NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED); + } + + if (fFileBacked) + delete pwalletdb; + } + + // Track how many getdata requests our transaction gets + mapRequestCount[wtxNew.GetHash()] = 0; + + // Broadcast + if (!wtxNew.AcceptToMemoryPool()) + { + // This must not fail. The transaction has already been signed and recorded. + printf("CommitTransaction() : Error: Transaction not valid"); + return false; + } + wtxNew.RelayWalletTransaction(); + } + return true; +} + + + + +string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee) +{ + CReserveKey reservekey(this); + int64 nFeeRequired; + + if (IsLocked()) + { + string strError = _("Error: Wallet locked, unable to create transaction "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } + if (fWalletUnlockMintOnly) + { + string strError = _("Error: Wallet unlocked for block staking only, unable to create transaction."); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) + { + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str()); + else + strError = _("Error: Transaction creation failed "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } + + if (fAskFee && !uiInterface.ThreadSafeAskFee(nFeeRequired, _("Sending..."))) + return "ABORTED"; + + if (!CommitTransaction(wtxNew, reservekey)) + return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); + + return ""; +} + + + +string CWallet::SendMoneyToDestination(const CTxDestination& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee) +{ + // Check amount + if (nValue <= 0) + return _("Invalid amount"); + if (nValue + nTransactionFee > GetBalance()) + return _("Insufficient funds"); + + // Parse Bitcoin address + CScript scriptPubKey; + scriptPubKey.SetDestination(address); + + return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee); +} + + + + +DBErrors CWallet::LoadWallet(bool& fFirstRunRet) +{ + if (!fFileBacked) + return DB_LOAD_OK; + fFirstRunRet = false; + DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this); + if (nLoadWalletRet == DB_NEED_REWRITE) + { + if (CDB::Rewrite(strWalletFile, "\x04pool")) + { + setKeyPool.clear(); + // Note: can't top-up keypool here, because wallet is locked. + // User will be prompted to unlock wallet the next operation + // the requires a new key. + } + } + + if (nLoadWalletRet != DB_LOAD_OK) + return nLoadWalletRet; + fFirstRunRet = !vchDefaultKey.IsValid(); + + NewThread(ThreadFlushWalletDB, &strWalletFile); + return DB_LOAD_OK; +} + + +bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName) +{ + std::map::iterator mi = mapAddressBook.find(address); + mapAddressBook[address] = strName; + NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED); + if (!fFileBacked) + return false; + return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName); +} + +bool CWallet::DelAddressBookName(const CTxDestination& address) +{ + mapAddressBook.erase(address); + NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED); + if (!fFileBacked) + return false; + return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString()); +} + + +void CWallet::PrintWallet(const CBlock& block) +{ + { + LOCK(cs_wallet); + if (block.IsProofOfWork() && mapWallet.count(block.vtx[0].GetHash())) + { + CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()]; + printf(" mine: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); + } + if (block.IsProofOfStake() && mapWallet.count(block.vtx[1].GetHash())) + { + CWalletTx& wtx = mapWallet[block.vtx[1].GetHash()]; + printf(" stake: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); + } + + } + printf("\n"); +} + +bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx) +{ + { + LOCK(cs_wallet); + map::iterator mi = mapWallet.find(hashTx); + if (mi != mapWallet.end()) + { + wtx = (*mi).second; + return true; + } + } + return false; +} + +bool CWallet::SetDefaultKey(const CPubKey &vchPubKey) +{ + if (fFileBacked) + { + if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey)) + return false; + } + vchDefaultKey = vchPubKey; + return true; +} + +bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut) +{ + if (!pwallet->fFileBacked) + return false; + strWalletFileOut = pwallet->strWalletFile; + return true; +} + +// +// Mark old keypool keys as used, +// and generate all new keys +// +bool CWallet::NewKeyPool() +{ + { + LOCK(cs_wallet); + CWalletDB walletdb(strWalletFile); + BOOST_FOREACH(int64 nIndex, setKeyPool) + walletdb.ErasePool(nIndex); + setKeyPool.clear(); + + if (IsLocked()) + return false; + + int64 nKeys = max(GetArg("-keypool", 100), (int64)0); + for (int i = 0; i < nKeys; i++) + { + int64 nIndex = i+1; + walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey())); + setKeyPool.insert(nIndex); + } + printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys); + } + return true; +} + +bool CWallet::TopUpKeyPool() +{ + { + LOCK(cs_wallet); + + if (IsLocked()) + return false; + + CWalletDB walletdb(strWalletFile); + + // Top up key pool + unsigned int nTargetSize = max(GetArg("-keypool", 100), 0LL); + while (setKeyPool.size() < (nTargetSize + 1)) + { + int64 nEnd = 1; + if (!setKeyPool.empty()) + nEnd = *(--setKeyPool.end()) + 1; + if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) + throw runtime_error("TopUpKeyPool() : writing generated key failed"); + setKeyPool.insert(nEnd); + printf("keypool added key %"PRI64d", size=%"PRIszu"\n", nEnd, setKeyPool.size()); + } + } + return true; +} + +void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) +{ + nIndex = -1; + keypool.vchPubKey = CPubKey(); + { + LOCK(cs_wallet); + + if (!IsLocked()) + TopUpKeyPool(); + + // Get the oldest key + if(setKeyPool.empty()) + return; + + CWalletDB walletdb(strWalletFile); + + nIndex = *(setKeyPool.begin()); + setKeyPool.erase(setKeyPool.begin()); + if (!walletdb.ReadPool(nIndex, keypool)) + throw runtime_error("ReserveKeyFromKeyPool() : read failed"); + if (!HaveKey(keypool.vchPubKey.GetID())) + throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); + assert(keypool.vchPubKey.IsValid()); + if (fDebug && GetBoolArg("-printkeypool")) + printf("keypool reserve %"PRI64d"\n", nIndex); + } +} + +int64 CWallet::AddReserveKey(const CKeyPool& keypool) +{ + { + LOCK2(cs_main, cs_wallet); + CWalletDB walletdb(strWalletFile); + + int64 nIndex = 1 + *(--setKeyPool.end()); + if (!walletdb.WritePool(nIndex, keypool)) + throw runtime_error("AddReserveKey() : writing added key failed"); + setKeyPool.insert(nIndex); + return nIndex; + } + return -1; +} + +void CWallet::KeepKey(int64 nIndex) +{ + // Remove from key pool + if (fFileBacked) + { + CWalletDB walletdb(strWalletFile); + walletdb.ErasePool(nIndex); + } + if(fDebug) + printf("keypool keep %"PRI64d"\n", nIndex); +} + +void CWallet::ReturnKey(int64 nIndex) +{ + // Return to key pool + { + LOCK(cs_wallet); + setKeyPool.insert(nIndex); + } + //if(fDebug) + //printf("keypool return %"PRI64d"\n", nIndex); +} + +bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse) +{ + int64 nIndex = 0; + CKeyPool keypool; + { + LOCK(cs_wallet); + ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) + { + if (fAllowReuse && vchDefaultKey.IsValid()) + { + result = vchDefaultKey; + return true; + } + if (IsLocked()) return false; + result = GenerateNewKey(); + return true; + } + KeepKey(nIndex); + result = keypool.vchPubKey; + } + return true; +} + +int64 CWallet::GetOldestKeyPoolTime() +{ + int64 nIndex = 0; + CKeyPool keypool; + ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) + return GetTime(); + ReturnKey(nIndex); + return keypool.nTime; +} + +std::map CWallet::GetAddressBalances() +{ + map balances; + + { + LOCK(cs_wallet); + BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet) + { + CWalletTx *pcoin = &walletEntry.second; + + if (!pcoin->IsFinal() || !pcoin->IsConfirmed()) + continue; + + if ((pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetBlocksToMaturity() > 0) + continue; + + int nDepth = pcoin->GetDepthInMainChain(); + if (nDepth < (pcoin->IsFromMe() ? 0 : 1)) + continue; + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) + { + CTxDestination addr; + if (!IsMine(pcoin->vout[i])) + continue; + if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr)) + continue; + + int64 n = pcoin->IsSpent(i) ? 0 : pcoin->vout[i].nValue; + + if (!balances.count(addr)) + balances[addr] = 0; + balances[addr] += n; + } + } + } + + return balances; +} + +set< set > CWallet::GetAddressGroupings() +{ + set< set > groupings; + set grouping; + + BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet) + { + CWalletTx *pcoin = &walletEntry.second; + + if (pcoin->vin.size() > 0 && IsMine(pcoin->vin[0])) + { + // group all input addresses with each other + BOOST_FOREACH(CTxIn txin, pcoin->vin) + { + CTxDestination address; + if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address)) + continue; + grouping.insert(address); + } + + // group change with input addresses + BOOST_FOREACH(CTxOut txout, pcoin->vout) + if (IsChange(txout)) + { + CWalletTx tx = mapWallet[pcoin->vin[0].prevout.hash]; + CTxDestination txoutAddr; + if(!ExtractDestination(txout.scriptPubKey, txoutAddr)) + continue; + grouping.insert(txoutAddr); + } + groupings.insert(grouping); + grouping.clear(); + } + + // group lone addrs by themselves + for (unsigned int i = 0; i < pcoin->vout.size(); i++) + if (IsMine(pcoin->vout[i])) + { + CTxDestination address; + if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address)) + continue; + grouping.insert(address); + groupings.insert(grouping); + grouping.clear(); + } + } + + set< set* > uniqueGroupings; // a set of pointers to groups of addresses + map< CTxDestination, set* > setmap; // map addresses to the unique group containing it + BOOST_FOREACH(set grouping, groupings) + { + // make a set of all the groups hit by this new group + set< set* > hits; + map< CTxDestination, set* >::iterator it; + BOOST_FOREACH(CTxDestination address, grouping) + if ((it = setmap.find(address)) != setmap.end()) + hits.insert((*it).second); + + // merge all hit groups into a new single group and delete old groups + set* merged = new set(grouping); + BOOST_FOREACH(set* hit, hits) + { + merged->insert(hit->begin(), hit->end()); + uniqueGroupings.erase(hit); + delete hit; + } + uniqueGroupings.insert(merged); + + // update setmap + BOOST_FOREACH(CTxDestination element, *merged) + setmap[element] = merged; + } + + set< set > ret; + BOOST_FOREACH(set* uniqueGrouping, uniqueGroupings) + { + ret.insert(*uniqueGrouping); + delete uniqueGrouping; + } + + return ret; +} + +// ppcoin: check 'spent' consistency between wallet and txindex +// ppcoin: fix wallet spent state according to txindex +void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion, bool fCheckOnly) +{ + nMismatchFound = 0; + nBalanceInQuestion = 0; + + LOCK(cs_wallet); + vector vCoins; + vCoins.reserve(mapWallet.size()); + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + vCoins.push_back(&(*it).second); + + CTxDB txdb("r"); + BOOST_FOREACH(CWalletTx* pcoin, vCoins) + { + // Find the corresponding transaction index + CTxIndex txindex; + if (!txdb.ReadTxIndex(pcoin->GetHash(), txindex)) + continue; + for (unsigned int n=0; n < pcoin->vout.size(); n++) + { + if (IsMine(pcoin->vout[n]) && pcoin->IsSpent(n) && (txindex.vSpent.size() <= n || txindex.vSpent[n].IsNull())) + { + printf("FixSpentCoins found lost coin %sppc %s[%d], %s\n", + FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); + nMismatchFound++; + nBalanceInQuestion += pcoin->vout[n].nValue; + if (!fCheckOnly) + { + pcoin->MarkUnspent(n); + pcoin->WriteToDisk(); + } + } + else if (IsMine(pcoin->vout[n]) && !pcoin->IsSpent(n) && (txindex.vSpent.size() > n && !txindex.vSpent[n].IsNull())) + { + printf("FixSpentCoins found spent coin %sppc %s[%d], %s\n", + FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); + nMismatchFound++; + nBalanceInQuestion += pcoin->vout[n].nValue; + if (!fCheckOnly) + { + pcoin->MarkSpent(n); + pcoin->WriteToDisk(); + } + } + } + } +} + +// ppcoin: disable transaction (only for coinstake) +void CWallet::DisableTransaction(const CTransaction &tx) +{ + if (!tx.IsCoinStake() || !IsFromMe(tx)) + return; // only disconnecting coinstake requires marking input unspent + + LOCK(cs_wallet); + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + map::iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + CWalletTx& prev = (*mi).second; + if (txin.prevout.n < prev.vout.size() && IsMine(prev.vout[txin.prevout.n])) + { + prev.MarkUnspent(txin.prevout.n); + prev.WriteToDisk(); + } + } + } +} + +CPubKey CReserveKey::GetReservedKey() +{ + if (nIndex == -1) + { + CKeyPool keypool; + pwallet->ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex != -1) + vchPubKey = keypool.vchPubKey; + else + { + printf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!"); + vchPubKey = pwallet->vchDefaultKey; + } + } + assert(vchPubKey.IsValid()); + return vchPubKey; +} + +void CReserveKey::KeepKey() +{ + if (nIndex != -1) + pwallet->KeepKey(nIndex); + nIndex = -1; + vchPubKey = CPubKey(); +} + +void CReserveKey::ReturnKey() +{ + if (nIndex != -1) + pwallet->ReturnKey(nIndex); + nIndex = -1; + vchPubKey = CPubKey(); +} + +void CWallet::GetAllReserveKeys(set& setAddress) +{ + setAddress.clear(); + + CWalletDB walletdb(strWalletFile); + + LOCK2(cs_main, cs_wallet); + BOOST_FOREACH(const int64& id, setKeyPool) + { + CKeyPool keypool; + if (!walletdb.ReadPool(id, keypool)) + throw runtime_error("GetAllReserveKeyHashes() : read failed"); + assert(keypool.vchPubKey.IsValid()); + CKeyID keyID = keypool.vchPubKey.GetID(); + if (!HaveKey(keyID)) + throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool"); + setAddress.insert(keyID); + } +} + +void CWallet::UpdatedTransaction(const uint256 &hashTx) +{ + { + LOCK(cs_wallet); + // Only notify UI if this transaction is in this wallet + map::const_iterator mi = mapWallet.find(hashTx); + if (mi != mapWallet.end()) + NotifyTransactionChanged(this, hashTx, CT_UPDATED); + } +} diff --git a/src/wallet.h b/src/wallet.h new file mode 100644 index 0000000..899f95a --- /dev/null +++ b/src/wallet.h @@ -0,0 +1,861 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_WALLET_H +#define BITCOIN_WALLET_H + +#include +#include + +#include + +#include "main.h" +#include "key.h" +#include "keystore.h" +#include "script.h" +#include "ui_interface.h" +#include "util.h" +#include "walletdb.h" + +extern bool fWalletUnlockMintOnly; +class CAccountingEntry; +class CWalletTx; +class CReserveKey; +class COutput; +class CCoinControl; + +/** (client) version numbers for particular wallet features */ +enum WalletFeature +{ + FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output) + + FEATURE_WALLETCRYPT = 40000, // wallet encryption + FEATURE_COMPRPUBKEY = 60000, // compressed public keys + + FEATURE_LATEST = 60000 +}; + + +/** A key pool entry */ +class CKeyPool +{ +public: + int64 nTime; + CPubKey vchPubKey; + + CKeyPool() + { + nTime = GetTime(); + } + + CKeyPool(const CPubKey& vchPubKeyIn) + { + nTime = GetTime(); + vchPubKey = vchPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(nTime); + READWRITE(vchPubKey); + ) +}; + +/** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, + * and provides the ability to create new transactions. + */ +class CWallet : public CCryptoKeyStore +{ +private: + bool SelectCoins(int64 nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64& nValueRet, const CCoinControl *coinControl=NULL) const; + + CWalletDB *pwalletdbEncryption; + + // the current wallet version: clients below this version are not able to load the wallet + int nWalletVersion; + + // the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded + int nWalletMaxVersion; + +public: + mutable CCriticalSection cs_wallet; + + bool fFileBacked; + std::string strWalletFile; + + std::set setKeyPool; + + + typedef std::map MasterKeyMap; + MasterKeyMap mapMasterKeys; + unsigned int nMasterKeyMaxID; + + CWallet() + { + nWalletVersion = FEATURE_BASE; + nWalletMaxVersion = FEATURE_BASE; + fFileBacked = false; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; + nOrderPosNext = 0; + } + CWallet(std::string strWalletFileIn) + { + nWalletVersion = FEATURE_BASE; + nWalletMaxVersion = FEATURE_BASE; + strWalletFile = strWalletFileIn; + fFileBacked = true; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; + nOrderPosNext = 0; + } + + std::map mapWallet; + int64 nOrderPosNext; + std::map mapRequestCount; + + std::map mapAddressBook; + + CPubKey vchDefaultKey; + + // check whether we are allowed to upgrade (or already support) to the named feature + bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; } + + void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl=NULL) const; + bool SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, int64& nValueRet) const; + // keystore implementation + // Generate a new key + CPubKey GenerateNewKey(); + // Adds a key to the store, and saves it to disk. + bool AddKey(const CKey& key); + // Adds a key to the store, without saving it to disk (used by LoadWallet) + bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); } + + bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } + + // Adds an encrypted key to the store, and saves it to disk. + bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret); + // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) + bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } + bool AddCScript(const CScript& redeemScript); + bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); } + + bool Unlock(const SecureString& strWalletPassphrase); + bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); + bool EncryptWallet(const SecureString& strWalletPassphrase); + + /** Increment the next transaction order id + @return next transaction order id + */ + int64 IncOrderPosNext(CWalletDB *pwalletdb = NULL); + + typedef std::pair TxPair; + typedef std::multimap TxItems; + + /** Get the wallet's activity log + @return multimap of ordered transactions and accounting entries + @warning Returned pointers are *only* valid within the scope of passed acentries + */ + TxItems OrderedTxItems(std::list& acentries, std::string strAccount = ""); + + void MarkDirty(); + bool AddToWallet(const CWalletTx& wtxIn); + bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false); + bool EraseFromWallet(uint256 hash); + void WalletUpdateSpent(const CTransaction& prevout); + int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); + int ScanForWalletTransaction(const uint256& hashTx); + void ReacceptWalletTransactions(); + void ResendWalletTransactions(); + int64 GetBalance() const; + int64 GetUnconfirmedBalance() const; + int64 GetImmatureBalance() const; + int64 GetStake() const; + int64 GetNewMint() const; + bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl *coinControl=NULL); + bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl *coinControl=NULL); + bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); + bool GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight); + bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew); + std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + + bool NewKeyPool(); + bool TopUpKeyPool(); + int64 AddReserveKey(const CKeyPool& keypool); + void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); + void KeepKey(int64 nIndex); + void ReturnKey(int64 nIndex); + bool GetKeyFromPool(CPubKey &key, bool fAllowReuse=true); + int64 GetOldestKeyPoolTime(); + void GetAllReserveKeys(std::set& setAddress); + + std::set< std::set > GetAddressGroupings(); + std::map GetAddressBalances(); + + bool IsMine(const CTxIn& txin) const; + int64 GetDebit(const CTxIn& txin) const; + bool IsMine(const CTxOut& txout) const + { + return ::IsMine(*this, txout.scriptPubKey); + } + int64 GetCredit(const CTxOut& txout) const + { + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetCredit() : value out of range"); + return (IsMine(txout) ? txout.nValue : 0); + } + bool IsChange(const CTxOut& txout) const; + int64 GetChange(const CTxOut& txout) const + { + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetChange() : value out of range"); + return (IsChange(txout) ? txout.nValue : 0); + } + bool IsMine(const CTransaction& tx) const + { + BOOST_FOREACH(const CTxOut& txout, tx.vout) + if (IsMine(txout)) + return true; + return false; + } + bool IsFromMe(const CTransaction& tx) const + { + return (GetDebit(tx) > 0); + } + int64 GetDebit(const CTransaction& tx) const + { + int64 nDebit = 0; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + nDebit += GetDebit(txin); + if (!MoneyRange(nDebit)) + throw std::runtime_error("CWallet::GetDebit() : value out of range"); + } + return nDebit; + } + int64 GetCredit(const CTransaction& tx) const + { + int64 nCredit = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nCredit += GetCredit(txout); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWallet::GetCredit() : value out of range"); + } + return nCredit; + } + int64 GetChange(const CTransaction& tx) const + { + int64 nChange = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nChange += GetChange(txout); + if (!MoneyRange(nChange)) + throw std::runtime_error("CWallet::GetChange() : value out of range"); + } + return nChange; + } + void SetBestChain(const CBlockLocator& loc); + + DBErrors LoadWallet(bool& fFirstRunRet); + + bool SetAddressBookName(const CTxDestination& address, const std::string& strName); + + bool DelAddressBookName(const CTxDestination& address); + + void UpdatedTransaction(const uint256 &hashTx); + + void PrintWallet(const CBlock& block); + + void Inventory(const uint256 &hash) + { + { + LOCK(cs_wallet); + std::map::iterator mi = mapRequestCount.find(hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } + } + + int GetKeyPoolSize() + { + return setKeyPool.size(); + } + + bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); + + bool SetDefaultKey(const CPubKey &vchPubKey); + + // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower + bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false); + + // change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format) + bool SetMaxVersion(int nVersion); + + // get the current wallet format (the oldest client version guaranteed to understand this wallet) + int GetVersion() { return nWalletVersion; } + + void FixSpentCoins(int& nMismatchSpent, int64& nBalanceInQuestion, bool fCheckOnly = false); + void DisableTransaction(const CTransaction &tx); + + /** Address book entry changed. + * @note called with lock cs_wallet held. + */ + boost::signals2::signal NotifyAddressBookChanged; + + /** Wallet transaction added, removed or updated. + * @note called with lock cs_wallet held. + */ + boost::signals2::signal NotifyTransactionChanged; +}; + +/** A key allocated from the key pool. */ +class CReserveKey +{ +protected: + CWallet* pwallet; + int64 nIndex; + CPubKey vchPubKey; +public: + CReserveKey(CWallet* pwalletIn) + { + nIndex = -1; + pwallet = pwalletIn; + } + + ~CReserveKey() + { + if (!fShutdown) + ReturnKey(); + } + + void ReturnKey(); + CPubKey GetReservedKey(); + void KeepKey(); +}; + + +typedef std::map mapValue_t; + + +static void ReadOrderPos(int64& nOrderPos, mapValue_t& mapValue) +{ + if (!mapValue.count("n")) + { + nOrderPos = -1; // TODO: calculate elsewhere + return; + } + nOrderPos = atoi64(mapValue["n"].c_str()); +} + + +static void WriteOrderPos(const int64& nOrderPos, mapValue_t& mapValue) +{ + if (nOrderPos == -1) + return; + mapValue["n"] = i64tostr(nOrderPos); +} + + +/** A transaction with a bunch of additional info that only the owner cares about. + * It includes any unrecorded transactions needed to link it back to the block chain. + */ +class CWalletTx : public CMerkleTx +{ +private: + const CWallet* pwallet; + +public: + std::vector vtxPrev; + mapValue_t mapValue; + std::vector > vOrderForm; + unsigned int fTimeReceivedIsTxTime; + unsigned int nTimeReceived; // time received by this node + unsigned int nTimeSmart; + char fFromMe; + std::string strFromAccount; + std::vector vfSpent; // which outputs are already spent + int64 nOrderPos; // position in ordered transaction list + + // memory only + mutable bool fDebitCached; + mutable bool fCreditCached; + mutable bool fAvailableCreditCached; + mutable bool fChangeCached; + mutable int64 nDebitCached; + mutable int64 nCreditCached; + mutable int64 nAvailableCreditCached; + mutable int64 nChangeCached; + + CWalletTx() + { + Init(NULL); + } + + CWalletTx(const CWallet* pwalletIn) + { + Init(pwalletIn); + } + + CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn) + { + Init(pwalletIn); + } + + CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn) + { + Init(pwalletIn); + } + + void Init(const CWallet* pwalletIn) + { + pwallet = pwalletIn; + vtxPrev.clear(); + mapValue.clear(); + vOrderForm.clear(); + fTimeReceivedIsTxTime = false; + nTimeReceived = 0; + nTimeSmart = 0; + fFromMe = false; + strFromAccount.clear(); + vfSpent.clear(); + fDebitCached = false; + fCreditCached = false; + fAvailableCreditCached = false; + fChangeCached = false; + nDebitCached = 0; + nCreditCached = 0; + nAvailableCreditCached = 0; + nChangeCached = 0; + nOrderPos = -1; + } + + IMPLEMENT_SERIALIZE + ( + CWalletTx* pthis = const_cast(this); + if (fRead) + pthis->Init(NULL); + char fSpent = false; + + if (!fRead) + { + pthis->mapValue["fromaccount"] = pthis->strFromAccount; + + std::string str; + BOOST_FOREACH(char f, vfSpent) + { + str += (f ? '1' : '0'); + if (f) + fSpent = true; + } + pthis->mapValue["spent"] = str; + + WriteOrderPos(pthis->nOrderPos, pthis->mapValue); + + if (nTimeSmart) + pthis->mapValue["timesmart"] = strprintf("%u", nTimeSmart); + } + + nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action); + READWRITE(vtxPrev); + READWRITE(mapValue); + READWRITE(vOrderForm); + READWRITE(fTimeReceivedIsTxTime); + READWRITE(nTimeReceived); + READWRITE(fFromMe); + READWRITE(fSpent); + + if (fRead) + { + pthis->strFromAccount = pthis->mapValue["fromaccount"]; + + if (mapValue.count("spent")) + BOOST_FOREACH(char c, pthis->mapValue["spent"]) + pthis->vfSpent.push_back(c != '0'); + else + pthis->vfSpent.assign(vout.size(), fSpent); + + ReadOrderPos(pthis->nOrderPos, pthis->mapValue); + + pthis->nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(pthis->mapValue["timesmart"]) : 0; + } + + pthis->mapValue.erase("fromaccount"); + pthis->mapValue.erase("version"); + pthis->mapValue.erase("spent"); + pthis->mapValue.erase("n"); + pthis->mapValue.erase("timesmart"); + ) + + // marks certain txout's as spent + // returns true if any update took place + bool UpdateSpent(const std::vector& vfNewSpent) + { + bool fReturn = false; + for (unsigned int i = 0; i < vfNewSpent.size(); i++) + { + if (i == vfSpent.size()) + break; + + if (vfNewSpent[i] && !vfSpent[i]) + { + vfSpent[i] = true; + fReturn = true; + fAvailableCreditCached = false; + } + } + return fReturn; + } + + // make sure balances are recalculated + void MarkDirty() + { + fCreditCached = false; + fAvailableCreditCached = false; + fDebitCached = false; + fChangeCached = false; + } + + void BindWallet(CWallet *pwalletIn) + { + pwallet = pwalletIn; + MarkDirty(); + } + + void MarkSpent(unsigned int nOut) + { + if (nOut >= vout.size()) + throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range"); + vfSpent.resize(vout.size()); + if (!vfSpent[nOut]) + { + vfSpent[nOut] = true; + fAvailableCreditCached = false; + } + } + + void MarkUnspent(unsigned int nOut) + { + if (nOut >= vout.size()) + throw std::runtime_error("CWalletTx::MarkUnspent() : nOut out of range"); + vfSpent.resize(vout.size()); + if (vfSpent[nOut]) + { + vfSpent[nOut] = false; + fAvailableCreditCached = false; + } + } + + bool IsSpent(unsigned int nOut) const + { + if (nOut >= vout.size()) + throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range"); + if (nOut >= vfSpent.size()) + return false; + return (!!vfSpent[nOut]); + } + + int64 GetDebit() const + { + if (vin.empty()) + return 0; + if (fDebitCached) + return nDebitCached; + nDebitCached = pwallet->GetDebit(*this); + fDebitCached = true; + return nDebitCached; + } + + int64 GetCredit(bool fUseCache=true) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0) + return 0; + + // GetBalance can assume transactions in mapWallet won't change + if (fUseCache && fCreditCached) + return nCreditCached; + nCreditCached = pwallet->GetCredit(*this); + fCreditCached = true; + return nCreditCached; + } + + int64 GetAvailableCredit(bool fUseCache=true) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0) + return 0; + + if (fUseCache && fAvailableCreditCached) + return nAvailableCreditCached; + + int64 nCredit = 0; + for (unsigned int i = 0; i < vout.size(); i++) + { + if (!IsSpent(i)) + { + const CTxOut &txout = vout[i]; + nCredit += pwallet->GetCredit(txout); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + } + } + + nAvailableCreditCached = nCredit; + fAvailableCreditCached = true; + return nCredit; + } + + + int64 GetChange() const + { + if (fChangeCached) + return nChangeCached; + nChangeCached = pwallet->GetChange(*this); + fChangeCached = true; + return nChangeCached; + } + + void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list >& listReceived, + std::list >& listSent, int64& nFee, std::string& strSentAccount) const; + + void GetAccountAmounts(const std::string& strAccount, int64& nGeneratedImmature, int64& nGeneratedMature, int64& nReceived, + int64& nSent, int64& nFee) const; + + bool IsFromMe() const + { + return (GetDebit() > 0); + } + + bool IsConfirmed() const + { + // Quick answer in most cases + if (!IsFinal()) + return false; + if (GetDepthInMainChain() >= 1) + return true; + if (!IsFromMe()) // using wtx's cached debit + return false; + + // If no confirmations but it's from us, we can still + // consider it confirmed if all dependencies are confirmed + std::map mapPrev; + std::vector vWorkQueue; + vWorkQueue.reserve(vtxPrev.size()+1); + vWorkQueue.push_back(this); + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + const CMerkleTx* ptx = vWorkQueue[i]; + + if (!ptx->IsFinal()) + return false; + if (ptx->GetDepthInMainChain() >= 1) + continue; + if (!pwallet->IsFromMe(*ptx)) + return false; + + if (mapPrev.empty()) + { + BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) + mapPrev[tx.GetHash()] = &tx; + } + + BOOST_FOREACH(const CTxIn& txin, ptx->vin) + { + if (!mapPrev.count(txin.prevout.hash)) + return false; + vWorkQueue.push_back(mapPrev[txin.prevout.hash]); + } + } + return true; + } + + bool WriteToDisk(); + + int64 GetTxTime() const; + int GetRequestCount() const; + + void AddSupportingTransactions(CTxDB& txdb); + + bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptWalletTransaction(); + + void RelayWalletTransaction(CTxDB& txdb); + void RelayWalletTransaction(); +}; + + + + +class COutput +{ +public: + const CWalletTx *tx; + int i; + int nDepth; + + COutput(const CWalletTx *txIn, int iIn, int nDepthIn) + { + tx = txIn; i = iIn; nDepth = nDepthIn; + } + + std::string ToString() const + { + return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString().substr(0,10).c_str(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +/** Private key that includes an expiration date in case it never gets used. */ +class CWalletKey +{ +public: + CPrivKey vchPrivKey; + int64 nTimeCreated; + int64 nTimeExpires; + std::string strComment; + //// todo: add something to note what created it (user, getnewaddress, change) + //// maybe should have a map property map + + CWalletKey(int64 nExpires=0) + { + nTimeCreated = (nExpires ? GetTime() : 0); + nTimeExpires = nExpires; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPrivKey); + READWRITE(nTimeCreated); + READWRITE(nTimeExpires); + READWRITE(strComment); + ) +}; + + + + + + +/** Account information. + * Stored in wallet with key "acc"+string account name. + */ +class CAccount +{ +public: + CPubKey vchPubKey; + + CAccount() + { + SetNull(); + } + + void SetNull() + { + vchPubKey = CPubKey(); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPubKey); + ) +}; + + + +/** Internal transfers. + * Database key is acentry. + */ +class CAccountingEntry +{ +public: + std::string strAccount; + int64 nCreditDebit; + int64 nTime; + std::string strOtherAccount; + std::string strComment; + mapValue_t mapValue; + int64 nOrderPos; // position in ordered transaction list + uint64 nEntryNo; + + CAccountingEntry() + { + SetNull(); + } + + void SetNull() + { + nCreditDebit = 0; + nTime = 0; + strAccount.clear(); + strOtherAccount.clear(); + strComment.clear(); + nOrderPos = -1; + } + + IMPLEMENT_SERIALIZE + ( + CAccountingEntry& me = *const_cast(this); + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + // Note: strAccount is serialized as part of the key, not here. + READWRITE(nCreditDebit); + READWRITE(nTime); + READWRITE(strOtherAccount); + + if (!fRead) + { + WriteOrderPos(nOrderPos, me.mapValue); + + if (!(mapValue.empty() && _ssExtra.empty())) + { + CDataStream ss(nType, nVersion); + ss.insert(ss.begin(), '\0'); + ss << mapValue; + ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); + me.strComment.append(ss.str()); + } + } + + READWRITE(strComment); + + size_t nSepPos = strComment.find("\0", 0, 1); + if (fRead) + { + me.mapValue.clear(); + if (std::string::npos != nSepPos) + { + CDataStream ss(std::vector(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); + ss >> me.mapValue; + me._ssExtra = std::vector(ss.begin(), ss.end()); + } + ReadOrderPos(me.nOrderPos, me.mapValue); + } + if (std::string::npos != nSepPos) + me.strComment.erase(nSepPos); + + me.mapValue.erase("n"); + ) + +private: + std::vector _ssExtra; +}; + +bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); + +#endif diff --git a/src/walletdb.cpp b/src/walletdb.cpp new file mode 100644 index 0000000..692a07c --- /dev/null +++ b/src/walletdb.cpp @@ -0,0 +1,676 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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 "walletdb.h" +#include "wallet.h" +#include + +using namespace std; +using namespace boost; + + +static uint64 nAccountingEntryNumber = 0; +extern bool fWalletUnlockMintOnly; + +// +// CWalletDB +// + +bool CWalletDB::WriteName(const string& strAddress, const string& strName) +{ + nWalletDBUpdated++; + return Write(make_pair(string("name"), strAddress), strName); +} + +bool CWalletDB::EraseName(const string& strAddress) +{ + // This should only be used for sending addresses, never for receiving addresses, + // receiving addresses must always have an address book entry if they're not change return. + nWalletDBUpdated++; + return Erase(make_pair(string("name"), strAddress)); +} + +bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account) +{ + account.SetNull(); + return Read(make_pair(string("acc"), strAccount), account); +} + +bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account) +{ + return Write(make_pair(string("acc"), strAccount), account); +} + +bool CWalletDB::WriteAccountingEntry(const uint64 nAccEntryNum, const CAccountingEntry& acentry) +{ + return Write(boost::make_tuple(string("acentry"), acentry.strAccount, nAccEntryNum), acentry); +} + +bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) +{ + return WriteAccountingEntry(++nAccountingEntryNumber, acentry); +} + +int64 CWalletDB::GetAccountCreditDebit(const string& strAccount) +{ + list entries; + ListAccountCreditDebit(strAccount, entries); + + int64 nCreditDebit = 0; + BOOST_FOREACH (const CAccountingEntry& entry, entries) + nCreditDebit += entry.nCreditDebit; + + return nCreditDebit; +} + +void CWalletDB::ListAccountCreditDebit(const string& strAccount, list& entries) +{ + bool fAllAccounts = (strAccount == "*"); + + Dbc* pcursor = GetCursor(); + if (!pcursor) + throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor"); + unsigned int fFlags = DB_SET_RANGE; + while(true) + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + if (fFlags == DB_SET_RANGE) + ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64(0)); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + pcursor->close(); + throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB"); + } + + // Unserialize + string strType; + ssKey >> strType; + if (strType != "acentry") + break; + CAccountingEntry acentry; + ssKey >> acentry.strAccount; + if (!fAllAccounts && acentry.strAccount != strAccount) + break; + + ssValue >> acentry; + ssKey >> acentry.nEntryNo; + entries.push_back(acentry); + } + + pcursor->close(); +} + + +DBErrors +CWalletDB::ReorderTransactions(CWallet* pwallet) +{ + LOCK(pwallet->cs_wallet); + // Old wallets didn't have any defined order for transactions + // Probably a bad idea to change the output of this + + // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap. + typedef pair TxPair; + typedef multimap TxItems; + TxItems txByTime; + + for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) + { + CWalletTx* wtx = &((*it).second); + txByTime.insert(make_pair(wtx->nTimeReceived, TxPair(wtx, (CAccountingEntry*)0))); + } + list acentries; + ListAccountCreditDebit("", acentries); + BOOST_FOREACH(CAccountingEntry& entry, acentries) + { + txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); + } + + int64& nOrderPosNext = pwallet->nOrderPosNext; + nOrderPosNext = 0; + std::vector nOrderPosOffsets; + for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + CAccountingEntry *const pacentry = (*it).second.second; + int64& nOrderPos = (pwtx != 0) ? pwtx->nOrderPos : pacentry->nOrderPos; + + if (nOrderPos == -1) + { + nOrderPos = nOrderPosNext++; + nOrderPosOffsets.push_back(nOrderPos); + + if (pacentry) + // Have to write accounting regardless, since we don't keep it in memory + if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) + return DB_LOAD_FAIL; + } + else + { + int64 nOrderPosOff = 0; + BOOST_FOREACH(const int64& nOffsetStart, nOrderPosOffsets) + { + if (nOrderPos >= nOffsetStart) + ++nOrderPosOff; + } + nOrderPos += nOrderPosOff; + nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1); + + if (!nOrderPosOff) + continue; + + // Since we're changing the order, write it back + if (pwtx) + { + if (!WriteTx(pwtx->GetHash(), *pwtx)) + return DB_LOAD_FAIL; + } + else + if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) + return DB_LOAD_FAIL; + } + } + + return DB_LOAD_OK; +} + + +bool +ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, + int& nFileVersion, vector& vWalletUpgrade, + bool& fIsEncrypted, bool& fAnyUnordered, string& strType, string& strErr) +{ + try { + // Unserialize + // Taking advantage of the fact that pair serialization + // is just the two items serialized one after the other + ssKey >> strType; + if (strType == "name") + { + string strAddress; + ssKey >> strAddress; + ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()]; + } + else if (strType == "tx") + { + uint256 hash; + ssKey >> hash; + CWalletTx& wtx = pwallet->mapWallet[hash]; + ssValue >> wtx; + if (wtx.CheckTransaction() && (wtx.GetHash() == hash)) + wtx.BindWallet(pwallet); + else + { + pwallet->mapWallet.erase(hash); + return false; + } + + // Undo serialize changes in 31600 + if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703) + { + if (!ssValue.empty()) + { + char fTmp; + char fUnused; + ssValue >> fTmp >> fUnused >> wtx.strFromAccount; + strErr = strprintf("LoadWallet() upgrading tx ver=%d %d '%s' %s", + wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount.c_str(), hash.ToString().c_str()); + wtx.fTimeReceivedIsTxTime = fTmp; + } + else + { + strErr = strprintf("LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString().c_str()); + wtx.fTimeReceivedIsTxTime = 0; + } + vWalletUpgrade.push_back(hash); + } + + if (wtx.nOrderPos == -1) + fAnyUnordered = true; + + //// debug print + //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); + //printf(" %12"PRI64d" %s %s %s\n", + // wtx.vout[0].nValue, + // DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()).c_str(), + // wtx.hashBlock.ToString().substr(0,20).c_str(), + // wtx.mapValue["message"].c_str()); + } + else if (strType == "acentry") + { + string strAccount; + ssKey >> strAccount; + uint64 nNumber; + ssKey >> nNumber; + if (nNumber > nAccountingEntryNumber) + nAccountingEntryNumber = nNumber; + + if (!fAnyUnordered) + { + CAccountingEntry acentry; + ssValue >> acentry; + if (acentry.nOrderPos == -1) + fAnyUnordered = true; + } + } + else if (strType == "key" || strType == "wkey") + { + vector vchPubKey; + ssKey >> vchPubKey; + CKey key; + if (strType == "key") + { + CPrivKey pkey; + ssValue >> pkey; + key.SetPubKey(vchPubKey); + if (!key.SetPrivKey(pkey)) + { + strErr = "Error reading wallet database: CPrivKey corrupt"; + return false; + } + if (key.GetPubKey() != vchPubKey) + { + strErr = "Error reading wallet database: CPrivKey pubkey inconsistency"; + return false; + } + if (!key.IsValid()) + { + strErr = "Error reading wallet database: invalid CPrivKey"; + return false; + } + } + else + { + CWalletKey wkey; + ssValue >> wkey; + key.SetPubKey(vchPubKey); + if (!key.SetPrivKey(wkey.vchPrivKey)) + { + strErr = "Error reading wallet database: CPrivKey corrupt"; + return false; + } + if (key.GetPubKey() != vchPubKey) + { + strErr = "Error reading wallet database: CWalletKey pubkey inconsistency"; + return false; + } + if (!key.IsValid()) + { + strErr = "Error reading wallet database: invalid CWalletKey"; + return false; + } + } + if (!pwallet->LoadKey(key)) + { + strErr = "Error reading wallet database: LoadKey failed"; + return false; + } + } + else if (strType == "mkey") + { + unsigned int nID; + ssKey >> nID; + CMasterKey kMasterKey; + ssValue >> kMasterKey; + if(pwallet->mapMasterKeys.count(nID) != 0) + { + strErr = strprintf("Error reading wallet database: duplicate CMasterKey id %u", nID); + return false; + } + pwallet->mapMasterKeys[nID] = kMasterKey; + if (pwallet->nMasterKeyMaxID < nID) + pwallet->nMasterKeyMaxID = nID; + } + else if (strType == "ckey") + { + vector vchPubKey; + ssKey >> vchPubKey; + vector vchPrivKey; + ssValue >> vchPrivKey; + if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey)) + { + strErr = "Error reading wallet database: LoadCryptedKey failed"; + return false; + } + fIsEncrypted = true; + } + else if (strType == "defaultkey") + { + ssValue >> pwallet->vchDefaultKey; + } + else if (strType == "pool") + { + int64 nIndex; + ssKey >> nIndex; + pwallet->setKeyPool.insert(nIndex); + } + else if (strType == "version") + { + ssValue >> nFileVersion; + if (nFileVersion == 10300) + nFileVersion = 300; + } + else if (strType == "cscript") + { + uint160 hash; + ssKey >> hash; + CScript script; + ssValue >> script; + if (!pwallet->LoadCScript(script)) + { + strErr = "Error reading wallet database: LoadCScript failed"; + return false; + } + } + else if (strType == "orderposnext") + { + ssValue >> pwallet->nOrderPosNext; + } + } catch (...) + { + return false; + } + return true; +} + +static bool IsKeyType(string strType) +{ + return (strType== "key" || strType == "wkey" || + strType == "mkey" || strType == "ckey"); +} + +DBErrors CWalletDB::LoadWallet(CWallet* pwallet) +{ + pwallet->vchDefaultKey = CPubKey(); + int nFileVersion = 0; + vector vWalletUpgrade; + bool fIsEncrypted = false; + bool fAnyUnordered = false; + bool fNoncriticalErrors = false; + DBErrors result = DB_LOAD_OK; + + try { + LOCK(pwallet->cs_wallet); + int nMinVersion = 0; + if (Read((string)"minversion", nMinVersion)) + { + if (nMinVersion > CLIENT_VERSION) + return DB_TOO_NEW; + pwallet->LoadMinVersion(nMinVersion); + } + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + { + printf("Error getting wallet database cursor\n"); + return DB_CORRUPT; + } + + while(true) + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + printf("Error reading next record from wallet database\n"); + return DB_CORRUPT; + } + + // Try to be tolerant of single corrupt records: + string strType, strErr; + if (!ReadKeyValue(pwallet, ssKey, ssValue, nFileVersion, + vWalletUpgrade, fIsEncrypted, fAnyUnordered, strType, strErr)) + { + // losing keys is considered a catastrophic error, anything else + // we assume the user can live with: + if (IsKeyType(strType)) + result = DB_CORRUPT; + else + { + // Leave other errors alone, if we try to fix them we might make things worse. + fNoncriticalErrors = true; // ... but do warn the user there is something wrong. + if (strType == "tx") + // Rescan if there is a bad transaction record: + SoftSetBoolArg("-rescan", true); + } + } + if (!strErr.empty()) + printf("%s\n", strErr.c_str()); + } + pcursor->close(); + } + catch (...) + { + result = DB_CORRUPT; + } + + if (fNoncriticalErrors && result == DB_LOAD_OK) + result = DB_NONCRITICAL_ERROR; + + // Any wallet corruption at all: skip any rewriting or + // upgrading, we don't want to make it worse. + if (result != DB_LOAD_OK) + return result; + + printf("nFileVersion = %d\n", nFileVersion); + + BOOST_FOREACH(uint256 hash, vWalletUpgrade) + WriteTx(hash, pwallet->mapWallet[hash]); + + // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc: + if (fIsEncrypted && (nFileVersion == 40000 || nFileVersion == 50000)) + return DB_NEED_REWRITE; + + if (nFileVersion < CLIENT_VERSION) // Update + WriteVersion(CLIENT_VERSION); + + if (fAnyUnordered) + result = ReorderTransactions(pwallet); + + return result; +} + +void ThreadFlushWalletDB(void* parg) +{ + // Make this thread recognisable as the wallet flushing thread + RenameThread("bitcoin-wallet"); + + const string& strFile = ((const string*)parg)[0]; + static bool fOneThread; + if (fOneThread) + return; + fOneThread = true; + if (!GetBoolArg("-flushwallet", true)) + return; + + unsigned int nLastSeen = nWalletDBUpdated; + unsigned int nLastFlushed = nWalletDBUpdated; + int64 nLastWalletUpdate = GetTime(); + while (!fShutdown) + { + Sleep(500); + + if (nLastSeen != nWalletDBUpdated) + { + nLastSeen = nWalletDBUpdated; + nLastWalletUpdate = GetTime(); + } + + if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) + { + TRY_LOCK(bitdb.cs_db,lockDb); + if (lockDb) + { + // Don't do this if any databases are in use + int nRefCount = 0; + map::iterator mi = bitdb.mapFileUseCount.begin(); + while (mi != bitdb.mapFileUseCount.end()) + { + nRefCount += (*mi).second; + mi++; + } + + if (nRefCount == 0 && !fShutdown) + { + map::iterator mi = bitdb.mapFileUseCount.find(strFile); + if (mi != bitdb.mapFileUseCount.end()) + { + printf("Flushing wallet.dat\n"); + nLastFlushed = nWalletDBUpdated; + int64 nStart = GetTimeMillis(); + + // Flush wallet.dat so it's self contained + bitdb.CloseDb(strFile); + bitdb.CheckpointLSN(strFile); + + bitdb.mapFileUseCount.erase(mi++); + printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); + } + } + } + } + } +} + +bool BackupWallet(const CWallet& wallet, const string& strDest) +{ + if (!wallet.fFileBacked) + return false; + while (!fShutdown) + { + { + LOCK(bitdb.cs_db); + if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0) + { + // Flush log data to the dat file + bitdb.CloseDb(wallet.strWalletFile); + bitdb.CheckpointLSN(wallet.strWalletFile); + bitdb.mapFileUseCount.erase(wallet.strWalletFile); + + // Copy wallet.dat + filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; + filesystem::path pathDest(strDest); + if (filesystem::is_directory(pathDest)) + pathDest /= wallet.strWalletFile; + + try { +#if BOOST_VERSION >= 104000 + filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists); +#else + filesystem::copy_file(pathSrc, pathDest); +#endif + printf("copied wallet.dat to %s\n", pathDest.string().c_str()); + return true; + } catch(const filesystem::filesystem_error &e) { + printf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what()); + return false; + } + } + } + Sleep(100); + } + return false; +} + +// +// Try to (very carefully!) recover wallet.dat if there is a problem. +// +bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) +{ + // Recovery procedure: + // move wallet.dat to wallet.timestamp.bak + // Call Salvage with fAggressive=true to + // get as much data as possible. + // Rewrite salvaged data to wallet.dat + // Set -rescan so any missing transactions will be + // found. + int64 now = GetTime(); + std::string newFilename = strprintf("wallet.%"PRI64d".bak", now); + + int result = dbenv.dbenv.dbrename(NULL, filename.c_str(), NULL, + newFilename.c_str(), DB_AUTO_COMMIT); + if (result == 0) + printf("Renamed %s to %s\n", filename.c_str(), newFilename.c_str()); + else + { + printf("Failed to rename %s to %s\n", filename.c_str(), newFilename.c_str()); + return false; + } + + std::vector salvagedData; + bool allOK = dbenv.Salvage(newFilename, true, salvagedData); + if (salvagedData.empty()) + { + printf("Salvage(aggressive) found no records in %s.\n", newFilename.c_str()); + return false; + } + printf("Salvage(aggressive) found %"PRIszu" records\n", salvagedData.size()); + + bool fSuccess = allOK; + Db* pdbCopy = new Db(&dbenv.dbenv, 0); + int ret = pdbCopy->open(NULL, // Txn pointer + filename.c_str(), // Filename + "main", // Logical db name + DB_BTREE, // Database type + DB_CREATE, // Flags + 0); + if (ret > 0) + { + printf("Cannot create database file %s\n", filename.c_str()); + return false; + } + CWallet dummyWallet; + int nFileVersion = 0; + vector vWalletUpgrade; + bool fIsEncrypted = false; + bool fAnyUnordered = false; + + DbTxn* ptxn = dbenv.TxnBegin(); + BOOST_FOREACH(CDBEnv::KeyValPair& row, salvagedData) + { + if (fOnlyKeys) + { + CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION); + CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION); + string strType, strErr; + bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, + nFileVersion, vWalletUpgrade, + fIsEncrypted, fAnyUnordered, + strType, strErr); + if (!IsKeyType(strType)) + continue; + if (!fReadOK) + { + printf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType.c_str(), strErr.c_str()); + continue; + } + } + Dbt datKey(&row.first[0], row.first.size()); + Dbt datValue(&row.second[0], row.second.size()); + int ret2 = pdbCopy->put(ptxn, &datKey, &datValue, DB_NOOVERWRITE); + if (ret2 > 0) + fSuccess = false; + } + ptxn->commit(0); + pdbCopy->close(0); + delete pdbCopy; + + return fSuccess; +} + +bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename) +{ + return CWalletDB::Recover(dbenv, filename, false); +} diff --git a/src/walletdb.h b/src/walletdb.h new file mode 100644 index 0000000..a3e779a --- /dev/null +++ b/src/walletdb.h @@ -0,0 +1,163 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 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_WALLETDB_H +#define BITCOIN_WALLETDB_H + +#include "db.h" +#include "base58.h" + +class CKeyPool; +class CAccount; +class CAccountingEntry; + +/** Error statuses for the wallet database */ +enum DBErrors +{ + DB_LOAD_OK, + DB_CORRUPT, + DB_NONCRITICAL_ERROR, + DB_TOO_NEW, + DB_LOAD_FAIL, + DB_NEED_REWRITE +}; + +/** Access to the wallet database (wallet.dat) */ +class CWalletDB : public CDB +{ +public: + CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode) + { + } +private: + CWalletDB(const CWalletDB&); + void operator=(const CWalletDB&); +public: + bool WriteName(const std::string& strAddress, const std::string& strName); + + bool EraseName(const std::string& strAddress); + + bool WriteTx(uint256 hash, const CWalletTx& wtx) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("tx"), hash), wtx); + } + + bool EraseTx(uint256 hash) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("tx"), hash)); + } + + bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("key"), vchPubKey.Raw()), vchPrivKey, false); + } + + bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector& vchCryptedSecret, bool fEraseUnencryptedKey = true) + { + nWalletDBUpdated++; + if (!Write(std::make_pair(std::string("ckey"), vchPubKey.Raw()), vchCryptedSecret, false)) + return false; + if (fEraseUnencryptedKey) + { + Erase(std::make_pair(std::string("key"), vchPubKey.Raw())); + Erase(std::make_pair(std::string("wkey"), vchPubKey.Raw())); + } + return true; + } + + bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); + } + + bool WriteCScript(const uint160& hash, const CScript& redeemScript) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false); + } + + bool WriteBestBlock(const CBlockLocator& locator) + { + nWalletDBUpdated++; + return Write(std::string("bestblock"), locator); + } + + bool ReadBestBlock(CBlockLocator& locator) + { + return Read(std::string("bestblock"), locator); + } + + bool WriteOrderPosNext(int64 nOrderPosNext) + { + nWalletDBUpdated++; + return Write(std::string("orderposnext"), nOrderPosNext); + } + + bool WriteDefaultKey(const CPubKey& vchPubKey) + { + nWalletDBUpdated++; + return Write(std::string("defaultkey"), vchPubKey.Raw()); + } + + bool ReadPool(int64 nPool, CKeyPool& keypool) + { + return Read(std::make_pair(std::string("pool"), nPool), keypool); + } + + bool WritePool(int64 nPool, const CKeyPool& keypool) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("pool"), nPool), keypool); + } + + bool ErasePool(int64 nPool) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("pool"), nPool)); + } + + // Settings are no longer stored in wallet.dat; these are + // used only for backwards compatibility: + template + bool ReadSetting(const std::string& strKey, T& value) + { + return Read(std::make_pair(std::string("setting"), strKey), value); + } + template + bool WriteSetting(const std::string& strKey, const T& value) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("setting"), strKey), value); + } + bool EraseSetting(const std::string& strKey) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("setting"), strKey)); + } + + bool WriteMinVersion(int nVersion) + { + return Write(std::string("minversion"), nVersion); + } + + bool ReadAccount(const std::string& strAccount, CAccount& account); + bool WriteAccount(const std::string& strAccount, const CAccount& account); +private: + bool WriteAccountingEntry(const uint64 nAccEntryNum, const CAccountingEntry& acentry); +public: + bool WriteAccountingEntry(const CAccountingEntry& acentry); + int64 GetAccountCreditDebit(const std::string& strAccount); + void ListAccountCreditDebit(const std::string& strAccount, std::list& acentries); + + DBErrors ReorderTransactions(CWallet*); + DBErrors LoadWallet(CWallet* pwallet); + static bool Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys); + static bool Recover(CDBEnv& dbenv, std::string filename); +}; + +#endif // BITCOIN_WALLETDB_H