commit c97d09c8de8a1751f2072908498f4237f824dd57 Author: LoRd_MuldeR Date: Wed May 10 23:08:24 2023 +0200 Initial commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de9d101 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.o +*.user +/**/obj +/.vs +/bin +/out diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..955913e --- /dev/null +++ b/Makefile @@ -0,0 +1,94 @@ +STATIC ?= 0 +FLTO ?= 0 +DEBUG ?= 0 +STRIP ?= 0 + +# ---------------------------------------------------------------------------- +# Flags +# ---------------------------------------------------------------------------- + +OS_TYPE := $(shell $(CC) -dumpmachine) + +ifneq ($(TARGET),) + CFLAGS += -target $(TARGET) +endif + +ifneq ($(SYSROOT),) + CFLAGS += --sysroot=$(SYSROOT) +endif + +ifneq ($(CPU),) + CFLAGS += -m$(CPU) +endif + +CFLAGS += -std=gnu99 -Wall -pedantic -Wno-deprecated-declarations -Ilibnuhash/include -D_FILE_OFFSET_BITS=64 + +ifneq ($(DEBUG),1) + CFLAGS += -Ofast -DNDEBUG +else + CFLAGS += -Og -g +endif + +ifeq ($(FLTO),1) + CFLAGS += -flto +endif + +ifneq ($(MARCH),) + CFLAGS += -march=$(MARCH) +endif + +ifneq ($(MTUNE),) + CFLAGS += -mtune=$(MTUNE) +endif + +ifeq ($(STATIC),1) + LDFLAGS += -static +endif + +ifeq ($(STRIP),1) + LDFLAGS += -Wl,-s +endif + +ifneq ($(filter %w64-mingw32 %w64-windows-gnu,$(OS_TYPE)),) + LDFLAGS += -municode +endif + +# ---------------------------------------------------------------------------- +# Files +# ---------------------------------------------------------------------------- + +INFILES = $(patsubst %.c,%.o,$(wildcard libnuhash/src/*.c)) $(patsubst %.c,%.o,$(wildcard tool/src/*.c)) +OUTFILE = bin/nuhash +OUTPATH = $(patsubst %/,%,$(dir $(OUTFILE))) + +ifneq ($(filter %mingw32 %windows-gnu %cygwin %cygnus,$(OS_TYPE)),) + OUTFILE := $(OUTFILE).exe +endif + +ifneq ($(filter %mingw32 %windows-gnu %cygwin %cygnus,$(OS_TYPE)),) + INFILES += $(patsubst %.rc,%.o,$(wildcard tool/res/*.rc)) +endif + +# ---------------------------------------------------------------------------- +# Rules +# ---------------------------------------------------------------------------- + +.PHONY: all clean + +all: $(OUTFILE) + +$(OUTFILE): $(INFILES) | $(OUTPATH) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +$(OUTPATH): + mkdir -p $@ + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.o: %.rc + windres -o $@ $< + +clean: + rm -vrf $(OUTPATH) + find . \! -path '*/.*' -type f -name '*.o' -exec rm -vf {} \; diff --git a/README.md b/README.md new file mode 100644 index 0000000..101a37e --- /dev/null +++ b/README.md @@ -0,0 +1,306 @@ +![](etc/images/nuhash_logo.png) + + +Introduction +============ + +**NuHash** is a fast, portable and secure hashing library, released under the CC0 license. + +The "core" library (*libnuhash*) is written in pure **C99**, but a high-level wrapper for **C++** is also provided. + +Supported platforms include Linux, Windows, *BSD, Illumos, Haiku OS, GNU Hurd and MacOS X. + + +Getting Started +=============== + +The following example shows how to use the *libnuhash* “stream” API in C99 code: + +```c +#include +#include + +int main(int argc, char *argv[]) +{ + /* state variables */ + nuhash_t context; + uint8_t buffer[BUFSIZ], digest[NUHASH_BYTES]; + char hexstr[NUHASH_CHARS]; + + /* initialization */ + nuhash_init(&context); + + /* input data processing */ + while(more_data()) + { + const size_t len = read_data(buffer, BUFSIZ); + nuhash_update(&context, buffer, len); + } + + /* finalization */ + nuhash_final(&context, digest); + + /* print the result */ + puts(nuhash_tohex(digest, 0, hexstr)); +} +``` + +If all input data is available at once, the *libnuhash* “simple” API can be used instead: + +```c +#include +#include + +int main(int argc, char *argv[]) +{ + /* state variables */ + uint8_t digest[NUHASH_BYTES]; + char hexstr[NUHASH_CHARS]; + + /* compute hash */ + nuhash_compute(get_data(), length(), digest); + + /* print the result */ + puts(nuhash_tohex(digest, 0, hexstr)); +} +``` + + +Command-line Usage +================== + +The **`nuhash`** command-line tool provides an interface similar to [`sha256sum`](https://linux.die.net/man/1/sha256sum) and friends: + +``` +Usage: + nuhash.exe [options] [ [... ]] + +Options: + -b --binary Output digest as binary, default is hex-string. + -h --help Print the help screen and exit. + -i --ignore Ignore interrupt signals. + -l --line-mode Process the input file(s) as text, line by line. + -p --progress Print progress, while computing the hash. + -s --stop Stop on all errors, default is to keep going. + -t --self-test Run the built-in self-test. + -u --uppercase Print digest as uppercase, default is lowercase. + -v --version Print version information and exit. +``` + +### Example output: + +``` +abe9d2f9f55d62951540397875f1104d0374a7ce3ca9e21cfde6efd638b75765885f186477669b79d78d13b6d1abe0a2 foo +06573eaba880f77db3a9e6a085e3a4f8c1bf6f2997d6789bc38439d1f581e0907b21200aff43df37de27d241dc64d19e bar +e26b0338b7a3d662397cbc1ff9f81ac8885ee71f861f5897fc3a7b113ea314994f749caf7618a4bfc1ac90727ef64f94 baz +d113572666421a1e2cf6e17481f1f94b2b006e8c48504fea03e4b24d04930db4302368dc0e7bf44b104f7118bdd62f2d qux +``` + + +Application Programming Interface (API) +======================================= + +C99 API +------- + +### Constants + +The C99 API defines the following constants: + +* **`NUHASH_WORDS`:** The size of the “raw” hash value (digest), in [`uint64_t`](https://cplusplus.com/reference/cstdint/) words. + +* **`NUHASH_BYTES`:** The size of the “raw” hash value (digest), in bytes. + +* **`NUHASH_CHARS`:** The size of the hash value (digest) encoded as a null-terminated “hex” string, in characters. This is twice the size of a “raw” hash value *plus* an additional slot for the terminating `\0` character. + +### Simple + +The ***simple*** API can be used to compute a hash value in an *“all at once”* fashion. + +Use this API, if *all* input data is available at once. It can compute the hash value with as *single* function call. + +#### `nuhash_compute()` + +Compute the hash value from the given input data and return the resulting hash value (digest). + +* Syntax: + ```c + uint8_t *nuhash_compute(const uint8_t *const src, const size_t len, uint8_t *const out); + ``` + +* Parameters: + - **`src`:** Pointer to the source array containing all input data to be processed (sequence of bytes). + - **`len`:** The length of the input data, in bytes. + - **`out`:** Pointer to the destination array where the hash value is stored, **must** be `NUHASH_BYTES` in size. + +* Return value: + - This function returns the given `out` pointer. + +#### `nuhash_compute_with_key()` + +Compute the hash value from the given input data and a user-defined key; returns the hash value (digest). + +* Syntax: + ```c + uint8_t *nuhash_compute_with_key(const uint8_t *const key, const size_t key_len, + const uint8_t *const src, const size_t in_len, uint8_t *const out); + ``` + +* Parameters: + - **`key`:** Pointer to the source array containing a user-defined key (sequence of bytes). + - **`key_len`:** The length of the user-defined key, in bytes. + - **`src`:** Pointer to the source array containing all input data to be processed (sequence of bytes). + - **`in_len`:** The length of the input data, in bytes. + - **`out`:** Pointer to the destination array where the hash value is stored, **must** be `NUHASH_BYTES` in size. + +* Return value: + - This function returns the given `out` pointer. + +### Stream API + +The ***stream*** API can be used to compute a hash value in a *“step by step”* fashion. + +Use this API, if **not** all input data is available at once. The input data can be processed in chunks of arbitrary size. + +#### `nuhash_t` + +An object containing the state of an ongoing hash computation. + +The application **shall** treat this type as an *opaque* data structure; it is **not** meant to be accessed directly! + +#### `nuhash_init()` + +Initialize or reset the state for a new hash computation. + +This function is supposed to be called exactly *once* at the beginning of a new hash computation! + +* Syntax: + ```c + void nuhash_init(nuhash_t *const ctx); + ``` + +* Parameters: + - **`ctx`:** Pointer to the `nuhash_t` instance to be initialized. + +#### `nuhash_init_with_key()` + +Initialize or reset the state for a new hash computation with a user-defined key. + +This function is supposed to be called exactly *once* at the beginning of a new hash computation! + +* Syntax: + ```c + void nuhash_init_with_key(nuhash_t *const ctx, const uint8_t *const key, const size_t len); + ``` + +* Parameters: + - **`ctx`:** Pointer to the `nuhash_t` instance to be initialized. + - **`key`:** Pointer to the source array containing the user-defined key (sequence of bytes). + - **`len`:** The length of the user-defined key, in bytes. + +#### `nuhash_update()` + +Process the next chunk of input data and update the state. + +This function is supposed to be called *repeatedly* until all the input data has been processed! + +* Syntax: + ```c + void nuhash_update(nuhash_t *const ctx, const uint8_t *const src, const size_t len); + ``` + +* Parameters: + - **`ctx`:** Pointer to the `nuhash_t` instance to be updated. + - **`src`:** Pointer to the source array containing the next chunk of input data (sequence of bytes). + - **`len`:** The length of the input data, in bytes. + +#### `nuhash_final()` + +Finish the hash computation and return the resulting hash value (digest). + +This function is supposed to be called exactly *once* after all the input data has been processed! After calling this function, the `nuhash_t` instance is **invalidated**; it must be [*reset*](#nuhash_init) in order to start a new hash computation. + +* Syntax: + ```c + uint8_t *nuhash_final(nuhash_t *const ctx, uint8_t *const out); + ``` + +* Parameters: + - **`ctx`:** Pointer to the `nuhash_t` instance to be updated. + - **`out`:** Pointer to the destination array where the hash value is stored, **must** be `NUHASH_BYTES` in size. + +* Return value: + - This function returns the given `out` pointer. + +### Utilities + +The C99 API also provides a few additional utility functions that may be helpful. + +#### `nuhash_tohex()` + +Converts a “raw” hash value (digest) into a null-terminated “hex” string. + +* Syntax: + ```c + char *nuhash_tohex(const uint8_t *const hash, const int upper, char *const out); + ``` + +* Parameters: + - **`hash`:** Pointer to the source array containing the “raw” hash value, **must** be `NUHASH_BYTES` in size. + - **`upper`:** If non-zero, generate upper-case characters; otherwise generate lower-case characters. + - **`out`:** Pointer to the destination array where the “hex” string is stored, **must** be `NUHASH_CHARS` in size. + +* Return value: + - This function returns the given `out` pointer. + +#### `nuhash_version()` + +Returns the version number and the build date of the current *libnuhash* library. + +* Syntax: + ```c + char *nuhash_version(uint16_t version[3U], char *const build); + ``` + +* Parameters: + - **`version`:** Pointer to the destination array where the *major*, *minor* and *patch* version are stored. + - **`build`:** Pointer to the destination array where the build date is stored, **must** be 12 characters in size. + +* Return value: + - This function returns the given `build` pointer. + +### Thread-safety + +All functions provided by ***libnuhash*** are *thread-safe* and *reentrant*, in the sense that there is **no** implicitly shared “global” state; the functions operate strictly on the given input parameters. Specifically, the functions of the “stream” API maintain **all** state of the hash computation within the given `nuhash_t` instance. This means that these functions are *thread-safe* and *reentrant* as long as each “concurrent” invocation uses its own separate `nuhash_t` instance; **no** synchronization is required in that case. However, *libnuhash* makes **no** attempt to coordinate the access to the *same* `nuhash_t` instance between concurrent threads. If the *same* `nuhash_t` instance needs to be accessed by *multiple* concurrent threads (which generally is **not** advised), then the application is responsible for *serializing* all access to that “shared” instance, e.g. by using a [*mutex*](https://pubs.opengroup.org/onlinepubs/009604499/functions/pthread_mutex_lock.html) lock! Reentrancy can **not** be achieved with a single “shared” `nuhash_t`. + + + +Source Code +=========== + +The source code is available from these [Git](https://git-scm.com/) mirrors: + +* `git clone https://github.com/lordmulder/NuHash.git` ([Browse](https://github.com/lordmulder/NuHash)) +* `git clone https://bitbucket.org/muldersoft/nuhash.git` ([Browse](https://bitbucket.org/muldersoft/nuhash/)) +* `git clone https://gitlab.com/lord_mulder/nuhash.git` ([Browse](https://gitlab.com/lord_mulder/nuhash)) +* `git clone https://repo.or.cz/nuhash.git` ([Browse](https://repo.or.cz/nuhash.git)) +* `git clone https://punkindrublic.mooo.com:3000/Muldersoft/NuHash.git` ([Browse](https://punkindrublic.mooo.com:3000/Muldersoft/NuHash)) + + +License +======= + +This work has been released under the **CC0 1.0 Universal** license. + +For details, please refer to: + + +Acknowledgment +-------------- + +Licenses for third-party components used by NuHash: + +* [**Hash icons**](https://www.flaticon.com/free-icons/hash) + Created by Vectors Market – Flaticon. Free for personal and commercial use with attribution. + +▮ diff --git a/etc/build/cygwin/mk-release.sh b/etc/build/cygwin/mk-release.sh new file mode 100755 index 0000000..779d482 --- /dev/null +++ b/etc/build/cygwin/mk-release.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -e +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../../.." + +mk_nuhash() { + local command="make -B CC=${2} MARCH=${3} MTUNE=${4} STATIC=1 STRIP=1" + $BASH -x -c "${command}" + mv -vf "${PWD}/bin/nuhash" "${PWD}/out/nuhash-${1}" +} + +if [[ "$(uname -s)" != "CYGWIN_NT"* ]]; then + echo "This script is supposed to run on the Cygwin platform !!!" + exit 1 +fi + +[[ "${1}" == "--no-remove" ]] || rm -vrf "${PWD}/out" && mkdir -vp "${PWD}/out" +$BASH -x -c "make clean" + +case "$(uname -m)" in + x86_64) + mk_nuhash "x86_64" "clang" "x86-64" "znver3" + ;; + i686) + mk_nuhash "i686" "gcc" "pentiumpro" "generic" + ;; + *) + echo "Unknown host CPU type !!!" + exit 1 +esac + +cp -vf "$(which cygwin1.dll)" "${PWD}/out" + +echo "Build completed successfully." diff --git a/etc/build/dragonfly/mk-release.sh b/etc/build/dragonfly/mk-release.sh new file mode 100755 index 0000000..fce2232 --- /dev/null +++ b/etc/build/dragonfly/mk-release.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# pkg install llvm14 +set -e +cd -- "$(dirname -- "${0}")/../../.." + +mk_nuhash() { + local command="gmake -B CC=clang14 STATIC=1 STRIP=1 ${2}" + $SHELL -x -c "${command}" + mv -vf "${PWD}/bin/nuhash" "${PWD}/out/nuhash-${1}" +} + +if [ "$(uname -sm)" != "DragonFly x86_64" ]; then + echo "This script is supposed to run on the DragonFly (x86_64) platform !!!" + exit 1 +fi + +rm -rf "${PWD}/out" && mkdir -p "${PWD}/out" +$SHELL -x -c "gmake clean" + +mk_nuhash "x86_64" "MARCH=x86-64 MTUNE=znver3" + +printf "\033[1;32m\nBuild completed successfully.\033[0m\n\n" diff --git a/etc/build/freebsd/mk-release.sh b/etc/build/freebsd/mk-release.sh new file mode 100755 index 0000000..a6f822c --- /dev/null +++ b/etc/build/freebsd/mk-release.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# pkg install {armv7,aarch64,powerpc,powerpc64,powerpc64le,riscv64}-freebsd-sysroot +set -e +cd -- "$(dirname -- "${0}")/../../.." + +mk_nuhash1() { + local command="gmake -B CPU=${1} STATIC=1 STRIP=1 FLTO=1 ${3}" + $SHELL -x -c "${command}" + mv -vf "${PWD}/bin/nuhash" "${PWD}/out/nuhash-${2}" +} + +mk_nuhash2() { + local command="gmake -B TARGET=${1}-unknown-freebsd SYSROOT=/usr/local/freebsd-sysroot/${1} STATIC=1 STRIP=1" + $SHELL -x -c "${command}" + mv -vf "${PWD}/bin/nuhash" "${PWD}/out/nuhash-${1}" +} + +if [ "$(uname -sm)" != "FreeBSD amd64" ]; then + echo "This script is supposed to run on the FreeBSD (amd64) platform !!!" + exit 1 +fi + +rm -rf "${PWD}/out" && mkdir -p "${PWD}/out" +$SHELL -x -c "gmake clean" + +mk_nuhash1 32 "i686" "MARCH=pentiumpro MTUNE=generic" +mk_nuhash1 64 "x86_64" "MARCH=x86-64 MTUNE=znver3" +mk_nuhash2 "armv7" +mk_nuhash2 "aarch64" +mk_nuhash2 "powerpc" +mk_nuhash2 "powerpc64" +mk_nuhash2 "powerpc64le" +mk_nuhash2 "riscv64" + +printf "\033[1;32m\nBuild completed successfully.\033[0m\n\n" diff --git a/etc/build/gnuhurd/mk-release.sh b/etc/build/gnuhurd/mk-release.sh new file mode 100755 index 0000000..584c346 --- /dev/null +++ b/etc/build/gnuhurd/mk-release.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -e +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../../.." + +function mk_nuhash() { + local command="make -B CC=gcc STATIC=1 STRIP=1 FLTO=1" + $BASH -x -c "${command}${2:+ ${2}}" + mv -vf "${PWD}/bin/nuhash" "${PWD}/out/nuhash-${1}" +} + +if [[ "$(uname -sm)" != "GNU i686-AT386" ]]; then + echo "This script is supposed to run on the GNU Hurd (i686) platform !!!" + exit 1 +fi + +rm -rf "${PWD}/out" && mkdir -p "${PWD}/out" +$BASH -x -c "make clean" + +mk_nuhash "i686" "MARCH=pentiumpro MTUNE=generic" + +printf "\033[1;32m\nBuild completed successfully.\033[0m\n\n" diff --git a/etc/build/haiku/mk-release.sh b/etc/build/haiku/mk-release.sh new file mode 100755 index 0000000..2e838b5 --- /dev/null +++ b/etc/build/haiku/mk-release.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# pkgman install llvm12_clang +set -e +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../../.." + +mk_nuhash() { + local command="make -B CC=${2} MARCH=${3} MTUNE=${4} STATIC=1 STRIP=1" + $BASH -x -c "${command}" + mv -vf "bin/nuhash" "out/nuhash-${1}" +} + +if [ "$(uname)" != "Haiku" ]; then + echo "This script is supposed to run on the Haiku platform !!!" + exit 1 +fi + +rm -rf "out" && mkdir -p "out" +$BASH -x -c "make clean" + +case "${BE_HOST_CPU}" in + x86_64) + mk_nuhash "x86_64" "clang-12" "x86-64" "znver3" + ;; + x86) + mk_nuhash "i686" "gcc-x86" "pentiumpro" "generic" + ;; + *) + echo "Unknown host CPU type !!!" + exit 1 +esac + +echo "Build completed successfully." diff --git a/etc/build/linux/mk-libmusl.sh b/etc/build/linux/mk-libmusl.sh new file mode 100755 index 0000000..fd87329 --- /dev/null +++ b/etc/build/linux/mk-libmusl.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# sudo apt install clang crossbuild-essential-{i386,armel,armhf,arm64,mips,mipsel,mips64,mips64el,mips64r6,mips64r6el,s390x,riscv64} +set -e +cd -- "$(dirname -- "${BASH_SOURCE[0]}")" + +function mk_musl() { + for cc in gcc clang; do + local outdir="/usr/local/musl/${1}-${cc}" + local build="${PWD}/musl-build" + rm -rf "${build}" && mkdir -p "${build}" + tar -xvf "${PWD}/musl-latest.tar.gz" --strip-components=1 -C "${build}" + pushd "${build}" + local optdirs="$(find './src' -mindepth 1 -maxdepth 1 -type d -printf '%f,' | sed 's/,$//g')" + if [ "${cc}" == "clang" ]; then + CC="${cc} --target=${2}" ./configure --enable-optimize="${optdirs}" --disable-shared --enable-wrapper=${cc} --prefix="${outdir}" --host="${2}" + else + CC="${2}-${cc}" ./configure --enable-optimize="${optdirs}" --disable-shared --enable-wrapper=${cc} --prefix="${outdir}" --host="${2}" + fi + make + sudo rm -rf "${outdir}" && sudo make install + popd + done +} + +if [[ "$(uname -sm)" != "Linux x86_64" ]]; then + echo "This script is supposed to run on the Linux (x86_64) platform !!!" + exit 1 +fi + +if ! which gcc clang > /dev/null; then + echo "Please make sure that \"gcc\" and \"clang\" are installed !!!" + exit 1 +fi + +rm -f "${PWD}/musl-latest.tar.gz" +curl -vkf -o "${PWD}/musl-latest.tar.gz" "https://musl.libc.org/releases/musl-latest.tar.gz" + +mk_musl x86_64 x86_64-linux-gnu +mk_musl i686 i686-linux-gnu +mk_musl armel arm-linux-gnueabi +mk_musl armhf arm-linux-gnueabihf +mk_musl arm64 aarch64-linux-gnu +mk_musl mips mips-linux-gnu +mk_musl mipsel mipsel-linux-gnu +mk_musl mips64 mips64-linux-gnuabi64 +mk_musl mips64el mips64el-linux-gnuabi64 +mk_musl mips64r6 mipsisa64r6-linux-gnuabi64 +mk_musl mips64r6el mipsisa64r6el-linux-gnuabi64 +mk_musl s390x s390x-linux-gnu +mk_musl riscv64 riscv64-linux-gnu + +rm -rvf "${PWD}/musl-build" diff --git a/etc/build/linux/mk-release.sh b/etc/build/linux/mk-release.sh new file mode 100755 index 0000000..7a53fdf --- /dev/null +++ b/etc/build/linux/mk-release.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# See "etc/utils/linux/mk-libmusl.sh" in order to build musl libc! +set -e +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../../.." + +function mk_nuhash() { + local command="make -B CC=/usr/local/musl/${1}-${3:-clang}/bin/musl-${3:-clang} STATIC=1 STRIP=1 FLTO=1" + $BASH -x -c "${command}${2:+ ${2}}" + mv -vf "${PWD}/bin/nuhash" "${PWD}/out/nuhash-${1}" +} + +if [[ "$(uname -sm)" != "Linux x86_64" ]]; then + echo "This script is supposed to run on the Linux (x86_64) platform !!!" + exit 1 +fi + +rm -vrf "${PWD}/out" && mkdir -vp "${PWD}/out" +$BASH -x -c "make clean" + +mk_nuhash "x86_64" "MARCH=x86-64 MTUNE=znver3" +mk_nuhash "i686" "MARCH=pentiumpro MTUNE=generic" +mk_nuhash "armel" +mk_nuhash "armhf" +mk_nuhash "arm64" +mk_nuhash "mips" +mk_nuhash "mipsel" +mk_nuhash "mips64" "" "gcc" +mk_nuhash "mips64el" "" "gcc" +mk_nuhash "mips64r6" "" "gcc" +mk_nuhash "mips64r6el" "" "gcc" +mk_nuhash "s390x" +mk_nuhash "riscv64" + +$BASH -x -c "pandoc --standalone --embed-resources --css \"${PWD}/etc/style/gh-pandoc.min.css\" --metadata title=\"NuHash README\" -o \"${PWD}/out/README.html\" \"${PWD}/README.md\"" + +printf "\033[1;32m\nBuild completed successfully.\033[0m\n\n" diff --git a/etc/build/macos/hdiutil.txt b/etc/build/macos/hdiutil.txt new file mode 100644 index 0000000..4056cb5 --- /dev/null +++ b/etc/build/macos/hdiutil.txt @@ -0,0 +1 @@ +sudo hdiutil create archive.dmg -ov -volname "NuHash" -fs HFS+ -srcfolder out diff --git a/etc/build/macos/mk-release.sh b/etc/build/macos/mk-release.sh new file mode 100755 index 0000000..3e59824 --- /dev/null +++ b/etc/build/macos/mk-release.sh @@ -0,0 +1,24 @@ +#!/bin/sh +set -e +cd -- "$(dirname -- "${0}")/../../.." + +mk_nuhash() { + local command="make -B TARGET=${1}-apple-darwin FLTO=1" + $SHELL -x -c "${command}" + mv -vf "${PWD}/bin/nuhash" "${PWD}/out/nuhash-${1}" +} + +if [ "$(uname)" != "Darwin" ]; then + echo "This script is supposed to run on the MacOS platform !!!" + exit 1 +fi + +rm -rf "${PWD}/out" && mkdir -p "${PWD}/out" +$SHELL -x -c "make clean" + +mk_nuhash "x86_64" +mk_nuhash "aarch64" + +find "${PWD}/out" -type f -name 'nuhash-*' -exec $SHELL -x -c "strip \"{}\"" \; + +printf "\033[1;32m\nBuild completed successfully.\033[0m\n\n" diff --git a/etc/build/mingw/mk-clang.cmd b/etc/build/mingw/mk-clang.cmd new file mode 100644 index 0000000..01f6a28 --- /dev/null +++ b/etc/build/mingw/mk-clang.cmd @@ -0,0 +1,27 @@ +@echo off +cd /d "%~dp0" + +if "%MSYS2_DIR%"=="" ( + set "MSYS2_DIR=C:\msys64" +) + +if not exist "%MSYS2_DIR%\msys2_shell.cmd" ( + echo MSYS2 shell not found. Please check MSYS2_DIR and try again! + pause + goto:eof +) + +if exist "%~dp0..\..\..\out" ( + rmdir /S /Q "%~dp0..\..\..\out" +) + +for %%m in (32,64) do ( + echo ======================================================================== + echo Clang%%m + echo ======================================================================== + echo. + call "%MSYS2_DIR%\msys2_shell.cmd" -clang%%m -no-start -defterm -where "%~dp0" -c "./mk-release.sh --no-remove" + echo. +) + +pause diff --git a/etc/build/mingw/mk-gcc.cmd b/etc/build/mingw/mk-gcc.cmd new file mode 100644 index 0000000..8eb8901 --- /dev/null +++ b/etc/build/mingw/mk-gcc.cmd @@ -0,0 +1,27 @@ +@echo off +cd /d "%~dp0" + +if "%MSYS2_DIR%"=="" ( + set "MSYS2_DIR=C:\msys64" +) + +if not exist "%MSYS2_DIR%\msys2_shell.cmd" ( + echo MSYS2 shell not found. Please check MSYS2_DIR and try again! + pause + goto:eof +) + +if exist "%~dp0..\..\..\out" ( + rmdir /S /Q "%~dp0..\..\..\out" +) + +for %%m in (32,64) do ( + echo ======================================================================== + echo MinGW%%m + echo ======================================================================== + echo. + call "%MSYS2_DIR%\msys2_shell.cmd" -mingw%%m -no-start -defterm -where "%~dp0" -c "./mk-release.sh --no-remove" + echo. +) + +pause diff --git a/etc/build/mingw/mk-release.sh b/etc/build/mingw/mk-release.sh new file mode 100755 index 0000000..2162ac8 --- /dev/null +++ b/etc/build/mingw/mk-release.sh @@ -0,0 +1,37 @@ +#!/bin/bash +set -e +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../../.." + +mk_nuhash() { + local command="make -B CC=${2} MARCH=${3} MTUNE=${4} STATIC=1 STRIP=1 FLTO=1" + $BASH -x -c "${command}" + mv -vf "${PWD}/bin/nuhash" "${PWD}/out/nuhash-${1}" +} + +if [[ "$(uname -so)" != "MINGW"*" Msys" ]]; then + echo "This script is supposed to run on the Mingw-w64 platform !!!" + exit 1 +fi + +[[ "${1}" == "--no-remove" ]] || rm -vrf "${PWD}/out" && mkdir -vp "${PWD}/out" +$BASH -x -c "make clean" + +case "$MSYSTEM" in + MINGW64) + mk_nuhash "x86_64" "gcc" "x86-64" "znver3" + ;; + MINGW32) + mk_nuhash "i686" "gcc" "pentiumpro" "generic" + ;; + CLANG64) + mk_nuhash "x86_64" "clang" "x86-64" "znver3" + ;; + CLANG32) + mk_nuhash "i686" "clang" "pentiumpro" "generic" + ;; + *) + echo "Unknown host CPU type !!!" + exit 1 +esac + +echo "Build completed successfully." diff --git a/etc/build/netbsd/mk-release.sh b/etc/build/netbsd/mk-release.sh new file mode 100755 index 0000000..80194e8 --- /dev/null +++ b/etc/build/netbsd/mk-release.sh @@ -0,0 +1,22 @@ +#!/bin/ksh +set -e +cd -- "$(dirname -- "${0}")/../../.." + +mk_nuhash() { + local command="gmake -B CC=clang CPU=${1} MARCH=${3} MTUNE=${4} STATIC=1 STRIP=1" + $SHELL -x -c "${command}" + mv -vf "bin/nuhash" "out/nuhash-${2}" +} + +if [ "$(uname)" != "NetBSD" ]; then + echo "This script is supposed to run on the OpenBSD platform !!!" + exit 1 +fi + +rm -rf "out" && mkdir -p "out" +$SHELL -x -c "gmake clean" + +mk_nuhash 32 "i686" "pentiumpro" "generic" +mk_nuhash 64 "x86_64" "x86-64" "znver3" + +echo "Build completed successfully." diff --git a/etc/build/openbsd/mk-release.sh b/etc/build/openbsd/mk-release.sh new file mode 100755 index 0000000..d1696d3 --- /dev/null +++ b/etc/build/openbsd/mk-release.sh @@ -0,0 +1,31 @@ +#!/bin/ksh +set -e +cd -- "$(dirname -- "${0}")/../../.." + +mk_nuhash() { + local command="gmake -B MARCH=${2} MTUNE=${3} STATIC=1 STRIP=1 FLTO=1" + $SHELL -x -c "${command}" + mv -vf "bin/nuhash" "out/nuhash-${1}" +} + +if [ "$(uname)" != "OpenBSD" ]; then + echo "This script is supposed to run on the OpenBSD platform !!!" + exit 1 +fi + +rm -rf "out" && mkdir -p "out" +$SHELL -x -c "gmake clean" + +case "$(arch -s)" in + amd64) + mk_nuhash "x86_64" "x86-64" "znver3" + ;; + i386) + mk_nuhash "i686" "pentiumpro" "generic" + ;; + *) + echo "Unknown host CPU type !!!" + exit 1 +esac + +echo "Build completed successfully." diff --git a/etc/images/nuhash_logo.png b/etc/images/nuhash_logo.png new file mode 100644 index 0000000..d504ded Binary files /dev/null and b/etc/images/nuhash_logo.png differ diff --git a/etc/images/table_xor.png b/etc/images/table_xor.png new file mode 100644 index 0000000..4b0e815 Binary files /dev/null and b/etc/images/table_xor.png differ diff --git a/etc/style/gh-pandoc.min.css b/etc/style/gh-pandoc.min.css new file mode 100644 index 0000000..c569a2a --- /dev/null +++ b/etc/style/gh-pandoc.min.css @@ -0,0 +1 @@ +html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.caption{margin-bottom:5em}*{box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:10pt;line-height:1.6;margin:auto;max-width:864px;min-width:360px;padding:2rem;word-wrap:break-word}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25;margin-bottom:16px;margin-top:24px}h1{padding-bottom:.3em;font-size:2em;border-bottom:1px solid #eee}h2{padding-bottom:.3em;font-size:1.5em;border-bottom:1px solid #eee}h3{font-size:1.25em}h4{font-size:1.12em}h5{font-size:.875em}h6{font-size:.85em;color:#777}h1 tt,h1 code,h2 tt,h2 code,h3 tt,h3 code,h4 tt,h4 code,h5 tt,h5 code,h6 tt,h6 code{font-size:inherit}body>h2:first-child{margin-top:0;padding-top:0}body>h1:first-child{margin-top:0;padding-top:0}body>h1:first-child+h2{margin-top:0;padding-top:0}body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child{margin-top:0;padding-top:0}a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6{margin-top:0;padding-top:0}a{color:#4078c0;text-decoration:none}a:active,a:hover{outline:0;text-decoration:underline}sup,sub,a.footnote{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}ol,ul{margin-bottom:16px;margin-top:0;padding-left:2em}p,blockquote,table,pre{margin:15px 0}ul,ol{padding-left:2em}ul.no-list,ol.no-list{padding:0;list-style-type:none}ul ul,ul ol,ol ol,ol ul{margin-top:0;margin-bottom:0}li>p{margin-top:16px}li+li{margin-top:.25em}ol li ul:first-of-type{margin-top:0}hr{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;border:0 none;color:#ccc;height:4px;margin:16px 0;padding:0}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p,ul li>:first-child,ol li>:first-child{margin-top:0}dl{padding:0}dl dt{font-size:1em;font-weight:bold;font-style:italic;padding:0;margin:15px 0 5px}dl dt:first-child{padding:0}dl dt>:first-child{margin-top:0}dl dt>:last-child{margin-bottom:0}dl dd{margin:0 0 15px;padding:0 15px}dl dd>:first-child{margin-top:0}dl dd>:last-child{margin-bottom:0}blockquote{border-left:4px solid #DDD;padding:0 15px;color:#777}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}table{border-collapse:collapse;border-spacing:0;font-size:100%;font:inherit}table th{font-weight:bold;border:1px solid #ccc;padding:6px 13px}table td{border:1px solid #ccc;padding:6px 13px}table td>p:first-child{margin-top:0}table td>p:last-child{margin-bottom:0}table tr{border-top:1px solid #ccc;background-color:#fff}table tr:nth-child(2n){background-color:#f8f8f8}img{max-width:100%}code,tt{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:10pt;background-color:rgba(0,0,0,0.04);border-radius:3px}pre>code{margin:0;padding:0;white-space:pre;border:0;background:transparent}pre{padding:16px;margin-top:0;margin-bottom:0;background-color:#f8f8f8;font-size:10pt;line-height:19px;overflow:auto;border-radius:3px}pre code,pre tt{background-color:transparent;border:0}code::before,code::after,tt::before,tt::after{letter-spacing:-0.2em;content:"\00a0"}pre code::before,pre code::after,pre tt::before,pre tt::after{content:normal}code>span.kw{color:#a71d5d;font-weight:normal}code>span.dt{color:inherit}code>span.dv{color:#0086b3}code>span.bn{color:#0086b3}code>span.fl{color:#0086b3}code>span.ch{color:#183691}code>span.st{color:#183691}code>span.co{color:#969896;font-style:normal}code>span.ot{color:#a71d5d}code>span.al{color:red}code>span.fu{color:#795da3}code>span.er{color:red;font-weight:bold}code>span.wa{color:#969896;font-weight:bold;font-style:italic}code>span.cn{color:#800}code>span.sc{color:#183691}code>span.vs{color:#183691}code>span.ss{color:#b68}code>span.va{color:#19177c}code>span.cf{color:#a71d5d;font-weight:normal}code>span.op{color:#666}code>span.pp{color:#bc7a00}code>span.at{color:#0086b3}code>span.do{color:#ba2121;font-style:italic}code>span.an{color:#969896;font-weight:bold;font-style:italic}code>span.cv{color:#969896;font-weight:bold;font-style:italic}code>span.in{color:#969896;font-weight:bold;font-style:italic}@media print{body{background:#fff}img,pre,blockquote,table,figure{page-break-inside:avoid}body{background:#fff;border:0}code{background-color:#fff;color:#333 !important;padding:0 .2em;border:1px solid #dedede}pre{background:#fff}pre code{background-color:white !important;overflow:visible}}@media screen{::selection{background:rgba(157,193,200,0.5)}h1::selection{background-color:rgba(45,156,208,0.3)}h2::selection{background-color:rgba(90,182,224,0.3)}h3::selection,h4::selection,h5::selection,h6::selection,li::selection,ol::selection{background-color:rgba(133,201,232,0.3)}code::selection{background-color:rgba(0,0,0,0.7);color:#eee}code span::selection{background-color:rgba(0,0,0,0.7) !important;color:#eee !important}a::selection{background-color:rgba(255,230,102,0.2)}.inverted a::selection{background-color:rgba(255,230,102,0.6)}td::selection,th::selection,caption::selection{background-color:rgba(180,237,95,0.5)}} \ No newline at end of file diff --git a/libnuhash/include/nuhash.h b/libnuhash/include/nuhash.h new file mode 100644 index 0000000..2da91d8 --- /dev/null +++ b/libnuhash/include/nuhash.h @@ -0,0 +1,109 @@ +/******************************************************************************/ +/* NuHash, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +#ifndef _INC_LIBNUHASH_H +#define _INC_LIBNUHASH_H + +#ifndef __cplusplus +# include +# include +#else +# include +# include +#endif + +#define NUHASH_WORDS 6U +#define NUHASH_BYTES (sizeof(uint64_t) * NUHASH_WORDS) +#define NUHASH_CHARS ((2U * NUHASH_BYTES) + 1U) + +/* Must be defined to build/use DLL */ +#ifdef LIBNUHASH_DLL +# ifdef LIBNUHASH_EXPORTS +# define NUHASH_API __declspec(dllexport) +# else +# define NUHASH_API __declspec(dllimport) +# endif +#else +# define NUHASH_API +#endif + +/* ------------------------------------------------------------------------ */ +/* C99 API */ +/* ------------------------------------------------------------------------ */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + uint64_t hash[NUHASH_WORDS]; +} +nuhash_t; + +/* Stream API */ +NUHASH_API void nuhash_init(nuhash_t *const ctx); +NUHASH_API void nuhash_init_with_key(nuhash_t *const ctx, const uint8_t *const key, const size_t len); +NUHASH_API void nuhash_update(nuhash_t *const ctx, const uint8_t *const src, const size_t len); +NUHASH_API uint8_t *nuhash_final(nuhash_t *const ctx, uint8_t *const out); + +/* Simple API */ +NUHASH_API uint8_t *nuhash_compute(const uint8_t *const src, const size_t len, uint8_t *const out); +NUHASH_API uint8_t *nuhash_compute_with_key(const uint8_t *const key, const size_t key_len, const uint8_t *const src, const size_t in_len, uint8_t *const out); + +/* Utilities */ +NUHASH_API char *nuhash_tohex(const uint8_t *const hash, const int upper, char *const out); +NUHASH_API char *nuhash_version(uint16_t version[3U], char *const build); + +#ifdef __cplusplus +} +#endif + +/* ------------------------------------------------------------------------ */ +/* C++ API */ +/* ------------------------------------------------------------------------ */ + +#if defined(__cplusplus) && !defined(NUHASH_NO_CPLUSPLUS) + +#include +#include +#include + +class NuHash +{ +public: + NuHash(void) { reset(); } + NuHash(const std::vector &key) { reset(key); } + void update(const uint8_t *const src, const size_t len) { ::nuhash_update(&m_ctx, src, len); } + void update(const uint8_t src) { ::nuhash_update(&m_ctx, &src, sizeof(uint8_t)); } + void update(const std::vector &src) { ::nuhash_update(&m_ctx, src.data(), src.size()); } + void update(const std::string &src) { ::nuhash_update(&m_ctx, reinterpret_cast(src.c_str()), src.size()); } + std::string do_final(const bool uppercase = false); + void do_final(std::array &out) { ::nuhash_final(&m_ctx, out.data()); } + void reset(void) { ::nuhash_init(&m_ctx); } + void reset(const std::vector &key) { ::nuhash_init_with_key(&m_ctx, key.data(), key.size()); } + static std::string version(std::array &version); +private: + nuhash_t m_ctx; + NuHash(const NuHash&) { std::abort(); } + NuHash &operator=(const NuHash&) { std::abort(); } +}; + +std::string NuHash::do_final(const bool uppercase) +{ + std::array digest; + std::array hex; + return std::string(::nuhash_tohex(::nuhash_final(&m_ctx, digest.data()), uppercase, hex.data())); +} + +std::string NuHash::version(std::array &version) +{ + std::array build; + return std::string(::nuhash_version(version.data(), build.data())); +} + +#endif + +#endif /*_INC_LIBNUHASH_H*/ diff --git a/libnuhash/libnuhash.vcxproj b/libnuhash/libnuhash.vcxproj new file mode 100644 index 0000000..639e500 --- /dev/null +++ b/libnuhash/libnuhash.vcxproj @@ -0,0 +1,463 @@ + + + + + Debug + ARM64 + + + Debug + Win32 + + + Release_DLL + ARM64 + + + Release_DLL + Win32 + + + Release_DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + 16.0 + Win32Proj + {8fa5c597-887d-46bc-a6c9-2183aef7b793} + libnuhash + 10.0.20348.0 + + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + x64 + + + DynamicLibrary + false + v143 + true + Unicode + x64 + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + x64 + + + DynamicLibrary + false + v143 + true + Unicode + x64 + + + StaticLibrary + false + v143 + true + Unicode + x64 + + + DynamicLibrary + false + v143 + true + Unicode + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + libnuhash-1 + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + libnuhash-1 + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + libnuhash-1 + + + true + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + libnuhash-1 + + + true + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + libnuhash-1 + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + libnuhash-1 + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + libnuhash-1 + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + libnuhash-1 + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + libnuhash-1 + + + + Level4 + false + WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + NotUsing + pch.h + $(ProjectDir)include + false + 4706;4996;6031 + true + + + + + true + + + + + Level4 + true + true + false + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + NotUsing + pch.h + $(ProjectDir)include + MultiThreaded + NoExtensions + false + AnySuitable + Speed + true + 4706;4996;6031 + true + false + Fast + false + MaxSpeed + true + + + + + true + true + true + + + + + Level4 + true + true + false + LIBNUHASH_DLL;LIBNUHASH_EXPORTS;WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + NotUsing + pch.h + $(ProjectDir)include + MultiThreadedDLL + NoExtensions + false + AnySuitable + Speed + true + 4706;4996;6031 + true + false + Fast + false + MaxSpeed + true + + + Console + true + true + true + 5.1 + + + + + Level4 + false + _DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + NotUsing + pch.h + $(ProjectDir)include + false + 4706;4996;6031 + true + + + + + true + + + + + Level4 + false + _DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + NotUsing + pch.h + $(ProjectDir)include + false + 4706;4996;6031 + true + + + + + true + + + + + Level4 + true + true + false + NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + NotUsing + pch.h + $(ProjectDir)include + MultiThreaded + false + AnySuitable + Speed + true + 4706;4996;6031 + true + false + Fast + false + MaxSpeed + true + + + + + true + true + true + + + + + Level4 + true + true + false + LIBNUHASH_DLL;LIBNUHASH_EXPORTS;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + NotUsing + pch.h + $(ProjectDir)include + MultiThreadedDLL + false + AnySuitable + Speed + true + 4706;4996;6031 + true + false + Fast + false + MaxSpeed + true + + + Console + true + true + true + 5.2 + + + + + Level4 + true + true + false + NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + NotUsing + pch.h + $(ProjectDir)include + MultiThreaded + false + AnySuitable + Speed + true + 4706;4996;6031 + true + false + Fast + false + MaxSpeed + true + + + + + true + true + true + + + + + Level4 + true + true + false + LIBNUHASH_DLL;LIBNUHASH_EXPORTS;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + NotUsing + pch.h + $(ProjectDir)include + MultiThreadedDLL + false + AnySuitable + Speed + true + 4706;4996;6031 + true + false + Fast + false + MaxSpeed + true + + + + + true + true + true + + + + + + \ No newline at end of file diff --git a/libnuhash/libnuhash.vcxproj.filters b/libnuhash/libnuhash.vcxproj.filters new file mode 100644 index 0000000..3331409 --- /dev/null +++ b/libnuhash/libnuhash.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Quelldateien + + + + + Headerdateien + + + Headerdateien + + + \ No newline at end of file diff --git a/libnuhash/src/nuhash.c b/libnuhash/src/nuhash.c new file mode 100644 index 0000000..95305c8 --- /dev/null +++ b/libnuhash/src/nuhash.c @@ -0,0 +1,554 @@ +/******************************************************************************/ +/* NuHash, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +#include "nuhash.h" +#include "version.h" +#include + +#define COUNT_OF(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0])) + +#define ROUNDS 5U + +/* Compiler inline support */ +#if defined(_MSC_VER) && !defined(__INTEL_LLVM_COMPILER) +# define INLINE __forceinline +#elif defined(__GNUC__) || defined(__clang__) || defined(__INTEL_LLVM_COMPILER) +# define INLINE __attribute__((always_inline)) __inline__ +#else +# define INLINE inline +#endif + +/* ------------------------------------------------------------------------ */ +/* Version */ +/* ------------------------------------------------------------------------ */ + +static const uint8_t VERSION_MAJOR = NUHASH_VERSION_MAJOR; +static const uint8_t VERSION_MINOR = NUHASH_VERSION_MINOR; +static const uint8_t VERSION_PATCH = NUHASH_VERSION_PATCH; + +static const char *const BUILD_DATE = __DATE__; + +/* ------------------------------------------------------------------------ */ +/* Const tables */ +/* ------------------------------------------------------------------------ */ + +/* 48 byte initialization vector containing the first 384 bits of PI */ +static const uint64_t NUHASH_INI[NUHASH_WORDS] = +{ + UINT64_C(0x243F6A8885A308D3), UINT64_C(0x13198A2E03707344), UINT64_C(0xA4093822299F31D0), + UINT64_C(0x082EFA98EC4E6C89), UINT64_C(0x452821E638D01377), UINT64_C(0xBE5466CF34E90C6C) +}; + +/* 257x48 byte matrix containing pre-computed 384-bit words with HamD(a,b) >= 182 for each pair (a,b) with a != b */ +static const uint64_t NUHASH_XOR[257U][NUHASH_WORDS] = +{ + { UINT64_C(0x01DCDF00414B3037), UINT64_C(0xB1B3AF661B8E96F8), UINT64_C(0x944D2873DB393121), UINT64_C(0x73DA9A36662AE755), UINT64_C(0x1F4F318C4ECB56B1), UINT64_C(0xF09743D99C2AA5BC) }, /*00*/ + { UINT64_C(0xA81FBBC6CBBFC954), UINT64_C(0x39DE43648959EDDB), UINT64_C(0x1A641A0BDA01822F), UINT64_C(0xB52E607266932658), UINT64_C(0x2C5B1731AC802084), UINT64_C(0xC2EF10671FC79DD4) }, /*01*/ + { UINT64_C(0xCF2A8D8E08810046), UINT64_C(0x8B7E9B2089E268F6), UINT64_C(0x930461652C5D2DEC), UINT64_C(0xF096E42223BFC8B9), UINT64_C(0x8DD338964CFE0970), UINT64_C(0x269C342F7CEC60BD) }, /*02*/ + { UINT64_C(0xB970A920D2ED0552), UINT64_C(0x010F894A254DA7E1), UINT64_C(0x8D5F205F9D1A40D8), UINT64_C(0x50C33DCCC3FD5F58), UINT64_C(0xB49F31BDE7D82C57), UINT64_C(0x7CDE04F62A959033) }, /*03*/ + { UINT64_C(0x49FAB2822B9C84AC), UINT64_C(0x34B8648CD68CBEF1), UINT64_C(0xE5121147BB4126DE), UINT64_C(0xC0B31F54B2FFE00F), UINT64_C(0x2F193DA38E8CC632), UINT64_C(0x058C984B429B8AFC) }, /*04*/ + { UINT64_C(0xE07F9DA44D8C9942), UINT64_C(0xBE2AF9B39ACA65F2), UINT64_C(0x5D3D8FB1466DC295), UINT64_C(0xC0051E3EC3F962C7), UINT64_C(0xF8FDC3CCD4CE2BB6), UINT64_C(0x9024C0EFC6199937) }, /*05*/ + { UINT64_C(0xA3111377EF01F5EF), UINT64_C(0x31F59B366C02A3FF), UINT64_C(0x61B82949760D16DC), UINT64_C(0xF6B958AF92BD3BDF), UINT64_C(0x7297AAEFEC69C0B2), UINT64_C(0xFE8A50AD9E8684CD) }, /*06*/ + { UINT64_C(0x3D3DD0C829EA9AA0), UINT64_C(0x3E77597EEC96C7A3), UINT64_C(0x8FD038231E7F1684), UINT64_C(0x64617B131FB7EDE0), UINT64_C(0x85C99CE4C5405874), UINT64_C(0xA58735D41F19C5E3) }, /*07*/ + { UINT64_C(0x8028628ACAF91B9A), UINT64_C(0x194A640538C97064), UINT64_C(0x04A15E018A4F1680), UINT64_C(0xF4BE1B04C2360955), UINT64_C(0xDFB24D4CEF581A20), UINT64_C(0x3C59D0A0FD15879D) }, /*08*/ + { UINT64_C(0x88F8E2ECE78AF1BC), UINT64_C(0xB46B6E22297364C2), UINT64_C(0x9339F17F926B99F3), UINT64_C(0x31293489B3B8F07C), UINT64_C(0x3909CE1649C9BCF1), UINT64_C(0x0C46103BFA31BCE9) }, /*09*/ + { UINT64_C(0x4D1A0B8CC7EFE2A9), UINT64_C(0xAFD7878CAD55E871), UINT64_C(0xC89CFBC858CF4153), UINT64_C(0xC4739486C74F75D6), UINT64_C(0x0BF7192C130AC9F2), UINT64_C(0x0084F2BC5E81BD9A) }, /*0A*/ + { UINT64_C(0x4AFBE975014FCACF), UINT64_C(0x41DEAF8CFACC41E4), UINT64_C(0x3C1EC23B53ED16E9), UINT64_C(0x78B06EB30F1C3248), UINT64_C(0xDD11165D04285C72), UINT64_C(0x6546D9B5609491E4) }, /*0B*/ + { UINT64_C(0xFFD1E2E04DC8D260), UINT64_C(0x07B186948A74ECCE), UINT64_C(0xB5120E45121AC531), UINT64_C(0xBD0BC86330810C85), UINT64_C(0xDE93AFDDDB487730), UINT64_C(0x78DEB0DE6EB99196) }, /*0C*/ + { UINT64_C(0x79BAA2AC3FDEBA55), UINT64_C(0xB1B7E3E1C92A567E), UINT64_C(0xA53F69AB4A5B0794), UINT64_C(0xF0DA7499954F6DDD), UINT64_C(0x58117C89E1132248), UINT64_C(0xD95DF5F794C51A6E) }, /*0D*/ + { UINT64_C(0x89BC8A0C65091C33), UINT64_C(0xB04EEAEE063135C2), UINT64_C(0xF53267E04AB6E689), UINT64_C(0xB4C579B7207E8BF2), UINT64_C(0x3FD31E51343CD2DF), UINT64_C(0x119E523E2F8197FE) }, /*0E*/ + { UINT64_C(0x2E10CB1C6060F32D), UINT64_C(0xBC92E732A94E6B63), UINT64_C(0xF3220D831FD04267), UINT64_C(0x502C5F7414BCE87F), UINT64_C(0x89E0651DE91D2457), UINT64_C(0x759E56B04482D915) }, /*0F*/ + { UINT64_C(0x43AEE32C6A84E803), UINT64_C(0x0C5007202C0BD7E3), UINT64_C(0xB4F464474205D32A), UINT64_C(0x7D17FC95DE386C06), UINT64_C(0xE8DFBF64567AA545), UINT64_C(0x55BD889D5853046F) }, /*10*/ + { UINT64_C(0x687ABE14EAB8DA27), UINT64_C(0x397B3AB50D72C344), UINT64_C(0x505EAA6D1FDE618D), UINT64_C(0x61BE79865DA13F69), UINT64_C(0x17BBAB29B5E90E2D), UINT64_C(0x010C921972FA8B2F) }, /*11*/ + { UINT64_C(0x8B7223A4F56FF453), UINT64_C(0x291B7B5CB98B6FE1), UINT64_C(0xFD421625786FBF7D), UINT64_C(0xE33D1020D0E8CDC8), UINT64_C(0xCA530C708B739E87), UINT64_C(0x878AF1F304B8A12F) }, /*12*/ + { UINT64_C(0x7ECE1F24E56DD711), UINT64_C(0x2E0869241B2FA6DF), UINT64_C(0x84B834DCC459B2FD), UINT64_C(0xE022EDA6319E7D3B), UINT64_C(0x59839D8CA03C9928), UINT64_C(0x644790F491BBC774) }, /*13*/ + { UINT64_C(0xCBDC6F49E6B0DD0D), UINT64_C(0x44BA2F8D00346732), UINT64_C(0x86BCC821586AE61C), UINT64_C(0xC7B7491285CEE55B), UINT64_C(0xED3912FFD97F3851), UINT64_C(0xF4AF0186BEBEBCBF) }, /*14*/ + { UINT64_C(0xCA8A48E54ECCE516), UINT64_C(0xBEDF1864B7F8F506), UINT64_C(0xD56A1F60A4B36AA4), UINT64_C(0x49B25AB5FE0DD9D9), UINT64_C(0x21377DBB5E49FCE1), UINT64_C(0x708F64F5D59D99E7) }, /*15*/ + { UINT64_C(0xE9F873A569AFE02C), UINT64_C(0xDA66BC05CA997390), UINT64_C(0x8C88174756D35385), UINT64_C(0xEAAAF16CF4FDA730), UINT64_C(0xB39F7A55653A3512), UINT64_C(0xF10AB727BC23E852) }, /*16*/ + { UINT64_C(0x93E96FF8C5BBE2AF), UINT64_C(0xA47785420253E97C), UINT64_C(0x704B25D1F77D074C), UINT64_C(0xC0B2093F1470559C), UINT64_C(0x8D5BFDD4E364AACF), UINT64_C(0x550518673F5B1BF7) }, /*17*/ + { UINT64_C(0x8DAC832E5BE81ACB), UINT64_C(0x588BFB202B7583D8), UINT64_C(0xA34D8A70DFD1D7E4), UINT64_C(0xD03B0627B687033E), UINT64_C(0xE3D0BE7EDBDC75CF), UINT64_C(0x818EE8C5B09F8BEA) }, /*18*/ + { UINT64_C(0x8E3B02E1489D7D31), UINT64_C(0x5336752B64E3B532), UINT64_C(0xE4D4CC795C580A65), UINT64_C(0x6DAB08F313ED767E), UINT64_C(0x8E567E88FDBA36BF), UINT64_C(0x259490F1D8E933D0) }, /*19*/ + { UINT64_C(0xEAB437D0D62CAA62), UINT64_C(0xC090AD28B982B003), UINT64_C(0xE255D768D25704EC), UINT64_C(0xA048511AF6256A43), UINT64_C(0xE79F078F4D498B5F), UINT64_C(0xC41735FB75B357FE) }, /*1A*/ + { UINT64_C(0x70DA9FC3504FF29D), UINT64_C(0xB9AB1F388673FF25), UINT64_C(0x36922F4CD17357BA), UINT64_C(0xF09C3AB292E7E04A), UINT64_C(0x90CE0BC3D9BA13EC), UINT64_C(0x647C4CA63C918DE3) }, /*1B*/ + { UINT64_C(0xD834A38DD1ECD688), UINT64_C(0xA97A0020DE46AB6A), UINT64_C(0x9CDEC7F6E62EA71F), UINT64_C(0x288A5A6FD74DC47E), UINT64_C(0xD44A2E2765CE50F1), UINT64_C(0xBB9B50B5DB9E4F3C) }, /*1C*/ + { UINT64_C(0xC66DA90E41DDF2E6), UINT64_C(0x5A3FE86F160C5C09), UINT64_C(0x6F6AF0405108CCBE), UINT64_C(0xF938382EB627FC7F), UINT64_C(0x163DD634617F006C), UINT64_C(0x5184B1FEDC908497) }, /*1D*/ + { UINT64_C(0xC95719ED07FCB21C), UINT64_C(0x5112DF043F6EE7EB), UINT64_C(0x50F9FD60012334CE), UINT64_C(0x589FA85104D96579), UINT64_C(0xB7129E44D71905A7), UINT64_C(0x3314766E0733528D) }, /*1E*/ + { UINT64_C(0xDC6C8014C5457CB8), UINT64_C(0xD635FDCD286A69B6), UINT64_C(0xD66F232CE27D01BF), UINT64_C(0x56AF4AC0F682EC0F), UINT64_C(0x57DF1D55B64328F5), UINT64_C(0x651ED4C52A87CACA) }, /*1F*/ + { UINT64_C(0x26D9D1CC79EEC502), UINT64_C(0x69BF340A34B1EBFE), UINT64_C(0xFAA5AAAC8E397174), UINT64_C(0xD0A8F9BD426BCF6F), UINT64_C(0x5B131F464D6D2452), UINT64_C(0x122DD15660D0D6DA) }, /*20*/ + { UINT64_C(0x6E389AEC5F51A22F), UINT64_C(0x7EF68F1C54C127FB), UINT64_C(0x986D4D46E0485C30), UINT64_C(0xF0A47B39E7CF8A31), UINT64_C(0x1D398DFDB7F2A78F), UINT64_C(0x2FC651D1FBB10D2E) }, /*21*/ + { UINT64_C(0xA44E4E8D1B49DCB0), UINT64_C(0x07A4822049C2F343), UINT64_C(0xC40AC04A8D6505BA), UINT64_C(0xD9B91D3F0729B16C), UINT64_C(0xAAF39951B50F9015), UINT64_C(0x966EF5D3AD3F9076) }, /*22*/ + { UINT64_C(0xEA78CBAC0EB6D009), UINT64_C(0xA0FEA6725A23DEAB), UINT64_C(0xCE729C7444CB94D9), UINT64_C(0x40A994626627AA0D), UINT64_C(0x37F738CDE3D018D5), UINT64_C(0x4C29491C01CDB3C5) }, /*23*/ + { UINT64_C(0x7C9792AEA745C87A), UINT64_C(0xD1FF5620C5BD8FD4), UINT64_C(0x9ECA84E3004B56B9), UINT64_C(0x5AFD3923C228B1D6), UINT64_C(0xE5DBF79EB3FD283B), UINT64_C(0x441712E354084B9F) }, /*24*/ + { UINT64_C(0xE35D288BD8E249BC), UINT64_C(0x91776C1453A366E5), UINT64_C(0xF5D1E1684E95EFEC), UINT64_C(0x9108E117D7DDF606), UINT64_C(0x81B30F9DA2CE7C8C), UINT64_C(0x6497DBD786818C0D) }, /*25*/ + { UINT64_C(0xC2F891FF45044BE0), UINT64_C(0x75A1A76D2B87E2EB), UINT64_C(0x85CE65798AF3C2BF), UINT64_C(0x213F532B4EFD09DC), UINT64_C(0x0DAA1DF5A53A6C88), UINT64_C(0x3028606A50D826B2) }, /*26*/ + { UINT64_C(0x609A62616379F33A), UINT64_C(0xA339A3BC53E4516D), UINT64_C(0xD7AD92616A5ADBEC), UINT64_C(0xD043726D86E924AA), UINT64_C(0x8555B564F4C29865), UINT64_C(0x56AA12AB31C1D6B0) }, /*27*/ + { UINT64_C(0xCED9ED85C1C17BFF), UINT64_C(0xEB522325ACBAFFC2), UINT64_C(0x04D3D8F4B2D15394), UINT64_C(0xD271504C04756EEA), UINT64_C(0x2DDBA4A91AF827F1), UINT64_C(0x1F67D5C28F8002E4) }, /*28*/ + { UINT64_C(0x8B9C08AD432DC08F), UINT64_C(0x5A7543E29796BBC7), UINT64_C(0x34A6DB5B3C1967DE), UINT64_C(0x016E3BC2A2804EE4), UINT64_C(0x5B9BCACCE5172F75), UINT64_C(0x7549598B80ADBDBA) }, /*29*/ + { UINT64_C(0x6F3FB117C5CDD155), UINT64_C(0x16C3B0A59CD6EEC5), UINT64_C(0xD9A1A411DE538769), UINT64_C(0x938C54979F4AC37C), UINT64_C(0x3737BCC1D55284DB), UINT64_C(0x6CAD9F8AF9156BB7) }, /*2A*/ + { UINT64_C(0xEBBF284F9C75EBDF), UINT64_C(0xB383EBB406753DE8), UINT64_C(0xAA86127AEE7C403C), UINT64_C(0x10BFDD10523DE027), UINT64_C(0x138BF6C4EB4A8A13), UINT64_C(0xB1EFF67DDB78B067) }, /*2B*/ + { UINT64_C(0xF6D1138D7AA3DA5E), UINT64_C(0xBAA8098D8FB66371), UINT64_C(0xDAE76D1B8B6CAAF2), UINT64_C(0x400F1034368D1EDC), UINT64_C(0x7C937F5172E8D277), UINT64_C(0x7D05BBF83CADE6EF) }, /*2C*/ + { UINT64_C(0x0E9C2EA6CF34B081), UINT64_C(0x9036B30D58F60BA0), UINT64_C(0xDB3A2C5848F08BCA), UINT64_C(0xC87AD1B94250D564), UINT64_C(0x7C892E09EEF96166), UINT64_C(0x26DB85CF571085F3) }, /*2D*/ + { UINT64_C(0x251EE3F58718C12A), UINT64_C(0xF9438D81178A2AE4), UINT64_C(0xF0929A889039A8A8), UINT64_C(0xF06B65225EBDCCFD), UINT64_C(0x2E4D14EDF7BF73C6), UINT64_C(0xA9369895BC1DFACF) }, /*2E*/ + { UINT64_C(0xCAE302B41D6979CB), UINT64_C(0xBBFA5A58B51EE623), UINT64_C(0x5113B99DC81AB52F), UINT64_C(0x6093795BEC17A056), UINT64_C(0x8F71FB4D2E5E355E), UINT64_C(0x762F92EDBA34A2F2) }, /*2F*/ + { UINT64_C(0xD130015265A4D9FF), UINT64_C(0x09BEA253D71F26C8), UINT64_C(0x81B6EAEDC46521E6), UINT64_C(0xFAE268165682B8A9), UINT64_C(0xA89C3EC4774AB623), UINT64_C(0x0D2E45E055219DB2) }, /*30*/ + { UINT64_C(0x2B560284C3A692AB), UINT64_C(0x37008AD0B379A7B8), UINT64_C(0xAF11CD2C30F90BFC), UINT64_C(0x7FE87A250F2762ED), UINT64_C(0xC3FBD711647242C3), UINT64_C(0x74ED8264F6B322BD) }, /*31*/ + { UINT64_C(0x28195CC8A7AD3943), UINT64_C(0x53CBE808464C4FC4), UINT64_C(0xD58E3D7A765F8726), UINT64_C(0xD83052F60185AA4F), UINT64_C(0xEFCB0D85223BB4E7), UINT64_C(0x5A31305E787FAC28) }, /*32*/ + { UINT64_C(0x725D0EE230F19543), UINT64_C(0x9091D2C6BDDF34E0), UINT64_C(0xE3BE49C6C2754601), UINT64_C(0x61BE300BA4AD566B), UINT64_C(0x02D79D7551FA7CC1), UINT64_C(0x6543910F5F1CDA58) }, /*33*/ + { UINT64_C(0x4099ADC44481B43F), UINT64_C(0xFE1361922FD9EB81), UINT64_C(0xA989C09E441FCEAC), UINT64_C(0x449B3A13D3CB9019), UINT64_C(0x45A9BE396F201134), UINT64_C(0xDC1AD05A046633FE) }, /*34*/ + { UINT64_C(0x1A563A6D522F3E69), UINT64_C(0xBE589E079F475A9E), UINT64_C(0x75A2A9638E4C0038), UINT64_C(0xDA3B6202577A0362), UINT64_C(0x211D3F1E0D727AF6), UINT64_C(0x5E1FFC529AD99233) }, /*35*/ + { UINT64_C(0x47B61E86C6D6D01B), UINT64_C(0x437D6F83ADADC318), UINT64_C(0xD5A361028DED738C), UINT64_C(0xA00D4C630425164B), UINT64_C(0x1A69AFA5AF4C9DD2), UINT64_C(0xF99E1C67F951B582) }, /*36*/ + { UINT64_C(0xA66A7740B6BDEA79), UINT64_C(0xFEF7FF1496AF80A3), UINT64_C(0x05AFD43EEACD898C), UINT64_C(0xB00C78ED31AD7134), UINT64_C(0x0ED31A1AD7846673), UINT64_C(0x74B96844161499BE) }, /*37*/ + { UINT64_C(0x46FA8D6CCBF6D12E), UINT64_C(0x31C2FC147F303956), UINT64_C(0x707F4401DE5F067F), UINT64_C(0x3AE5FEC7E33594E9), UINT64_C(0x28E39F8A63531714), UINT64_C(0xB7B329EA1E9FCAB2) }, /*38*/ + { UINT64_C(0xEFD8F755825C7804), UINT64_C(0x1F5A93870BD30CD1), UINT64_C(0xEFBF894671FF8716), UINT64_C(0x28ED617FF22BDA58), UINT64_C(0x411289CCAE5CB62E), UINT64_C(0x95DD42F41801F2F9) }, /*39*/ + { UINT64_C(0xA8525B8645FC59E1), UINT64_C(0x75E62DC00A5F7F0C), UINT64_C(0x09C56785210416AC), UINT64_C(0x50EF76E9B30D7626), UINT64_C(0x2B3B2CDC19F5D665), UINT64_C(0xA41297CD11D8F4FF) }, /*3A*/ + { UINT64_C(0xEAC99A649EEE5039), UINT64_C(0xA593C92F143C0065), UINT64_C(0xB314735203071206), UINT64_C(0xEA2761A0C764A4EC), UINT64_C(0x02AA7FD46CAC25B3), UINT64_C(0xC68CC182A96D03BF) }, /*3B*/ + { UINT64_C(0xB2873F024EC83CA8), UINT64_C(0x97470AB8FD8853EB), UINT64_C(0x18FE15C159B305BD), UINT64_C(0xB0AB08F687EAEAFD), UINT64_C(0x510A3FDE73602E43), UINT64_C(0x03E1B84DCCF0FCF0) }, /*3C*/ + { UINT64_C(0xD85BBBDC8033C0D8), UINT64_C(0x9223D9C39CA9F34F), UINT64_C(0x7D3BCB6D5B63C3FD), UINT64_C(0x1C30F974DA0C0FB5), UINT64_C(0x8B24BC9EBEFB5143), UINT64_C(0xC58954925B7B84FC) }, /*3D*/ + { UINT64_C(0x6ABD7C2E0844D7A7), UINT64_C(0xCCF2EA456CDF530D), UINT64_C(0xE8938CF52B3921B8), UINT64_C(0xBA023CA2F281657C), UINT64_C(0xEC635DA675D1EDAE), UINT64_C(0xB4AA52F22EE1BE6C) }, /*3E*/ + { UINT64_C(0x981C3AC677CB5904), UINT64_C(0x6A92B54C84877B49), UINT64_C(0x745BA6BB40C55815), UINT64_C(0xB7AF550D22A371ED), UINT64_C(0xD5E8BD87C65F5374), UINT64_C(0x67874A37F0F538F5) }, /*3F*/ + { UINT64_C(0xC23BBA2A9DECC021), UINT64_C(0x4E610E930B0E3450), UINT64_C(0x1A681AA91477577E), UINT64_C(0x38A3209714EDC376), UINT64_C(0x0FD15563EEEB4AB6), UINT64_C(0x7D57668A01D42178) }, /*40*/ + { UINT64_C(0x6AF88CE145A098B5), UINT64_C(0x1AEB858CD88B8B46), UINT64_C(0xE8B733AFB8E2D6E8), UINT64_C(0x313FAA8C10A7EBFA), UINT64_C(0x127D375E77557CEA), UINT64_C(0x96BDA2F70B2F2155) }, /*41*/ + { UINT64_C(0xEC8903978FAFB636), UINT64_C(0xC7213C425C079763), UINT64_C(0x760384036AB6D17C), UINT64_C(0xE0C63A26385F1F49), UINT64_C(0x299877D6811A6DF5), UINT64_C(0x876F90FC5304B88D) }, /*42*/ + { UINT64_C(0xA6FABBC2D6E0BA16), UINT64_C(0x9B70C9640080E6BC), UINT64_C(0x29B2D5265598B27B), UINT64_C(0x4A9657C726E4397E), UINT64_C(0xA801CCC6766678D5), UINT64_C(0x800EF7CC72619998) }, /*43*/ + { UINT64_C(0x235931A8CF5490BF), UINT64_C(0xE798F98E0E8F879F), UINT64_C(0xC6EEE29C38F30CA7), UINT64_C(0x929A79F2D53E0024), UINT64_C(0x88F2E12749587A45), UINT64_C(0x0B85B28F38891965) }, /*44*/ + { UINT64_C(0x165E0303E4A4D827), UINT64_C(0x67994F42D1E8436A), UINT64_C(0xE6CC8BCF6E130D1B), UINT64_C(0x50101711709DDEFC), UINT64_C(0x373BDEC40CD05328), UINT64_C(0x40B274A4AA5109F6) }, /*45*/ + { UINT64_C(0xA9F88BA008FDF8C8), UINT64_C(0xECC897E3476EE05A), UINT64_C(0xBCE290AB69D57A74), UINT64_C(0xFA44DB1811E3115D), UINT64_C(0x6267AEFD64480C88), UINT64_C(0x2697D04A2D3AECEB) }, /*46*/ + { UINT64_C(0xC0782AF2ABCD3313), UINT64_C(0x02BA1290F2F96273), UINT64_C(0x63C82F1A56ADC2B9), UINT64_C(0x10F8E8C03EFE51C4), UINT64_C(0xE3EB348625CCAFFD), UINT64_C(0x93D607969CB8E7AE) }, /*47*/ + { UINT64_C(0xCC6E179443E58FBC), UINT64_C(0xD21C93C655A7B8EE), UINT64_C(0x2B9834A31F2B8BA4), UINT64_C(0xC83B69516025ECEE), UINT64_C(0x9176EB7B427AAE94), UINT64_C(0x8CB65B9E30B7A76E) }, /*48*/ + { UINT64_C(0xC1A33A0AD6EDD989), UINT64_C(0x18B3C5D95813B5F7), UINT64_C(0xB024BD263B359A8B), UINT64_C(0xC8C17C2216A99B50), UINT64_C(0x71F9A11D58237729), UINT64_C(0x3AA67C7618284290) }, /*49*/ + { UINT64_C(0x99B7465E09201C7B), UINT64_C(0x9AF89FA01CA4FA81), UINT64_C(0xFC2EC63E761AD123), UINT64_C(0xE2A9A39585B17D14), UINT64_C(0x08394DE529F94E81), UINT64_C(0x479448E69794FAA4) }, /*4A*/ + { UINT64_C(0x23CA3D1C4CBDCABB), UINT64_C(0xE3265436CE1A37E4), UINT64_C(0x1BBF10F69E8A4CC9), UINT64_C(0x05A66708048F5C4D), UINT64_C(0xE259DCDD9C5BFEFE), UINT64_C(0x439E65FAFD936EFD) }, /*4B*/ + { UINT64_C(0xA24D73B6978F719C), UINT64_C(0x3F53F343CCB0BB8E), UINT64_C(0xBE3C72769EE07C6A), UINT64_C(0xFACB9E539CF558DD), UINT64_C(0x67B91D4E30DE986A), UINT64_C(0x1DB913D11698913A) }, /*4C*/ + { UINT64_C(0x98BD4E140DC3C3C6), UINT64_C(0x142B1592BF3263E8), UINT64_C(0xCDBEAC59ED095B0E), UINT64_C(0x900763F0F625896A), UINT64_C(0xE213550F30324E39), UINT64_C(0x8A13A4417A803195) }, /*4D*/ + { UINT64_C(0x2ACD98ED8C626073), UINT64_C(0x1CAAA6B4C4CF3238), UINT64_C(0x04DCB41EB677EB5D), UINT64_C(0xF88B5844A8105B68), UINT64_C(0x981D9E951A061A4D), UINT64_C(0xBC9471894C878EDB) }, /*4E*/ + { UINT64_C(0x4959FEAD5D6C2DBD), UINT64_C(0x6ABD59E28C503049), UINT64_C(0x06D2C5494CAF8B34), UINT64_C(0x70E4541304A4293C), UINT64_C(0x520F3416CAF2F503), UINT64_C(0xB23D09D92613DB85) }, /*4F*/ + { UINT64_C(0x26B5A815C32D1791), UINT64_C(0x2C99E7555BB033C6), UINT64_C(0x09CE9D6A0002514F), UINT64_C(0xD485282B2B8D7997), UINT64_C(0x9C5B792F4A4A14C6), UINT64_C(0x851D9D02DC0BB4E7) }, /*50*/ + { UINT64_C(0x62FEB6CACFB060EC), UINT64_C(0x9D977D69D5C661EA), UINT64_C(0xBF08EFD806D81556), UINT64_C(0x25F1EEA460EA5718), UINT64_C(0xA25346B51F5A9665), UINT64_C(0xD92F9ADC358CA274) }, /*51*/ + { UINT64_C(0x27E63DFC63E8FFA6), UINT64_C(0xCDB9CCE2CE99FDA3), UINT64_C(0x979D5B754974830D), UINT64_C(0x3298C8407D6693BE), UINT64_C(0x629D5FADA39B42B7), UINT64_C(0x2654D31271CD84E1) }, /*52*/ + { UINT64_C(0xAB1FA4DAF66E583C), UINT64_C(0xEEB6B7A236D24766), UINT64_C(0xA90738CDFDF5C6B3), UINT64_C(0x28CBA9E5648E2D4C), UINT64_C(0xFDE5BF6C0CFE0DA3), UINT64_C(0x9D00B863D7D78485) }, /*53*/ + { UINT64_C(0x75FBBF094EEA16AA), UINT64_C(0x48931F027CD729F2), UINT64_C(0x5D360679009B2E7F), UINT64_C(0xDDFCD148BD3DE21A), UINT64_C(0x4DBFF544B094D0E1), UINT64_C(0x9C0E5C6294352C22) }, /*54*/ + { UINT64_C(0x283A27FF968853D2), UINT64_C(0xB0960C6CEA0D03F2), UINT64_C(0x172BBA07A473DB38), UINT64_C(0x688C87D296E6F4BB), UINT64_C(0x5CB7E9BC5D68CF0F), UINT64_C(0x57A5D71B0E47BFB4) }, /*55*/ + { UINT64_C(0xDE0108AAC1E4FF2F), UINT64_C(0xD346CFABEAC62B99), UINT64_C(0xB72E203F98B5F608), UINT64_C(0x81853D8CA54B29BE), UINT64_C(0xA6AED7C89FAA1680), UINT64_C(0xD2093B155C39D7ED) }, /*56*/ + { UINT64_C(0x0BAEAC99D4974B84), UINT64_C(0xC7F258A699C9B4DA), UINT64_C(0x6F622C5E4ACCF5C1), UINT64_C(0x58AB397D9781BEAA), UINT64_C(0xBF811F67E101FFE3), UINT64_C(0xAFBCC2881C3C0EF3) }, /*57*/ + { UINT64_C(0x26B211FB518D6C3E), UINT64_C(0x64BADAD51A10784A), UINT64_C(0xE6BE4E06A587186C), UINT64_C(0xD471F5C61343CD5C), UINT64_C(0x8389BB0DD6AAED5D), UINT64_C(0xC88112678914A17D) }, /*58*/ + { UINT64_C(0x2B2D0BC3BB88D27D), UINT64_C(0xC5A7D1FAFF517AD2), UINT64_C(0x96F39056A09F82AD), UINT64_C(0xFB38A61A6CED4D4E), UINT64_C(0x9D308E4EA6F9B264), UINT64_C(0x9097CE294AECC6B3) }, /*59*/ + { UINT64_C(0x8FCA2B950690B1A2), UINT64_C(0x293EFCBF03D422DF), UINT64_C(0x8C9125B3E76353AB), UINT64_C(0x3D402092A1A70173), UINT64_C(0x9BAB974CAB9BF676), UINT64_C(0x5EA8FCC55D8C586E) }, /*5A*/ + { UINT64_C(0x408C92E8C2E1EC8C), UINT64_C(0x4AF4C914B71B4350), UINT64_C(0x5186AEE0CDFB1069), UINT64_C(0x2385EAFAB9657C67), UINT64_C(0xF708E4D3C898CA80), UINT64_C(0x1EC8B9F89884907E) }, /*5B*/ + { UINT64_C(0x46E8958B6A2C1878), UINT64_C(0x2172FD410F78A647), UINT64_C(0x9D8E9DD83A299004), UINT64_C(0x390913C3265AD025), UINT64_C(0xD231F1E23077CBF1), UINT64_C(0xE7EE3E574E80D7F3) }, /*5C*/ + { UINT64_C(0x5A8567A3D85E40B2), UINT64_C(0x16ECF161133FCF73), UINT64_C(0x52DA5C6FBA3C0DD7), UINT64_C(0x56E57983DEB34BFB), UINT64_C(0x83254FDCB768D153), UINT64_C(0x9A14F95F35C6B82D) }, /*5D*/ + { UINT64_C(0x498A29C6E19D4AE6), UINT64_C(0x2EF4AAF46027BA11), UINT64_C(0xBDBA7DAA84F39505), UINT64_C(0x940B2A04F6DC944D), UINT64_C(0x4E7ED35610FC0D53), UINT64_C(0xBADD94C2907E59E1) }, /*5E*/ + { UINT64_C(0x14DF0FC43F475F80), UINT64_C(0x17E2AA8D264BF82F), UINT64_C(0x92625BDFE58B934D), UINT64_C(0x8384F415A4ACEA81), UINT64_C(0x8E9C5EAEC5D8642B), UINT64_C(0x4D8EF55F1C826687) }, /*5F*/ + { UINT64_C(0x4A2335C4F77128D9), UINT64_C(0x544E1476D29ABA94), UINT64_C(0x654EC86321785044), UINT64_C(0xB04AD9B02F80445A), UINT64_C(0xB0E01B6480C8D020), UINT64_C(0x596E325E88A3CBBF) }, /*60*/ + { UINT64_C(0x896955157448D062), UINT64_C(0x0DB08C4C0F236D68), UINT64_C(0x3BA8FC5B3CD1C4A2), UINT64_C(0x04F57C53E144535B), UINT64_C(0xB7D04DCC7BE46840), UINT64_C(0x4BBE993192334646) }, /*61*/ + { UINT64_C(0x1D7837E6AB02CE27), UINT64_C(0x3EA35BAED4493EA4), UINT64_C(0xD1CAFDB5DF94FABE), UINT64_C(0x98B580BB62170C4F), UINT64_C(0xC3C57A6CA9421C43), UINT64_C(0x68D65FC2C1201634) }, /*62*/ + { UINT64_C(0xFAEABABC48717536), UINT64_C(0x454251E8F62F7315), UINT64_C(0xB318E8A7FDCDC523), UINT64_C(0x7C2E832013C91344), UINT64_C(0x4D9E5DAFD1699052), UINT64_C(0x12262E8C870537A7) }, /*63*/ + { UINT64_C(0x8A3E5D0BEF8402A2), UINT64_C(0xA33BC5FAFA019909), UINT64_C(0x63CBE8ACD00762F5), UINT64_C(0xEA26A3F181984178), UINT64_C(0x6EEB78D1BB4AF6BB), UINT64_C(0x7ECF9671300E845F) }, /*64*/ + { UINT64_C(0x0811B67CCCF5D0FC), UINT64_C(0x9F8CAB3F3496BD6B), UINT64_C(0x57CB7D24F1355C2D), UINT64_C(0x58218594165BDE80), UINT64_C(0xFAF3368A653A78F8), UINT64_C(0xC04CD80176267762) }, /*65*/ + { UINT64_C(0xE6417CE75AAA23B0), UINT64_C(0x34A7BFE3CBA61761), UINT64_C(0x8C13E396F8C9B6ED), UINT64_C(0x5C9066464B09ED63), UINT64_C(0x76CB6A642C5CE283), UINT64_C(0x498E082A3EB449C6) }, /*66*/ + { UINT64_C(0x6F2ADEA6357B5AA0), UINT64_C(0x54DA382B15557B69), UINT64_C(0x302BD81946237AAE), UINT64_C(0x8F0CBB82111EFEDC), UINT64_C(0x45DD2DADCE20F2D3), UINT64_C(0x8A77A5E9E8A2D1D8) }, /*67*/ + { UINT64_C(0xE1EC332735862A28), UINT64_C(0x92B68B1A7E9C7C44), UINT64_C(0xF45618DC99E963E3), UINT64_C(0x7CAC984502DD1A73), UINT64_C(0xC8650598CD70840D), UINT64_C(0x9A5DA584A26D4EFD) }, /*68*/ + { UINT64_C(0x16B19B010740C15C), UINT64_C(0xB4544AC01016439A), UINT64_C(0x221F749C9E2F99A5), UINT64_C(0xA63E8A279A65570F), UINT64_C(0xC7231669ADD072AD), UINT64_C(0xC5BC35BA740BC801) }, /*69*/ + { UINT64_C(0x6C44E75A4F378694), UINT64_C(0xD27ACE108A577647), UINT64_C(0x17C487FAFA7E15D6), UINT64_C(0x6A3654D5C8E29EDF), UINT64_C(0x0CE35EEDCC611FFA), UINT64_C(0xD88A8C03C0095093) }, /*6A*/ + { UINT64_C(0xCF106948BC4B1F2C), UINT64_C(0x91C0DC9990B99712), UINT64_C(0x193B21E3E109AB32), UINT64_C(0x3340DE0608DD1666), UINT64_C(0x8A5BB677BF602828), UINT64_C(0x402C410B1197B771) }, /*6B*/ + { UINT64_C(0xEB080FF49CA5543E), UINT64_C(0xB4B9429542D6CA27), UINT64_C(0x5999D45DC1533205), UINT64_C(0xF7EA9E398A1BEF3E), UINT64_C(0xBE8817775476DEC6), UINT64_C(0x17064D7790C84100) }, /*6C*/ + { UINT64_C(0xF3328E9150A7F8D6), UINT64_C(0x52E3E61B04ACFDF8), UINT64_C(0x51D82010F3CEB015), UINT64_C(0x59D673336676D5D8), UINT64_C(0x4CB3BCEF1D91C342), UINT64_C(0x0C589AB58033BE49) }, /*6D*/ + { UINT64_C(0x54B8E70EDCE03855), UINT64_C(0x7BB590E99687FD57), UINT64_C(0x6CFF08688D2B1FDD), UINT64_C(0xFD0F6D068BFE994F), UINT64_C(0xEB9BCE302489AE44), UINT64_C(0x66B21F200661E3E4) }, /*6E*/ + { UINT64_C(0x2F5E0060189669AD), UINT64_C(0x473AF1D03C00CAE4), UINT64_C(0x0278299268D1F3B4), UINT64_C(0x888714BC3A7EC9D2), UINT64_C(0x9FF9C7F071EBD2D9), UINT64_C(0x875A5DC25DFFDB10) }, /*6F*/ + { UINT64_C(0xE2A97A3E468399D8), UINT64_C(0x3BF7EACA32C80DA1), UINT64_C(0x13DCAC8EB6C2231D), UINT64_C(0x227EC90E1102EE97), UINT64_C(0xB2344832F0381434), UINT64_C(0x8613888303B190EB) }, /*70*/ + { UINT64_C(0x3A3D3B6CE026BFFE), UINT64_C(0x18D4953B9A68ED59), UINT64_C(0x24BB7B574AB777A0), UINT64_C(0xE0CB7DD64983DCB1), UINT64_C(0xCF768C439869AC97), UINT64_C(0x8062BC7A900E6033) }, /*71*/ + { UINT64_C(0x39D4C3B78A7A33C7), UINT64_C(0x43D72EF22AB0B4EB), UINT64_C(0x54AE8184DDA50394), UINT64_C(0x0C2A7DA083C38536), UINT64_C(0x9DBC6F921D4AD822), UINT64_C(0x2CBB61FE182EAA42) }, /*72*/ + { UINT64_C(0xD8CE9A806C0BD24D), UINT64_C(0xF69D65A65845727C), UINT64_C(0xC3FF81CC76F2B048), UINT64_C(0x76B1FDC3CA67CE58), UINT64_C(0xCED0970AFBCBE78A), UINT64_C(0x57502941B726F5F3) }, /*73*/ + { UINT64_C(0xE006AEC17FCEFCF9), UINT64_C(0x05CAA1629E003591), UINT64_C(0xB7050CC99F585312), UINT64_C(0x669260401E159490), UINT64_C(0x8442D25AA757CC5A), UINT64_C(0x228655CD4038770C) }, /*74*/ + { UINT64_C(0x93EE8D67D3F1F3A1), UINT64_C(0xBEA46D48DBF8D7F4), UINT64_C(0x3C91F02B8646453C), UINT64_C(0x6C3D7C1F04188A58), UINT64_C(0xEFA97287F89CEF84), UINT64_C(0xCB40364E108BFF4B) }, /*75*/ + { UINT64_C(0xC6DCE3730D4FF825), UINT64_C(0x02AF54F87D972790), UINT64_C(0x7D69D20F6F4F788F), UINT64_C(0x90C255C64C166E8F), UINT64_C(0xA3529FBF4BF9C9A2), UINT64_C(0x3ECEC41136694F6B) }, /*76*/ + { UINT64_C(0x3DE10A5EC6CA7B3F), UINT64_C(0x7E196081D085ACAA), UINT64_C(0xDF5F0DE3705D60F7), UINT64_C(0x393E7C83DCC57075), UINT64_C(0xA5F33BC2DCB98F97), UINT64_C(0x0AEB7F050D1204C0) }, /*77*/ + { UINT64_C(0x6F3B3B3D11A8BC05), UINT64_C(0xB52269AB2B95B8DC), UINT64_C(0x12EDE24EB1385F13), UINT64_C(0x202BBA6B5836B5E1), UINT64_C(0xEE3636C5925ACC49), UINT64_C(0x42224CF6EEB509BF) }, /*78*/ + { UINT64_C(0x5F0CC3BBC4BE9A92), UINT64_C(0x584313FCCC54DD2E), UINT64_C(0xC11FE90F00394036), UINT64_C(0x3371667C72FC9723), UINT64_C(0x9611990B62AC8D9F), UINT64_C(0x4CFCB9EB3C317FAD) }, /*79*/ + { UINT64_C(0xCA8E520A894A3FBA), UINT64_C(0xBD9ED1B80098CC40), UINT64_C(0xBDF24507DFF3757C), UINT64_C(0x47AEC572E68D35EC), UINT64_C(0xF3D4523D27B373E4), UINT64_C(0x1AB11E16973A05AB) }, /*7A*/ + { UINT64_C(0xFFC293A6C26B817D), UINT64_C(0x2C9E9D134959D828), UINT64_C(0x7FA5216408199BBF), UINT64_C(0xA6F002DE0DCCD861), UINT64_C(0xBE8F9DC57F2CF35D), UINT64_C(0x1352E2DF86A47647) }, /*7B*/ + { UINT64_C(0x84B55BE101708E74), UINT64_C(0x3ADEC53721209F3E), UINT64_C(0xB18F9A1E68DFADBD), UINT64_C(0x09A050819774CF2D), UINT64_C(0xE4AB295D380A8762), UINT64_C(0xA3605B0C689C239F) }, /*7C*/ + { UINT64_C(0xDDC7031FBFDFFE8F), UINT64_C(0x0B175DE65B832F0A), UINT64_C(0x31162ABC65719685), UINT64_C(0x51215E534BBC36B1), UINT64_C(0x9F2F7D3B5D01AE44), UINT64_C(0xCF43A2426E83B61B) }, /*7D*/ + { UINT64_C(0x7E32DB672B16F04A), UINT64_C(0xCE6F45DE0E6AB788), UINT64_C(0x25718548B8E70B41), UINT64_C(0xD7368BCF39A0FAC4), UINT64_C(0x956863EC49880C47), UINT64_C(0x720E335796341674) }, /*7E*/ + { UINT64_C(0x06707A8E33D9D6C6), UINT64_C(0xB684BFE26CD576C6), UINT64_C(0x44F47E5ECD5FC46C), UINT64_C(0xAF1B23A856D844B7), UINT64_C(0x98A627916AC5657E), UINT64_C(0x040C3964A1127E19) }, /*7F*/ + { UINT64_C(0xA5DAEC3134C0A39B), UINT64_C(0x0CA04160BD5ADB1F), UINT64_C(0xB50EC5A9F29E1ACB), UINT64_C(0xBE2FA1126AF7BFAF), UINT64_C(0xBEFC0AC4C9C5A4B3), UINT64_C(0x994739C71FB1EB29) }, /*80*/ + { UINT64_C(0x6FEC2D343E83A763), UINT64_C(0x5BDBA5715757F50C), UINT64_C(0xD6F6282EE46A11B3), UINT64_C(0xA8B501F5922A5524), UINT64_C(0xA782A21006B605CA), UINT64_C(0xA10BD2E896975C81) }, /*81*/ + { UINT64_C(0xB8AAE0532226D0ED), UINT64_C(0x891831C0470E84B7), UINT64_C(0x74C824D648E8FF28), UINT64_C(0xB5E4E02EAD3906EB), UINT64_C(0x5ABB086ADA60A713), UINT64_C(0xA80C57666A9E29F1) }, /*82*/ + { UINT64_C(0x529E3E52B1E7230A), UINT64_C(0x0C148861C9F08E26), UINT64_C(0x0CFC8A131BAD803D), UINT64_C(0x8C09F324902FAA9F), UINT64_C(0x0231EE4987999848), UINT64_C(0x3B0688492E2B5457) }, /*83*/ + { UINT64_C(0xEFA6EAC5036814CD), UINT64_C(0x02773C1F8DAA5DF5), UINT64_C(0x0E4EEDBD0702DE31), UINT64_C(0xBA7FD757D0D740EF), UINT64_C(0xA8805F0C74005F8B), UINT64_C(0x1448467BFF3E1EF8) }, /*84*/ + { UINT64_C(0x2A07B766016AC70D), UINT64_C(0x64215C35364219E9), UINT64_C(0xCD6F7EFE35FCF6F1), UINT64_C(0xF05CC06084C29267), UINT64_C(0xAB3BF2F32579A444), UINT64_C(0xAC75F42D9A25B9C9) }, /*85*/ + { UINT64_C(0xEF3A14B5EDDB8464), UINT64_C(0x2314E0802D2DD0E9), UINT64_C(0x14DEAEA9F928762A), UINT64_C(0x5763EBB480E15A02), UINT64_C(0x25F7CA14E8CDF5E6), UINT64_C(0x8E594510DC61E6BC) }, /*86*/ + { UINT64_C(0xE62C38DCFD21000B), UINT64_C(0x7BB32AE917EE3DA7), UINT64_C(0xE49F15E24CC9B656), UINT64_C(0x56E28259DCA361D8), UINT64_C(0xB43B8008A9285F48), UINT64_C(0x0DC6B4AF7E4AE61B) }, /*87*/ + { UINT64_C(0x703C64241142DCAE), UINT64_C(0x732D33342C45063A), UINT64_C(0x37877EA1624567CB), UINT64_C(0x2871D534614DD114), UINT64_C(0xE748092A1D94F5D1), UINT64_C(0x4524056F0C6D1CB7) }, /*88*/ + { UINT64_C(0xE325B1823A595DF9), UINT64_C(0x742D0DD5C96F397C), UINT64_C(0x44361C9540A9F451), UINT64_C(0x02382F9BF6331FB9), UINT64_C(0x8ECBAFBBE91A0467), UINT64_C(0x528EBF3811F904A8) }, /*89*/ + { UINT64_C(0xFD2BC6534631FB0D), UINT64_C(0x27A5F036FEEB9A6C), UINT64_C(0xD0F876D7911D0775), UINT64_C(0x12EFB3A29C6E0B72), UINT64_C(0xDC4BCA3D5E871DA1), UINT64_C(0x028FB6E6E608F46F) }, /*8A*/ + { UINT64_C(0xEF17ECC8930A7B4A), UINT64_C(0x9D97B34672FB273D), UINT64_C(0xC6AE835F35A25D8F), UINT64_C(0x6C27469530C21F5B), UINT64_C(0x2FBC16A26150E795), UINT64_C(0x02AD93AAE0B5C71A) }, /*8B*/ + { UINT64_C(0x6D24BE43CF07DD56), UINT64_C(0x63681D62A38D2A2F), UINT64_C(0x9872C9B411724AA0), UINT64_C(0xB882B4857C19690A), UINT64_C(0x87B1BA8D2804C6F4), UINT64_C(0xD7B199CC36F40B49) }, /*8C*/ + { UINT64_C(0xEEFB8D8573FD9E0F), UINT64_C(0x933403199B91560A), UINT64_C(0xFF0DB41665D5248C), UINT64_C(0x322EE105EA984196), UINT64_C(0xDB8CE0F83890D89B), UINT64_C(0x3A32F8983C901F80) }, /*8D*/ + { UINT64_C(0x082CDAF93F215BAC), UINT64_C(0x67C118A1B9274FAC), UINT64_C(0xAF74501CFB93198A), UINT64_C(0x53525CABA0E812D3), UINT64_C(0xC9AF3A005EFE8A6E), UINT64_C(0xF242DCB60DA7B2FE) }, /*8E*/ + { UINT64_C(0xD3887FBFBB7314DF), UINT64_C(0xDDDCCCF0F720C342), UINT64_C(0xB2C4331C33C8C415), UINT64_C(0x1666010767F4785B), UINT64_C(0x8455B7C1FD5DE487), UINT64_C(0xA821C5EA181875F2) }, /*8F*/ + { UINT64_C(0x7E289831418562F0), UINT64_C(0x2AD12E3042B185C3), UINT64_C(0x7C20D0D735A6AE96), UINT64_C(0xA68BEF98E22CBD41), UINT64_C(0xA1411D22F8D93243), UINT64_C(0xD813FB404F3D2F38) }, /*90*/ + { UINT64_C(0xE13FC0A76F664294), UINT64_C(0x7E21C9D9F7FDDDCB), UINT64_C(0x161E68B366D6B1F8), UINT64_C(0x55BF957EB5743874), UINT64_C(0xB23213EF8364D766), UINT64_C(0x529BB98AF96643D4) }, /*91*/ + { UINT64_C(0x036D7ADDAADB5C33), UINT64_C(0x0525835F802D032E), UINT64_C(0x7DF7D0D8D7A2BEF2), UINT64_C(0x84927644B27696B7), UINT64_C(0x215E21E4D1F9B5B9), UINT64_C(0x77743669C40EB7FD) }, /*92*/ + { UINT64_C(0xA9B3534BE8897784), UINT64_C(0x5BFD4283541A5090), UINT64_C(0x97AFFCCD121C9778), UINT64_C(0xC146C4C9637989C7), UINT64_C(0x0820E72FCBDA59C7), UINT64_C(0x5526E2F4A0AE4F4F) }, /*93*/ + { UINT64_C(0xA4739E20FD72BDC2), UINT64_C(0x6D6EE5A5C1A54CA6), UINT64_C(0x70A97A6FCB884E5C), UINT64_C(0x2B6108339E979C48), UINT64_C(0x93A63730D6BB23A7), UINT64_C(0x5B1DCEAB00045EE5) }, /*94*/ + { UINT64_C(0x427C14E4F88C8BDB), UINT64_C(0x1D8630868E039BC2), UINT64_C(0x33DB40A251502D1B), UINT64_C(0xE043C9CCB45D2B3D), UINT64_C(0x292B67B6EE077B2D), UINT64_C(0x1C3A2FBDE24C742A) }, /*95*/ + { UINT64_C(0x3DED69F37016D86A), UINT64_C(0x9A947B13AC66D7C3), UINT64_C(0x822D8645DF4CB39C), UINT64_C(0x2BA20F98F19E10DA), UINT64_C(0x6703138D422AC4C4), UINT64_C(0x8D34D6138FA04A1D) }, /*96*/ + { UINT64_C(0x28E59C8B257D112C), UINT64_C(0x8747068CC5499FCF), UINT64_C(0xD6C16EB780F9191A), UINT64_C(0xB416151633F7AF08), UINT64_C(0xA230E00D6BA1A1C3), UINT64_C(0xFD066FB9965B83D2) }, /*97*/ + { UINT64_C(0x70F4BC1B7F8FFC37), UINT64_C(0x38DC0331E56B0FDC), UINT64_C(0xA9AB7290AD2B0BBD), UINT64_C(0xB307973C3D0783C6), UINT64_C(0xBDC455F6CDCA111F), UINT64_C(0x23F0E08317B8F0DC) }, /*98*/ + { UINT64_C(0x0AEEC24E9285C50F), UINT64_C(0x3BCDA47833B61ACE), UINT64_C(0x839986F959EE0723), UINT64_C(0xC959034A8D7F5EB9), UINT64_C(0xD4AD7E05B05C4FB5), UINT64_C(0x6C37A3D39F7A0EC4) }, /*99*/ + { UINT64_C(0x0227B7230FBF2D07), UINT64_C(0x28D7D2AD632BED47), UINT64_C(0x07BD8F8B5012EFD0), UINT64_C(0x48A0D43AE0403442), UINT64_C(0x9B8939207F1449A1), UINT64_C(0x351EAD01B9FDF219) }, /*9A*/ + { UINT64_C(0xA7119D2E311CEF25), UINT64_C(0x1E532CD0C4ED0479), UINT64_C(0x2272F878D8D30A0B), UINT64_C(0x769C412CED9C4C42), UINT64_C(0x262FFBFA65CBDDF5), UINT64_C(0xDB73D86721EA368E) }, /*9B*/ + { UINT64_C(0x4BDBE90B3FBADCB2), UINT64_C(0x1324EC3A8D6FEA57), UINT64_C(0x6D9EFBE530850D00), UINT64_C(0x401A88AFF8A4C8F4), UINT64_C(0x655CB76B8A2E271C), UINT64_C(0x35505B6DBDE16F43) }, /*9C*/ + { UINT64_C(0x6E15E57E23F57037), UINT64_C(0x4962737362C1FA26), UINT64_C(0xC962372D1829B80B), UINT64_C(0xA1FE6832EA4D6211), UINT64_C(0x6726E307F96E7763), UINT64_C(0x04C761081677505B) }, /*9D*/ + { UINT64_C(0x42E2FF3A8A6FC164), UINT64_C(0xFB85B2BC9D28B268), UINT64_C(0xC559CFF024533A28), UINT64_C(0x2EC83F3911DAB3CE), UINT64_C(0xAE0FC74A9D736A27), UINT64_C(0xDB9CDD048BAB4CCF) }, /*9E*/ + { UINT64_C(0xD79C52221D20E765), UINT64_C(0x499EDD73903CE704), UINT64_C(0x9B016D987DF48349), UINT64_C(0xFCFAB44AD12FC5C1), UINT64_C(0x811293F3B800FDF9), UINT64_C(0x511DC619CA53CEBE) }, /*9F*/ + { UINT64_C(0xA059EE78B826EDDF), UINT64_C(0x4673AF294D17C85A), UINT64_C(0x5E527D4E4DF282B5), UINT64_C(0xDB5B9A2693F95CE3), UINT64_C(0x6551D304FB54F296), UINT64_C(0xAB3EB70D65912FCC) }, /*A0*/ + { UINT64_C(0x7D0C4F67B6C78135), UINT64_C(0x390CAEA7DE304D37), UINT64_C(0x49E19FABC8D494FE), UINT64_C(0x1A9E1B6437A04516), UINT64_C(0x886CC4BDAB6AF35A), UINT64_C(0x0529217344F502FE) }, /*A1*/ + { UINT64_C(0x3CEDF34141B52CEE), UINT64_C(0x8133BA924753573F), UINT64_C(0xCB32BE22BC66025A), UINT64_C(0x0C480183DE403CB3), UINT64_C(0xBF5B84B427DFCF31), UINT64_C(0x7251428DB0232156) }, /*A2*/ + { UINT64_C(0x86FCE831C58E25CB), UINT64_C(0x5CC43FFE45CBFC75), UINT64_C(0x33877CC042F199BE), UINT64_C(0x1212FA7F0CC22E1C), UINT64_C(0x448EAB4B7D1F9823), UINT64_C(0xA7B1363A9FA7599E) }, /*A3*/ + { UINT64_C(0x2D8C2FEDA0E5106D), UINT64_C(0x192E366838BBEB3F), UINT64_C(0x36226AA60ACEA0AF), UINT64_C(0xE7E1285DC1F3926A), UINT64_C(0x900371FA1883D9EC), UINT64_C(0xBAC33B1AF360EB66) }, /*A4*/ + { UINT64_C(0xD4A2A11612BDE0E3), UINT64_C(0x82AB0DA614CB4CB8), UINT64_C(0x189A4D50AC01F4C6), UINT64_C(0xE36A5DA1D9F6A647), UINT64_C(0xE43120D6B16B11B6), UINT64_C(0x7D395F4236E75378) }, /*A5*/ + { UINT64_C(0xC0C155CD47F3877F), UINT64_C(0x4B03BFE5C334CA71), UINT64_C(0x77710F1F4B844FF7), UINT64_C(0x3443BBAB720E8DC5), UINT64_C(0xF03F8868C5863406), UINT64_C(0x0FD60511C872EB50) }, /*A6*/ + { UINT64_C(0x8C253DAAB5286306), UINT64_C(0x9AA438F54A6196AC), UINT64_C(0x181D08C723A22C5E), UINT64_C(0x633C49C88E3910A1), UINT64_C(0xC9F54A67992675B0), UINT64_C(0x1FDD98ACBD38D976) }, /*A7*/ + { UINT64_C(0xA10893DA7575A9F7), UINT64_C(0x8F5F4A025AB2A018), UINT64_C(0xD80538F0336BFFC0), UINT64_C(0x0F9751D33889626F), UINT64_C(0x30383EB925BF911A), UINT64_C(0xE6149F68CE19CC60) }, /*A8*/ + { UINT64_C(0xB9081DBAC6BE0598), UINT64_C(0x785DD9BC69C71492), UINT64_C(0x8B035A0CA56E172B), UINT64_C(0x8946783500724888), UINT64_C(0xAF1E57C958650569), UINT64_C(0xE1DE4E944FF22261) }, /*A9*/ + { UINT64_C(0xEA5EDC4D2718C0D2), UINT64_C(0xCB1C5D4DA15A8AE4), UINT64_C(0xC6272382F8163015), UINT64_C(0x94A934E5057B54CE), UINT64_C(0x658E481A3D68D10D), UINT64_C(0xE8F24929E50A46A0) }, /*AA*/ + { UINT64_C(0x7DF146281AF482CD), UINT64_C(0x014B68E726407B06), UINT64_C(0x6CE564938C70DDBC), UINT64_C(0x36DAD2DE72A5DAA2), UINT64_C(0x6D573BF69C0B2980), UINT64_C(0x684DAB14B4AA0329) }, /*AB*/ + { UINT64_C(0x9C69DC064E738B5F), UINT64_C(0x83CC16BD5A1C36F5), UINT64_C(0xA99B365E6E141B12), UINT64_C(0x2748FA5AD0FACCE8), UINT64_C(0x26D073A047D99C49), UINT64_C(0xB005B182505B0C0C) }, /*AC*/ + { UINT64_C(0x15B6A2A20ED0FD1C), UINT64_C(0x9333AF729BD65A25), UINT64_C(0x22CC333293BD2C1B), UINT64_C(0xD724D949B15E8BE1), UINT64_C(0x69D0DB0512B97117), UINT64_C(0x85ACA8980DD7653C) }, /*AD*/ + { UINT64_C(0x230EC629D77BB3F2), UINT64_C(0x43115B991D297CB2), UINT64_C(0xA2F955792C53C76F), UINT64_C(0x48A76728EBE25BA7), UINT64_C(0x7CE662A405384400), UINT64_C(0xDDC06B7E6BF49D66) }, /*AE*/ + { UINT64_C(0x20DDB9BD7644410B), UINT64_C(0x056391B1FA2E8C06), UINT64_C(0xCA4EDE51CF167C00), UINT64_C(0x46602B550536F870), UINT64_C(0x5040672597C21FF4), UINT64_C(0x0AF8EC6E8AFB844B) }, /*AF*/ + { UINT64_C(0x0023C5749251B883), UINT64_C(0x335A4F86D66B7E00), UINT64_C(0xAE353DED3EFACE8F), UINT64_C(0x3FC80526D67B35DE), UINT64_C(0x0D9078FBDA80BC53), UINT64_C(0x467900DFF3FE4C14) }, /*B0*/ + { UINT64_C(0x0F9CB2BE6A448113), UINT64_C(0xE38D541B6A9A5829), UINT64_C(0x673953DAF354FC0E), UINT64_C(0x3C818A277F8569E9), UINT64_C(0x8D16EA77DB122A3B), UINT64_C(0xE40A860318B6EA84) }, /*B1*/ + { UINT64_C(0x78CE11F42D7D5E50), UINT64_C(0x84F76DFF199C998D), UINT64_C(0x999B578E3AE935CB), UINT64_C(0xD9FD092C1BE63212), UINT64_C(0x31F33C63ACD316D8), UINT64_C(0x5AA08030B8D65C0C) }, /*B2*/ + { UINT64_C(0x0098DBE19CA84FE9), UINT64_C(0xE2426617D1142137), UINT64_C(0x63C3C4166A78E21B), UINT64_C(0x74B145353E03B0E4), UINT64_C(0xF43C0824EAE508C4), UINT64_C(0x58C1E6622528602A) }, /*B3*/ + { UINT64_C(0x9E27EBE6D1426A6F), UINT64_C(0x2A6A600A6B5FA342), UINT64_C(0x8FF7E2306BA90370), UINT64_C(0xDF83D91A683EDDDD), UINT64_C(0x29572442F0225388), UINT64_C(0xE9CC0F1B6437320A) }, /*B4*/ + { UINT64_C(0x054DF380E896064E), UINT64_C(0xFAB81A4AA3AD88A4), UINT64_C(0xF87426486CCA156F), UINT64_C(0xBB1B3C8237472960), UINT64_C(0x7EC0B87CF73F960A), UINT64_C(0x5C57D7E6470F7808) }, /*B5*/ + { UINT64_C(0x5758E103AC614A1A), UINT64_C(0x766AEE86F81358DF), UINT64_C(0x203FBA51DC74396A), UINT64_C(0x78C93DF969C5721F), UINT64_C(0xE69E32E230196597), UINT64_C(0xE287C6CECD8AB95B) }, /*B6*/ + { UINT64_C(0x2A06A7C10C0DCC97), UINT64_C(0x99D5298268A6745F), UINT64_C(0xF2D818BB774858B3), UINT64_C(0xD52A820D4F64D886), UINT64_C(0x2F808EF87A263981), UINT64_C(0xBB91206E6347C676) }, /*B7*/ + { UINT64_C(0x0847C6D71CE0C746), UINT64_C(0x86FD451B447C1E11), UINT64_C(0xC20623B0E2856FCC), UINT64_C(0x3ADDFA2D0398181E), UINT64_C(0x6736A0A06B336B46), UINT64_C(0xD1C70AEEB2B1257D) }, /*B8*/ + { UINT64_C(0x5633260D141A9776), UINT64_C(0xD530805F596CA3DB), UINT64_C(0x8CE33EF69437CE46), UINT64_C(0xF62D54E97E747088), UINT64_C(0xDF5C9318489B45EA), UINT64_C(0xA4AAD29F0BA850CA) }, /*B9*/ + { UINT64_C(0xBDBD7B16767F6D9F), UINT64_C(0xF7968427F1B7B6DD), UINT64_C(0x58C76599B35276EE), UINT64_C(0x286F4C7F6CADD791), UINT64_C(0x8188C0401742117B), UINT64_C(0xCEC4F1964266D163) }, /*BA*/ + { UINT64_C(0x97E4E8A6B5135B24), UINT64_C(0x8A8BD785E5297977), UINT64_C(0x4545C1A0975BC5BB), UINT64_C(0x13FAE3BD9F59E37D), UINT64_C(0xAFD5627C0E91DE2B), UINT64_C(0xA223AC778474E1A9) }, /*BB*/ + { UINT64_C(0xDE1BF1EAF86C6B3B), UINT64_C(0xA246A3ACD50035FE), UINT64_C(0x6F80179DD96A21CD), UINT64_C(0x3F8DB7CB17300D03), UINT64_C(0x497A798B5D94506C), UINT64_C(0xAD52DCC6F61AE841) }, /*BC*/ + { UINT64_C(0xF4A4E1D08E1F440B), UINT64_C(0x5E27633CD56422E0), UINT64_C(0x1465C14F1DB41420), UINT64_C(0x9A939043988D37C2), UINT64_C(0xCBE65CFA245DB368), UINT64_C(0x6340AEDE28DDA855) }, /*BD*/ + { UINT64_C(0x1F7AB65A3F892454), UINT64_C(0xD70AB4167EBEB5A1), UINT64_C(0x9B2631E824C2028D), UINT64_C(0xD5D97BDEE31519BC), UINT64_C(0xEA2DC77449E4058C), UINT64_C(0xEB204F2D6D2FBAFF) }, /*BE*/ + { UINT64_C(0x6537E69171A2665D), UINT64_C(0x3FD2F835435A3F23), UINT64_C(0xADD5DD3E622D6C8A), UINT64_C(0xC522CDD5E5E243F8), UINT64_C(0x5AEC27F3DBFDA8A2), UINT64_C(0x477A65ED570E1445) }, /*BF*/ + { UINT64_C(0x3BA7CB01D32E9D63), UINT64_C(0x9E335734E7B5416B), UINT64_C(0x0ED96A84F94539F6), UINT64_C(0x45CEE2E46DF5A70D), UINT64_C(0xDE142EE1E9AFEC1C), UINT64_C(0x78D6121C4FDC72DD) }, /*C0*/ + { UINT64_C(0x7BB30AF653390B77), UINT64_C(0x2D394F2B7F8F7BB6), UINT64_C(0x0277A3C213AF3489), UINT64_C(0x7DF6E674DD56D084), UINT64_C(0x5643CD3073C42451), UINT64_C(0xFAB15F8BD1A1DC18) }, /*C1*/ + { UINT64_C(0x42B453ABF5150D8B), UINT64_C(0x913F109C1188E18C), UINT64_C(0xC27BB7631FB43BF9), UINT64_C(0xEBDDE685EF108419), UINT64_C(0x76D67C87C56D33EA), UINT64_C(0x95EC73C0AF40F084) }, /*C2*/ + { UINT64_C(0xBCE43D59A1F50BFB), UINT64_C(0xBA7027CA04D84600), UINT64_C(0xFB6FDB98A2BE644B), UINT64_C(0xD5DE777E993DED4A), UINT64_C(0xFCA39F1EDF710F3A), UINT64_C(0xA5E5893C858D8841) }, /*C3*/ + { UINT64_C(0xC68AC776E6AEACFC), UINT64_C(0x538067C7866106EB), UINT64_C(0xD27B4A352F4EFDE3), UINT64_C(0x847DA2B3BF01E378), UINT64_C(0x3C79E3C136926D58), UINT64_C(0xF957BC8726AA1610) }, /*C4*/ + { UINT64_C(0x95492C4203C7C612), UINT64_C(0x0DD60DB1EE8321FC), UINT64_C(0xE1D9EBA902F62B42), UINT64_C(0xEA2DBF7D0E37A4F2), UINT64_C(0xE11FB9098BF5DA48), UINT64_C(0xDBFE213F818EA338) }, /*C5*/ + { UINT64_C(0x17CB21316D4756DD), UINT64_C(0xB88952498140146A), UINT64_C(0x648112F580844288), UINT64_C(0x4947ADC3F7D58F35), UINT64_C(0x651CCE28E26A5377), UINT64_C(0x0B3803DAF337F89B) }, /*C6*/ + { UINT64_C(0xBEAB16E2DCE6B6E3), UINT64_C(0x8F39ECC8E39172DF), UINT64_C(0x607CC9553FF29C0E), UINT64_C(0x4BFD15154F4F0BA7), UINT64_C(0xEE6230B6BD408CE4), UINT64_C(0x35B654110D164E99) }, /*C7*/ + { UINT64_C(0xADDDFF1BD2C11CD4), UINT64_C(0x2A1A262CBA6E1AA0), UINT64_C(0x0BF2291D09475A46), UINT64_C(0x4C93A0ABADF4DE32), UINT64_C(0x73EE8E1327333E63), UINT64_C(0xF3AE2031F5D13B28) }, /*C8*/ + { UINT64_C(0x246C7CABB2D9A55C), UINT64_C(0x50E9C7282C1EE0F6), UINT64_C(0x2FBDA09565A0D3D7), UINT64_C(0x196552679C04A4EB), UINT64_C(0x137C66DA29A6DD82), UINT64_C(0x08A76B6B4BDA56BF) }, /*C9*/ + { UINT64_C(0x7CA3C59BE3E28610), UINT64_C(0x6ADD75CF1F7AE248), UINT64_C(0x01747450737A6435), UINT64_C(0xA1F2259CB2B4923B), UINT64_C(0xE0C8F55E8ECE7210), UINT64_C(0xD7964398F350B69B) }, /*CA*/ + { UINT64_C(0xE045864ED1825101), UINT64_C(0xAC54969193E1A1C5), UINT64_C(0x23D85A934D0794C7), UINT64_C(0xB4FA88CB734A4213), UINT64_C(0x7C5CBFD6BDA3D5F9), UINT64_C(0x66607FE938748825) }, /*CB*/ + { UINT64_C(0xBAF36FD2A180D481), UINT64_C(0xEAC440AC1B9598F7), UINT64_C(0x9AA24D80FFB7B06C), UINT64_C(0x79601F517358F163), UINT64_C(0xD1071831418BB63B), UINT64_C(0x819609A6AE7D3A03) }, /*CC*/ + { UINT64_C(0x3E9152D8CDBAE551), UINT64_C(0x86AD793F203DD016), UINT64_C(0xBE3AEB778AD4A891), UINT64_C(0x2810254DD76B6618), UINT64_C(0x9B5DCDE36636C327), UINT64_C(0x0A8AAD65868BC58C) }, /*CD*/ + { UINT64_C(0x6D0672780D93152A), UINT64_C(0xEEE705247B828091), UINT64_C(0x9EBDB976F137463F), UINT64_C(0xA7DE3E73A2D0C1BF), UINT64_C(0xF871A00BA0046AC7), UINT64_C(0x484C96A803F23486) }, /*CE*/ + { UINT64_C(0x0FC7BCDABB06BFFB), UINT64_C(0xF75C3FFB3D6309B3), UINT64_C(0xECA305D103109162), UINT64_C(0x373F503B204FFF61), UINT64_C(0xCE332C9F54963FA2), UINT64_C(0x9A4420A52242CDB4) }, /*CF*/ + { UINT64_C(0xC71D481179D198C1), UINT64_C(0x505A2845CEE92569), UINT64_C(0xF339BFF6DD6755B5), UINT64_C(0x8BEAD52B8DE89245), UINT64_C(0x4B686E65920DCA2B), UINT64_C(0x99593FA43EE68A37) }, /*D0*/ + { UINT64_C(0xD90A68D717E61501), UINT64_C(0x9BB920AEA19161A6), UINT64_C(0x2F3D6F96D90EB1E4), UINT64_C(0xDF15ECBA10513D7D), UINT64_C(0xE6E5D539B4F01831), UINT64_C(0xC7D17A7528FECE36) }, /*D1*/ + { UINT64_C(0xA04FF0BEB4EBFBAF), UINT64_C(0xE5E90A5B3DDAA3CA), UINT64_C(0x8453542209F4A145), UINT64_C(0x80A6FFD72BB5A707), UINT64_C(0x14E0C4705A1ABF6A), UINT64_C(0xD699EC1FC18A677D) }, /*D2*/ + { UINT64_C(0x7021A124E3181575), UINT64_C(0xDC7AAE2817AD945F), UINT64_C(0x8BB5521E7F0D565A), UINT64_C(0x6671D3792F0805EE), UINT64_C(0xD3888EA394413A1A), UINT64_C(0xCE4D7E47B55BF9CC) }, /*D3*/ + { UINT64_C(0x22F440263CAADE68), UINT64_C(0xE77BB287772EAC7B), UINT64_C(0x29493775962A40E9), UINT64_C(0x1E06A27FA68CB91B), UINT64_C(0xDDEF02932ABDB9C7), UINT64_C(0x79F03B88DC175233) }, /*D4*/ + { UINT64_C(0x65F6D517B53E2391), UINT64_C(0x97DB65A2F00B1C39), UINT64_C(0x1D77AE9B85AA4855), UINT64_C(0x19133B9B3E9B0771), UINT64_C(0x6376D9F11A7DB3D4), UINT64_C(0x949AD02F5AE16184) }, /*D5*/ + { UINT64_C(0xFE4434CDE09D923B), UINT64_C(0x03B0FCFD713B7052), UINT64_C(0x2D713290D4A67238), UINT64_C(0x2B56946FF629EE96), UINT64_C(0x60A15D01B2B3C428), UINT64_C(0x0B1D5EAF793933A0) }, /*D6*/ + { UINT64_C(0xBC40FCFB0E0D494B), UINT64_C(0xA31C4648C7B3D1DE), UINT64_C(0xF1113C219A07EC8D), UINT64_C(0x2378BEB1A5C2BD1C), UINT64_C(0x190CC3478070A194), UINT64_C(0x63DAB6E1CCF56329) }, /*D7*/ + { UINT64_C(0x901B6B9E82BABF91), UINT64_C(0x872A234C45D61001), UINT64_C(0x6CA46A95C1CC6D6C), UINT64_C(0x22779315E0F02295), UINT64_C(0x60A59396346BE6AC), UINT64_C(0xFB67A503CB488846) }, /*D8*/ + { UINT64_C(0x50D440F74C97660B), UINT64_C(0xE71ECABF64EDFE0C), UINT64_C(0x80201B895718CE22), UINT64_C(0xA05D89804D35D306), UINT64_C(0x8F700402A2B0D086), UINT64_C(0x326FCB334CA4DFC0) }, /*D9*/ + { UINT64_C(0xBCFBD02EA005CDD5), UINT64_C(0xF0225A4675553115), UINT64_C(0x08E18B3692A7AF62), UINT64_C(0x05D34A820C8CED0A), UINT64_C(0x51A8D7CEC33E80EA), UINT64_C(0x0AC007503FAE879C) }, /*DA*/ + { UINT64_C(0xF43EEFB5C83C521A), UINT64_C(0xE5E9B05FC48841AC), UINT64_C(0x79C52C38BF85B5F9), UINT64_C(0x26CD0818AE3BF7A9), UINT64_C(0x4F385C32CA8F5F74), UINT64_C(0xF17B22107B954752) }, /*DB*/ + { UINT64_C(0x1A48FC969198A4B0), UINT64_C(0xD9A78940BB0C4E1C), UINT64_C(0x42781D9BE60E7691), UINT64_C(0x87D1CAF3680F8A30), UINT64_C(0xD09FF193606AAF29), UINT64_C(0x4518DABC60048793) }, /*DC*/ + { UINT64_C(0xF05D48134A56A034), UINT64_C(0x89A65EEB91DC69B9), UINT64_C(0x8FC7F43960E63C62), UINT64_C(0xFA1C6B9FF9415E92), UINT64_C(0x7E219D4E56347935), UINT64_C(0x2B6A48D6DE0AEF85) }, /*DD*/ + { UINT64_C(0x1A7FF9C54B045FFD), UINT64_C(0x44A0A9562E9468B2), UINT64_C(0xF11425A22D1EBF92), UINT64_C(0x208D33120BD28E0E), UINT64_C(0xF2D74197AF80E162), UINT64_C(0xCEEDCA73DFE66C93) }, /*DE*/ + { UINT64_C(0xD57190439D29C9A4), UINT64_C(0x44C007DC2B5EAF9D), UINT64_C(0xEF6DDF48A780CEDC), UINT64_C(0x61B205E4A96024B1), UINT64_C(0x1885B6CE84C3FE5D), UINT64_C(0xB8B56986B6E2CE21) }, /*DF*/ + { UINT64_C(0xF36DACFA34237E99), UINT64_C(0xBE45EB5253BCFED0), UINT64_C(0x402C6946B8B21AC0), UINT64_C(0x2460A6FCE7E9CD67), UINT64_C(0xF89A6D5B162629FC), UINT64_C(0xF66CCEA374DB821E) }, /*E0*/ + { UINT64_C(0x16E06074DCC31A1D), UINT64_C(0xF172017AC3FA38C3), UINT64_C(0xBBC1CE4BB784ED60), UINT64_C(0xDA89A8BCE82AE671), UINT64_C(0xA6DACFFB8D26C0BB), UINT64_C(0x185181AE9609F6D6) }, /*E1*/ + { UINT64_C(0xF110DBDD94D17661), UINT64_C(0xF59FBB4CBA69F393), UINT64_C(0x463B60FB3F3C5E00), UINT64_C(0x1C60B896FE8E78AC), UINT64_C(0x5EB3E26795DE5AB6), UINT64_C(0x997328D4654D6219) }, /*E2*/ + { UINT64_C(0x21069118ABE24B61), UINT64_C(0x811CB8C48FCEFC6A), UINT64_C(0x483B032CFB56F902), UINT64_C(0xFB32E848198CC057), UINT64_C(0xA620815462A04F70), UINT64_C(0x900038D1894959E2) }, /*E3*/ + { UINT64_C(0x5AD509789BFFECD0), UINT64_C(0xDDCD5E8325F69CA0), UINT64_C(0x154D8F1ACD9B8C82), UINT64_C(0xAC7DF75E94CE3CAF), UINT64_C(0x6D6554D1B38754BE), UINT64_C(0xB5DB64AF738486E7) }, /*E4*/ + { UINT64_C(0x35A308A1AC9A43BF), UINT64_C(0x2647805AB3E6E492), UINT64_C(0x4BB74A616F61588F), UINT64_C(0xFA4602EE5BDBF54E), UINT64_C(0x3FDD62470A7174DB), UINT64_C(0x5795433CA808FAAC) }, /*E5*/ + { UINT64_C(0x51A094B8774CA605), UINT64_C(0x5F07974C74EEF225), UINT64_C(0x022AFEF7AD81A953), UINT64_C(0x0967C44BBA336FD6), UINT64_C(0x8AA327918AECBA3D), UINT64_C(0xF70B8436573C3F0A) }, /*E6*/ + { UINT64_C(0xCF374F83420766C3), UINT64_C(0x71F31901A13EF07C), UINT64_C(0x63AD56C7DEF9DC0F), UINT64_C(0x9E5BB5E859F5A231), UINT64_C(0xD0BF453BB9893E4C), UINT64_C(0xA1E14B66C2719760) }, /*E7*/ + { UINT64_C(0xB41861CC73FD3E48), UINT64_C(0x461D79A138B04BE1), UINT64_C(0x4010D37D37FBA817), UINT64_C(0x7D9622AA693225A4), UINT64_C(0x2204454B8126799A), UINT64_C(0x33A5D487DCCD6EB6) }, /*E8*/ + { UINT64_C(0xD291D0317A053320), UINT64_C(0xE27678F1E50D1F76), UINT64_C(0x9A3D663A63159FC7), UINT64_C(0xAD7B4D3F67BAB452), UINT64_C(0x269CC05E2B33CE1C), UINT64_C(0x0FB8261CD734BCC3) }, /*E9*/ + { UINT64_C(0xF3D0546D3D4A25EE), UINT64_C(0xB42874AD28C9B7F2), UINT64_C(0x73EC788B29962D28), UINT64_C(0x4AE73A48132B8553), UINT64_C(0x756C99D7A0910B66), UINT64_C(0xECA7E2C2712D555C) }, /*EA*/ + { UINT64_C(0x559FA5BF24911FDD), UINT64_C(0xA1DDF5DE3770554B), UINT64_C(0xC7C3FD139366B946), UINT64_C(0x6E7ECC0C881D2BA4), UINT64_C(0x14E76D6A27E54B87), UINT64_C(0x7352D5FBC4FAB878) }, /*EB*/ + { UINT64_C(0xF19A622BED8DAC0A), UINT64_C(0x35548E5D7EFC5A2E), UINT64_C(0xCAC84974B4F057B2), UINT64_C(0xAB317ED03D0335AE), UINT64_C(0x710FC138F2C51738), UINT64_C(0x9C90CC495A403416) }, /*EC*/ + { UINT64_C(0x9FA7DEB936F10461), UINT64_C(0xA1529B0B58462F9D), UINT64_C(0x9F109111C8B9EC65), UINT64_C(0x23A3EB28444E33EA), UINT64_C(0x554084CA75118937), UINT64_C(0x599D58A7C946EAC2) }, /*ED*/ + { UINT64_C(0x6EC3AABB7856AC4E), UINT64_C(0x980E6907C1CBCCAF), UINT64_C(0x1F8557ADC700CBF5), UINT64_C(0x7DCB1CE0AF48D9F4), UINT64_C(0x7FB3DADF8199AB8A), UINT64_C(0xE6B36DB8FADBF312) }, /*EE*/ + { UINT64_C(0xC00F0D3F7A101660), UINT64_C(0x605B94B12DB6C697), UINT64_C(0x79944F7BA2B65F38), UINT64_C(0x40858ADEDD47E2BC), UINT64_C(0x1E044BDB0E9FB02B), UINT64_C(0x86C79D01A3109539) }, /*EF*/ + { UINT64_C(0x9731893D5B98482A), UINT64_C(0xFB8DE267F9790326), UINT64_C(0x8780F407143A505D), UINT64_C(0xA41CAEFCCCD3A8E3), UINT64_C(0xA042F0B3D7B7A7FE), UINT64_C(0x3E3151FEBB19A1AC) }, /*F0*/ + { UINT64_C(0xE7EDF679003A6950), UINT64_C(0xBAFC97D4A8C6AB12), UINT64_C(0x13C096B49C79559A), UINT64_C(0xC3052501434B5019), UINT64_C(0x1280FB23E7ADFB09), UINT64_C(0x1959905D31BD2FC0) }, /*F1*/ + { UINT64_C(0x575C0C46FCFCC65B), UINT64_C(0xFE625E873F34B419), UINT64_C(0x1696FDCC7F51B8A3), UINT64_C(0xC79C56F30E5AE7C0), UINT64_C(0x14E3461CD27FAD15), UINT64_C(0x1B7BCCB9CB472859) }, /*F2*/ + { UINT64_C(0x3806FE58E5CC8F16), UINT64_C(0xF8244ED76734C1BF), UINT64_C(0x4E04940E0F5DDB56), UINT64_C(0x5BD0AFDDC4158B7B), UINT64_C(0xA4C6BA949911C5C9), UINT64_C(0xFF6E2AC155AE9726) }, /*F3*/ + { UINT64_C(0x49C7C844B8114144), UINT64_C(0xB450E41BCA35CB00), UINT64_C(0x302450EC67BEF97C), UINT64_C(0xA8662049DB1E0D8B), UINT64_C(0xDA69C022528EB8FA), UINT64_C(0x6ABBF16585C1A2F7) }, /*F4*/ + { UINT64_C(0x37BB420DF67F044E), UINT64_C(0xDCC0E9F3E2EF07B3), UINT64_C(0x4D10088618777841), UINT64_C(0x0492E5379305DAAE), UINT64_C(0x3DA4791C37E4128F), UINT64_C(0x80688445CBA4EA17) }, /*F5*/ + { UINT64_C(0x51398A7CE4CF8D9D), UINT64_C(0x49A5FCD891A69CA5), UINT64_C(0x3D72A60EC2392DA5), UINT64_C(0x0E8296B879AB5539), UINT64_C(0x6BCB00AF2EDC0BDE), UINT64_C(0xBEB93848E54B3E90) }, /*F6*/ + { UINT64_C(0x7AD7C52A18922E19), UINT64_C(0x29292C57C4F5B8F5), UINT64_C(0xF0CF1F98A577C10B), UINT64_C(0x072B9F293BB660CD), UINT64_C(0x09B8604F5575B6FB), UINT64_C(0xDECB396A81B9FCDB) }, /*F7*/ + { UINT64_C(0x254AD7ADB4C220DE), UINT64_C(0x6C62E20F95A0070D), UINT64_C(0xADEB89F339309BD8), UINT64_C(0xA2F685CC178B289F), UINT64_C(0x9343905B5DEE95A5), UINT64_C(0xE0C30F34A2977C86) }, /*F8*/ + { UINT64_C(0x669CD51AF7CFBFAA), UINT64_C(0xE3E0806F6880271D), UINT64_C(0x6934C259E098BF90), UINT64_C(0x5DFEEAF0FBCA7249), UINT64_C(0x89F74B948B4118B6), UINT64_C(0x53640AEAFB6807C3) }, /*F9*/ + { UINT64_C(0xDD3BACDCC04BE120), UINT64_C(0x6D4949BD64198E51), UINT64_C(0x31FDB39666598A74), UINT64_C(0xBBBC6DE9C0C15A81), UINT64_C(0xF27F201C61C06279), UINT64_C(0x2738AFE3E84E5CDD) }, /*FA*/ + { UINT64_C(0xCDD71FD35A6411DE), UINT64_C(0x3CC012793E87523F), UINT64_C(0xB0CFF8720FCA36F3), UINT64_C(0x93E85FE07300F012), UINT64_C(0xE894A085263F090B), UINT64_C(0x2DF60A01DAFA90EC) }, /*FB*/ + { UINT64_C(0x9DA50DB1EEB4FADD), UINT64_C(0xE524E49C9974799A), UINT64_C(0xDE09FFF26A24CBB9), UINT64_C(0xAF9D71E9F3ACE7CD), UINT64_C(0xEB62B1A62566EC9D), UINT64_C(0x06D02AB1217D3553) }, /*FC*/ + { UINT64_C(0xDD31E6391AE03522), UINT64_C(0x93ACD1065B35E915), UINT64_C(0xF4EB56CC03E79218), UINT64_C(0x0717815C850C97F1), UINT64_C(0xBF4F6A8AC0540A6F), UINT64_C(0xFCF8AE5DE9507FF0) }, /*FD*/ + { UINT64_C(0xAB45B413DC50B207), UINT64_C(0x40B417369551D8D5), UINT64_C(0xCA32286A108E7210), UINT64_C(0x03225E54D8D093AF), UINT64_C(0x4B6CA5591EA576E9), UINT64_C(0x4E12AB774DC4E062) }, /*FE*/ + { UINT64_C(0xD9F4F850DF6CB96C), UINT64_C(0x8ABAD81B1667335D), UINT64_C(0xCB4079CFE79C72E5), UINT64_C(0xE5542F763E316996), UINT64_C(0x303E4B79B9D397C4), UINT64_C(0xE46933038B945111) }, /*FF*/ + { UINT64_C(0x75B15CC53B0D2502), UINT64_C(0xDA1BCA6BA0524358), UINT64_C(0x9EDA977556C06B7E), UINT64_C(0x6C57727ECF0A1325), UINT64_C(0xDC613D5A78E5C3F8), UINT64_C(0xCE062D94A3B4945A) } /*ZZ*/ +}; + +/* 144 byte round keys containing the first 1152 bits of sqrt(2) */ +static const uint64_t NUHASH_RND[ROUNDS][NUHASH_WORDS] = +{ + { UINT64_C(0x6A09E667F3BCC908), UINT64_C(0xB2FB1366EA957D3E), UINT64_C(0x3ADEC17512775099), UINT64_C(0xDA2F590B0667322A), UINT64_C(0x95F9060875714587), UINT64_C(0x5163FCDFB907B672) }, /*R1*/ + { UINT64_C(0x1EE950BC8738F694), UINT64_C(0xF0090E6C7BF44ED1), UINT64_C(0xA4405D0E855E3E9C), UINT64_C(0xA60B38C0237866F7), UINT64_C(0x956379222D108B14), UINT64_C(0x8C1578E45EF89C67) }, /*R2*/ + { UINT64_C(0x8DAB5147176FD3B9), UINT64_C(0x9654C68663E7909B), UINT64_C(0xEA5E241F06DCB05D), UINT64_C(0xD549411320819495), UINT64_C(0x0272956DB1FA1DFB), UINT64_C(0xE9A74059D7927C18) }, /*R3*/ + { UINT64_C(0x84C9B579AA516CA3), UINT64_C(0x719E6836DF046D8E), UINT64_C(0x0209B803FC646A5E), UINT64_C(0x6654BD3EF7B43D7F), UINT64_C(0xED437C7F9444260F), UINT64_C(0xBD40C483EF550385) }, /*R4*/ + { UINT64_C(0x83F97BBD45EFB866), UINT64_C(0x3107145D5FEBE765), UINT64_C(0xA49E94EC7F597105), UINT64_C(0xFBFC2E1FA763EF01), UINT64_C(0xF3599C82F2FE500B), UINT64_C(0x848CF0BD252AE046) }, /*R5*/ +}; + +/* 16x16 8-bit substitution box, borrowed straight from Rijndael */ +static const uint8_t NUHASH_SBX[256U] = +{ + UINT8_C(0x63), UINT8_C(0x7C), UINT8_C(0x77), UINT8_C(0x7B), UINT8_C(0xF2), UINT8_C(0x6B), UINT8_C(0x6F), UINT8_C(0xC5), UINT8_C(0x30), UINT8_C(0x01), UINT8_C(0x67), UINT8_C(0x2B), UINT8_C(0xFE), UINT8_C(0xD7), UINT8_C(0xAB), UINT8_C(0x76), + UINT8_C(0xCA), UINT8_C(0x82), UINT8_C(0xC9), UINT8_C(0x7D), UINT8_C(0xFA), UINT8_C(0x59), UINT8_C(0x47), UINT8_C(0xF0), UINT8_C(0xAD), UINT8_C(0xD4), UINT8_C(0xA2), UINT8_C(0xAF), UINT8_C(0x9C), UINT8_C(0xA4), UINT8_C(0x72), UINT8_C(0xC0), + UINT8_C(0xB7), UINT8_C(0xFD), UINT8_C(0x93), UINT8_C(0x26), UINT8_C(0x36), UINT8_C(0x3F), UINT8_C(0xF7), UINT8_C(0xCC), UINT8_C(0x34), UINT8_C(0xA5), UINT8_C(0xE5), UINT8_C(0xF1), UINT8_C(0x71), UINT8_C(0xD8), UINT8_C(0x31), UINT8_C(0x15), + UINT8_C(0x04), UINT8_C(0xC7), UINT8_C(0x23), UINT8_C(0xC3), UINT8_C(0x18), UINT8_C(0x96), UINT8_C(0x05), UINT8_C(0x9A), UINT8_C(0x07), UINT8_C(0x12), UINT8_C(0x80), UINT8_C(0xE2), UINT8_C(0xEB), UINT8_C(0x27), UINT8_C(0xB2), UINT8_C(0x75), + UINT8_C(0x09), UINT8_C(0x83), UINT8_C(0x2C), UINT8_C(0x1A), UINT8_C(0x1B), UINT8_C(0x6E), UINT8_C(0x5A), UINT8_C(0xA0), UINT8_C(0x52), UINT8_C(0x3B), UINT8_C(0xD6), UINT8_C(0xB3), UINT8_C(0x29), UINT8_C(0xE3), UINT8_C(0x2F), UINT8_C(0x84), + UINT8_C(0x53), UINT8_C(0xD1), UINT8_C(0x00), UINT8_C(0xED), UINT8_C(0x20), UINT8_C(0xFC), UINT8_C(0xB1), UINT8_C(0x5B), UINT8_C(0x6A), UINT8_C(0xCB), UINT8_C(0xBE), UINT8_C(0x39), UINT8_C(0x4A), UINT8_C(0x4C), UINT8_C(0x58), UINT8_C(0xCF), + UINT8_C(0xD0), UINT8_C(0xEF), UINT8_C(0xAA), UINT8_C(0xFB), UINT8_C(0x43), UINT8_C(0x4D), UINT8_C(0x33), UINT8_C(0x85), UINT8_C(0x45), UINT8_C(0xF9), UINT8_C(0x02), UINT8_C(0x7F), UINT8_C(0x50), UINT8_C(0x3C), UINT8_C(0x9F), UINT8_C(0xA8), + UINT8_C(0x51), UINT8_C(0xA3), UINT8_C(0x40), UINT8_C(0x8F), UINT8_C(0x92), UINT8_C(0x9D), UINT8_C(0x38), UINT8_C(0xF5), UINT8_C(0xBC), UINT8_C(0xB6), UINT8_C(0xDA), UINT8_C(0x21), UINT8_C(0x10), UINT8_C(0xFF), UINT8_C(0xF3), UINT8_C(0xD2), + UINT8_C(0xCD), UINT8_C(0x0C), UINT8_C(0x13), UINT8_C(0xEC), UINT8_C(0x5F), UINT8_C(0x97), UINT8_C(0x44), UINT8_C(0x17), UINT8_C(0xC4), UINT8_C(0xA7), UINT8_C(0x7E), UINT8_C(0x3D), UINT8_C(0x64), UINT8_C(0x5D), UINT8_C(0x19), UINT8_C(0x73), + UINT8_C(0x60), UINT8_C(0x81), UINT8_C(0x4F), UINT8_C(0xDC), UINT8_C(0x22), UINT8_C(0x2A), UINT8_C(0x90), UINT8_C(0x88), UINT8_C(0x46), UINT8_C(0xEE), UINT8_C(0xB8), UINT8_C(0x14), UINT8_C(0xDE), UINT8_C(0x5E), UINT8_C(0x0B), UINT8_C(0xDB), + UINT8_C(0xE0), UINT8_C(0x32), UINT8_C(0x3A), UINT8_C(0x0A), UINT8_C(0x49), UINT8_C(0x06), UINT8_C(0x24), UINT8_C(0x5C), UINT8_C(0xC2), UINT8_C(0xD3), UINT8_C(0xAC), UINT8_C(0x62), UINT8_C(0x91), UINT8_C(0x95), UINT8_C(0xE4), UINT8_C(0x79), + UINT8_C(0xE7), UINT8_C(0xC8), UINT8_C(0x37), UINT8_C(0x6D), UINT8_C(0x8D), UINT8_C(0xD5), UINT8_C(0x4E), UINT8_C(0xA9), UINT8_C(0x6C), UINT8_C(0x56), UINT8_C(0xF4), UINT8_C(0xEA), UINT8_C(0x65), UINT8_C(0x7A), UINT8_C(0xAE), UINT8_C(0x08), + UINT8_C(0xBA), UINT8_C(0x78), UINT8_C(0x25), UINT8_C(0x2E), UINT8_C(0x1C), UINT8_C(0xA6), UINT8_C(0xB4), UINT8_C(0xC6), UINT8_C(0xE8), UINT8_C(0xDD), UINT8_C(0x74), UINT8_C(0x1F), UINT8_C(0x4B), UINT8_C(0xBD), UINT8_C(0x8B), UINT8_C(0x8A), + UINT8_C(0x70), UINT8_C(0x3E), UINT8_C(0xB5), UINT8_C(0x66), UINT8_C(0x48), UINT8_C(0x03), UINT8_C(0xF6), UINT8_C(0x0E), UINT8_C(0x61), UINT8_C(0x35), UINT8_C(0x57), UINT8_C(0xB9), UINT8_C(0x86), UINT8_C(0xC1), UINT8_C(0x1D), UINT8_C(0x9E), + UINT8_C(0xE1), UINT8_C(0xF8), UINT8_C(0x98), UINT8_C(0x11), UINT8_C(0x69), UINT8_C(0xD9), UINT8_C(0x8E), UINT8_C(0x94), UINT8_C(0x9B), UINT8_C(0x1E), UINT8_C(0x87), UINT8_C(0xE9), UINT8_C(0xCE), UINT8_C(0x55), UINT8_C(0x28), UINT8_C(0xDF), + UINT8_C(0x8C), UINT8_C(0xA1), UINT8_C(0x89), UINT8_C(0x0D), UINT8_C(0xBF), UINT8_C(0xE6), UINT8_C(0x42), UINT8_C(0x68), UINT8_C(0x41), UINT8_C(0x99), UINT8_C(0x2D), UINT8_C(0x0F), UINT8_C(0xB0), UINT8_C(0x54), UINT8_C(0xBB), UINT8_C(0x16) +}; + +/* 256 byte finalization vector, random permutation courtesy of Random.org */ +static const uint8_t NUHASH_FIN[256U] = +{ + UINT8_C(0xB4), UINT8_C(0x98), UINT8_C(0x0C), UINT8_C(0x84), UINT8_C(0x24), UINT8_C(0xF3), UINT8_C(0x27), UINT8_C(0x8F), UINT8_C(0xA6), UINT8_C(0x5E), UINT8_C(0xF0), UINT8_C(0x65), UINT8_C(0x86), UINT8_C(0xBC), UINT8_C(0x09), UINT8_C(0x92), + UINT8_C(0x75), UINT8_C(0x21), UINT8_C(0xB9), UINT8_C(0x95), UINT8_C(0x66), UINT8_C(0x8A), UINT8_C(0x2F), UINT8_C(0x13), UINT8_C(0xB5), UINT8_C(0xB7), UINT8_C(0x6B), UINT8_C(0x33), UINT8_C(0x2A), UINT8_C(0xBF), UINT8_C(0xF7), UINT8_C(0x0F), + UINT8_C(0x0A), UINT8_C(0xE7), UINT8_C(0x16), UINT8_C(0x30), UINT8_C(0x77), UINT8_C(0x61), UINT8_C(0x48), UINT8_C(0x90), UINT8_C(0xDF), UINT8_C(0xAF), UINT8_C(0x72), UINT8_C(0x79), UINT8_C(0xF6), UINT8_C(0xA5), UINT8_C(0x58), UINT8_C(0xD1), + UINT8_C(0xF2), UINT8_C(0x40), UINT8_C(0x9F), UINT8_C(0x41), UINT8_C(0xE8), UINT8_C(0x03), UINT8_C(0xA1), UINT8_C(0x05), UINT8_C(0xC5), UINT8_C(0x35), UINT8_C(0xC7), UINT8_C(0x97), UINT8_C(0x54), UINT8_C(0x7B), UINT8_C(0xB3), UINT8_C(0xF5), + UINT8_C(0xB8), UINT8_C(0xA8), UINT8_C(0xD8), UINT8_C(0x68), UINT8_C(0x51), UINT8_C(0xAD), UINT8_C(0xE3), UINT8_C(0xC2), UINT8_C(0x5D), UINT8_C(0xCF), UINT8_C(0xEA), UINT8_C(0x89), UINT8_C(0x37), UINT8_C(0xF1), UINT8_C(0x55), UINT8_C(0x60), + UINT8_C(0xA4), UINT8_C(0x26), UINT8_C(0xAC), UINT8_C(0x32), UINT8_C(0x0E), UINT8_C(0xD2), UINT8_C(0x85), UINT8_C(0x6F), UINT8_C(0xC8), UINT8_C(0xDC), UINT8_C(0x36), UINT8_C(0x6D), UINT8_C(0xA3), UINT8_C(0x22), UINT8_C(0x5A), UINT8_C(0xC9), + UINT8_C(0x5C), UINT8_C(0x91), UINT8_C(0x1B), UINT8_C(0x5B), UINT8_C(0xE9), UINT8_C(0x78), UINT8_C(0xD7), UINT8_C(0x44), UINT8_C(0xEB), UINT8_C(0x1A), UINT8_C(0xC0), UINT8_C(0xCA), UINT8_C(0x94), UINT8_C(0x53), UINT8_C(0xC4), UINT8_C(0x11), + UINT8_C(0x12), UINT8_C(0xCC), UINT8_C(0xFF), UINT8_C(0x88), UINT8_C(0x0D), UINT8_C(0x4E), UINT8_C(0xB2), UINT8_C(0xB1), UINT8_C(0x4A), UINT8_C(0x3A), UINT8_C(0xE1), UINT8_C(0x2E), UINT8_C(0x0B), UINT8_C(0x4C), UINT8_C(0x5F), UINT8_C(0x06), + UINT8_C(0x81), UINT8_C(0x31), UINT8_C(0xD9), UINT8_C(0x3D), UINT8_C(0xFD), UINT8_C(0x43), UINT8_C(0x67), UINT8_C(0x62), UINT8_C(0x00), UINT8_C(0x9C), UINT8_C(0x50), UINT8_C(0xCE), UINT8_C(0x6E), UINT8_C(0x15), UINT8_C(0x82), UINT8_C(0x29), + UINT8_C(0x96), UINT8_C(0xDA), UINT8_C(0x87), UINT8_C(0xEF), UINT8_C(0x6C), UINT8_C(0xC1), UINT8_C(0x8B), UINT8_C(0x07), UINT8_C(0x8E), UINT8_C(0x17), UINT8_C(0xEC), UINT8_C(0x9A), UINT8_C(0xBA), UINT8_C(0x46), UINT8_C(0x04), UINT8_C(0x73), + UINT8_C(0x39), UINT8_C(0xE4), UINT8_C(0x63), UINT8_C(0xBE), UINT8_C(0x64), UINT8_C(0x47), UINT8_C(0xE6), UINT8_C(0x3F), UINT8_C(0x25), UINT8_C(0x52), UINT8_C(0x59), UINT8_C(0xA7), UINT8_C(0x42), UINT8_C(0x38), UINT8_C(0x99), UINT8_C(0x01), + UINT8_C(0xE5), UINT8_C(0x1D), UINT8_C(0x28), UINT8_C(0x7A), UINT8_C(0xB0), UINT8_C(0x7C), UINT8_C(0x9D), UINT8_C(0x56), UINT8_C(0xE2), UINT8_C(0xD6), UINT8_C(0xA0), UINT8_C(0xF4), UINT8_C(0x1E), UINT8_C(0xE0), UINT8_C(0xD3), UINT8_C(0x83), + UINT8_C(0x6A), UINT8_C(0xBB), UINT8_C(0x18), UINT8_C(0x20), UINT8_C(0xAE), UINT8_C(0x57), UINT8_C(0xAA), UINT8_C(0x8D), UINT8_C(0x71), UINT8_C(0x1F), UINT8_C(0x34), UINT8_C(0x4D), UINT8_C(0x2D), UINT8_C(0x3C), UINT8_C(0x2B), UINT8_C(0xF8), + UINT8_C(0x10), UINT8_C(0x7E), UINT8_C(0xCB), UINT8_C(0xFB), UINT8_C(0x49), UINT8_C(0xA2), UINT8_C(0x45), UINT8_C(0x7F), UINT8_C(0x3E), UINT8_C(0xBD), UINT8_C(0xC3), UINT8_C(0xFC), UINT8_C(0x14), UINT8_C(0x74), UINT8_C(0x23), UINT8_C(0x4F), + UINT8_C(0x7D), UINT8_C(0x69), UINT8_C(0x93), UINT8_C(0x19), UINT8_C(0xD0), UINT8_C(0x1C), UINT8_C(0x08), UINT8_C(0xF9), UINT8_C(0xDD), UINT8_C(0xC6), UINT8_C(0x2C), UINT8_C(0x9E), UINT8_C(0xA9), UINT8_C(0x4B), UINT8_C(0xFE), UINT8_C(0xED), + UINT8_C(0x76), UINT8_C(0xDB), UINT8_C(0xAB), UINT8_C(0xD4), UINT8_C(0x80), UINT8_C(0xCD), UINT8_C(0xB6), UINT8_C(0x8C), UINT8_C(0xDE), UINT8_C(0x70), UINT8_C(0x9B), UINT8_C(0xD5), UINT8_C(0xFA), UINT8_C(0xEE), UINT8_C(0x02), UINT8_C(0x3B) +}; + +/* ------------------------------------------------------------------------ */ +/* Mix functions */ +/* ------------------------------------------------------------------------ */ + +/* Based on "Better Bit Mixing" functions, by David Stafford */ +#define MIX_FUNCTION(U,V,W,X,Y,Z) \ + static INLINE uint64_t mix_##U(uint64_t key) \ + { \ + key = (key ^ (key >> (V))) * (W); \ + key = (key ^ (key >> (X))) * (Y); \ + return key ^ (key >> (Z)); \ + } + +MIX_FUNCTION(1, 31, UINT64_C(0x7FB5D329728EA185), 27, UINT64_C(0x81DADEF4BC2DD44D), 33) /* Mix01 */ +MIX_FUNCTION(2, 31, UINT64_C(0x99BCF6822B23CA35), 30, UINT64_C(0x14020A57ACCED8B7), 33) /* Mix03 */ +MIX_FUNCTION(3, 31, UINT64_C(0x69B0BC90BD9A8C49), 27, UINT64_C(0x3D5E661A2A77868D), 30) /* Mix06 */ +MIX_FUNCTION(4, 30, UINT64_C(0x16A6AC37883AF045), 26, UINT64_C(0xCC9C31A4274686A5), 32) /* Mix07 */ +MIX_FUNCTION(5, 30, UINT64_C(0xBF58476D1CE4E5B9), 27, UINT64_C(0x94D049BB133111EB), 31) /* Mix13 */ +MIX_FUNCTION(6, 30, UINT64_C(0x4BE98134A5976FD3), 29, UINT64_C(0x3BC0993A5AD19A13), 31) /* Mix14 */ + +/* ------------------------------------------------------------------------ */ +/* Substitution function */ +/* ------------------------------------------------------------------------ */ + +static INLINE void substitute_bytes(uint8_t *const buffer, const size_t len) +{ + size_t pos; + for (pos = 0U; pos < len; ++pos) + { + buffer[pos] = NUHASH_SBX[buffer[pos]]; + } +} + +/* ------------------------------------------------------------------------ */ +/* Update function */ +/* ------------------------------------------------------------------------ */ + +static INLINE void update(nuhash_t *const ctx, const size_t index) +{ + size_t rnd; + const uint64_t *const row_addr = NUHASH_XOR[index]; + + for (rnd = 0U; rnd < ROUNDS; ++rnd) + { + const uint64_t initial_value = ctx->hash[0U]; + + ctx->hash[0U] = mix_1(((ctx->hash[0U] << 32) | (ctx->hash[1U] >> 32)) ^ row_addr[0U] ^ NUHASH_RND[rnd][0U]); + ctx->hash[1U] = mix_2(((ctx->hash[1U] << 32) | (ctx->hash[2U] >> 32)) ^ row_addr[1U] ^ NUHASH_RND[rnd][1U]); + ctx->hash[2U] = mix_3(((ctx->hash[2U] << 32) | (ctx->hash[3U] >> 32)) ^ row_addr[2U] ^ NUHASH_RND[rnd][2U]); + ctx->hash[3U] = mix_4(((ctx->hash[3U] << 32) | (ctx->hash[4U] >> 32)) ^ row_addr[3U] ^ NUHASH_RND[rnd][3U]); + ctx->hash[4U] = mix_5(((ctx->hash[4U] << 32) | (ctx->hash[5U] >> 32)) ^ row_addr[4U] ^ NUHASH_RND[rnd][4U]); + ctx->hash[5U] = mix_6(((ctx->hash[5U] << 32) | (initial_value >> 32)) ^ row_addr[5U] ^ NUHASH_RND[rnd][5U]); + + substitute_bytes((uint8_t*)ctx->hash, NUHASH_BYTES); + } +} + +/* ------------------------------------------------------------------------ */ +/* Bit function */ +/* ------------------------------------------------------------------------ */ + +static INLINE void store_ui64(uint8_t *const out, uint64_t value) +{ + size_t pos; + for (pos = sizeof(uint64_t); pos--; value >>= 8) + { + out[pos] = (uint8_t)(value & 0xFF); + } +} + +static INLINE void store_words(uint8_t *out, const uint64_t *const src, const size_t count) +{ + size_t pos; + for (pos = 0U; pos < count; ++pos, out += sizeof(uint64_t)) + { + store_ui64(out, src[pos]); + } +} + +static INLINE void copy_words(uint64_t *const out, const uint64_t *const src, const size_t count) +{ + size_t pos; + for (pos = 0U; pos < count; ++pos) + { + out[pos] = src[pos]; + } +} + +/* ------------------------------------------------------------------------ */ +/* Stream API */ +/* ------------------------------------------------------------------------ */ + +void nuhash_init(nuhash_t *const ctx) +{ + copy_words(ctx->hash, NUHASH_INI, NUHASH_WORDS); +} + +void nuhash_init_with_key(nuhash_t *const ctx, const uint8_t *const key, const size_t len) +{ + size_t pos; + nuhash_init(ctx); + + if (len > 0U) + { + for (pos = 0U; pos < len; ++pos) + { + update(ctx, key[pos]); + } + update(ctx, 256U); + } +} + +void nuhash_update(nuhash_t *const ctx, const uint8_t *const src, const size_t len) +{ + size_t pos; + for (pos = 0U; pos < len; ++pos) + { + update(ctx, src[pos]); + } +} + +uint8_t *nuhash_final(nuhash_t *const ctx, uint8_t *const out) +{ + size_t pos; + update(ctx, 256U); + + for (pos = 0U; pos < COUNT_OF(NUHASH_FIN); ++pos) + { + update(ctx, NUHASH_FIN[pos]); + } + + store_words(out, ctx->hash, NUHASH_WORDS); + return out; +} + +/* ------------------------------------------------------------------------ */ +/* Simple API */ +/* ------------------------------------------------------------------------ */ + +uint8_t *nuhash_compute(const uint8_t *const src, const size_t len, uint8_t *const out) +{ + nuhash_t ctx; + nuhash_init(&ctx); + + if (len > 0U) + { + nuhash_update(&ctx, src, len); + } + + nuhash_final(&ctx, out); + return out; +} + +uint8_t *nuhash_compute_with_key(const uint8_t *const key, const size_t key_len, const uint8_t *const src, const size_t in_len, uint8_t *const out) +{ + nuhash_t ctx; + nuhash_init_with_key(&ctx, key, key_len); + + if (in_len > 0U) + { + nuhash_update(&ctx, src, in_len); + } + + nuhash_final(&ctx, out); + return out; +} + +/* ------------------------------------------------------------------------ */ +/* Utility functions */ +/* ------------------------------------------------------------------------ */ + +static const char* const XDIGIT_LOWER = "0123456789abcdef"; +static const char* const XDIGIT_UPPER = "0123456789ABCDEF"; + +char *nuhash_tohex(const uint8_t *const hash, const int upper, char *const out) +{ + char *ptr = out; + const char *const xdigit = upper ? XDIGIT_UPPER : XDIGIT_LOWER; + size_t pos; + for (pos = 0U; pos < NUHASH_BYTES; ++pos) + { + *(ptr++) = xdigit[(hash[pos] >> 4) & 0x0F]; + *(ptr++) = xdigit[(hash[pos] >> 0) & 0x0F]; + } + + *ptr = (char)0U; + return out; +} + +char *nuhash_version(uint16_t version[3U], char *const build) +{ + version[0U] = VERSION_MAJOR; + version[1U] = VERSION_MINOR; + version[2U] = VERSION_PATCH; + + return strcpy(build, BUILD_DATE); +} diff --git a/libnuhash/src/version.h b/libnuhash/src/version.h new file mode 100644 index 0000000..62a2315 --- /dev/null +++ b/libnuhash/src/version.h @@ -0,0 +1,8 @@ +/******************************************************************************/ +/* NuHash, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +#define NUHASH_VERSION_MAJOR 1 +#define NUHASH_VERSION_MINOR 0 +#define NUHASH_VERSION_PATCH 0 diff --git a/make.cmd b/make.cmd new file mode 100644 index 0000000..a8ef0ec --- /dev/null +++ b/make.cmd @@ -0,0 +1,95 @@ +@echo off +cd /d "%~dp0" + +if "%MSVC_PATH%"=="" ( + set "MSVC_PATH=C:\Program Files\Microsoft Visual Studio\2022\Community" +) + +if exist "%MSVC_PATH%\VC\Auxiliary\Build\vcvarsall.bat" ( + call "%MSVC_PATH%\VC\Auxiliary\Build\vcvarsall.bat" x86 +) else ( + echo vcvarsall.bat not found. Please check your MSVC_PATH variable! + goto BuildError +) + +if "%PANDODC_PATH%"=="" ( + set "PANDODC_PATH=C:\Program Files\Pandoc" +) + +if not exist "%PANDODC_PATH%\pandoc.exe" ( + echo pandoc.exe not found. Please check your PANDODC_PATH variable! + goto BuildError +) + +REM ------------------------------------------------------------ +REM CLEAN UP +REM ------------------------------------------------------------ + +if exist "%CD%\bin\" rmdir /S /Q "%CD%\bin" +if exist "%CD%\bin\" ( + echo Failed to clean up intermediate files! + goto BuildError +) + +if exist "%CD%\obj\" rmdir /S /Q "%CD%\obj" +if exist "%CD%\obj\" ( + echo Failed to clean up intermediate files! + goto BuildError +) + +REM ------------------------------------------------------------ +REM BUILD EXECUTABLES +REM ------------------------------------------------------------ + +MSBuild.exe /property:Platform=x86 /property:Configuration=Release /target:rebuild "%CD%\nuhash.sln" +if not "%ERRORLEVEL%"=="0" goto BuildError + +MSBuild.exe /property:Platform=x64 /property:Configuration=Release /target:rebuild "%CD%\nuhash.sln" +if not "%ERRORLEVEL%"=="0" goto BuildError + +MSBuild.exe /property:Platform=ARM64 /property:Configuration=Release /target:rebuild "%CD%\nuhash.sln" +if not "%ERRORLEVEL%"=="0" goto BuildError + +REM ------------------------------------------------------------ +REM GENERATE DOCUMENTS +REM ------------------------------------------------------------ + +if not exist "%CD%\out\" mkdir "%CD%\out" + +"%PANDODC_PATH%\pandoc.exe" --standalone --embed-resources --css etc\style\gh-pandoc.min.css --metadata title="NuHash README" -o "%~dp0\out\README.html" "%~dp0\README.md" + +REM ------------------------------------------------------------ +REM COPY FILES +REM ------------------------------------------------------------ + +if exist "%CD%\out\nuhash-x86.exe" del /F "%CD%\out\nuhash-x86.exe" +if exist "%CD%\out\nuhash-x64.exe" del /F "%CD%\out\nuhash-x64.exe" +if exist "%CD%\out\nuhash-a64.exe" del /F "%CD%\out\nuhash-a64.exe" + +copy /Y /B "%CD%\bin\Win32\Release\nuhash.exe" "%CD%\out\nuhash-x86.exe" +copy /Y /B "%CD%\bin\x64\Release\nuhash.exe" "%CD%\out\nuhash-x64.exe" +copy /Y /B "%CD%\bin\ARM64\Release\nuhash.exe" "%CD%\out\nuhash-a64.exe" + +attrib +R "%CD%\out\nuhash-x86.exe" +attrib +R "%CD%\out\nuhash-x64.exe" +attrib +R "%CD%\out\nuhash-a64.exe" + +REM ------------------------------------------------------------ +REM COMPLETED +REM ------------------------------------------------------------ + +echo. +echo Build completed. +echo. +pause +goto:eof + +REM ------------------------------------------------------------ +REM BUILD ERROR +REM ------------------------------------------------------------ + +:BuildError +echo. +echo Build has failed !!! +echo. +pause diff --git a/nuhash.sln b/nuhash.sln new file mode 100644 index 0000000..a7ab20a --- /dev/null +++ b/nuhash.sln @@ -0,0 +1,66 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33815.320 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NuHash", "tool\nuhash.vcxproj", "{867A1634-C6AC-4089-B645-A1BE289D597B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnuhash", "libnuhash\libnuhash.vcxproj", "{8FA5C597-887D-46BC-A6C9-2183AEF7B793}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release_DLL|ARM64 = Release_DLL|ARM64 + Release_DLL|x64 = Release_DLL|x64 + Release_DLL|x86 = Release_DLL|x86 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {867A1634-C6AC-4089-B645-A1BE289D597B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Debug|ARM64.Build.0 = Debug|ARM64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Debug|x64.ActiveCfg = Debug|x64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Debug|x64.Build.0 = Debug|x64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Debug|x86.ActiveCfg = Debug|Win32 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Debug|x86.Build.0 = Debug|Win32 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release_DLL|ARM64.ActiveCfg = Release_DLL|ARM64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release_DLL|ARM64.Build.0 = Release_DLL|ARM64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release_DLL|x64.ActiveCfg = Release_DLL|x64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release_DLL|x64.Build.0 = Release_DLL|x64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release_DLL|x86.ActiveCfg = Release_DLL|Win32 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release_DLL|x86.Build.0 = Release_DLL|Win32 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release|ARM64.ActiveCfg = Release|ARM64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release|ARM64.Build.0 = Release|ARM64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release|x64.ActiveCfg = Release|x64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release|x64.Build.0 = Release|x64 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release|x86.ActiveCfg = Release|Win32 + {867A1634-C6AC-4089-B645-A1BE289D597B}.Release|x86.Build.0 = Release|Win32 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Debug|ARM64.Build.0 = Debug|ARM64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Debug|x64.ActiveCfg = Debug|x64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Debug|x64.Build.0 = Debug|x64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Debug|x86.ActiveCfg = Debug|Win32 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Debug|x86.Build.0 = Debug|Win32 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release_DLL|ARM64.ActiveCfg = Release_DLL|ARM64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release_DLL|ARM64.Build.0 = Release_DLL|ARM64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release_DLL|x64.ActiveCfg = Release_DLL|x64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release_DLL|x64.Build.0 = Release_DLL|x64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release_DLL|x86.ActiveCfg = Release_DLL|Win32 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release_DLL|x86.Build.0 = Release_DLL|Win32 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release|ARM64.ActiveCfg = Release|ARM64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release|ARM64.Build.0 = Release|ARM64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release|x64.ActiveCfg = Release|x64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release|x64.Build.0 = Release|x64 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release|x86.ActiveCfg = Release|Win32 + {8FA5C597-887D-46BC-A6C9-2183AEF7B793}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A92699B5-187B-4A92-95AF-F0392B047DDD} + EndGlobalSection +EndGlobal diff --git a/tool/nuhash.user b/tool/nuhash.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/tool/nuhash.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/tool/nuhash.vcxproj b/tool/nuhash.vcxproj new file mode 100644 index 0000000..3fce237 --- /dev/null +++ b/tool/nuhash.vcxproj @@ -0,0 +1,473 @@ + + + + + Debug + ARM64 + + + Debug + Win32 + + + Release_DLL + ARM64 + + + Release_DLL + Win32 + + + Release_DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {867a1634-c6ac-4089-b645-a1be289d597b} + NuHash + 10.0.20348.0 + NuHash + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + x64 + + + Application + false + v143 + true + Unicode + x64 + + + Application + true + v143 + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + x64 + + + Application + false + v143 + true + Unicode + x64 + + + Application + false + v143 + true + Unicode + x64 + + + Application + false + v143 + true + Unicode + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + nuhash + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + nuhash + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + nuhash + + + true + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + nuhash + + + true + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + nuhash + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + nuhash + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + nuhash + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + nuhash + + + false + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + nuhash + + + + Level4 + false + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_OBSOLETE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + $(SolutionDir)libnuhash\include + 4706;4996;6031 + false + true + + + Console + true + + + + + Level4 + true + true + false + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_OBSOLETE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + $(SolutionDir)libnuhash\include + MultiThreaded + false + MaxSpeed + AnySuitable + Speed + true + true + true + NoExtensions + 4706;4996;6031 + false + Fast + false + + + Console + true + true + false + UseLinkTimeCodeGeneration + wsetargv.obj;%(AdditionalDependencies) + 5.1 + + + + + Level4 + true + true + false + LIBNUHASH_DLL;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_OBSOLETE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + $(SolutionDir)libnuhash\include + MultiThreadedDLL + false + MaxSpeed + AnySuitable + Speed + true + true + true + NoExtensions + 4706;4996;6031 + false + Fast + false + + + Console + true + true + false + UseLinkTimeCodeGeneration + wsetargv.obj;%(AdditionalDependencies) + 5.1 + + + + + Level4 + false + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_OBSOLETE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + $(SolutionDir)libnuhash\include + 4706;4996;6031 + false + true + + + Console + true + + + + + Level4 + false + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_OBSOLETE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + $(SolutionDir)libnuhash\include + 4706;4996;6031 + true + + + Console + true + + + + + Level4 + true + true + false + NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_OBSOLETE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + $(SolutionDir)libnuhash\include + MultiThreaded + false + MaxSpeed + AnySuitable + Speed + true + true + true + 4706;4996;6031 + false + Fast + false + + + Console + true + true + false + UseLinkTimeCodeGeneration + wsetargv.obj;%(AdditionalDependencies) + 5.2 + + + + + Level4 + true + true + false + LIBNUHASH_DLL;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_OBSOLETE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + $(SolutionDir)libnuhash\include + MultiThreadedDLL + false + MaxSpeed + AnySuitable + Speed + true + true + true + 4706;4996;6031 + false + Fast + false + + + Console + true + true + false + UseLinkTimeCodeGeneration + wsetargv.obj;%(AdditionalDependencies) + 5.2 + + + + + Level4 + true + true + false + NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + $(SolutionDir)libnuhash\include + MultiThreaded + false + MaxSpeed + AnySuitable + Speed + true + true + true + 4706;4996;6031 + false + Fast + false + + + Console + true + true + false + UseLinkTimeCodeGeneration + wsetargv.obj;%(AdditionalDependencies) + + + + + Level4 + true + true + false + LIBNUHASH_DLL;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + $(SolutionDir)libnuhash\include + MultiThreadedDLL + false + MaxSpeed + AnySuitable + Speed + true + true + true + 4706;4996;6031 + false + Fast + false + + + Console + true + true + false + UseLinkTimeCodeGeneration + wsetargv.obj;%(AdditionalDependencies) + + + + + + + + + {8fa5c597-887d-46bc-a6c9-2183aef7b793} + + + + + _M_X64;%(PreprocessorDefinitions) + _M_X64;%(PreprocessorDefinitions) + _M_X64;%(PreprocessorDefinitions) + _M_ARM64;%(PreprocessorDefinitions) + _M_ARM64;%(PreprocessorDefinitions) + _M_ARM64;%(PreprocessorDefinitions) + _M_IX86;%(PreprocessorDefinitions) + _M_IX86;%(PreprocessorDefinitions) + _M_IX86;%(PreprocessorDefinitions) + + + + + + + + + + + + \ No newline at end of file diff --git a/tool/nuhash.vcxproj.filters b/tool/nuhash.vcxproj.filters new file mode 100644 index 0000000..6fd0edd --- /dev/null +++ b/tool/nuhash.vcxproj.filters @@ -0,0 +1,40 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Quelldateien + + + Quelldateien + + + + + Ressourcendateien + + + + + Ressourcendateien + + + + + Headerdateien + + + \ No newline at end of file diff --git a/tool/res/compatibility.manifest b/tool/res/compatibility.manifest new file mode 100644 index 0000000..fce5b0f --- /dev/null +++ b/tool/res/compatibility.manifest @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/tool/res/hash.ico b/tool/res/hash.ico new file mode 100644 index 0000000..09c27ff Binary files /dev/null and b/tool/res/hash.ico differ diff --git a/tool/res/version.rc b/tool/res/version.rc new file mode 100644 index 0000000..8e84b47 --- /dev/null +++ b/tool/res/version.rc @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Microsoft Visual C++ generated resource script. +// +#define APSTUDIO_READONLY_SYMBOLS +#include "WinResrc.h" +#undef APSTUDIO_READONLY_SYMBOLS + +#include "../../libnuhash/src/version.h" + +#define MY_VERSION_NUMBER NUHASH_VERSION_MAJOR, NUHASH_VERSION_MINOR, NUHASH_VERSION_PATCH, 0 +#define ___MY_VERSION_STRING(X) #X +#define __MY_VERSION_STRING(X,Y,Z) ___MY_VERSION_STRING(X.Y.Z) +#define _MY_VERSION_STRING(X,Y,Z) __MY_VERSION_STRING(X,Y,Z) +#define MY_VERSION_STRING _MY_VERSION_STRING(NUHASH_VERSION_MAJOR, NUHASH_VERSION_MINOR, NUHASH_VERSION_PATCH) + +#if defined(_M_X64) || defined(__x86_64__) +# define ARCH_NAME "x64" +#elif defined(_M_ARM64) || defined(__aarch64__) +# define ARCH_NAME "ARM64" +#elif defined(_M_IX86) || defined(__i386__) +# define ARCH_NAME "x86" +#else +# error Unsupported CPU architecture! +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Neutral resources +// +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// +101 ICON "hash.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +VS_VERSION_INFO VERSIONINFO + FILEVERSION MY_VERSION_NUMBER + PRODUCTVERSION MY_VERSION_NUMBER + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x3L +#else + FILEFLAGS 0x2L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "ProductName", "NuHash" + VALUE "FileDescription", "NuHash (" ARCH_NAME ")" + VALUE "ProductVersion", MY_VERSION_STRING + VALUE "FileVersion", MY_VERSION_STRING + VALUE "InternalName", "nuhash" + VALUE "OriginalFilename", "nuhash.exe" + VALUE "LegalCopyright", "Created by LoRd_MuldeR " + VALUE "CompanyName", "Muldersoft" + VALUE "LegalTrademarks", "Muldersoft" + VALUE "Comments", "This work has been released under the CC0 1.0 Universal license!" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/tool/src/main.c b/tool/src/main.c new file mode 100644 index 0000000..3620762 --- /dev/null +++ b/tool/src/main.c @@ -0,0 +1,502 @@ +/******************************************************************************/ +/* NuHash, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +/* libnuhash*/ +#include + +/* Platfrom */ +#include "platform.h" + +/* wildcard support */ +#ifdef __MINGW32__ +const int _dowildcard = 1; +#endif + +/* array length */ +#define COUNT_OF(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0])) + +/* I/O buffer */ +#define BUFFSIZE 4096U + +/* update interval */ +#define UPDATE_INTERVAL 997U + +/* ------------------------------------------------------------------------ */ +/* Print digest */ +/* ------------------------------------------------------------------------ */ + +#define PRINTF_DIGEST(FORMAT, ...) do \ +{ \ + if (!binary_mode) \ + { \ + FPRINTF(stdout, FMT_HCHAR TEXT(" ") FORMAT TEXT("\n"), nuhash_tohex(digest, upper_case, hexstr), __VA_ARGS__); \ + } \ + else \ + { \ + fwrite(digest, sizeof(uint8_t), NUHASH_BYTES, stdout); \ + } \ + fflush(stdout); \ +} \ +while (0) + +/* ------------------------------------------------------------------------ */ +/* Print progress */ +/* ------------------------------------------------------------------------ */ + +#define SUFFIX(FLAG, STR1, STR2) ((FLAG) ? (STR1 STR2) : (STR1)) +#define PREFIX(FLAG, STR1, STR2) ((FLAG) ? (STR1 STR2) : (STR2)) + +static void print_progress(const uint64_t total, const uint64_t current, const int finished) +{ + if (total > 0U) + { + FPRINTF(stderr, SUFFIX(finished, TEXT("\r%") TEXT(PRIu64) TEXT("/%") TEXT(PRIu64) TEXT(" bytes hashed... [%.1f%%]"), TEXT("\n")), current, total, 100.0 * (current / (double)total)); + } + else + { + FPRINTF(stderr, SUFFIX(finished, TEXT("\r%") TEXT(PRIu64) TEXT(" bytes hashed..."), TEXT(" done\n")), current); + } + fflush(stderr); +} + +/* ------------------------------------------------------------------------ */ +/* Self-test */ +/* ------------------------------------------------------------------------ */ + +typedef struct +{ + size_t iterations; + const char* message; +} +testcase_t; + +static const testcase_t TEST_VECTOR[] = +{ + { 0x0000001, "" }, + { 0x0000001, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { 0x0000001, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, + { 0x00F4240, "a" }, + { 0x1000000, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno" }, + { 0x1000000, "g4tB,=[TU%/|8lv_c5Y?F9Sqs1PnV#bNO6DW\\0em~p3E7" }, + { 0x1000000, "\xA4\x2C\x55\xA5\xB0\x5E\xD8\x33\xF3\x18\xFB\xA7\x20\xC7\x34\xD7\x1D\x2D\x46\x8D\xCA\x8A\xE7\xFC\x68\x5B\x54\xDA\xF9\xC3\x76\x62\xA9\x3D\x39\xBF\x17\xB7\xB2\x8C\x10\xA2\x1F\xE3\x74\x6A\x4A\x6C\x7A\x92\xD1\x52\xEA\x88\xBA\x6B\xD6\x64\x96\x9E\xE6\x4C\x47\x42\xC5\x51\xF2\x50\xF4\x7B\x4F\xE9\x87\x6D\x94\x4B\x23\xF0\x45\x1A\x9A\xE4\x91\x0F\x3B\xB4\x71\x82\x99\xC9\x49\xE5\xBE\x28\x93\x98\x2A\xD9\x73\x65\x58\xC0\x83\x48\x8F\x03\x14\x40\x1B\x24\x1E\xA6\x3F\xF7\x67\xAB\x37\x06\xAC\xF6\x66\xB6\xDD\x1C\x0A\x35\x9F\x56\x15\xEC\xF1\x2B\x7C\x57\x5D\x02\xED\xA8\x63\x16\x75\xDC\x9B\x5C\x7D\x0D\x5F\xFD\x05\xA0\x6E\x90\x95\x85\xD2\x13\x61\x08\xA3\x01\xC8\xD3\x84\xAA\x09\xF5\x70\x6F\xDE\xB9\x04\xB5\xDB\x30\xBC\x07\x8E\xFE\x89\x60\x26\x4E\x59\xCB\x36\x86\x11\x72\xE2\xC6\xAF\x3A\x8B\x7F\xFA\x41\x38\xDF\xEE\x2F\x32\xA1\x27\x69\x31\x29\x43\xC4\x9C\x77\x21\x44\xB8\x79\xD0\xAD\x97\xE0\xE1\x0E\x19\x2E\x22\xBD\x80\xE8\xB1\xF8\x4D\x3E\xC2\x7E\x0C\xB3\x81\x12\xCC\xC1\x53\xCF\x78\xCE\x3C\xD5\x5A\xBB\x9D\xEB\xEF\xCD\xFF\x0B\x25\xAE\xD4" }, + { 0x1000000, "\xB5\xC8\x9B\xD1\xBA\x66\x29\x19\xD2\x30\xED\x26\x5B\xC4\x91\x4D\x14\xF7\x16\x35\x5A\x69\xFE\x99\xA5\x49\xF1\x94\x2B\xBC\xDC\x4C\xDD\x4F\xCA\x1B\x88\x9C\xA9\xF6\x73\x2F\xFD\x3F\x40\x39\x13\xDA\xB3\x71\xF4\xDE\x7F\x02\x3D\x64\x78\x7A\x17\x0A\x93\xDF\xEB\x9F\x07\x04\x79\x8C\x98\xB8\x28\x80\xAD\x1F\xF2\x96\x6B\xBD\x45\xD9\xFA\x2C\x56\xCE\xF0\x87\x23\x22\xEA\xC5\x27\xD3\x63\xAF\x24\xC7\xB7\x06\xE4\x75\x83\x7B\xBF\x2E\xA4\xEF\xF5\x12\x5D\x60\x95\xA7\x53\x11\x74\xB4\xA0\x9E\xE3\xAE\xBB\x55\x72\x59\xA6\x9D\xD5\x89\x6D\x8F\x4A\x0C\x1D\xCD\x2A\xFB\xEE\xD7\xC3\xF3\x25\x62\x8E\xB0\xB2\xC2\x38\x3C\x6A\x6F\x4E\x3B\x08\xD4\x86\x36\x18\x5C\xE0\x1E\x81\x77\xF8\x68\xDB\x58\x54\xFF\x97\x7E\x61\xC0\x51\xC9\x6C\xE5\x82\xBE\xCF\x32\x43\x01\x3A\x5E\x50\x47\xA1\x34\xCC\x0D\x70\xAC\xC6\x44\x9A\x3E\x10\x0E\xEC\x03\xE2\x6E\xAA\xFC\x7D\x37\x31\x4B\xE6\xB6\xC1\x15\x8B\x05\x85\x8A\x67\xF9\xAB\x8D\xE1\xA2\x48\x1C\xCB\x52\x65\x76\x0F\x1A\x21\xA8\xA3\x42\x41\x90\x92\xD0\x84\x09\x2D\x33\x5F\xD8\x7C\xB1\xB9\x57\xE8\xD6\x0B\x20\xE7\x46\xE9" } +}; + +static const char *const EXPECTED[] = +{ + "d7964fe1bec2b5ecf21ecc88c86ce4f1e89fb1ef3669d52e34eb049d7fd6c42d4b2bbeeeb70d12c3fcaf43dd2229abc9", + "b3f13f534034ae8d645d410e8828673761fe2d697218879f9ea528d976ba2e15a3f7485105e612b9a46cb3988635a70f", + "63703476f4ffce4a8c758d0d3b91a857b9a2e3433ee864f931ba328fa7247b1b0ac9c2e0279243b83051aafac6a7e710", + "c6808aeb911c8837cee2e6867e589ab28526a8153494cf35a40c4bd6e20312da33cac4a390cd3b51a2eb4226e60b53e1", + "bcca6bc8d113dd3fc171d743ac7ad2d3e63163ea7107d3c78517cf5b53ee0b2f4a0fe079e6a74df350c667b7cfe3cf09", + "56770e133b9eb4205f11824ad7280f5c31bc04dd333d1844b3589ab8b94ab95dc09b77be9a8128d7f155fa73de617597", + "9a8579bb88112b2f3285781a61348d7b04a5632fec12a73a7e0e367a556794a24a32ca7bb14da68eaed83e99c2f8f4c0", + "fbf4444b0329f508bfc6cf44920b311a718e5f4c4c1af978e78223ec3579365ff5d15c16bb5a33d69cb36f3d40564757" +}; + +static int self_test(const int upper_case, const int ignore_int, const int show_progress) +{ + int result; + size_t len, index, round, errors = 0U; + uint64_t total_size, bytes_done, tm_curr = 0U, tm_next = 0U; + uint_fast16_t spinner = 0U; + nuhash_t context; + uint8_t digest[NUHASH_BYTES]; + char hex[NUHASH_CHARS]; + + for (index = 0U; index < COUNT_OF(TEST_VECTOR); ++index) + { + len = strlen(TEST_VECTOR[index].message); + total_size = (uint64_t)len * (uint64_t)TEST_VECTOR[index].iterations; + bytes_done = 0U; + + if (show_progress && index) + { + print_progress(total_size, bytes_done, 0); + tm_next = get_mtime() + UPDATE_INTERVAL; + } + + nuhash_init(&context); + + for (round = 0U; round < TEST_VECTOR[index].iterations; ++round) + { + nuhash_update(&context, (const uint8_t*)TEST_VECTOR[index].message, len); + bytes_done += len; + if ((!ignore_int) && g_aborted) + { + FPUTS(PREFIX(show_progress, TEXT("\n"), TEXT("The process has been interrupted!\n")), stderr); + return (-1); + } + if (show_progress && index && (!(++spinner & 0x1F)) && ((tm_curr = get_mtime()) >= tm_next)) + { + print_progress(total_size, bytes_done, 0); + tm_next = tm_curr + UPDATE_INTERVAL; + } + } + + if (show_progress && index) + { + print_progress(total_size, bytes_done, 1); + fflush(stderr); + } + + if (!(result = !strcasecmp(nuhash_tohex(nuhash_final(&context, digest), upper_case, hex), EXPECTED[index]))) + { + errors += 1U; + } + + FPRINTF(stdout, FMT_HCHAR TEXT(" Test#%u - ") FMT_TCHAR TEXT("\n"), hex, (unsigned)(index + 1U), result ? TEXT("OK") : TEXT("Failed!")); + fflush(stdout); + } + + FPUTS(errors ? TEXT("Error: At least one test failed !!!\n") : TEXT("All tests completed successfully.\n"), stderr); + return (!errors); +} + +/* ------------------------------------------------------------------------ */ +/* Stress-test */ +/* ------------------------------------------------------------------------ */ + +#define RUN_STRESS_TEST(TYPE, FORMAT) do \ +{ \ + TYPE value = 0; do \ + { \ + nuhash_compute((uint8_t*)&value, sizeof(TYPE), digest); \ + PRINTF_DIGEST(FORMAT, value); \ + if ((!ignore_int) && g_aborted) { return (-1); } \ + } \ + while (++value); \ +} \ +while (0) + +static int stress_test(const int upper_case, const int binary_mode, const int ignore_int) +{ + uint8_t digest[NUHASH_BYTES]; + char hexstr[NUHASH_CHARS]; + + RUN_STRESS_TEST(uint8_t , TEXT("%02" ) TEXT(PRIX8 )); + RUN_STRESS_TEST(uint16_t, TEXT("%04" ) TEXT(PRIX16)); + RUN_STRESS_TEST(uint32_t, TEXT("%08" ) TEXT(PRIX32)); + RUN_STRESS_TEST(uint64_t, TEXT("%016") TEXT(PRIX64)); + + return 1; +} + +/* ------------------------------------------------------------------------ */ +/* Process File */ +/* ------------------------------------------------------------------------ */ + +#define CHECK_INTERRUPTED(SHOW_PROGRESS) do \ +{ \ + if ((!ignore_int) && g_aborted) \ + { \ + FPUTS(PREFIX((SHOW_PROGRESS), TEXT("\n"), TEXT("The process has been interrupted!\n")), stderr); \ + result = (-1); \ + goto clean_up; \ + } \ +} \ +while (0) + +static int process_file(FILE *const file, const CHAR_T *const name, const int line_mode, const int binary_mode, const int upper_case, const int ignore_int, const int show_progress) +{ + int result = 0; + uint64_t input_size = 0U, bytes_done = 0U, tm_curr = 0U, tm_next = 0U; + uint_fast16_t spinner = 0U; + nuhash_t context; + struct STAT_STRUCT file_stat; + uint8_t buffer[BUFFSIZE], digest[NUHASH_BYTES]; + char hexstr[NUHASH_CHARS]; + + if(!FSTAT(file, &file_stat)) + { + if (FILE_IS_DIR(file_stat.st_mode)) + { + FPRINTF(stderr, TEXT("Error: Input file \"") FMT_TCHAR TEXT("\" is a directory!\n"), name); + goto clean_up; + } + if (FILE_IS_REG(file_stat.st_mode) && (file_stat.st_size > 0)) + { + input_size = (uint64_t)file_stat.st_size; + } + } + + if (!line_mode) + { + if (show_progress) + { + print_progress(input_size, bytes_done, 0); + tm_next = get_mtime() + UPDATE_INTERVAL; + } + + nuhash_init(&context); + + while ((!feof(file)) && (!ferror(file))) + { + const size_t len = fread(buffer, sizeof(uint8_t), BUFFSIZE, file); + if (len > 0U) + { + nuhash_update(&context, buffer, len); + bytes_done += len; + if (show_progress && (!(++spinner & 0x1F)) && ((tm_curr = get_mtime()) >= tm_next)) + { + print_progress(input_size, bytes_done, 0); + tm_next = tm_curr + UPDATE_INTERVAL; + } + } + CHECK_INTERRUPTED(show_progress); + } + + if (!ferror(file)) + { + if (show_progress) + { + print_progress(input_size, bytes_done, 1); + } + nuhash_final(&context, digest); + PRINTF_DIGEST(FMT_TCHAR, name); + } + } + else + { + while (fgets((char*)buffer, BUFFSIZE, file)) + { + size_t len = strlen((char*)buffer); + while ((len > 0U) && ((((char*)buffer)[len - 1U] == '\n') || (((char*)buffer)[len - 1U] == '\r'))) + { + buffer[--len] = 0x00; + } + if (len > 0U) + { + nuhash_compute(buffer, len, digest); + PRINTF_DIGEST(FMT_HCHAR, buffer); + } + CHECK_INTERRUPTED(0); + } + } + + if (ferror(file)) + { + FPUTS(PREFIX(show_progress && (!line_mode), TEXT("\n"), TEXT("Error: Read operation has failed!\n")), stderr); \ + goto clean_up; + } + + result = 1; + +clean_up: + + if ((file != stdin) && (file != stdout) && (file != stderr)) + { + fclose(file); + } + + return result; +} + +/* ------------------------------------------------------------------------ */ +/* Options */ +/* ------------------------------------------------------------------------ */ + +#define OPTION_BINARY 0x001 +#define OPTION_HELP 0x002 +#define OPTION_IGNORE 0x004 +#define OPTION_LINE_MODE 0x008 +#define OPTION_PROGRESS 0x010 +#define OPTION_SELF_TEST 0x020 +#define OPTION_STOP 0x040 +#define OPTION_STRESS 0x080 +#define OPTION_UPPERCASE 0x100 +#define OPTION_VERSION 0x200 + +static const struct +{ + int option; + const CHAR_T short_name, *long_name; +} +OPTIONS[] = +{ + { OPTION_BINARY, TEXT('b'), TEXT("binary") }, + { OPTION_HELP, TEXT('h'), TEXT("help") }, + { OPTION_IGNORE, TEXT('i'), TEXT("ignore") }, + { OPTION_LINE_MODE, TEXT('l'), TEXT("line-mode") }, + { OPTION_PROGRESS, TEXT('p'), TEXT("progress") }, + { OPTION_SELF_TEST, TEXT('t'), TEXT("self-test") }, + { OPTION_STOP, TEXT('s'), TEXT("stop") }, + { OPTION_STRESS, (CHAR_T)0, TEXT("stress") }, + { OPTION_UPPERCASE, TEXT('u'), TEXT("uppercase") }, + { OPTION_VERSION, TEXT('v'), TEXT("version") } +}; + +static int parse_option_short(int *const options, const CHAR_T *arg_str) +{ + while (*arg_str) + { + const CHAR_T c = TOLOWER(*(arg_str++)); + size_t pos; + for (pos = 0U; pos < COUNT_OF(OPTIONS); ++pos) + { + if (c == OPTIONS[pos].short_name) + { + *options |= OPTIONS[pos].option; + goto success; + } + } + return 0; + success:; + } + return 1; +} + +static int parse_option_long(int* const options, const CHAR_T *const arg_str) +{ + size_t pos; + for (pos = 0U; pos < COUNT_OF(OPTIONS); ++pos) + { + if (!STRCASECMP(arg_str, OPTIONS[pos].long_name)) + { + *options |= OPTIONS[pos].option; + return 1; + } + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* Help screen */ +/* ------------------------------------------------------------------------ */ + +static void print_helpscreen(FILE *const stream, const int full_info) +{ + uint16_t version[3U]; + char build[12]; + nuhash_version(version, build); + + FPRINTF(stream, TEXT("nuhash ") OS_NAME TEXT("-") CPU_ARCH TEXT(" v%u.%u.%u [") FMT_HCHAR TEXT("]\n"), version[0U], version[1U], version[2U], build); + FPRINTF(stream, TEXT("built on ") FMT_HCHAR TEXT(" at ") FMT_HCHAR TEXT(" with ") COMPILER_FMT TEXT("\n\n"), __DATE__, __TIME__, COMPILER_ARG); + + if (full_info) + { + FPUTS(TEXT("Usage:\n"), stream); + FPUTS(TEXT(" nuhash") EXE_SUFFIX TEXT(" [options] [ [... ]]\n\n"), stream); + FPUTS(TEXT("Options:\n"), stream); + FPUTS(TEXT(" -b --binary Output digest as binary, default is hex-string.\n"), stream); + FPUTS(TEXT(" -h --help Print the help screen and exit.\n"), stream); + FPUTS(TEXT(" -i --ignore Ignore interrupt signals.\n"), stream); + FPUTS(TEXT(" -l --line-mode Process the input file(s) as text, line by line.\n"), stream); + FPUTS(TEXT(" -p --progress Print progress, while computing the hash.\n"), stream); + FPUTS(TEXT(" -s --stop Stop on all errors, default is to keep going.\n"), stream); + FPUTS(TEXT(" -t --self-test Run the built-in self-test.\n"), stream); + FPUTS(TEXT(" -u --uppercase Print digest as uppercase, default is lowercase.\n"), stream); + FPUTS(TEXT(" -v --version Print version information and exit.\n\n"), stream); + } +} + +/* ------------------------------------------------------------------------ */ +/* MAIN */ +/* ------------------------------------------------------------------------ */ + +int MAIN(const int argc, const CHAR_T *const argv[]) +{ + int exit_code = EXIT_SUCCESS, index = 1, options = 0, nostd = 0, result = 0; + + initialize_process(); + SETMODE(stderr, FMODE_TXT); + + if ((argc > 1) && (!STRCASECMP(argv[1], TEXT("/?")))) + { + options |= OPTION_HELP; + index = argc; + } + + while ((index < argc) && (argv[index][0U] == TEXT('-')) && (argv[index][1U] != TEXT('\0'))) + { + const CHAR_T *const arg_str = argv[index++]; + if (arg_str[1U] == TEXT('-')) + { + if (arg_str[2U] == TEXT('\0')) + { + nostd = 1; + break; + } + else if (parse_option_long(&options, arg_str + 2U)) + { + continue; + } + } + else if (parse_option_short(&options, arg_str + 1U)) + { + continue; + } + FPRINTF(stderr, TEXT("Error: Unknown option \"") FMT_TCHAR TEXT("\" encountered!\n"), arg_str); + return EXIT_FAILURE; + } + + if (options & (OPTION_HELP | OPTION_VERSION)) + { + print_helpscreen(stderr, options & OPTION_HELP); + return EXIT_SUCCESS; + } + + if ((options & OPTION_BINARY) && ISATTY(stdout)) + { + FPUTS(TEXT("Error: Binray output is not supported when writing to terminal!\n"), stderr); + return EXIT_FAILURE; + } + + if ((options & (OPTION_SELF_TEST | OPTION_STRESS)) && (index < argc)) + { + FPUTS(TEXT("Warning: Excess command-line argument(s) will be ignored!\n"), stderr); + } + + SETMODE(stdin, FMODE_BIN); + SETMODE(stdout, (options & OPTION_BINARY) ? FMODE_BIN : FMODE_TXT); + + if (options & OPTION_SELF_TEST) + { + result = self_test(options & OPTION_UPPERCASE, options & OPTION_IGNORE, options & OPTION_PROGRESS); + return (result < 1) ? EXIT_FAILURE : EXIT_SUCCESS; + } + + if (options & OPTION_STRESS) + { + result = stress_test(options & OPTION_UPPERCASE, options & OPTION_BINARY, options & OPTION_IGNORE); + return (result < 1) ? EXIT_FAILURE : EXIT_SUCCESS; + } + + if (index < argc) + { + for (; index < argc; ++index) + { + FILE *const input = (nostd || STRCASECMP(argv[index], TEXT("-"))) ? FOPEN(argv[index], TEXT("rb")) : stdin; + if (input) + { + result = process_file(input, argv[index], options & OPTION_LINE_MODE, options & OPTION_BINARY, options & OPTION_UPPERCASE, options & OPTION_IGNORE, options & OPTION_PROGRESS); + if (result < 1) + { + exit_code = EXIT_FAILURE; + } + } + else + { + FPRINTF(stderr, TEXT("Error: Failed to open file \"") FMT_TCHAR TEXT("\" for reading!\n"), argv[index]); + exit_code = EXIT_FAILURE; + } + + if ((result < 0) || ((exit_code != EXIT_SUCCESS) && (options & OPTION_STOP))) + { + break; + } + } + } + else if (!(options & (OPTION_SELF_TEST | OPTION_STRESS))) + { + result = process_file(stdin, TEXT("-"), options & OPTION_LINE_MODE, options & OPTION_BINARY, options & OPTION_UPPERCASE, options & OPTION_IGNORE, options & OPTION_PROGRESS); + if (result < 1) + { + exit_code = EXIT_FAILURE; + } + } + + return exit_code; +} diff --git a/tool/src/platform.c b/tool/src/platform.c new file mode 100644 index 0000000..1c15ac3 --- /dev/null +++ b/tool/src/platform.c @@ -0,0 +1,74 @@ +/******************************************************************************/ +/* NuHash, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +#include + +#ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN 1 +# include +#else +# include +# include +# include +#endif + +#define UNUSED(X) ((void)(X)) +#define Q64(X) ((uint64_t)(X).QuadPart) + +volatile int g_aborted = 0; + +#ifdef _WIN32 +static LARGE_INTEGER s_frequency; +#endif + +static void sig_handler(const int signal_no) +{ + UNUSED(signal_no); + g_aborted = 1; +} + +#ifdef _WIN32 +static BOOL WINAPI console_ctrl_handler(const DWORD type) +{ + switch (type) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_CLOSE_EVENT: + sig_handler(2); + return TRUE; + default: + return FALSE; + } +} +#endif + +void initialize_process(void) +{ +#if defined(_WIN32) + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); + QueryPerformanceFrequency(&s_frequency); + SetConsoleCtrlHandler(console_ctrl_handler, TRUE); +#else + struct sigaction action; + action.sa_handler = sig_handler; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + sigaction(SIGINT, &action, NULL); +#endif +} + +uint64_t get_mtime(void) +{ +#if defined(_WIN32) + LARGE_INTEGER counter; + QueryPerformanceCounter(&counter); + return ((Q64(counter) / Q64(s_frequency)) * UINT64_C(1000)) + (((Q64(counter) % Q64(s_frequency)) * UINT64_C(1000)) / Q64(s_frequency)); +#else + struct timespec time_stamp; + clock_gettime(CLOCK_MONOTONIC, &time_stamp); + return ((uint64_t)time_stamp.tv_sec * UINT64_C(1000)) + ((uint64_t)time_stamp.tv_nsec / UINT64_C(1000000)); +#endif +} diff --git a/tool/src/platform.h b/tool/src/platform.h new file mode 100644 index 0000000..8bb9c4e --- /dev/null +++ b/tool/src/platform.h @@ -0,0 +1,211 @@ +/******************************************************************************/ +/* NuHash, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +#ifndef _INC_NUHASH_PLATFORM_H +#define _INC_NUHASH_PLATFORM_H + +/* CRT */ +#include +#include +#include +#include +#include +#include +#include + +/* platform-specific */ +#ifdef _WIN32 +# include +# include +# include +#else +# include +#endif + +/* initialization */ +void initialize_process(void); + +/* monotonic clock */ +uint64_t get_mtime(void); + +/* abort flag */ +extern volatile int g_aborted; + +/* integer types */ +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) +# include +#else +# define PRIX8 "hhX" +# define PRIX16 "hX" +# define PRIX32 "X" +# define PRIX64 "llX" +#endif + +/* Unicode support*/ +#ifdef _WIN32 +# define CHAR_T wchar_t +# define __TEXT(X) L##X +# define TEXT(X) __TEXT(X) +# define MAIN wmain +# define FPRINTF fwprintf +# define FPUTS fputws +# define FOPEN(X,Y) _wfsopen((X),(Y),_SH_SECURE) +# define STRCASECMP _wcsicmp +# define strcasecmp _stricmp +# define TOLOWER(X) towlower((unsigned short)(X)) +# ifndef __USE_MINGW_ANSI_STDIO +# define FMT_TCHAR L"%s" +# define FMT_HCHAR L"%S" +# else +# define FMT_TCHAR L"%ls" +# define FMT_HCHAR L"%hs" +# endif +#else +# define CHAR_T char +# define TEXT(X) X +# define MAIN main +# define FPRINTF fprintf +# define FPUTS fputs +# define FOPEN fopen +# define STRCASECMP strcasecmp +# define TOLOWER(X) tolower((unsigned char)(X)) +# define FMT_TCHAR "%s" +# define FMT_HCHAR "%s" +#endif + +/* CPU arch */ +#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) +# define CPU_ARCH TEXT("x64") +#elif defined(__i386__) || defined(_X86_) || defined(_M_IX86) || defined(__IA32__) +# define CPU_ARCH TEXT("x86") +#elif defined(__aarch64__) || defined(_M_ARM64) +# define CPU_ARCH TEXT("arm64") +#elif defined(__arm__) && defined(__ARM_FP) +# define CPU_ARCH TEXT("armhf") +#elif defined(__arm__) && defined(__ARMEL__) +# define CPU_ARCH TEXT("armel") +#elif defined(__arm__) || defined(_M_ARM) +# define CPU_ARCH TEXT("arm") +#elif defined(__mips__) && defined(_MIPS_ARCH_MIPS64R6) && defined(_MIPSEL) +# define CPU_ARCH TEXT("mips64r6el") +#elif defined(__mips__) && defined(_MIPS_ARCH_MIPS64R6) +# define CPU_ARCH TEXT("mips64r6") +#elif defined(__mips__) && defined(_MIPS_ARCH_MIPS32R6) && defined(_MIPSEL) +# define CPU_ARCH TEXT("mipsr6el") +#elif defined(__mips__) && defined(_MIPS_ARCH_MIPS32R6) +# define CPU_ARCH TEXT("mipsr6") +#elif defined(__mips__) && (defined(__mips64) || (__mips == 64)) && defined(_MIPSEL) +# define CPU_ARCH TEXT("mips64el") +#elif defined(__mips__) && (defined(__mips64) || (__mips == 64)) +# define CPU_ARCH TEXT("mips64") +#elif (defined(__mips__) || defined(_mips) || defined(__mips)) && defined(_MIPSEL) +# define CPU_ARCH TEXT("mipsel") +#elif defined(__mips__) || defined(_mips) || defined(__mips) +# define CPU_ARCH TEXT("mips") +#elif defined(__powerpc64__) || defined(__PPC64__) || defined(_ARCH_PPC64) +# define CPU_ARCH TEXT("ppc64") +#elif defined(__powerpc__) || defined(__PPC__) || defined(_ARCH_PPC) +# define CPU_ARCH TEXT("ppc") +#elif defined(__s390x__) || defined(__zarch__) +# define CPU_ARCH TEXT("s390x") +#elif defined(__riscv) && (__riscv_xlen == 64) +# define CPU_ARCH TEXT("riscv64") +#else +# error Unsupported CPU architecture encountered! +#endif + +/* OS family */ +#if defined(__linux__) +# define OS_NAME TEXT("linux") +#elif defined(__gnu_hurd__) +# define OS_NAME TEXT("hurd") +#elif defined(__FreeBSD__) +# define OS_NAME TEXT("freebsd") +#elif defined(__OpenBSD__) +# define OS_NAME TEXT("openbsd") +#elif defined(__NetBSD__) +# define OS_NAME TEXT("netbsd") +#elif defined(__DragonFly__) +# define OS_NAME TEXT("dragonfly") +#elif defined(__illumos__) +# define OS_NAME TEXT("illumos") +#elif defined(__sun) && defined(__svr4__) +# define OS_NAME TEXT("solaris") +#elif defined(__QNX__) +# define OS_NAME TEXT("qnx") +#elif defined(__APPLE__) && defined(__MACH__) +# define OS_NAME TEXT("darwin") +#elif defined(__HAIKU__) +# define OS_NAME TEXT("haiku") +#elif defined(__CYGWIN__) +# define OS_NAME TEXT("cygwin") +#elif defined(_WIN32) +# define OS_NAME TEXT("windows") +#elif defined(__unix__) +# define OS_NAME TEXT("unix") +#else +# error Unsupported operating system encountered! +#endif + +/* Compiler */ +#if defined(__INTEL_LLVM_COMPILER) +# define COMPILER_FMT TEXT("Intel C++ Compiler v%u.%u.%u") +# define COMPILER_ARG __INTEL_LLVM_COMPILER / 10000U, (__INTEL_LLVM_COMPILER % 10000U) / 100U, __INTEL_LLVM_COMPILER % 100U +#elif defined(__clang__) +# define COMPILER_FMT TEXT("Clang v%u.%u.%u") +# define COMPILER_ARG __clang_major__, __clang_minor__, __clang_patchlevel__ +#elif defined(__GNUC__) +# define COMPILER_FMT TEXT("GCC v%u.%u.%u") +# define COMPILER_ARG __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ +#elif defined(_MSC_VER) +# define COMPILER_FMT TEXT("MSVC v%u.%02u.%u") +# define COMPILER_ARG _MSC_VER / 100U, _MSC_VER % 100U, _MSC_FULL_VER % 100000U +#else +# error Unsupported compiler encountered! +#endif + +/* fstat() support */ +#ifdef _WIN32 +# define FSTAT(X,Y) _fstat64(_fileno(X),(Y)) +# define STAT_STRUCT _stat64 +# define FILE_IS_DIR(X) (((X) & _S_IFMT) == _S_IFDIR) +# define FILE_IS_REG(X) (((X) & _S_IFMT) == _S_IFREG) +#else +# define FSTAT(X,Y) fstat(fileno(X),(Y)) +# define STAT_STRUCT stat +# define FILE_IS_DIR(X) S_ISDIR((X)) +# define FILE_IS_REG(X) S_ISREG((X)) +#endif + +/* assert file size */ +#define STATIC_ASSERT(X,Y) typedef char _static_assertion_##X[(Y) ? 1 : (-1)] +STATIC_ASSERT(file_size, sizeof(((struct STAT_STRUCT*)NULL)->st_size) >= 8U); + +/* setmode() support */ +#ifdef _WIN32 +# define FMODE_BIN _O_BINARY +# define FMODE_TXT _O_U8TEXT +# define SETMODE(X,Y) _setmode(_fileno((X)), (Y)) +#else +# define FMODE_BIN 0x1 +# define FMODE_TXT 0x2 +# define SETMODE(X,Y) ((void)0) +#endif + +/* isatty() support */ +#ifdef _WIN32 +# define ISATTY(X) _isatty(_fileno((X))) +#else +# define ISATTY(X) isatty(fileno((X))) +#endif + +/* executable name */ +#ifdef _WIN32 +# define EXE_SUFFIX TEXT(".exe") +#else +# define EXE_SUFFIX +#endif + +#endif /* _INC_NUHASH_PLATFORM_H */