Full Code of fireice-uk/xmr-stak-amd for AI

master 3358f25d55c5 cached
91 files
1.1 MB
331.3k tokens
830 symbols
1 requests
Download .txt
Showing preview only (1,128K chars total). Download the full file or copy to clipboard to get everything.
Repository: fireice-uk/xmr-stak-amd
Branch: master
Commit: 3358f25d55c5
Files: 91
Total size: 1.1 MB

Directory structure:
gitextract_saqq7bck/

├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── amd_gpu/
│   ├── gpu.c
│   └── gpu.h
├── cli-miner.cpp
├── config.txt
├── console.cpp
├── console.h
├── crypto/
│   ├── c_blake256.c
│   ├── c_blake256.h
│   ├── c_groestl.c
│   ├── c_groestl.h
│   ├── c_jh.c
│   ├── c_jh.h
│   ├── c_keccak.c
│   ├── c_keccak.h
│   ├── c_skein.c
│   ├── c_skein.h
│   ├── cryptonight.h
│   ├── cryptonight_aesni.h
│   ├── cryptonight_common.cpp
│   ├── groestl_tables.h
│   ├── hash.h
│   ├── int-util.h
│   ├── skein_port.h
│   └── soft_aes.c
├── donate-level.h
├── executor.cpp
├── executor.h
├── httpd.cpp
├── httpd.h
├── jconf.cpp
├── jconf.h
├── jext.h
├── jpsock.cpp
├── jpsock.h
├── libmicrohttpd/
│   └── microhttpd.h
├── minethd.cpp
├── minethd.h
├── msgstruct.h
├── opencl/
│   ├── blake256.cl
│   ├── cryptonight.cl
│   ├── groestl256.cl
│   ├── jh.cl
│   ├── wolf-aes.cl
│   └── wolf-skein.cl
├── rapidjson/
│   ├── allocators.h
│   ├── document.h
│   ├── encodedstream.h
│   ├── encodings.h
│   ├── error/
│   │   ├── en.h
│   │   └── error.h
│   ├── filereadstream.h
│   ├── filewritestream.h
│   ├── fwd.h
│   ├── internal/
│   │   ├── biginteger.h
│   │   ├── diyfp.h
│   │   ├── dtoa.h
│   │   ├── ieee754.h
│   │   ├── itoa.h
│   │   ├── meta.h
│   │   ├── pow10.h
│   │   ├── regex.h
│   │   ├── stack.h
│   │   ├── strfunc.h
│   │   ├── strtod.h
│   │   └── swap.h
│   ├── istreamwrapper.h
│   ├── memorybuffer.h
│   ├── memorystream.h
│   ├── msinttypes/
│   │   ├── inttypes.h
│   │   └── stdint.h
│   ├── ostreamwrapper.h
│   ├── pointer.h
│   ├── prettywriter.h
│   ├── rapidjson.h
│   ├── reader.h
│   ├── schema.h
│   ├── stream.h
│   ├── stringbuffer.h
│   └── writer.h
├── socket.cpp
├── socket.h
├── socks.h
├── thdq.hpp
├── version.h
├── webdesign.cpp
├── webdesign.h
└── xmr-stak-amd.cbp

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
bin/
obj/
xmr-stak-amd.layout
xmr-stak-amd.depend
config-debug.txt


================================================
FILE: CMakeLists.txt
================================================
project(xmr-stak-amd)

cmake_minimum_required(VERSION 3.1.3)

# enforce C++11
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 11)

if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE PATH "install prefix" FORCE)
endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)

# help to find AMD app SDK on systems with a software module system
list(APPEND CMAKE_PREFIX_PATH "$ENV{AMDAPPSDKROOT}")
# allow user to extent CMAKE_PREFIX_PATH via environment variable
list(APPEND CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}")

################################################################################
# CMake user options
################################################################################

# gcc 5.1 is the first GNU version without CoW strings
# https://github.com/fireice-uk/xmr-stak-nvidia/pull/10#issuecomment-290821792
# If you remove this guard to compile with older gcc versions the miner will produce
# a high rate of wrong shares.
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
    if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
        message(FATAL_ERROR "GCC version must be at least 5.1!")
    endif()
endif()

set(BUILD_TYPE "Release;Debug")
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build" FORCE)
endif()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${BUILD_TYPE}")

# option to add static libgcc and libstdc++
option(CMAKE_LINK_STATIC "link as much as possible libraries static" OFF)

###############################################################################
# Find OpenCL
###############################################################################

find_package(OpenCL REQUIRED)
include_directories(SYSTEM ${OpenCL_INCLUDE_DIRS})
set(LIBS ${LIBS} ${OpenCL_LIBRARY})
link_directories(${OpenCL_LIBRARY})

################################################################################
# Find PThreads
################################################################################

find_package(Threads REQUIRED)
set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT})

################################################################################
# Find microhttpd
################################################################################

option(MICROHTTPD_ENABLE "Enable or disable the requirement of microhttp (http deamon)" ON)
if(MICROHTTPD_ENABLE)
    find_library(MHTD NAMES microhttpd)
    if("${MHTD}" STREQUAL "MHTD-NOTFOUND")
        message(FATAL_ERROR "microhttpd NOT found: use `-DMICROHTTPD_ENABLE=OFF` to build without http deamon support")
    else()
        set(LIBS ${LIBS} ${MHTD})
    endif()
else()
    add_definitions("-DCONF_NO_HTTPD")
endif()

###############################################################################
# Find OpenSSL
###############################################################################

option(OpenSSL_ENABLE "Enable or disable the requirement of OpenSSL" ON)
if(OpenSSL_ENABLE)
    find_package(OpenSSL)
    if(OPENSSL_FOUND)
        include_directories(${OPENSSL_INCLUDE_DIR})
        set(LIBS ${LIBS} ${OPENSSL_LIBRARIES})
    else()
        message(FATAL_ERROR "OpenSSL NOT found: use `-DOpenSSL_ENABLE=OFF` to build without SSL support")
    endif()
else()
    add_definitions("-DCONF_NO_TLS")
endif()

################################################################################
# Compile & Link
################################################################################

include_directories(.)

# activate sse2 and aes-ni
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2 -maes")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2 -maes")

# activate static libgcc and libstdc++ linking
if(CMAKE_LINK_STATIC)
    set(BUILD_SHARED_LIBRARIES OFF)
    set(DL_LIB ${CMAKE_DL_LIBS})
    set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
    set(LIBS "-static-libgcc -static-libstdc++ ${LIBS}")
endif()

file(GLOB SRCFILES_CPP "*.cpp" "crypto/*.cpp")
file(GLOB SRCFILES_C "crypto/*.c" "amd_gpu/*.c")

add_library(xmr-stak-amd-c
    STATIC
    ${SRCFILES_C}
)
set_property(TARGET xmr-stak-amd-c PROPERTY C_STANDARD 99)
target_link_libraries(xmr-stak-amd-c PUBLIC ${OpenCL_LIBRARY})

add_executable(xmr-stak-amd
    ${SRCFILES_CPP}
)
set(EXECUTABLE_OUTPUT_PATH "bin")
target_link_libraries(xmr-stak-amd ${LIBS} xmr-stak-amd-c)

################################################################################
# Install
################################################################################

# do not install the binary if the project and install are equal
if( NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "${PROJECT_BINARY_DIR}" )
    install(TARGETS xmr-stak-amd
            RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
endif()

install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/opencl"
        DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")

# avoid overwrite of user defined settings
# install `config.txt`if file not exists in `${CMAKE_INSTALL_PREFIX}/bin`
install(CODE " \
    if(NOT EXISTS ${CMAKE_INSTALL_PREFIX}/bin/config.txt)\n   \
        file(INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/config.txt   \
            DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)\n        \
    endif()"
)


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.



================================================
FILE: README.md
================================================
# XMR-Stak is now supporting CPU, AMD and NVIDIA GPUs in a unified miner.

Our new repository is https://github.com/fireice-uk/xmr-stak.

Please use our new miner, the old version is retired and unsupported.


================================================
FILE: amd_gpu/gpu.c
================================================
/*
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */

#include <stdio.h>
#include <string.h>
#include <math.h>

#ifdef _WIN32
#include <windows.h>
const char* sSourcePath = "opencl\\cryptonight.cl";

static inline void port_sleep(size_t sec)
{
	Sleep(sec * 1000);
}
#else
#include <unistd.h>
const char* sSourcePath = "opencl/cryptonight.cl";

static inline void port_sleep(size_t sec)
{
	sleep(sec);
}
#endif // _WIN32

static inline long long unsigned int int_port(size_t i)
{
	return i;
}

#include "gpu.h"

const char* err_to_str(cl_int ret)
{
	switch(ret)
	{
	case CL_SUCCESS:
		return "CL_SUCCESS";
	case CL_DEVICE_NOT_FOUND:
		return "CL_DEVICE_NOT_FOUND";
	case CL_DEVICE_NOT_AVAILABLE:
		return "CL_DEVICE_NOT_AVAILABLE";
	case CL_COMPILER_NOT_AVAILABLE:
		return "CL_COMPILER_NOT_AVAILABLE";
	case CL_MEM_OBJECT_ALLOCATION_FAILURE:
		return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
	case CL_OUT_OF_RESOURCES:
		return "CL_OUT_OF_RESOURCES";
	case CL_OUT_OF_HOST_MEMORY:
		return "CL_OUT_OF_HOST_MEMORY";
	case CL_PROFILING_INFO_NOT_AVAILABLE:
		return "CL_PROFILING_INFO_NOT_AVAILABLE";
	case CL_MEM_COPY_OVERLAP:
		return "CL_MEM_COPY_OVERLAP";
	case CL_IMAGE_FORMAT_MISMATCH:
		return "CL_IMAGE_FORMAT_MISMATCH";
	case CL_IMAGE_FORMAT_NOT_SUPPORTED:
		return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
	case CL_BUILD_PROGRAM_FAILURE:
		return "CL_BUILD_PROGRAM_FAILURE";
	case CL_MAP_FAILURE:
		return "CL_MAP_FAILURE";
	case CL_MISALIGNED_SUB_BUFFER_OFFSET:
		return "CL_MISALIGNED_SUB_BUFFER_OFFSET";
	case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST:
		return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST";
	case CL_COMPILE_PROGRAM_FAILURE:
		return "CL_COMPILE_PROGRAM_FAILURE";
	case CL_LINKER_NOT_AVAILABLE:
		return "CL_LINKER_NOT_AVAILABLE";
	case CL_LINK_PROGRAM_FAILURE:
		return "CL_LINK_PROGRAM_FAILURE";
	case CL_DEVICE_PARTITION_FAILED:
		return "CL_DEVICE_PARTITION_FAILED";
	case CL_KERNEL_ARG_INFO_NOT_AVAILABLE:
		return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE";
	case CL_INVALID_VALUE:
		return "CL_INVALID_VALUE";
	case CL_INVALID_DEVICE_TYPE:
		return "CL_INVALID_DEVICE_TYPE";
	case CL_INVALID_PLATFORM:
		return "CL_INVALID_PLATFORM";
	case CL_INVALID_DEVICE:
		return "CL_INVALID_DEVICE";
	case CL_INVALID_CONTEXT:
		return "CL_INVALID_CONTEXT";
	case CL_INVALID_QUEUE_PROPERTIES:
		return "CL_INVALID_QUEUE_PROPERTIES";
	case CL_INVALID_COMMAND_QUEUE:
		return "CL_INVALID_COMMAND_QUEUE";
	case CL_INVALID_HOST_PTR:
		return "CL_INVALID_HOST_PTR";
	case CL_INVALID_MEM_OBJECT:
		return "CL_INVALID_MEM_OBJECT";
	case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:
		return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
	case CL_INVALID_IMAGE_SIZE:
		return "CL_INVALID_IMAGE_SIZE";
	case CL_INVALID_SAMPLER:
		return "CL_INVALID_SAMPLER";
	case CL_INVALID_BINARY:
		return "CL_INVALID_BINARY";
	case CL_INVALID_BUILD_OPTIONS:
		return "CL_INVALID_BUILD_OPTIONS";
	case CL_INVALID_PROGRAM:
		return "CL_INVALID_PROGRAM";
	case CL_INVALID_PROGRAM_EXECUTABLE:
		return "CL_INVALID_PROGRAM_EXECUTABLE";
	case CL_INVALID_KERNEL_NAME:
		return "CL_INVALID_KERNEL_NAME";
	case CL_INVALID_KERNEL_DEFINITION:
		return "CL_INVALID_KERNEL_DEFINITION";
	case CL_INVALID_KERNEL:
		return "CL_INVALID_KERNEL";
	case CL_INVALID_ARG_INDEX:
		return "CL_INVALID_ARG_INDEX";
	case CL_INVALID_ARG_VALUE:
		return "CL_INVALID_ARG_VALUE";
	case CL_INVALID_ARG_SIZE:
		return "CL_INVALID_ARG_SIZE";
	case CL_INVALID_KERNEL_ARGS:
		return "CL_INVALID_KERNEL_ARGS";
	case CL_INVALID_WORK_DIMENSION:
		return "CL_INVALID_WORK_DIMENSION";
	case CL_INVALID_WORK_GROUP_SIZE:
		return "CL_INVALID_WORK_GROUP_SIZE";
	case CL_INVALID_WORK_ITEM_SIZE:
		return "CL_INVALID_WORK_ITEM_SIZE";
	case CL_INVALID_GLOBAL_OFFSET:
		return "CL_INVALID_GLOBAL_OFFSET";
	case CL_INVALID_EVENT_WAIT_LIST:
		return "CL_INVALID_EVENT_WAIT_LIST";
	case CL_INVALID_EVENT:
		return "CL_INVALID_EVENT";
	case CL_INVALID_OPERATION:
		return "CL_INVALID_OPERATION";
	case CL_INVALID_GL_OBJECT:
		return "CL_INVALID_GL_OBJECT";
	case CL_INVALID_BUFFER_SIZE:
		return "CL_INVALID_BUFFER_SIZE";
	case CL_INVALID_MIP_LEVEL:
		return "CL_INVALID_MIP_LEVEL";
	case CL_INVALID_GLOBAL_WORK_SIZE:
		return "CL_INVALID_GLOBAL_WORK_SIZE";
	case CL_INVALID_PROPERTY:
		return "CL_INVALID_PROPERTY";
	case CL_INVALID_IMAGE_DESCRIPTOR:
		return "CL_INVALID_IMAGE_DESCRIPTOR";
	case CL_INVALID_COMPILER_OPTIONS:
		return "CL_INVALID_COMPILER_OPTIONS";
	case CL_INVALID_LINKER_OPTIONS:
		return "CL_INVALID_LINKER_OPTIONS";
	case CL_INVALID_DEVICE_PARTITION_COUNT:
		return "CL_INVALID_DEVICE_PARTITION_COUNT";
#ifdef CL_VERSION_2_0
	case CL_INVALID_PIPE_SIZE:
		return "CL_INVALID_PIPE_SIZE";
	case CL_INVALID_DEVICE_QUEUE:
		return "CL_INVALID_DEVICE_QUEUE";
#endif
	default:
		return "UNKNOWN_ERROR";
	}
}

void printer_print_msg(const char* fmt, ...);
void printer_print_str(const char* str);

char* LoadTextFile(const char* filename)
{
	size_t flen;
	char* out;
	FILE* kernel = fopen(filename, "rb");

	if(kernel == NULL)
		return NULL;

	fseek(kernel, 0, SEEK_END);
	flen = ftell(kernel);
	fseek(kernel, 0, SEEK_SET);

	out = (char*)malloc(flen+1);
	size_t r = fread(out, flen, 1, kernel);
	fclose(kernel);

	if(r != 1)
	{
		free(out);
		return NULL;
	}

	out[flen] = '\0';
	return out;
}

size_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, char* source_code)
{
	size_t MaximumWorkSize;
	cl_int ret;

	if((ret = clGetDeviceInfo(ctx->DeviceID, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &MaximumWorkSize, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when querying a device's max worksize using clGetDeviceInfo.", err_to_str(ret));
		return ERR_OCL_API;
	}

	printer_print_msg("Device %lu work size %lu / %lu.", ctx->deviceIdx, ctx->workSize, MaximumWorkSize);
#ifdef CL_VERSION_2_0
	const cl_queue_properties CommandQueueProperties[] = { 0, 0, 0 };
	ctx->CommandQueues = clCreateCommandQueueWithProperties(opencl_ctx, ctx->DeviceID, CommandQueueProperties, &ret);
#else
	const cl_command_queue_properties CommandQueueProperties = { 0 };
	ctx->CommandQueues = clCreateCommandQueue(opencl_ctx, ctx->DeviceID, CommandQueueProperties, &ret);
#endif

	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateCommandQueueWithProperties.", err_to_str(ret));
		return ERR_OCL_API;
	}

	ctx->InputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_ONLY, 88, NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateBuffer to create input buffer.", err_to_str(ret));
		return ERR_OCL_API;
	}

	size_t g_thd = ctx->rawIntensity;
	ctx->ExtraBuffers[0] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, (1 << 21) * g_thd, NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateBuffer to create hash scratchpads buffer.", err_to_str(ret));
		return ERR_OCL_API;
	}

	ctx->ExtraBuffers[1] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, 200 * g_thd, NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateBuffer to create hash states buffer.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Blake-256 branches
	ctx->ExtraBuffers[2] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateBuffer to create Branch 0 buffer.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Groestl-256 branches
	ctx->ExtraBuffers[3] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateBuffer to create Branch 1 buffer.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// JH-256 branches
	ctx->ExtraBuffers[4] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateBuffer to create Branch 2 buffer.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Skein-512 branches
	ctx->ExtraBuffers[5] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateBuffer to create Branch 3 buffer.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Assume we may find up to 0xFF nonces in one run - it's reasonable
	ctx->OutputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * 0x100, NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateBuffer to create output buffer.", err_to_str(ret));
		return ERR_OCL_API;
	}

	ctx->Program = clCreateProgramWithSource(opencl_ctx, 1, (const char**)&source_code, NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateProgramWithSource on the contents of cryptonight.cl", err_to_str(ret));
		return ERR_OCL_API;
	}

	char options[32];
	snprintf(options, sizeof(options), "-I. -DWORKSIZE=%llu", int_port(ctx->workSize));
	ret = clBuildProgram(ctx->Program, 1, &ctx->DeviceID, options, NULL, NULL);
	if(ret != CL_SUCCESS)
	{
		size_t len;
		printer_print_msg("Error %s when calling clBuildProgram.", err_to_str(ret));

		if((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_LOG, 0, NULL, &len)) != CL_SUCCESS)
		{
			printer_print_msg("Error %s when calling clGetProgramBuildInfo for length of build log output.", err_to_str(ret));
			return ERR_OCL_API;
		}

		char* BuildLog = (char*)malloc(len + 1);
		BuildLog[0] = '\0';

		if((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_LOG, len, BuildLog, NULL)) != CL_SUCCESS)
		{
			free(BuildLog);
			printer_print_msg("Error %s when calling clGetProgramBuildInfo for build log.", err_to_str(ret));
			return ERR_OCL_API;
		}

		printer_print_str("Build log:\n");
		printer_print_str(BuildLog);

		free(BuildLog);
		return ERR_OCL_API;
	}

	cl_build_status status;
	do
	{
		if((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &status, NULL)) != CL_SUCCESS)
		{
			printer_print_msg("Error %s when calling clGetProgramBuildInfo for status of build.", err_to_str(ret));
			return ERR_OCL_API;
		}
		port_sleep(1);
	}
	while(status == CL_BUILD_IN_PROGRESS);

	const char *KernelNames[] = { "cn0", "cn1", "cn2", "Blake", "Groestl", "JH", "Skein" };
	for(int i = 0; i < 7; ++i)
	{
		ctx->Kernels[i] = clCreateKernel(ctx->Program, KernelNames[i], &ret);
		if(ret != CL_SUCCESS)
		{
			printer_print_msg("Error %s when calling clCreateKernel for kernel %s.", err_to_str(ret), KernelNames[i]);
			return ERR_OCL_API;
		}
	}

	ctx->Nonce = 0;
	return 0;
}

// RequestedDeviceIdxs is a list of OpenCL device indexes
// NumDevicesRequested is number of devices in RequestedDeviceIdxs list
// Returns 0 on success, -1 on stupid params, -2 on OpenCL API error
size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx)
{
	cl_context opencl_ctx;
	cl_int ret;
	cl_uint entries;

	if((ret = clGetPlatformIDs(0, NULL, &entries)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clGetPlatformIDs for number of platforms.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// The number of platforms naturally is the index of the last platform plus one.
	if(entries <= platform_idx)
	{
		printer_print_msg("Selected OpenCL platform index %d doesn't exist.", platform_idx);
		return ERR_STUPID_PARAMS;
	}

	/*MSVC skimping on devel costs by shoehorning C99 to be a subset of C++? Noooo... can't be.*/
#ifdef __GNUC__
	cl_platform_id PlatformIDList[entries];
#else
	cl_platform_id* PlatformIDList = _alloca(entries * sizeof(cl_platform_id));
#endif
	if((ret = clGetPlatformIDs(entries, PlatformIDList, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clGetPlatformIDs for platform ID information.", err_to_str(ret));
		return ERR_OCL_API;
	}

	if((ret = clGetDeviceIDs(PlatformIDList[platform_idx], CL_DEVICE_TYPE_GPU, 0, NULL, &entries)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clGetDeviceIDs for number of devices.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Same as the platform index sanity check, except we must check all requested device indexes
	for(int i = 0; i < num_gpus; ++i)
	{
		if(entries <= ctx[i].deviceIdx)
		{
			printer_print_msg("Selected OpenCL device index %lu doesn't exist.\n", ctx[i].deviceIdx);
			return ERR_STUPID_PARAMS;
		}
	}

#ifdef __GNUC__
	cl_device_id DeviceIDList[entries];
#else
	cl_device_id* DeviceIDList = _alloca(entries * sizeof(cl_device_id));
#endif
	if((ret = clGetDeviceIDs(PlatformIDList[platform_idx], CL_DEVICE_TYPE_GPU, entries, DeviceIDList, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clGetDeviceIDs for device ID information.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Indexes sanity checked above
#ifdef __GNUC__
	cl_device_id TempDeviceList[num_gpus];
#else
	cl_device_id* TempDeviceList = _alloca(entries * sizeof(cl_device_id));
#endif
	for(int i = 0; i < num_gpus; ++i)
	{
		ctx[i].DeviceID = DeviceIDList[ctx[i].deviceIdx];
		TempDeviceList[i] = DeviceIDList[ctx[i].deviceIdx];
	}

	opencl_ctx = clCreateContext(NULL, num_gpus, TempDeviceList, NULL, NULL, &ret);
	if(ret != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clCreateContext.", err_to_str(ret));
		return ERR_OCL_API;
	}

	char* source_code = LoadTextFile(sSourcePath);
	if(source_code == NULL)
	{
		printer_print_msg("Couldn't locate GPU source code file at %s.", sSourcePath);
		return ERR_STUPID_PARAMS;
	}

	for(int i = 0; i < num_gpus; ++i)
	{
		if((ret = InitOpenCLGpu(opencl_ctx, &ctx[i], source_code)) != ERR_SUCCESS)
		{
			free(source_code);
			return ret;
		}
	}
	free(source_code);

	return ERR_SUCCESS;
}

size_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint32_t target)
{
	cl_int ret;

	if(input_len > 84)
		return ERR_STUPID_PARAMS;

	input[input_len] = 0x01;
	memset(input + input_len + 1, 0, 88 - input_len - 1);

	if((ret = clEnqueueWriteBuffer(ctx->CommandQueues, ctx->InputBuffer, CL_TRUE, 0, 88, input, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueWriteBuffer to fill input buffer.", err_to_str(ret));
		return ERR_OCL_API;
	}

	if((ret = clSetKernelArg(ctx->Kernels[0], 0, sizeof(cl_mem), &ctx->InputBuffer)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 0, argument 0.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Scratchpads
	if((ret = clSetKernelArg(ctx->Kernels[0], 1, sizeof(cl_mem), ctx->ExtraBuffers + 0)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 0, argument 1.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// States
	if((ret = clSetKernelArg(ctx->Kernels[0], 2, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 0, argument 2.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// CN2 Kernel

	// Scratchpads
	if((ret = clSetKernelArg(ctx->Kernels[1], 0, sizeof(cl_mem), ctx->ExtraBuffers + 0)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 1, argument 0.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// States
	if((ret = clSetKernelArg(ctx->Kernels[1], 1, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 1, argument 1.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// CN3 Kernel
	// Scratchpads
	if((ret = clSetKernelArg(ctx->Kernels[2], 0, sizeof(cl_mem), ctx->ExtraBuffers + 0)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 2, argument 0.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// States
	if((ret = clSetKernelArg(ctx->Kernels[2], 1, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 2, argument 1.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Branch 0
	if((ret = clSetKernelArg(ctx->Kernels[2], 2, sizeof(cl_mem), ctx->ExtraBuffers + 2)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 2, argument 2.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Branch 1
	if((ret = clSetKernelArg(ctx->Kernels[2], 3, sizeof(cl_mem), ctx->ExtraBuffers + 3)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 2, argument 3.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Branch 2
	if((ret = clSetKernelArg(ctx->Kernels[2], 4, sizeof(cl_mem), ctx->ExtraBuffers + 4)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 2, argument 4.", err_to_str(ret));
		return ERR_OCL_API;
	}

	// Branch 3
	if((ret = clSetKernelArg(ctx->Kernels[2], 5, sizeof(cl_mem), ctx->ExtraBuffers + 5)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clSetKernelArg for kernel 2, argument 5.", err_to_str(ret));
		return ERR_OCL_API;
	}

	for(int i = 0; i < 4; ++i)
	{
		// States
		if((ret = clSetKernelArg(ctx->Kernels[i + 3], 0, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS)
		{
			printer_print_msg("Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 0);
			return ERR_OCL_API;
		}

		// Nonce buffer
		if((ret = clSetKernelArg(ctx->Kernels[i + 3], 1, sizeof(cl_mem), ctx->ExtraBuffers + (i + 2))) != CL_SUCCESS)
		{
			printer_print_msg("Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 1);
			return ERR_OCL_API;
		}

		// Output
		if((ret = clSetKernelArg(ctx->Kernels[i + 3], 2, sizeof(cl_mem), &ctx->OutputBuffer)) != CL_SUCCESS)
		{
			printer_print_msg("Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 2);
			return ERR_OCL_API;
		}

		// Target
		if((ret = clSetKernelArg(ctx->Kernels[i + 3], 3, sizeof(cl_uint), &target)) != CL_SUCCESS)
		{
			printer_print_msg("Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 3);
			return ERR_OCL_API;
		}
	}

	return ERR_SUCCESS;
}

size_t XMRRunJob(GpuContext* ctx, cl_uint* HashOutput)
{
	cl_int ret;
	cl_uint zero = 0;
	size_t BranchNonces[4] = {0};

	size_t g_thd = ctx->rawIntensity;
	size_t w_size = ctx->workSize;

	for(int i = 2; i < 6; ++i)
	{
		if((ret = clEnqueueWriteBuffer(ctx->CommandQueues, ctx->ExtraBuffers[i], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), &zero, 0, NULL, NULL)) != CL_SUCCESS)
		{
			printer_print_msg("Error %s when calling clEnqueueWriteBuffer to zero branch buffer counter %d.", err_to_str(ret), i - 2);
			return ERR_OCL_API;
		}
	}

	if((ret = clEnqueueWriteBuffer(ctx->CommandQueues, ctx->OutputBuffer, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(cl_uint), &zero, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret));
		return ERR_OCL_API;
	}

	clFinish(ctx->CommandQueues);

	size_t Nonce[2] = {ctx->Nonce, 1}, gthreads[2] = { g_thd, 8 }, lthreads[2] = { w_size, 8 };
	if((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[0], 2, Nonce, gthreads, lthreads, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), 0);
		return ERR_OCL_API;
	}

	/*for(int i = 1; i < 3; ++i)
	{
		if((ret = clEnqueueNDRangeKernel(*ctx->CommandQueues, ctx->Kernels[i], 1, &ctx->Nonce, &g_thd, &w_size, 0, NULL, NULL)) != CL_SUCCESS)
		{
			Log(LOG_CRITICAL, "Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), i);
			return(ERR_OCL_API);
		}
	}*/

	if((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[1], 1, &ctx->Nonce, &g_thd, &w_size, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), 1);
		return ERR_OCL_API;
	}

	if((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[2], 2, Nonce, gthreads, lthreads, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), 2);
		return ERR_OCL_API;
	}

	if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[2], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret));
		return ERR_OCL_API;
	}

	if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[3], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces + 1, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret));
		return ERR_OCL_API;
	}

	if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[4], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces + 2, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret));
		return ERR_OCL_API;
	}

	if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[5], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces + 3, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret));
		return ERR_OCL_API;
	}

	clFinish(ctx->CommandQueues);

	for(int i = 0; i < 4; ++i)
	{
		if(BranchNonces[i])
		{
			// Threads
			if((clSetKernelArg(ctx->Kernels[i + 3], 4, sizeof(cl_ulong), BranchNonces + i)) != CL_SUCCESS)
			{
				printer_print_msg("Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 4);
				return(ERR_OCL_API);
			}

			BranchNonces[i] = ((size_t)ceil( (double)BranchNonces[i] / (double)w_size) ) * w_size;
			if((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[i + 3], 1, &ctx->Nonce, BranchNonces + i, &w_size, 0, NULL, NULL)) != CL_SUCCESS)
			{
				printer_print_msg("Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), i + 3);
				return ERR_OCL_API;
			}
		}
	}

	if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->OutputBuffer, CL_TRUE, 0, sizeof(cl_uint) * 0x100, HashOutput, 0, NULL, NULL)) != CL_SUCCESS)
	{
		printer_print_msg("Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret));
		return ERR_OCL_API;
	}

	clFinish(ctx->CommandQueues);
	ctx->Nonce += g_thd;

	return ERR_SUCCESS;
}


================================================
FILE: amd_gpu/gpu.h
================================================
#pragma once

#include <CL/cl.h>
#include <stdint.h>

#define ERR_SUCCESS (0)
#define ERR_OCL_API (2)
#define ERR_STUPID_PARAMS (1)

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

typedef struct _GpuContext
{
	/*Input vars*/
	size_t deviceIdx;
	size_t rawIntensity;
	size_t workSize;

	/*Output vars*/
	cl_device_id DeviceID;
	cl_command_queue CommandQueues;
	cl_mem InputBuffer;
	cl_mem OutputBuffer;
	cl_mem ExtraBuffers[6];
	cl_program Program;
	cl_kernel Kernels[7];

	size_t Nonce;
} GpuContext;

size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx);
size_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint32_t target);
size_t XMRRunJob(GpuContext* ctx, cl_uint* HashOutput);

#ifdef __cplusplus
}
#endif // __cplusplus


================================================
FILE: cli-miner.cpp
================================================
 /*
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  * Additional permission under GNU GPL version 3 section 7
  *
  * If you modify this Program, or any covered work, by linking or combining
  * it with OpenSSL (or a modified version of that library), containing parts
  * covered by the terms of OpenSSL License and SSLeay License, the licensors
  * of this Program grant you additional permission to convey the resulting work.
  *
  */

#include "executor.h"
#include "minethd.h"
#include "jconf.h"
#include "console.h"
#include "donate-level.h"
#include "version.h"

#ifndef CONF_NO_HTTPD
#	include "httpd.h"
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifndef CONF_NO_TLS
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif

//Do a press any key for the windows folk. *insert any key joke here*
#ifdef _WIN32
void win_exit()
{
	printer::inst()->print_str("Press any key to exit.");
	get_key();
	return;
}

#define strcasecmp _stricmp

#else
void win_exit() { return; }
#endif // _WIN32

void do_benchmark();

int main(int argc, char *argv[])
{
#ifndef CONF_NO_TLS
	SSL_library_init();
	SSL_load_error_strings();
	ERR_load_BIO_strings();
	ERR_load_crypto_strings();
	SSL_load_error_strings();
	OpenSSL_add_all_digests();
#endif

	const char* sFilename = "config.txt";
	bool benchmark_mode = false;

	if(argc >= 2)
	{
		if(strcmp(argv[1], "-h") == 0)
		{
			printer::inst()->print_msg(L0, "Usage %s [CONFIG FILE]", argv[0]);
			win_exit();
			return 0;
		}

		if(argc >= 3 && strcasecmp(argv[1], "-c") == 0)
		{
			sFilename = argv[2];
		}
		else if(argc >= 3 && strcasecmp(argv[1], "benchmark_mode") == 0)
		{
			sFilename = argv[2];
			benchmark_mode = true;
		}
		else
			sFilename = argv[1];
	}

	if(!jconf::inst()->parse_config(sFilename))
	{
		win_exit();
		return 0;
	}

	if(!minethd::init_gpus())
	{
		win_exit();
		return 0;
	}

	if(benchmark_mode)
	{
		do_benchmark();
		win_exit();
		return 0;
	}

#ifndef CONF_NO_HTTPD
	if(jconf::inst()->GetHttpdPort() != 0)
	{
		if (!httpd::inst()->start_daemon())
		{
			win_exit();
			return 0;
		}
	}
#endif

	printer::inst()->print_str("-------------------------------------------------------------------\n");
	printer::inst()->print_str( XMR_STAK_NAME" " XMR_STAK_VERSION " mining software, AMD Version.\n");
	printer::inst()->print_str("AMD mining code was written by wolf9466.\n");
	printer::inst()->print_str("Brought to you by fireice_uk under GPLv3.\n\n");
	char buffer[64];
	snprintf(buffer, sizeof(buffer), "Configurable dev donation level is set to %.1f %%\n\n", fDevDonationLevel * 100.0);
	printer::inst()->print_str(buffer);
	printer::inst()->print_str("You can use following keys to display reports:\n");
	printer::inst()->print_str("'h' - hashrate\n");
	printer::inst()->print_str("'r' - results\n");
	printer::inst()->print_str("'c' - connection\n");
	printer::inst()->print_str("-------------------------------------------------------------------\n");

	if(strlen(jconf::inst()->GetOutputFile()) != 0)
		printer::inst()->open_logfile(jconf::inst()->GetOutputFile());

	executor::inst()->ex_start(jconf::inst()->DaemonMode());

	using namespace std::chrono;
	uint64_t lastTime = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();

	int key;
	while(true)
	{
		key = get_key();

		switch(key)
		{
		case 'h':
			executor::inst()->push_event(ex_event(EV_USR_HASHRATE));
			break;
		case 'r':
			executor::inst()->push_event(ex_event(EV_USR_RESULTS));
			break;
		case 'c':
			executor::inst()->push_event(ex_event(EV_USR_CONNSTAT));
			break;
		default:
			break;
		}

		uint64_t currentTime = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();

		/* Hard guard to make sure we never get called more than twice per second */
		if( currentTime - lastTime < 500)
			std::this_thread::sleep_for(std::chrono::milliseconds(500 - (currentTime - lastTime)));
		lastTime = currentTime;
	}

	return 0;
}

void do_benchmark()
{
	using namespace std::chrono;
	std::vector<minethd*>* pvThreads;

	printer::inst()->print_msg(L0, "Running a 60 second benchmark...");

	uint8_t work[76] = {0};
	minethd::miner_work oWork = minethd::miner_work("", work, sizeof(work), 0, 0, 0);
	pvThreads = minethd::thread_starter(oWork);

	uint64_t iStartStamp = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();

	std::this_thread::sleep_for(std::chrono::seconds(60));

	oWork = minethd::miner_work();
	minethd::switch_work(oWork);

	double fTotalHps = 0.0;
	for (uint32_t i = 0; i < pvThreads->size(); i++)
	{
		double fHps = pvThreads->at(i)->iHashCount;
		fHps /= (pvThreads->at(i)->iTimestamp - iStartStamp) / 1000.0;

		printer::inst()->print_msg(L0, "Thread %u: %.1f H/S", i, fHps);
		fTotalHps += fHps;
	}

	printer::inst()->print_msg(L0, "Total: %.1f H/S", fTotalHps);
}


================================================
FILE: config.txt
================================================
/* 
 * Number of GPUs that you have in your system. Each GPU will get its own CPU thread.
 */
"gpu_thread_num" : 6,

/*
 * GPU configuration. You should play around with intensity and worksize as the fastest settings will vary.
 *      index    - GPU index number usually starts from 0
 *  intensity    - Number of parallel GPU threads (nothing to do with CPU threads)
 *   worksize    - Number of local GPU threads (nothing to do with CPU threads)
 * affine_to_cpu - This will affine the thread to a CPU. This can make a GPU miner play along nicer with a CPU miner.
 */
"gpu_threads_conf" : [ 
	{ "index" : 0, "intensity" : 1000, "worksize" : 8, "affine_to_cpu" : false },
	{ "index" : 1, "intensity" : 1000, "worksize" : 8, "affine_to_cpu" : false },
	{ "index" : 2, "intensity" : 1000, "worksize" : 8, "affine_to_cpu" : false },
	{ "index" : 3, "intensity" : 1000, "worksize" : 8, "affine_to_cpu" : false },
	{ "index" : 4, "intensity" : 1000, "worksize" : 8, "affine_to_cpu" : false },
	{ "index" : 5, "intensity" : 1000, "worksize" : 8, "affine_to_cpu" : false },
],

/*
 * Platform index. This will be 0 unless you have different OpenCL platform - eg. AMD and Intel.
 */
"platform_index" : 0,

/*
 * TLS Settings
 * If you need real security, make sure tls_secure_algo is enabled (otherwise MITM attack can downgrade encryption
 * to trivially breakable stuff like DES and MD5), and verify the server's fingerprint through a trusted channel. 
 *
 * use_tls         - This option will make us connect using Transport Layer Security.
 * tls_secure_algo - Use only secure algorithms. This will make us quit with an error if we can't negotiate a secure algo.
 * tls_fingerprint - Server's SHA256 fingerprint. If this string is non-empty then we will check the server's cert against it.
 */
"use_tls" : false,
"tls_secure_algo" : true,
"tls_fingerprint" : "",

/*
 * pool_address	  - Pool address should be in the form "pool.supportxmr.com:3333". Only stratum pools are supported.
 * wallet_address - Your wallet, or pool login.
 * pool_password  - Can be empty in most cases or "x".
 */
"pool_address" : "pool.supportxmr.com:3333",
"wallet_address" : "",
"pool_password" : "",

/*
 * Network timeouts.
 * Because of the way this client is written it doesn't need to constantly talk (keep-alive) to the server to make 
 * sure it is there. We detect a buggy / overloaded server by the call timeout. The default values will be ok for 
 * nearly all cases. If they aren't the pool has most likely overload issues. Low call timeout values are preferable -
 * long timeouts mean that we waste hashes on potentially stale jobs. Connection report will tell you how long the
 * server usually takes to process our calls.
 *
 * call_timeout - How long should we wait for a response from the server before we assume it is dead and drop the connection.
 * retry_time	- How long should we wait before another connection attempt.
 *                Both values are in seconds.
 * giveup_limit - Limit how many times we try to reconnect to the pool. Zero means no limit. Note that stak miners
 *                don't mine while the connection is lost, so your computer's power usage goes down to idle.
 */
"call_timeout" : 10,
"retry_time" : 10,
"giveup_limit" : 0,

/*
 * Output control.
 * Since most people are used to miners printing all the time, that's what we do by default too. This is suboptimal
 * really, since you cannot see errors under pages and pages of text and performance stats. Given that we have internal
 * performance monitors, there is very little reason to spew out pages of text instead of concise reports.
 * Press 'h' (hashrate), 'r' (results) or 'c' (connection) to print reports.
 *
 * verbose_level - 0 - Don't print anything. 
 *                 1 - Print intro, connection event, disconnect event
 *                 2 - All of level 1, and new job (block) event if the difficulty is different from the last job
 *                 3 - All of level 1, and new job (block) event in all cases, result submission event.
 *                 4 - All of level 3, and automatic hashrate report printing 
 */
"verbose_level" : 3,

/*
 * Automatic hashrate report
 *
 * h_print_time - How often, in seconds, should we print a hashrate report if verbose_level is set to 4.
 *                This option has no effect if verbose_level is not 4.
 */
"h_print_time" : 60,

/*
 * Daemon mode
 *
 * If you are running the process in the background and you don't need the keyboard reports, set this to true.
 * This should solve the hashrate problems on some emulated terminals.
 */
"daemon_mode" : false,

/*
 * Output file
 *
 * output_file  - This option will log all output to a file.
 *
 */
"output_file" : "",

/*
 * Built-in web server
 * I like checking my hashrate on my phone. Don't you?
 * Keep in mind that you will need to set up port forwarding on your router if you want to access it from
 * outside of your home network. Ports lower than 1024 on Linux systems will require root.
 *
 * httpd_port - Port we should listen on. Default, 0, will switch off the server.
 */
"httpd_port" : 0,

/*
 * prefer_ipv4 - IPv6 preference. If the host is available on both IPv4 and IPv6 net, which one should be choose?
 *               This setting will only be needed in 2020's. No need to worry about it now.
 */
"prefer_ipv4" : true,


================================================
FILE: console.cpp
================================================
/*
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  * Additional permission under GNU GPL version 3 section 7
  *
  * If you modify this Program, or any covered work, by linking or combining
  * it with OpenSSL (or a modified version of that library), containing parts
  * covered by the terms of OpenSSL License and SSLeay License, the licensors
  * of this Program grant you additional permission to convey the resulting work.
  *
  */

#include "console.h"
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#ifdef _WIN32
#include <windows.h>

int get_key()
{
	DWORD mode, rd;
	HANDLE h;

	if ((h = GetStdHandle(STD_INPUT_HANDLE)) == NULL)
		return -1;

	GetConsoleMode( h, &mode );
	SetConsoleMode( h, mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT) );

	int c = 0;
	ReadConsole( h, &c, 1, &rd, NULL );
	SetConsoleMode( h, mode );

	return c;
}

void set_colour(out_colours cl)
{
	WORD attr = 0;

	switch(cl)
	{
	case K_RED:
		attr = FOREGROUND_RED | FOREGROUND_INTENSITY;
		break;
	case K_GREEN:
		attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
		break;
	case K_BLUE:
		attr = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
		break;
	case K_YELLOW:
		attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
		break;
	case K_CYAN:
		attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
		break;
	case K_MAGENTA:
		attr = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;
		break;
	case K_WHITE:
		attr = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
		break;
	default:
		break;
	}

	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attr);
}

void reset_colour()
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
}

#else
#include <termios.h>
#include <unistd.h>
#include <stdio.h>

int get_key()
{
	struct termios oldattr, newattr;
	int ch;
	tcgetattr( STDIN_FILENO, &oldattr );
	newattr = oldattr;
	newattr.c_lflag &= ~( ICANON | ECHO );
	tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
	ch = getchar();
	tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
	return ch;
}

void set_colour(out_colours cl)
{
	switch(cl)
	{
	case K_RED:
		fputs("\x1B[1;31m", stdout);
		break;
	case K_GREEN:
		fputs("\x1B[1;32m", stdout);
		break;
	case K_BLUE:
		fputs("\x1B[1;34m", stdout);
		break;
	case K_YELLOW:
		fputs("\x1B[1;33m", stdout);
		break;
	case K_CYAN:
		fputs("\x1B[1;36m", stdout);
		break;
	case K_MAGENTA:
		fputs("\x1B[1;35m", stdout);
		break;
	case K_WHITE:
		fputs("\x1B[1;37m", stdout);
		break;
	default:
		break;
	}
}

void reset_colour()
{
	fputs("\x1B[0m", stdout);
}
#endif // _WIN32

inline void comp_localtime(const time_t* ctime, tm* stime)
{
#ifdef _WIN32
	localtime_s(stime, ctime);
#else
	localtime_r(ctime, stime);
#endif // __WIN32
}

printer* printer::oInst = nullptr;

printer::printer()
{
	verbose_level = LINF;
	logfile = nullptr;
}

bool printer::open_logfile(const char* file)
{
	logfile = fopen(file, "ab+");
	return logfile != nullptr;
}

void printer::print_msg(verbosity verbose, const char* fmt, ...)
{
	if(verbose > verbose_level)
		return;

	char buf[1024];
	size_t bpos;
	tm stime;

	time_t now = time(nullptr);
	comp_localtime(&now, &stime);
	strftime(buf, sizeof(buf), "[%F %T] : ", &stime);
	bpos = strlen(buf);

	va_list args;
	va_start(args, fmt);
	vsnprintf(buf+bpos, sizeof(buf)-bpos, fmt, args);
	va_end(args);
	bpos = strlen(buf);

	if(bpos+2 >= sizeof(buf))
		return;

	buf[bpos] = '\n';
	buf[bpos+1] = '\0';

	std::unique_lock<std::mutex> lck(print_mutex);
	fputs(buf, stdout);

	if(logfile != nullptr)
	{
		fputs(buf, logfile);
		fflush(logfile);
	}
}

void printer::print_str(const char* str)
{
	std::unique_lock<std::mutex> lck(print_mutex);
	fputs(str, stdout);

	if(logfile != nullptr)
	{
		fputs(str, logfile);
		fflush(logfile);
	}
}

extern "C" void printer_print_msg(const char* fmt, ...)
{
	char buf[1024];
	size_t bpos;
	tm stime;

	time_t now = time(nullptr);
	comp_localtime(&now, &stime);
	strftime(buf, sizeof(buf), "[%F %T] : ", &stime);
	bpos = strlen(buf);

	va_list args;
	va_start(args, fmt);
	vsnprintf(buf+bpos, sizeof(buf)-bpos, fmt, args);
	va_end(args);
	bpos = strlen(buf);

	if(bpos+2 >= sizeof(buf))
		return;

	buf[bpos] = '\n';
	buf[bpos+1] = '\0';

	printer::inst()->print_str(buf);
}

extern "C" void printer_print_str(const char* str)
{
	printer::inst()->print_str(str);
}


================================================
FILE: console.h
================================================
#pragma once
#include <mutex>

enum out_colours { K_RED, K_GREEN, K_BLUE, K_YELLOW, K_CYAN, K_MAGENTA, K_WHITE, K_NONE };

// Warning - on Linux get_key will detect control keys, but not on Windows.
// We will only use it for alphanum keys anyway.
int get_key();

void set_colour(out_colours cl);
void reset_colour();

// on MSVC sizeof(long int) = 4, gcc sizeof(long int) = 8, this is the workaround
// now we can use %llu on both compilers
inline long long unsigned int int_port(size_t i)
{
	return i;
}

enum verbosity : size_t { L0 = 0, L1 = 1, L2 = 2, L3 = 3, L4 = 4, LINF = 100};

class printer
{
public:
	static inline printer* inst()
	{
		if (oInst == nullptr) oInst = new printer;
		return oInst;
	};

	inline void set_verbose_level(size_t level) { verbose_level = (verbosity)level; }
	void print_msg(verbosity verbose, const char* fmt, ...);
	void print_str(const char* str);
	bool open_logfile(const char* file);

private:
	printer();
	static printer* oInst;

	std::mutex print_mutex;
	verbosity verbose_level;
	FILE* logfile;
};


================================================
FILE: crypto/c_blake256.c
================================================
/*
 * The blake256_* and blake224_* functions are largely copied from
 * blake256_light.c and blake224_light.c from the BLAKE website:
 *
 *     http://131002.net/blake/
 *
 * The hmac_* functions implement HMAC-BLAKE-256 and HMAC-BLAKE-224.
 * HMAC is specified by RFC 2104.
 */

#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include "c_blake256.h"

#define U8TO32(p) \
	(((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) |    \
	 ((uint32_t)((p)[2]) <<  8) | ((uint32_t)((p)[3])      ))
#define U32TO8(p, v) \
	(p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \
	(p)[2] = (uint8_t)((v) >>  8); (p)[3] = (uint8_t)((v)      );

const uint8_t sigma[][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}
};

const uint32_t cst[16] = {
	0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
	0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
	0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
	0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917
};

static const uint8_t padding[] = {
	0x80,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};


void blake256_compress(state *S, const uint8_t *block) {
	uint32_t v[16], m[16], i;

#define ROT(x,n) (((x)<<(32-n))|((x)>>(n)))
#define G(a,b,c,d,e)                                      \
	v[a] += (m[sigma[i][e]] ^ cst[sigma[i][e+1]]) + v[b]; \
	v[d] = ROT(v[d] ^ v[a],16);                           \
	v[c] += v[d];                                         \
	v[b] = ROT(v[b] ^ v[c],12);                           \
	v[a] += (m[sigma[i][e+1]] ^ cst[sigma[i][e]])+v[b];   \
	v[d] = ROT(v[d] ^ v[a], 8);                           \
	v[c] += v[d];                                         \
	v[b] = ROT(v[b] ^ v[c], 7);

	for (i = 0; i < 16; ++i) m[i] = U8TO32(block + i * 4);
	for (i = 0; i < 8;  ++i) v[i] = S->h[i];
	v[ 8] = S->s[0] ^ 0x243F6A88;
	v[ 9] = S->s[1] ^ 0x85A308D3;
	v[10] = S->s[2] ^ 0x13198A2E;
	v[11] = S->s[3] ^ 0x03707344;
	v[12] = 0xA4093822;
	v[13] = 0x299F31D0;
	v[14] = 0x082EFA98;
	v[15] = 0xEC4E6C89;

	if (S->nullt == 0) {
		v[12] ^= S->t[0];
		v[13] ^= S->t[0];
		v[14] ^= S->t[1];
		v[15] ^= S->t[1];
	}

	for (i = 0; i < 14; ++i) {
		G(0, 4,  8, 12,  0);
		G(1, 5,  9, 13,  2);
		G(2, 6, 10, 14,  4);
		G(3, 7, 11, 15,  6);
		G(3, 4,  9, 14, 14);
		G(2, 7,  8, 13, 12);
		G(0, 5, 10, 15,  8);
		G(1, 6, 11, 12, 10);
	}

	for (i = 0; i < 16; ++i) S->h[i % 8] ^= v[i];
	for (i = 0; i < 8;  ++i) S->h[i] ^= S->s[i % 4];
}

void blake256_init(state *S) {
	S->h[0] = 0x6A09E667;
	S->h[1] = 0xBB67AE85;
	S->h[2] = 0x3C6EF372;
	S->h[3] = 0xA54FF53A;
	S->h[4] = 0x510E527F;
	S->h[5] = 0x9B05688C;
	S->h[6] = 0x1F83D9AB;
	S->h[7] = 0x5BE0CD19;
	S->t[0] = S->t[1] = S->buflen = S->nullt = 0;
	S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0;
}

void blake224_init(state *S) {
	S->h[0] = 0xC1059ED8;
	S->h[1] = 0x367CD507;
	S->h[2] = 0x3070DD17;
	S->h[3] = 0xF70E5939;
	S->h[4] = 0xFFC00B31;
	S->h[5] = 0x68581511;
	S->h[6] = 0x64F98FA7;
	S->h[7] = 0xBEFA4FA4;
	S->t[0] = S->t[1] = S->buflen = S->nullt = 0;
	S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0;
}

// datalen = number of bits
void blake256_update(state *S, const uint8_t *data, uint64_t datalen) {
	int left = S->buflen >> 3;
	int fill = 64 - left;

	if (left && (((datalen >> 3) & 0x3F) >= (unsigned) fill)) {
		memcpy((void *) (S->buf + left), (void *) data, fill);
		S->t[0] += 512;
		if (S->t[0] == 0) S->t[1]++;
		blake256_compress(S, S->buf);
		data += fill;
		datalen -= (fill << 3);
		left = 0;
	}

	while (datalen >= 512) {
		S->t[0] += 512;
		if (S->t[0] == 0) S->t[1]++;
		blake256_compress(S, data);
		data += 64;
		datalen -= 512;
	}

	if (datalen > 0) {
		memcpy((void *) (S->buf + left), (void *) data, datalen >> 3);
		S->buflen = (left << 3) + datalen;
	} else {
		S->buflen = 0;
	}
}

// datalen = number of bits
void blake224_update(state *S, const uint8_t *data, uint64_t datalen) {
	blake256_update(S, data, datalen);
}

void blake256_final_h(state *S, uint8_t *digest, uint8_t pa, uint8_t pb) {
	uint8_t msglen[8];
	uint32_t lo = S->t[0] + S->buflen, hi = S->t[1];
	if (lo < (unsigned) S->buflen) hi++;
	U32TO8(msglen + 0, hi);
	U32TO8(msglen + 4, lo);

	if (S->buflen == 440) { /* one padding byte */
		S->t[0] -= 8;
		blake256_update(S, &pa, 8);
	} else {
		if (S->buflen < 440) { /* enough space to fill the block  */
			if (S->buflen == 0) S->nullt = 1;
			S->t[0] -= 440 - S->buflen;
			blake256_update(S, padding, 440 - S->buflen);
		} else { /* need 2 compressions */
			S->t[0] -= 512 - S->buflen;
			blake256_update(S, padding, 512 - S->buflen);
			S->t[0] -= 440;
			blake256_update(S, padding + 1, 440);
			S->nullt = 1;
		}
		blake256_update(S, &pb, 8);
		S->t[0] -= 8;
	}
	S->t[0] -= 64;
	blake256_update(S, msglen, 64);

	U32TO8(digest +  0, S->h[0]);
	U32TO8(digest +  4, S->h[1]);
	U32TO8(digest +  8, S->h[2]);
	U32TO8(digest + 12, S->h[3]);
	U32TO8(digest + 16, S->h[4]);
	U32TO8(digest + 20, S->h[5]);
	U32TO8(digest + 24, S->h[6]);
	U32TO8(digest + 28, S->h[7]);
}

void blake256_final(state *S, uint8_t *digest) {
	blake256_final_h(S, digest, 0x81, 0x01);
}

void blake224_final(state *S, uint8_t *digest) {
	blake256_final_h(S, digest, 0x80, 0x00);
}

// inlen = number of bytes
void blake256_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {
	state S;
	blake256_init(&S);
	blake256_update(&S, in, inlen * 8);
	blake256_final(&S, out);
}

// inlen = number of bytes
void blake224_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {
	state S;
	blake224_init(&S);
	blake224_update(&S, in, inlen * 8);
	blake224_final(&S, out);
}

// keylen = number of bytes
void hmac_blake256_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {
	const uint8_t *key = _key;
	uint8_t keyhash[32];
	uint8_t pad[64];
	uint64_t i;

	if (keylen > 64) {
		blake256_hash(keyhash, key, keylen);
		key = keyhash;
		keylen = 32;
	}

	blake256_init(&S->inner);
	memset(pad, 0x36, 64);
	for (i = 0; i < keylen; ++i) {
		pad[i] ^= key[i];
	}
	blake256_update(&S->inner, pad, 512);

	blake256_init(&S->outer);
	memset(pad, 0x5c, 64);
	for (i = 0; i < keylen; ++i) {
		pad[i] ^= key[i];
	}
	blake256_update(&S->outer, pad, 512);

	memset(keyhash, 0, 32);
}

// keylen = number of bytes
void hmac_blake224_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {
	const uint8_t *key = _key;
	uint8_t keyhash[32];
	uint8_t pad[64];
	uint64_t i;

	if (keylen > 64) {
		blake256_hash(keyhash, key, keylen);
		key = keyhash;
		keylen = 28;
	}

	blake224_init(&S->inner);
	memset(pad, 0x36, 64);
	for (i = 0; i < keylen; ++i) {
		pad[i] ^= key[i];
	}
	blake224_update(&S->inner, pad, 512);

	blake224_init(&S->outer);
	memset(pad, 0x5c, 64);
	for (i = 0; i < keylen; ++i) {
		pad[i] ^= key[i];
	}
	blake224_update(&S->outer, pad, 512);

	memset(keyhash, 0, 32);
}

// datalen = number of bits
void hmac_blake256_update(hmac_state *S, const uint8_t *data, uint64_t datalen) {
  // update the inner state
  blake256_update(&S->inner, data, datalen);
}

// datalen = number of bits
void hmac_blake224_update(hmac_state *S, const uint8_t *data, uint64_t datalen) {
  // update the inner state
  blake224_update(&S->inner, data, datalen);
}

void hmac_blake256_final(hmac_state *S, uint8_t *digest) {
	uint8_t ihash[32];
	blake256_final(&S->inner, ihash);
	blake256_update(&S->outer, ihash, 256);
	blake256_final(&S->outer, digest);
	memset(ihash, 0, 32);
}

void hmac_blake224_final(hmac_state *S, uint8_t *digest) {
	uint8_t ihash[32];
	blake224_final(&S->inner, ihash);
	blake224_update(&S->outer, ihash, 224);
	blake224_final(&S->outer, digest);
	memset(ihash, 0, 32);
}

// keylen = number of bytes; inlen = number of bytes
void hmac_blake256_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) {
	hmac_state S;
	hmac_blake256_init(&S, key, keylen);
	hmac_blake256_update(&S, in, inlen * 8);
	hmac_blake256_final(&S, out);
}

// keylen = number of bytes; inlen = number of bytes
void hmac_blake224_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) {
	hmac_state S;
	hmac_blake224_init(&S, key, keylen);
	hmac_blake224_update(&S, in, inlen * 8);
	hmac_blake224_final(&S, out);
}


================================================
FILE: crypto/c_blake256.h
================================================
#ifndef _BLAKE256_H_
#define _BLAKE256_H_

#include <stdint.h>

typedef struct {
  uint32_t h[8], s[4], t[2];
  int buflen, nullt;
  uint8_t buf[64];
} state;

typedef struct {
  state inner;
  state outer;
} hmac_state;

void blake256_init(state *);
void blake224_init(state *);

void blake256_update(state *, const uint8_t *, uint64_t);
void blake224_update(state *, const uint8_t *, uint64_t);

void blake256_final(state *, uint8_t *);
void blake224_final(state *, uint8_t *);

void blake256_hash(uint8_t *, const uint8_t *, uint64_t);
void blake224_hash(uint8_t *, const uint8_t *, uint64_t);

/* HMAC functions: */

void hmac_blake256_init(hmac_state *, const uint8_t *, uint64_t);
void hmac_blake224_init(hmac_state *, const uint8_t *, uint64_t);

void hmac_blake256_update(hmac_state *, const uint8_t *, uint64_t);
void hmac_blake224_update(hmac_state *, const uint8_t *, uint64_t);

void hmac_blake256_final(hmac_state *, uint8_t *);
void hmac_blake224_final(hmac_state *, uint8_t *);

void hmac_blake256_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t);
void hmac_blake224_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t);

#endif /* _BLAKE256_H_ */


================================================
FILE: crypto/c_groestl.c
================================================
/* hash.c     April 2012
 * Groestl ANSI C code optimised for 32-bit machines
 * Author: Thomas Krinninger
 *
 *  This work is based on the implementation of
 *          Soeren S. Thomsen and Krystian Matusiewicz
 *          
 *
 */

#include "c_groestl.h"
#include "groestl_tables.h"

#define P_TYPE 0
#define Q_TYPE 1

const uint8_t shift_Values[2][8] = {{0,1,2,3,4,5,6,7},{1,3,5,7,0,2,4,6}};

const uint8_t indices_cyclic[15] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6};


#define ROTATE_COLUMN_DOWN(v1, v2, amount_bytes, temp_var) {temp_var = (v1<<(8*amount_bytes))|(v2>>(8*(4-amount_bytes))); \
															v2 = (v2<<(8*amount_bytes))|(v1>>(8*(4-amount_bytes))); \
															v1 = temp_var;}
  

#define COLUMN(x,y,i,c0,c1,c2,c3,c4,c5,c6,c7,tv1,tv2,tu,tl,t)				\
   tu = T[2*(uint32_t)x[4*c0+0]];			    \
   tl = T[2*(uint32_t)x[4*c0+0]+1];		    \
   tv1 = T[2*(uint32_t)x[4*c1+1]];			\
   tv2 = T[2*(uint32_t)x[4*c1+1]+1];			\
   ROTATE_COLUMN_DOWN(tv1,tv2,1,t)	\
   tu ^= tv1;						\
   tl ^= tv2;						\
   tv1 = T[2*(uint32_t)x[4*c2+2]];			\
   tv2 = T[2*(uint32_t)x[4*c2+2]+1];			\
   ROTATE_COLUMN_DOWN(tv1,tv2,2,t)	\
   tu ^= tv1;						\
   tl ^= tv2;   					\
   tv1 = T[2*(uint32_t)x[4*c3+3]];			\
   tv2 = T[2*(uint32_t)x[4*c3+3]+1];			\
   ROTATE_COLUMN_DOWN(tv1,tv2,3,t)	\
   tu ^= tv1;						\
   tl ^= tv2;						\
   tl ^= T[2*(uint32_t)x[4*c4+0]];			\
   tu ^= T[2*(uint32_t)x[4*c4+0]+1];			\
   tv1 = T[2*(uint32_t)x[4*c5+1]];			\
   tv2 = T[2*(uint32_t)x[4*c5+1]+1];			\
   ROTATE_COLUMN_DOWN(tv1,tv2,1,t)	\
   tl ^= tv1;						\
   tu ^= tv2;						\
   tv1 = T[2*(uint32_t)x[4*c6+2]];			\
   tv2 = T[2*(uint32_t)x[4*c6+2]+1];			\
   ROTATE_COLUMN_DOWN(tv1,tv2,2,t)	\
   tl ^= tv1;						\
   tu ^= tv2;   					\
   tv1 = T[2*(uint32_t)x[4*c7+3]];			\
   tv2 = T[2*(uint32_t)x[4*c7+3]+1];			\
   ROTATE_COLUMN_DOWN(tv1,tv2,3,t)	\
   tl ^= tv1;						\
   tu ^= tv2;						\
   y[i] = tu;						\
   y[i+1] = tl;


/* compute one round of P (short variants) */
static void RND512P(uint8_t *x, uint32_t *y, uint32_t r) {
  uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp;
  uint32_t* x32 = (uint32_t*)x;
  x32[ 0] ^= 0x00000000^r;
  x32[ 2] ^= 0x00000010^r;
  x32[ 4] ^= 0x00000020^r;
  x32[ 6] ^= 0x00000030^r;
  x32[ 8] ^= 0x00000040^r;
  x32[10] ^= 0x00000050^r;
  x32[12] ^= 0x00000060^r;
  x32[14] ^= 0x00000070^r;
  COLUMN(x,y, 0,  0,  2,  4,  6,  9, 11, 13, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y, 2,  2,  4,  6,  8, 11, 13, 15,  1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y, 4,  4,  6,  8, 10, 13, 15,  1,  3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y, 6,  6,  8, 10, 12, 15,  1,  3,  5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y, 8,  8, 10, 12, 14,  1,  3,  5,  7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y,10, 10, 12, 14,  0,  3,  5,  7,  9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y,12, 12, 14,  0,  2,  5,  7,  9, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y,14, 14,  0,  2,  4,  7,  9, 11, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
}

/* compute one round of Q (short variants) */
static void RND512Q(uint8_t *x, uint32_t *y, uint32_t r) {
  uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp;
  uint32_t* x32 = (uint32_t*)x;
  x32[ 0] = ~x32[ 0];
  x32[ 1] ^= 0xffffffff^r;
  x32[ 2] = ~x32[ 2];
  x32[ 3] ^= 0xefffffff^r;
  x32[ 4] = ~x32[ 4];
  x32[ 5] ^= 0xdfffffff^r;
  x32[ 6] = ~x32[ 6];
  x32[ 7] ^= 0xcfffffff^r;
  x32[ 8] = ~x32[ 8];
  x32[ 9] ^= 0xbfffffff^r;
  x32[10] = ~x32[10];
  x32[11] ^= 0xafffffff^r;
  x32[12] = ~x32[12];
  x32[13] ^= 0x9fffffff^r;
  x32[14] = ~x32[14];
  x32[15] ^= 0x8fffffff^r;
  COLUMN(x,y, 0,  2,  6, 10, 14,  1,  5,  9, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y, 2,  4,  8, 12,  0,  3,  7, 11, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y, 4,  6, 10, 14,  2,  5,  9, 13,  1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y, 6,  8, 12,  0,  4,  7, 11, 15,  3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y, 8, 10, 14,  2,  6,  9, 13,  1,  5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y,10, 12,  0,  4,  8, 11, 15,  3,  7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y,12, 14,  2,  6, 10, 13,  1,  5,  9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
  COLUMN(x,y,14,  0,  4,  8, 12, 15,  3,  7, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp);
}

/* compute compression function (short variants) */
static void F512(uint32_t *h, const uint32_t *m) {
  int i;
  uint32_t Ptmp[2*COLS512];
  uint32_t Qtmp[2*COLS512];
  uint32_t y[2*COLS512];
  uint32_t z[2*COLS512];

  for (i = 0; i < 2*COLS512; i++) {
	z[i] = m[i];
	Ptmp[i] = h[i]^m[i];
  }

  /* compute Q(m) */
  RND512Q((uint8_t*)z, y, 0x00000000);
  RND512Q((uint8_t*)y, z, 0x01000000);
  RND512Q((uint8_t*)z, y, 0x02000000);
  RND512Q((uint8_t*)y, z, 0x03000000);
  RND512Q((uint8_t*)z, y, 0x04000000);
  RND512Q((uint8_t*)y, z, 0x05000000);
  RND512Q((uint8_t*)z, y, 0x06000000);
  RND512Q((uint8_t*)y, z, 0x07000000);
  RND512Q((uint8_t*)z, y, 0x08000000);
  RND512Q((uint8_t*)y, Qtmp, 0x09000000);

  /* compute P(h+m) */
  RND512P((uint8_t*)Ptmp, y, 0x00000000);
  RND512P((uint8_t*)y, z, 0x00000001);
  RND512P((uint8_t*)z, y, 0x00000002);
  RND512P((uint8_t*)y, z, 0x00000003);
  RND512P((uint8_t*)z, y, 0x00000004);
  RND512P((uint8_t*)y, z, 0x00000005);
  RND512P((uint8_t*)z, y, 0x00000006);
  RND512P((uint8_t*)y, z, 0x00000007);
  RND512P((uint8_t*)z, y, 0x00000008);
  RND512P((uint8_t*)y, Ptmp, 0x00000009);

  /* compute P(h+m) + Q(m) + h */
  for (i = 0; i < 2*COLS512; i++) {
	h[i] ^= Ptmp[i]^Qtmp[i];
  }
}


/* digest up to msglen bytes of input (full blocks only) */
static void Transform(groestlHashState *ctx,
	       const uint8_t *input, 
	       int msglen) {

  /* digest message, one block at a time */
  for (; msglen >= SIZE512; 
	   msglen -= SIZE512, input += SIZE512) {
	F512(ctx->chaining,(uint32_t*)input);

	/* increment block counter */
	ctx->block_counter1++;
	if (ctx->block_counter1 == 0) ctx->block_counter2++;
  }
}

/* given state h, do h <- P(h)+h */
static void OutputTransformation(groestlHashState *ctx) {
  int j;
  uint32_t temp[2*COLS512];
  uint32_t y[2*COLS512];
  uint32_t z[2*COLS512];



	for (j = 0; j < 2*COLS512; j++) {
	  temp[j] = ctx->chaining[j];
	}
	RND512P((uint8_t*)temp, y, 0x00000000);
	RND512P((uint8_t*)y, z, 0x00000001);
	RND512P((uint8_t*)z, y, 0x00000002);
	RND512P((uint8_t*)y, z, 0x00000003);
	RND512P((uint8_t*)z, y, 0x00000004);
	RND512P((uint8_t*)y, z, 0x00000005);
	RND512P((uint8_t*)z, y, 0x00000006);
	RND512P((uint8_t*)y, z, 0x00000007);
	RND512P((uint8_t*)z, y, 0x00000008);
	RND512P((uint8_t*)y, temp, 0x00000009);
	for (j = 0; j < 2*COLS512; j++) {
	  ctx->chaining[j] ^= temp[j];
	}									  
}

/* initialise context */
static void Init(groestlHashState* ctx) {
  int i = 0;
  /* allocate memory for state and data buffer */

  for(;i<(SIZE512/sizeof(uint32_t));i++)
  {
	ctx->chaining[i] = 0;
  }

  /* set initial value */
  ctx->chaining[2*COLS512-1] = u32BIG((uint32_t)HASH_BIT_LEN);

  /* set other variables */
  ctx->buf_ptr = 0;
  ctx->block_counter1 = 0;
  ctx->block_counter2 = 0;
  ctx->bits_in_last_byte = 0;
}

/* update state with databitlen bits of input */
static void Update(groestlHashState* ctx,
		  const BitSequence* input,
		  DataLength databitlen) {
  int index = 0;
  int msglen = (int)(databitlen/8);
  int rem = (int)(databitlen%8);

  /* if the buffer contains data that has not yet been digested, first
	 add data to buffer until full */
  if (ctx->buf_ptr) {
	while (ctx->buf_ptr < SIZE512 && index < msglen) {
	  ctx->buffer[(int)ctx->buf_ptr++] = input[index++];
	}
	if (ctx->buf_ptr < SIZE512) {
	  /* buffer still not full, return */
	  if (rem) {
	ctx->bits_in_last_byte = rem;
	ctx->buffer[(int)ctx->buf_ptr++] = input[index];
	  }
	  return;
	}

	/* digest buffer */
	ctx->buf_ptr = 0;
	Transform(ctx, ctx->buffer, SIZE512);
  }

  /* digest bulk of message */
  Transform(ctx, input+index, msglen-index);
  index += ((msglen-index)/SIZE512)*SIZE512;

  /* store remaining data in buffer */
  while (index < msglen) {
	ctx->buffer[(int)ctx->buf_ptr++] = input[index++];
  }

  /* if non-integral number of bytes have been supplied, store
	 remaining bits in last byte, together with information about
	 number of bits */
  if (rem) {
	ctx->bits_in_last_byte = rem;
	ctx->buffer[(int)ctx->buf_ptr++] = input[index];
  }
}

#define BILB ctx->bits_in_last_byte

/* finalise: process remaining data (including padding), perform
   output transformation, and write hash result to 'output' */
static void Final(groestlHashState* ctx,
		 BitSequence* output) {
  int i, j = 0, hashbytelen = HASH_BIT_LEN/8;
  uint8_t *s = (BitSequence*)ctx->chaining;

  /* pad with '1'-bit and first few '0'-bits */
  if (BILB) {
	ctx->buffer[(int)ctx->buf_ptr-1] &= ((1<<BILB)-1)<<(8-BILB);
	ctx->buffer[(int)ctx->buf_ptr-1] ^= 0x1<<(7-BILB);
	BILB = 0;
  }
  else ctx->buffer[(int)ctx->buf_ptr++] = 0x80;

  /* pad with '0'-bits */
  if (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) {
	/* padding requires two blocks */
	while (ctx->buf_ptr < SIZE512) {
	  ctx->buffer[(int)ctx->buf_ptr++] = 0;
	}
	/* digest first padding block */
	Transform(ctx, ctx->buffer, SIZE512);
	ctx->buf_ptr = 0;
  }
  while (ctx->buf_ptr < SIZE512-LENGTHFIELDLEN) {
	ctx->buffer[(int)ctx->buf_ptr++] = 0;
  }

  /* length padding */
  ctx->block_counter1++;
  if (ctx->block_counter1 == 0) ctx->block_counter2++;
  ctx->buf_ptr = SIZE512;

  while (ctx->buf_ptr > SIZE512-(int)sizeof(uint32_t)) {
	ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter1;
	ctx->block_counter1 >>= 8;
  }
  while (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) {
	ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter2;
	ctx->block_counter2 >>= 8;
  }
  /* digest final padding block */
  Transform(ctx, ctx->buffer, SIZE512); 
  /* perform output transformation */
  OutputTransformation(ctx);

  /* store hash result in output */
  for (i = SIZE512-hashbytelen; i < SIZE512; i++,j++) {
	output[j] = s[i];
  }

  /* zeroise relevant variables and deallocate memory */
  for (i = 0; i < COLS512; i++) {
	ctx->chaining[i] = 0;
  }
  for (i = 0; i < SIZE512; i++) {
	ctx->buffer[i] = 0;
  }
}

/* hash bit sequence */
void groestl(const BitSequence* data, 
		DataLength databitlen,
		BitSequence* hashval) {

  groestlHashState context;

  /* initialise */
	Init(&context);


  /* process message */
  Update(&context, data, databitlen);

  /* finalise */
  Final(&context, hashval);
}
/*
static int crypto_hash(unsigned char *out,
		const unsigned char *in,
		unsigned long long len)
{
  groestl(in, 8*len, out);
  return 0;
}

*/


================================================
FILE: crypto/c_groestl.h
================================================
#ifndef __hash_h
#define __hash_h
/*
#include "crypto_uint8.h"
#include "crypto_uint32.h"
#include "crypto_uint64.h"
#include "crypto_hash.h" 

typedef crypto_uint8 uint8_t; 
typedef crypto_uint32 uint32_t; 
typedef crypto_uint64 uint64_t;
*/
#include <stdint.h>

#include "hash.h"

/* some sizes (number of bytes) */
#define ROWS 8
#define LENGTHFIELDLEN ROWS
#define COLS512 8

#define SIZE512 (ROWS*COLS512)

#define ROUNDS512 10
#define HASH_BIT_LEN 256

#define ROTL32(v, n) ((((v)<<(n))|((v)>>(32-(n))))&li_32(ffffffff))


#define li_32(h) 0x##h##u
#define EXT_BYTE(var,n) ((uint8_t)((uint32_t)(var) >> (8*n)))
#define u32BIG(a)				\
  ((ROTL32(a,8) & li_32(00FF00FF)) |		\
   (ROTL32(a,24) & li_32(FF00FF00)))


/* NIST API begin */
typedef struct {
  uint32_t chaining[SIZE512/sizeof(uint32_t)];            /* actual state */
  uint32_t block_counter1,
  block_counter2;         /* message block counter(s) */
  BitSequence buffer[SIZE512];      /* data buffer */
  int buf_ptr;              /* data buffer pointer */
  int bits_in_last_byte;    /* no. of message bits in last byte of
			       data buffer */
} groestlHashState;

/*void Init(hashState*);
void Update(hashState*, const BitSequence*, DataLength);
void Final(hashState*, BitSequence*); */
void groestl(const BitSequence*, DataLength, BitSequence*);
/* NIST API end   */

/*
int crypto_hash(unsigned char *out,
		const unsigned char *in,
		unsigned long long len);
*/

#endif /* __hash_h */


================================================
FILE: crypto/c_jh.c
================================================
/*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C

   --------------------------------
   Performance

   Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz)
   Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic)
   Speed for long message:
   1) 45.8 cycles/byte   compiler: Intel C++ Compiler 11.1   compilation option: icc -O2
   2) 56.8 cycles/byte   compiler: gcc 4.4.3                 compilation option: gcc -O3

   --------------------------------
   Last Modified: January 16, 2011
*/

#include "c_jh.h"

#include <stdint.h>
#include <string.h>

/*typedef unsigned long long uint64;*/
typedef uint64_t uint64;

/*define data alignment for different C compilers*/
#if defined(__GNUC__)
	  #define DATA_ALIGN16(x) x __attribute__ ((aligned(16)))
#else
	  #define DATA_ALIGN16(x) __declspec(align(16)) x
#endif


typedef struct {
	int hashbitlen;	   	              /*the message digest size*/
	unsigned long long databitlen;    /*the message size in bits*/
	unsigned long long datasize_in_buffer;      /*the size of the message remained in buffer; assumed to be multiple of 8bits except for the last partial block at the end of the message*/
	DATA_ALIGN16(uint64 x[8][2]);     /*the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode*/
	unsigned char buffer[64];         /*the 512-bit message block to be hashed;*/
} hashState;


/*The initial hash value H(0)*/
const unsigned char JH224_H0[128]={0x2d,0xfe,0xdd,0x62,0xf9,0x9a,0x98,0xac,0xae,0x7c,0xac,0xd6,0x19,0xd6,0x34,0xe7,0xa4,0x83,0x10,0x5,0xbc,0x30,0x12,0x16,0xb8,0x60,0x38,0xc6,0xc9,0x66,0x14,0x94,0x66,0xd9,0x89,0x9f,0x25,0x80,0x70,0x6f,0xce,0x9e,0xa3,0x1b,0x1d,0x9b,0x1a,0xdc,0x11,0xe8,0x32,0x5f,0x7b,0x36,0x6e,0x10,0xf9,0x94,0x85,0x7f,0x2,0xfa,0x6,0xc1,0x1b,0x4f,0x1b,0x5c,0xd8,0xc8,0x40,0xb3,0x97,0xf6,0xa1,0x7f,0x6e,0x73,0x80,0x99,0xdc,0xdf,0x93,0xa5,0xad,0xea,0xa3,0xd3,0xa4,0x31,0xe8,0xde,0xc9,0x53,0x9a,0x68,0x22,0xb4,0xa9,0x8a,0xec,0x86,0xa1,0xe4,0xd5,0x74,0xac,0x95,0x9c,0xe5,0x6c,0xf0,0x15,0x96,0xd,0xea,0xb5,0xab,0x2b,0xbf,0x96,0x11,0xdc,0xf0,0xdd,0x64,0xea,0x6e};
const unsigned char JH256_H0[128]={0xeb,0x98,0xa3,0x41,0x2c,0x20,0xd3,0xeb,0x92,0xcd,0xbe,0x7b,0x9c,0xb2,0x45,0xc1,0x1c,0x93,0x51,0x91,0x60,0xd4,0xc7,0xfa,0x26,0x0,0x82,0xd6,0x7e,0x50,0x8a,0x3,0xa4,0x23,0x9e,0x26,0x77,0x26,0xb9,0x45,0xe0,0xfb,0x1a,0x48,0xd4,0x1a,0x94,0x77,0xcd,0xb5,0xab,0x26,0x2,0x6b,0x17,0x7a,0x56,0xf0,0x24,0x42,0xf,0xff,0x2f,0xa8,0x71,0xa3,0x96,0x89,0x7f,0x2e,0x4d,0x75,0x1d,0x14,0x49,0x8,0xf7,0x7d,0xe2,0x62,0x27,0x76,0x95,0xf7,0x76,0x24,0x8f,0x94,0x87,0xd5,0xb6,0x57,0x47,0x80,0x29,0x6c,0x5c,0x5e,0x27,0x2d,0xac,0x8e,0xd,0x6c,0x51,0x84,0x50,0xc6,0x57,0x5,0x7a,0xf,0x7b,0xe4,0xd3,0x67,0x70,0x24,0x12,0xea,0x89,0xe3,0xab,0x13,0xd3,0x1c,0xd7,0x69};
const unsigned char JH384_H0[128]={0x48,0x1e,0x3b,0xc6,0xd8,0x13,0x39,0x8a,0x6d,0x3b,0x5e,0x89,0x4a,0xde,0x87,0x9b,0x63,0xfa,0xea,0x68,0xd4,0x80,0xad,0x2e,0x33,0x2c,0xcb,0x21,0x48,0xf,0x82,0x67,0x98,0xae,0xc8,0x4d,0x90,0x82,0xb9,0x28,0xd4,0x55,0xea,0x30,0x41,0x11,0x42,0x49,0x36,0xf5,0x55,0xb2,0x92,0x48,0x47,0xec,0xc7,0x25,0xa,0x93,0xba,0xf4,0x3c,0xe1,0x56,0x9b,0x7f,0x8a,0x27,0xdb,0x45,0x4c,0x9e,0xfc,0xbd,0x49,0x63,0x97,0xaf,0xe,0x58,0x9f,0xc2,0x7d,0x26,0xaa,0x80,0xcd,0x80,0xc0,0x8b,0x8c,0x9d,0xeb,0x2e,0xda,0x8a,0x79,0x81,0xe8,0xf8,0xd5,0x37,0x3a,0xf4,0x39,0x67,0xad,0xdd,0xd1,0x7a,0x71,0xa9,0xb4,0xd3,0xbd,0xa4,0x75,0xd3,0x94,0x97,0x6c,0x3f,0xba,0x98,0x42,0x73,0x7f};
const unsigned char JH512_H0[128]={0x6f,0xd1,0x4b,0x96,0x3e,0x0,0xaa,0x17,0x63,0x6a,0x2e,0x5,0x7a,0x15,0xd5,0x43,0x8a,0x22,0x5e,0x8d,0xc,0x97,0xef,0xb,0xe9,0x34,0x12,0x59,0xf2,0xb3,0xc3,0x61,0x89,0x1d,0xa0,0xc1,0x53,0x6f,0x80,0x1e,0x2a,0xa9,0x5,0x6b,0xea,0x2b,0x6d,0x80,0x58,0x8e,0xcc,0xdb,0x20,0x75,0xba,0xa6,0xa9,0xf,0x3a,0x76,0xba,0xf8,0x3b,0xf7,0x1,0x69,0xe6,0x5,0x41,0xe3,0x4a,0x69,0x46,0xb5,0x8a,0x8e,0x2e,0x6f,0xe6,0x5a,0x10,0x47,0xa7,0xd0,0xc1,0x84,0x3c,0x24,0x3b,0x6e,0x71,0xb1,0x2d,0x5a,0xc1,0x99,0xcf,0x57,0xf6,0xec,0x9d,0xb1,0xf8,0x56,0xa7,0x6,0x88,0x7c,0x57,0x16,0xb1,0x56,0xe3,0xc2,0xfc,0xdf,0xe6,0x85,0x17,0xfb,0x54,0x5a,0x46,0x78,0xcc,0x8c,0xdd,0x4b};

/*42 round constants, each round constant is 32-byte (256-bit)*/
const unsigned char E8_bitslice_roundconstant[42][32]={
{0x72,0xd5,0xde,0xa2,0xdf,0x15,0xf8,0x67,0x7b,0x84,0x15,0xa,0xb7,0x23,0x15,0x57,0x81,0xab,0xd6,0x90,0x4d,0x5a,0x87,0xf6,0x4e,0x9f,0x4f,0xc5,0xc3,0xd1,0x2b,0x40},
{0xea,0x98,0x3a,0xe0,0x5c,0x45,0xfa,0x9c,0x3,0xc5,0xd2,0x99,0x66,0xb2,0x99,0x9a,0x66,0x2,0x96,0xb4,0xf2,0xbb,0x53,0x8a,0xb5,0x56,0x14,0x1a,0x88,0xdb,0xa2,0x31},
{0x3,0xa3,0x5a,0x5c,0x9a,0x19,0xe,0xdb,0x40,0x3f,0xb2,0xa,0x87,0xc1,0x44,0x10,0x1c,0x5,0x19,0x80,0x84,0x9e,0x95,0x1d,0x6f,0x33,0xeb,0xad,0x5e,0xe7,0xcd,0xdc},
{0x10,0xba,0x13,0x92,0x2,0xbf,0x6b,0x41,0xdc,0x78,0x65,0x15,0xf7,0xbb,0x27,0xd0,0xa,0x2c,0x81,0x39,0x37,0xaa,0x78,0x50,0x3f,0x1a,0xbf,0xd2,0x41,0x0,0x91,0xd3},
{0x42,0x2d,0x5a,0xd,0xf6,0xcc,0x7e,0x90,0xdd,0x62,0x9f,0x9c,0x92,0xc0,0x97,0xce,0x18,0x5c,0xa7,0xb,0xc7,0x2b,0x44,0xac,0xd1,0xdf,0x65,0xd6,0x63,0xc6,0xfc,0x23},
{0x97,0x6e,0x6c,0x3,0x9e,0xe0,0xb8,0x1a,0x21,0x5,0x45,0x7e,0x44,0x6c,0xec,0xa8,0xee,0xf1,0x3,0xbb,0x5d,0x8e,0x61,0xfa,0xfd,0x96,0x97,0xb2,0x94,0x83,0x81,0x97},
{0x4a,0x8e,0x85,0x37,0xdb,0x3,0x30,0x2f,0x2a,0x67,0x8d,0x2d,0xfb,0x9f,0x6a,0x95,0x8a,0xfe,0x73,0x81,0xf8,0xb8,0x69,0x6c,0x8a,0xc7,0x72,0x46,0xc0,0x7f,0x42,0x14},
{0xc5,0xf4,0x15,0x8f,0xbd,0xc7,0x5e,0xc4,0x75,0x44,0x6f,0xa7,0x8f,0x11,0xbb,0x80,0x52,0xde,0x75,0xb7,0xae,0xe4,0x88,0xbc,0x82,0xb8,0x0,0x1e,0x98,0xa6,0xa3,0xf4},
{0x8e,0xf4,0x8f,0x33,0xa9,0xa3,0x63,0x15,0xaa,0x5f,0x56,0x24,0xd5,0xb7,0xf9,0x89,0xb6,0xf1,0xed,0x20,0x7c,0x5a,0xe0,0xfd,0x36,0xca,0xe9,0x5a,0x6,0x42,0x2c,0x36},
{0xce,0x29,0x35,0x43,0x4e,0xfe,0x98,0x3d,0x53,0x3a,0xf9,0x74,0x73,0x9a,0x4b,0xa7,0xd0,0xf5,0x1f,0x59,0x6f,0x4e,0x81,0x86,0xe,0x9d,0xad,0x81,0xaf,0xd8,0x5a,0x9f},
{0xa7,0x5,0x6,0x67,0xee,0x34,0x62,0x6a,0x8b,0xb,0x28,0xbe,0x6e,0xb9,0x17,0x27,0x47,0x74,0x7,0x26,0xc6,0x80,0x10,0x3f,0xe0,0xa0,0x7e,0x6f,0xc6,0x7e,0x48,0x7b},
{0xd,0x55,0xa,0xa5,0x4a,0xf8,0xa4,0xc0,0x91,0xe3,0xe7,0x9f,0x97,0x8e,0xf1,0x9e,0x86,0x76,0x72,0x81,0x50,0x60,0x8d,0xd4,0x7e,0x9e,0x5a,0x41,0xf3,0xe5,0xb0,0x62},
{0xfc,0x9f,0x1f,0xec,0x40,0x54,0x20,0x7a,0xe3,0xe4,0x1a,0x0,0xce,0xf4,0xc9,0x84,0x4f,0xd7,0x94,0xf5,0x9d,0xfa,0x95,0xd8,0x55,0x2e,0x7e,0x11,0x24,0xc3,0x54,0xa5},
{0x5b,0xdf,0x72,0x28,0xbd,0xfe,0x6e,0x28,0x78,0xf5,0x7f,0xe2,0xf,0xa5,0xc4,0xb2,0x5,0x89,0x7c,0xef,0xee,0x49,0xd3,0x2e,0x44,0x7e,0x93,0x85,0xeb,0x28,0x59,0x7f},
{0x70,0x5f,0x69,0x37,0xb3,0x24,0x31,0x4a,0x5e,0x86,0x28,0xf1,0x1d,0xd6,0xe4,0x65,0xc7,0x1b,0x77,0x4,0x51,0xb9,0x20,0xe7,0x74,0xfe,0x43,0xe8,0x23,0xd4,0x87,0x8a},
{0x7d,0x29,0xe8,0xa3,0x92,0x76,0x94,0xf2,0xdd,0xcb,0x7a,0x9,0x9b,0x30,0xd9,0xc1,0x1d,0x1b,0x30,0xfb,0x5b,0xdc,0x1b,0xe0,0xda,0x24,0x49,0x4f,0xf2,0x9c,0x82,0xbf},
{0xa4,0xe7,0xba,0x31,0xb4,0x70,0xbf,0xff,0xd,0x32,0x44,0x5,0xde,0xf8,0xbc,0x48,0x3b,0xae,0xfc,0x32,0x53,0xbb,0xd3,0x39,0x45,0x9f,0xc3,0xc1,0xe0,0x29,0x8b,0xa0},
{0xe5,0xc9,0x5,0xfd,0xf7,0xae,0x9,0xf,0x94,0x70,0x34,0x12,0x42,0x90,0xf1,0x34,0xa2,0x71,0xb7,0x1,0xe3,0x44,0xed,0x95,0xe9,0x3b,0x8e,0x36,0x4f,0x2f,0x98,0x4a},
{0x88,0x40,0x1d,0x63,0xa0,0x6c,0xf6,0x15,0x47,0xc1,0x44,0x4b,0x87,0x52,0xaf,0xff,0x7e,0xbb,0x4a,0xf1,0xe2,0xa,0xc6,0x30,0x46,0x70,0xb6,0xc5,0xcc,0x6e,0x8c,0xe6},
{0xa4,0xd5,0xa4,0x56,0xbd,0x4f,0xca,0x0,0xda,0x9d,0x84,0x4b,0xc8,0x3e,0x18,0xae,0x73,0x57,0xce,0x45,0x30,0x64,0xd1,0xad,0xe8,0xa6,0xce,0x68,0x14,0x5c,0x25,0x67},
{0xa3,0xda,0x8c,0xf2,0xcb,0xe,0xe1,0x16,0x33,0xe9,0x6,0x58,0x9a,0x94,0x99,0x9a,0x1f,0x60,0xb2,0x20,0xc2,0x6f,0x84,0x7b,0xd1,0xce,0xac,0x7f,0xa0,0xd1,0x85,0x18},
{0x32,0x59,0x5b,0xa1,0x8d,0xdd,0x19,0xd3,0x50,0x9a,0x1c,0xc0,0xaa,0xa5,0xb4,0x46,0x9f,0x3d,0x63,0x67,0xe4,0x4,0x6b,0xba,0xf6,0xca,0x19,0xab,0xb,0x56,0xee,0x7e},
{0x1f,0xb1,0x79,0xea,0xa9,0x28,0x21,0x74,0xe9,0xbd,0xf7,0x35,0x3b,0x36,0x51,0xee,0x1d,0x57,0xac,0x5a,0x75,0x50,0xd3,0x76,0x3a,0x46,0xc2,0xfe,0xa3,0x7d,0x70,0x1},
{0xf7,0x35,0xc1,0xaf,0x98,0xa4,0xd8,0x42,0x78,0xed,0xec,0x20,0x9e,0x6b,0x67,0x79,0x41,0x83,0x63,0x15,0xea,0x3a,0xdb,0xa8,0xfa,0xc3,0x3b,0x4d,0x32,0x83,0x2c,0x83},
{0xa7,0x40,0x3b,0x1f,0x1c,0x27,0x47,0xf3,0x59,0x40,0xf0,0x34,0xb7,0x2d,0x76,0x9a,0xe7,0x3e,0x4e,0x6c,0xd2,0x21,0x4f,0xfd,0xb8,0xfd,0x8d,0x39,0xdc,0x57,0x59,0xef},
{0x8d,0x9b,0xc,0x49,0x2b,0x49,0xeb,0xda,0x5b,0xa2,0xd7,0x49,0x68,0xf3,0x70,0xd,0x7d,0x3b,0xae,0xd0,0x7a,0x8d,0x55,0x84,0xf5,0xa5,0xe9,0xf0,0xe4,0xf8,0x8e,0x65},
{0xa0,0xb8,0xa2,0xf4,0x36,0x10,0x3b,0x53,0xc,0xa8,0x7,0x9e,0x75,0x3e,0xec,0x5a,0x91,0x68,0x94,0x92,0x56,0xe8,0x88,0x4f,0x5b,0xb0,0x5c,0x55,0xf8,0xba,0xbc,0x4c},
{0xe3,0xbb,0x3b,0x99,0xf3,0x87,0x94,0x7b,0x75,0xda,0xf4,0xd6,0x72,0x6b,0x1c,0x5d,0x64,0xae,0xac,0x28,0xdc,0x34,0xb3,0x6d,0x6c,0x34,0xa5,0x50,0xb8,0x28,0xdb,0x71},
{0xf8,0x61,0xe2,0xf2,0x10,0x8d,0x51,0x2a,0xe3,0xdb,0x64,0x33,0x59,0xdd,0x75,0xfc,0x1c,0xac,0xbc,0xf1,0x43,0xce,0x3f,0xa2,0x67,0xbb,0xd1,0x3c,0x2,0xe8,0x43,0xb0},
{0x33,0xa,0x5b,0xca,0x88,0x29,0xa1,0x75,0x7f,0x34,0x19,0x4d,0xb4,0x16,0x53,0x5c,0x92,0x3b,0x94,0xc3,0xe,0x79,0x4d,0x1e,0x79,0x74,0x75,0xd7,0xb6,0xee,0xaf,0x3f},
{0xea,0xa8,0xd4,0xf7,0xbe,0x1a,0x39,0x21,0x5c,0xf4,0x7e,0x9,0x4c,0x23,0x27,0x51,0x26,0xa3,0x24,0x53,0xba,0x32,0x3c,0xd2,0x44,0xa3,0x17,0x4a,0x6d,0xa6,0xd5,0xad},
{0xb5,0x1d,0x3e,0xa6,0xaf,0xf2,0xc9,0x8,0x83,0x59,0x3d,0x98,0x91,0x6b,0x3c,0x56,0x4c,0xf8,0x7c,0xa1,0x72,0x86,0x60,0x4d,0x46,0xe2,0x3e,0xcc,0x8,0x6e,0xc7,0xf6},
{0x2f,0x98,0x33,0xb3,0xb1,0xbc,0x76,0x5e,0x2b,0xd6,0x66,0xa5,0xef,0xc4,0xe6,0x2a,0x6,0xf4,0xb6,0xe8,0xbe,0xc1,0xd4,0x36,0x74,0xee,0x82,0x15,0xbc,0xef,0x21,0x63},
{0xfd,0xc1,0x4e,0xd,0xf4,0x53,0xc9,0x69,0xa7,0x7d,0x5a,0xc4,0x6,0x58,0x58,0x26,0x7e,0xc1,0x14,0x16,0x6,0xe0,0xfa,0x16,0x7e,0x90,0xaf,0x3d,0x28,0x63,0x9d,0x3f},
{0xd2,0xc9,0xf2,0xe3,0x0,0x9b,0xd2,0xc,0x5f,0xaa,0xce,0x30,0xb7,0xd4,0xc,0x30,0x74,0x2a,0x51,0x16,0xf2,0xe0,0x32,0x98,0xd,0xeb,0x30,0xd8,0xe3,0xce,0xf8,0x9a},
{0x4b,0xc5,0x9e,0x7b,0xb5,0xf1,0x79,0x92,0xff,0x51,0xe6,0x6e,0x4,0x86,0x68,0xd3,0x9b,0x23,0x4d,0x57,0xe6,0x96,0x67,0x31,0xcc,0xe6,0xa6,0xf3,0x17,0xa,0x75,0x5},
{0xb1,0x76,0x81,0xd9,0x13,0x32,0x6c,0xce,0x3c,0x17,0x52,0x84,0xf8,0x5,0xa2,0x62,0xf4,0x2b,0xcb,0xb3,0x78,0x47,0x15,0x47,0xff,0x46,0x54,0x82,0x23,0x93,0x6a,0x48},
{0x38,0xdf,0x58,0x7,0x4e,0x5e,0x65,0x65,0xf2,0xfc,0x7c,0x89,0xfc,0x86,0x50,0x8e,0x31,0x70,0x2e,0x44,0xd0,0xb,0xca,0x86,0xf0,0x40,0x9,0xa2,0x30,0x78,0x47,0x4e},
{0x65,0xa0,0xee,0x39,0xd1,0xf7,0x38,0x83,0xf7,0x5e,0xe9,0x37,0xe4,0x2c,0x3a,0xbd,0x21,0x97,0xb2,0x26,0x1,0x13,0xf8,0x6f,0xa3,0x44,0xed,0xd1,0xef,0x9f,0xde,0xe7},
{0x8b,0xa0,0xdf,0x15,0x76,0x25,0x92,0xd9,0x3c,0x85,0xf7,0xf6,0x12,0xdc,0x42,0xbe,0xd8,0xa7,0xec,0x7c,0xab,0x27,0xb0,0x7e,0x53,0x8d,0x7d,0xda,0xaa,0x3e,0xa8,0xde},
{0xaa,0x25,0xce,0x93,0xbd,0x2,0x69,0xd8,0x5a,0xf6,0x43,0xfd,0x1a,0x73,0x8,0xf9,0xc0,0x5f,0xef,0xda,0x17,0x4a,0x19,0xa5,0x97,0x4d,0x66,0x33,0x4c,0xfd,0x21,0x6a},
{0x35,0xb4,0x98,0x31,0xdb,0x41,0x15,0x70,0xea,0x1e,0xf,0xbb,0xed,0xcd,0x54,0x9b,0x9a,0xd0,0x63,0xa1,0x51,0x97,0x40,0x72,0xf6,0x75,0x9d,0xbf,0x91,0x47,0x6f,0xe2}};


static void E8(hashState *state);  /*The bijective function E8, in bitslice form*/
static void F8(hashState *state);  /*The compression function F8 */

/*The API functions*/
static HashReturn Init(hashState *state, int hashbitlen);
static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen);
static HashReturn Final(hashState *state, BitSequence *hashval);
HashReturn jh_hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval);

/*swapping bit 2i with bit 2i+1 of 64-bit x*/
#define SWAP1(x)   (x) = ((((x) & 0x5555555555555555ULL) << 1) | (((x) & 0xaaaaaaaaaaaaaaaaULL) >> 1));
/*swapping bits 4i||4i+1 with bits 4i+2||4i+3 of 64-bit x*/
#define SWAP2(x)   (x) = ((((x) & 0x3333333333333333ULL) << 2) | (((x) & 0xccccccccccccccccULL) >> 2));
/*swapping bits 8i||8i+1||8i+2||8i+3 with bits 8i+4||8i+5||8i+6||8i+7 of 64-bit x*/
#define SWAP4(x)   (x) = ((((x) & 0x0f0f0f0f0f0f0f0fULL) << 4) | (((x) & 0xf0f0f0f0f0f0f0f0ULL) >> 4));
/*swapping bits 16i||16i+1||......||16i+7  with bits 16i+8||16i+9||......||16i+15 of 64-bit x*/
#define SWAP8(x)   (x) = ((((x) & 0x00ff00ff00ff00ffULL) << 8) | (((x) & 0xff00ff00ff00ff00ULL) >> 8));
/*swapping bits 32i||32i+1||......||32i+15 with bits 32i+16||32i+17||......||32i+31 of 64-bit x*/
#define SWAP16(x)  (x) = ((((x) & 0x0000ffff0000ffffULL) << 16) | (((x) & 0xffff0000ffff0000ULL) >> 16));
/*swapping bits 64i||64i+1||......||64i+31 with bits 64i+32||64i+33||......||64i+63 of 64-bit x*/
#define SWAP32(x)  (x) = (((x) << 32) | ((x) >> 32));

/*The MDS transform*/
#define L(m0,m1,m2,m3,m4,m5,m6,m7) \
	  (m4) ^= (m1);                \
	  (m5) ^= (m2);                \
	  (m6) ^= (m0) ^ (m3);         \
	  (m7) ^= (m0);                \
	  (m0) ^= (m5);                \
	  (m1) ^= (m6);                \
	  (m2) ^= (m4) ^ (m7);         \
	  (m3) ^= (m4);

/*Two Sboxes are computed in parallel, each Sbox implements S0 and S1, selected by a constant bit*/
/*The reason to compute two Sboxes in parallel is to try to fully utilize the parallel processing power*/
#define SS(m0,m1,m2,m3,m4,m5,m6,m7,cc0,cc1)   \
	  m3  = ~(m3);                  \
	  m7  = ~(m7);                  \
	  m0 ^= ((~(m2)) & (cc0));      \
	  m4 ^= ((~(m6)) & (cc1));      \
	  temp0 = (cc0) ^ ((m0) & (m1));\
	  temp1 = (cc1) ^ ((m4) & (m5));\
	  m0 ^= ((m2) & (m3));          \
	  m4 ^= ((m6) & (m7));          \
	  m3 ^= ((~(m1)) & (m2));       \
	  m7 ^= ((~(m5)) & (m6));       \
	  m1 ^= ((m0) & (m2));          \
	  m5 ^= ((m4) & (m6));          \
	  m2 ^= ((m0) & (~(m3)));       \
	  m6 ^= ((m4) & (~(m7)));       \
	  m0 ^= ((m1) | (m3));          \
	  m4 ^= ((m5) | (m7));          \
	  m3 ^= ((m1) & (m2));          \
	  m7 ^= ((m5) & (m6));          \
	  m1 ^= (temp0 & (m0));         \
	  m5 ^= (temp1 & (m4));         \
	  m2 ^= temp0;                  \
	  m6 ^= temp1;

/*The bijective function E8, in bitslice form*/
static void E8(hashState *state)
{
	  uint64 i,roundnumber,temp0,temp1;

	  for (roundnumber = 0; roundnumber < 42; roundnumber = roundnumber+7) {
			/*round 7*roundnumber+0: Sbox, MDS and Swapping layers*/
			for (i = 0; i < 2; i++) {
				  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i+2] );
				  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
				  SWAP1(state->x[1][i]); SWAP1(state->x[3][i]); SWAP1(state->x[5][i]); SWAP1(state->x[7][i]);
			}

			/*round 7*roundnumber+1: Sbox, MDS and Swapping layers*/
			for (i = 0; i < 2; i++) {
				  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i+2] );
				  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
				  SWAP2(state->x[1][i]); SWAP2(state->x[3][i]); SWAP2(state->x[5][i]); SWAP2(state->x[7][i]);
			}

			/*round 7*roundnumber+2: Sbox, MDS and Swapping layers*/
			for (i = 0; i < 2; i++) {
				  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i+2] );
				  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
				  SWAP4(state->x[1][i]); SWAP4(state->x[3][i]); SWAP4(state->x[5][i]); SWAP4(state->x[7][i]);
			}

			/*round 7*roundnumber+3: Sbox, MDS and Swapping layers*/
			for (i = 0; i < 2; i++) {
				  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i+2] );
				  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
				  SWAP8(state->x[1][i]); SWAP8(state->x[3][i]); SWAP8(state->x[5][i]); SWAP8(state->x[7][i]);
			}

			/*round 7*roundnumber+4: Sbox, MDS and Swapping layers*/
			for (i = 0; i < 2; i++) {
				  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i+2] );
				  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
				  SWAP16(state->x[1][i]); SWAP16(state->x[3][i]); SWAP16(state->x[5][i]); SWAP16(state->x[7][i]);
			}

			/*round 7*roundnumber+5: Sbox, MDS and Swapping layers*/
			for (i = 0; i < 2; i++) {
				  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i+2] );
				  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
				  SWAP32(state->x[1][i]); SWAP32(state->x[3][i]); SWAP32(state->x[5][i]); SWAP32(state->x[7][i]);
			}

			/*round 7*roundnumber+6: Sbox and MDS layers*/
			for (i = 0; i < 2; i++) {
				  SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i+2] );
				  L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]);
			}
			/*round 7*roundnumber+6: swapping layer*/
			for (i = 1; i < 8; i = i+2) {
				  temp0 = state->x[i][0]; state->x[i][0] = state->x[i][1]; state->x[i][1] = temp0;
			}
	  }

}

/*The compression function F8 */
static void F8(hashState *state)
{
	  uint64  i;

	  /*xor the 512-bit message with the fist half of the 1024-bit hash state*/
	  for (i = 0; i < 8; i++)  state->x[i >> 1][i & 1] ^= ((uint64*)state->buffer)[i];

	  /*the bijective function E8 */
	  E8(state);

	  /*xor the 512-bit message with the second half of the 1024-bit hash state*/
	  for (i = 0; i < 8; i++)  state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64*)state->buffer)[i];
}

/*before hashing a message, initialize the hash state as H0 */
static HashReturn Init(hashState *state, int hashbitlen)
{
	  state->databitlen = 0;
	  state->datasize_in_buffer = 0;

	  /*initialize the initial hash value of JH*/
	  state->hashbitlen = hashbitlen;

	  /*load the intital hash value into state*/
	  switch (hashbitlen)
	  {
			case 224: memcpy(state->x,JH224_H0,128); break;
			case 256: memcpy(state->x,JH256_H0,128); break;
			case 384: memcpy(state->x,JH384_H0,128); break;
			case 512: memcpy(state->x,JH512_H0,128); break;
	  }

	  return(SUCCESS);
}


/*hash each 512-bit message block, except the last partial block*/
static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen)
{
	  DataLength index; /*the starting address of the data to be compressed*/

	  state->databitlen += databitlen;
	  index = 0;

	  /*if there is remaining data in the buffer, fill it to a full message block first*/
	  /*we assume that the size of the data in the buffer is the multiple of 8 bits if it is not at the end of a message*/

	  /*There is data in the buffer, but the incoming data is insufficient for a full block*/
	  if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) < 512)  ) {
			if ( (databitlen & 7) == 0 ) {
				 memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)) ;
		    }
			else memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)+1) ;
			state->datasize_in_buffer += databitlen;
			databitlen = 0;
	  }

	  /*There is data in the buffer, and the incoming data is sufficient for a full block*/
	  if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) >= 512)  ) {
	        memcpy( state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3) ) ;
	        index = 64-(state->datasize_in_buffer >> 3);
	        databitlen = databitlen - (512 - state->datasize_in_buffer);
	        F8(state);
	        state->datasize_in_buffer = 0;
	  }

	  /*hash the remaining full message blocks*/
	  for ( ; databitlen >= 512; index = index+64, databitlen = databitlen - 512) {
			memcpy(state->buffer, data+index, 64);
			F8(state);
	  }

	  /*store the partial block into buffer, assume that -- if part of the last byte is not part of the message, then that part consists of 0 bits*/
	  if ( databitlen > 0) {
			if ((databitlen & 7) == 0)
				  memcpy(state->buffer, data+index, (databitlen & 0x1ff) >> 3);
			else
				  memcpy(state->buffer, data+index, ((databitlen & 0x1ff) >> 3)+1);
			state->datasize_in_buffer = databitlen;
	  }

	  return(SUCCESS);
}

/*pad the message, process the padded block(s), truncate the hash value H to obtain the message digest*/
static HashReturn Final(hashState *state, BitSequence *hashval)
{
	  unsigned int i;

	  if ( (state->databitlen & 0x1ff) == 0 ) {
			/*pad the message when databitlen is multiple of 512 bits, then process the padded block*/
			memset(state->buffer, 0, 64);
			state->buffer[0]  = 0x80;
			state->buffer[63] = state->databitlen & 0xff;
			state->buffer[62] = (state->databitlen >> 8)  & 0xff;
			state->buffer[61] = (state->databitlen >> 16) & 0xff;
			state->buffer[60] = (state->databitlen >> 24) & 0xff;
			state->buffer[59] = (state->databitlen >> 32) & 0xff;
			state->buffer[58] = (state->databitlen >> 40) & 0xff;
			state->buffer[57] = (state->databitlen >> 48) & 0xff;
			state->buffer[56] = (state->databitlen >> 56) & 0xff;
			F8(state);
	  }
	  else {
		    /*set the rest of the bytes in the buffer to 0*/
			if ( (state->datasize_in_buffer & 7) == 0)
				  for (i = (state->databitlen & 0x1ff) >> 3; i < 64; i++)  state->buffer[i] = 0;
			else
				  for (i = ((state->databitlen & 0x1ff) >> 3)+1; i < 64; i++)  state->buffer[i] = 0;

			/*pad and process the partial block when databitlen is not multiple of 512 bits, then hash the padded blocks*/
			state->buffer[((state->databitlen & 0x1ff) >> 3)] |= 1 << (7- (state->databitlen & 7));

			F8(state);
			memset(state->buffer, 0, 64);
			state->buffer[63] = state->databitlen & 0xff;
			state->buffer[62] = (state->databitlen >> 8) & 0xff;
			state->buffer[61] = (state->databitlen >> 16) & 0xff;
			state->buffer[60] = (state->databitlen >> 24) & 0xff;
			state->buffer[59] = (state->databitlen >> 32) & 0xff;
			state->buffer[58] = (state->databitlen >> 40) & 0xff;
			state->buffer[57] = (state->databitlen >> 48) & 0xff;
			state->buffer[56] = (state->databitlen >> 56) & 0xff;
			F8(state);
	  }

	  /*truncating the final hash value to generate the message digest*/
	  switch(state->hashbitlen) {
			case 224: memcpy(hashval,(unsigned char*)state->x+64+36,28);  break;
			case 256: memcpy(hashval,(unsigned char*)state->x+64+32,32);  break;
			case 384: memcpy(hashval,(unsigned char*)state->x+64+16,48);  break;
			case 512: memcpy(hashval,(unsigned char*)state->x+64,64);     break;
	  }

	  return(SUCCESS);
}

/* hash a message,
   three inputs: message digest size in bits (hashbitlen); message (data); message length in bits (databitlen)
   one output:   message digest (hashval)
*/
HashReturn jh_hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval)
{
	  hashState state;

	  if ( hashbitlen == 224 || hashbitlen == 256 || hashbitlen == 384 || hashbitlen == 512 ) {
			Init(&state, hashbitlen);
			Update(&state, data, databitlen);
			Final(&state, hashval);
			return SUCCESS;
	  }
	  else
			return(BAD_HASHLEN);
}


================================================
FILE: crypto/c_jh.h
================================================
/*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C

   --------------------------------
   Performance

   Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz)
   Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic)
   Speed for long message:
   1) 45.8 cycles/byte   compiler: Intel C++ Compiler 11.1   compilation option: icc -O2
   2) 56.8 cycles/byte   compiler: gcc 4.4.3                 compilation option: gcc -O3

   --------------------------------
   Last Modified: January 16, 2011
*/
#pragma once

#include "hash.h"

HashReturn jh_hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval);


================================================
FILE: crypto/c_keccak.c
================================================
// keccak.c
// 19-Nov-11  Markku-Juhani O. Saarinen <mjos@iki.fi>
// A baseline Keccak (3rd round) implementation.

#include <stdint.h>
#include <memory.h>

#define HASH_DATA_AREA 136
#define KECCAK_ROUNDS 24

#ifndef ROTL64
#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
#endif

const uint64_t keccakf_rndc[24] = 
{
	0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
	0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
	0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
	0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
	0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
	0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 
	0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
	0x8000000000008080, 0x0000000080000001, 0x8000000080008008
};

const int keccakf_rotc[24] = 
{
	1,  3,  6,  10, 15, 21, 28, 36, 45, 55, 2,  14, 
	27, 41, 56, 8,  25, 43, 62, 18, 39, 61, 20, 44
};

const int keccakf_piln[24] = 
{
	10, 7,  11, 17, 18, 3, 5,  16, 8,  21, 24, 4, 
	15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1 
};

// update the state with given number of rounds

void keccakf(uint64_t st[25], int rounds)
{
	int i, j, round;
	uint64_t t, bc[5];

	for (round = 0; round < rounds; ++round) {

		// Theta
		bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
		bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
		bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
		bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
		bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];

		for (i = 0; i < 5; ++i) {
			t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
			st[i     ] ^= t;
			st[i +  5] ^= t;
			st[i + 10] ^= t;
			st[i + 15] ^= t;
			st[i + 20] ^= t;
		}

		// Rho Pi
		t = st[1];
		for (i = 0; i < 24; ++i) {
			bc[0] = st[keccakf_piln[i]];
			st[keccakf_piln[i]] = ROTL64(t, keccakf_rotc[i]);
			t = bc[0];
		}

		//  Chi
		for (j = 0; j < 25; j += 5) {
			bc[0] = st[j    ];
			bc[1] = st[j + 1];
			bc[2] = st[j + 2];
			bc[3] = st[j + 3];
			bc[4] = st[j + 4];
			st[j    ] ^= (~bc[1]) & bc[2];
			st[j + 1] ^= (~bc[2]) & bc[3];
			st[j + 2] ^= (~bc[3]) & bc[4];
			st[j + 3] ^= (~bc[4]) & bc[0];
			st[j + 4] ^= (~bc[0]) & bc[1];
		}

		//  Iota
		st[0] ^= keccakf_rndc[round];
	}
}

// compute a keccak hash (md) of given byte length from "in"
typedef uint64_t state_t[25];

void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen)
{
	state_t st;
	uint8_t temp[144];
	int i, rsiz, rsizw;

	rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen;
	rsizw = rsiz / 8;
	
	memset(st, 0, sizeof(st));

	for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) {
		for (i = 0; i < rsizw; i++)
			st[i] ^= ((uint64_t *) in)[i];
		keccakf(st, KECCAK_ROUNDS);
	}
	
	// last block and padding
	memcpy(temp, in, inlen);
	temp[inlen++] = 1;
	memset(temp + inlen, 0, rsiz - inlen);
	temp[rsiz - 1] |= 0x80;

	for (i = 0; i < rsizw; i++)
		st[i] ^= ((uint64_t *) temp)[i];

	keccakf(st, KECCAK_ROUNDS);

	memcpy(md, st, mdlen);
}

void keccak1600(const uint8_t *in, int inlen, uint8_t *md)
{
	keccak(in, inlen, md, sizeof(state_t));
}

================================================
FILE: crypto/c_keccak.h
================================================
// keccak.h
// 19-Nov-11  Markku-Juhani O. Saarinen <mjos@iki.fi>

#ifndef KECCAK_H
#define KECCAK_H

#include <stdint.h>
#include <string.h>

#ifndef KECCAK_ROUNDS
#define KECCAK_ROUNDS 24
#endif

#ifndef ROTL64
#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
#endif

// compute a keccak hash (md) of given byte length from "in"
int keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen);

// update the state
void keccakf(uint64_t st[25], int norounds);

void keccak1600(const uint8_t *in, int inlen, uint8_t *md);

#endif


================================================
FILE: crypto/c_skein.c
================================================
/***********************************************************************
**
** Implementation of the Skein hash function.
**
** Source code author: Doug Whiting, 2008.
**
** This algorithm and source code is released to the public domain.
** 
************************************************************************/

#define  SKEIN_PORT_CODE /* instantiate any code in skein_port.h */

#include <stddef.h>                          /* get size_t definition */
#include <string.h>      /* get the memcpy/memset functions */
#include "c_skein.h"       /* get the Skein API definitions   */

#define DISABLE_UNUSED 0

#ifndef SKEIN_256_NIST_MAX_HASHBITS
#define SKEIN_256_NIST_MAX_HASHBITS (0)
#endif

#ifndef SKEIN_512_NIST_MAX_HASHBITS
#define SKEIN_512_NIST_MAX_HASHBITS (512)
#endif

#define  SKEIN_MODIFIER_WORDS  ( 2)          /* number of modifier (tweak) words */

#define  SKEIN_256_STATE_WORDS ( 4)
#define  SKEIN_512_STATE_WORDS ( 8)
#define  SKEIN1024_STATE_WORDS (16)
#define  SKEIN_MAX_STATE_WORDS (16)

#define  SKEIN_256_STATE_BYTES ( 8*SKEIN_256_STATE_WORDS)
#define  SKEIN_512_STATE_BYTES ( 8*SKEIN_512_STATE_WORDS)
#define  SKEIN1024_STATE_BYTES ( 8*SKEIN1024_STATE_WORDS)

#define  SKEIN_256_STATE_BITS  (64*SKEIN_256_STATE_WORDS)
#define  SKEIN_512_STATE_BITS  (64*SKEIN_512_STATE_WORDS)
#define  SKEIN1024_STATE_BITS  (64*SKEIN1024_STATE_WORDS)

#define  SKEIN_256_BLOCK_BYTES ( 8*SKEIN_256_STATE_WORDS)
#define  SKEIN_512_BLOCK_BYTES ( 8*SKEIN_512_STATE_WORDS)
#define  SKEIN1024_BLOCK_BYTES ( 8*SKEIN1024_STATE_WORDS)

#define SKEIN_RND_SPECIAL       (1000u)
#define SKEIN_RND_KEY_INITIAL   (SKEIN_RND_SPECIAL+0u)
#define SKEIN_RND_KEY_INJECT    (SKEIN_RND_SPECIAL+1u)
#define SKEIN_RND_FEED_FWD      (SKEIN_RND_SPECIAL+2u)

typedef struct
{
  size_t  hashBitLen;                      /* size of hash result, in bits */
  size_t  bCnt;                            /* current byte count in buffer b[] */
  u64b_t  T[SKEIN_MODIFIER_WORDS];         /* tweak words: T[0]=byte cnt, T[1]=flags */
} Skein_Ctxt_Hdr_t;

typedef struct                               /*  256-bit Skein hash context structure */
{
  Skein_Ctxt_Hdr_t h;                      /* common header context variables */
  u64b_t  X[SKEIN_256_STATE_WORDS];        /* chaining variables */
  u08b_t  b[SKEIN_256_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */
} Skein_256_Ctxt_t;

typedef struct                               /*  512-bit Skein hash context structure */
{
  Skein_Ctxt_Hdr_t h;                      /* common header context variables */
  u64b_t  X[SKEIN_512_STATE_WORDS];        /* chaining variables */
  u08b_t  b[SKEIN_512_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */
} Skein_512_Ctxt_t;

typedef struct                               /* 1024-bit Skein hash context structure */
{
  Skein_Ctxt_Hdr_t h;                      /* common header context variables */
  u64b_t  X[SKEIN1024_STATE_WORDS];        /* chaining variables */
  u08b_t  b[SKEIN1024_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */
} Skein1024_Ctxt_t;

/*   Skein APIs for (incremental) "straight hashing" */
#if SKEIN_256_NIST_MAX_HASH_BITS
static int  Skein_256_Init  (Skein_256_Ctxt_t *ctx, size_t hashBitLen);
#endif
static int  Skein_512_Init  (Skein_512_Ctxt_t *ctx, size_t hashBitLen);
static int  Skein1024_Init  (Skein1024_Ctxt_t *ctx, size_t hashBitLen);

static int  Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);
static int  Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);
static int  Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);

static int  Skein_256_Final (Skein_256_Ctxt_t *ctx, u08b_t * hashVal);
static int  Skein_512_Final (Skein_512_Ctxt_t *ctx, u08b_t * hashVal);
static int  Skein1024_Final (Skein1024_Ctxt_t *ctx, u08b_t * hashVal);

/*
**   Skein APIs for "extended" initialization: MAC keys, tree hashing.
**   After an InitExt() call, just use Update/Final calls as with Init().
**
**   Notes: Same parameters as _Init() calls, plus treeInfo/key/keyBytes.
**          When keyBytes == 0 and treeInfo == SKEIN_SEQUENTIAL, 
**              the results of InitExt() are identical to calling Init().
**          The function Init() may be called once to "precompute" the IV for
**              a given hashBitLen value, then by saving a copy of the context
**              the IV computation may be avoided in later calls.
**          Similarly, the function InitExt() may be called once per MAC key 
**              to precompute the MAC IV, then a copy of the context saved and
**              reused for each new MAC computation.
**/
#if 0
static int  Skein_256_InitExt(Skein_256_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);
static int  Skein_512_InitExt(Skein_512_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);
static int  Skein1024_InitExt(Skein1024_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);
#endif

/*
**   Skein APIs for MAC and tree hash:
**      Final_Pad:  pad, do final block, but no OUTPUT type
**      Output:     do just the output stage
*/
#if 0
static int  Skein_256_Final_Pad(Skein_256_Ctxt_t *ctx, u08b_t * hashVal);
static int  Skein_512_Final_Pad(Skein_512_Ctxt_t *ctx, u08b_t * hashVal);
static int  Skein1024_Final_Pad(Skein1024_Ctxt_t *ctx, u08b_t * hashVal);
#endif

#ifndef SKEIN_TREE_HASH
#define SKEIN_TREE_HASH (1)
#endif
#if 0
#if  SKEIN_TREE_HASH
static int  Skein_256_Output   (Skein_256_Ctxt_t *ctx, u08b_t * hashVal);
static int  Skein_512_Output   (Skein_512_Ctxt_t *ctx, u08b_t * hashVal);
static int  Skein1024_Output   (Skein1024_Ctxt_t *ctx, u08b_t * hashVal);
#endif
#endif

/*****************************************************************
** "Internal" Skein definitions
**    -- not needed for sequential hashing API, but will be 
**           helpful for other uses of Skein (e.g., tree hash mode).
**    -- included here so that they can be shared between
**           reference and optimized code.
******************************************************************/

/* tweak word T[1]: bit field starting positions */
#define SKEIN_T1_BIT(BIT)       ((BIT) - 64)            /* offset 64 because it's the second word  */

#define SKEIN_T1_POS_TREE_LVL   SKEIN_T1_BIT(112)       /* bits 112..118: level in hash tree       */
#define SKEIN_T1_POS_BIT_PAD    SKEIN_T1_BIT(119)       /* bit  119     : partial final input byte */
#define SKEIN_T1_POS_BLK_TYPE   SKEIN_T1_BIT(120)       /* bits 120..125: type field               */
#define SKEIN_T1_POS_FIRST      SKEIN_T1_BIT(126)       /* bits 126     : first block flag         */
#define SKEIN_T1_POS_FINAL      SKEIN_T1_BIT(127)       /* bit  127     : final block flag         */

/* tweak word T[1]: flag bit definition(s) */
#define SKEIN_T1_FLAG_FIRST     (((u64b_t)  1 ) << SKEIN_T1_POS_FIRST)
#define SKEIN_T1_FLAG_FINAL     (((u64b_t)  1 ) << SKEIN_T1_POS_FINAL)
#define SKEIN_T1_FLAG_BIT_PAD   (((u64b_t)  1 ) << SKEIN_T1_POS_BIT_PAD)

/* tweak word T[1]: tree level bit field mask */
#define SKEIN_T1_TREE_LVL_MASK  (((u64b_t)0x7F) << SKEIN_T1_POS_TREE_LVL)
#define SKEIN_T1_TREE_LEVEL(n)  (((u64b_t) (n)) << SKEIN_T1_POS_TREE_LVL)

/* tweak word T[1]: block type field */
#define SKEIN_BLK_TYPE_KEY      ( 0)                    /* key, for MAC and KDF */
#define SKEIN_BLK_TYPE_CFG      ( 4)                    /* configuration block */
#define SKEIN_BLK_TYPE_PERS     ( 8)                    /* personalization string */
#define SKEIN_BLK_TYPE_PK       (12)                    /* public key (for digital signature hashing) */
#define SKEIN_BLK_TYPE_KDF      (16)                    /* key identifier for KDF */
#define SKEIN_BLK_TYPE_NONCE    (20)                    /* nonce for PRNG */
#define SKEIN_BLK_TYPE_MSG      (48)                    /* message processing */
#define SKEIN_BLK_TYPE_OUT      (63)                    /* output stage */
#define SKEIN_BLK_TYPE_MASK     (63)                    /* bit field mask */

#define SKEIN_T1_BLK_TYPE(T)   (((u64b_t) (SKEIN_BLK_TYPE_##T)) << SKEIN_T1_POS_BLK_TYPE)
#define SKEIN_T1_BLK_TYPE_KEY   SKEIN_T1_BLK_TYPE(KEY)  /* key, for MAC and KDF */
#define SKEIN_T1_BLK_TYPE_CFG   SKEIN_T1_BLK_TYPE(CFG)  /* configuration block */
#define SKEIN_T1_BLK_TYPE_PERS  SKEIN_T1_BLK_TYPE(PERS) /* personalization string */
#define SKEIN_T1_BLK_TYPE_PK    SKEIN_T1_BLK_TYPE(PK)   /* public key (for digital signature hashing) */
#define SKEIN_T1_BLK_TYPE_KDF   SKEIN_T1_BLK_TYPE(KDF)  /* key identifier for KDF */
#define SKEIN_T1_BLK_TYPE_NONCE SKEIN_T1_BLK_TYPE(NONCE)/* nonce for PRNG */
#define SKEIN_T1_BLK_TYPE_MSG   SKEIN_T1_BLK_TYPE(MSG)  /* message processing */
#define SKEIN_T1_BLK_TYPE_OUT   SKEIN_T1_BLK_TYPE(OUT)  /* output stage */
#define SKEIN_T1_BLK_TYPE_MASK  SKEIN_T1_BLK_TYPE(MASK) /* field bit mask */

#define SKEIN_T1_BLK_TYPE_CFG_FINAL       (SKEIN_T1_BLK_TYPE_CFG | SKEIN_T1_FLAG_FINAL)
#define SKEIN_T1_BLK_TYPE_OUT_FINAL       (SKEIN_T1_BLK_TYPE_OUT | SKEIN_T1_FLAG_FINAL)

#define SKEIN_VERSION           (1)

#ifndef SKEIN_ID_STRING_LE      /* allow compile-time personalization */
#define SKEIN_ID_STRING_LE      (0x33414853)            /* "SHA3" (little-endian)*/
#endif

#define SKEIN_MK_64(hi32,lo32)  ((lo32) + (((u64b_t) (hi32)) << 32))
#define SKEIN_SCHEMA_VER        SKEIN_MK_64(SKEIN_VERSION,SKEIN_ID_STRING_LE)
#define SKEIN_KS_PARITY         SKEIN_MK_64(0x1BD11BDA,0xA9FC1A22)

#define SKEIN_CFG_STR_LEN       (4*8)

/* bit field definitions in config block treeInfo word */
#define SKEIN_CFG_TREE_LEAF_SIZE_POS  ( 0)
#define SKEIN_CFG_TREE_NODE_SIZE_POS  ( 8)
#define SKEIN_CFG_TREE_MAX_LEVEL_POS  (16)

#define SKEIN_CFG_TREE_LEAF_SIZE_MSK  (((u64b_t) 0xFF) << SKEIN_CFG_TREE_LEAF_SIZE_POS)
#define SKEIN_CFG_TREE_NODE_SIZE_MSK  (((u64b_t) 0xFF) << SKEIN_CFG_TREE_NODE_SIZE_POS)
#define SKEIN_CFG_TREE_MAX_LEVEL_MSK  (((u64b_t) 0xFF) << SKEIN_CFG_TREE_MAX_LEVEL_POS)

#define SKEIN_CFG_TREE_INFO(leaf,node,maxLvl)                   \
  ( (((u64b_t)(leaf  )) << SKEIN_CFG_TREE_LEAF_SIZE_POS) |    \
  (((u64b_t)(node  )) << SKEIN_CFG_TREE_NODE_SIZE_POS) |    \
  (((u64b_t)(maxLvl)) << SKEIN_CFG_TREE_MAX_LEVEL_POS) )

#define SKEIN_CFG_TREE_INFO_SEQUENTIAL SKEIN_CFG_TREE_INFO(0,0,0) /* use as treeInfo in InitExt() call for sequential processing */

/*
**   Skein macros for getting/setting tweak words, etc.
**   These are useful for partial input bytes, hash tree init/update, etc.
**/
#define Skein_Get_Tweak(ctxPtr,TWK_NUM)         ((ctxPtr)->h.T[TWK_NUM])
#define Skein_Set_Tweak(ctxPtr,TWK_NUM,tVal)    {(ctxPtr)->h.T[TWK_NUM] = (tVal);}

#define Skein_Get_T0(ctxPtr)    Skein_Get_Tweak(ctxPtr,0)
#define Skein_Get_T1(ctxPtr)    Skein_Get_Tweak(ctxPtr,1)
#define Skein_Set_T0(ctxPtr,T0) Skein_Set_Tweak(ctxPtr,0,T0)
#define Skein_Set_T1(ctxPtr,T1) Skein_Set_Tweak(ctxPtr,1,T1)

/* set both tweak words at once */
#define Skein_Set_T0_T1(ctxPtr,T0,T1)           \
{                                           \
  Skein_Set_T0(ctxPtr,(T0));                  \
  Skein_Set_T1(ctxPtr,(T1));                  \
}

#define Skein_Set_Type(ctxPtr,BLK_TYPE)         \
  Skein_Set_T1(ctxPtr,SKEIN_T1_BLK_TYPE_##BLK_TYPE)

/* set up for starting with a new type: h.T[0]=0; h.T[1] = NEW_TYPE; h.bCnt=0; */
#define Skein_Start_New_Type(ctxPtr,BLK_TYPE)   \
{ Skein_Set_T0_T1(ctxPtr,0,SKEIN_T1_FLAG_FIRST | SKEIN_T1_BLK_TYPE_##BLK_TYPE); (ctxPtr)->h.bCnt=0; }

#define Skein_Clear_First_Flag(hdr)      { (hdr).T[1] &= ~SKEIN_T1_FLAG_FIRST;       }
#define Skein_Set_Bit_Pad_Flag(hdr)      { (hdr).T[1] |=  SKEIN_T1_FLAG_BIT_PAD;     }

#define Skein_Set_Tree_Level(hdr,height) { (hdr).T[1] |= SKEIN_T1_TREE_LEVEL(height);}

/*****************************************************************
** "Internal" Skein definitions for debugging and error checking
******************************************************************/
#define Skein_Show_Block(bits,ctx,X,blkPtr,wPtr,ksEvenPtr,ksOddPtr)
#define Skein_Show_Round(bits,ctx,r,X)
#define Skein_Show_R_Ptr(bits,ctx,r,X_ptr)
#define Skein_Show_Final(bits,ctx,cnt,outPtr)
#define Skein_Show_Key(bits,ctx,key,keyBytes)


#ifndef SKEIN_ERR_CHECK        /* run-time checks (e.g., bad params, uninitialized context)? */
#define Skein_Assert(x,retCode)/* default: ignore all Asserts, for performance */
#define Skein_assert(x)
#elif   defined(SKEIN_ASSERT)
#include <assert.h>     
#define Skein_Assert(x,retCode) assert(x) 
#define Skein_assert(x)         assert(x) 
#else
#include <assert.h>     
#define Skein_Assert(x,retCode) { if (!(x)) return retCode; } /*  caller  error */
#define Skein_assert(x)         assert(x)                     /* internal error */
#endif

/*****************************************************************
** Skein block function constants (shared across Ref and Opt code)
******************************************************************/
enum    
{   
  /* Skein_256 round rotation constants */
  R_256_0_0=14, R_256_0_1=16,
  R_256_1_0=52, R_256_1_1=57,
  R_256_2_0=23, R_256_2_1=40,
  R_256_3_0= 5, R_256_3_1=37,
  R_256_4_0=25, R_256_4_1=33,
  R_256_5_0=46, R_256_5_1=12,
  R_256_6_0=58, R_256_6_1=22,
  R_256_7_0=32, R_256_7_1=32,

  /* Skein_512 round rotation constants */
  R_512_0_0=46, R_512_0_1=36, R_512_0_2=19, R_512_0_3=37,
  R_512_1_0=33, R_512_1_1=27, R_512_1_2=14, R_512_1_3=42,
  R_512_2_0=17, R_512_2_1=49, R_512_2_2=36, R_512_2_3=39,
  R_512_3_0=44, R_512_3_1= 9, R_512_3_2=54, R_512_3_3=56,
  R_512_4_0=39, R_512_4_1=30, R_512_4_2=34, R_512_4_3=24,
  R_512_5_0=13, R_512_5_1=50, R_512_5_2=10, R_512_5_3=17,
  R_512_6_0=25, R_512_6_1=29, R_512_6_2=39, R_512_6_3=43,
  R_512_7_0= 8, R_512_7_1=35, R_512_7_2=56, R_512_7_3=22,

  /* Skein1024 round rotation constants */
  R1024_0_0=24, R1024_0_1=13, R1024_0_2= 8, R1024_0_3=47, R1024_0_4= 8, R1024_0_5=17, R1024_0_6=22, R1024_0_7=37,
  R1024_1_0=38, R1024_1_1=19, R1024_1_2=10, R1024_1_3=55, R1024_1_4=49, R1024_1_5=18, R1024_1_6=23, R1024_1_7=52,
  R1024_2_0=33, R1024_2_1= 4, R1024_2_2=51, R1024_2_3=13, R1024_2_4=34, R1024_2_5=41, R1024_2_6=59, R1024_2_7=17,
  R1024_3_0= 5, R1024_3_1=20, R1024_3_2=48, R1024_3_3=41, R1024_3_4=47, R1024_3_5=28, R1024_3_6=16, R1024_3_7=25,
  R1024_4_0=41, R1024_4_1= 9, R1024_4_2=37, R1024_4_3=31, R1024_4_4=12, R1024_4_5=47, R1024_4_6=44, R1024_4_7=30,
  R1024_5_0=16, R1024_5_1=34, R1024_5_2=56, R1024_5_3=51, R1024_5_4= 4, R1024_5_5=53, R1024_5_6=42, R1024_5_7=41,
  R1024_6_0=31, R1024_6_1=44, R1024_6_2=47, R1024_6_3=46, R1024_6_4=19, R1024_6_5=42, R1024_6_6=44, R1024_6_7=25,
  R1024_7_0= 9, R1024_7_1=48, R1024_7_2=35, R1024_7_3=52, R1024_7_4=23, R1024_7_5=31, R1024_7_6=37, R1024_7_7=20
};

#ifndef SKEIN_ROUNDS
#define SKEIN_256_ROUNDS_TOTAL (72)          /* number of rounds for the different block sizes */
#define SKEIN_512_ROUNDS_TOTAL (72)
#define SKEIN1024_ROUNDS_TOTAL (80)
#else                                        /* allow command-line define in range 8*(5..14)   */
#define SKEIN_256_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/100) + 5) % 10) + 5))
#define SKEIN_512_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/ 10) + 5) % 10) + 5))
#define SKEIN1024_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS    ) + 5) % 10) + 5))
#endif


/*
***************** Pre-computed Skein IVs *******************
**
** NOTE: these values are not "magic" constants, but
** are generated using the Threefish block function.
** They are pre-computed here only for speed; i.e., to
** avoid the need for a Threefish call during Init().
**
** The IV for any fixed hash length may be pre-computed.
** Only the most common values are included here.
**
************************************************************
**/

#define MK_64 SKEIN_MK_64

/* blkSize =  256 bits. hashSize =  128 bits */
const u64b_t SKEIN_256_IV_128[] =
	{
	MK_64(0xE1111906,0x964D7260),
	MK_64(0x883DAAA7,0x7C8D811C),
	MK_64(0x10080DF4,0x91960F7A),
	MK_64(0xCCF7DDE5,0xB45BC1C2)
	};

/* blkSize =  256 bits. hashSize =  160 bits */
const u64b_t SKEIN_256_IV_160[] =
	{
	MK_64(0x14202314,0x72825E98),
	MK_64(0x2AC4E9A2,0x5A77E590),
	MK_64(0xD47A5856,0x8838D63E),
	MK_64(0x2DD2E496,0x8586AB7D)
	};

/* blkSize =  256 bits. hashSize =  224 bits */
const u64b_t SKEIN_256_IV_224[] =
	{
	MK_64(0xC6098A8C,0x9AE5EA0B),
	MK_64(0x876D5686,0x08C5191C),
	MK_64(0x99CB88D7,0xD7F53884),
	MK_64(0x384BDDB1,0xAEDDB5DE)
	};

/* blkSize =  256 bits. hashSize =  256 bits */
const u64b_t SKEIN_256_IV_256[] =
	{
	MK_64(0xFC9DA860,0xD048B449),
	MK_64(0x2FCA6647,0x9FA7D833),
	MK_64(0xB33BC389,0x6656840F),
	MK_64(0x6A54E920,0xFDE8DA69)
	};

/* blkSize =  512 bits. hashSize =  128 bits */
const u64b_t SKEIN_512_IV_128[] =
	{
	MK_64(0xA8BC7BF3,0x6FBF9F52),
	MK_64(0x1E9872CE,0xBD1AF0AA),
	MK_64(0x309B1790,0xB32190D3),
	MK_64(0xBCFBB854,0x3F94805C),
	MK_64(0x0DA61BCD,0x6E31B11B),
	MK_64(0x1A18EBEA,0xD46A32E3),
	MK_64(0xA2CC5B18,0xCE84AA82),
	MK_64(0x6982AB28,0x9D46982D)
	};

/* blkSize =  512 bits. hashSize =  160 bits */
const u64b_t SKEIN_512_IV_160[] =
	{
	MK_64(0x28B81A2A,0xE013BD91),
	MK_64(0xC2F11668,0xB5BDF78F),
	MK_64(0x1760D8F3,0xF6A56F12),
	MK_64(0x4FB74758,0x8239904F),
	MK_64(0x21EDE07F,0x7EAF5056),
	MK_64(0xD908922E,0x63ED70B8),
	MK_64(0xB8EC76FF,0xECCB52FA),
	MK_64(0x01A47BB8,0xA3F27A6E)
	};

/* blkSize =  512 bits. hashSize =  224 bits */
const u64b_t SKEIN_512_IV_224[] =
	{
	MK_64(0xCCD06162,0x48677224),
	MK_64(0xCBA65CF3,0xA92339EF),
	MK_64(0x8CCD69D6,0x52FF4B64),
	MK_64(0x398AED7B,0x3AB890B4),
	MK_64(0x0F59D1B1,0x457D2BD0),
	MK_64(0x6776FE65,0x75D4EB3D),
	MK_64(0x99FBC70E,0x997413E9),
	MK_64(0x9E2CFCCF,0xE1C41EF7)
	};

/* blkSize =  512 bits. hashSize =  256 bits */
const u64b_t SKEIN_512_IV_256[] =
	{
	MK_64(0xCCD044A1,0x2FDB3E13),
	MK_64(0xE8359030,0x1A79A9EB),
	MK_64(0x55AEA061,0x4F816E6F),
	MK_64(0x2A2767A4,0xAE9B94DB),
	MK_64(0xEC06025E,0x74DD7683),
	MK_64(0xE7A436CD,0xC4746251),
	MK_64(0xC36FBAF9,0x393AD185),
	MK_64(0x3EEDBA18,0x33EDFC13)
	};

/* blkSize =  512 bits. hashSize =  384 bits */
const u64b_t SKEIN_512_IV_384[] =
	{
	MK_64(0xA3F6C6BF,0x3A75EF5F),
	MK_64(0xB0FEF9CC,0xFD84FAA4),
	MK_64(0x9D77DD66,0x3D770CFE),
	MK_64(0xD798CBF3,0xB468FDDA),
	MK_64(0x1BC4A666,0x8A0E4465),
	MK_64(0x7ED7D434,0xE5807407),
	MK_64(0x548FC1AC,0xD4EC44D6),
	MK_64(0x266E1754,0x6AA18FF8)
	};

/* blkSize =  512 bits. hashSize =  512 bits */
const u64b_t SKEIN_512_IV_512[] =
	{
	MK_64(0x4903ADFF,0x749C51CE),
	MK_64(0x0D95DE39,0x9746DF03),
	MK_64(0x8FD19341,0x27C79BCE),
	MK_64(0x9A255629,0xFF352CB1),
	MK_64(0x5DB62599,0xDF6CA7B0),
	MK_64(0xEABE394C,0xA9D5C3F4),
	MK_64(0x991112C7,0x1A75B523),
	MK_64(0xAE18A40B,0x660FCC33)
	};

/* blkSize = 1024 bits. hashSize =  384 bits */
const u64b_t SKEIN1024_IV_384[] =
	{
	MK_64(0x5102B6B8,0xC1894A35),
	MK_64(0xFEEBC9E3,0xFE8AF11A),
	MK_64(0x0C807F06,0xE32BED71),
	MK_64(0x60C13A52,0xB41A91F6),
	MK_64(0x9716D35D,0xD4917C38),
	MK_64(0xE780DF12,0x6FD31D3A),
	MK_64(0x797846B6,0xC898303A),
	MK_64(0xB172C2A8,0xB3572A3B),
	MK_64(0xC9BC8203,0xA6104A6C),
	MK_64(0x65909338,0xD75624F4),
	MK_64(0x94BCC568,0x4B3F81A0),
	MK_64(0x3EBBF51E,0x10ECFD46),
	MK_64(0x2DF50F0B,0xEEB08542),
	MK_64(0x3B5A6530,0x0DBC6516),
	MK_64(0x484B9CD2,0x167BBCE1),
	MK_64(0x2D136947,0xD4CBAFEA)
	};

/* blkSize = 1024 bits. hashSize =  512 bits */
const u64b_t SKEIN1024_IV_512[] =
	{
	MK_64(0xCAEC0E5D,0x7C1B1B18),
	MK_64(0xA01B0E04,0x5F03E802),
	MK_64(0x33840451,0xED912885),
	MK_64(0x374AFB04,0xEAEC2E1C),
	MK_64(0xDF25A0E2,0x813581F7),
	MK_64(0xE4004093,0x8B12F9D2),
	MK_64(0xA662D539,0xC2ED39B6),
	MK_64(0xFA8B85CF,0x45D8C75A),
	MK_64(0x8316ED8E,0x29EDE796),
	MK_64(0x053289C0,0x2E9F91B8),
	MK_64(0xC3F8EF1D,0x6D518B73),
	MK_64(0xBDCEC3C4,0xD5EF332E),
	MK_64(0x549A7E52,0x22974487),
	MK_64(0x67070872,0x5B749816),
	MK_64(0xB9CD28FB,0xF0581BD1),
	MK_64(0x0E2940B8,0x15804974)
	};

/* blkSize = 1024 bits. hashSize = 1024 bits */
const u64b_t SKEIN1024_IV_1024[] =
	{
	MK_64(0xD593DA07,0x41E72355),
	MK_64(0x15B5E511,0xAC73E00C),
	MK_64(0x5180E5AE,0xBAF2C4F0),
	MK_64(0x03BD41D3,0xFCBCAFAF),
	MK_64(0x1CAEC6FD,0x1983A898),
	MK_64(0x6E510B8B,0xCDD0589F),
	MK_64(0x77E2BDFD,0xC6394ADA),
	MK_64(0xC11E1DB5,0x24DCB0A3),
	MK_64(0xD6D14AF9,0xC6329AB5),
	MK_64(0x6A9B0BFC,0x6EB67E0D),
	MK_64(0x9243C60D,0xCCFF1332),
	MK_64(0x1A1F1DDE,0x743F02D4),
	MK_64(0x0996753C,0x10ED0BB8),
	MK_64(0x6572DD22,0xF2B4969A),
	MK_64(0x61FD3062,0xD00A579A),
	MK_64(0x1DE0536E,0x8682E539)
	};


#ifndef SKEIN_USE_ASM
#define SKEIN_USE_ASM   (0)                     /* default is all C code (no ASM) */
#endif

#ifndef SKEIN_LOOP
#define SKEIN_LOOP 001                          /* default: unroll 256 and 512, but not 1024 */
#endif

#define BLK_BITS        (WCNT*64)               /* some useful definitions for code here */
#define KW_TWK_BASE     (0)
#define KW_KEY_BASE     (3)
#define ks              (kw + KW_KEY_BASE)                
#define ts              (kw + KW_TWK_BASE)

#ifdef SKEIN_DEBUG
#define DebugSaveTweak(ctx) { ctx->h.T[0] = ts[0]; ctx->h.T[1] = ts[1]; }
#else
#define DebugSaveTweak(ctx)
#endif

/*****************************  Skein_256 ******************************/
#if !(SKEIN_USE_ASM & 256)
static void Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)
	{ /* do it in C */
	enum
		{
		WCNT = SKEIN_256_STATE_WORDS
		};
#undef  RCNT
#define RCNT  (SKEIN_256_ROUNDS_TOTAL/8)

#ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */
#define SKEIN_UNROLL_256 (((SKEIN_LOOP)/100)%10)
#else
#define SKEIN_UNROLL_256 (0)
#endif

#if SKEIN_UNROLL_256
#if (RCNT % SKEIN_UNROLL_256)
#error "Invalid SKEIN_UNROLL_256"               /* sanity check on unroll count */
#endif
	size_t  r;
	u64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + "rotation"*/
#else
	u64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */
#endif
	u64b_t  X0,X1,X2,X3;                        /* local copy of context vars, for speed */
	u64b_t  w [WCNT];                           /* local copy of input block */
#ifdef SKEIN_DEBUG
	const u64b_t *Xptr[4];                      /* use for debugging (help compiler put Xn in registers) */
	Xptr[0] = &X0;  Xptr[1] = &X1;  Xptr[2] = &X2;  Xptr[3] = &X3;
#endif
	Skein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */
	ts[0] = ctx->h.T[0];
	ts[1] = ctx->h.T[1];
	do  {
		/* this implementation only supports 2**64 input bytes (no carry out here) */
		ts[0] += byteCntAdd;                    /* update processed length */

		/* precompute the key schedule for this block */
		ks[0] = ctx->X[0];     
		ks[1] = ctx->X[1];
		ks[2] = ctx->X[2];
		ks[3] = ctx->X[3];
		ks[4] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ SKEIN_KS_PARITY;

		ts[2] = ts[0] ^ ts[1];

		Skein_Get64_LSB_First(w,blkPtr,WCNT);   /* get input block in little-endian format */
		DebugSaveTweak(ctx);
		Skein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);

		X0 = w[0] + ks[0];                      /* do the first full key injection */
		X1 = w[1] + ks[1] + ts[0];
		X2 = w[2] + ks[2] + ts[1];
		X3 = w[3] + ks[3];

		Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);    /* show starting state values */

		blkPtr += SKEIN_256_BLOCK_BYTES;

		/* run the rounds */

#define Round256(p0,p1,p2,p3,ROT,rNum)                              \
	X##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0; \
	X##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2; \

#if SKEIN_UNROLL_256 == 0                       
#define R256(p0,p1,p2,p3,ROT,rNum)           /* fully unrolled */   \
	Round256(p0,p1,p2,p3,ROT,rNum)                                  \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,rNum,Xptr);

#define I256(R)                                                     \
	X0   += ks[((R)+1) % 5];    /* inject the key schedule value */ \
	X1   += ks[((R)+2) % 5] + ts[((R)+1) % 3];                      \
	X2   += ks[((R)+3) % 5] + ts[((R)+2) % 3];                      \
	X3   += ks[((R)+4) % 5] +     (R)+1;                            \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);
#else                                       /* looping version */
#define R256(p0,p1,p2,p3,ROT,rNum)                                  \
	Round256(p0,p1,p2,p3,ROT,rNum)                                  \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rNum,Xptr);

#define I256(R)                                                     \
	X0   += ks[r+(R)+0];        /* inject the key schedule value */ \
	X1   += ks[r+(R)+1] + ts[r+(R)+0];                              \
	X2   += ks[r+(R)+2] + ts[r+(R)+1];                              \
	X3   += ks[r+(R)+3] +    r+(R)   ;                              \
	ks[r + (R)+4    ]   = ks[r+(R)-1];     /* rotate key schedule */\
	ts[r + (R)+2    ]   = ts[r+(R)-1];                              \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);

	for (r=1;r < 2*RCNT;r+=2*SKEIN_UNROLL_256)  /* loop thru it */
#endif  
		{    
#define R256_8_rounds(R)                  \
		R256(0,1,2,3,R_256_0,8*(R) + 1);  \
		R256(0,3,2,1,R_256_1,8*(R) + 2);  \
		R256(0,1,2,3,R_256_2,8*(R) + 3);  \
		R256(0,3,2,1,R_256_3,8*(R) + 4);  \
		I256(2*(R));                      \
		R256(0,1,2,3,R_256_4,8*(R) + 5);  \
		R256(0,3,2,1,R_256_5,8*(R) + 6);  \
		R256(0,1,2,3,R_256_6,8*(R) + 7);  \
		R256(0,3,2,1,R_256_7,8*(R) + 8);  \
		I256(2*(R)+1);

		R256_8_rounds( 0);

#define R256_Unroll_R(NN) ((SKEIN_UNROLL_256 == 0 && SKEIN_256_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_256 > (NN)))

  #if   R256_Unroll_R( 1)
		R256_8_rounds( 1);
  #endif
  #if   R256_Unroll_R( 2)
		R256_8_rounds( 2);
  #endif
  #if   R256_Unroll_R( 3)
		R256_8_rounds( 3);
  #endif
  #if   R256_Unroll_R( 4)
		R256_8_rounds( 4);
  #endif
  #if   R256_Unroll_R( 5)
		R256_8_rounds( 5);
  #endif
  #if   R256_Unroll_R( 6)
		R256_8_rounds( 6);
  #endif
  #if   R256_Unroll_R( 7)
		R256_8_rounds( 7);
  #endif
  #if   R256_Unroll_R( 8)
		R256_8_rounds( 8);
  #endif
  #if   R256_Unroll_R( 9)
		R256_8_rounds( 9);
  #endif
  #if   R256_Unroll_R(10)
		R256_8_rounds(10);
  #endif
  #if   R256_Unroll_R(11)
		R256_8_rounds(11);
  #endif
  #if   R256_Unroll_R(12)
		R256_8_rounds(12);
  #endif
  #if   R256_Unroll_R(13)
		R256_8_rounds(13);
  #endif
  #if   R256_Unroll_R(14)
		R256_8_rounds(14);
  #endif
  #if  (SKEIN_UNROLL_256 > 14)
#error  "need more unrolling in Skein_256_Process_Block"
  #endif
		}
		/* do the final "feedforward" xor, update context chaining vars */
		ctx->X[0] = X0 ^ w[0];
		ctx->X[1] = X1 ^ w[1];
		ctx->X[2] = X2 ^ w[2];
		ctx->X[3] = X3 ^ w[3];

		Skein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);

		ts[1] &= ~SKEIN_T1_FLAG_FIRST;
		}
	while (--blkCnt);
	ctx->h.T[0] = ts[0];
	ctx->h.T[1] = ts[1];
	}

#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
static size_t Skein_256_Process_Block_CodeSize(void)
	{
	return ((u08b_t *) Skein_256_Process_Block_CodeSize) -
		   ((u08b_t *) Skein_256_Process_Block);
	}
static uint_t Skein_256_Unroll_Cnt(void)
	{
	return SKEIN_UNROLL_256;
	}
#endif
#endif

/*****************************  Skein_512 ******************************/
#if !(SKEIN_USE_ASM & 512)
static void Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)
	{ /* do it in C */
	enum
		{
		WCNT = SKEIN_512_STATE_WORDS
		};
#undef  RCNT
#define RCNT  (SKEIN_512_ROUNDS_TOTAL/8)

#ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */
#define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10)
#else
#define SKEIN_UNROLL_512 (0)
#endif

#if SKEIN_UNROLL_512
#if (RCNT % SKEIN_UNROLL_512)
#error "Invalid SKEIN_UNROLL_512"               /* sanity check on unroll count */
#endif
	size_t  r;
	u64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + "rotation"*/
#else
	u64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */
#endif
	u64b_t  X0,X1,X2,X3,X4,X5,X6,X7;            /* local copy of vars, for speed */
	u64b_t  w [WCNT];                           /* local copy of input block */
#ifdef SKEIN_DEBUG
	const u64b_t *Xptr[8];                      /* use for debugging (help compiler put Xn in registers) */
	Xptr[0] = &X0;  Xptr[1] = &X1;  Xptr[2] = &X2;  Xptr[3] = &X3;
	Xptr[4] = &X4;  Xptr[5] = &X5;  Xptr[6] = &X6;  Xptr[7] = &X7;
#endif

	Skein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */
	ts[0] = ctx->h.T[0];
	ts[1] = ctx->h.T[1];
	do  {
		/* this implementation only supports 2**64 input bytes (no carry out here) */
		ts[0] += byteCntAdd;                    /* update processed length */

		/* precompute the key schedule for this block */
		ks[0] = ctx->X[0];
		ks[1] = ctx->X[1];
		ks[2] = ctx->X[2];
		ks[3] = ctx->X[3];
		ks[4] = ctx->X[4];
		ks[5] = ctx->X[5];
		ks[6] = ctx->X[6];
		ks[7] = ctx->X[7];
		ks[8] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ 
				ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ SKEIN_KS_PARITY;

		ts[2] = ts[0] ^ ts[1];

		Skein_Get64_LSB_First(w,blkPtr,WCNT); /* get input block in little-endian format */
		DebugSaveTweak(ctx);
		Skein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);

		X0   = w[0] + ks[0];                    /* do the first full key injection */
		X1   = w[1] + ks[1];
		X2   = w[2] + ks[2];
		X3   = w[3] + ks[3];
		X4   = w[4] + ks[4];
		X5   = w[5] + ks[5] + ts[0];
		X6   = w[6] + ks[6] + ts[1];
		X7   = w[7] + ks[7];

		blkPtr += SKEIN_512_BLOCK_BYTES;

		Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);
		/* run the rounds */
#define Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                  \
	X##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0; \
	X##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2; \
	X##p4 += X##p5; X##p5 = RotL_64(X##p5,ROT##_2); X##p5 ^= X##p4; \
	X##p6 += X##p7; X##p7 = RotL_64(X##p7,ROT##_3); X##p7 ^= X##p6; \

#if SKEIN_UNROLL_512 == 0                       
#define R512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)      /* unrolled */  \
	Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,rNum,Xptr);

#define I512(R)                                                     \
	X0   += ks[((R)+1) % 9];   /* inject the key schedule value */  \
	X1   += ks[((R)+2) % 9];                                        \
	X2   += ks[((R)+3) % 9];                                        \
	X3   += ks[((R)+4) % 9];                                        \
	X4   += ks[((R)+5) % 9];                                        \
	X5   += ks[((R)+6) % 9] + ts[((R)+1) % 3];                      \
	X6   += ks[((R)+7) % 9] + ts[((R)+2) % 3];                      \
	X7   += ks[((R)+8) % 9] +     (R)+1;                            \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);
#else                                       /* looping version */
#define R512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \
	Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rNum,Xptr);

#define I512(R)                                                     \
	X0   += ks[r+(R)+0];        /* inject the key schedule value */ \
	X1   += ks[r+(R)+1];                                            \
	X2   += ks[r+(R)+2];                                            \
	X3   += ks[r+(R)+3];                                            \
	X4   += ks[r+(R)+4];                                            \
	X5   += ks[r+(R)+5] + ts[r+(R)+0];                              \
	X6   += ks[r+(R)+6] + ts[r+(R)+1];                              \
	X7   += ks[r+(R)+7] +    r+(R)   ;                              \
	ks[r +       (R)+8] = ks[r+(R)-1];  /* rotate key schedule */   \
	ts[r +       (R)+2] = ts[r+(R)-1];                              \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);

	for (r=1;r < 2*RCNT;r+=2*SKEIN_UNROLL_512)   /* loop thru it */
#endif                         /* end of looped code definitions */
		{
#define R512_8_rounds(R)  /* do 8 full rounds */  \
		R512(0,1,2,3,4,5,6,7,R_512_0,8*(R)+ 1);   \
		R512(2,1,4,7,6,5,0,3,R_512_1,8*(R)+ 2);   \
		R512(4,1,6,3,0,5,2,7,R_512_2,8*(R)+ 3);   \
		R512(6,1,0,7,2,5,4,3,R_512_3,8*(R)+ 4);   \
		I512(2*(R));                              \
		R512(0,1,2,3,4,5,6,7,R_512_4,8*(R)+ 5);   \
		R512(2,1,4,7,6,5,0,3,R_512_5,8*(R)+ 6);   \
		R512(4,1,6,3,0,5,2,7,R_512_6,8*(R)+ 7);   \
		R512(6,1,0,7,2,5,4,3,R_512_7,8*(R)+ 8);   \
		I512(2*(R)+1);        /* and key injection */

		R512_8_rounds( 0);

#define R512_Unroll_R(NN) ((SKEIN_UNROLL_512 == 0 && SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_512 > (NN)))

  #if   R512_Unroll_R( 1)
		R512_8_rounds( 1);
  #endif
  #if   R512_Unroll_R( 2)
		R512_8_rounds( 2);
  #endif
  #if   R512_Unroll_R( 3)
		R512_8_rounds( 3);
  #endif
  #if   R512_Unroll_R( 4)
		R512_8_rounds( 4);
  #endif
  #if   R512_Unroll_R( 5)
		R512_8_rounds( 5);
  #endif
  #if   R512_Unroll_R( 6)
		R512_8_rounds( 6);
  #endif
  #if   R512_Unroll_R( 7)
		R512_8_rounds( 7);
  #endif
  #if   R512_Unroll_R( 8)
		R512_8_rounds( 8);
  #endif
  #if   R512_Unroll_R( 9)
		R512_8_rounds( 9);
  #endif
  #if   R512_Unroll_R(10)
		R512_8_rounds(10);
  #endif
  #if   R512_Unroll_R(11)
		R512_8_rounds(11);
  #endif
  #if   R512_Unroll_R(12)
		R512_8_rounds(12);
  #endif
  #if   R512_Unroll_R(13)
		R512_8_rounds(13);
  #endif
  #if   R512_Unroll_R(14)
		R512_8_rounds(14);
  #endif
  #if  (SKEIN_UNROLL_512 > 14)
#error  "need more unrolling in Skein_512_Process_Block"
  #endif
		}

		/* do the final "feedforward" xor, update context chaining vars */
		ctx->X[0] = X0 ^ w[0];
		ctx->X[1] = X1 ^ w[1];
		ctx->X[2] = X2 ^ w[2];
		ctx->X[3] = X3 ^ w[3];
		ctx->X[4] = X4 ^ w[4];
		ctx->X[5] = X5 ^ w[5];
		ctx->X[6] = X6 ^ w[6];
		ctx->X[7] = X7 ^ w[7];
		Skein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);

		ts[1] &= ~SKEIN_T1_FLAG_FIRST;
		}
	while (--blkCnt);
	ctx->h.T[0] = ts[0];
	ctx->h.T[1] = ts[1];
	}

#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
static size_t Skein_512_Process_Block_CodeSize(void)
	{
	return ((u08b_t *) Skein_512_Process_Block_CodeSize) -
		   ((u08b_t *) Skein_512_Process_Block);
	}
static uint_t Skein_512_Unroll_Cnt(void)
	{
	return SKEIN_UNROLL_512;
	}
#endif
#endif

/*****************************  Skein1024 ******************************/
#if !(SKEIN_USE_ASM & 1024)
static void Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)
	{ /* do it in C, always looping (unrolled is bigger AND slower!) */
	enum
		{
		WCNT = SKEIN1024_STATE_WORDS
		};
#undef  RCNT
#define RCNT  (SKEIN1024_ROUNDS_TOTAL/8)

#ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */
#define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10)
#else
#define SKEIN_UNROLL_1024 (0)
#endif

#if (SKEIN_UNROLL_1024 != 0)
#if (RCNT % SKEIN_UNROLL_1024)
#error "Invalid SKEIN_UNROLL_1024"              /* sanity check on unroll count */
#endif
	size_t  r;
	u64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + "rotation"*/
#else
	u64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */
#endif

	u64b_t  X00,X01,X02,X03,X04,X05,X06,X07,    /* local copy of vars, for speed */
			X08,X09,X10,X11,X12,X13,X14,X15;
	u64b_t  w [WCNT];                           /* local copy of input block */
#ifdef SKEIN_DEBUG
	const u64b_t *Xptr[16];                     /* use for debugging (help compiler put Xn in registers) */
	Xptr[ 0] = &X00;  Xptr[ 1] = &X01;  Xptr[ 2] = &X02;  Xptr[ 3] = &X03;
	Xptr[ 4] = &X04;  Xptr[ 5] = &X05;  Xptr[ 6] = &X06;  Xptr[ 7] = &X07;
	Xptr[ 8] = &X08;  Xptr[ 9] = &X09;  Xptr[10] = &X10;  Xptr[11] = &X11;
	Xptr[12] = &X12;  Xptr[13] = &X13;  Xptr[14] = &X14;  Xptr[15] = &X15;
#endif

	Skein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */
	ts[0] = ctx->h.T[0];
	ts[1] = ctx->h.T[1];
	do  {
		/* this implementation only supports 2**64 input bytes (no carry out here) */
		ts[0] += byteCntAdd;                    /* update processed length */

		/* precompute the key schedule for this block */
		ks[ 0] = ctx->X[ 0];
		ks[ 1] = ctx->X[ 1];
		ks[ 2] = ctx->X[ 2];
		ks[ 3] = ctx->X[ 3];
		ks[ 4] = ctx->X[ 4];
		ks[ 5] = ctx->X[ 5];
		ks[ 6] = ctx->X[ 6];
		ks[ 7] = ctx->X[ 7];
		ks[ 8] = ctx->X[ 8];
		ks[ 9] = ctx->X[ 9];
		ks[10] = ctx->X[10];
		ks[11] = ctx->X[11];
		ks[12] = ctx->X[12];
		ks[13] = ctx->X[13];
		ks[14] = ctx->X[14];
		ks[15] = ctx->X[15];
		ks[16] = ks[ 0] ^ ks[ 1] ^ ks[ 2] ^ ks[ 3] ^
				 ks[ 4] ^ ks[ 5] ^ ks[ 6] ^ ks[ 7] ^
				 ks[ 8] ^ ks[ 9] ^ ks[10] ^ ks[11] ^
				 ks[12] ^ ks[13] ^ ks[14] ^ ks[15] ^ SKEIN_KS_PARITY;

		ts[2]  = ts[0] ^ ts[1];

		Skein_Get64_LSB_First(w,blkPtr,WCNT); /* get input block in little-endian format */
		DebugSaveTweak(ctx);
		Skein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);

		X00    = w[ 0] + ks[ 0];                 /* do the first full key injection */
		X01    = w[ 1] + ks[ 1];
		X02    = w[ 2] + ks[ 2];
		X03    = w[ 3] + ks[ 3];
		X04    = w[ 4] + ks[ 4];
		X05    = w[ 5] + ks[ 5];
		X06    = w[ 6] + ks[ 6];
		X07    = w[ 7] + ks[ 7];
		X08    = w[ 8] + ks[ 8];
		X09    = w[ 9] + ks[ 9];
		X10    = w[10] + ks[10];
		X11    = w[11] + ks[11];
		X12    = w[12] + ks[12];
		X13    = w[13] + ks[13] + ts[0];
		X14    = w[14] + ks[14] + ts[1];
		X15    = w[15] + ks[15];

		Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);

#define Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rNum) \
	X##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0;   \
	X##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2;   \
	X##p4 += X##p5; X##p5 = RotL_64(X##p5,ROT##_2); X##p5 ^= X##p4;   \
	X##p6 += X##p7; X##p7 = RotL_64(X##p7,ROT##_3); X##p7 ^= X##p6;   \
	X##p8 += X##p9; X##p9 = RotL_64(X##p9,ROT##_4); X##p9 ^= X##p8;   \
	X##pA += X##pB; X##pB = RotL_64(X##pB,ROT##_5); X##pB ^= X##pA;   \
	X##pC += X##pD; X##pD = RotL_64(X##pD,ROT##_6); X##pD ^= X##pC;   \
	X##pE += X##pF; X##pF = RotL_64(X##pF,ROT##_7); X##pF ^= X##pE;   \

#if SKEIN_UNROLL_1024 == 0                      
#define R1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \
	Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,rn,Xptr);

#define I1024(R)                                                      \
	X00   += ks[((R)+ 1) % 17]; /* inject the key schedule value */   \
	X01   += ks[((R)+ 2) % 17];                                       \
	X02   += ks[((R)+ 3) % 17];                                       \
	X03   += ks[((R)+ 4) % 17];                                       \
	X04   += ks[((R)+ 5) % 17];                                       \
	X05   += ks[((R)+ 6) % 17];                                       \
	X06   += ks[((R)+ 7) % 17];                                       \
	X07   += ks[((R)+ 8) % 17];                                       \
	X08   += ks[((R)+ 9) % 17];                                       \
	X09   += ks[((R)+10) % 17];                                       \
	X10   += ks[((R)+11) % 17];                                       \
	X11   += ks[((R)+12) % 17];                                       \
	X12   += ks[((R)+13) % 17];                                       \
	X13   += ks[((R)+14) % 17] + ts[((R)+1) % 3];                     \
	X14   += ks[((R)+15) % 17] + ts[((R)+2) % 3];                     \
	X15   += ks[((R)+16) % 17] +     (R)+1;                           \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr); 
#else                                       /* looping version */
#define R1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \
	Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rn,Xptr);

#define I1024(R)                                                      \
	X00   += ks[r+(R)+ 0];    /* inject the key schedule value */     \
	X01   += ks[r+(R)+ 1];                                            \
	X02   += ks[r+(R)+ 2];                                            \
	X03   += ks[r+(R)+ 3];                                            \
	X04   += ks[r+(R)+ 4];                                            \
	X05   += ks[r+(R)+ 5];                                            \
	X06   += ks[r+(R)+ 6];                                            \
	X07   += ks[r+(R)+ 7];                                            \
	X08   += ks[r+(R)+ 8];                                            \
	X09   += ks[r+(R)+ 9];                                            \
	X10   += ks[r+(R)+10];                                            \
	X11   += ks[r+(R)+11];                                            \
	X12   += ks[r+(R)+12];                                            \
	X13   += ks[r+(R)+13] + ts[r+(R)+0];                              \
	X14   += ks[r+(R)+14] + ts[r+(R)+1];                              \
	X15   += ks[r+(R)+15] +    r+(R)   ;                              \
	ks[r  +       (R)+16] = ks[r+(R)-1];  /* rotate key schedule */   \
	ts[r  +       (R)+ 2] = ts[r+(R)-1];                              \
	Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);

	for (r=1;r <= 2*RCNT;r+=2*SKEIN_UNROLL_1024)    /* loop thru it */
#endif  
		{
#define R1024_8_rounds(R)    /* do 8 full rounds */                               \
		R1024(00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,R1024_0,8*(R) + 1); \
		R1024(00,09,02,13,06,11,04,15,10,07,12,03,14,05,08,01,R1024_1,8*(R) + 2); \
		R1024(00,07,02,05,04,03,06,01,12,15,14,13,08,11,10,09,R1024_2,8*(R) + 3); \
		R1024(00,15,02,11,06,13,04,09,14,01,08,05,10,03,12,07,R1024_3,8*(R) + 4); \
		I1024(2*(R));                                                             \
		R1024(00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,R1024_4,8*(R) + 5); \
		R1024(00,09,02,13,06,11,04,15,10,07,12,03,14,05,08,01,R1024_5,8*(R) + 6); \
		R1024(00,07,02,05,04,03,06,01,12,15,14,13,08,11,10,09,R1024_6,8*(R) + 7); \
		R1024(00,15,02,11,06,13,04,09,14,01,08,05,10,03,12,07,R1024_7,8*(R) + 8); \
		I1024(2*(R)+1);

		R1024_8_rounds( 0);

#define R1024_Unroll_R(NN) ((SKEIN_UNROLL_1024 == 0 && SKEIN1024_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_1024 > (NN)))

  #if   R1024_Unroll_R( 1)
		R1024_8_rounds( 1);
  #endif
  #if   R1024_Unroll_R( 2)
		R1024_8_rounds( 2);
  #endif
  #if   R1024_Unroll_R( 3)
		R1024_8_rounds( 3);
  #endif
  #if   R1024_Unroll_R( 4)
		R1024_8_rounds( 4);
  #endif
  #if   R1024_Unroll_R( 5)
		R1024_8_rounds( 5);
  #endif
  #if   R1024_Unroll_R( 6)
		R1024_8_rounds( 6);
  #endif
  #if   R1024_Unroll_R( 7)
		R1024_8_rounds( 7);
  #endif
  #if   R1024_Unroll_R( 8)
		R1024_8_rounds( 8);
  #endif
  #if   R1024_Unroll_R( 9)
		R1024_8_rounds( 9);
  #endif
  #if   R1024_Unroll_R(10)
		R1024_8_rounds(10);
  #endif
  #if   R1024_Unroll_R(11)
		R1024_8_rounds(11);
  #endif
  #if   R1024_Unroll_R(12)
		R1024_8_rounds(12);
  #endif
  #if   R1024_Unroll_R(13)
		R1024_8_rounds(13);
  #endif
  #if   R1024_Unroll_R(14)
		R1024_8_rounds(14);
  #endif
  #if  (SKEIN_UNROLL_1024 > 14)
#error  "need more unrolling in Skein_1024_Process_Block"
  #endif
		}
		/* do the final "feedforward" xor, update context chaining vars */

		ctx->X[ 0] = X00 ^ w[ 0];
		ctx->X[ 1] = X01 ^ w[ 1];
		ctx->X[ 2] = X02 ^ w[ 2];
		ctx->X[ 3] = X03 ^ w[ 3];
		ctx->X[ 4] = X04 ^ w[ 4];
		ctx->X[ 5] = X05 ^ w[ 5];
		ctx->X[ 6] = X06 ^ w[ 6];
		ctx->X[ 7] = X07 ^ w[ 7];
		ctx->X[ 8] = X08 ^ w[ 8];
		ctx->X[ 9] = X09 ^ w[ 9];
		ctx->X[10] = X10 ^ w[10];
		ctx->X[11] = X11 ^ w[11];
		ctx->X[12] = X12 ^ w[12];
		ctx->X[13] = X13 ^ w[13];
		ctx->X[14] = X14 ^ w[14];
		ctx->X[15] = X15 ^ w[15];

		Skein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);
		
		ts[1] &= ~SKEIN_T1_FLAG_FIRST;
		blkPtr += SKEIN1024_BLOCK_BYTES;
		}
	while (--blkCnt);
	ctx->h.T[0] = ts[0];
	ctx->h.T[1] = ts[1];
	}

#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
static size_t Skein1024_Process_Block_CodeSize(void)
	{
	return ((u08b_t *) Skein1024_Process_Block_CodeSize) -
		   ((u08b_t *) Skein1024_Process_Block);
	}
static uint_t Skein1024_Unroll_Cnt(void)
	{
	return SKEIN_UNROLL_1024;
	}
#endif
#endif


#if 0
/*****************************************************************/
/*     256-bit Skein                                             */
/*****************************************************************/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* init the context for a straight hashing operation  */
static int Skein_256_Init(Skein_256_Ctxt_t *ctx, size_t hashBitLen)
	{
	union
		{
		u08b_t  b[SKEIN_256_STATE_BYTES];
		u64b_t  w[SKEIN_256_STATE_WORDS];
		} cfg;                              /* config block */
		
	Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
	ctx->h.hashBitLen = hashBitLen;         /* output hash bit count */

	switch (hashBitLen)
		{             /* use pre-computed values, where available */
#ifndef SKEIN_NO_PRECOMP
		case  256: memcpy(ctx->X,SKEIN_256_IV_256,sizeof(ctx->X));  break;
		case  224: memcpy(ctx->X,SKEIN_256_IV_224,sizeof(ctx->X));  break;
		case  160: memcpy(ctx->X,SKEIN_256_IV_160,sizeof(ctx->X));  break;
		case  128: memcpy(ctx->X,SKEIN_256_IV_128,sizeof(ctx->X));  break;
#endif
		default:
			/* here if there is no precomputed IV value available */
			/* build/process the config block, type == CONFIG (could be precomputed) */
			Skein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */

			cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */
			cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */
			cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
			memset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */

			/* compute the initial chaining values from config block */
			memset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */
			Skein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);
			break;
		}
	/* The chaining vars ctx->X are now initialized for the given hashBitLen. */
	/* Set up to process the data message portion of the hash (default) */
	Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type */

	return SKEIN_SUCCESS;
	}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* init the context for a MAC and/or tree hash operation */
/* [identical to Skein_256_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
static int Skein_256_InitExt(Skein_256_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)
	{
	union
		{
		u08b_t  b[SKEIN_256_STATE_BYTES];
		u64b_t  w[SKEIN_256_STATE_WORDS];
		} cfg;                              /* config block */
		
	Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
	Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);

	/* compute the initial chaining values ctx->X[], based on key */
	if (keyBytes == 0)                          /* is there a key? */
		{                                   
		memset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */
		}
	else                                        /* here to pre-process a key */
		{
		Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
		/* do a mini-Init right here */
		ctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */
		Skein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */
		memset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */
		Skein_256_Update(ctx,key,keyBytes);     /* hash the key */
		Skein_256_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */
		memcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */
#if SKEIN_NEED_SWAP
		{
		uint_t i;
		for (i=0;i<SKEIN_256_STATE_WORDS;i++)   /* convert key bytes to context words */
			ctx->X[i] = Skein_Swap64(ctx->X[i]);
		}
#endif
		}
	/* build/process the config block, type == CONFIG (could be precomputed for each key) */
	ctx->h.hashBitLen = hashBitLen;             /* output hash bit count */
	Skein_Start_New_Type(ctx,CFG_FINAL);

	memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */
	cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
	cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */
	cfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */

	Skein_Show_Key(256,&ctx->h,key,keyBytes);

	/* compute the initial chaining values from config block */
	Skein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);

	/* The chaining vars ctx->X are now initialized */
	/* Set up to process the data message portion of the hash (default) */
	ctx->h.bCnt = 0;                            /* buffer b[] starts out empty */
	Skein_Start_New_Type(ctx,MSG);
	
	return SKEIN_SUCCESS;
	}
#endif

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* process the input bytes */
static int Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)
	{
	size_t n;

	Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */

	/* process full blocks, if any */
	if (msgByteCnt + ctx->h.bCnt > SKEIN_256_BLOCK_BYTES)
		{
		if (ctx->h.bCnt)                              /* finish up any buffered message data */
			{
			n = SKEIN_256_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */
			if (n)
				{
				Skein_assert(n < msgByteCnt);         /* check on our logic here */
				memcpy(&ctx->b[ctx->h.bCnt],msg,n);
				msgByteCnt  -= n;
				msg         += n;
				ctx->h.bCnt += n;
				}
			Skein_assert(ctx->h.bCnt == SKEIN_256_BLOCK_BYTES);
			Skein_256_Process_Block(ctx,ctx->b,1,SKEIN_256_BLOCK_BYTES);
			ctx->h.bCnt = 0;
			}
		/* now process any remaining full blocks, directly from input message data */
		if (msgByteCnt > SKEIN_256_BLOCK_BYTES)
			{
			n = (msgByteCnt-1) / SKEIN_256_BLOCK_BYTES;   /* number of full blocks to process */
			Skein_256_Process_Block(ctx,msg,n,SKEIN_256_BLOCK_BYTES);
			msgByteCnt -= n * SKEIN_256_BLOCK_BYTES;
			msg        += n * SKEIN_256_BLOCK_BYTES;
			}
		Skein_assert(ctx->h.bCnt == 0);
		}

	/* copy any remaining source message data bytes into b[] */
	if (msgByteCnt)
		{
		Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES);
		memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);
		ctx->h.bCnt += msgByteCnt;
		}

	return SKEIN_SUCCESS;
	}
   
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* finalize the hash computation and output the result */
static int Skein_256_Final(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)
	{
	size_t i,n,byteCnt;
	u64b_t X[SKEIN_256_STATE_WORDS];
	Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */

	ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */
	if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)            /* zero pad b[] if necessary */
		memset(&ctx->b[ctx->h.bCnt],0,SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);

	Skein_256_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */
	
	/* now output the result */
	byteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */

	/* run Threefish in "counter mode" to generate output */
	memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */
	memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */
	for (i=0;i < byteCnt;i += SKEIN_256_BLOCK_BYTES)
		{
		((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
		Skein_Start_New_Type(ctx,OUT_FINAL);
		Skein_256_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
		n = byteCnt - i;   /* number of output bytes left to go */
		if (n >= SKEIN_256_BLOCK_BYTES)
			n  = SKEIN_256_BLOCK_BYTES;
		Skein_Put64_LSB_First(hashVal+i,ctx->X,n);   /* "output" the ctr mode bytes */
		Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_256_BLOCK_BYTES);
		memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */
		}
	return SKEIN_SUCCESS;
	}

#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
static size_t Skein_256_API_CodeSize(void)
	{
	return ((u08b_t *) Skein_256_API_CodeSize) -
		   ((u08b_t *) Skein_256_Init);
	}
#endif

/*****************************************************************/
/*     512-bit Skein                                             */
/*****************************************************************/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* init the context for a straight hashing operation  */
static int Skein_512_Init(Skein_512_Ctxt_t *ctx, size_t hashBitLen)
	{
	union
		{
		u08b_t  b[SKEIN_512_STATE_BYTES];
		u64b_t  w[SKEIN_512_STATE_WORDS];
		} cfg;                              /* config block */
		
	Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
	ctx->h.hashBitLen = hashBitLen;         /* output hash bit count */

	switch (hashBitLen)
		{             /* use pre-computed values, where available */
#ifndef SKEIN_NO_PRECOMP
		case  512: memcpy(ctx->X,SKEIN_512_IV_512,sizeof(ctx->X));  break;
		case  384: memcpy(ctx->X,SKEIN_512_IV_384,sizeof(ctx->X));  break;
		case  256: memcpy(ctx->X,SKEIN_512_IV_256,sizeof(ctx->X));  break;
		case  224: memcpy(ctx->X,SKEIN_512_IV_224,sizeof(ctx->X));  break;
#endif
		default:
			/* here if there is no precomputed IV value available */
			/* build/process the config block, type == CONFIG (could be precomputed) */
			Skein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */

			cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */
			cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */
			cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
			memset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */

			/* compute the initial chaining values from config block */
			memset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */
			Skein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);
			break;
		}

	/* The chaining vars ctx->X are now initialized for the given hashBitLen. */
	/* Set up to process the data message portion of the hash (default) */
	Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type */

	return SKEIN_SUCCESS;
	}

#if 0
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* init the context for a MAC and/or tree hash operation */
/* [identical to Skein_512_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
static int Skein_512_InitExt(Skein_512_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)
	{
	union
		{
		u08b_t  b[SKEIN_512_STATE_BYTES];
		u64b_t  w[SKEIN_512_STATE_WORDS];
		} cfg;                              /* config block */
		
	Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
	Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);

	/* compute the initial chaining values ctx->X[], based on key */
	if (keyBytes == 0)                          /* is there a key? */
		{                                   
		memset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */
		}
	else                                        /* here to pre-process a key */
		{
		Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
		/* do a mini-Init right here */
		ctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */
		Skein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */
		memset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */
		Skein_512_Update(ctx,key,keyBytes);     /* hash the key */
		Skein_512_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */
		memcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */
#if SKEIN_NEED_SWAP
		{
		uint_t i;
		for (i=0;i<SKEIN_512_STATE_WORDS;i++)   /* convert key bytes to context words */
			ctx->X[i] = Skein_Swap64(ctx->X[i]);
		}
#endif
		}
	/* build/process the config block, type == CONFIG (could be precomputed for each key) */
	ctx->h.hashBitLen = hashBitLen;             /* output hash bit count */
	Skein_Start_New_Type(ctx,CFG_FINAL);

	memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */
	cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
	cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */
	cfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */

	Skein_Show_Key(512,&ctx->h,key,keyBytes);

	/* compute the initial chaining values from config block */
	Skein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);

	/* The chaining vars ctx->X are now initialized */
	/* Set up to process the data message portion of the hash (default) */
	ctx->h.bCnt = 0;                            /* buffer b[] starts out empty */
	Skein_Start_New_Type(ctx,MSG);
	
	return SKEIN_SUCCESS;
	}
#endif

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* process the input bytes */
static int Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)
	{
	size_t n;

	Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */

	/* process full blocks, if any */
	if (msgByteCnt + ctx->h.bCnt > SKEIN_512_BLOCK_BYTES)
		{
		if (ctx->h.bCnt)                              /* finish up any buffered message data */
			{
			n = SKEIN_512_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */
			if (n)
				{
				Skein_assert(n < msgByteCnt);         /* check on our logic here */
				memcpy(&ctx->b[ctx->h.bCnt],msg,n);
				msgByteCnt  -= n;
				msg         += n;
				ctx->h.bCnt += n;
				}
			Skein_assert(ctx->h.bCnt == SKEIN_512_BLOCK_BYTES);
			Skein_512_Process_Block(ctx,ctx->b,1,SKEIN_512_BLOCK_BYTES);
			ctx->h.bCnt = 0;
			}
		/* now process any remaining full blocks, directly from input message data */
		if (msgByteCnt > SKEIN_512_BLOCK_BYTES)
			{
			n = (msgByteCnt-1) / SKEIN_512_BLOCK_BYTES;   /* number of full blocks to process */
			Skein_512_Process_Block(ctx,msg,n,SKEIN_512_BLOCK_BYTES);
			msgByteCnt -= n * SKEIN_512_BLOCK_BYTES;
			msg        += n * SKEIN_512_BLOCK_BYTES;
			}
		Skein_assert(ctx->h.bCnt == 0);
		}

	/* copy any remaining source message data bytes into b[] */
	if (msgByteCnt)
		{
		Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES);
		memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);
		ctx->h.bCnt += msgByteCnt;
		}

	return SKEIN_SUCCESS;
	}
   
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* finalize the hash computation and output the result */
static int Skein_512_Final(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)
	{
	size_t i,n,byteCnt;
	u64b_t X[SKEIN_512_STATE_WORDS];
	Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */

	ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */
	if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)            /* zero pad b[] if necessary */
		memset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);

	Skein_512_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */
	
	/* now output the result */
	byteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */

	/* run Threefish in "counter mode" to generate output */
	memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */
	memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */
	for (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++)
		{
		((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
		Skein_Start_New_Type(ctx,OUT_FINAL);
		Skein_512_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
		n = byteCnt - i*SKEIN_512_BLOCK_BYTES;   /* number of output bytes left to go */
		if (n >= SKEIN_512_BLOCK_BYTES)
			n  = SKEIN_512_BLOCK_BYTES;
		Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n);   /* "output" the ctr mode bytes */
		Skein_Show_Final(512,&ctx->h,n,hashVal+i*SKEIN_512_BLOCK_BYTES);
		memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */
		}
	return SKEIN_SUCCESS;
	}

#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
static size_t Skein_512_API_CodeSize(void)
	{
	return ((u08b_t *) Skein_512_API_CodeSize) -
		   ((u08b_t *) Skein_512_Init);
	}
#endif

/*****************************************************************/
/*    1024-bit Skein                                             */
/*****************************************************************/
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* init the context for a straight hashing operation  */
static int Skein1024_Init(Skein1024_Ctxt_t *ctx, size_t hashBitLen)
	{
	union
		{
		u08b_t  b[SKEIN1024_STATE_BYTES];
		u64b_t  w[SKEIN1024_STATE_WORDS];
		} cfg;                              /* config block */
		
	Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
	ctx->h.hashBitLen = hashBitLen;         /* output hash bit count */

	switch (hashBitLen)
		{              /* use pre-computed values, where available */
#ifndef SKEIN_NO_PRECOMP
		case  512: memcpy(ctx->X,SKEIN1024_IV_512 ,sizeof(ctx->X)); break;
		case  384: memcpy(ctx->X,SKEIN1024_IV_384 ,sizeof(ctx->X)); break;
		case 1024: memcpy(ctx->X,SKEIN1024_IV_1024,sizeof(ctx->X)); break;
#endif
		default:
			/* here if there is no precomputed IV value available */
			/* build/process the config block, type == CONFIG (could be precomputed) */
			Skein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */

			cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */
			cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */
			cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
			memset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */

			/* compute the initial chaining values from config block */
			memset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */
			Skein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);
			break;
		}

	/* The chaining vars ctx->X are now initialized for the given hashBitLen. */
	/* Set up to process the data message portion of the hash (default) */
	Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type */

	return SKEIN_SUCCESS;
	}

#if 0
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* init the context for a MAC and/or tree hash operation */
/* [identical to Skein1024_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
static int Skein1024_InitExt(Skein1024_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)
	{
	union
		{
		u08b_t  b[SKEIN1024_STATE_BYTES];
		u64b_t  w[SKEIN1024_STATE_WORDS];
		} cfg;                              /* config block */
		
	Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
	Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);

	/* compute the initial chaining values ctx->X[], based on key */
	if (keyBytes == 0)                          /* is there a key? */
		{                                   
		memset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */
		}
	else                                        /* here to pre-process a key */
		{
		Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
		/* do a mini-Init right here */
		ctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */
		Skein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */
		memset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */
		Skein1024_Update(ctx,key,keyBytes);     /* hash the key */
		Skein1024_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */
		memcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */
#if SKEIN_NEED_SWAP
		{
		uint_t i;
		for (i=0;i<SKEIN1024_STATE_WORDS;i++)   /* convert key bytes to context words */
			ctx->X[i] = Skein_Swap64(ctx->X[i]);
		}
#endif
		}
	/* build/process the config block, type == CONFIG (could be precomputed for each key) */
	ctx->h.hashBitLen = hashBitLen;             /* output hash bit count */
	Skein_Start_New_Type(ctx,CFG_FINAL);

	memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */
	cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
	cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */
	cfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */

	Skein_Show_Key(1024,&ctx->h,key,keyBytes);

	/* compute the initial chaining values from config block */
	Skein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);

	/* The chaining vars ctx->X are now initialized */
	/* Set up to process the data message portion of the hash (default) */
	ctx->h.bCnt = 0;                            /* buffer b[] starts out empty */
	Skein_Start_New_Type(ctx,MSG);
	
	return SKEIN_SUCCESS;
	}
#endif

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* process the input bytes */
static int Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)
	{
	size_t n;

	Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */

	/* process full blocks, if any */
	if (msgByteCnt + ctx->h.bCnt > SKEIN1024_BLOCK_BYTES)
		{
		if (ctx->h.bCnt)                              /* finish up any buffered message data */
			{
			n = SKEIN1024_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */
			if (n)
				{
				Skein_assert(n < msgByteCnt);         /* check on our logic here */
				memcpy(&ctx->b[ctx->h.bCnt],msg,n);
				msgByteCnt  -= n;
				msg         += n;
				ctx->h.bCnt += n;
				}
			Skein_assert(ctx->h.bCnt == SKEIN1024_BLOCK_BYTES);
			Skein1024_Process_Block(ctx,ctx->b,1,SKEIN1024_BLOCK_BYTES);
			ctx->h.bCnt = 0;
			}
		/* now process any remaining full blocks, directly from input message data */
		if (msgByteCnt > SKEIN1024_BLOCK_BYTES)
			{
			n = (msgByteCnt-1) / SKEIN1024_BLOCK_BYTES;   /* number of full blocks to process */
			Skein1024_Process_Block(ctx,msg,n,SKEIN1024_BLOCK_BYTES);
			msgByteCnt -= n * SKEIN1024_BLOCK_BYTES;
			msg        += n * SKEIN1024_BLOCK_BYTES;
			}
		Skein_assert(ctx->h.bCnt == 0);
		}

	/* copy any remaining source message data bytes into b[] */
	if (msgByteCnt)
		{
		Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES);
		memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);
		ctx->h.bCnt += msgByteCnt;
		}

	return SKEIN_SUCCESS;
	}
   
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* finalize the hash computation and output the result */
static int Skein1024_Final(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)
	{
	size_t i,n,byteCnt;
	u64b_t X[SKEIN1024_STATE_WORDS];
	Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */

	ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */
	if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)            /* zero pad b[] if necessary */
		memset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);

	Skein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */
	
	/* now output the result */
	byteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */

	/* run Threefish in "counter mode" to generate output */
	memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */
	memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */
	for (i=0;i*SKEIN1024_BLOCK_BYTES < byteCnt;i++)
		{
		((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
		Skein_Start_New_Type(ctx,OUT_FINAL);
		Skein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
		n = byteCnt - i*SKEIN1024_BLOCK_BYTES;   /* number of output bytes left t
Download .txt
gitextract_saqq7bck/

├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── amd_gpu/
│   ├── gpu.c
│   └── gpu.h
├── cli-miner.cpp
├── config.txt
├── console.cpp
├── console.h
├── crypto/
│   ├── c_blake256.c
│   ├── c_blake256.h
│   ├── c_groestl.c
│   ├── c_groestl.h
│   ├── c_jh.c
│   ├── c_jh.h
│   ├── c_keccak.c
│   ├── c_keccak.h
│   ├── c_skein.c
│   ├── c_skein.h
│   ├── cryptonight.h
│   ├── cryptonight_aesni.h
│   ├── cryptonight_common.cpp
│   ├── groestl_tables.h
│   ├── hash.h
│   ├── int-util.h
│   ├── skein_port.h
│   └── soft_aes.c
├── donate-level.h
├── executor.cpp
├── executor.h
├── httpd.cpp
├── httpd.h
├── jconf.cpp
├── jconf.h
├── jext.h
├── jpsock.cpp
├── jpsock.h
├── libmicrohttpd/
│   └── microhttpd.h
├── minethd.cpp
├── minethd.h
├── msgstruct.h
├── opencl/
│   ├── blake256.cl
│   ├── cryptonight.cl
│   ├── groestl256.cl
│   ├── jh.cl
│   ├── wolf-aes.cl
│   └── wolf-skein.cl
├── rapidjson/
│   ├── allocators.h
│   ├── document.h
│   ├── encodedstream.h
│   ├── encodings.h
│   ├── error/
│   │   ├── en.h
│   │   └── error.h
│   ├── filereadstream.h
│   ├── filewritestream.h
│   ├── fwd.h
│   ├── internal/
│   │   ├── biginteger.h
│   │   ├── diyfp.h
│   │   ├── dtoa.h
│   │   ├── ieee754.h
│   │   ├── itoa.h
│   │   ├── meta.h
│   │   ├── pow10.h
│   │   ├── regex.h
│   │   ├── stack.h
│   │   ├── strfunc.h
│   │   ├── strtod.h
│   │   └── swap.h
│   ├── istreamwrapper.h
│   ├── memorybuffer.h
│   ├── memorystream.h
│   ├── msinttypes/
│   │   ├── inttypes.h
│   │   └── stdint.h
│   ├── ostreamwrapper.h
│   ├── pointer.h
│   ├── prettywriter.h
│   ├── rapidjson.h
│   ├── reader.h
│   ├── schema.h
│   ├── stream.h
│   ├── stringbuffer.h
│   └── writer.h
├── socket.cpp
├── socket.h
├── socks.h
├── thdq.hpp
├── version.h
├── webdesign.cpp
├── webdesign.h
└── xmr-stak-amd.cbp
Download .txt
SYMBOL INDEX (830 symbols across 69 files)

FILE: amd_gpu/gpu.c
  function port_sleep (line 24) | static inline void port_sleep(size_t sec)
  function port_sleep (line 32) | static inline void port_sleep(size_t sec)
  function int_port (line 38) | static inline long long unsigned int int_port(size_t i)
  function InitOpenCLGpu (line 208) | size_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, char* sourc...
  function InitOpenCL (line 364) | size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx)
  function XMRSetJob (line 461) | size_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint...
  function XMRRunJob (line 590) | size_t XMRRunJob(GpuContext* ctx, cl_uint* HashOutput)

FILE: amd_gpu/gpu.h
  type GpuContext (line 14) | typedef struct _GpuContext

FILE: cli-miner.cpp
  function win_exit (line 46) | void win_exit()
  function win_exit (line 56) | void win_exit() { return; }
  function main (line 61) | int main(int argc, char *argv[])
  function do_benchmark (line 179) | void do_benchmark()

FILE: console.cpp
  function get_key (line 33) | int get_key()
  function set_colour (line 51) | void set_colour(out_colours cl)
  function reset_colour (line 85) | void reset_colour()
  function get_key (line 95) | int get_key()
  function set_colour (line 108) | void set_colour(out_colours cl)
  function reset_colour (line 138) | void reset_colour()
  function comp_localtime (line 144) | inline void comp_localtime(const time_t* ctime, tm* stime)
  function printer_print_msg (line 215) | void printer_print_msg(const char* fmt, ...)
  function printer_print_str (line 241) | void printer_print_str(const char* str)

FILE: console.h
  type out_colours (line 4) | enum out_colours { K_RED, K_GREEN, K_BLUE, K_YELLOW, K_CYAN, K_MAGENTA, ...
  function int_port (line 15) | inline long long unsigned int int_port(size_t i)
  type verbosity (line 20) | enum verbosity : size_t { L0 = 0, L1 = 1, L2 = 2, L3 = 3, L4 = 4, LINF =...
  function class (line 22) | class printer

FILE: crypto/c_blake256.c
  function blake256_compress (line 53) | void blake256_compress(state *S, const uint8_t *block) {
  function blake256_init (line 100) | void blake256_init(state *S) {
  function blake224_init (line 113) | void blake224_init(state *S) {
  function blake256_update (line 127) | void blake256_update(state *S, const uint8_t *data, uint64_t datalen) {
  function blake224_update (line 158) | void blake224_update(state *S, const uint8_t *data, uint64_t datalen) {
  function blake256_final_h (line 162) | void blake256_final_h(state *S, uint8_t *digest, uint8_t pa, uint8_t pb) {
  function blake256_final (line 200) | void blake256_final(state *S, uint8_t *digest) {
  function blake224_final (line 204) | void blake224_final(state *S, uint8_t *digest) {
  function blake256_hash (line 209) | void blake256_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {
  function blake224_hash (line 217) | void blake224_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) {
  function hmac_blake256_init (line 225) | void hmac_blake256_init(hmac_state *S, const uint8_t *_key, uint64_t key...
  function hmac_blake224_init (line 255) | void hmac_blake224_init(hmac_state *S, const uint8_t *_key, uint64_t key...
  function hmac_blake256_update (line 285) | void hmac_blake256_update(hmac_state *S, const uint8_t *data, uint64_t d...
  function hmac_blake224_update (line 291) | void hmac_blake224_update(hmac_state *S, const uint8_t *data, uint64_t d...
  function hmac_blake256_final (line 296) | void hmac_blake256_final(hmac_state *S, uint8_t *digest) {
  function hmac_blake224_final (line 304) | void hmac_blake224_final(hmac_state *S, uint8_t *digest) {
  function hmac_blake256_hash (line 313) | void hmac_blake256_hash(uint8_t *out, const uint8_t *key, uint64_t keyle...
  function hmac_blake224_hash (line 321) | void hmac_blake224_hash(uint8_t *out, const uint8_t *key, uint64_t keyle...

FILE: crypto/c_blake256.h
  type state (line 6) | typedef struct {
  type hmac_state (line 12) | typedef struct {

FILE: crypto/c_groestl.c
  function RND512P (line 67) | static void RND512P(uint8_t *x, uint32_t *y, uint32_t r) {
  function RND512Q (line 89) | static void RND512Q(uint8_t *x, uint32_t *y, uint32_t r) {
  function F512 (line 119) | static void F512(uint32_t *h, const uint32_t *m) {
  function Transform (line 163) | static void Transform(groestlHashState *ctx,
  function OutputTransformation (line 179) | static void OutputTransformation(groestlHashState *ctx) {
  function Init (line 206) | static void Init(groestlHashState* ctx) {
  function Update (line 226) | static void Update(groestlHashState* ctx,
  function Final (line 275) | static void Final(groestlHashState* ctx,
  function groestl (line 335) | void groestl(const BitSequence* data,

FILE: crypto/c_groestl.h
  type groestlHashState (line 38) | typedef struct {

FILE: crypto/c_jh.c
  type uint64 (line 22) | typedef uint64_t uint64;
  type hashState (line 32) | typedef struct {
  function E8 (line 153) | static void E8(hashState *state)
  function F8 (line 214) | static void F8(hashState *state)
  function HashReturn (line 229) | static HashReturn Init(hashState *state, int hashbitlen)
  function HashReturn (line 251) | static HashReturn Update(hashState *state, const BitSequence *data, Data...
  function HashReturn (line 299) | static HashReturn Final(hashState *state, BitSequence *hashval)
  function HashReturn (line 355) | HashReturn jh_hash(int hashbitlen, const BitSequence *data,DataLength da...

FILE: crypto/c_keccak.c
  function keccakf (line 41) | void keccakf(uint64_t st[25], int rounds)
  function keccak (line 94) | void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen)
  function keccak1600 (line 125) | void keccak1600(const uint8_t *in, int inlen, uint8_t *md)

FILE: crypto/c_skein.c
  type Skein_Ctxt_Hdr_t (line 51) | typedef struct
  type Skein_256_Ctxt_t (line 58) | typedef struct                               /*  256-bit Skein hash cont...
  type Skein_512_Ctxt_t (line 65) | typedef struct                               /*  512-bit Skein hash cont...
  type Skein1024_Ctxt_t (line 72) | typedef struct                               /* 1024-bit Skein hash cont...
  function Skein_256_Process_Block (line 532) | static void Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *...
  function Skein_256_Process_Block_CodeSize (line 703) | static size_t Skein_256_Process_Block_CodeSize(void)
  function uint_t (line 708) | static uint_t Skein_256_Unroll_Cnt(void)
  function Skein_512_Process_Block (line 717) | static void Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *...
  function Skein_512_Process_Block_CodeSize (line 911) | static size_t Skein_512_Process_Block_CodeSize(void)
  function uint_t (line 916) | static uint_t Skein_512_Unroll_Cnt(void)
  function Skein1024_Process_Block (line 925) | static void Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *...
  function Skein1024_Process_Block_CodeSize (line 1169) | static size_t Skein1024_Process_Block_CodeSize(void)
  function uint_t (line 1174) | static uint_t Skein1024_Unroll_Cnt(void)
  function Skein_256_Init (line 1189) | static int Skein_256_Init(Skein_256_Ctxt_t *ctx, size_t hashBitLen)
  function Skein_256_InitExt (line 1233) | static int Skein_256_InitExt(Skein_256_Ctxt_t *ctx,size_t hashBitLen,u64...
  function Skein_256_Update (line 1292) | static int Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, si...
  function Skein_256_Final (line 1340) | static int Skein_256_Final(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)
  function Skein_256_API_CodeSize (line 1374) | static size_t Skein_256_API_CodeSize(void)
  function Skein_512_Init (line 1387) | static int Skein_512_Init(Skein_512_Ctxt_t *ctx, size_t hashBitLen)
  function Skein_512_InitExt (line 1433) | static int Skein_512_InitExt(Skein_512_Ctxt_t *ctx,size_t hashBitLen,u64...
  function Skein_512_Update (line 1492) | static int Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, si...
  function Skein_512_Final (line 1540) | static int Skein_512_Final(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)
  function Skein_512_API_CodeSize (line 1574) | static size_t Skein_512_API_CodeSize(void)
  function Skein1024_Init (line 1586) | static int Skein1024_Init(Skein1024_Ctxt_t *ctx, size_t hashBitLen)
  function Skein1024_InitExt (line 1631) | static int Skein1024_InitExt(Skein1024_Ctxt_t *ctx,size_t hashBitLen,u64...
  function Skein1024_Update (line 1690) | static int Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, si...
  function Skein1024_Final (line 1738) | static int Skein1024_Final(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)
  function Skein1024_API_CodeSize (line 1772) | static size_t Skein1024_API_CodeSize(void)
  function Skein_256_Final_Pad (line 1785) | static int Skein_256_Final_Pad(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)
  function Skein_512_Final_Pad (line 1801) | static int Skein_512_Final_Pad(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)
  function Skein1024_Final_Pad (line 1817) | static int Skein1024_Final_Pad(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)
  function Skein_256_Output (line 1835) | static int Skein_256_Output(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)
  function Skein_512_Output (line 1864) | static int Skein_512_Output(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)
  function Skein1024_Output (line 1893) | static int Skein1024_Output(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)
  type hashState (line 1922) | typedef struct
  function SkeinHashReturn (line 1942) | static SkeinHashReturn Init(hashState *state, int hashbitlen)
  function SkeinHashReturn (line 1966) | static SkeinHashReturn Update(hashState *state, const SkeinBitSequence *...
  function SkeinHashReturn (line 2011) | static SkeinHashReturn Final(hashState *state, SkeinBitSequence *hashval)
  function SkeinHashReturn (line 2025) | SkeinHashReturn skein_hash(int hashbitlen, const SkeinBitSequence *data,...

FILE: crypto/c_skein.h
  type SkeinHashReturn (line 32) | typedef enum
  type SkeinDataLength (line 40) | typedef size_t   SkeinDataLength;
  type u08b_t (line 41) | typedef u08b_t   SkeinBitSequence;

FILE: crypto/cryptonight.h
  type cryptonight_ctx (line 13) | typedef struct {

FILE: crypto/cryptonight_aesni.h
  function _umul128 (line 24) | static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi)
  function __m128i (line 52) | static inline __m128i sl_xor(__m128i tmp1)
  function aes_genkey_sub (line 65) | void aes_genkey_sub(__m128i* xout0, __m128i* xout2)
  function soft_aes_genkey_sub (line 77) | static inline void soft_aes_genkey_sub(__m128i* xout0, __m128i* xout2, u...
  function aes_genkey (line 90) | void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i...
  function aes_round (line 129) | static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m1...
  function soft_aes_round (line 141) | static inline void soft_aes_round(__m128i key, __m128i* x0, __m128i* x1,...
  function cryptonight_hash (line 283) | void cryptonight_hash(const void* input, size_t len, void* output, crypt...
  function cryptonight_double_hash (line 342) | void cryptonight_double_hash(const void* input, size_t len, void* output...

FILE: crypto/cryptonight_common.cpp
  function do_blake_hash (line 50) | void do_blake_hash(const void* input, size_t len, char* output) {
  function do_groestl_hash (line 54) | void do_groestl_hash(const void* input, size_t len, char* output) {
  function do_jh_hash (line 58) | void do_jh_hash(const void* input, size_t len, char* output) {
  function do_skein_hash (line 62) | void do_skein_hash(const void* input, size_t len, char* output) {
  function cryptonight_hash_ctx (line 69) | void cryptonight_hash_ctx(const void* input, size_t len, void* output, c...
  function cryptonight_hash_ctx_soft (line 74) | void cryptonight_hash_ctx_soft(const void* input, size_t len, void* outp...

FILE: crypto/hash.h
  type BitSequence (line 3) | typedef unsigned char BitSequence;
  type DataLength (line 4) | typedef unsigned long long DataLength;
  type HashReturn (line 5) | typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn;

FILE: crypto/int-util.h
  function rol32 (line 15) | static inline uint32_t rol32(uint32_t x, int r) {
  function rol64 (line 20) | static inline uint64_t rol64(uint64_t x, int r) {
  function rol32 (line 26) | static inline uint32_t rol32(uint32_t x, int r) {
  function rol64 (line 30) | static inline uint64_t rol64(uint64_t x, int r) {
  function hi_dword (line 36) | static inline uint64_t hi_dword(uint64_t val) {
  function lo_dword (line 40) | static inline uint64_t lo_dword(uint64_t val) {
  function div_with_reminder (line 44) | static inline uint64_t div_with_reminder(uint64_t dividend, uint32_t div...
  function div128_32 (line 51) | static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend...
  function ident32 (line 84) | static inline uint32_t ident32(uint32_t x) { return x; }
  function ident64 (line 85) | static inline uint64_t ident64(uint64_t x) { return x; }
  function swap32 (line 87) | static inline uint32_t swap32(uint32_t x) {
  function swap64 (line 91) | static inline uint64_t swap64(uint64_t x) {
  function mem_inplace_ident (line 102) | static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { }
  function mem_inplace_swap32 (line 105) | static inline void mem_inplace_swap32(void *mem, size_t n) {
  function mem_inplace_swap64 (line 111) | static inline void mem_inplace_swap64(void *mem, size_t n) {
  function memcpy_ident32 (line 118) | static inline void memcpy_ident32(void *dst, const void *src, size_t n) {
  function memcpy_ident64 (line 121) | static inline void memcpy_ident64(void *dst, const void *src, size_t n) {
  function memcpy_swap32 (line 125) | static inline void memcpy_swap32(void *dst, const void *src, size_t n) {
  function memcpy_swap64 (line 131) | static inline void memcpy_swap64(void *dst, const void *src, size_t n) {

FILE: crypto/skein_port.h
  type uint_t (line 60) | typedef unsigned int    uint_t;
  type u08b_t (line 61) | typedef uint8_t         u08b_t;
  type u64b_t (line 62) | typedef uint64_t        u64b_t;
  function Skein_Put64_LSB_First (line 144) | void    Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt)
  function Skein_Get64_LSB_First (line 159) | void    Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt)

FILE: crypto/soft_aes.c
  function __m128i (line 155) | __m128i soft_aesenc(__m128i in, __m128i key)
  function sub_word (line 190) | static inline void sub_word(uint8_t* key)
  function _rotr (line 199) | uint32_t _rotr(uint32_t value, uint32_t amount)
  function __m128i (line 205) | __m128i soft_aeskeygenassist(__m128i key, uint8_t rcon)

FILE: executor.cpp
  function jpsock (line 170) | jpsock* executor::pick_pool_by_id(size_t pool_id)

FILE: executor.h
  function class (line 15) | class executor
  function compare (line 130) | bool compare(std::string& err)
  function reset_stats (line 155) | inline void reset_stats()
  function sec_to_ticks (line 178) | inline size_t sec_to_ticks(size_t sec) { return sec * (1000 / iTickTime); }

FILE: httpd.cpp
  type MHD_Response (line 62) | struct MHD_Response

FILE: httpd.h
  type MHD_Daemon (line 3) | struct MHD_Daemon
  type MHD_Connection (line 4) | struct MHD_Connection
  function class (line 6) | class httpd

FILE: jconf.cpp
  type configEnum (line 48) | enum configEnum { iGpuThreadNum, aGpuThreadsConf, iPlatformIdx,
  type configVal (line 53) | struct configVal {
  function checkType (line 83) | inline bool checkType(Type have, Type want)
  type jconf::opaque_private (line 95) | struct jconf::opaque_private
    method opaque_private (line 100) | opaque_private()

FILE: jconf.h
  function class (line 5) | class jconf

FILE: jext.h
  function Value (line 6) | inline const Value* GetObjectMember(const Value& obj, const char* key)

FILE: jpsock.cpp
  type jpsock::call_rsp (line 41) | struct jpsock::call_rsp
    method call_rsp (line 48) | call_rsp(Value* val) : pCallData(val)
  type jpsock::opaque_private (line 71) | struct jpsock::opaque_private
    method opaque_private (line 81) | opaque_private(uint8_t* bCallMem, uint8_t* bRecvMem, uint8_t* bParseMe...
  type jpsock::opq_json_val (line 91) | struct jpsock::opq_json_val
    method opq_json_val (line 94) | opq_json_val(const Value* val) : val(val) {}
  function hf_hex2bin (line 570) | inline unsigned char hf_hex2bin(char c, bool &err)
  function hf_bin2hex (line 594) | inline char hf_bin2hex(unsigned char c)

FILE: jpsock.h
  function class (line 24) | class jpsock

FILE: libmicrohttpd/microhttpd.h
  type MHD_socket (line 181) | typedef int MHD_socket;
  type SOCKET (line 186) | typedef SOCKET MHD_socket;
  type MHD_Daemon (line 491) | struct MHD_Daemon
  type MHD_Connection (line 501) | struct MHD_Connection
  type MHD_Response (line 507) | struct MHD_Response
  type MHD_PostProcessor (line 513) | struct MHD_PostProcessor
  type MHD_FLAG (line 527) | enum MHD_FLAG
  type MHD_OPTION (line 699) | enum MHD_OPTION
  type MHD_OptionItem (line 1004) | struct MHD_OptionItem
  type MHD_ValueKind (line 1032) | enum MHD_ValueKind
  type MHD_RequestTerminationCode (line 1078) | enum MHD_RequestTerminationCode
  type MHD_ConnectionNotificationCode (line 1136) | enum MHD_ConnectionNotificationCode
  type sockaddr (line 1193) | struct sockaddr
  type MHD_Daemon (line 1199) | struct MHD_Daemon
  type MHD_ConnectionInfoType (line 1214) | enum MHD_ConnectionInfoType
  type MHD_DaemonInfoType (line 1288) | enum MHD_DaemonInfoType
  type sockaddr (line 1346) | struct sockaddr
  type MHD_Connection (line 1391) | struct MHD_Connection
  type MHD_Connection (line 1414) | struct MHD_Connection
  type MHD_RequestTerminationCode (line 1416) | enum MHD_RequestTerminationCode
  type MHD_Connection (line 1439) | struct MHD_Connection
  type MHD_ConnectionNotificationCode (line 1441) | enum MHD_ConnectionNotificationCode
  type MHD_ValueKind (line 1461) | enum MHD_ValueKind
  type MHD_ValueKind (line 1551) | enum MHD_ValueKind
  type MHD_Daemon (line 1631) | struct MHD_Daemon
  type MHD_Daemon (line 1641) | struct MHD_Daemon
  type MHD_Daemon (line 1674) | struct MHD_Daemon
  type sockaddr (line 1676) | struct sockaddr
  type MHD_Daemon (line 1700) | struct MHD_Daemon
  type MHD_Daemon (line 1729) | struct MHD_Daemon
  type MHD_Daemon (line 1775) | struct MHD_Daemon
  type MHD_Daemon (line 1799) | struct MHD_Daemon
  type MHD_Daemon (line 1822) | struct MHD_Daemon
  type MHD_Connection (line 1844) | struct MHD_Connection
  type MHD_ValueKind (line 1845) | enum MHD_ValueKind
  type MHD_Connection (line 1876) | struct MHD_Connection
  type MHD_ValueKind (line 1877) | enum MHD_ValueKind
  type MHD_Connection (line 1926) | struct MHD_Connection
  type MHD_ValueKind (line 1927) | enum MHD_ValueKind
  type MHD_Connection (line 1943) | struct MHD_Connection
  type MHD_Response (line 1945) | struct MHD_Response
  type MHD_Connection (line 1976) | struct MHD_Connection
  type MHD_Connection (line 1988) | struct MHD_Connection
  type MHD_ResponseFlags (line 1997) | enum MHD_ResponseFlags
  type MHD_ResponseOptions (line 2017) | enum MHD_ResponseOptions
  type MHD_Response (line 2035) | struct MHD_Response
  type MHD_ResponseFlags (line 2036) | enum MHD_ResponseFlags
  type MHD_Response (line 2078) | struct MHD_Response
  type MHD_ResponseMemoryMode (line 2090) | enum MHD_ResponseMemoryMode
  type MHD_ResponseMemoryMode (line 2134) | enum MHD_ResponseMemoryMode
  type MHD_Response (line 2188) | struct MHD_Response
  type MHD_UpgradeAction (line 2231) | enum MHD_UpgradeAction
  type MHD_UpgradeResponseHandle (line 2260) | struct MHD_UpgradeResponseHandle
  type MHD_UpgradeResponseHandle (line 2276) | struct MHD_UpgradeResponseHandle
  type MHD_UpgradeAction (line 2277) | enum MHD_UpgradeAction
  type MHD_Connection (line 2334) | struct MHD_Connection
  type MHD_UpgradeResponseHandle (line 2338) | struct MHD_UpgradeResponseHandle
  type MHD_Response (line 2385) | struct MHD_Response
  type MHD_Response (line 2399) | struct MHD_Response
  type MHD_Response (line 2414) | struct MHD_Response
  type MHD_Response (line 2429) | struct MHD_Response
  type MHD_Response (line 2445) | struct MHD_Response
  type MHD_Response (line 2458) | struct MHD_Response
  type MHD_Connection (line 2490) | struct MHD_Connection
  type MHD_PostProcessor (line 2509) | struct MHD_PostProcessor
  type MHD_PostProcessor (line 2524) | struct MHD_PostProcessor
  type MHD_Connection (line 2547) | struct MHD_Connection
  type MHD_Connection (line 2564) | struct MHD_Connection
  type MHD_Connection (line 2586) | struct MHD_Connection
  type MHD_Response (line 2589) | struct MHD_Response
  type MHD_Connection (line 2603) | struct MHD_Connection
  type MHD_Connection (line 2620) | struct MHD_Connection
  type MHD_Response (line 2622) | struct MHD_Response
  type MHD_Connection (line 2638) | struct MHD_Connection
  type MHD_ConnectionInfoType (line 2639) | enum MHD_ConnectionInfoType
  type MHD_CONNECTION_OPTION (line 2647) | enum MHD_CONNECTION_OPTION
  type MHD_Connection (line 2670) | struct MHD_Connection
  type MHD_CONNECTION_OPTION (line 2671) | enum MHD_CONNECTION_OPTION
  type MHD_Daemon (line 2717) | struct MHD_Daemon
  type MHD_DaemonInfoType (line 2718) | enum MHD_DaemonInfoType
  type MHD_FEATURE (line 2736) | enum MHD_FEATURE
  type MHD_FEATURE (line 2865) | enum MHD_FEATURE

FILE: minethd.cpp
  function thd_setaffinity (line 33) | void thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id)
  function thd_setaffinity (line 47) | void thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id)

FILE: minethd.h
  function class (line 7) | class telemetry
  function class (line 22) | class minethd
  function calc_start_nonce (line 105) | inline uint32_t calc_start_nonce(uint32_t resume)

FILE: msgstruct.h
  type pool_job (line 9) | struct pool_job

FILE: rapidjson/allocators.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 20) | RAPIDJSON_NAMESPACE_BEGIN
  function Clear (line 145) | void Clear() {
  function Capacity (line 158) | size_t Capacity() const {
  function Free (line 225) | static void Free(void *ptr) { (void)ptr; }
  function AddChunk (line 237) | bool AddChunk(size_t capacity) {
  type ChunkHeader (line 256) | struct ChunkHeader {

FILE: rapidjson/document.h
  type GenericMember (line 116) | typedef GenericMember<Encoding,Allocator> PlainType;
  type typename (line 117) | typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
  type std (line 118) | typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
  type typename (line 129) | typedef typename BaseType::pointer         Pointer;
  type typename (line 131) | typedef typename BaseType::reference       Reference;
  type typename (line 133) | typedef typename BaseType::difference_type DifferenceType;
  function ptr_ (line 157) | GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
  function ConstIterator (line 179) | bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
  function ConstIterator (line 180) | bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
  function ConstIterator (line 181) | bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
  function ConstIterator (line 182) | bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
  function operator (line 183) | bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
  function operator (line 184) | bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
  function Reference (line 189) | Reference operator*() const { return *ptr_; }
  function Pointer (line 190) | Pointer   operator->() const { return ptr_; }
  function Reference (line 191) | Reference operator[](DifferenceType n) const { return ptr_[n]; }
  type CharType (line 258) | typedef CharType Ch;
  function explicit (line 310) | explicit GenericStringRef(const CharType* str)
  function operator (line 328) | operator const Ch *() const { return s; }
  function namespace (line 399) | namespace internal {
  function namespace (line 416) | namespace internal {
  function Is (line 490) | static bool Is(const ValueType& v) { return v.IsString(); }
  function StringType (line 491) | static StringType Get(const ValueType& v) { return StringType(v.GetStrin...
  type typename (line 498) | typedef typename ValueType::Array ArrayType;
  function Is (line 499) | static bool Is(const ValueType& v) { return v.IsArray(); }
  function ArrayType (line 500) | static ArrayType Get(ValueType& v) { return v.GetArray(); }
  type typename (line 507) | typedef typename ValueType::ConstArray ArrayType;
  function Is (line 508) | static bool Is(const ValueType& v) { return v.IsArray(); }
  function ArrayType (line 509) | static ArrayType Get(const ValueType& v) { return v.GetArray(); }
  type typename (line 514) | typedef typename ValueType::Object ObjectType;
  function Is (line 515) | static bool Is(const ValueType& v) { return v.IsObject(); }
  function ObjectType (line 516) | static ObjectType Get(ValueType& v) { return v.GetObject(); }
  type typename (line 523) | typedef typename ValueType::ConstObject ObjectType;
  function Is (line 524) | static bool Is(const ValueType& v) { return v.IsObject(); }
  function ObjectType (line 525) | static ObjectType Get(const ValueType& v) { return v.GetObject(); }
  type Encoding (line 552) | typedef Encoding EncodingType;
  type Allocator (line 553) | typedef Allocator AllocatorType;
  type typename (line 554) | typedef typename Encoding::Ch Ch;
  type GenericStringRef (line 555) | typedef GenericStringRef<Ch> StringRefType;
  type typename (line 556) | typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterat...
  type typename (line 557) | typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterato...
  type GenericValue (line 558) | typedef GenericValue* ValueIterator;
  type GenericValue (line 559) | typedef const GenericValue* ConstValueIterator;
  type GenericValue (line 560) | typedef GenericValue<Encoding, Allocator> ValueType;
  function explicit (line 672) | explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
  function explicit (line 681) | explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
  function explicit (line 687) | explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
  function explicit (line 693) | explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
  function explicit (line 708) | explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
  function explicit (line 720) | explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d...
  function explicit (line 723) | explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d ...
  function explicit (line 729) | explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { Se...
  function data_ (line 750) | GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
  function data_ (line 761) | GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
  type GenericValue (line 903) | typedef GenericValue<Encoding, SourceAllocator> RhsType;
  function rhs (line 950) | bool operator==(const std::basic_string<Ch>& rhs) const { return *this =...
  function GetBool (line 1051) | bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags ...
  function SizeType (line 1066) | SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data...
  function GenericValue (line 1120) | const GenericValue& operator[](const std::basic_string<Ch>& name) const ...
  function ConstMemberIterator (line 1125) | ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); ...
  function MemberIterator (line 1131) | MemberIterator MemberBegin()            { RAPIDJSON_ASSERT(IsObject()); ...
  function MemberIterator (line 1134) | MemberIterator MemberEnd()              { RAPIDJSON_ASSERT(IsObject()); ...
  function HasMember (line 1144) | bool HasMember(const Ch* name) const { return FindMember(name) != Member...
  function HasMember (line 1155) | bool HasMember(const std::basic_string<Ch>& name) const { return FindMem...
  function MemberIterator (line 1182) | MemberIterator FindMember(const Ch* name) {
  function ConstMemberIterator (line 1187) | ConstMemberIterator FindMember(const Ch* name) const { return const_cast...
  function MemberIterator (line 1222) | MemberIterator FindMember(const std::basic_string<Ch>& name) { return Fi...
  function ConstMemberIterator (line 1223) | ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const ...
  function RemoveAllMembers (line 1387) | void RemoveAllMembers() {
  function RemoveMember (line 1402) | bool RemoveMember(const Ch* name) {
  function MemberIterator (line 1430) | MemberIterator RemoveMember(MemberIterator m) {
  function MemberIterator (line 1454) | MemberIterator EraseMember(ConstMemberIterator pos) {
  function MemberIterator (line 1467) | MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterato...
  function EraseMember (line 1488) | bool EraseMember(const Ch* name) {
  function Object (line 1508) | Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
  function ConstObject (line 1509) | ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return Con...
  function SizeType (line 1521) | SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
  function Empty (line 1527) | bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size ==...
  function GenericValue (line 1551) | const GenericValue& operator[](SizeType index) const { return const_cast...
  function ValueIterator (line 1555) | ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsP...
  function ValueIterator (line 1558) | ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPoi...
  function ValueIterator (line 1660) | ValueIterator Erase(ConstValueIterator pos) {
  function ValueIterator (line 1672) | ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
  function Array (line 1687) | Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
  function ConstArray (line 1688) | ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstA...
  function GetDouble (line 1703) | double GetDouble() const {
  function Ch (line 1731) | const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data...
  function SizeType (line 1736) | SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ...
  type Flag (line 1895) | struct Flag {
  type String (line 1906) | struct String {
  function SetLength (line 1920) | struct ShortString {
  type I (line 1932) | struct I {
  type U (line 1936) | struct U {
  type I (line 1941) | struct I {
  type U (line 1945) | struct U {
  type ObjectData (line 1955) | struct ObjectData {
  type ArrayData (line 1961) | struct ArrayData {
  function RAPIDJSON_FORCEINLINE (line 1976) | RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJ...
  function RAPIDJSON_FORCEINLINE (line 1977) | RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return...
  function RAPIDJSON_FORCEINLINE (line 1978) | RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return ...
  function RAPIDJSON_FORCEINLINE (line 1979) | RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* ele...
  function RAPIDJSON_FORCEINLINE (line 1980) | RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJS...
  function RAPIDJSON_FORCEINLINE (line 1981) | RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { retur...
  function SetArrayRaw (line 1984) | void SetArrayRaw(GenericValue* values, SizeType count, Allocator& alloca...
  function SetObjectRaw (line 1997) | void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
  function SetStringRaw (line 2010) | void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
  function SetStringRaw (line 2017) | void SetStringRaw(StringRefType s, Allocator& allocator) {
  function RawAssign (line 2034) | void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
  type GenericValue (line 2060) | typedef GenericValue<UTF8<> > Value;
  type GenericValue (line 2077) | typedef GenericValue<Encoding, Allocator> ValueType;
  type Allocator (line 2078) | typedef Allocator AllocatorType;
  type ClearStackOnExit (line 2368) | struct ClearStackOnExit {
  function Bool (line 2384) | bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b)...
  function Int (line 2385) | bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); ...
  function Uint (line 2386) | bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueTyp...
  function Int64 (line 2387) | bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueTyp...
  function Uint64 (line 2388) | bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueT...
  function Double (line 2389) | bool Double(double d) { new (stack_.template Push<ValueType>()) ValueTyp...
  function RawNumber (line 2391) | bool RawNumber(const Ch* str, SizeType length, bool copy) {
  function String (line 2399) | bool String(const Ch* str, SizeType length, bool copy) {
  function StartObject (line 2407) | bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(k...
  function Key (line 2409) | bool Key(const Ch* str, SizeType length, bool copy) { return String(str,...
  function EndObject (line 2411) | bool EndObject(SizeType memberCount) {
  function StartArray (line 2417) | bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kA...
  function EndArray (line 2419) | bool EndArray(SizeType elementCount) {
  function ClearStack (line 2431) | void ClearStack() {
  function Destroy (line 2440) | void Destroy() {
  type GenericDocument (line 2452) | typedef GenericDocument<UTF8<> > Document;
  type ValueT (line 2464) | typedef ValueT PlainType;
  type typename (line 2465) | typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
  type ValueType (line 2466) | typedef ValueType* ValueIterator;
  type ValueT (line 2467) | typedef const ValueT* ConstValueIterator;
  type typename (line 2468) | typedef typename ValueType::AllocatorType AllocatorType;
  type typename (line 2469) | typedef typename ValueType::StringRefType StringRefType;
  function value_ (line 2474) | GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
  function GenericArray (line 2485) | GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) con...
  function GenericArray (line 2486) | GenericArray PushBack(ValueType& value, AllocatorType& allocator) const ...
  function GenericArray (line 2488) | GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const...
  function GenericArray (line 2490) | GenericArray PushBack(StringRefType value, AllocatorType& allocator) con...
  function ValueIterator (line 2493) | ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(...
  function ValueIterator (line 2494) | ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) c...
  function value_ (line 2503) | value_(value) {}
  type ValueT (line 2517) | typedef ValueT PlainType;
  type typename (line 2518) | typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
  type GenericMemberIterator (line 2519) | typedef GenericMemberIterator<Const, typename
  type GenericMemberIterator (line 2520) | typedef GenericMemberIterator<true, typename
  type typename (line 2521) | typedef typename ValueType::AllocatorType AllocatorType;
  type typename (line 2522) | typedef typename ValueType::StringRefType StringRefType;
  type typename (line 2523) | typedef typename ValueType::EncodingType EncodingType;
  type typename (line 2524) | typedef typename ValueType::Ch Ch;
  function value_ (line 2529) | GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
  function HasMember (line 2542) | bool HasMember(const Ch* name) const { return value_.HasMember(name); }
  function MemberIterator (line 2547) | MemberIterator FindMember(const Ch* name) const { return value_.FindMemb...
  function GenericObject (line 2555) | GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, A...
  function GenericObject (line 2559) | GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorTy...
  function GenericObject (line 2560) | GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorTyp...
  function GenericObject (line 2561) | GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorTyp...
  function GenericObject (line 2562) | GenericObject AddMember(StringRefType name, ValueType&& value, Allocator...
  function GenericObject (line 2564) | GenericObject AddMember(StringRefType name, ValueType& value, AllocatorT...
  function GenericObject (line 2565) | GenericObject AddMember(StringRefType name, StringRefType value, Allocat...
  function RemoveMember (line 2568) | bool RemoveMember(const Ch* name) const { return value_.RemoveMember(nam...
  function value_ (line 2589) | value_(value) {}

FILE: rapidjson/encodedstream.h
  function RAPIDJSON_DIAG_PUSH (line 27) | RAPIDJSON_DIAG_PUSH
  function Ch (line 49) | Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; }
  function Put (line 53) | void Put(Ch) { RAPIDJSON_ASSERT(false); }
  function Flush (line 54) | void Flush() { RAPIDJSON_ASSERT(false); }
  function Ch (line 55) | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
  function PutEnd (line 56) | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
  function is_ (line 72) | is_(is) {
  function Ch (line 78) | Ch Take() { return is_.Take(); }
  function Put (line 82) | void Put(Ch) {}
  function Flush (line 83) | void Flush() {}
  function Ch (line 84) | Ch* PutBegin() { return 0; }
  function PutEnd (line 85) | size_t PutEnd(Ch*) { return 0; }
  function os_ (line 105) | os_(os) {
  function Put (line 110) | void Put(Ch c) { Encoding::Put(os_, c);  }
  function Flush (line 111) | void Flush() { os_.Flush(); }
  function Ch (line 115) | Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
  function Tell (line 116) | size_t Tell() const { RAPIDJSON_ASSERT(false);  return 0; }
  function Ch (line 157) | Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
  function Put (line 161) | void Put(Ch) { RAPIDJSON_ASSERT(false); }
  function Flush (line 162) | void Flush() { RAPIDJSON_ASSERT(false); }
  function Ch (line 163) | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
  function PutEnd (line 164) | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
  function DetectType (line 171) | void DetectType() {
  type Ch (line 219) | typedef Ch (*TakeFunc)(InputByteStream& is);
  function Put (line 260) | void Put(Ch c) { putFunc_(*os_, c); }
  function Flush (line 261) | void Flush() { os_->Flush(); }
  function Ch (line 265) | Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
  function Tell (line 266) | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
  function PutBOM (line 274) | void PutBOM() {

FILE: rapidjson/encodings.h
  function RAPIDJSON_DIAG_PUSH (line 25) | RAPIDJSON_DIAG_PUSH
  function else (line 131) | else if (codepoint <= 0xFFFF) {
  function GetRange (line 204) | static unsigned char GetRange(unsigned char c) {
  type CharType (line 270) | typedef CharType Ch;
  type CharType (line 419) | typedef CharType Ch;
  type CharType (line 543) | typedef CharType Ch;
  type UTFType (line 603) | enum UTFType {
  type CharType (line 616) | typedef CharType Ch;
  function Encode (line 623) | static void Encode(OutputStream& os, unsigned codepoint) {
  function EncodeUnsafe (line 630) | static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
  function Decode (line 637) | static bool Decode(InputStream& is, unsigned* codepoint) {
  function Validate (line 644) | static bool Validate(InputStream& is, OutputStream& os) {
  function Transcode (line 661) | static bool Transcode(InputStream& is, OutputStream& os) {
  function TranscodeUnsafe (line 670) | static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
  function Validate (line 680) | static bool Validate(InputStream& is, OutputStream& os) {
  function Transcode (line 693) | static bool Transcode(InputStream& is, OutputStream& os) {
  function TranscodeUnsafe (line 699) | static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
  function Validate (line 705) | static bool Validate(InputStream& is, OutputStream& os) {

FILE: rapidjson/error/en.h
  function RAPIDJSON_DIAG_PUSH (line 21) | RAPIDJSON_DIAG_PUSH

FILE: rapidjson/error/error.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 55) | RAPIDJSON_NAMESPACE_BEGIN
  type RAPIDJSON_ERROR_CHARTYPE (line 147) | typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorC...

FILE: rapidjson/filereadstream.h
  function RAPIDJSON_DIAG_PUSH (line 22) | RAPIDJSON_DIAG_PUSH
  function Ch (line 51) | Ch Take() { Ch c = *current_; Read(); return c; }
  function Put (line 55) | void Put(Ch) { RAPIDJSON_ASSERT(false); }
  function Flush (line 56) | void Flush() { RAPIDJSON_ASSERT(false); }
  function Ch (line 57) | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
  function PutEnd (line 58) | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
  function Ch (line 61) | const Ch* Peek4() const {

FILE: rapidjson/filewritestream.h
  function RAPIDJSON_DIAG_PUSH (line 22) | RAPIDJSON_DIAG_PUSH
  function Put (line 40) | void Put(char c) {
  function PutN (line 47) | void PutN(char c, size_t n) {
  function Flush (line 63) | void Flush() {
  function Peek (line 75) | char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
  function Tell (line 77) | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
  function PutEnd (line 79) | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
  function PutN (line 94) | inline void PutN(FileWriteStream& stream, char c, size_t n) {

FILE: rapidjson/fwd.h
  type GenericStringStream (line 49) | typedef GenericStringStream<UTF8<char> > StringStream;
  type GenericInsituStringStream (line 54) | typedef GenericInsituStringStream<UTF8<char> > InsituStringStream;
  type GenericStringBuffer (line 61) | typedef GenericStringBuffer<UTF8<char>, CrtAllocator> StringBuffer;
  type GenericMemoryBuffer (line 76) | typedef GenericMemoryBuffer<CrtAllocator> MemoryBuffer;
  type MemoryStream (line 80) | struct MemoryStream
  type GenericReader (line 90) | typedef GenericReader<UTF8<char>, UTF8<char>, CrtAllocator> Reader;
  type GenericValue (line 116) | typedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value;
  type GenericDocument (line 121) | typedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator>, C...
  type GenericPointer (line 128) | typedef GenericPointer<Value, CrtAllocator> Pointer;
  type GenericSchemaDocument (line 138) | typedef GenericSchemaDocument<Value, CrtAllocator> SchemaDocument;
  type IGenericRemoteSchemaDocumentProvider (line 139) | typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSche...
  type GenericSchemaValidator (line 147) | typedef GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<ch...

FILE: rapidjson/internal/biginteger.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 25) | RAPIDJSON_NAMESPACE_BEGIN
  function Difference (line 186) | bool Difference(const BigInteger& rhs, BigInteger* out) const {
  function Compare (line 208) | int Compare(const BigInteger& rhs) const {
  function Type (line 220) | Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); re...
  function PushBack (line 234) | void PushBack(Type digit) {
  function ParseUint64 (line 239) | static uint64_t ParseUint64(const char* begin, const char* end) {
  function MulAdd64 (line 249) | static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* o...

FILE: rapidjson/internal/diyfp.h
  function RAPIDJSON_DIAG_PUSH (line 39) | RAPIDJSON_DIAG_PUSH
  type uint128 (line 78) | __extension__ typedef unsigned __int128 uint128;
  function DiyFp (line 119) | DiyFp NormalizeBoundary() const {
  function NormalizedBoundaries (line 130) | void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const {
  function ToDouble (line 139) | double ToDouble() const {
  function DiyFp (line 226) | inline DiyFp GetCachedPower(int e, int* K) {
  function DiyFp (line 240) | inline DiyFp GetCachedPower10(int exp, int *outExp) {

FILE: rapidjson/internal/dtoa.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 26) | RAPIDJSON_NAMESPACE_BEGIN

FILE: rapidjson/internal/ieee754.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 20) | RAPIDJSON_NAMESPACE_BEGIN

FILE: rapidjson/internal/itoa.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 20) | RAPIDJSON_NAMESPACE_BEGIN

FILE: rapidjson/internal/meta.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 34) | RAPIDJSON_NAMESPACE_BEGIN

FILE: rapidjson/internal/pow10.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 20) | RAPIDJSON_NAMESPACE_BEGIN

FILE: rapidjson/internal/regex.h
  function RAPIDJSON_DIAG_PUSH (line 23) | RAPIDJSON_DIAG_PUSH
  type typename (line 601) | typedef typename Encoding::Ch Ch;
  function Match (line 625) | bool Match(const Ch* s) {
  function Search (line 635) | bool Search(const Ch* s) {
  type typename (line 642) | typedef typename RegexType::Range Range;
  function AddState (line 683) | bool AddState(Stack<Allocator>& l, SizeType index) {
  function MatchRange (line 698) | bool MatchRange(SizeType rangeIndex, unsigned codepoint) const {
  type GenericRegex (line 717) | typedef GenericRegex<UTF8<> > Regex;
  type GenericRegexSearch (line 718) | typedef GenericRegexSearch<Regex> RegexSearch;

FILE: rapidjson/internal/stack.h
  function RAPIDJSON_DIAG_PUSH (line 22) | RAPIDJSON_DIAG_PUSH
  function T (line 149) | T* Top() const {
  function T (line 158) | T* End() const { return reinterpret_cast<T*>(stackTop_); }
  function T (line 164) | T* Bottom() const { return reinterpret_cast<T*>(stack_); }
  function Resize (line 199) | void Resize(size_t newCapacity) {
  function Destroy (line 206) | void Destroy() {

FILE: rapidjson/internal/strfunc.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 20) | RAPIDJSON_NAMESPACE_BEGIN

FILE: rapidjson/internal/strtod.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 23) | RAPIDJSON_NAMESPACE_BEGIN

FILE: rapidjson/internal/swap.h
  function RAPIDJSON_DIAG_PUSH (line 21) | RAPIDJSON_DIAG_PUSH

FILE: rapidjson/istreamwrapper.h
  function Ch (line 60) | Ch Take() {
  function Ch (line 73) | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
  function Put (line 74) | void Put(Ch) { RAPIDJSON_ASSERT(false); }
  function Flush (line 75) | void Flush() { RAPIDJSON_ASSERT(false); }
  function PutEnd (line 76) | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
  function Ch (line 79) | const Ch* Peek4() const {
  type BasicIStreamWrapper (line 106) | typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
  type BasicIStreamWrapper (line 107) | typedef BasicIStreamWrapper<std::wistream> WIStreamWrapper;

FILE: rapidjson/memorystream.h
  function RAPIDJSON_DIAG_PUSH (line 21) | RAPIDJSON_DIAG_PUSH
  function Ch (line 46) | Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; }
  function Ch (line 49) | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
  function Put (line 50) | void Put(Ch) { RAPIDJSON_ASSERT(false); }
  function Flush (line 51) | void Flush() { RAPIDJSON_ASSERT(false); }
  function PutEnd (line 52) | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
  function Ch (line 55) | const Ch* Peek4() const {

FILE: rapidjson/msinttypes/inttypes.h
  type imaxdiv_t (line 57) | typedef struct {
  function _inline (line 286) | static

FILE: rapidjson/msinttypes/stdint.h
  type int_least8_t (line 140) | typedef int8_t    int_least8_t;
  type int_least16_t (line 141) | typedef int16_t   int_least16_t;
  type int_least32_t (line 142) | typedef int32_t   int_least32_t;
  type int_least64_t (line 143) | typedef int64_t   int_least64_t;
  type uint_least8_t (line 144) | typedef uint8_t   uint_least8_t;
  type uint_least16_t (line 145) | typedef uint16_t  uint_least16_t;
  type uint_least32_t (line 146) | typedef uint32_t  uint_least32_t;
  type uint_least64_t (line 147) | typedef uint64_t  uint_least64_t;
  type int_fast8_t (line 150) | typedef int8_t    int_fast8_t;
  type int_fast16_t (line 151) | typedef int16_t   int_fast16_t;
  type int_fast32_t (line 152) | typedef int32_t   int_fast32_t;
  type int_fast64_t (line 153) | typedef int64_t   int_fast64_t;
  type uint_fast8_t (line 154) | typedef uint8_t   uint_fast8_t;
  type uint_fast16_t (line 155) | typedef uint16_t  uint_fast16_t;
  type uint_fast32_t (line 156) | typedef uint32_t  uint_fast32_t;
  type uint_fast64_t (line 157) | typedef uint64_t  uint_fast64_t;
  type intmax_t (line 169) | typedef int64_t   intmax_t;
  type uintmax_t (line 170) | typedef uint64_t  uintmax_t;

FILE: rapidjson/ostreamwrapper.h
  function RAPIDJSON_DIAG_PUSH (line 22) | RAPIDJSON_DIAG_PUSH
  function Put (line 50) | void Put(Ch c) {
  function Flush (line 54) | void Flush() {
  function Peek (line 59) | char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
  function Tell (line 61) | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
  function PutEnd (line 63) | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
  type BasicOStreamWrapper (line 72) | typedef BasicOStreamWrapper<std::ostream> OStreamWrapper;
  type BasicOStreamWrapper (line 73) | typedef BasicOStreamWrapper<std::wostream> WOStreamWrapper;

FILE: rapidjson/pointer.h
  function RAPIDJSON_DIAG_PUSH (line 27) | RAPIDJSON_DIAG_PUSH
  function Token (line 320) | const Token* GetTokens() const { return tokens_; }
  function Erase (line 711) | bool Erase(ValueType& root) const {
  function NeedPercentEncode (line 790) | bool NeedPercentEncode(Ch c) const {
  function Parse (line 802) | void Parse(const Ch* source, size_t length) {
  function class (line 980) | class PercentDecodeStream {
  function Put (line 1028) | void Put(char c) { // UTF-8 must be byte
  type GenericPointer (line 1049) | typedef GenericPointer<Value> Pointer;

FILE: rapidjson/prettywriter.h
  function RAPIDJSON_DIAG_PUSH (line 26) | RAPIDJSON_DIAG_PUSH
  function Null (line 95) | bool Null()                 { PrettyPrefix(kNullType);   return Base::Wr...
  function Bool (line 96) | bool Bool(bool b)           { PrettyPrefix(b ? kTrueType : kFalseType); ...
  function Int (line 97) | bool Int(int i)             { PrettyPrefix(kNumberType); return Base::Wr...
  function Uint (line 98) | bool Uint(unsigned u)       { PrettyPrefix(kNumberType); return Base::Wr...
  function Int64 (line 99) | bool Int64(int64_t i64)     { PrettyPrefix(kNumberType); return Base::Wr...
  function Uint64 (line 100) | bool Uint64(uint64_t u64)   { PrettyPrefix(kNumberType); return Base::Wr...
  function Double (line 101) | bool Double(double d)       { PrettyPrefix(kNumberType); return Base::Wr...
  function StartObject (line 123) | bool StartObject() {
  function StartArray (line 155) | bool StartArray() {
  function String (line 185) | bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
  function Key (line 186) | bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
  function RawValue (line 199) | bool RawValue(const Ch* json, size_t length, Type type) {
  function WriteIndent (line 250) | void WriteIndent()  {

FILE: rapidjson/rapidjson.h
  type STATIC_ASSERTION_FAILURE (line 415) | struct STATIC_ASSERTION_FAILURE

FILE: rapidjson/reader.h
  function RAPIDJSON_DIAG_PUSH (line 39) | RAPIDJSON_DIAG_PUSH
  type ParseFlag (line 145) | enum ParseFlag {
  type typename (line 197) | typedef typename Encoding::Ch Ch;
  type typename (line 199) | typedef typename internal::SelectIf<internal::IsSame<Derived, void>, Bas...
  function Default (line 201) | bool Default() { return true; }
  function Null (line 202) | bool Null() { return static_cast<Override&>(*this).Default(); }
  function Bool (line 203) | bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
  function Int (line 204) | bool Int(int) { return static_cast<Override&>(*this).Default(); }
  function Uint (line 205) | bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }
  function Int64 (line 206) | bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }
  function Uint64 (line 207) | bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }
  function Double (line 208) | bool Double(double) { return static_cast<Override&>(*this).Default(); }
  function RawNumber (line 210) | bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_c...
  function String (line 211) | bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*...
  function StartObject (line 212) | bool StartObject() { return static_cast<Override&>(*this).Default(); }
  function Key (line 213) | bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Ov...
  function EndObject (line 214) | bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(...
  function StartArray (line 215) | bool StartArray() { return static_cast<Override&>(*this).Default(); }
  function EndArray (line 216) | bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
  function namespace (line 222) | namespace internal {
  function SkipWhitespace (line 418) | inline void SkipWhitespace(InsituStringStream& is) {
  function SkipWhitespace (line 423) | inline void SkipWhitespace(StringStream& is) {
  function SkipWhitespace (line 427) | inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
  function ClearStack (line 533) | void ClearStack() { stack_.Clear(); }
  type ClearStackOnExit (line 536) | struct ClearStackOnExit {
  function Consume (line 730) | bool Consume(InputStream& is, typename InputStream::Ch expect) {
  function RAPIDJSON_FORCEINLINE (line 768) | RAPIDJSON_FORCEINLINE void Put(Ch c) {
  function RAPIDJSON_FORCEINLINE (line 773) | RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
  function Ch (line 780) | Ch* Pop() {
  type typename (line 1061) | typedef typename InputStream::Ch Ch;
  function is (line 1063) | is(s) { (void)reader;  }
  function RAPIDJSON_FORCEINLINE (line 1066) | RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
  function RAPIDJSON_FORCEINLINE (line 1067) | RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
  function RAPIDJSON_FORCEINLINE (line 1068) | RAPIDJSON_FORCEINLINE void Push(char) {}
  function Tell (line 1070) | size_t Tell() { return is.Tell(); }
  function Length (line 1071) | size_t Length() { return 0; }
  function RAPIDJSON_FORCEINLINE (line 1086) | RAPIDJSON_FORCEINLINE Ch TakePush() {
  function RAPIDJSON_FORCEINLINE (line 1091) | RAPIDJSON_FORCEINLINE void Push(char c) {
  function Length (line 1095) | size_t Length() { return stackStream.Length(); }
  function RAPIDJSON_FORCEINLINE (line 1112) | RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
  type IterativeParsingState (line 1393) | enum IterativeParsingState {
  type Token (line 1419) | enum Token {
  function RAPIDJSON_FORCEINLINE (line 1438) | RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
  function RAPIDJSON_FORCEINLINE (line 1465) | RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingStat...
  function IterativeParsingState (line 1632) | IterativeParsingState Transit(IterativeParsingState src, Token token, It...
  type GenericReader (line 1845) | typedef GenericReader<UTF8<>, UTF8<> > Reader;

FILE: rapidjson/schema.h
  function namespace (line 78) | namespace internal {
  function namespace (line 130) | namespace internal {
  type typename (line 341) | typedef typename SchemaDocumentType::AllocatorType AllocatorType;
  type typename (line 342) | typedef typename SchemaDocumentType::PointerType PointerType;
  type typename (line 343) | typedef typename ValueType::EncodingType EncodingType;
  type typename (line 344) | typedef typename EncodingType::Ch Ch;
  type SchemaValidationContext (line 345) | typedef SchemaValidationContext<SchemaDocumentType> Context;
  type Schema (line 346) | typedef Schema<SchemaDocumentType> SchemaType;
  type GenericValue (line 347) | typedef GenericValue<EncodingType, AllocatorType> SValue;
  type typename (line 384) | typedef typename ValueType::ConstValueIterator ConstValueIterator;
  type typename (line 385) | typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
  type Hasher (line 403) | typedef Hasher<EncodingType, MemoryPoolAllocator<> > EnumHasherType;
  function BeginValue (line 599) | bool BeginValue(Context& context) const {
  function Null (line 691) | bool Null(Context& context) const {
  function Bool (line 697) | bool Bool(Context& context, bool) const {
  function Int (line 703) | bool Int(Context& context, int i) const {
  function Uint (line 709) | bool Uint(Context& context, unsigned u) const {
  function Int64 (line 715) | bool Int64(Context& context, int64_t i) const {
  function Uint64 (line 721) | bool Uint64(Context& context, uint64_t u) const {
  function Double (line 727) | bool Double(Context& context, double d) const {
  function String (line 743) | bool String(Context& context, const Ch* str, SizeType length, bool) const {
  function StartObject (line 763) | bool StartObject(Context& context) const {
  function Key (line 782) | bool Key(Context& context, const Ch* str, SizeType len, bool) const {
  function EndObject (line 827) | bool EndObject(Context& context, SizeType memberCount) const {
  function StartArray (line 857) | bool StartArray(Context& context) const {
  function EndArray (line 867) | bool EndArray(Context& context, SizeType elementCount) const {
  type SchemaValueType (line 924) | enum SchemaValueType {
  type internal (line 936) | typedef internal::GenericRegex<EncodingType> RegexType;
  type std (line 938) | typedef std::basic_regex<Ch> RegexType;
  type RegexType (line 940) | typedef char RegexType;
  type SchemaArray (line 943) | struct SchemaArray {
  function ValueType (line 960) | static const ValueType* GetMember(const ValueType& value, const ValueTyp...
  function AssignIfExist (line 965) | static void AssignIfExist(bool& out, const ValueType& value, const Value...
  function AssignIfExist (line 971) | static void AssignIfExist(SizeType& out, const ValueType& value, const V...
  function AssignIfExist (line 977) | void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument,...
  function IsPatternMatch (line 1007) | static bool IsPatternMatch(const RegexType* pattern, const Ch *str, Size...
  function IsPatternMatch (line 1023) | static bool IsPatternMatch(const RegexType* pattern, const Ch *str, Size...
  function FindPropertyIndex (line 1081) | bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const {
  function CheckInt (line 1094) | bool CheckInt(Context& context, int64_t i) const {
  function CheckUint (line 1133) | bool CheckUint(Context& context, uint64_t i) const {
  function CheckDoubleMinimum (line 1171) | bool CheckDoubleMinimum(Context& context, double d) const {
  function CheckDoubleMaximum (line 1177) | bool CheckDoubleMaximum(Context& context, double d) const {
  function CheckDoubleMultipleOf (line 1183) | bool CheckDoubleMultipleOf(Context& context, double d) const {
  type Property (line 1192) | struct Property {
  type PatternProperty (line 1203) | struct PatternProperty {
  function virtual (line 1299) | virtual ~IGenericRemoteSchemaDocumentProvider() {}
  type IGenericRemoteSchemaDocumentProvider (line 1319) | typedef IGenericRemoteSchemaDocumentProvider<GenericSchemaDocument> IRem...
  type Allocator (line 1320) | typedef Allocator AllocatorType;
  type typename (line 1321) | typedef typename ValueType::EncodingType EncodingType;
  type typename (line 1322) | typedef typename EncodingType::Ch Ch;
  type internal (line 1323) | typedef internal::Schema<GenericSchemaDocument> SchemaType;
  type GenericPointer (line 1324) | typedef GenericPointer<ValueType, Allocator> PointerType;
  type SchemaRefEntry (line 1419) | struct SchemaRefEntry {
  function CreateSchemaRecursive (line 1439) | void CreateSchemaRecursive(const SchemaType** schema, const PointerType&...
  function CreateSchema (line 1456) | void CreateSchema(const SchemaType** schema, const PointerType& pointer,...
  function HandleRefSchema (line 1468) | bool HandleRefSchema(const PointerType& source, const SchemaType** schem...
  function SchemaType (line 1514) | const SchemaType* GetSchema(const PointerType& pointer) const {
  function PointerType (line 1521) | PointerType GetPointer(const SchemaType* schema) const {
  function SchemaType (line 1528) | const SchemaType* GetTypeless() const { return typeless_; }
  type GenericSchemaDocument (line 1543) | typedef GenericSchemaDocument<Value> SchemaDocument;
  type IGenericRemoteSchemaDocumentProvider (line 1545) | typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSche...
  type typename (line 1572) | typedef typename SchemaDocumentType::PointerType PointerType;
  type typename (line 1573) | typedef typename SchemaType::EncodingType EncodingType;
  type typename (line 1574) | typedef typename EncodingType::Ch Ch;
  function Reset (line 1643) | void Reset() {
  function Ch (line 1660) | const Ch* GetInvalidSchemaKeyword() const {
  function Null (line 1707) | bool Null()             { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null,   (Curren...
  function Bool (line 1708) | bool Bool(bool b)       { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool,   (Curren...
  function Int (line 1709) | bool Int(int i)         { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int,    (Curren...
  function Uint (line 1710) | bool Uint(unsigned u)   { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint,   (Curren...
  function Int64 (line 1711) | bool Int64(int64_t i)   { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64,  (Curren...
  function Uint64 (line 1712) | bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (Curren...
  function Double (line 1713) | bool Double(double d)   { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (Curren...
  function RawNumber (line 1714) | bool RawNumber(const Ch* str, SizeType length, bool copy)
  function String (line 1716) | bool String(const Ch* str, SizeType length, bool copy)
  function StartObject (line 1719) | bool StartObject() {
  function Key (line 1725) | bool Key(const Ch* str, SizeType len, bool copy) {
  function EndObject (line 1733) | bool EndObject(SizeType memberCount) {
  function StartArray (line 1740) | bool StartArray() {
  function EndArray (line 1746) | bool EndArray(SizeType elementCount) {
  function virtual (line 1759) | virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) {
  function virtual (line 1767) | virtual void DestroySchemaValidator(ISchemaValidator* validator) {
  function virtual (line 1773) | virtual void* CreateHasher() {
  function virtual (line 1777) | virtual uint64_t GetHashCode(void* hasher) {
  function virtual (line 1781) | virtual void DestroryHasher(void* hasher) {
  function virtual (line 1787) | virtual void* MallocState(size_t size) {
  function virtual (line 1791) | virtual void FreeState(void* p) {
  type GenericValue (line 1797) | typedef GenericValue<UTF8<>, StateAllocator> HashCodeArray;
  type internal (line 1798) | typedef internal::Hasher<EncodingType, StateAllocator> HasherType;
  function BeginValue (line 1830) | bool BeginValue() {
  function EndValue (line 1861) | bool EndValue() {
  function AppendToken (line 1898) | void AppendToken(const Ch* str, SizeType len) {
  function RAPIDJSON_FORCEINLINE (line 1915) | RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (s...
  function RAPIDJSON_FORCEINLINE (line 1917) | RAPIDJSON_FORCEINLINE void PopSchema() {
  type GenericSchemaValidator (line 1950) | typedef GenericSchemaValidator<SchemaDocument> SchemaValidator;
  type typename (line 1974) | typedef typename InputStream::Ch Ch;
  function Ch (line 2007) | const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; }

FILE: rapidjson/stream.h
  function RAPIDJSON_NAMESPACE_BEGIN (line 22) | RAPIDJSON_NAMESPACE_BEGIN
  type typename (line 111) | typedef typename Encoding::Ch Ch;
  function Ch (line 116) | Ch Take() { return *src_++; }
  function Ch (line 119) | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
  function Put (line 120) | void Put(Ch) { RAPIDJSON_ASSERT(false); }
  function Flush (line 121) | void Flush() { RAPIDJSON_ASSERT(false); }
  function PutEnd (line 122) | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
  type GenericStringStream (line 134) | typedef GenericStringStream<UTF8<> > StringStream;
  type typename (line 145) | typedef typename Encoding::Ch Ch;
  function Ch (line 150) | Ch Peek() { return *src_; }
  function Ch (line 151) | Ch Take() { return *src_++; }
  function Tell (line 152) | size_t Tell() { return static_cast<size_t>(src_ - head_); }
  function Put (line 155) | void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
  function Ch (line 157) | Ch* PutBegin() { return dst_ = src_; }
  function PutEnd (line 158) | size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
  function Flush (line 159) | void Flush() {}
  function Ch (line 161) | Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
  function Pop (line 162) | void Pop(size_t count) { dst_ -= count; }
  type GenericInsituStringStream (line 175) | typedef GenericInsituStringStream<UTF8<> > InsituStringStream;

FILE: rapidjson/writer.h
  type WriteFlag (line 64) | enum WriteFlag {
  function Reset (line 132) | void Reset(OutputStream& os) {
  function SetMaxDecimalPlaces (line 171) | void SetMaxDecimalPlaces(int maxDecimalPlaces) {
  function Null (line 180) | bool Null()                 { Prefix(kNullType);   return EndValue(Write...
  function Bool (line 181) | bool Bool(bool b)           { Prefix(b ? kTrueType : kFalseType); return...
  function Int (line 182) | bool Int(int i)             { Prefix(kNumberType); return EndValue(Write...
  function Uint (line 183) | bool Uint(unsigned u)       { Prefix(kNumberType); return EndValue(Write...
  function Int64 (line 184) | bool Int64(int64_t i64)     { Prefix(kNumberType); return EndValue(Write...
  function Uint64 (line 185) | bool Uint64(uint64_t u64)   { Prefix(kNumberType); return EndValue(Write...
  function Double (line 192) | bool Double(double d)       { Prefix(kNumberType); return EndValue(Write...
  function StartObject (line 214) | bool StartObject() {
  function StartArray (line 230) | bool StartArray() {
  function String (line 249) | bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
  function Key (line 250) | bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
  function RawValue (line 262) | bool RawValue(const Ch* json, size_t length, Type type) {
  type Level (line 270) | struct Level {
  function WriteNull (line 278) | bool WriteNull()  {
  function WriteBool (line 283) | bool WriteBool(bool b)  {
  function WriteInt (line 295) | bool WriteInt(int i) {
  function WriteUint (line 304) | bool WriteUint(unsigned u) {
  function WriteInt64 (line 313) | bool WriteInt64(int64_t i64) {
  function WriteUint64 (line 322) | bool WriteUint64(uint64_t u64) {
  function WriteDouble (line 331) | bool WriteDouble(double d) {
  function WriteString (line 359) | bool WriteString(const Ch* str, SizeType length)  {
  function ScanWriteUnescapedString (line 433) | bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is, s...
  function WriteStartObject (line 437) | bool WriteStartObject() { os_->Put('{'); return true; }
  function WriteEndObject (line 438) | bool WriteEndObject()   { os_->Put('}'); return true; }
  function WriteStartArray (line 439) | bool WriteStartArray()  { os_->Put('['); return true; }
  function WriteEndArray (line 440) | bool WriteEndArray()    { os_->Put(']'); return true; }
  function WriteRawValue (line 442) | bool WriteRawValue(const Ch* json, size_t length) {
  function Prefix (line 451) | void Prefix(Type type) {
  function EndValue (line 472) | bool EndValue(bool ret) {
  function WriteUint (line 500) | inline bool Writer<StringBuffer>::WriteUint(unsigned u) {
  function WriteInt64 (line 508) | inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
  function WriteUint64 (line 516) | inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
  function WriteDouble (line 524) | inline bool Writer<StringBuffer>::WriteDouble(double d) {

FILE: socket.h
  function class (line 5) | class base_socket
  function class (line 15) | class plain_socket : public base_socket
  type SSL_CTX (line 33) | typedef struct ssl_ctx_st SSL_CTX;
  type BIO (line 34) | typedef struct bio_st BIO;
  type SSL (line 35) | typedef struct ssl_st SSL;
  function class (line 37) | class tls_socket : public base_socket

FILE: socks.h
  function sock_init (line 10) | inline void sock_init()
  function sock_close (line 22) | inline void sock_close(SOCKET s)
  function sock_init (line 64) | inline void sock_init() {}
  type SOCKET (line 65) | typedef int SOCKET;
  function sock_close (line 70) | inline void sock_close(SOCKET s)

FILE: thdq.hpp
  class thdq (line 9) | class thdq
    method T (line 12) | T pop()
    method pop (line 21) | void pop(T& item)
    method push (line 29) | void push(const T& item)
    method push (line 37) | void push(T&& item)
Condensed preview — 91 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,165K chars).
[
  {
    "path": ".gitignore",
    "chars": 67,
    "preview": "bin/\nobj/\nxmr-stak-amd.layout\nxmr-stak-amd.depend\nconfig-debug.txt\n"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 5215,
    "preview": "project(xmr-stak-amd)\n\ncmake_minimum_required(VERSION 3.1.3)\n\n# enforce C++11\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CM"
  },
  {
    "path": "LICENSE",
    "chars": 32423,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.md",
    "chars": 208,
    "preview": "# XMR-Stak is now supporting CPU, AMD and NVIDIA GPUs in a unified miner.\n\nOur new repository is https://github.com/fire"
  },
  {
    "path": "amd_gpu/gpu.c",
    "chars": 23028,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "amd_gpu/gpu.h",
    "chars": 770,
    "preview": "#pragma once\n\n#include <CL/cl.h>\n#include <stdint.h>\n\n#define ERR_SUCCESS (0)\n#define ERR_OCL_API (2)\n#define ERR_STUPID"
  },
  {
    "path": "cli-miner.cpp",
    "chars": 5453,
    "preview": " /*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General P"
  },
  {
    "path": "config.txt",
    "chars": 5458,
    "preview": "/* \r\n * Number of GPUs that you have in your system. Each GPU will get its own CPU thread.\r\n */\r\n\"gpu_thread_num\" : 6,\r\n"
  },
  {
    "path": "console.cpp",
    "chars": 4999,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "console.h",
    "chars": 1041,
    "preview": "#pragma once\n#include <mutex>\n\nenum out_colours { K_RED, K_GREEN, K_BLUE, K_YELLOW, K_CYAN, K_MAGENTA, K_WHITE, K_NONE }"
  },
  {
    "path": "crypto/c_blake256.c",
    "chars": 8872,
    "preview": "/*\n * The blake256_* and blake224_* functions are largely copied from\n * blake256_light.c and blake224_light.c from the "
  },
  {
    "path": "crypto/c_blake256.h",
    "chars": 1201,
    "preview": "#ifndef _BLAKE256_H_\n#define _BLAKE256_H_\n\n#include <stdint.h>\n\ntypedef struct {\n  uint32_t h[8], s[4], t[2];\n  int bufl"
  },
  {
    "path": "crypto/c_groestl.c",
    "chars": 11020,
    "preview": "/* hash.c     April 2012\n * Groestl ANSI C code optimised for 32-bit machines\n * Author: Thomas Krinninger\n *\n *  This w"
  },
  {
    "path": "crypto/c_groestl.h",
    "chars": 1463,
    "preview": "#ifndef __hash_h\n#define __hash_h\n/*\n#include \"crypto_uint8.h\"\n#include \"crypto_uint32.h\"\n#include \"crypto_uint64.h\"\n#in"
  },
  {
    "path": "crypto/c_jh.c",
    "chars": 24172,
    "preview": "/*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C\n\n   -------------------------------"
  },
  {
    "path": "crypto/c_jh.h",
    "chars": 706,
    "preview": "/*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C\n\n   -------------------------------"
  },
  {
    "path": "crypto/c_keccak.c",
    "chars": 3104,
    "preview": "// keccak.c\n// 19-Nov-11  Markku-Juhani O. Saarinen <mjos@iki.fi>\n// A baseline Keccak (3rd round) implementation.\n\n#inc"
  },
  {
    "path": "crypto/c_keccak.h",
    "chars": 541,
    "preview": "// keccak.h\n// 19-Nov-11  Markku-Juhani O. Saarinen <mjos@iki.fi>\n\n#ifndef KECCAK_H\n#define KECCAK_H\n\n#include <stdint.h"
  },
  {
    "path": "crypto/c_skein.c",
    "chars": 79397,
    "preview": "/***********************************************************************\n**\n** Implementation of the Skein hash function"
  },
  {
    "path": "crypto/c_skein.h",
    "chars": 1923,
    "preview": "#ifndef _SKEIN_H_\n#define _SKEIN_H_     1\n/**************************************************************************\n**"
  },
  {
    "path": "crypto/cryptonight.h",
    "chars": 530,
    "preview": "#ifndef __CRYPTONIGHT_H_INCLUDED\n#define __CRYPTONIGHT_H_INCLUDED\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <std"
  },
  {
    "path": "crypto/cryptonight_aesni.h",
    "chars": 15851,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "crypto/cryptonight_common.cpp",
    "chars": 2448,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "crypto/groestl_tables.h",
    "chars": 6222,
    "preview": "#ifndef __tables_h\n#define __tables_h\n\n\nconst uint32_t T[512] = {0xa5f432c6, 0xc6a597f4, 0x84976ff8, 0xf884eb97, 0x99b05"
  },
  {
    "path": "crypto/hash.h",
    "chars": 154,
    "preview": "#pragma once\n\ntypedef unsigned char BitSequence;\ntypedef unsigned long long DataLength;\ntypedef enum {SUCCESS = 0, FAIL "
  },
  {
    "path": "crypto/int-util.h",
    "chars": 4676,
    "preview": "// Copyright(c) 2012 - 2013 The Cryptonote developers\n// Distributed under the MIT/X11 software license, see the accompa"
  },
  {
    "path": "crypto/skein_port.h",
    "chars": 6177,
    "preview": "#ifndef _SKEIN_PORT_H_\n#define _SKEIN_PORT_H_\n\n#include <limits.h>\n#include <stdint.h>\n#include <stddef.h>\n\n#ifndef RETU"
  },
  {
    "path": "crypto/soft_aes.c",
    "chars": 9964,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "donate-level.h",
    "chars": 691,
    "preview": "#pragma once\n\n/*\n * Dev donation.\n * Percentage of your hashing power that you want to donate to the developer, can be 0"
  },
  {
    "path": "executor.cpp",
    "chars": 22072,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "executor.h",
    "chars": 4122,
    "preview": "#pragma once\n#include \"thdq.hpp\"\n#include \"msgstruct.h\"\n#include <atomic>\n#include <array>\n#include <list>\n#include <fut"
  },
  {
    "path": "httpd.cpp",
    "chars": 4371,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "httpd.h",
    "chars": 503,
    "preview": "#pragma once\n\nstruct MHD_Daemon;\nstruct MHD_Connection;\n\nclass httpd\n{\npublic:\n\tstatic httpd* inst()\n\t{\n\t\tif (oInst == n"
  },
  {
    "path": "jconf.cpp",
    "chars": 10121,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "jconf.h",
    "chars": 1010,
    "preview": "#pragma once\n#include <stdlib.h>\n#include <string>\n\nclass jconf\n{\npublic:\n\tstatic jconf* inst()\n\t{\n\t\tif (oInst == nullpt"
  },
  {
    "path": "jext.h",
    "chars": 310,
    "preview": "#pragma once\n\nusing namespace rapidjson;\n\n/* This macro brings rapidjson more in line with other libs */\ninline const Va"
  },
  {
    "path": "jpsock.cpp",
    "chars": 14637,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "jpsock.h",
    "chars": 2925,
    "preview": "#pragma once\n#include <mutex>\n#include <atomic>\n#include <condition_variable>\n#include <thread>\n#include <string>\n\n#incl"
  },
  {
    "path": "libmicrohttpd/microhttpd.h",
    "chars": 97367,
    "preview": "/*\n     This file is part of libmicrohttpd\n     Copyright (C) 2006-2015 Christian Grothoff (and other contributing autho"
  },
  {
    "path": "minethd.cpp",
    "chars": 7878,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "minethd.h",
    "chars": 3423,
    "preview": "#pragma once\n#include <thread>\n#include <atomic>\n\n#include \"amd_gpu/gpu.h\"\n\nclass telemetry\n{\npublic:\n\ttelemetry(size_t "
  },
  {
    "path": "msgstruct.h",
    "chars": 3736,
    "preview": "#pragma once\n#include <string>\n#include <string.h>\n#include <assert.h>\n\n// Structures that we use to pass info between t"
  },
  {
    "path": "opencl/blake256.cl",
    "chars": 3332,
    "preview": "/*\n* blake256 kernel implementation.\n*\n* ==========================(LICENSE BEGIN)============================\n* Copyrig"
  },
  {
    "path": "opencl/cryptonight.cl",
    "chars": 31013,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "opencl/groestl256.cl",
    "chars": 16648,
    "preview": "/* $Id: groestl.c 260 2011-07-21 01:02:38Z tp $ */\n/*\n * Groestl256\n *\n * ==========================(LICENSE BEGIN)====="
  },
  {
    "path": "opencl/jh.cl",
    "chars": 10073,
    "preview": "/* $Id: jh.c 255 2011-06-07 19:50:20Z tp $ */\n/*\n * JH implementation.\n *\n * ==========================(LICENSE BEGIN)=="
  },
  {
    "path": "opencl/wolf-aes.cl",
    "chars": 4180,
    "preview": "#ifndef WOLF_AES_CL\n#define WOLF_AES_CL\n\n// AES table - the other three are generated on the fly\n\nstatic const __constan"
  },
  {
    "path": "opencl/wolf-skein.cl",
    "chars": 2959,
    "preview": "#ifndef WOLF_SKEIN_CL\n#define WOLF_SKEIN_CL\n\n// Vectorized Skein implementation macros and functions by Wolf\n\n#define SK"
  },
  {
    "path": "rapidjson/allocators.h",
    "chars": 10311,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/document.h",
    "chars": 115255,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/encodedstream.h",
    "chars": 10686,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/encodings.h",
    "chars": 28553,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/error/en.h",
    "chars": 3870,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/error/error.h",
    "chars": 5824,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/filereadstream.h",
    "chars": 2988,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/filewritestream.h",
    "chars": 3139,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/fwd.h",
    "chars": 4035,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/biginteger.h",
    "chars": 9139,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/diyfp.h",
    "chars": 11512,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/dtoa.h",
    "chars": 8172,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/ieee754.h",
    "chars": 3022,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/itoa.h",
    "chars": 10306,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/meta.h",
    "chars": 6572,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/pow10.h",
    "chars": 3595,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/regex.h",
    "chars": 25726,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/stack.h",
    "chars": 7026,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/strfunc.h",
    "chars": 1994,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/strtod.h",
    "chars": 8672,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/internal/swap.h",
    "chars": 1419,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n//\n// Copyright (C) 2015 THL A"
  },
  {
    "path": "rapidjson/istreamwrapper.h",
    "chars": 3576,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/memorybuffer.h",
    "chars": 2560,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/memorystream.h",
    "chars": 2667,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/msinttypes/inttypes.h",
    "chars": 8372,
    "preview": "// ISO C9x  compliant inttypes.h for Microsoft Visual Studio\n// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) "
  },
  {
    "path": "rapidjson/msinttypes/stdint.h",
    "chars": 9386,
    "preview": "// ISO C9x  compliant stdint.h for Microsoft Visual Studio\n// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG"
  },
  {
    "path": "rapidjson/ostreamwrapper.h",
    "chars": 2331,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/pointer.h",
    "chars": 58465,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/prettywriter.h",
    "chars": 10102,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/rapidjson.h",
    "chars": 21461,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/reader.h",
    "chars": 79233,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n//\n// Copyright (C) 2015 THL A"
  },
  {
    "path": "rapidjson/schema.h",
    "chars": 80695,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available->\n// \n// Copyright (C) 2015 THL"
  },
  {
    "path": "rapidjson/stream.h",
    "chars": 5466,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/stringbuffer.h",
    "chars": 3993,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "rapidjson/writer.h",
    "chars": 23653,
    "preview": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL "
  },
  {
    "path": "socket.cpp",
    "chars": 7660,
    "preview": "/*\n  * This program is free software: you can redistribute it and/or modify\n  * it under the terms of the GNU General Pu"
  },
  {
    "path": "socket.h",
    "chars": 1084,
    "preview": "#pragma once\n#include \"socks.h\"\nclass jpsock;\n\nclass base_socket\n{\npublic:\n\tvirtual bool set_hostname(const char* sAddr)"
  },
  {
    "path": "socks.h",
    "chars": 1796,
    "preview": "#pragma once\n#ifdef _WIN32\n#ifndef _WIN32_WINNT\n#define _WIN32_WINNT 0x0601  /* Windows 7 */\n#endif\n#include <winsock2.h"
  },
  {
    "path": "thdq.hpp",
    "chars": 904,
    "preview": "#pragma once\r\n\r\n#include <queue>\r\n#include <thread>\r\n#include <mutex>\r\n#include <condition_variable>\r\n\r\ntemplate <typena"
  },
  {
    "path": "version.h",
    "chars": 90,
    "preview": "#pragma once\n\n#define XMR_STAK_NAME \"xmr-stak-amd\"\n#define XMR_STAK_VERSION \"1.1.0-1.4.0\"\n"
  },
  {
    "path": "webdesign.cpp",
    "chars": 4282,
    "preview": "#include <stdlib.h>\n\nextern const char sHtmlCssEtag [] = \"00000006\";\nextern const char sHtmlCssFile [] =\n\t\"body {\"\n\t\t\"fo"
  },
  {
    "path": "webdesign.h",
    "chars": 537,
    "preview": "#pragma once\n\nextern const char sHtmlCssEtag[];\nextern const char sHtmlCssFile[];\nextern size_t sHtmlCssSize;\n\nextern co"
  },
  {
    "path": "xmr-stak-amd.cbp",
    "chars": 5620,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n<CodeBlocks_project_file>\n\t<FileVersion major=\"1\" minor=\"6\" />\n"
  }
]

About this extraction

This page contains the full source code of the fireice-uk/xmr-stak-amd GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 91 files (1.1 MB), approximately 331.3k tokens, and a symbol index with 830 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!